풀스택 취미 클래스 수강 신청 폼 - 실시간 잔여석 확인 - 바이브코딩 레시피
입문 PHP + JavaScript Laravel + React AI: Claude

풀스택 취미 클래스 수강 신청 폼 - 실시간 잔여석 확인

리포지토리명 hobby-class-enrollment-form
조회수 58 0건 제출

문제 설명

🎨 프로젝트 개요

요가, 베이킹, 도예 등 취미 클래스를 운영하는 소규모 비즈니스를 위한 수강 신청 접수 페이지를 만듭니다. 고객이 원하는 클래스를 선택하고 이름, 연락처, 희망 시간대를 입력하면 신청 내역이 저장되고, 실시간으로 남은 자리 수가 업데이트됩니다.

✅ 필수 기능

  • 클래스 목록 표시: 클래스명, 강사명, 정원, 현재 신청 인원, 남은 자리 수 표시
  • 수강 신청 폼: 이름, 전화번호, 이메일, 희망 시간대 선택
  • 실시간 잔여석 업데이트: 신청 완료 시 해당 클래스의 남은 자리 수 자동 감소
  • 신청 완료 알림: 신청 성공 시 화면에 "신청이 완료되었습니다!" 메시지 표시
  • 마감 표시: 정원이 다 찬 클래스는 "마감" 배지 표시 및 신청 버튼 비활성화

🎁 선택 추가 기능 (보너스)

  • 클래스 카테고리별 필터링 (예: 운동, 요리, 공예)
  • 신청 내역 확인 페이지 (이메일로 조회)
  • 대기자 등록 기능 (마감된 클래스 대기 신청)
  • 신청 시 자동 확인 이메일 발송 (Laravel Mail 사용)
  • 모바일 반응형 디자인

🛠 기술 스택

  • 백엔드: Laravel 13.x (RESTful API)
  • 프론트엔드: React 19 (Vite)
  • 데이터베이스: SQLite
  • 스타일링: Tailwind CSS

이 프로젝트를 통해 Laravel API와 React 프론트엔드를 연동하는 기본적인 풀스택 개발 흐름을 익힐 수 있습니다.

제약 조건

  • • Laravel 13.x 최신 버전 사용 (구버전 절대 금지)
  • • React 19 최신 버전 사용
  • • SQLite 데이터베이스 사용 (설치 간편)
  • • Laravel은 API 서버로만 사용 (routes/api.php에 라우트 정의)
  • • React는 별도 Vite 프로젝트로 구성 (fetch 또는 axios로 API 호출)
  • • CORS 설정 필수 (Laravel에서 React 프론트엔드 접근 허용)
  • • Tailwind CSS로 깔끔한 UI 구성
  • • useState만 사용 (복잡한 상태관리 라이브러리 금지)
  • • 실시간 채팅 기능 금지 (HTTP 기반 폼 제출만 사용)

프롬프트 레시피

아래 프롬프트를 순서대로 AI에게 보내면 됩니다. 복사 버튼을 눌러 바로 사용하세요.

1
Step 1
mkdir hobby-class-enrollment-form && cd hobby-class-enrollment-form

이 폴더에서 프로젝트를 시작합니다.

## Laravel 13.x API 백엔드 설정

1. Laravel 13.x 프로젝트를 생성하세요:
   ```bash
   composer create-project laravel/laravel backend
   cd backend
   ```

2. `.env` 파일을 열고 데이터베이스를 SQLite로 변경하세요:
   ```
   DB_CONNECTION=sqlite
   # DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD 주석 처리
   ```

3. `database/database.sqlite` 빈 파일을 생성하세요:
   ```bash
   touch database/database.sqlite
   ```

4. CORS 설정을 위해 `config/cors.php` 파일을 열고 다음과 같이 수정하세요:
   ```php
   'paths' => ['api/*'],
   'allowed_origins' => ['http://localhost:5173'],
   'allowed_methods' => ['*'],
   'allowed_headers' => ['*'],
   'supports_credentials' => false,
   ```

5. 다음 명령어로 마이그레이션을 실행하세요:
   ```bash
   php artisan migrate
   ```

6. Laravel 개발 서버를 실행하세요:
   ```bash
   php artisan serve
   ```

Laravel이 `http://localhost:8000`에서 실행되는지 확인하세요.

기대 결과: Laravel 13.x 프로젝트가 생성되고, SQLite 데이터베이스가 설정되며, CORS가 활성화되고, 개발 서버가 정상 실행됩니다. 브라우저에서 http://localhost:8000 접속 시 Laravel 기본 페이지가 표시됩니다.

2
Step 2
## 클래스 모델 및 마이그레이션 생성

1. `HobbyClass` 모델과 마이그레이션을 생성하세요:
   ```bash
   php artisan make:model HobbyClass -m
   ```

2. `database/migrations/xxxx_create_hobby_classes_table.php` 파일을 열고 다음 컬럼을 추가하세요:
   - `name` (string): 클래스명
   - `instructor` (string): 강사명
   - `category` (string): 카테고리 (예: 운동, 요리, 공예)
   - `capacity` (integer): 정원
   - `enrolled_count` (integer, default 0): 현재 신청 인원
   - `time_slot` (string): 시간대 (예: "매주 화요일 19:00")

3. 마이그레이션을 실행하세요:
   ```bash
   php artisan migrate
   ```

4. `Enrollment` 모델과 마이그레이션을 생성하세요 (수강 신청 내역 저장):
   ```bash
   php artisan make:model Enrollment -m
   ```

5. `database/migrations/xxxx_create_enrollments_table.php` 파일을 열고 다음 컬럼을 추가하세요:
   - `hobby_class_id` (foreignId): 클래스 ID (외래키)
   - `student_name` (string): 신청자 이름
   - `phone` (string): 전화번호
   - `email` (string): 이메일
   - `preferred_time` (string): 희망 시간대

6. 마이그레이션을 실행하세요:
   ```bash
   php artisan migrate
   ```

7. `database/seeders/DatabaseSeeder.php` 파일을 열고 샘플 클래스 데이터를 시딩하세요:
   ```php
   \App\Models\HobbyClass::create([
       'name' => '초보자 요가 클래스',
       'instructor' => '김요가',
       'category' => '운동',
       'capacity' => 10,
       'enrolled_count' => 3,
       'time_slot' => '매주 화요일 19:00',
   ]);
   
   \App\Models\HobbyClass::create([
       'name' => '홈베이킹 기초',
       'instructor' => '박베이킹',
       'category' => '요리',
       'capacity' => 8,
       'enrolled_count' => 8,
       'time_slot' => '매주 목요일 14:00',
   ]);
   
   \App\Models\HobbyClass::create([
       'name' => '도자기 만들기',
       'instructor' => '이도예',
       'category' => '공예',
       'capacity' => 6,
       'enrolled_count' => 2,
       'time_slot' => '매주 토요일 10:00',
   ]);
   ```

8. 시더를 실행하세요:
   ```bash
   php artisan db:seed
   ```

기대 결과: HobbyClass와 Enrollment 모델이 생성되고, 마이그레이션이 실행되며, 샘플 클래스 데이터 3개가 데이터베이스에 저장됩니다.

3
Step 3
## Laravel API 라우트 및 컨트롤러 생성

1. API 컨트롤러를 생성하세요:
   ```bash
   php artisan make:controller Api/HobbyClassController
   ```

2. `app/Http/Controllers/Api/HobbyClassController.php` 파일을 열고 다음 메서드를 작성하세요:

   - `index()`: 모든 클래스 목록 반환 (남은 자리 수 계산 포함)
   - `store()`: 수강 신청 접수 (Enrollment 생성 및 enrolled_count 증가)

   각 클래스 객체에 `available_seats` 필드를 추가하세요 (capacity - enrolled_count).

3. `routes/api.php` 파일을 열고 다음 라우트를 추가하세요:
   ```php
   Route::get('/classes', [HobbyClassController::class, 'index']);
   Route::post('/enrollments', [HobbyClassController::class, 'store']);
   ```

4. `store()` 메서드에서는 다음을 검증하세요:
   - 클래스가 존재하는지
   - 정원이 남아있는지 (enrolled_count < capacity)
   - 필수 입력값 (student_name, phone, email, preferred_time) 존재 여부

5. 신청 성공 시 해당 클래스의 `enrolled_count`를 1 증가시키고, 업데이트된 클래스 정보와 함께 201 응답을 반환하세요.

6. Postman이나 curl로 API를 테스트하세요:
   - GET `http://localhost:8000/api/classes`
   - POST `http://localhost:8000/api/enrollments` (JSON body에 클래스 ID와 신청자 정보 포함)

기대 결과: Laravel API가 정상적으로 동작하여 클래스 목록을 반환하고, 수강 신청 시 데이터베이스에 저장되며 enrolled_count가 증가합니다. API 테스트 성공.

4
Step 4
## React 19 프론트엔드 설정

1. 프로젝트 루트 폴더(`hobby-class-enrollment-form`)로 이동하세요:
   ```bash
   cd ..
   ```

2. Vite + React 19 프로젝트를 생성하세요:
   ```bash
   npm create vite@latest frontend -- --template react
   cd frontend
   npm install
   ```

3. Tailwind CSS를 설치하고 설정하세요:
   ```bash
   npm install -D tailwindcss postcss autoprefixer
   npx tailwindcss init -p
   ```

4. `tailwind.config.js` 파일을 열고 content 경로를 설정하세요:
   ```js
   content: [
     "./index.html",
     "./src/**/*.{js,ts,jsx,tsx}",
   ],
   ```

5. `src/index.css` 파일을 열고 Tailwind 지시어를 추가하세요:
   ```css
   @tailwind base;
   @tailwind components;
   @tailwind utilities;
   ```

6. React 개발 서버를 실행하세요:
   ```bash
   npm run dev
   ```

React가 `http://localhost:5173`에서 실행되는지 확인하세요.

기대 결과: React 19 프로젝트가 생성되고, Tailwind CSS가 설정되며, 개발 서버가 정상 실행됩니다. 브라우저에서 http://localhost:5173 접속 시 Vite + React 기본 페이지가 표시됩니다.

5
Step 5
## React 컴포넌트 구현 - 클래스 목록 표시

1. `src/App.jsx` 파일을 열고 다음 기능을 구현하세요:

   - `useState`로 `classes` 상태 생성 (빈 배열로 초기화)
   - `useState`로 `loading` 상태 생성 (true로 초기화)
   - `useEffect`로 컴포넌트 마운트 시 Laravel API에서 클래스 목록 가져오기:
     ```js
     fetch('http://localhost:8000/api/classes')
       .then(res => res.json())
       .then(data => {
         setClasses(data);
         setLoading(false);
       });
     ```

2. 클래스 목록을 카드 형태로 표시하세요:
   - 각 카드에 클래스명, 강사명, 카테고리, 시간대, 정원, 남은 자리 수 표시
   - 남은 자리 수가 0이면 "마감" 배지 표시 (빨간색 배경)
   - 남은 자리 수가 1~3이면 "서둘러요!" 배지 표시 (주황색 배경)
   - 각 카드에 "신청하기" 버튼 추가 (마감된 클래스는 버튼 비활성화)

3. Tailwind CSS로 깔끔한 그리드 레이아웃을 구성하세요 (grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3).

4. 로딩 중일 때는 "클래스 목록을 불러오는 중..." 메시지를 표시하세요.

5. 페이지 상단에 "🎨 취미 클래스 수강 신청" 제목을 추가하세요.

기대 결과: React 앱에서 Laravel API로부터 클래스 목록을 성공적으로 가져와 화면에 카드 형태로 표시됩니다. 마감 배지와 신청하기 버튼이 정상적으로 렌더링됩니다.

6
Step 6
## React 컴포넌트 구현 - 수강 신청 폼 모달

1. `src/App.jsx`에서 다음 상태를 추가하세요:
   - `selectedClass` (선택된 클래스 객체, null로 초기화)
   - `formData` (신청자 정보 객체: student_name, phone, email, preferred_time)
   - `isSubmitting` (제출 중 여부, false로 초기화)
   - `successMessage` (신청 완료 메시지, 빈 문자열로 초기화)

2. "신청하기" 버튼 클릭 시 `selectedClass`를 해당 클래스로 설정하여 모달을 열도록 구현하세요.

3. 모달 컴포넌트를 만드세요 (조건부 렌더링: `selectedClass`가 null이 아닐 때만 표시):
   - 모달 배경 (반투명 검은색 오버레이)
   - 모달 내용 (흰색 카드)
   - 선택된 클래스 정보 표시 (클래스명, 강사명, 시간대)
   - 입력 폼 필드:
     - 이름 (input type="text")
     - 전화번호 (input type="tel")
     - 이메일 (input type="email")
     - 희망 시간대 (select 드롭다운: "오전", "오후", "저녁", "주말")
   - "신청 완료" 버튼 및 "취소" 버튼

4. 폼 입력값이 변경될 때마다 `formData` 상태를 업데이트하세요.

5. "취소" 버튼 클릭 시 모달을 닫고 `selectedClass`를 null로 설정하세요.

6. Tailwind CSS로 모달 스타일을 깔끔하게 구성하세요.

기대 결과: 신청하기 버튼 클릭 시 모달이 열리고, 선택된 클래스 정보와 입력 폼이 표시됩니다. 취소 버튼으로 모달을 닫을 수 있습니다.

7
Step 7
## React - 수강 신청 제출 및 실시간 업데이트

1. "신청 완료" 버튼 클릭 시 다음을 수행하세요:

   - `isSubmitting`을 true로 설정 (버튼 비활성화)
   - Laravel API에 POST 요청:
     ```js
     fetch('http://localhost:8000/api/enrollments', {
       method: 'POST',
       headers: {
         'Content-Type': 'application/json',
       },
       body: JSON.stringify({
         hobby_class_id: selectedClass.id,
         ...formData,
       }),
     })
       .then(res => res.json())
       .then(data => {
         // 성공 처리
       });
     ```

2. 신청 성공 시:
   - `successMessage`를 "신청이 완료되었습니다! 🎉"로 설정
   - 모달을 닫고 `selectedClass`를 null로 설정
   - 클래스 목록을 다시 불러와서 남은 자리 수 업데이트 (fetch로 `/api/classes` 재호출)
   - 3초 후 `successMessage`를 빈 문자열로 초기화

3. 신청 실패 시 (정원 초과 등):
   - 에러 메시지를 alert로 표시
   - `isSubmitting`을 false로 설정

4. `successMessage`가 비어있지 않으면 화면 상단에 초록색 배경의 성공 알림 배너를 표시하세요.

5. 입력 폼 필드에 간단한 유효성 검사를 추가하세요 (빈 값 체크).

6. 제출 중일 때 "신청 완료" 버튼에 "제출 중..." 텍스트를 표시하고 버튼을 비활성화하세요.

기대 결과: 수강 신청 폼을 제출하면 Laravel API로 데이터가 전송되고, 성공 시 알림 메시지가 표시되며, 클래스 목록이 자동으로 업데이트되어 남은 자리 수가 줄어듭니다. 마감된 클래스는 더 이상 신청할 수 없습니다.

제출된 작품 (0)

로그인 후 제출

아직 제출된 작품이 없습니다. 첫 번째 도전자가 되어보세요!

댓글 (0)

로그인 후 댓글을 남길 수 있습니다.
아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!