๐ ํธ๋ํธ๋ญ ๋ฉ๋ดํ & ์ค์๊ฐ ์ฃผ๋ฌธ ์ ์ ์์คํ
food-truck-menu-order-system
๋ฌธ์ ์ค๋ช
๐ ํ๋ก์ ํธ ๊ฐ์
ํธ๋ํธ๋ญ ์ด์์๋ฅผ ์ํ ๋์งํธ ๋ฉ๋ดํ๊ณผ ์ฃผ๋ฌธ ์ ์ ์์คํ ์ ๋ง๋ญ๋๋ค. ๊ณ ๊ฐ์ด QR ์ฝ๋๋ฅผ ์ค์บํ์ฌ ๋ฉ๋ด๋ฅผ ๋ณด๊ณ ์ฃผ๋ฌธํ๋ฉด, ์ด์์๋ ์ค์๊ฐ์ผ๋ก ์ฃผ๋ฌธ์ ํ์ธํ๊ณ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
โจ ํ์ ๊ธฐ๋ฅ
๊ณ ๊ฐ ํ๋ฉด (Public)
- ๐ฑ ํธ๋ํธ๋ญ ๋ฉ๋ดํ ์กฐํ (์นดํ ๊ณ ๋ฆฌ๋ณ ํํฐ๋ง)
- ๐ผ๏ธ ๋ฉ๋ด ์ด๋ฏธ์ง์ ์์ธ ์ค๋ช , ๊ฐ๊ฒฉ ํ์
- ๐ ์ฅ๋ฐ๊ตฌ๋์ ๋ฉ๋ด ์ถ๊ฐ/์ ๊ฑฐ
- ๐ ์ฃผ๋ฌธ์ ์์ฑ (๊ณ ๊ฐ ์ด๋ฆ, ์ฐ๋ฝ์ฒ, ํน๋ณ ์์ฒญ์ฌํญ)
- โ ์ฃผ๋ฌธ ์๋ฃ ํ ์ฃผ๋ฌธ๋ฒํธ ๋ฐ๊ธ
- ๐ ์ฃผ๋ฌธ๋ฒํธ๋ก ์ฃผ๋ฌธ ์ํ ์กฐํ (๋๊ธฐ์ค/์กฐ๋ฆฌ์ค/์๋ฃ)
์ด์์ ํ๋ฉด (Protected)
- ๐ ๊ฐ๋จํ ๋ก๊ทธ์ธ (Laravel Breeze ์ธ์ฆ)
- ๐ ์ค์๊ฐ ์ฃผ๋ฌธ ๋ชฉ๋ก (์ ์ฃผ๋ฌธ ์๋ ํ์)
- ๐จ ์ฃผ๋ฌธ ์ํ ๋ณ๊ฒฝ (๋๊ธฐ์ค โ ์กฐ๋ฆฌ์ค โ ์๋ฃ)
- ๐ ๋ฉ๋ด ๊ด๋ฆฌ (์ถ๊ฐ/์์ /์ญ์ /ํ์ ํ์)
- ๐ ์ค๋์ ์ฃผ๋ฌธ ํต๊ณ (์ด ์ฃผ๋ฌธ ์, ๋งค์ถ์ก)
๐ ๋ณด๋์ค ๊ธฐ๋ฅ
- ๐ท๏ธ ์ธ๊ธฐ ๋ฉ๋ด ๋ฑ์ง (์ฃผ๋ฌธ ํ์ ๊ธฐ๋ฐ)
- โฐ ์์ ์กฐ๋ฆฌ ์๊ฐ ํ์
- ๐ถ๏ธ ๋งต๊ธฐ ๋จ๊ณ ์ ํ ์ต์
- ๐ซ ์ฃผ๋ฌธ ์๋ฃ ์ ์๋ SMS/์ด๋ฉ์ผ ์๋ฆผ
- ๐ ์ฃผ๊ฐ/์๊ฐ ๋งค์ถ ํต๊ณ ์ฐจํธ
- ๐จ๏ธ ์ฃผ๋ฌธ์ ํ๋ฆฐํธ ๊ธฐ๋ฅ
๐ฏ ํ์ต ๋ชฉํ
- Laravel 13.x + Inertia.js + React 19 ๋ชจ๋ ธ๋ฆฌ์ค ์ํคํ ์ฒ
- Eloquent ORM ๊ด๊ณ ์ค์ (๋ฉ๋ด-์นดํ ๊ณ ๋ฆฌ, ์ฃผ๋ฌธ-์ฃผ๋ฌธํญ๋ชฉ)
- Laravel Breeze ์ธ์ฆ ์์คํ ํ์ฉ
- React ์ํ ๊ด๋ฆฌ (์ฅ๋ฐ๊ตฌ๋ ๋ก์ง)
- Inertia.js ํผ ์ฒ๋ฆฌ ๋ฐ ๊ฒ์ฆ
- ์ค์๊ฐ ๋ฐ์ดํฐ ๊ฐฑ์ (ํด๋ง ๋๋ Inertia ์๋ ๋ฆฌํ๋ ์)
- ์ด๋ฏธ์ง ์ ๋ก๋ ๋ฐ ์คํ ๋ฆฌ์ง ๊ด๋ฆฌ
- ๋ฐ์ํ ๋์์ธ (๋ชจ๋ฐ์ผ ์ต์ ํ)
์ ์ฝ ์กฐ๊ฑด
- โข Laravel 13.x + Inertia.js + React 19 ๋ชจ๋ ธ๋ฆฌ์ค ๊ตฌ์กฐ ์ฌ์ฉ
- โข Laravel Breeze (React + Inertia) starter kit์ผ๋ก ํ๋ก์ ํธ ์์ฑ
- โข SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฌ์ฉ (๊ฐ๋ฐ ํธ์์ฑ)
- โข Tailwind CSS๋ก ์คํ์ผ๋ง
- โข ๋ณ๋ REST API ๋ผ์ฐํธ ์์ด Inertia::render()๋ก ๋ฐ์ดํฐ ์ ๋ฌ
- โข ์ด๋ฏธ์ง ์ ๋ก๋๋ Laravel Storage ์ฌ์ฉ (public disk)
- โข ์ค์๊ฐ ์ฑํ ๊ธ์ง - HTTP ํด๋ง ๋๋ ํ์ด์ง ์๋ก๊ณ ์นจ์ผ๋ก ์ฃผ๋ฌธ ์ ๋ฐ์ดํธ
- โข ๋ชจ๋ฐ์ผ ์ฐ์ ๋ฐ์ํ ๋์์ธ (ํธ๋ํธ๋ญ ํ์ฅ ์ฌ์ฉ ๊ณ ๋ ค)
- โข ์ฃผ๋ฌธ๋ฒํธ๋ 6์๋ฆฌ ๋๋ค ์ฝ๋ ์์ฑ (์: F7K2M9)
ํ๋กฌํํธ ๋ ์ํผ
์๋ ํ๋กฌํํธ๋ฅผ ์์๋๋ก AI์๊ฒ ๋ณด๋ด๋ฉด ๋ฉ๋๋ค. ๋ณต์ฌ ๋ฒํผ์ ๋๋ฌ ๋ฐ๋ก ์ฌ์ฉํ์ธ์.
mkdir food-truck-menu-order-system && cd food-truck-menu-order-system ์ด ํด๋์์ ํธ๋ํธ๋ญ ๋ฉ๋ดํ & ์ฃผ๋ฌธ ์์คํ ํ๋ก์ ํธ๋ฅผ ์์ํฉ๋๋ค. Laravel 13.x + Inertia.js + React 19 ํ๋ก์ ํธ๋ฅผ ์์ฑํด์ฃผ์ธ์: ```bash npx create-laravel@latest . --breeze --stack=react --no-interaction ``` ํ๋ก์ ํธ ์์ฑ ํ ๋ค์ ์ค์ ์ ํด์ฃผ์ธ์: 1. `.env` ํ์ผ์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ SQLite๋ก ์ค์ : ``` DB_CONNECTION=sqlite ``` 2. `database/database.sqlite` ํ์ผ ์์ฑ 3. ๊ธฐ๋ณธ ๋ง์ด๊ทธ๋ ์ด์ ์คํ: ```bash php artisan migrate ``` 4. ๊ฐ๋ฐ ์๋ฒ ์คํ: ```bash php artisan serve # ๋ณ๋ ํฐ๋ฏธ๋์์ npm run dev ``` ํ๋ก์ ํธ๊ฐ ์ ์์ ์ผ๋ก ์คํ๋๋์ง ํ์ธํ๊ณ , Laravel Breeze์ ๊ธฐ๋ณธ ์ธ์ฆ ํ๋ฉด์ด ํ์๋๋์ง ํ ์คํธํด์ฃผ์ธ์.
๊ธฐ๋ ๊ฒฐ๊ณผ: Laravel 13.x + Breeze(React+Inertia) ํ๋ก์ ํธ๊ฐ ์์ฑ๋๊ณ , SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ๋ฐ ๊ธฐ๋ณธ ์ธ์ฆ ์์คํ ์ด ์๋ํฉ๋๋ค. http://localhost:8000 ์์ ์ฐ์ปด ํ์ด์ง์ ๋ก๊ทธ์ธ/ํ์๊ฐ์ ๋งํฌ๊ฐ ๋ณด์ ๋๋ค.
ํธ๋ํธ๋ญ ์์คํ ์ ์ํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์คํค๋ง๋ฅผ ์ค๊ณํ๊ณ ๋ง์ด๊ทธ๋ ์ด์ ์ ์์ฑํด์ฃผ์ธ์. ํ์ํ ํ ์ด๋ธ: 1. **categories** (๋ฉ๋ด ์นดํ ๊ณ ๋ฆฌ) - id (PK) - name (string, ์นดํ ๊ณ ๋ฆฌ๋ช ์: '๋ฉ์ธ๋ฉ๋ด', '์ฌ์ด๋', '์๋ฃ') - display_order (integer, ์ ๋ ฌ ์์) - timestamps 2. **menu_items** (๋ฉ๋ด ํญ๋ชฉ) - id (PK) - category_id (FK to categories) - name (string, ๋ฉ๋ด๋ช ) - description (text, ์ค๋ช ) - price (decimal, ๊ฐ๊ฒฉ) - image_path (string, nullable, ์ด๋ฏธ์ง ๊ฒฝ๋ก) - is_available (boolean, default true, ํ์ ์ฌ๋ถ) - is_popular (boolean, default false, ์ธ๊ธฐ ๋ฉ๋ด) - timestamps 3. **orders** (์ฃผ๋ฌธ) - id (PK) - order_number (string, unique, 6์๋ฆฌ ์ฝ๋) - customer_name (string, ๊ณ ๊ฐ๋ช ) - customer_phone (string, ์ฐ๋ฝ์ฒ) - status (enum: 'pending', 'preparing', 'completed', default 'pending') - special_request (text, nullable, ํน๋ณ ์์ฒญ์ฌํญ) - total_amount (decimal, ์ด ๊ธ์ก) - timestamps 4. **order_items** (์ฃผ๋ฌธ ํญ๋ชฉ) - id (PK) - order_id (FK to orders) - menu_item_id (FK to menu_items) - quantity (integer, ์๋) - price (decimal, ์ฃผ๋ฌธ ๋น์ ๊ฐ๊ฒฉ) - timestamps ๋ง์ด๊ทธ๋ ์ด์ ํ์ผ์ ์์ฑํ๊ณ ์คํํด์ฃผ์ธ์: ```bash php artisan make:migration create_food_truck_tables php artisan migrate ``` ๋ํ ๊ฐ ํ ์ด๋ธ์ ๋์ํ๋ Eloquent ๋ชจ๋ธ์ ์์ฑํ๊ณ , ๊ด๊ณ๋ฅผ ์ค์ ํด์ฃผ์ธ์: - Category hasMany MenuItem - MenuItem belongsTo Category - Order hasMany OrderItem - OrderItem belongsTo Order, belongsTo MenuItem
๊ธฐ๋ ๊ฒฐ๊ณผ: 4๊ฐ์ ํ ์ด๋ธ์ด ์์ฑ๋๊ณ , Category, MenuItem, Order, OrderItem ๋ชจ๋ธ์ด ์์ฑ๋์ด ๊ด๊ณ๊ฐ ์ค์ ๋ฉ๋๋ค. ๋ง์ด๊ทธ๋ ์ด์ ์ด ์ฑ๊ณต์ ์ผ๋ก ์คํ๋ฉ๋๋ค.
์๋(Seeder)๋ฅผ ์์ฑํ์ฌ ์ด๊ธฐ ๋ฐ์ดํฐ๋ฅผ ์
๋ ฅํด์ฃผ์ธ์.
`database/seeders/FoodTruckSeeder.php` ํ์ผ์ ์์ฑํ๊ณ ๋ค์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์
:
**์นดํ
๊ณ ๋ฆฌ:**
- ๋ฉ์ธ๋ฉ๋ด (display_order: 1)
- ์ฌ์ด๋ (display_order: 2)
- ์๋ฃ (display_order: 3)
**๋ฉ๋ด ํญ๋ชฉ (๊ฐ ์นดํ
๊ณ ๋ฆฌ๋ณ 3~4๊ฐ):**
๋ฉ์ธ๋ฉ๋ด:
- ์น์ฆ๋ฒ๊ฑฐ - 9,000์ (์ธ๊ธฐ๋ฉ๋ด)
- ๋ฒ ์ด์ปจ๋ฒ๊ฑฐ - 10,500์
- ์์ฐ๋ฒ๊ฑฐ - 11,000์
- ์นํจํ
๋ - 8,500์
์ฌ์ด๋:
- ๊ฐ์ํ๊น - 3,500์ (์ธ๊ธฐ๋ฉ๋ด)
- ์ด๋์ธ๋ง - 4,000์
- ์น์ฆ์คํฑ - 4,500์
์๋ฃ:
- ์ฝ๋ผ - 2,000์
- ์ฌ์ด๋ค - 2,000์
- ์์ด์คํฐ - 2,500์
์๋ ์คํ:
```bash
php artisan make:seeder FoodTruckSeeder
php artisan db:seed --class=FoodTruckSeeder
```
๋ฐ์ดํฐ๊ฐ ์ ์์ ์ผ๋ก ๋ค์ด๊ฐ๋์ง tinker๋ก ํ์ธ:
```bash
php artisan tinker
App\Models\MenuItem::with('category')->get();
```
๊ธฐ๋ ๊ฒฐ๊ณผ: ์นดํ ๊ณ ๋ฆฌ 3๊ฐ์ ๋ฉ๋ด ํญ๋ชฉ 11๊ฐ๊ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฝ์ ๋ฉ๋๋ค. tinker์์ ๋ฐ์ดํฐ ์กฐํ ์ ๊ด๊ณ๊ฐ ์ ์์ ์ผ๋ก ๋ก๋๋ฉ๋๋ค.
๊ณ ๊ฐ์ฉ ๋ฉ๋ดํ ํ์ด์ง๋ฅผ ๊ตฌํํด์ฃผ์ธ์.
**๋ผ์ฐํธ ์ค์ (routes/web.php):**
```php
Route::get('/', [MenuController::class, 'index'])->name('menu.index');
Route::get('/menu/{menuItem}', [MenuController::class, 'show'])->name('menu.show');
```
**์ปจํธ๋กค๋ฌ ์์ฑ:**
```bash
php artisan make:controller MenuController
```
MenuController์์:
- `index()`: ๋ชจ๋ ์นดํ
๊ณ ๋ฆฌ์ ๋ฉ๋ด ํญ๋ชฉ์ ๋ก๋ํ์ฌ Inertia::render('Menu/Index')๋ก ์ ๋ฌ
- `show($menuItem)`: ํน์ ๋ฉ๋ด ์์ธ ์ ๋ณด๋ฅผ Inertia::render('Menu/Show')๋ก ์ ๋ฌ
**React ์ปดํฌ๋ํธ ์์ฑ (resources/js/Pages/Menu/):**
1. `Index.jsx`: ๋ฉ๋ดํ ๋ฉ์ธ ํ์ด์ง
- ์นดํ
๊ณ ๋ฆฌ ํญ (๊ฐ๋ก ์คํฌ๋กค ๊ฐ๋ฅ)
- ์นดํ
๊ณ ๋ฆฌ๋ณ ๋ฉ๋ด ๊ทธ๋ฆฌ๋ (์ด๋ฏธ์ง, ์ด๋ฆ, ๊ฐ๊ฒฉ)
- ์ธ๊ธฐ ๋ฉ๋ด์ ๐ฅ ๋ฑ์ง ํ์
- ํ์ ๋ฉ๋ด๋ ๋ฐํฌ๋ช
์ฒ๋ฆฌ
- ๊ฐ ๋ฉ๋ด ํด๋ฆญ ์ ์ฅ๋ฐ๊ตฌ๋ ์ถ๊ฐ ๋ฒํผ ๋ชจ๋ฌ
2. `Show.jsx`: ๋ฉ๋ด ์์ธ ํ์ด์ง (์ ํ์ฌํญ)
Tailwind CSS๋ก ๋ชจ๋ฐ์ผ ์ต์ ํ ๋์์ธ:
- ์๋จ์ ํธ๋ํธ๋ญ ๋ก๊ณ /์ด๋ฆ
- ์นดํ
๊ณ ๋ฆฌ ํญ์ sticky header
- ๋ฉ๋ด ์นด๋๋ 2์ด ๊ทธ๋ฆฌ๋ (sm: 1์ด)
- ๊ฐ๊ฒฉ์ ๊ฐ์กฐ ํ์
์ฅ๋ฐ๊ตฌ๋ ์ํ ๊ด๋ฆฌ:
- React useState๋ก ์ฅ๋ฐ๊ตฌ๋ ๋ฐฐ์ด ๊ด๋ฆฌ
- ํ๋จ์ ๊ณ ์ ๋ '์ฃผ๋ฌธํ๊ธฐ' ๋ฒํผ (์ฅ๋ฐ๊ตฌ๋ ํญ๋ชฉ ์ ํ์)
์์ง ์ฃผ๋ฌธ ๊ธฐ๋ฅ์ ๊ตฌํํ์ง ๋ง๊ณ , ์ฅ๋ฐ๊ตฌ๋์ ๋ด๋ UI๋ง ์์ฑํด์ฃผ์ธ์.
๊ธฐ๋ ๊ฒฐ๊ณผ: ๋ฉ๋ดํ ํ์ด์ง๊ฐ ํ์๋๊ณ , ์นดํ ๊ณ ๋ฆฌ๋ณ๋ก ๋ฉ๋ด๊ฐ ์ ๋ ฌ๋์ด ๋ณด์ ๋๋ค. ์ฅ๋ฐ๊ตฌ๋์ ๋ฉ๋ด๋ฅผ ์ถ๊ฐ/์ ๊ฑฐํ ์ ์๊ณ , ํ๋จ ๋ฒํผ์ ์ฅ๋ฐ๊ตฌ๋ ํญ๋ชฉ ์๊ฐ ํ์๋ฉ๋๋ค. ์ธ๊ธฐ ๋ฉ๋ด์ ํ์ ๋ฉ๋ด๊ฐ ์๊ฐ์ ์ผ๋ก ๊ตฌ๋ถ๋ฉ๋๋ค.
์ฃผ๋ฌธ ์์ฑ ๊ธฐ๋ฅ์ ๊ตฌํํด์ฃผ์ธ์.
**๋ผ์ฐํธ ์ถ๊ฐ (routes/web.php):**
```php
Route::post('/orders', [OrderController::class, 'store'])->name('orders.store');
Route::get('/orders/{orderNumber}', [OrderController::class, 'show'])->name('orders.show');
```
**์ปจํธ๋กค๋ฌ ์์ฑ:**
```bash
php artisan make:controller OrderController
```
OrderController์์:
1. `store()` ๋ฉ์๋:
- ์์ฒญ ๋ฐ์ดํฐ ๊ฒ์ฆ (customer_name, customer_phone, cart items ํ์)
- 6์๋ฆฌ ๋๋ค ์ฃผ๋ฌธ๋ฒํธ ์์ฑ (์: strtoupper(Str::random(6)))
- Order ๋ ์ฝ๋ ์์ฑ (status: 'pending')
- OrderItem ๋ ์ฝ๋๋ค ์์ฑ (๊ฐ ์ฅ๋ฐ๊ตฌ๋ ํญ๋ชฉ)
- total_amount ๊ณ์ฐ ๋ฐ ์
๋ฐ์ดํธ
- ์์ฑ๋ ์ฃผ๋ฌธ๋ฒํธ๋ฅผ ๋ฐํํ์ฌ ์ฃผ๋ฌธ ์๋ฃ ํ์ด์ง๋ก ๋ฆฌ๋ค์ด๋ ํธ
2. `show($orderNumber)` ๋ฉ์๋:
- ์ฃผ๋ฌธ๋ฒํธ๋ก Order ์กฐํ (with orderItems, menuItems)
- Inertia::render('Orders/Show')๋ก ์ฃผ๋ฌธ ์์ธ ์ ๋ฌ
**React ์ปดํฌ๋ํธ:**
1. `Menu/Index.jsx` ์์ :
- '์ฃผ๋ฌธํ๊ธฐ' ๋ฒํผ ํด๋ฆญ ์ ์ฃผ๋ฌธ์ ์์ฑ ๋ชจ๋ฌ ํ์
- ๋ชจ๋ฌ์์ ๊ณ ๊ฐ๋ช
, ์ฐ๋ฝ์ฒ, ํน๋ณ ์์ฒญ์ฌํญ ์
๋ ฅ ํผ
- Inertia.post('/orders', formData)๋ก ์ฃผ๋ฌธ ์ ์ก
- ์ฃผ๋ฌธ ์๋ฃ ์ ์ฃผ๋ฌธ๋ฒํธ ํ์ด์ง๋ก ์ด๋
2. `Orders/Show.jsx` ์์ฑ:
- ์ฃผ๋ฌธ๋ฒํธ ํฐ ๊ธ์จ๋ก ํ์
- ์ฃผ๋ฌธ ์ํ (๋๊ธฐ์ค/์กฐ๋ฆฌ์ค/์๋ฃ) ๋ฑ์ง
- ์ฃผ๋ฌธ ํญ๋ชฉ ๋ชฉ๋ก (๋ฉ๋ด๋ช
, ์๋, ๊ฐ๊ฒฉ)
- ์ด ๊ธ์ก
- ๊ณ ๊ฐ ์ ๋ณด
- ํน๋ณ ์์ฒญ์ฌํญ
- '๋ฉ๋ดํ์ผ๋ก ๋์๊ฐ๊ธฐ' ๋ฒํผ
์ฃผ๋ฌธ ์๋ฃ ํ์ด์ง๋ ๊ณ ๊ฐ์ด ๋ถ๋งํฌํ์ฌ ๋์ค์ ์ฃผ๋ฌธ ์ํ๋ฅผ ํ์ธํ ์ ์๋๋ก URL์ ๊ณต์ ๊ฐ๋ฅํ๊ฒ ๋ง๋ค์ด์ฃผ์ธ์.
๊ธฐ๋ ๊ฒฐ๊ณผ: ๊ณ ๊ฐ์ด ์ฅ๋ฐ๊ตฌ๋์ ๋ด์ ๋ฉ๋ด๋ก ์ฃผ๋ฌธ์ ์์ฑํ ์ ์์ต๋๋ค. ์ฃผ๋ฌธ ์๋ฃ ์ ์ฃผ๋ฌธ๋ฒํธ๊ฐ ๋ฐ๊ธ๋๊ณ , ํด๋น ํ์ด์ง์์ ์ฃผ๋ฌธ ์์ธ ์ ๋ณด๋ฅผ ํ์ธํ ์ ์์ต๋๋ค. ์ฃผ๋ฌธ ๋ฐ์ดํฐ๊ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์์ ์ผ๋ก ์ ์ฅ๋ฉ๋๋ค.
์ด์์์ฉ ์ฃผ๋ฌธ ๊ด๋ฆฌ ํ์ด์ง๋ฅผ ๊ตฌํํด์ฃผ์ธ์.
**๋ผ์ฐํธ ์ถ๊ฐ (routes/web.php):**
```php
Route::middleware(['auth'])->group(function () {
Route::get('/admin/orders', [AdminOrderController::class, 'index'])->name('admin.orders.index');
Route::patch('/admin/orders/{order}/status', [AdminOrderController::class, 'updateStatus'])->name('admin.orders.updateStatus');
Route::get('/admin/dashboard', [AdminOrderController::class, 'dashboard'])->name('admin.dashboard');
});
```
**์ปจํธ๋กค๋ฌ ์์ฑ:**
```bash
php artisan make:controller AdminOrderController
```
AdminOrderController์์:
1. `index()`: ์ค๋์ ์ฃผ๋ฌธ ๋ชฉ๋ก์ ์ต์ ์์ผ๋ก ์กฐํ (with orderItems, menuItems), Inertia::render('Admin/Orders/Index')๋ก ์ ๋ฌ
2. `updateStatus(Order $order)`: ์ฃผ๋ฌธ ์ํ ์
๋ฐ์ดํธ (pending โ preparing โ completed), ๊ฒ์ฆ ํ ์ ์ฅ
3. `dashboard()`: ์ค๋์ ํต๊ณ (์ด ์ฃผ๋ฌธ ์, ๋งค์ถ์ก, ์ํ๋ณ ์ฃผ๋ฌธ ์), Inertia::render('Admin/Dashboard')๋ก ์ ๋ฌ
**React ์ปดํฌ๋ํธ (resources/js/Pages/Admin/):**
1. `Orders/Index.jsx`:
- ์ํ๋ณ ํญ (์ ์ฒด/๋๊ธฐ์ค/์กฐ๋ฆฌ์ค/์๋ฃ)
- ์ฃผ๋ฌธ ์นด๋ ๋ชฉ๋ก (์ฃผ๋ฌธ๋ฒํธ, ๊ณ ๊ฐ๋ช
, ์ฃผ๋ฌธ ํญ๋ชฉ ์์ฝ, ์ด์ก, ์๊ฐ)
- ๊ฐ ์ฃผ๋ฌธ ์นด๋์ ์ํ ๋ณ๊ฒฝ ๋ฒํผ (๋๊ธฐ์ค โ ์กฐ๋ฆฌ์ค, ์กฐ๋ฆฌ์ค โ ์๋ฃ)
- Inertia.patch()๋ก ์ํ ์
๋ฐ์ดํธ
- ์๋ ์๋ก๊ณ ์นจ (์ ํ์ฌํญ: 30์ด๋ง๋ค Inertia.reload())
2. `Dashboard.jsx`:
- ์ค๋์ ํต๊ณ ์นด๋ (์ด ์ฃผ๋ฌธ, ๋งค์ถ์ก, ์๋ฃ์จ)
- ์ต๊ทผ ์ฃผ๋ฌธ ๋ชฉ๋ก (์ต์ 10๊ฐ)
- '์ฃผ๋ฌธ ๊ด๋ฆฌ๋ก ์ด๋' ๋ฒํผ
**๋ค๋น๊ฒ์ด์
์์ :**
- Breeze์ ๊ธฐ๋ณธ ๋ค๋น๊ฒ์ด์
์ '์ฃผ๋ฌธ ๊ด๋ฆฌ', '๋์๋ณด๋' ๋งํฌ ์ถ๊ฐ
- ๋ก๊ทธ์ธ ํ์๋ง ํ์
Tailwind CSS๋ก ๊ด๋ฆฌ์ UI ์คํ์ผ๋ง:
- ์ฃผ๋ฌธ ์นด๋๋ ์ํ์ ๋ฐ๋ผ ์์ ๊ตฌ๋ถ (pending: yellow, preparing: blue, completed: green)
- ์ํ ๋ณ๊ฒฝ ๋ฒํผ์ ํฌ๊ณ ๋์ ๋๊ฒ
- ํต๊ณ ์นด๋๋ ๊ทธ๋ฆฌ๋ ๋ ์ด์์
๊ธฐ๋ ๊ฒฐ๊ณผ: ์ด์์๊ฐ ๋ก๊ทธ์ธ ํ ์ฃผ๋ฌธ ๋ชฉ๋ก์ ํ์ธํ๊ณ , ๊ฐ ์ฃผ๋ฌธ์ ์ํ๋ฅผ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค. ๋์๋ณด๋์์ ์ค๋์ ํต๊ณ๋ฅผ ํ๋์ ๋ณผ ์ ์์ต๋๋ค. ์ฃผ๋ฌธ ์ํ๊ฐ ๋ณ๊ฒฝ๋๋ฉด ๊ณ ๊ฐ์ฉ ์ฃผ๋ฌธ ์กฐํ ํ์ด์ง์๋ ๋ฐ์๋ฉ๋๋ค.
์ ์ถ๋ ์ํ (0)
๋ก๊ทธ์ธ ํ ์ ์ถ์์ง ์ ์ถ๋ ์ํ์ด ์์ต๋๋ค. ์ฒซ ๋ฒ์งธ ๋์ ์๊ฐ ๋์ด๋ณด์ธ์!