스튜디오 타임슬롯 예약 시스템 - 음악/사진 스튜디오 시간 예약
studio-timeslot-booking-inertia
문제 설명
🎵 스튜디오 타임슬롯 예약 시스템
음악 스튜디오나 사진 촬영 스튜디오를 시간 단위로 예약할 수 있는 풀스택 예약 플랫폼입니다. Laravel 13.x + Inertia.js + React 19 모노리스 아키텍처로 구현하며, 실시간 예약 현황을 캘린더 뷰로 확인하고 타임슬롯별 예약 가능 여부를 시각적으로 표시합니다.
필수 기능
- 스튜디오 관리: 여러 스튜디오룸(A룸, B룸 등) 등록 및 관리
- 타임슬롯 시스템: 30분 또는 1시간 단위로 예약 가능한 시간대 설정
- 캘린더 뷰: 주간 또는 일간 캘린더로 예약 현황 한눈에 보기
- 예약 생성: 사용자가 원하는 스튜디오와 시간대 선택하여 예약
- 예약 상태 관리: 예약 대기/확정/취소 상태 관리
- 충돌 방지: 동일 시간대 중복 예약 불가 로직
- 내 예약 목록: 사용자별 예약 내역 조회 및 취소 기능
- 실시간 가용성 표시: 예약된 슬롯은 회색, 가능한 슬롯은 초록색으로 표시
보너스 기능
- 예약 시 자동 이메일 알림 (Laravel Mail)
- 예약 전날 리마인더 알림
- 스튜디오별 가격 차등 및 결제 금액 계산
- 관리자 대시보드로 전체 예약 통계 확인
- 반복 예약 기능 (매주 같은 시간 자동 예약)
- 예약 취소 정책 설정 (24시간 전까지만 취소 가능 등)
제약 조건
- • Laravel 13.x + Inertia.js + React 19 모노리스 풀스택 구조 (별도 API 라우트 없이 Inertia::render() 사용)
- • Laravel Breeze (React + Inertia) starter kit으로 프로젝트 초기화
- • SQLite 데이터베이스 사용 (개발 환경 간소화)
- • Tailwind CSS로 UI 스타일링
- • 타임슬롯은 30분 또는 1시간 단위로 설정 (설정 가능하게)
- • 동일 시간대 중복 예약 불가 검증 로직 필수
- • React 컴포넌트는 Pages 폴더에 배치 (Inertia 컨벤션)
- • Laravel의 Eloquent 관계(hasMany, belongsTo)를 활용한 DB 설계
- • 예약 상태는 Enum 또는 상수로 관리 (pending, confirmed, cancelled)
- • 캘린더 UI는 react-big-calendar 또는 직접 구현
- • 날짜/시간 처리는 Carbon (Laravel) 및 date-fns (React) 활용
프롬프트 레시피
아래 프롬프트를 순서대로 AI에게 보내면 됩니다. 복사 버튼을 눌러 바로 사용하세요.
mkdir studio-timeslot-booking-inertia && cd studio-timeslot-booking-inertia 이 폴더에서 스튜디오 타임슬롯 예약 시스템 프로젝트를 시작합니다. Laravel 13.x + Inertia.js + React 19 기반 모노리스 풀스택 프로젝트를 생성해주세요. 1. `npx create laravel` 명령으로 Laravel 13.x 프로젝트 생성 (현재 폴더에) 2. Laravel Breeze (React + Inertia) starter kit 설치: - `php artisan breeze:install react` - `npm install && npm run dev` 3. SQLite 데이터베이스 설정: - `.env` 파일에서 `DB_CONNECTION=sqlite` - `touch database/database.sqlite` 4. 프로젝트 구조 확인: - `resources/js/Pages/` (React 페이지 컴포넌트) - `app/Http/Controllers/` (Laravel 컨트롤러) - `routes/web.php` (Inertia 라우트) 5. Tailwind CSS가 이미 설정되어 있는지 확인 6. 기본 인증 시스템(로그인/회원가입) 동작 확인 프로젝트가 정상적으로 생성되고 `npm run dev` 및 `php artisan serve`로 실행되면 브라우저에서 기본 화면을 확인해주세요.
기대 결과: Laravel 13.x + Breeze (React + Inertia) 프로젝트가 생성되고, 기본 인증 페이지(로그인/회원가입)가 정상 작동합니다. SQLite 데이터베이스 파일이 생성되고, Vite 개발 서버가 실행됩니다.
데이터베이스 스키마를 설계하고 마이그레이션을 생성해주세요. 필요한 테이블: 1. **studios 테이블** (스튜디오룸 정보) - id (primary key) - name (스튜디오명, 예: 'A룸', 'B룸') - description (설명, nullable) - capacity (수용 인원, integer) - hourly_rate (시간당 가격, decimal, nullable) - is_active (활성화 여부, boolean, default true) - timestamps 2. **bookings 테이블** (예약 정보) - id (primary key) - user_id (foreign key to users) - studio_id (foreign key to studios) - booking_date (예약 날짜, date) - start_time (시작 시간, time) - end_time (종료 시간, time) - status (예약 상태: 'pending', 'confirmed', 'cancelled', default 'pending') - purpose (예약 목적, text, nullable) - total_price (총 가격, decimal, nullable) - cancelled_at (취소 시간, timestamp, nullable) - timestamps - unique index on (studio_id, booking_date, start_time) - 중복 예약 방지 마이그레이션 파일을 생성하고 `php artisan migrate` 실행까지 해주세요. 추가로 Studio와 Booking 모델도 생성하고 Eloquent 관계를 설정해주세요: - Studio hasMany Bookings - Booking belongsTo Studio - Booking belongsTo User
기대 결과: studios, bookings 테이블이 생성되고, Studio 및 Booking 모델이 Eloquent 관계와 함께 생성됩니다. 데이터베이스 마이그레이션이 성공적으로 실행됩니다.
시더(Seeder)를 생성하여 테스트 데이터를 추가해주세요. 1. **StudioSeeder** 생성: - 3개의 스튜디오룸 생성 (예: 'A룸 - 녹음실', 'B룸 - 연습실', 'C룸 - 촬영 스튜디오') - 각 스튜디오에 설명, 수용 인원(2~10명), 시간당 가격(20,000~50,000원) 설정 2. **BookingSeeder** 생성 (선택사항): - 더미 예약 데이터 5~10개 생성 (다양한 날짜와 시간대) - 일부는 confirmed, 일부는 pending 상태로 `DatabaseSeeder`에서 StudioSeeder를 호출하도록 설정하고 `php artisan db:seed` 실행해주세요. 추가로 `php artisan tinker`에서 Studio::all()을 실행하여 데이터가 잘 들어갔는지 확인해주세요.
기대 결과: 3개의 스튜디오룸 데이터가 데이터베이스에 삽입되고, tinker에서 조회 가능합니다. 선택적으로 더미 예약 데이터도 생성됩니다.
스튜디오 목록 및 상세 페이지를 구현해주세요.
1. **StudioController 생성**:
- `index()` 메서드: 모든 활성화된 스튜디오 목록 조회
- `show($id)` 메서드: 특정 스튜디오 상세 정보 및 해당 스튜디오의 금주 예약 현황 조회
- Inertia::render()로 React 컴포넌트에 데이터 전달
2. **라우트 설정** (routes/web.php):
- `GET /studios` → StudioController@index
- `GET /studios/{id}` → StudioController@show
- 인증된 사용자만 접근 가능하도록 auth 미들웨어 적용
3. **React 컴포넌트 생성**:
- `resources/js/Pages/Studios/Index.jsx`: 스튜디오 목록 페이지
* 스튜디오 카드 형태로 표시 (이름, 설명, 수용 인원, 시간당 가격)
* 각 카드 클릭 시 상세 페이지로 이동 (Link 컴포넌트 사용)
- `resources/js/Pages/Studios/Show.jsx`: 스튜디오 상세 페이지
* 스튜디오 정보 표시
* 금주 예약 현황을 간단한 테이블 또는 리스트로 표시
* "예약하기" 버튼 (다음 단계에서 구현)
4. Tailwind CSS로 깔끔하게 스타일링해주세요.
네비게이션 바에 "스튜디오 목록" 링크를 추가하여 접근 가능하게 해주세요.
기대 결과: 스튜디오 목록 페이지에서 모든 스튜디오를 카드 형태로 볼 수 있고, 클릭 시 상세 페이지로 이동합니다. 상세 페이지에서는 스튜디오 정보와 금주 예약 현황을 확인할 수 있습니다.
예약 생성 페이지 및 로직을 구현해주세요.
1. **BookingController 생성**:
- `create($studioId)` 메서드: 예약 폼 페이지 렌더링 (선택한 스튜디오 정보 전달)
- `store(Request $request)` 메서드: 예약 생성 로직
* 유효성 검증: booking_date, start_time, end_time, studio_id 필수
* 중복 예약 체크: 동일 스튜디오, 동일 날짜, 겹치는 시간대가 있는지 확인
* 예약 생성 시 user_id는 auth()->id()로 자동 설정
* 총 가격 계산 (스튜디오 시간당 가격 * 예약 시간)
* 성공 시 "예약이 완료되었습니다" 메시지와 함께 내 예약 목록 페이지로 리다이렉트
* 실패 시 에러 메시지 반환
2. **라우트 설정**:
- `GET /studios/{id}/book` → BookingController@create
- `POST /bookings` → BookingController@store
3. **React 컴포넌트 생성**:
- `resources/js/Pages/Bookings/Create.jsx`: 예약 폼
* 스튜디오 정보 표시 (읽기 전용)
* 날짜 선택 (input type="date", 오늘 이후 날짜만 선택 가능)
* 시작 시간 선택 (select 또는 input type="time", 30분 단위 옵션)
* 종료 시간 선택 (시작 시간 이후만 선택 가능)
* 예약 목적 입력 (textarea, 선택사항)
* 예상 총 가격 표시 (시작/종료 시간 선택 시 자동 계산)
* "예약하기" 버튼 (Inertia form submit)
4. 중복 예약 방지 로직을 명확히 구현해주세요:
- 기존 예약 중 status가 'cancelled'가 아닌 것만 체크
- 새 예약의 (start_time, end_time)이 기존 예약 시간대와 겹치는지 확인
5. 스튜디오 상세 페이지의 "예약하기" 버튼을 `/studios/{id}/book` 링크로 연결해주세요.
기대 결과: 스튜디오 상세 페이지에서 "예약하기" 버튼을 클릭하면 예약 폼 페이지로 이동합니다. 날짜와 시간을 선택하면 예상 가격이 자동 계산되고, 예약 제출 시 중복 체크 후 성공적으로 예약이 생성됩니다.
내 예약 목록 페이지 및 예약 취소 기능을 구현해주세요.
1. **BookingController에 메서드 추가**:
- `index()` 메서드: 현재 로그인한 사용자의 모든 예약 조회 (스튜디오 정보 포함, with('studio'))
* 최신 예약순으로 정렬
* status별로 필터링 가능하도록 (선택사항)
- `cancel($id)` 메서드: 예약 취소 로직
* 해당 예약이 현재 사용자의 것인지 확인
* status를 'cancelled'로 변경, cancelled_at에 현재 시간 저장
* 성공 메시지와 함께 내 예약 목록으로 리다이렉트
2. **라우트 설정**:
- `GET /my-bookings` → BookingController@index
- `DELETE /bookings/{id}` → BookingController@cancel
3. **React 컴포넌트 생성**:
- `resources/js/Pages/Bookings/Index.jsx`: 내 예약 목록
* 예약 목록을 테이블 또는 카드 형태로 표시
* 각 예약: 스튜디오명, 예약 날짜, 시작/종료 시간, 상태, 총 가격
* 상태별 색상 구분 (pending: 노란색, confirmed: 초록색, cancelled: 회색)
* confirmed 또는 pending 상태인 예약에만 "취소하기" 버튼 표시
* 취소 버튼 클릭 시 확인 메시지 후 DELETE 요청
* 예약이 없을 경우 "예약 내역이 없습니다" 메시지 표시
4. 네비게이션 바에 "내 예약" 링크를 추가해주세요.
5. 취소 버튼은 Inertia의 router.delete() 또는 Link method="delete"를 사용하여 구현해주세요.
기대 결과: "내 예약" 페이지에서 사용자의 모든 예약을 확인할 수 있고, 상태별로 색상이 구분됩니다. "취소하기" 버튼을 클릭하면 확인 후 예약이 취소되고, 상태가 'cancelled'로 변경됩니다.
스튜디오 상세 페이지에 주간 캘린더 뷰를 추가하여 예약 가능 시간대를 시각적으로 표시해주세요.
1. **StudioController의 show() 메서드 수정**:
- 선택한 주(week)의 예약 현황을 조회 (기본값: 이번 주)
- 해당 스튜디오의 모든 예약 중 status가 'cancelled'가 아닌 것만 필터링
- 날짜별, 시간대별로 그룹화하여 React 컴포넌트에 전달
- 추가로 스튜디오의 운영 시간 정보 전달 (예: 09:00 ~ 22:00, 30분 단위)
2. **React 컴포넌트 수정** (Studios/Show.jsx):
- 주간 캘린더 UI 구현:
* 월요일부터 일요일까지 7일 표시
* 각 날짜별로 시간대(09:00, 09:30, 10:00, ... 22:00) 세로 나열
* 예약된 시간대는 회색 배경 + "예약됨" 표시
* 예약 가능한 시간대는 초록색 배경 + 클릭 시 예약 폼으로 이동 (날짜/시간 자동 입력)
* 과거 시간대는 비활성화 (회색 + 클릭 불가)
- 이전 주/다음 주 버튼 추가 (주 단위 네비게이션)
- 반응형 디자인: 모바일에서는 하루씩 스와이프 가능하게 (선택사항)
3. 예약 가능한 슬롯 클릭 시:
- 예약 폼 페이지로 이동하면서 날짜와 시작 시간을 쿼리 파라미터로 전달
- 예약 폼에서 이 값들을 자동으로 채워주기
4. Tailwind CSS로 캘린더 그리드 레이아웃을 깔끔하게 구현해주세요.
캘린더 라이브러리를 사용하지 않고 직접 구현하거나, react-big-calendar 등을 사용해도 좋습니다.
기대 결과: 스튜디오 상세 페이지에 주간 캘린더가 표시되고, 예약된 시간대는 회색, 예약 가능한 시간대는 초록색으로 구분됩니다. 예약 가능한 슬롯을 클릭하면 해당 날짜/시간이 자동 입력된 예약 폼으로 이동합니다.
제출된 작품 (0)
로그인 후 제출아직 제출된 작품이 없습니다. 첫 번째 도전자가 되어보세요!