๐ ์จ๋ผ์ธ ํํฐ๋ง ์ธ์ ์์ฝ ํ๋ซํผ
tutoring-session-booking-platform
๋ฌธ์ ์ค๋ช
ํ๋ก์ ํธ ๊ฐ์
๊ฐ์ธ ๊ณผ์ธ ์ ์๋์ด๋ ์จ๋ผ์ธ ํํฐ๊ฐ ์์ ์ ์์ ์๊ฐํ๋ฅผ ๊ณต๊ฐํ๊ณ , ํ์๋ค์ด ์ํ๋ ์๊ฐ๋๋ฅผ ์ ํํด ์์ฝํ ์ ์๋ ํ์คํ ํ๋ซํผ์ ๋๋ค. Laravel 13.x API ๋ฐฑ์๋์ React 19 ํ๋ก ํธ์๋๋ฅผ ๋ถ๋ฆฌํ์ฌ RESTful ๊ตฌ์กฐ๋ก ๊ตฌํํฉ๋๋ค.
ํต์ฌ ๊ธฐ๋ฅ
ํ์ ๊ธฐ๋ฅ
- ํํฐ ํ๋กํ ํ์ด์ง: ํํฐ ์ด๋ฆ, ์ ๋ฌธ ๋ถ์ผ, ์๊ฐ๋น ์์ ๋ฃ, ์๊ฐ ๋ฌธ๊ตฌ ํ์
- ์์ฝ ๊ฐ๋ฅ ์๊ฐํ: ๋ ์ง๋ณ๋ก ์์ฝ ๊ฐ๋ฅํ ์๊ฐ ์ฌ๋กฏ ํ์ (์: ์ค์ 10์, ์คํ 2์ ๋ฑ)
- ์์ฝ ์ ์ฒญ ํผ: ํ์ ์ด๋ฆ, ์ด๋ฉ์ผ, ์ ํํ ์๊ฐ๋, ๊ฐ๋จํ ์์ฒญ ์ฌํญ ์ ๋ ฅ
- ์์ฝ ๋ชฉ๋ก ์กฐํ: ํํฐ๊ฐ ๋ฐ์ ์์ฝ ์ ์ฒญ ๋ชฉ๋ก์ ํ์ธํ ์ ์๋ ๊ฐ๋จํ ๋์๋ณด๋
- ์์ฝ ์ํ ํ์: ์์ฝ ๊ฐ๋ฅ/์์ฝ ์๋ฃ ์ํ๋ฅผ ์๊ฐ์ ์ผ๋ก ๊ตฌ๋ถ
๋ณด๋์ค ๊ธฐ๋ฅ
- ์์ฝ ์๊ฐ๋๋ณ ์์ ์ฝ๋ฉ (์ค์ /์คํ/์ ๋ )
- ์์ฝ ํ์ ์ ๊ฐ๋จํ ์๋ด ๋ฉ์์ง ํ์
- ํํฐ๋ณ ๋์ ์์ฝ ํ์ ๋ฐฐ์ง
- ์ต๊ทผ ์์ฝ ๋ชฉ๋ก ๋ฏธ๋ฆฌ๋ณด๊ธฐ (์ต๋ 5๊ฐ)
- ๋ฐ์ํ ๋์์ธ์ผ๋ก ๋ชจ๋ฐ์ผ์์๋ ์์ฝ ๊ฐ๋ฅ
๊ธฐ์ ์คํ
- ๋ฐฑ์๋: Laravel 13.x (RESTful API ์๋ฒ, SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค)
- ํ๋ก ํธ์๋: React 19 (Vite ๊ธฐ๋ฐ ๋ณ๋ ํ๋ก์ ํธ)
- ์คํ์ผ๋ง: Tailwind CSS
- HTTP ํด๋ผ์ด์ธํธ: Axios
ํ์ต ํฌ์ธํธ
- Laravel API ๋ผ์ฐํธ์ ์ปจํธ๋กค๋ฌ ์ค๊ณ
- React์์ fetch/axios๋ก API ํธ์ถํ์ฌ ๋ฐ์ดํฐ ์ฐ๋
- ๊ฐ๋จํ CRUD ์์ (์์ฝ ์์ฑ, ์กฐํ)
- useState ํ ์ ์ฌ์ฉํ ์ํ ๊ด๋ฆฌ
- ์ปดํฌ๋ํธ ๊ธฐ๋ฐ UI ์ค๊ณ
- CORS ์ค์ ๊ณผ ํ๋ก ํธ์๋-๋ฐฑ์๋ ํต์
์ ์ฝ ์กฐ๊ฑด
- โข Laravel 13.x ์ต์ ๋ฒ์ ์ฌ์ฉ ํ์
- โข React 19 ์ต์ ๋ฒ์ ์ฌ์ฉ ํ์
- โข Vite ๊ธฐ๋ฐ React ํ๋ก์ ํธ ๊ตฌ์ฑ
- โข SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฌ์ฉ (๊ฐ๋จํ ์ค์ )
- โข ๋ณ๋์ ์ธ์ฆ ์์คํ ์์ด ๊ณต๊ฐ ์์ฝ ๊ฐ๋ฅ
- โข ์ค์๊ฐ ์ฑํ ๊ธฐ๋ฅ ๊ธ์ง (HTTP ๊ธฐ๋ฐ ์์ฝ๋ง)
- โข ๋ณต์กํ ์ํ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(Redux, Zustand ๋ฑ) ์ฌ์ฉ ๊ธ์ง
- โข useState๋ง ์ฌ์ฉํ์ฌ ์ํ ๊ด๋ฆฌ
- โข Tailwind CSS๋ก ์คํ์ผ๋ง
- โข API๋ JSON ํ์์ผ๋ก ์๋ต
ํ๋กฌํํธ ๋ ์ํผ
์๋ ํ๋กฌํํธ๋ฅผ ์์๋๋ก AI์๊ฒ ๋ณด๋ด๋ฉด ๋ฉ๋๋ค. ๋ณต์ฌ ๋ฒํผ์ ๋๋ฌ ๋ฐ๋ก ์ฌ์ฉํ์ธ์.
mkdir tutoring-session-booking-platform && cd tutoring-session-booking-platform ์ด ํด๋์์ Laravel 13.x API ๋ฐฑ์๋ ํ๋ก์ ํธ๋ฅผ ์์ํฉ๋๋ค. # Laravel API ๋ฐฑ์๋ ์ค์ 1. Laravel 13.x ํ๋ก์ ํธ๋ฅผ 'backend' ํด๋์ ์์ฑํด์ฃผ์ธ์: ```bash composer create-project laravel/laravel:^13.0 backend cd backend ``` 2. .env ํ์ผ์ SQLite๋ก ์ค์ : ``` DB_CONNECTION=sqlite DB_DATABASE=database/database.sqlite ``` 3. SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ์ผ ์์ฑ: ```bash touch database/database.sqlite ``` 4. ํํฐ(Tutor)์ ์์ฝ(Booking) ๋ชจ๋ธ ๋ฐ ๋ง์ด๊ทธ๋ ์ด์ ์์ฑ: - Tutor ๋ชจ๋ธ: ์ด๋ฆ, ์ ๋ฌธ ๋ถ์ผ, ์๊ฐ๋น ์์ ๋ฃ, ์๊ฐ - Booking ๋ชจ๋ธ: ํ์ ์ด๋ฆ, ์ด๋ฉ์ผ, ์์ฝ ๋ ์ง, ์์ฝ ์๊ฐ, ์์ฒญ ์ฌํญ, ์ํ(pending/confirmed) 5. ๋ง์ด๊ทธ๋ ์ด์ ํ์ผ ์์ฑ: - tutors ํ ์ด๋ธ: name(string), specialty(string), hourly_rate(integer), bio(text) - bookings ํ ์ด๋ธ: tutor_id(foreignId), student_name(string), student_email(string), booking_date(date), booking_time(string), message(text, nullable), status(string, default 'pending') 6. ๋ง์ด๊ทธ๋ ์ด์ ์คํ: ```bash php artisan migrate ``` 7. Tutor ์๋ ์์ฑํ์ฌ ์ํ ํํฐ 2~3๋ช ์ถ๊ฐ (DatabaseSeeder.php ๋๋ ๋ณ๋ TutorSeeder ์์ฑ) 8. ์๋ ์คํ: ```bash php artisan db:seed ``` ์๋ฃ ํ 'Laravel API ๋ฐฑ์๋ ๊ธฐ๋ณธ ์ค์ ์๋ฃ'๋ผ๊ณ ์๋ ค์ฃผ์ธ์.
๊ธฐ๋ ๊ฒฐ๊ณผ: Laravel 13.x ํ๋ก์ ํธ๊ฐ backend ํด๋์ ์์ฑ๋๊ณ , SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค์ ์๋ฃ. Tutor์ Booking ๋ชจ๋ธ ๋ฐ ๋ง์ด๊ทธ๋ ์ด์ ์ด ์์ฑ๋์ด ํ ์ด๋ธ์ด ๋ง๋ค์ด์ง๊ณ , ์ํ ํํฐ ๋ฐ์ดํฐ๊ฐ ์๋๋ฅผ ํตํด ์ถ๊ฐ๋จ.
# Laravel API ๋ผ์ฐํธ ๋ฐ ์ปจํธ๋กค๋ฌ ๊ตฌํ
backend ํด๋์์ ์์
ํฉ๋๋ค.
1. API ๋ผ์ฐํธ ์ ์ (routes/api.php):
- GET /api/tutors: ๋ชจ๋ ํํฐ ๋ชฉ๋ก ์กฐํ
- GET /api/tutors/{id}: ํน์ ํํฐ ์์ธ ์ ๋ณด ์กฐํ
- GET /api/tutors/{id}/bookings: ํน์ ํํฐ์ ์์ฝ ๋ชฉ๋ก ์กฐํ
- POST /api/bookings: ์๋ก์ด ์์ฝ ์์ฑ
2. TutorController ์์ฑ ๋ฐ ๋ฉ์๋ ๊ตฌํ:
```bash
php artisan make:controller Api/TutorController
```
- index(): ๋ชจ๋ ํํฐ ๋ฐํ (JSON)
- show($id): ํน์ ํํฐ ๋ฐํ (JSON)
- bookings($id): ํน์ ํํฐ์ ์์ฝ ๋ชฉ๋ก ๋ฐํ (์ต์ ์ ์ ๋ ฌ)
3. BookingController ์์ฑ ๋ฐ ๋ฉ์๋ ๊ตฌํ:
```bash
php artisan make:controller Api/BookingController
```
- store(Request $request): ์๋ก์ด ์์ฝ ์์ฑ
- ์ ํจ์ฑ ๊ฒ์ฌ: student_name, student_email(์ด๋ฉ์ผ ํ์), booking_date(๋ ์ง ํ์), booking_time, tutor_id ํ์
- ์์ฝ ์ ์ฅ ํ JSON ์๋ต ๋ฐํ
4. CORS ์ค์ (config/cors.php):
- 'paths' => ['api/*']
- 'allowed_origins' => ['http://localhost:5173'] (Vite ๊ธฐ๋ณธ ํฌํธ)
- 'allowed_methods' => ['*']
5. API ํ
์คํธ:
```bash
php artisan serve
```
๋ธ๋ผ์ฐ์ ๋๋ Postman์ผ๋ก http://localhost:8000/api/tutors ์ ์ํ์ฌ JSON ์๋ต ํ์ธ
์๋ฃ ํ 'Laravel API ๋ผ์ฐํธ ๋ฐ ์ปจํธ๋กค๋ฌ ๊ตฌํ ์๋ฃ'๋ผ๊ณ ์๋ ค์ฃผ์ธ์.
๊ธฐ๋ ๊ฒฐ๊ณผ: API ๋ผ์ฐํธ๊ฐ ์ ์๋๊ณ , TutorController์ BookingController๊ฐ ์์ฑ๋์ด ํํฐ ๋ชฉ๋ก ์กฐํ, ํํฐ ์์ธ ์กฐํ, ์์ฝ ์์ฑ ๋ฑ์ ์๋ํฌ์ธํธ๊ฐ ์๋ํจ. CORS ์ค์ ์ผ๋ก ํ๋ก ํธ์๋์์ API ํธ์ถ ๊ฐ๋ฅ.
# React 19 ํ๋ก ํธ์๋ ํ๋ก์ ํธ ์ค์
tutoring-session-booking-platform ๋ฃจํธ ํด๋์์ ์์
ํฉ๋๋ค.
1. React 19 + Vite ํ๋ก์ ํธ๋ฅผ 'frontend' ํด๋์ ์์ฑ:
```bash
npm create vite@latest frontend -- --template react
cd frontend
npm install
```
2. Axios ๋ฐ Tailwind CSS ์ค์น:
```bash
npm install axios
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
```
3. Tailwind ์ค์ (tailwind.config.js):
```js
content: ['./index.html', './src/**/*.{js,jsx}'],
```
4. Tailwind CSS ์ํฌํธ (src/index.css):
```css
@tailwind base;
@tailwind components;
@tailwind utilities;
```
5. Axios ๊ธฐ๋ณธ ์ค์ (src/api/axios.js ํ์ผ ์์ฑ):
```js
import axios from 'axios';
const api = axios.create({
baseURL: 'http://localhost:8000/api',
});
export default api;
```
6. ๊ฐ๋ฐ ์๋ฒ ์คํ:
```bash
npm run dev
```
๋ธ๋ผ์ฐ์ ์์ http://localhost:5173 ์ ์ํ์ฌ Vite ๊ธฐ๋ณธ ํ๋ฉด ํ์ธ
์๋ฃ ํ 'React ํ๋ก ํธ์๋ ํ๋ก์ ํธ ์ค์ ์๋ฃ'๋ผ๊ณ ์๋ ค์ฃผ์ธ์.
๊ธฐ๋ ๊ฒฐ๊ณผ: React 19 ํ๋ก์ ํธ๊ฐ frontend ํด๋์ ์์ฑ๋๊ณ , Axios์ Tailwind CSS๊ฐ ์ค์น๋จ. Axios ๊ธฐ๋ณธ ์ค์ ์ผ๋ก Laravel API์ ํต์ ์ค๋น ์๋ฃ.
# React ์ปดํฌ๋ํธ ๊ตฌํ - ํํฐ ๋ชฉ๋ก ํ์ด์ง
frontend/src ํด๋์์ ์์
ํฉ๋๋ค.
1. ํํฐ ๋ชฉ๋ก ์ปดํฌ๋ํธ ์์ฑ (src/components/TutorList.jsx):
- useState๋ก tutors ์ํ ๊ด๋ฆฌ
- useEffect๋ก ์ปดํฌ๋ํธ ๋ง์ดํธ ์ API ํธ์ถ (GET /api/tutors)
- Axios๋ก ๋ฐ์ดํฐ ๊ฐ์ ธ์์ tutors ์ํ์ ์ ์ฅ
- ํํฐ ์นด๋ ํ์์ผ๋ก ํ์:
- ์ด๋ฆ, ์ ๋ฌธ ๋ถ์ผ, ์๊ฐ๋น ์์
๋ฃ, ์๊ฐ ๋ฌธ๊ตฌ
- '์์ฝํ๊ธฐ' ๋ฒํผ (ํด๋ฆญ ์ ํํฐ ID๋ฅผ ๋ถ๋ชจ ์ปดํฌ๋ํธ๋ก ์ ๋ฌ)
- Tailwind CSS๋ก ์นด๋ ์คํ์ผ๋ง (๊ทธ๋ฆฌ๋ ๋ ์ด์์, ์นด๋ hover ํจ๊ณผ)
2. App.jsx ์์ :
- TutorList ์ปดํฌ๋ํธ ์ํฌํธ ๋ฐ ๋ ๋๋ง
- ๊ฐ๋จํ ํค๋ ์ถ๊ฐ ('์จ๋ผ์ธ ํํฐ๋ง ์์ฝ ํ๋ซํผ')
3. ์คํ์ผ๋ง:
- ํค๋: ๋ฐฐ๊ฒฝ์, ์ค์ ์ ๋ ฌ, ํจ๋ฉ
- ํํฐ ์นด๋: ๊ทธ๋ฆผ์, ๋ฅ๊ทผ ๋ชจ์๋ฆฌ, ํธ๋ฒ ์ ํ๋ ํจ๊ณผ
์๋ฃ ํ ๋ธ๋ผ์ฐ์ ์์ ํํฐ ๋ชฉ๋ก์ด ์นด๋ ํ์์ผ๋ก ํ์๋๋์ง ํ์ธํ๊ณ 'ํํฐ ๋ชฉ๋ก ํ์ด์ง ๊ตฌํ ์๋ฃ'๋ผ๊ณ ์๋ ค์ฃผ์ธ์.
๊ธฐ๋ ๊ฒฐ๊ณผ: TutorList ์ปดํฌ๋ํธ๊ฐ ์์ฑ๋์ด Laravel API์์ ํํฐ ๋ชฉ๋ก์ ๊ฐ์ ธ์ ํ๋ฉด์ ์นด๋ ํ์์ผ๋ก ํ์๋จ. Tailwind CSS๋ก ๊น๋ํ๊ฒ ์คํ์ผ๋ง๋๊ณ , '์์ฝํ๊ธฐ' ๋ฒํผ์ด ๊ฐ ํํฐ ์นด๋์ ํ์๋จ.
# React ์ปดํฌ๋ํธ ๊ตฌํ - ์์ฝ ํผ
frontend/src/components ํด๋์์ ์์
ํฉ๋๋ค.
1. ์์ฝ ํผ ์ปดํฌ๋ํธ ์์ฑ (BookingForm.jsx):
- props๋ก tutorId, tutorName ๋ฐ๊ธฐ
- useState๋ก ํผ ์
๋ ฅ ์ํ ๊ด๋ฆฌ:
- studentName, studentEmail, bookingDate, bookingTime, message
- ํผ ํ๋:
- ํ์ ์ด๋ฆ (ํ
์คํธ ์
๋ ฅ)
- ํ์ ์ด๋ฉ์ผ (์ด๋ฉ์ผ ์
๋ ฅ)
- ์์ฝ ๋ ์ง (date ํ์
input)
- ์์ฝ ์๊ฐ (select ๋๋กญ๋ค์ด: 09:00, 10:00, 11:00, 14:00, 15:00, 16:00, 19:00, 20:00)
- ์์ฒญ ์ฌํญ (textarea, ์ ํ ์ฌํญ)
- ํผ ์ ์ถ ์:
- Axios๋ก POST /api/bookings ์์ฒญ
- ์์ฒญ ๋ณธ๋ฌธ: { tutor_id: tutorId, student_name, student_email, booking_date, booking_time, message }
- ์ฑ๊ณต ์ '์์ฝ์ด ์๋ฃ๋์์ต๋๋ค!' ์๋ฆผ ํ์ ๋ฐ ํผ ์ด๊ธฐํ
- ์คํจ ์ ์๋ฌ ๋ฉ์์ง ํ์
- Tailwind CSS๋ก ํผ ์คํ์ผ๋ง (๋ผ๋ฒจ, ์
๋ ฅ ํ๋, ๋ฒํผ)
2. App.jsx ์์ :
- selectedTutor ์ํ ์ถ๊ฐ (null ๋๋ ํํฐ ๊ฐ์ฒด)
- TutorList์์ '์์ฝํ๊ธฐ' ํด๋ฆญ ์ selectedTutor ์ค์
- selectedTutor๊ฐ ์์ผ๋ฉด BookingForm ํ์, ์์ผ๋ฉด TutorList ํ์
- '๋ค๋ก ๊ฐ๊ธฐ' ๋ฒํผ ์ถ๊ฐํ์ฌ selectedTutor๋ฅผ null๋ก ์ค์
์๋ฃ ํ '์์ฝ ํผ ๊ตฌํ ์๋ฃ'๋ผ๊ณ ์๋ ค์ฃผ์ธ์.
๊ธฐ๋ ๊ฒฐ๊ณผ: BookingForm ์ปดํฌ๋ํธ๊ฐ ์์ฑ๋์ด ํ์ ์ ๋ณด์ ์์ฝ ์๊ฐ์ ์ ๋ ฅ๋ฐ๊ณ , API๋ก ์์ฝ ๋ฐ์ดํฐ๋ฅผ ์ ์กํจ. ์์ฝ ์ฑ๊ณต ์ ์๋ฆผ์ด ํ์๋๊ณ , ํํฐ ๋ชฉ๋ก๊ณผ ์์ฝ ํผ ๊ฐ ์ ํ์ด ๊ฐ๋ฅํจ.
# ์์ฝ ๋ชฉ๋ก ์กฐํ ๊ธฐ๋ฅ ์ถ๊ฐ
frontend/src/components ํด๋์์ ์์
ํฉ๋๋ค.
1. ์์ฝ ๋ชฉ๋ก ์ปดํฌ๋ํธ ์์ฑ (BookingList.jsx):
- props๋ก tutorId ๋ฐ๊ธฐ
- useState๋ก bookings ์ํ ๊ด๋ฆฌ
- useEffect๋ก ์ปดํฌ๋ํธ ๋ง์ดํธ ์ API ํธ์ถ (GET /api/tutors/{tutorId}/bookings)
- ์์ฝ ๋ชฉ๋ก ํ
์ด๋ธ ๋๋ ์นด๋ ํ์์ผ๋ก ํ์:
- ํ์ ์ด๋ฆ, ์ด๋ฉ์ผ, ์์ฝ ๋ ์ง, ์์ฝ ์๊ฐ, ์ํ(pending/confirmed)
- ์ํ๋ณ ์์ ํ์ (pending: ๋
ธ๋์, confirmed: ์ด๋ก์)
- ์์ฝ์ด ์์ผ๋ฉด '์์ง ์์ฝ์ด ์์ต๋๋ค' ๋ฉ์์ง ํ์
- Tailwind CSS๋ก ํ
์ด๋ธ ์คํ์ผ๋ง
2. App.jsx ์์ :
- viewBookings ์ํ ์ถ๊ฐ (boolean)
- TutorList์ '์์ฝ ๋ชฉ๋ก ๋ณด๊ธฐ' ๋ฒํผ ์ถ๊ฐ
- viewBookings๊ฐ true์ด๋ฉด BookingList ํ์
- '๋ค๋ก ๊ฐ๊ธฐ' ๋ฒํผ์ผ๋ก viewBookings๋ฅผ false๋ก ์ค์
3. ์ต์ข
ํ
์คํธ:
- ํํฐ ๋ชฉ๋ก ์กฐํ
- ์์ฝ ์์ฑ
- ์์ฝ ๋ชฉ๋ก ์กฐํ
- ๋ชจ๋ ๊ธฐ๋ฅ์ด ์ ์ ์๋ํ๋์ง ํ์ธ
์๋ฃ ํ '์์ฝ ๋ชฉ๋ก ์กฐํ ๊ธฐ๋ฅ ์ถ๊ฐ ์๋ฃ ๋ฐ ์ ์ฒด ํ๋ก์ ํธ ์์ฑ'์ด๋ผ๊ณ ์๋ ค์ฃผ์ธ์.
๊ธฐ๋ ๊ฒฐ๊ณผ: BookingList ์ปดํฌ๋ํธ๊ฐ ์์ฑ๋์ด ํน์ ํํฐ์ ์์ฝ ๋ชฉ๋ก์ API์์ ๊ฐ์ ธ์ ํ์ํจ. ์์ฝ ์ํ๊ฐ ์์์ผ๋ก ๊ตฌ๋ถ๋๊ณ , ํํฐ ๋ชฉ๋ก-์์ฝ ํผ-์์ฝ ๋ชฉ๋ก ๊ฐ ์ ํ์ด ์ํํ๊ฒ ์๋ํจ. ์ ์ฒด ํ์คํ ํ๋ซํผ์ด ์์ฑ๋จ.
์ ์ถ๋ ์ํ (0)
๋ก๊ทธ์ธ ํ ์ ์ถ์์ง ์ ์ถ๋ ์ํ์ด ์์ต๋๋ค. ์ฒซ ๋ฒ์งธ ๋์ ์๊ฐ ๋์ด๋ณด์ธ์!