๐ŸŽ“ ์˜จ๋ผ์ธ ์ˆ˜๊ฐ• ์‹ ์ฒญ ํผ - ๊ฐ•์ขŒ ์„ ํƒ๋ถ€ํ„ฐ ๊ฒฐ์ œ ์•ˆ๋‚ด๊นŒ์ง€ - ๋ฐ”์ด๋ธŒ์ฝ”๋”ฉ ๋ ˆ์‹œํ”ผ
์ž…๋ฌธ PHP Laravel AI: Claude

๐ŸŽ“ ์˜จ๋ผ์ธ ์ˆ˜๊ฐ• ์‹ ์ฒญ ํผ - ๊ฐ•์ขŒ ์„ ํƒ๋ถ€ํ„ฐ ๊ฒฐ์ œ ์•ˆ๋‚ด๊นŒ์ง€

๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ช… course-enrollment-form-laravel
์กฐํšŒ์ˆ˜ 53 0๊ฑด ์ œ์ถœ

๋ฌธ์ œ ์„ค๋ช…

๐Ÿ“š ํ”„๋กœ์ ํŠธ ์†Œ๊ฐœ

๊ต์œก ๊ธฐ๊ด€์ด๋‚˜ ํ•™์›, ์˜จ๋ผ์ธ ๊ฐ•์˜ ํ”Œ๋žซํผ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ˆ˜๊ฐ• ์‹ ์ฒญ ํผ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ๊ฐœ์„ค๋œ ๊ฐ•์ขŒ ๋ชฉ๋ก์„ ํ™•์ธํ•˜๊ณ , ์›ํ•˜๋Š” ๊ฐ•์ขŒ๋ฅผ ์„ ํƒํ•˜์—ฌ ์ˆ˜๊ฐ• ์‹ ์ฒญ์„œ๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. ์‹ ์ฒญ์ด ์™„๋ฃŒ๋˜๋ฉด ์ž๋™์œผ๋กœ ์‹ ์ฒญ ๋‚ด์—ญ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

โœ… ํ•„์ˆ˜ ๊ธฐ๋Šฅ

  • ๊ฐ•์ขŒ ๋ชฉ๋ก ํŽ˜์ด์ง€: ๊ฐœ์„ค๋œ ๊ฐ•์ขŒ ๋ฆฌ์ŠคํŠธ (์ œ๋ชฉ, ๊ฐ•์‚ฌ๋ช…, ์ˆ˜๊ฐ•๋ฃŒ, ์ •์›) ํ‘œ์‹œ
  • ์ˆ˜๊ฐ• ์‹ ์ฒญ ํผ: ์ด๋ฆ„, ์ด๋ฉ”์ผ, ์ „ํ™”๋ฒˆํ˜ธ, ์„ ํƒํ•œ ๊ฐ•์ขŒ ์ž…๋ ฅ
  • ์‹ ์ฒญ ๋‚ด์—ญ ์ €์žฅ: SQLite ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์‹ ์ฒญ ์ •๋ณด ์ €์žฅ
  • ์‹ ์ฒญ ์™„๋ฃŒ ํŽ˜์ด์ง€: ์‹ ์ฒญํ•œ ๊ฐ•์ขŒ ์ •๋ณด & ๊ฒฐ์ œ ์•ˆ๋‚ด ๋ฉ”์‹œ์ง€ ํ‘œ์‹œ
  • ๋ฐ˜์‘ํ˜• UI: Tailwind CSS๋กœ ๋ชจ๋ฐ”์ผ/๋ฐ์Šคํฌํ†ฑ ๋ชจ๋‘ ๊น”๋”ํ•˜๊ฒŒ

๐ŸŽ ์„ ํƒ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ (๋ณด๋„ˆ์Šค)

  • ๊ฐ•์ขŒ ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ (๊ฐ•์ขŒ๋ช…, ๊ฐ•์‚ฌ๋ช…์œผ๋กœ ํ•„ํ„ฐ๋ง)
  • ์ •์› ์ดˆ๊ณผ ์‹œ "๋งˆ๊ฐ" ๋ฐฐ์ง€ ํ‘œ์‹œ
  • ์‹ ์ฒญ ๋‚ด์—ญ ๋ชฉ๋ก ํŽ˜์ด์ง€ (๊ด€๋ฆฌ์ž์šฉ ๊ฐ„๋‹จ ๋ฆฌ์ŠคํŠธ)
  • ์ด๋ฉ”์ผ ํ˜•์‹ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ (Laravel Validation)
  • ์‹ ์ฒญ ์‹œ ์ž๋™์œผ๋กœ ๊ณ ์œ  ์‹ ์ฒญ๋ฒˆํ˜ธ ์ƒ์„ฑ

๐ŸŽฏ ํ•™์Šต ๋ชฉํ‘œ

  • Laravel 13.x ํ”„๋กœ์ ํŠธ ์ดˆ๊ธฐ ์„ค์ • (SQLite ์—ฐ๊ฒฐ)
  • Blade ํ…œํ”Œ๋ฆฟ์œผ๋กœ ํผ & ๋ฆฌ์ŠคํŠธ UI ๊ตฌ์„ฑ
  • ๋ผ์šฐํŠธ์™€ ์ปจํŠธ๋กค๋Ÿฌ๋กœ ์š”์ฒญ ์ฒ˜๋ฆฌ
  • Eloquent ๋ชจ๋ธ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค CRUD ์กฐ์ž‘
  • Tailwind CSS๋กœ ์‹ค์šฉ์ ์ธ UI ๋””์ž์ธ

์ œ์•ฝ ์กฐ๊ฑด

  • โ€ข Laravel 13.x ํ”„๋ ˆ์ž„์›Œํฌ ์‚ฌ์šฉ (์ตœ์‹  ๋ฒ„์ „ ํ•„์ˆ˜)
  • โ€ข Blade ํ…œํ”Œ๋ฆญ ์—”์ง„์œผ๋กœ UI ๊ตฌ์„ฑ (React/Vue ๋“ฑ SPA ๊ธˆ์ง€)
  • โ€ข SQLite ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์‚ฌ์šฉ (์„ค์ • ๊ฐ„๋‹จ, ํŒŒ์ผ ๊ธฐ๋ฐ˜)
  • โ€ข Tailwind CSS๋กœ ์Šคํƒ€์ผ๋ง (CDN ๋˜๋Š” Vite ๋นŒ๋“œ)
  • โ€ข ๋ผ์šฐํŠธ๋Š” web.php์— ์ •์˜
  • โ€ข ์ปจํŠธ๋กค๋Ÿฌ๋Š” app/Http/Controllers์— ์ž‘์„ฑ
  • โ€ข ๋ชจ๋ธ์€ app/Models์— ์ž‘์„ฑ
  • โ€ข ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํŒŒ์ผ๋กœ ํ…Œ์ด๋ธ” ์Šคํ‚ค๋งˆ ๊ด€๋ฆฌ

ํ”„๋กฌํ”„ํŠธ ๋ ˆ์‹œํ”ผ

์•„๋ž˜ ํ”„๋กฌํ”„ํŠธ๋ฅผ ์ˆœ์„œ๋Œ€๋กœ AI์—๊ฒŒ ๋ณด๋‚ด๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๋ณต์‚ฌ ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ๋ฐ”๋กœ ์‚ฌ์šฉํ•˜์„ธ์š”.

1
Step 1
mkdir course-enrollment-form-laravel && cd course-enrollment-form-laravel

์ด ํด๋”์—์„œ Laravel 13.x ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

Laravel 13.x ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ดˆ๊ธฐ ์„ค์ •์„ ์™„๋ฃŒํ•ด์ฃผ์„ธ์š”.

**์š”๊ตฌ์‚ฌํ•ญ:**
1. Laravel 13.x ์ตœ์‹  ๋ฒ„์ „์œผ๋กœ ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ (composer create-project laravel/laravel . ๋˜๋Š” Laravel installer ์‚ฌ์šฉ)
2. .env ํŒŒ์ผ์—์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ SQLite๋กœ ์„ค์ •:
   - DB_CONNECTION=sqlite
   - DB_DATABASE ๊ฒฝ๋กœ๋ฅผ database/database.sqlite๋กœ ์ง€์ •
   - database/database.sqlite ํŒŒ์ผ ์ƒ์„ฑ (touch database/database.sqlite ๋˜๋Š” ๋นˆ ํŒŒ์ผ ์ƒ์„ฑ)
3. Tailwind CSS ์„ค์ •:
   - npm install -D tailwindcss postcss autoprefixer
   - npx tailwindcss init -p
   - tailwind.config.js์˜ content ๋ฐฐ์—ด์— Blade ํŒŒ์ผ ๊ฒฝ๋กœ ์ถ”๊ฐ€: './resources/**/*.blade.php', './resources/**/*.js'
   - resources/css/app.css์— Tailwind ๋””๋ ‰ํ‹ฐ๋ธŒ ์ถ”๊ฐ€ (@tailwind base; @tailwind components; @tailwind utilities;)
4. Vite ๋นŒ๋“œ ์„ค์ • ํ™•์ธ (vite.config.js์—์„œ Laravel ํ”Œ๋Ÿฌ๊ทธ์ธ ์‚ฌ์šฉ)
5. npm install && npm run dev ์‹คํ–‰ํ•˜์—ฌ Tailwind ๋นŒ๋“œ ํ™•์ธ

**ํ™•์ธ ๋ฐฉ๋ฒ•:**
- php artisan serve ์‹คํ–‰ ์‹œ Laravel ๊ธฐ๋ณธ ํ™”๋ฉด์ด ์ •์ƒ์ ์œผ๋กœ ํ‘œ์‹œ๋˜์–ด์•ผ ํ•จ
- database/database.sqlite ํŒŒ์ผ์ด ์กด์žฌํ•ด์•ผ ํ•จ
- npm run dev ์‹คํ–‰ ์‹œ Tailwind CSS๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ๋นŒ๋“œ๋˜์–ด์•ผ ํ•จ

๊ธฐ๋Œ€ ๊ฒฐ๊ณผ: Laravel 13.x ํ”„๋กœ์ ํŠธ๊ฐ€ ์ƒ์„ฑ๋˜๊ณ , SQLite ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํŒŒ์ผ์ด ์ค€๋น„๋˜๋ฉฐ, Tailwind CSS๊ฐ€ ์„ค์ •๋˜์–ด ๊ฐœ๋ฐœ ์„œ๋ฒ„๊ฐ€ ์ •์ƒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

2
Step 2
์ˆ˜๊ฐ• ์‹ ์ฒญ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ…Œ์ด๋ธ”์„ ์„ค๊ณ„ํ•˜๊ณ  ์ƒ์„ฑํ•ด์ฃผ์„ธ์š”.

**์š”๊ตฌ์‚ฌํ•ญ:**
1. ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํŒŒ์ผ ์ƒ์„ฑ:
   - php artisan make:migration create_courses_table (๊ฐ•์ขŒ ํ…Œ์ด๋ธ”)
   - php artisan make:migration create_enrollments_table (์ˆ˜๊ฐ• ์‹ ์ฒญ ํ…Œ์ด๋ธ”)

2. **courses ํ…Œ์ด๋ธ” ์Šคํ‚ค๋งˆ** (database/migrations/xxxx_create_courses_table.php):
   - id: bigint, primary key, auto increment
   - title: string, ๊ฐ•์ขŒ๋ช… (์˜ˆ: "์›น ๊ฐœ๋ฐœ ๊ธฐ์ดˆ", "ํŒŒ์ด์ฌ ๋ฐ์ดํ„ฐ ๋ถ„์„")
   - instructor: string, ๊ฐ•์‚ฌ๋ช…
   - price: integer, ์ˆ˜๊ฐ•๋ฃŒ (์› ๋‹จ์œ„)
   - capacity: integer, ์ •์›
   - enrolled_count: integer, ํ˜„์žฌ ์‹ ์ฒญ ์ธ์› (๊ธฐ๋ณธ๊ฐ’ 0)
   - timestamps (created_at, updated_at)

3. **enrollments ํ…Œ์ด๋ธ” ์Šคํ‚ค๋งˆ** (database/migrations/xxxx_create_enrollments_table.php):
   - id: bigint, primary key, auto increment
   - course_id: bigint, foreign key โ†’ courses.id (onDelete cascade)
   - name: string, ์‹ ์ฒญ์ž ์ด๋ฆ„
   - email: string, ์‹ ์ฒญ์ž ์ด๋ฉ”์ผ
   - phone: string, ์‹ ์ฒญ์ž ์ „ํ™”๋ฒˆํ˜ธ
   - enrollment_number: string, ๊ณ ์œ  ์‹ ์ฒญ๋ฒˆํ˜ธ (์˜ˆ: "ENR-20250101-0001")
   - timestamps

4. ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์‹คํ–‰:
   - php artisan migrate

5. ์‹œ๋”(Seeder) ์ƒ์„ฑํ•˜์—ฌ ํ…Œ์ŠคํŠธ ๊ฐ•์ขŒ ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€:
   - php artisan make:seeder CourseSeeder
   - CourseSeeder์—์„œ 5๊ฐœ ์ •๋„์˜ ์ƒ˜ํ”Œ ๊ฐ•์ขŒ ๋ฐ์ดํ„ฐ ์‚ฝ์ž… (์ œ๋ชฉ, ๊ฐ•์‚ฌ, ์ˆ˜๊ฐ•๋ฃŒ, ์ •์› ๋‹ค์–‘ํ•˜๊ฒŒ)
   - DatabaseSeeder์—์„œ CourseSeeder ํ˜ธ์ถœ
   - php artisan db:seed

**ํ™•์ธ ๋ฐฉ๋ฒ•:**
- php artisan migrate ์‹คํ–‰ ํ›„ ์—๋Ÿฌ ์—†์ด ์™„๋ฃŒ
- database/database.sqlite ํŒŒ์ผ์„ SQLite ๋ทฐ์–ด๋กœ ์—ด์–ด courses, enrollments ํ…Œ์ด๋ธ” ํ™•์ธ
- php artisan db:seed ์‹คํ–‰ ํ›„ courses ํ…Œ์ด๋ธ”์— ์ƒ˜ํ”Œ ๋ฐ์ดํ„ฐ๊ฐ€ ์‚ฝ์ž…๋˜์–ด ์žˆ์–ด์•ผ ํ•จ

๊ธฐ๋Œ€ ๊ฒฐ๊ณผ: courses์™€ enrollments ํ…Œ์ด๋ธ”์ด ์ƒ์„ฑ๋˜๊ณ , courses ํ…Œ์ด๋ธ”์— ์ƒ˜ํ”Œ ๊ฐ•์ขŒ ๋ฐ์ดํ„ฐ 5๊ฐœ๊ฐ€ ์‚ฝ์ž…๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

3
Step 3
๊ฐ•์ขŒ ๋ชฉ๋ก์„ ๋ณด์—ฌ์ฃผ๋Š” ๋ฉ”์ธ ํŽ˜์ด์ง€์™€ ์ˆ˜๊ฐ• ์‹ ์ฒญ ํผ ํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“ค์–ด์ฃผ์„ธ์š”.

**์š”๊ตฌ์‚ฌํ•ญ:**
1. **๋ชจ๋ธ ์ƒ์„ฑ**:
   - php artisan make:model Course (์ด๋ฏธ ์žˆ๋‹ค๋ฉด ์Šคํ‚ต)
   - php artisan make:model Enrollment
   - Course ๋ชจ๋ธ์—์„œ fillable ์†์„ฑ์— ['title', 'instructor', 'price', 'capacity', 'enrolled_count'] ์ถ”๊ฐ€
   - Enrollment ๋ชจ๋ธ์—์„œ fillable ์†์„ฑ์— ['course_id', 'name', 'email', 'phone', 'enrollment_number'] ์ถ”๊ฐ€
   - Course์™€ Enrollment ๊ฐ„ ๊ด€๊ณ„ ์„ค์ •:
     - Course ๋ชจ๋ธ: public function enrollments() { return $this->hasMany(Enrollment::class); }
     - Enrollment ๋ชจ๋ธ: public function course() { return $this->belongsTo(Course::class); }

2. **์ปจํŠธ๋กค๋Ÿฌ ์ƒ์„ฑ**:
   - php artisan make:controller CourseController
   - CourseController์— index() ๋ฉ”์„œ๋“œ ์ž‘์„ฑ: ๋ชจ๋“  ๊ฐ•์ขŒ ๋ชฉ๋ก์„ ๊ฐ€์ ธ์™€ courses.index ๋ทฐ๋กœ ์ „๋‹ฌ
   - CourseController์— enroll() ๋ฉ”์„œ๋“œ ์ž‘์„ฑ: ํŠน์ • ๊ฐ•์ขŒ ID๋ฅผ ๋ฐ›์•„ ํ•ด๋‹น ๊ฐ•์ขŒ ์ •๋ณด๋ฅผ courses.enroll ๋ทฐ๋กœ ์ „๋‹ฌ

3. **๋ผ์šฐํŠธ ์„ค์ •** (routes/web.php):
   - GET / โ†’ CourseController@index (๊ฐ•์ขŒ ๋ชฉ๋ก ํŽ˜์ด์ง€)
   - GET /courses/{id}/enroll โ†’ CourseController@enroll (์ˆ˜๊ฐ• ์‹ ์ฒญ ํผ ํŽ˜์ด์ง€)

4. **Blade ๋ทฐ ์ƒ์„ฑ**:

   **resources/views/layout.blade.php** (๊ณตํ†ต ๋ ˆ์ด์•„์›ƒ):
   - <!DOCTYPE html> ๊ธฐ๋ณธ ๊ตฌ์กฐ
   - <head>์— Tailwind CSS ๋กœ๋“œ (@vite(['resources/css/app.css', 'resources/js/app.js']))
   - <body>์— ์ƒ๋‹จ ๋„ค๋น„๊ฒŒ์ด์…˜ ๋ฐ” (์‚ฌ์ดํŠธ ๋กœ๊ณ  "์ˆ˜๊ฐ•์‹ ์ฒญ ์‹œ์Šคํ…œ", ํ™ˆ ๋งํฌ)
   - @yield('content')๋กœ ๋ณธ๋ฌธ ์˜์—ญ ์ง€์ •
   - ํ‘ธํ„ฐ (ยฉ 2025 ์ˆ˜๊ฐ•์‹ ์ฒญ ์‹œ์Šคํ…œ)

   **resources/views/courses/index.blade.php** (๊ฐ•์ขŒ ๋ชฉ๋ก ํŽ˜์ด์ง€):
   - @extends('layout')
   - ํŽ˜์ด์ง€ ์ œ๋ชฉ: "๊ฐœ์„ค ๊ฐ•์ขŒ ๋ชฉ๋ก"
   - ๊ฐ•์ขŒ ๋ฆฌ์ŠคํŠธ๋ฅผ ์นด๋“œ ํ˜•ํƒœ๋กœ ํ‘œ์‹œ (Tailwind grid, md:grid-cols-2, lg:grid-cols-3)
   - ๊ฐ ์นด๋“œ:
     - ๊ฐ•์ขŒ๋ช… (ํ…์ŠคํŠธ ํฌ๊ธฐ lg, ๊ตต๊ฒŒ)
     - ๊ฐ•์‚ฌ๋ช… (ํšŒ์ƒ‰ ํ…์ŠคํŠธ)
     - ์ˆ˜๊ฐ•๋ฃŒ (์› ๋‹จ์œ„, ์ฒœ ๋‹จ์œ„ ์ฝค๋งˆ ํ‘œ์‹œ)
     - ์ •์› ์ •๋ณด: "์ •์› {{$course->capacity}}๋ช… / ์‹ ์ฒญ {{$course->enrolled_count}}๋ช…"
     - ์ •์› ์ดˆ๊ณผ ์‹œ "๋งˆ๊ฐ" ๋ฐฐ์ง€ ํ‘œ์‹œ (๋นจ๊ฐ„ ๋ฐฐ๊ฒฝ, ํฐ ๊ธ€์”จ)
     - "์ˆ˜๊ฐ• ์‹ ์ฒญ" ๋ฒ„ํŠผ (ํŒŒ๋ž€ ๋ฐฐ๊ฒฝ, ํฐ ๊ธ€์”จ, ์ •์› ์ดˆ๊ณผ ์‹œ ๋น„ํ™œ์„ฑํ™” & ํšŒ์ƒ‰)
     - ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ /courses/{id}/enroll๋กœ ์ด๋™ (a ํƒœ๊ทธ)

   **resources/views/courses/enroll.blade.php** (์ˆ˜๊ฐ• ์‹ ์ฒญ ํผ ํŽ˜์ด์ง€):
   - @extends('layout')
   - ํŽ˜์ด์ง€ ์ œ๋ชฉ: "์ˆ˜๊ฐ• ์‹ ์ฒญ์„œ ์ž‘์„ฑ"
   - ์„ ํƒํ•œ ๊ฐ•์ขŒ ์ •๋ณด ํ‘œ์‹œ (๊ฐ•์ขŒ๋ช…, ๊ฐ•์‚ฌ๋ช…, ์ˆ˜๊ฐ•๋ฃŒ) - ์ฝ๊ธฐ ์ „์šฉ ๋ฐ•์Šค
   - ์‹ ์ฒญ ํผ (POST /enrollments):
     - @csrf
     - hidden input: course_id (์„ ํƒํ•œ ๊ฐ•์ขŒ ID)
     - ์ด๋ฆ„ ์ž…๋ ฅ (required)
     - ์ด๋ฉ”์ผ ์ž…๋ ฅ (required, type="email")
     - ์ „ํ™”๋ฒˆํ˜ธ ์ž…๋ ฅ (required)
     - ์ œ์ถœ ๋ฒ„ํŠผ: "์‹ ์ฒญ ์™„๋ฃŒ" (ํŒŒ๋ž€ ๋ฐฐ๊ฒฝ, ํฐ ๊ธ€์”จ)
   - Tailwind๋กœ ํผ ์Šคํƒ€์ผ๋ง (input ๋ฐ•์Šค, ๋ผ๋ฒจ, ๊ฐ„๊ฒฉ ๋“ฑ)

**ํ™•์ธ ๋ฐฉ๋ฒ•:**
- php artisan serve๋กœ ์„œ๋ฒ„ ์‹คํ–‰
- ๋ธŒ๋ผ์šฐ์ €์—์„œ http://localhost:8000 ์ ‘์† ์‹œ ๊ฐ•์ขŒ ๋ชฉ๋ก ํŽ˜์ด์ง€๊ฐ€ ํ‘œ์‹œ๋˜์–ด์•ผ ํ•จ
- ๊ฐ•์ขŒ ์นด๋“œ๊ฐ€ ๊ทธ๋ฆฌ๋“œ๋กœ ์ •๋ ฌ๋˜๊ณ , ์ˆ˜๊ฐ•๋ฃŒ์— ์ฒœ ๋‹จ์œ„ ์ฝค๋งˆ๊ฐ€ ํ‘œ์‹œ๋˜์–ด์•ผ ํ•จ
- "์ˆ˜๊ฐ• ์‹ ์ฒญ" ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ /courses/{id}/enroll ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๊ณ  ํผ์ด ํ‘œ์‹œ๋˜์–ด์•ผ ํ•จ

๊ธฐ๋Œ€ ๊ฒฐ๊ณผ: ๊ฐ•์ขŒ ๋ชฉ๋ก ํŽ˜์ด์ง€์™€ ์ˆ˜๊ฐ• ์‹ ์ฒญ ํผ ํŽ˜์ด์ง€๊ฐ€ Tailwind CSS๋กœ ๊น”๋”ํ•˜๊ฒŒ ๋””์ž์ธ๋˜์–ด ํ‘œ์‹œ๋˜๋ฉฐ, ์‚ฌ์šฉ์ž๊ฐ€ ๊ฐ•์ขŒ๋ฅผ ์„ ํƒํ•˜๊ณ  ์‹ ์ฒญ ํผ์œผ๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

4
Step 4
์ˆ˜๊ฐ• ์‹ ์ฒญ ํผ ์ œ์ถœ ์ฒ˜๋ฆฌ ๋กœ์ง๊ณผ ์‹ ์ฒญ ์™„๋ฃŒ ํŽ˜์ด์ง€๋ฅผ ๊ตฌํ˜„ํ•ด์ฃผ์„ธ์š”.

**์š”๊ตฌ์‚ฌํ•ญ:**
1. **์ปจํŠธ๋กค๋Ÿฌ ๋ฉ”์„œ๋“œ ์ถ”๊ฐ€** (CourseController):
   - store() ๋ฉ”์„œ๋“œ ์ž‘์„ฑ:
     - POST /enrollments ์š”์ฒญ ์ฒ˜๋ฆฌ
     - ์š”์ฒญ ๋ฐ์ดํ„ฐ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ (Laravel Validation):
       - name: required, string, max:255
       - email: required, email
       - phone: required, string
       - course_id: required, exists:courses,id
     - ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ ์‹œ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€์™€ ํ•จ๊ป˜ ์ด์ „ ํŽ˜์ด์ง€๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ (withErrors, withInput)
     - ์„ ํƒํ•œ ๊ฐ•์ขŒ์˜ ์ •์› ํ™•์ธ:
       - enrolled_count >= capacity์ธ ๊ฒฝ์šฐ "์ •์› ์ดˆ๊ณผ" ์—๋Ÿฌ ๋ฉ”์‹œ์ง€์™€ ํ•จ๊ป˜ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
     - ๊ณ ์œ  ์‹ ์ฒญ๋ฒˆํ˜ธ ์ƒ์„ฑ:
       - ํ˜•์‹: "ENR-" + ์˜ค๋Š˜ ๋‚ ์งœ(Ymd) + "-" + 4์ž๋ฆฌ ๋žœ๋ค ์ˆซ์ž
       - ์˜ˆ: "ENR-20250601-1234"
     - Enrollment ๋ชจ๋ธ๋กœ ์‹ ์ฒญ ๋ฐ์ดํ„ฐ ์ €์žฅ
     - ํ•ด๋‹น ๊ฐ•์ขŒ์˜ enrolled_count 1 ์ฆ๊ฐ€ (Course::find($course_id)->increment('enrolled_count'))
     - ์‹ ์ฒญ ์™„๋ฃŒ ํŽ˜์ด์ง€๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ (/enrollments/{id}/success)

   - success() ๋ฉ”์„œ๋“œ ์ž‘์„ฑ:
     - GET /enrollments/{id}/success ์š”์ฒญ ์ฒ˜๋ฆฌ
     - ์‹ ์ฒญ ID๋กœ Enrollment ๋ฐ์ดํ„ฐ ์กฐํšŒ (with('course')๋กœ ๊ฐ•์ขŒ ์ •๋ณด๋„ ํ•จ๊ป˜)
     - courses.success ๋ทฐ๋กœ ์ „๋‹ฌ

2. **๋ผ์šฐํŠธ ์ถ”๊ฐ€** (routes/web.php):
   - POST /enrollments โ†’ CourseController@store
   - GET /enrollments/{id}/success โ†’ CourseController@success

3. **Blade ๋ทฐ ์ƒ์„ฑ**:

   **resources/views/courses/success.blade.php** (์‹ ์ฒญ ์™„๋ฃŒ ํŽ˜์ด์ง€):
   - @extends('layout')
   - ํŽ˜์ด์ง€ ์ œ๋ชฉ: "์ˆ˜๊ฐ• ์‹ ์ฒญ ์™„๋ฃŒ"
   - ์„ฑ๊ณต ๋ฉ”์‹œ์ง€: "โœ… ์ˆ˜๊ฐ• ์‹ ์ฒญ์ด ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค!"
   - ์‹ ์ฒญ ์ •๋ณด ๋ฐ•์Šค (์—ฐ๋‘์ƒ‰ ๋ฐฐ๊ฒฝ):
     - ์‹ ์ฒญ๋ฒˆํ˜ธ: {{$enrollment->enrollment_number}}
     - ๊ฐ•์ขŒ๋ช…: {{$enrollment->course->title}}
     - ๊ฐ•์‚ฌ: {{$enrollment->course->instructor}}
     - ์ˆ˜๊ฐ•๋ฃŒ: {{number_format($enrollment->course->price)}}์›
     - ์‹ ์ฒญ์ž ์ด๋ฆ„: {{$enrollment->name}}
     - ์ด๋ฉ”์ผ: {{$enrollment->email}}
     - ์ „ํ™”๋ฒˆํ˜ธ: {{$enrollment->phone}}
   - ๊ฒฐ์ œ ์•ˆ๋‚ด ๋ฉ”์‹œ์ง€:
     - "์•„๋ž˜ ๊ณ„์ขŒ๋กœ ์ˆ˜๊ฐ•๋ฃŒ๋ฅผ ์ž…๊ธˆํ•ด์ฃผ์„ธ์š”."
     - ์€ํ–‰: ๊ตญ๋ฏผ์€ํ–‰
     - ๊ณ„์ขŒ๋ฒˆํ˜ธ: 123-456-789012
     - ์˜ˆ๊ธˆ์ฃผ: (์ฃผ)์ˆ˜๊ฐ•์‹ ์ฒญ์‹œ์Šคํ…œ
     - ์ž…๊ธˆ ์‹œ ์‹ ์ฒญ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.
   - "๊ฐ•์ขŒ ๋ชฉ๋ก์œผ๋กœ ๋Œ์•„๊ฐ€๊ธฐ" ๋ฒ„ํŠผ (ํ™ˆ์œผ๋กœ ์ด๋™)

   **resources/views/courses/enroll.blade.php ์ˆ˜์ •**:
   - ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ํ‘œ์‹œ (@error ๋””๋ ‰ํ‹ฐ๋ธŒ ์‚ฌ์šฉ)
   - ๊ฐ ์ž…๋ ฅ ํ•„๋“œ ์•„๋ž˜์— ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ํ‘œ์‹œ (๋นจ๊ฐ„ ํ…์ŠคํŠธ)

**ํ™•์ธ ๋ฐฉ๋ฒ•:**
- ์ˆ˜๊ฐ• ์‹ ์ฒญ ํผ์—์„œ ์ด๋ฆ„, ์ด๋ฉ”์ผ, ์ „ํ™”๋ฒˆํ˜ธ ์ž…๋ ฅ ํ›„ "์‹ ์ฒญ ์™„๋ฃŒ" ๋ฒ„ํŠผ ํด๋ฆญ
- ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ํ†ต๊ณผ ์‹œ ์‹ ์ฒญ ์™„๋ฃŒ ํŽ˜์ด์ง€(/enrollments/{id}/success)๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
- ์‹ ์ฒญ ์ •๋ณด(์‹ ์ฒญ๋ฒˆํ˜ธ, ๊ฐ•์ขŒ๋ช…, ์‹ ์ฒญ์ž ์ •๋ณด)๊ฐ€ ์ •ํ™•ํžˆ ํ‘œ์‹œ๋˜์–ด์•ผ ํ•จ
- database/database.sqlite์—์„œ enrollments ํ…Œ์ด๋ธ”์— ์‹ ์ฒญ ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋˜์–ด ์žˆ์–ด์•ผ ํ•จ
- courses ํ…Œ์ด๋ธ”์˜ enrolled_count๊ฐ€ 1 ์ฆ๊ฐ€ํ•ด์•ผ ํ•จ
- ์ด๋ฉ”์ผ ํ˜•์‹ ์˜ค๋ฅ˜ ์‹œ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๊ฐ€ ํ‘œ์‹œ๋˜์–ด์•ผ ํ•จ
- ์ •์› ์ดˆ๊ณผ ๊ฐ•์ขŒ ์‹ ์ฒญ ์‹œ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๊ฐ€ ํ‘œ์‹œ๋˜์–ด์•ผ ํ•จ

๊ธฐ๋Œ€ ๊ฒฐ๊ณผ: ์ˆ˜๊ฐ• ์‹ ์ฒญ ํผ ์ œ์ถœ ์‹œ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๊ฐ€ ์ˆ˜ํ–‰๋˜๊ณ , ์‹ ์ฒญ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅ๋˜๋ฉฐ, ์‹ ์ฒญ ์™„๋ฃŒ ํŽ˜์ด์ง€์—์„œ ์‹ ์ฒญ ์ •๋ณด์™€ ๊ฒฐ์ œ ์•ˆ๋‚ด๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ์ •์› ์ดˆ๊ณผ ์‹œ ์‹ ์ฒญ์ด ์ฐจ๋‹จ๋ฉ๋‹ˆ๋‹ค.

์ œ์ถœ๋œ ์ž‘ํ’ˆ (0)

๋กœ๊ทธ์ธ ํ›„ ์ œ์ถœ

์•„์ง ์ œ์ถœ๋œ ์ž‘ํ’ˆ์ด ์—†์Šต๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ๋„์ „์ž๊ฐ€ ๋˜์–ด๋ณด์„ธ์š”!

๋Œ“๊ธ€ (0)

๋กœ๊ทธ์ธ ํ›„ ๋Œ“๊ธ€์„ ๋‚จ๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์•„์ง ๋Œ“๊ธ€์ด ์—†์Šต๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ๋Œ“๊ธ€์„ ๋‚จ๊ฒจ๋ณด์„ธ์š”!