๐ฌ ๋ ๋ฆฝ์ํ ์์ํ ํฐ์ผ ์๋งค ํ์ด์ง - ์ข์ ์ ํ & ์๋งค ํ์ธ์
indie-film-screening-ticket-booking
๋ฌธ์ ์ค๋ช
๐ฌ ๋ ๋ฆฝ์ํ ์์ํ ํฐ์ผ ์๋งค ํ์ด์ง
๋ ๋ฆฝ์ํ๊ด์ด๋ ์๊ท๋ชจ ์์ํ๋ฅผ ์ํ ๊ฐ๋จํ ํฐ์ผ ์๋งค ์์คํ ์ ๋ง๋ญ๋๋ค. Laravel 13.x ๋ฐฑ์๋ API์ React 19 ํ๋ก ํธ์๋๋ฅผ ๋ถ๋ฆฌํ์ฌ ๊ตฌ์ฑํ๋ฉฐ, ๊ณ ๊ฐ์ด ์์ ์ผ์ ์ ํ์ธํ๊ณ ์ข์์ ์ ํํด ์๋งคํ ์ ์๋ ์ค์ฉ์ ์ธ ํ์คํ ํ๋ก์ ํธ์ ๋๋ค.
ํ์ ๊ธฐ๋ฅ
- ์์ ์ผ์ ๋ชฉ๋ก: ์ํ ์ ๋ชฉ, ์์ ๋ ์ง/์๊ฐ, ํฌ์คํฐ ์ด๋ฏธ์ง ํ์
- ์ข์ ์ ํ UI: ์ข์ ๋ฐฐ์น๋์์ ์์ฝ ๊ฐ๋ฅ/๋ถ๊ฐ๋ฅ ์ข์ ๊ตฌ๋ถ (๊ทธ๋ฆฌ๋ ๋ ์ด์์)
- ์๋งค ํผ: ์ด๋ฆ, ์ด๋ฉ์ผ, ์ ํ๋ฒํธ ์ ๋ ฅ
- ์๋งค ํ์ธ ํ์ด์ง: ์๋งค ๋ฒํธ, ์ํ ์ ๋ณด, ์ข์ ๋ฒํธ, ์๋งค์ ์ ๋ณด ํ์
- ์๋งค ๋ด์ญ ์กฐํ: ์๋งค ๋ฒํธ๋ก ์๋งค ์ ๋ณด ํ์ธ
๊ธฐ์ ์คํ
- ๋ฐฑ์๋: Laravel 13.x (RESTful API ์๋ฒ, SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค)
- ํ๋ก ํธ์๋: React 19 (Vite ํ๋ก์ ํธ, Tailwind CSS)
- API ํต์ : fetch ๋๋ axios๋ก Laravel API ํธ์ถ
๋ณด๋์ค ๊ธฐ๋ฅ (์ ํ)
- ์ข์ ๋ฑ๊ธ๋ณ ๊ฐ๊ฒฉ ์ฐจ๋ฑ (์ผ๋ฐ์ 10,000์, VIP์ 15,000์)
- ์๋งค ์ทจ์ ๊ธฐ๋ฅ (์๋งค ๋ฒํธ๋ก ์ทจ์)
- ์ํ ํฌ์คํฐ ์ด๋ฏธ์ง ์ ๋ก๋ (Laravel Storage ํ์ฉ)
- ์๋งค ์๋ฃ ์ ์๋ ์ด๋ฉ์ผ ๋ฐ์ก (Laravel Mail)
- ๋ฐ์ํ ๋์์ธ (๋ชจ๋ฐ์ผ ์นํ์ )
ํ์ต ๋ชฉํ
- Laravel ๋ง์ด๊ทธ๋ ์ด์ ๊ณผ ๋ชจ๋ธ๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค๊ณ
- RESTful API ์๋ํฌ์ธํธ ์์ฑ (GET, POST)
- React์์ fetch/axios๋ก API ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ
- useState๋ก ์ข์ ์ ํ ์ํ ๊ด๋ฆฌ
- ํผ ์ ์ถ๊ณผ ์๋ต ์ฒ๋ฆฌ
- ์กฐ๊ฑด๋ถ ๋ ๋๋ง (์์ฝ ๊ฐ๋ฅ/๋ถ๊ฐ๋ฅ ์ข์ ํ์)
์ ์ฝ ์กฐ๊ฑด
- โข Laravel 13.x์ React 19 ์ต์ ๋ฒ์ ์ฌ์ฉ
- โข ๋ฐฑ์๋(Laravel)์ ํ๋ก ํธ์๋(React)๋ฅผ ๋ณ๋ ํ๋ก์ ํธ๋ก ๋ถ๋ฆฌ
- โข Laravel์ API ์ ์ฉ ์๋ฒ๋ก ๊ตฌ์ฑ (routes/api.php ์ฌ์ฉ)
- โข React๋ Vite๋ก ์์ฑํ๊ณ fetch/axios๋ก API ํธ์ถ
- โข SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฌ์ฉ (๊ฐ๋จํ ์ค์ )
- โข Tailwind CSS๋ก ์คํ์ผ๋ง
- โข ๋ณต์กํ ์ํ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(Redux, Zustand ๋ฑ) ์ฌ์ฉ ๊ธ์ง - useState๋ง ์ฌ์ฉ
- โข ์ค์๊ฐ ๊ธฐ๋ฅ(WebSocket) ๊ธ์ง - HTTP ์์ฒญ๋ง ์ฌ์ฉ
- โข ์ธ์ฆ/๋ก๊ทธ์ธ ๊ธฐ๋ฅ ์์ (์ ๋ฌธ์์ฉ ๋จ์ํ)
- โข ์ข์์ 5x6 ๊ทธ๋ฆฌ๋ (30์) ๊ณ ์ ์ผ๋ก ์์
ํ๋กฌํํธ ๋ ์ํผ
์๋ ํ๋กฌํํธ๋ฅผ ์์๋๋ก AI์๊ฒ ๋ณด๋ด๋ฉด ๋ฉ๋๋ค. ๋ณต์ฌ ๋ฒํผ์ ๋๋ฌ ๋ฐ๋ก ์ฌ์ฉํ์ธ์.
mkdir indie-film-screening-ticket-booking && cd indie-film-screening-ticket-booking
์ด ํด๋์์ ํ๋ก์ ํธ๋ฅผ ์์ํฉ๋๋ค.
# Laravel 13.x ๋ฐฑ์๋ API ํ๋ก์ ํธ ์์ฑ
1. `backend` ํด๋์ Laravel 13.x ํ๋ก์ ํธ๋ฅผ ์์ฑํ์ธ์:
```bash
composer create-project laravel/laravel:^13.0 backend
cd backend
```
2. `.env` ํ์ผ์ ์์ ํ์ฌ SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฌ์ฉํ๋๋ก ์ค์ :
```
DB_CONNECTION=sqlite
# DB_HOST, DB_PORT, DB_DATABASE ๋ฑ ๋ค๋ฅธ DB ์ค์ ์ ์ฃผ์ ์ฒ๋ฆฌ
```
3. `database/database.sqlite` ํ์ผ ์์ฑ:
```bash
touch database/database.sqlite
```
4. CORS ์ค์ (React ํ๋ก ํธ์๋์ ํต์ ํ๊ธฐ ์ํด):
- `config/cors.php` ํ์ผ์์ `'allowed_origins'`๋ฅผ `['http://localhost:5173']`๋ก ์ค์ (Vite ๊ธฐ๋ณธ ํฌํธ)
- ๋๋ `'supports_credentials' => true` ํ์ธ
5. API ๋ผ์ฐํธ ํ์ธ:
- `routes/api.php` ํ์ผ์ด ์กด์ฌํ๋์ง ํ์ธ (Laravel 13.x ๊ธฐ๋ณธ ์ ๊ณต)
6. ๋ง์ด๊ทธ๋ ์ด์
ํ์ผ 2๊ฐ ์์ฑ:
```bash
php artisan make:migration create_screenings_table
php artisan make:migration create_bookings_table
```
7. `database/migrations/xxxx_create_screenings_table.php` ์์ฑ:
- ์ปฌ๋ผ: id, title (์ํ ์ ๋ชฉ), screening_date (์์ ๋ ์ง), screening_time (์์ ์๊ฐ), poster_url (ํฌ์คํฐ ์ด๋ฏธ์ง URL, nullable), total_seats (์ด ์ข์ ์, ๊ธฐ๋ณธ๊ฐ 30), timestamps
8. `database/migrations/xxxx_create_bookings_table.php` ์์ฑ:
- ์ปฌ๋ผ: id, screening_id (์ธ๋ํค), seat_number (์ข์ ๋ฒํธ, ์: 'A1'), customer_name (์๋งค์ ์ด๋ฆ), customer_email, customer_phone, booking_number (์๋งค ๋ฒํธ, ์ ๋ํฌ), timestamps
- ์ธ๋ํค ์ ์ฝ: screening_id๋ screenings ํ
์ด๋ธ ์ฐธ์กฐ, onDelete('cascade')
9. ๋ง์ด๊ทธ๋ ์ด์
์คํ:
```bash
php artisan migrate
```
10. ์๋ ํ์ผ ์์ฑํ์ฌ ์ํ ์์ ๋ฐ์ดํฐ ์ถ๊ฐ:
```bash
php artisan make:seeder ScreeningSeeder
```
- `database/seeders/ScreeningSeeder.php`์ ์ํ ์ํ 2~3๊ฐ ์ถ๊ฐ (์ ๋ชฉ, ๋ ์ง, ์๊ฐ, ํฌ์คํฐ URL์ Unsplash placeholder ์ฌ์ฉ)
- `database/seeders/DatabaseSeeder.php`์์ ScreeningSeeder ํธ์ถ
- ์คํ: `php artisan db:seed`
ํ๋ก์ ํธ ๊ตฌ์กฐ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ์ค๋น๋์๋์ง ํ์ธํ์ธ์.
๊ธฐ๋ ๊ฒฐ๊ณผ: Laravel 13.x ๋ฐฑ์๋ ํ๋ก์ ํธ๊ฐ `backend` ํด๋์ ์์ฑ๋๊ณ , SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค์ `screenings`์ `bookings` ํ ์ด๋ธ์ด ์์ฑ๋ฉ๋๋ค. ์ํ ์์ ๋ฐ์ดํฐ๊ฐ ์๋๋ฅผ ํตํด ์ถ๊ฐ๋์ด API ํ ์คํธ ์ค๋น๊ฐ ์๋ฃ๋ฉ๋๋ค.
# Laravel API ์๋ํฌ์ธํธ ์์ฑ
`backend` ํด๋์์ ์์
ํฉ๋๋ค.
1. Screening ๋ชจ๋ธ ์์ฑ:
```bash
php artisan make:model Screening
```
- `app/Models/Screening.php`์ `$fillable = ['title', 'screening_date', 'screening_time', 'poster_url', 'total_seats'];` ์ถ๊ฐ
- bookings ๊ด๊ณ ์ ์: `public function bookings() { return $this->hasMany(Booking::class); }`
2. Booking ๋ชจ๋ธ ์์ฑ:
```bash
php artisan make:model Booking
```
- `app/Models/Booking.php`์ `$fillable = ['screening_id', 'seat_number', 'customer_name', 'customer_email', 'customer_phone', 'booking_number'];` ์ถ๊ฐ
- screening ๊ด๊ณ ์ ์: `public function screening() { return $this->belongsTo(Screening::class); }`
3. API ์ปจํธ๋กค๋ฌ ์์ฑ:
```bash
php artisan make:controller Api/ScreeningController
php artisan make:controller Api/BookingController
```
4. `app/Http/Controllers/Api/ScreeningController.php` ์์ฑ:
- `index()` ๋ฉ์๋: ๋ชจ๋ ์์ ์ผ์ ๋ฐํ (JSON)
```php
public function index() {
$screenings = Screening::all();
return response()->json($screenings);
}
```
- `show($id)` ๋ฉ์๋: ํน์ ์์ ์ ๋ณด + ์์ฝ๋ ์ข์ ๋ฒํธ ๋ฐฐ์ด ๋ฐํ
```php
public function show($id) {
$screening = Screening::with('bookings:screening_id,seat_number')->findOrFail($id);
$bookedSeats = $screening->bookings->pluck('seat_number');
return response()->json([
'screening' => $screening,
'bookedSeats' => $bookedSeats
]);
}
```
5. `app/Http/Controllers/Api/BookingController.php` ์์ฑ:
- `store(Request $request)` ๋ฉ์๋: ์๋งค ์์ฑ
- ์
๋ ฅ: screening_id, seat_number, customer_name, customer_email, customer_phone
- ์ข์ ์ค๋ณต ์ฒดํฌ (์ด๋ฏธ ์์ฝ๋ ์ข์์ธ์ง ํ์ธ)
- booking_number ์์ฑ (์: 'BK' + timestamp + random 4์๋ฆฌ)
- ์๋งค ์ ์ฅ ํ ์๋งค ์ ๋ณด ๋ฐํ (JSON)
- `show($bookingNumber)` ๋ฉ์๋: ์๋งค ๋ฒํธ๋ก ์๋งค ์ ๋ณด ์กฐํ
- Booking::where('booking_number', $bookingNumber)->with('screening')->firstOrFail() ๋ฐํ
6. `routes/api.php`์ ๋ผ์ฐํธ ์ถ๊ฐ:
```php
use App\Http\Controllers\Api\ScreeningController;
use App\Http\Controllers\Api\BookingController;
Route::get('/screenings', [ScreeningController::class, 'index']);
Route::get('/screenings/{id}', [ScreeningController::class, 'show']);
Route::post('/bookings', [BookingController::class, 'store']);
Route::get('/bookings/{bookingNumber}', [BookingController::class, 'show']);
```
7. Laravel ๊ฐ๋ฐ ์๋ฒ ์คํ:
```bash
php artisan serve
```
- ๊ธฐ๋ณธ ํฌํธ: http://localhost:8000
8. API ํ
์คํธ (Postman ๋๋ curl):
- GET http://localhost:8000/api/screenings (์์ ๋ชฉ๋ก)
- GET http://localhost:8000/api/screenings/1 (ํน์ ์์ + ์์ฝ๋ ์ข์)
API๊ฐ ์ ์์ ์ผ๋ก ์๋ํ๋์ง ํ์ธํ์ธ์.
๊ธฐ๋ ๊ฒฐ๊ณผ: Laravel API ์๋ํฌ์ธํธ๊ฐ ์์ฑ๋์ด ์์ ์ผ์ ์กฐํ, ํน์ ์์์ ์์ฝ๋ ์ข์ ์กฐํ, ์๋งค ์์ฑ, ์๋งค ์กฐํ ๊ธฐ๋ฅ์ด ์๋ํฉ๋๋ค. Postman์ด๋ curl๋ก ํ ์คํธํ์ฌ JSON ์๋ต์ ํ์ธํ ์ ์์ต๋๋ค.
# React 19 ํ๋ก ํธ์๋ ํ๋ก์ ํธ ์์ฑ
ํ๋ก์ ํธ ๋ฃจํธ ํด๋(`indie-film-screening-ticket-booking`)๋ก ๋์์์ ์์
ํฉ๋๋ค.
1. `frontend` ํด๋์ React 19 ํ๋ก์ ํธ ์์ฑ (Vite ์ฌ์ฉ):
```bash
npm create vite@latest frontend -- --template react
cd frontend
npm install
```
2. Tailwind CSS ์ค์น ๋ฐ ์ค์ :
```bash
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
```
- `tailwind.config.js` ์์ :
```js
content: ["./index.html", "./src/**/*.{js,jsx}"],
```
- `src/index.css`์ Tailwind directives ์ถ๊ฐ:
```css
@tailwind base;
@tailwind components;
@tailwind utilities;
```
3. axios ์ค์น (API ํต์ ์ฉ):
```bash
npm install axios
```
4. `src/App.jsx` ์ด๊ธฐ ๊ตฌ์กฐ ์์ฑ:
- useState๋ก `screenings` ์ํ ๊ด๋ฆฌ
- useEffect์์ `http://localhost:8000/api/screenings` ํธ์ถํ์ฌ ์์ ๋ชฉ๋ก ๊ฐ์ ธ์ค๊ธฐ
- ์์ ๋ชฉ๋ก์ ์นด๋ ํํ๋ก ํ์ (์ํ ์ ๋ชฉ, ๋ ์ง, ์๊ฐ, ํฌ์คํฐ ์ด๋ฏธ์ง)
- ๊ฐ ์นด๋์ "์๋งคํ๊ธฐ" ๋ฒํผ ์ถ๊ฐ (ํด๋ฆญ ์ ํด๋น ์์ ID ์ ์ฅ)
5. Tailwind CSS๋ก ์คํ์ผ๋ง:
- ์นด๋ ๋ ์ด์์: ๊ทธ๋ฆฌ๋ ๋๋ flexbox
- ํฌ์คํฐ ์ด๋ฏธ์ง: aspect-ratio ์ ์ง, rounded corners
- ๋ฒํผ: bg-blue-600 hover:bg-blue-700 ๋ฑ
6. ๊ฐ๋ฐ ์๋ฒ ์คํ:
```bash
npm run dev
```
- ๊ธฐ๋ณธ ํฌํธ: http://localhost:5173
7. ๋ธ๋ผ์ฐ์ ์์ ํ์ธ:
- ์์ ๋ชฉ๋ก์ด ํ์๋๋์ง ํ์ธ
- CORS ์๋ฌ ๋ฐ์ ์ Laravel `config/cors.php` ์ฌํ์ธ
ํ๋ก ํธ์๋ ๊ธฐ๋ณธ ๊ตฌ์กฐ๊ฐ ์์ฑ๋์๋์ง ํ์ธํ์ธ์.
๊ธฐ๋ ๊ฒฐ๊ณผ: React 19 ํ๋ก ํธ์๋ ํ๋ก์ ํธ๊ฐ ์์ฑ๋๊ณ , Tailwind CSS๊ฐ ์ค์ ๋ฉ๋๋ค. ์์ ๋ชฉ๋ก์ด ์นด๋ ํํ๋ก ํ์๋๋ฉฐ, Laravel API์์ ๋ฐ์ดํฐ๋ฅผ ์ฑ๊ณต์ ์ผ๋ก ๊ฐ์ ธ์ต๋๋ค.
# ์ข์ ์ ํ UI ๊ตฌํ
`frontend/src` ํด๋์์ ์์
ํฉ๋๋ค.
1. `src/components/SeatMap.jsx` ์ปดํฌ๋ํธ ์์ฑ:
- props: `bookedSeats` (๋ฐฐ์ด), `selectedSeat` (๋ฌธ์์ด), `onSeatSelect` (ํจ์)
- ์ข์ ๋ฐฐ์น: 5ํ(A~E) x 6์ด(1~6) = 30์ ๊ทธ๋ฆฌ๋ ์์ฑ
- ๊ฐ ์ข์์ ๋ฒํผ์ผ๋ก ๋ ๋๋ง:
- ์์ฝ ๊ฐ๋ฅ: ํด๋ฆญ ์ `onSeatSelect` ํธ์ถ, ๋ฐฐ๊ฒฝ์ ํ์
- ์์ฝ ๋ถ๊ฐ๋ฅ (`bookedSeats`์ ํฌํจ): ํด๋ฆญ ๋ถ๊ฐ, ๋ฐฐ๊ฒฝ์ ๋นจ๊ฐ์, cursor-not-allowed
- ์ ํ๋ ์ข์ (`selectedSeat`): ๋ฐฐ๊ฒฝ์ ์ด๋ก์
- Tailwind CSS๋ก ๊ทธ๋ฆฌ๋ ๋ ์ด์์ (grid grid-cols-6 gap-2)
2. `src/App.jsx` ์์ :
- "์๋งคํ๊ธฐ" ๋ฒํผ ํด๋ฆญ ์:
- ์ ํํ ์์ ID๋ก `http://localhost:8000/api/screenings/{id}` ํธ์ถ
- ์๋ต์์ `screening` ์ ๋ณด์ `bookedSeats` ๋ฐฐ์ด ์ ์ฅ
- ์ข์ ์ ํ ํ๋ฉด์ผ๋ก ์ ํ (์กฐ๊ฑด๋ถ ๋ ๋๋ง)
- ์ํ ์ถ๊ฐ:
- `selectedScreening` (์ ํํ ์์ ์ ๋ณด)
- `bookedSeats` (์์ฝ๋ ์ข์ ๋ฐฐ์ด)
- `selectedSeat` (์ฌ์ฉ์๊ฐ ์ ํํ ์ข์)
- `SeatMap` ์ปดํฌ๋ํธ ๋ ๋๋ง:
- `onSeatSelect` ํจ์๋ก `selectedSeat` ์ํ ์
๋ฐ์ดํธ
3. ์ข์ ์ ํ ํ ์๋งค ํผ ํ์:
- ์ข์ ์ ํ ํ "๋ค์" ๋ฒํผ ํ์ฑํ
- ํด๋ฆญ ์ ์๋งค ํผ ํ์ (์ด๋ฆ, ์ด๋ฉ์ผ, ์ ํ๋ฒํธ ์
๋ ฅ ํ๋)
4. ์คํ์ผ๋ง:
- ์ข์ ๋ฒํผ: w-10 h-10, ํ
์คํธ ์ค์ ์ ๋ ฌ
- ๋ฒ๋ก ์ถ๊ฐ: ์์ฝ ๊ฐ๋ฅ(ํ์), ์์ฝ ๋ถ๊ฐ(๋นจ๊ฐ์), ์ ํ๋จ(์ด๋ก์)
๋ธ๋ผ์ฐ์ ์์ ์ข์ ์ ํ์ด ์ ์์ ์ผ๋ก ์๋ํ๋์ง ํ์ธํ์ธ์.
๊ธฐ๋ ๊ฒฐ๊ณผ: ์ข์ ๋ฐฐ์น๋๊ฐ 5x6 ๊ทธ๋ฆฌ๋๋ก ํ์๋๋ฉฐ, ์์ฝ ๊ฐ๋ฅ/๋ถ๊ฐ๋ฅ ์ข์์ด ์์์ผ๋ก ๊ตฌ๋ถ๋ฉ๋๋ค. ์ฌ์ฉ์๊ฐ ์ข์์ ํด๋ฆญํ๋ฉด ์ ํ ์ํ๊ฐ ์ด๋ก์์ผ๋ก ๋ณ๊ฒฝ๋๊ณ , ์๋งค ํผ์ผ๋ก ์งํํ ์ ์์ต๋๋ค.
# ์๋งค ํผ ์ ์ถ ๋ฐ ์๋งค ํ์ธ ํ์ด์ง
`frontend/src` ํด๋์์ ์์
ํฉ๋๋ค.
1. `src/components/BookingForm.jsx` ์ปดํฌ๋ํธ ์์ฑ:
- props: `screening` (์์ ์ ๋ณด), `selectedSeat` (์ ํํ ์ข์), `onSubmit` (ํจ์)
- ํผ ํ๋:
- ์ด๋ฆ (input text, required)
- ์ด๋ฉ์ผ (input email, required)
- ์ ํ๋ฒํธ (input tel, required)
- ์ ์ถ ๋ฒํผ: "์๋งค ์๋ฃ"
- ํผ ์ ์ถ ์ `onSubmit` ํจ์ ํธ์ถ (์
๋ ฅ๊ฐ ์ ๋ฌ)
2. `src/App.jsx` ์์ :
- `BookingForm` ์ปดํฌ๋ํธ ๋ ๋๋ง (์ข์ ์ ํ ํ)
- `handleBookingSubmit` ํจ์ ์์ฑ:
- axios POST ์์ฒญ: `http://localhost:8000/api/bookings`
- ์์ฒญ ๋ณธ๋ฌธ: { screening_id, seat_number, customer_name, customer_email, customer_phone }
- ์๋ต์์ ์๋งค ์ ๋ณด ๋ฐ์ `bookingConfirmation` ์ํ์ ์ ์ฅ
- ์๋งค ํ์ธ ํ์ด์ง๋ก ์ ํ
3. `src/components/BookingConfirmation.jsx` ์ปดํฌ๋ํธ ์์ฑ:
- props: `booking` (์๋งค ์ ๋ณด ๊ฐ์ฒด)
- ํ์ ๋ด์ฉ:
- "์๋งค๊ฐ ์๋ฃ๋์์ต๋๋ค!" ๋ฉ์์ง
- ์๋งค ๋ฒํธ (ํฐ ๊ธ์จ๋ก ๊ฐ์กฐ)
- ์ํ ์ ๋ชฉ, ์์ ๋ ์ง/์๊ฐ
- ์ข์ ๋ฒํธ
- ์๋งค์ ์ด๋ฆ, ์ด๋ฉ์ผ, ์ ํ๋ฒํธ
- "์ฒ์์ผ๋ก" ๋ฒํผ (์์ ๋ชฉ๋ก์ผ๋ก ๋์๊ฐ๊ธฐ)
4. `src/App.jsx`์์ ์กฐ๊ฑด๋ถ ๋ ๋๋ง:
- `bookingConfirmation` ์ํ๊ฐ ์์ผ๋ฉด `BookingConfirmation` ์ปดํฌ๋ํธ ํ์
- ์์ผ๋ฉด ์์ ๋ชฉ๋ก ๋๋ ์ข์ ์ ํ ํ๋ฉด ํ์
5. ์คํ์ผ๋ง:
- ํผ: ์ธ๋ก ๋ ์ด์์, ์
๋ ฅ ํ๋ ๊ฐ๊ฒฉ, ๋ผ๋ฒจ ์ถ๊ฐ
- ์๋งค ํ์ธ ํ์ด์ง: ์นด๋ ํํ, ์ค์ ์ ๋ ฌ, ๋ฐฐ๊ฒฝ์ ๊ตฌ๋ถ
6. ํ
์คํธ:
- ์์ ์ ํ โ ์ข์ ์ ํ โ ์๋งค ํผ ์์ฑ โ ์๋งค ์๋ฃ โ ํ์ธ ํ์ด์ง ํ์
- Laravel ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์๋งค ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋๋์ง ํ์ธ (SQLite ๋ธ๋ผ์ฐ์ ๋๋ `php artisan tinker`๋ก ํ์ธ)
์ ์ฒด ์๋งค ํ๋ฆ์ด ์ ์์ ์ผ๋ก ์๋ํ๋์ง ํ์ธํ์ธ์.
๊ธฐ๋ ๊ฒฐ๊ณผ: ์ฌ์ฉ์๊ฐ ์ข์์ ์ ํํ๊ณ ์๋งค ํผ์ ์์ฑํ๋ฉด, Laravel API๋ฅผ ํตํด ์๋งค๊ฐ ์์ฑ๋๊ณ ์๋งค ํ์ธ ํ์ด์ง๊ฐ ํ์๋ฉ๋๋ค. ์๋งค ๋ฒํธ, ์ํ ์ ๋ณด, ์ข์ ์ ๋ณด๊ฐ ๋ช ํํ๊ฒ ํ์๋ฉ๋๋ค.
# ์๋งค ๋ด์ญ ์กฐํ ๊ธฐ๋ฅ ์ถ๊ฐ ๋ฐ ์ต์ข
๋ง๋ฌด๋ฆฌ
`frontend/src` ํด๋์์ ์์
ํฉ๋๋ค.
1. `src/components/BookingLookup.jsx` ์ปดํฌ๋ํธ ์์ฑ:
- ์๋งค ๋ฒํธ ์
๋ ฅ ํ๋ (input text)
- "์กฐํ" ๋ฒํผ
- ๋ฒํผ ํด๋ฆญ ์ `http://localhost:8000/api/bookings/{bookingNumber}` GET ์์ฒญ
- ์๋ต ๋ฐ์ผ๋ฉด ์๋งค ์ ๋ณด ํ์ (BookingConfirmation ์ปดํฌ๋ํธ ์ฌ์ฌ์ฉ ๋๋ ์ ์ฌํ ๋ ์ด์์)
- ์๋งค๋ฅผ ์ฐพ์ ์ ์๋ ๊ฒฝ์ฐ ์๋ฌ ๋ฉ์์ง ํ์
2. `src/App.jsx` ์์ :
- ์์ ๋ชฉ๋ก ํ์ด์ง ์๋จ์ "์๋งค ์กฐํ" ๋งํฌ ๋๋ ๋ฒํผ ์ถ๊ฐ
- ํด๋ฆญ ์ `BookingLookup` ์ปดํฌ๋ํธ ํ์ (์กฐ๊ฑด๋ถ ๋ ๋๋ง)
- "๋ค๋ก ๊ฐ๊ธฐ" ๋ฒํผ์ผ๋ก ์์ ๋ชฉ๋ก์ผ๋ก ๋์๊ฐ๊ธฐ
3. ์๋ฌ ํธ๋ค๋ง ๊ฐ์ :
- API ์์ฒญ ์คํจ ์ ์ฌ์ฉ์์๊ฒ ์๋ฆผ (alert ๋๋ toast)
- ์ข์ ์ค๋ณต ์์ฝ ์๋ ์ Laravel์์ ์๋ฌ ๋ฐํ โ React์์ ์ฒ๋ฆฌ
4. UI/UX ๊ฐ์ :
- ๋ก๋ฉ ์ํ ํ์ (API ์์ฒญ ์ค ์คํผ๋ ๋๋ "๋ก๋ฉ ์ค..." ๋ฉ์์ง)
- ๋ฐ์ํ ๋์์ธ ํ์ธ (๋ชจ๋ฐ์ผ ํ๋ฉด์์๋ ์ ๋ณด์ด๋์ง)
- ํฌ์คํฐ ์ด๋ฏธ์ง ์๋ ๊ฒฝ์ฐ ํ๋ ์ด์คํ๋ ํ์
5. README.md ์์ฑ:
- ํ๋ก์ ํธ ์ค๋ช
- ์ค์น ๋ฐฉ๋ฒ:
```
# ๋ฐฑ์๋
cd backend
composer install
cp .env.example .env
php artisan key:generate
touch database/database.sqlite
php artisan migrate --seed
php artisan serve
# ํ๋ก ํธ์๋ (์ ํฐ๋ฏธ๋)
cd frontend
npm install
npm run dev
```
- ์ฌ์ฉ ๋ฐฉ๋ฒ (์คํฌ๋ฆฐ์ท ์ถ๊ฐ ๊ถ์ฅ)
- ๊ธฐ์ ์คํ ๋ช
์
6. ์ต์ข
ํ
์คํธ:
- ์ ์ฒด ์๋งค ํ๋ฆ (์์ ์ ํ โ ์ข์ ์ ํ โ ์๋งค โ ํ์ธ)
- ์๋งค ์กฐํ ๊ธฐ๋ฅ
- ์ค๋ณต ์ข์ ์์ฝ ์๋ (์๋ฌ ์ฒ๋ฆฌ ํ์ธ)
- ์ฌ๋ฌ ์์ ์ผ์ ์ ๋ํด ์๋งค ํ
์คํธ
7. Git ์ปค๋ฐ ๋ฐ GitHub ์
๋ก๋:
```bash
git init
git add .
git commit -m "Initial commit: ๋
๋ฆฝ์ํ ์์ํ ํฐ์ผ ์๋งค ์์คํ
"
git branch -M main
git remote add origin https://github.com/your-username/indie-film-screening-ticket-booking.git
git push -u origin main
```
ํ๋ก์ ํธ๊ฐ ์์ฑ๋์์ต๋๋ค! ๋ชจ๋ ๊ธฐ๋ฅ์ด ์ ์์ ์ผ๋ก ์๋ํ๋์ง ์ต์ข
ํ์ธํ์ธ์.
๊ธฐ๋ ๊ฒฐ๊ณผ: ์๋งค ๋ฒํธ๋ก ์๋งค ๋ด์ญ์ ์กฐํํ ์ ์๋ ๊ธฐ๋ฅ์ด ์ถ๊ฐ๋๊ณ , ์๋ฌ ํธ๋ค๋ง๊ณผ ๋ก๋ฉ ์ํ ํ์๊ฐ ๊ฐ์ ๋ฉ๋๋ค. README.md๊ฐ ์์ฑ๋์ด ํ๋ก์ ํธ ์ค์น ๋ฐ ์คํ ๋ฐฉ๋ฒ์ด ๋ช ํํด์ง๋๋ค. ์ ์ฒด ํ๋ก์ ํธ๊ฐ GitHub์ ์ ๋ก๋๋์ด ํฌํธํด๋ฆฌ์ค๋ก ํ์ฉํ ์ ์์ต๋๋ค.
์ ์ถ๋ ์ํ (0)
๋ก๊ทธ์ธ ํ ์ ์ถ์์ง ์ ์ถ๋ ์ํ์ด ์์ต๋๋ค. ์ฒซ ๋ฒ์งธ ๋์ ์๊ฐ ๋์ด๋ณด์ธ์!