Laravel 미니 쿠킹클래스 수강 신청 폼 - 정원 관리 & 자동 대기자 등록
cooking-class-registration-form
문제 설명
🍳 프로젝트 개요
요리 학원, 베이킹 클래스, 쿠킹 스튜디오를 운영하는 소규모 사업자를 위한 수강 신청 접수 페이지를 만듭니다. 고객이 원하는 클래스를 선택하고 신청서를 제출하면, 정원이 남아있으면 즉시 확정되고, 정원이 마감되었다면 자동으로 대기자 명단에 등록됩니다.
실제 쿠킹클래스 운영자가 바로 사용할 수 있도록 클래스 목록 페이지, 신청 폼, 신청 완료 페이지를 구현합니다. Laravel 13.x + Blade 템플릿 + Tailwind CSS로 깔끔한 UI를 제공하고, SQLite 데이터베이스로 간단하게 클래스 정보와 신청자 데이터를 관리합니다.
✅ 필수 기능
-
클래스 목록 페이지
- 운영 중인 쿠킹클래스 목록 표시 (예: 파스타 만들기, 베이킹 기초, 한식 반상 등)
- 각 클래스마다 이미지, 제목, 날짜, 시간, 정원, 현재 신청 인원 표시
- "신청하기" 버튼 (정원 마감 시 "대기 신청" 버튼으로 변경)
-
수강 신청 폼
- 신청자 이름, 이메일, 전화번호 입력
- 알레르기/식이 제한 사항 메모 (선택 입력)
- 개인정보 수집 동의 체크박스
- 제출 시 정원 체크 → 정원 내면 "확정", 초과면 "대기" 상태로 저장
-
신청 완료 페이지
- "신청이 확정되었습니다!" 또는 "대기자로 등록되었습니다" 메시지 표시
- 신청 정보 요약 (클래스명, 날짜, 신청자 정보)
- 클래스 목록으로 돌아가기 버튼
-
데이터베이스 구조
classes테이블: 클래스 정보 (제목, 설명, 날짜, 시간, 정원, 이미지 URL)registrations테이블: 신청 정보 (클래스 ID, 신청자 정보, 상태: confirmed/waiting)
-
UI/UX
- Tailwind CSS로 모바일 친화적 반응형 디자인
- 클래스 카드 레이아웃 (그리드 또는 리스트)
- 폼 검증 (필수 입력 항목 체크)
- 정원 마감 시 시각적 표시 (배지, 색상 변경)
🎁 선택 추가 기능 (보너스)
- 클래스 검색/필터 기능 (날짜별, 카테고리별)
- 신청 취소 기능 (이메일 링크로 취소 페이지 접근)
- 관리자 페이지: 신청자 명단 확인 및 대기자 → 확정 전환
- 이메일 알림: 신청 확정/대기 시 자동 이메일 발송 (Laravel Mail)
- 클래스 후기 남기기 (간단한 별점 + 한줄평)
🎯 학습 목표
- Laravel 13.x의 라우팅, 컨트롤러, 모델, 마이그레이션 기초 이해
- Blade 템플릿 문법 (조건문, 반복문, 컴포넌트)
- 폼 데이터 검증 (Validation)
- 데이터베이스 관계 (1:N - 클래스:신청자)
- Tailwind CSS로 빠른 UI 구축
- 실제 비즈니스 로직 구현 (정원 체크, 상태 관리)
제약 조건
- • Laravel 13.x 사용 (최신 버전 필수)
- • Blade 템플릿 엔진 사용 (React/Vue 등 SPA 프레임워크 사용 금지)
- • Tailwind CSS로 스타일링 (CDN 또는 Vite 빌드)
- • SQLite 데이터베이스 사용 (간단한 설정)
- • 최소 3개 이상의 샘플 클래스 데이터 시딩
- • 폼 검증 규칙 적용 (required, email, max 등)
- • 모바일 반응형 디자인 필수
프롬프트 레시피
아래 프롬프트를 순서대로 AI에게 보내면 됩니다. 복사 버튼을 눌러 바로 사용하세요.
mkdir cooking-class-registration-form && cd cooking-class-registration-form
이 폴더에서 Laravel 13.x 프로젝트를 시작합니다.
1. Laravel 13.x 프로젝트 생성:
```bash
composer create-project laravel/laravel . "^13.0"
```
2. .env 파일 설정:
- DB_CONNECTION=sqlite
- DB_DATABASE 경로를 database/database.sqlite로 설정
- database/database.sqlite 파일 생성 (touch 명령 또는 수동 생성)
3. Tailwind CSS 설치 및 설정:
```bash
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
```
- tailwind.config.js에서 content 경로 설정: `['./resources/**/*.blade.php', './resources/**/*.js']`
- resources/css/app.css에 Tailwind directives 추가:
```css
@tailwind base;
@tailwind components;
@tailwind utilities;
```
- vite.config.js 확인 (Laravel 기본 설정 유지)
4. 기본 레이아웃 Blade 파일 생성:
- resources/views/layouts/app.blade.php
- HTML 기본 구조, Tailwind CSS 로드 (@vite(['resources/css/app.css', 'resources/js/app.js']))
- 네비게이션 바 (로고, 클래스 목록 링크)
- @yield('content') 섹션
5. 웰컴 페이지 수정:
- resources/views/welcome.blade.php를 간단한 랜딩 페이지로 변경
- "쿠킹클래스 수강 신청" 타이틀과 "클래스 둘러보기" 버튼
6. 개발 서버 실행 확인:
```bash
php artisan serve
npm run dev
```
모든 설정이 완료되고 브라우저에서 http://localhost:8000 접속 시 Tailwind가 적용된 랜딩 페이지가 보여야 합니다.
기대 결과: Laravel 13.x 프로젝트 생성 완료, Tailwind CSS 설정 완료, 기본 레이아웃 Blade 파일 생성, SQLite 데이터베이스 연결 설정 완료. 개발 서버 실행 시 스타일이 적용된 랜딩 페이지가 표시됨.
데이터베이스 구조를 설계하고 마이그레이션 및 모델을 생성합니다.
1. `classes` 테이블 마이그레이션 생성:
```bash
php artisan make:migration create_classes_table
```
- 컬럼: id, title (string), description (text), class_date (date), class_time (time), capacity (integer, 정원), image_url (string, nullable), created_at, updated_at
2. `registrations` 테이블 마이그레이션 생성:
```bash
php artisan make:migration create_registrations_table
```
- 컬럼: id, class_id (foreignId, classes 테이블 참조), name (string), email (string), phone (string), dietary_notes (text, nullable), status (enum: 'confirmed', 'waiting'), created_at, updated_at
- foreignId 제약 조건: onDelete('cascade')
3. 마이그레이션 실행:
```bash
php artisan migrate
```
4. 모델 생성:
```bash
php artisan make:model ClassModel
php artisan make:model Registration
```
- ClassModel (app/Models/ClassModel.php):
- $fillable 배열에 모든 필드 추가
- registrations() 관계 메서드: hasMany(Registration::class, 'class_id')
- confirmedRegistrations() 메서드: registrations()->where('status', 'confirmed')
- isFull() 메서드: confirmedRegistrations()->count() >= $this->capacity
- Registration (app/Models/Registration.php):
- $fillable 배열에 모든 필드 추가
- classModel() 관계 메서드: belongsTo(ClassModel::class, 'class_id')
5. 시더 파일 생성 및 샘플 데이터 추가:
```bash
php artisan make:seeder ClassSeeder
```
- database/seeders/ClassSeeder.php에서 최소 3개의 샘플 클래스 생성
- 예시 데이터:
- "홈메이드 파스타 마스터 클래스" (정원 10명, 2024-02-15, 14:00)
- "프렌치 베이킹 기초" (정원 8명, 2024-02-20, 10:00)
- "한식 반상 차리기" (정원 12명, 2024-02-25, 11:00)
- image_url은 Unsplash 등 무료 이미지 URL 사용
6. DatabaseSeeder에서 ClassSeeder 호출:
```php
public function run() {
$this->call(ClassSeeder::class);
}
```
7. 시더 실행:
```bash
php artisan db:seed
```
데이터베이스 테이블이 생성되고 샘플 클래스 데이터가 입력되어야 합니다.
기대 결과: classes, registrations 테이블 마이그레이션 완료. ClassModel, Registration 모델 생성 및 관계 설정 완료. 최소 3개의 샘플 클래스 데이터가 데이터베이스에 시딩됨. isFull() 등 비즈니스 로직 메서드 구현 완료.
클래스 목록 페이지를 구현합니다.
1. 컨트롤러 생성:
```bash
php artisan make:controller ClassController
```
- app/Http/Controllers/ClassController.php
- index() 메서드:
- ClassModel::with('registrations')->get()으로 모든 클래스 조회 (N+1 방지)
- 각 클래스의 현재 신청 인원 계산 (confirmedRegistrations()->count())
- compact('classes')로 뷰에 전달
2. 라우트 등록:
- routes/web.php에 추가:
```php
use App\Http\Controllers\ClassController;
Route::get('/classes', [ClassController::class, 'index'])->name('classes.index');
```
3. 클래스 목록 뷰 생성:
- resources/views/classes/index.blade.php
- @extends('layouts.app')
- @section('content')
- 페이지 타이틀: "수강 가능한 쿠킹클래스"
- 클래스 목록을 그리드 레이아웃으로 표시 (Tailwind grid, md:grid-cols-2 lg:grid-cols-3)
- 각 클래스 카드:
- 이미지 (object-cover, rounded-t-lg)
- 제목 (text-xl font-bold)
- 날짜/시간 (text-gray-600)
- 정원 정보: "{{ $confirmedCount }}/{{ $class->capacity }}명" (진행 바 또는 배지)
- 조건부 버튼:
- 정원 마감 시: "대기 신청" 버튼 (bg-yellow-500)
- 정원 여유 시: "신청하기" 버튼 (bg-green-600)
- 버튼 클릭 시 신청 폼 페이지로 이동 (route('classes.register', $class->id))
4. 레이아웃 네비게이션 수정:
- resources/views/layouts/app.blade.php
- 네비게이션 바에 "클래스 목록" 링크 추가 (route('classes.index'))
5. 웰컴 페이지 버튼 연결:
- resources/views/welcome.blade.php
- "클래스 둘러보기" 버튼이 route('classes.index')로 이동하도록 수정
브라우저에서 /classes 접속 시 샘플 클래스 3개가 카드 형태로 표시되고, 각 카드에 신청 버튼이 보여야 합니다.
기대 결과: ClassController의 index() 메서드 구현 완료. classes/index.blade.php 뷰에서 클래스 목록이 그리드 레이아웃으로 표시됨. 각 클래스 카드에 이미지, 제목, 날짜, 정원 정보, 신청 버튼이 포함됨. 정원 마감 여부에 따라 버튼 텍스트와 색상이 변경됨.
수강 신청 폼 페이지를 구현합니다.
1. ClassController에 show() 메서드 추가:
- public function show($id)
- ClassModel::findOrFail($id)로 클래스 조회
- compact('class')로 뷰에 전달
2. 라우트 등록:
- routes/web.php에 추가:
```php
Route::get('/classes/{id}/register', [ClassController::class, 'show'])->name('classes.register');
Route::post('/classes/{id}/register', [ClassController::class, 'store'])->name('classes.store');
```
3. 신청 폼 뷰 생성:
- resources/views/classes/register.blade.php
- @extends('layouts.app')
- 클래스 정보 요약 표시 (제목, 날짜, 시간, 남은 자리)
- 폼 필드:
- 이름 (name, required)
- 이메일 (email, required, type="email")
- 전화번호 (phone, required)
- 알레르기/식이 제한 (dietary_notes, textarea, 선택)
- 개인정보 수집 동의 체크박스 (required)
- CSRF 토큰: @csrf
- 제출 버튼: "신청하기" (bg-blue-600)
- 취소 버튼: 클래스 목록으로 돌아가기
4. 폼 검증 및 저장 로직 (ClassController::store() 메서드):
- $request->validate() 규칙:
- name: required|string|max:100
- email: required|email
- phone: required|string
- dietary_notes: nullable|string
- ClassModel::findOrFail($id)로 클래스 조회
- 정원 체크:
- if ($class->isFull()): status = 'waiting'
- else: status = 'confirmed'
- Registration::create()로 신청 데이터 저장
- 성공 메시지와 함께 완료 페이지로 리다이렉트:
```php
return redirect()->route('classes.success', $registration->id)
->with('message', $status === 'confirmed' ? '신청이 확정되었습니다!' : '대기자로 등록되었습니다.');
```
5. 에러 메시지 표시:
- register.blade.php에 @error 디렉티브 추가 (각 필드 아래)
- Tailwind로 빨간색 에러 텍스트 스타일링
신청 폼이 정상적으로 표시되고, 필수 항목 누락 시 검증 에러가 표시되어야 합니다.
기대 결과: ClassController의 show(), store() 메서드 구현 완료. classes/register.blade.php 뷰에서 클래스 정보와 신청 폼이 표시됨. 폼 검증 규칙 적용 완료. 정원 체크 로직에 따라 confirmed 또는 waiting 상태로 데이터 저장됨. 에러 메시지가 각 필드 아래 표시됨.
신청 완료 페이지를 구현하고 전체 흐름을 테스트합니다.
1. ClassController에 success() 메서드 추가:
- public function success($registrationId)
- Registration::with('classModel')->findOrFail($registrationId)로 신청 정보 조회
- compact('registration')로 뷰에 전달
2. 라우트 등록:
- routes/web.php에 추가:
```php
Route::get('/classes/success/{registrationId}', [ClassController::class, 'success'])->name('classes.success');
```
3. 완료 페이지 뷰 생성:
- resources/views/classes/success.blade.php
- @extends('layouts.app')
- 성공 메시지 표시:
- if ($registration->status === 'confirmed'): "✅ 신청이 확정되었습니다!"
- else: "⏳ 대기자로 등록되었습니다. 자리가 나면 연락드리겠습니다."
- 신청 정보 요약 카드:
- 클래스명: {{ $registration->classModel->title }}
- 날짜/시간: {{ $registration->classModel->class_date }} {{ $registration->classModel->class_time }}
- 신청자 이름: {{ $registration->name }}
- 이메일: {{ $registration->email }}
- 전화번호: {{ $registration->phone }}
- 안내 문구:
- "신청하신 이메일로 자세한 안내를 보내드렸습니다."
- "궁금하신 사항은 고객센터로 문의해주세요."
- 버튼:
- "다른 클래스 보기" (route('classes.index'))
- "홈으로" (route('welcome'))
4. 웰컴 페이지 라우트 이름 추가:
- routes/web.php에서 기본 라우트에 이름 추가:
```php
Route::get('/', function () {
return view('welcome');
})->name('welcome');
```
5. 전체 흐름 테스트:
- 클래스 목록 → 신청 폼 → 제출 → 완료 페이지
- 정원 마감 클래스 테스트: 정원을 초과하여 신청 시 "대기자" 메시지 확인
- 폼 검증 테스트: 필수 항목 누락 시 에러 메시지 확인
6. UI 최종 다듬기:
- 모든 페이지에 일관된 Tailwind 스타일 적용
- 버튼 호버 효과 (hover:bg-xxx-700)
- 카드 그림자 효과 (shadow-lg)
- 반응형 레이아웃 확인 (모바일, 태블릿, 데스크톱)
7. README.md 작성:
- 프로젝트 소개
- 설치 방법 (composer install, npm install, .env 설정, migrate, seed)
- 실행 방법 (php artisan serve, npm run dev)
- 주요 기능 설명
- 스크린샷 추가 (선택)
모든 기능이 정상 작동하고, 사용자가 클래스 신청부터 완료까지 매끄럽게 진행할 수 있어야 합니다.
기대 결과: ClassController의 success() 메서드 구현 완료. classes/success.blade.php 뷰에서 신청 완료 메시지와 신청 정보 요약이 표시됨. 전체 사용자 흐름(목록 → 폼 → 완료)이 정상 작동함. 정원 마감 시 대기자 등록 로직 테스트 완료. UI가 모든 화면 크기에서 반응형으로 작동함. README.md 작성 완료.
제출된 작품 (0)
로그인 후 제출아직 제출된 작품이 없습니다. 첫 번째 도전자가 되어보세요!