나만의 간식 평가 노트 - 먹어본 간식 별점 & 메모
snack-rating-notebook
문제 설명
프로젝트 개요
먹어본 간식들을 기록하고 별점과 메모를 남기는 간단한 웹 애플리케이션입니다. Laravel 12.x + Inertia.js + React 19 스택으로 모노리스 풀스택 구조를 경험할 수 있습니다.
필수 기능
- ✅ 간식 추가하기 (이름, 카테고리, 별점, 메모)
- ✅ 간식 목록 조회 (카드 형태로 표시)
- ✅ 간식 정보 수정하기
- ✅ 간식 삭제하기
- ✅ 별점 시각화 (⭐ 이모지 또는 별 아이콘)
- ✅ 카테고리별 필터링 (과자, 초콜릿, 아이스크림, 음료 등)
보너스 기능
- 🎨 Tailwind CSS로 예쁜 카드 디자인
- 📊 평균 별점 통계 표시
- 🔍 간식 이름 검색 기능
- 📱 반응형 디자인 (모바일 친화적)
기술 스택
- 백엔드: Laravel 12.x (SQLite, Eloquent ORM)
- 프론트엔드: React 19 + Inertia.js
- 스타일링: Tailwind CSS
- 아키텍처: Inertia.js를 통한 모노리스 풀스택 (별도 API 없음)
제약 조건
- • Laravel 12.x + Inertia.js + React 19 스택 사용
- • Laravel Breeze (React + Inertia) starter kit 또는 `npx create laravel` 사용 권장
- • SQLite 데이터베이스 사용 (간단한 설정)
- • Inertia::render()로 Laravel 컨트롤러에서 React 컴포넌트에 데이터 전달
- • 별도의 REST API 엔드포인트 구현 금지 (Inertia.js가 처리)
- • 복잡한 상태관리 라이브러리 사용 금지 (useState만 사용)
- • Tailwind CSS로 스타일링
- • 간식 카테고리: 과자, 초콜릿, 아이스크림, 음료, 기타 중 선택
프롬프트 레시피
아래 프롬프트를 순서대로 AI에게 보내면 됩니다. 복사 버튼을 눌러 바로 사용하세요.
Laravel 12.x + React + Inertia.js 프로젝트를 생성해주세요.
요구사항:
- Laravel Breeze의 React + Inertia 스타터 킷을 사용하여 프로젝트 초기화
- 프로젝트명: snack-rating-notebook
- 데이터베이스: SQLite 사용 (.env 설정 포함)
- Tailwind CSS 포함
프로젝트 생성 후:
1. 기본 인증 기능은 제거하고 간단하게 시작
2. routes/web.php에 홈 라우트만 남기기
3. resources/js/Pages/Home.jsx 컴포넌트 생성 ("간식 평가 노트" 타이틀 표시)
4. npm install && npm run dev 실행 가이드 제공
초기 화면에는 "🍪 나만의 간식 평가 노트"라는 헤더와 "간식을 추가해보세요!" 메시지를 표시해주세요.
기대 결과: Laravel + Inertia + React 프로젝트가 생성되고, 개발 서버 실행 시 홈 화면에 타이틀이 표시됩니다. SQLite 데이터베이스가 설정되고, Tailwind CSS가 적용된 기본 레이아웃이 준비됩니다.
Snack 모델과 데이터베이스 마이그레이션을 생성해주세요. 요구사항: - php artisan make:model Snack -m 명령어 사용 - 마이그레이션 파일에 다음 컬럼 추가: - name (string, 간식 이름) - category (string, 카테고리: 과자/초콜릿/아이스크림/음료/기타) - rating (integer, 별점 1-5) - memo (text, nullable, 메모) - timestamps (created_at, updated_at) - app/Models/Snack.php에 $fillable 속성 추가 - php artisan migrate 실행하여 테이블 생성 생성 후 SnackController도 만들어주세요: - php artisan make:controller SnackController - index, store, update, destroy 메서드 스켈레톤 작성
기대 결과: snacks 테이블이 SQLite 데이터베이스에 생성되고, Snack 모델이 준비됩니다. SnackController가 생성되어 CRUD 메서드 뼈대가 마련됩니다.
간식 목록 조회 및 추가 기능을 구현해주세요.
백엔드 (SnackController):
- index 메서드: Snack::latest()->get()으로 전체 간식 조회 후 Inertia::render('Home', ['snacks' => $snacks])로 전달
- store 메서드: Request 검증 (name, category, rating 필수, memo 선택) 후 Snack::create()로 저장, 저장 후 redirect()->route('snacks.index')로 리다이렉트
라우트 (routes/web.php):
- GET '/' -> SnackController@index (name: 'snacks.index')
- POST '/snacks' -> SnackController@store (name: 'snacks.store')
프론트엔드 (resources/js/Pages/Home.jsx):
- Inertia의 useForm 훅 사용하여 폼 상태 관리
- 간식 추가 폼 UI:
- 간식 이름 입력 (text input)
- 카테고리 선택 (select: 과자, 초콜릿, 아이스크림, 음료, 기타)
- 별점 선택 (1-5, radio 버튼 또는 별 아이콘 클릭)
- 메모 입력 (textarea, 선택사항)
- 제출 버튼
- 간식 목록 표시: props.snacks를 map으로 순회하며 카드 형태로 표시 (이름, 카테고리, 별점 ⭐, 메모)
- Tailwind CSS로 폼과 카드 스타일링
폼 제출 시 useForm의 post() 메서드로 '/snacks' 엔드포인트에 전송하세요.
기대 결과: 간식을 추가할 수 있는 폼이 표시되고, 제출하면 데이터베이스에 저장된 후 목록에 새로운 간식 카드가 나타납니다. 별점은 ⭐ 이모지로 시각화됩니다.
간식 수정 및 삭제 기능을 추가해주세요.
백엔드 (SnackController):
- update 메서드: Snack::findOrFail($id)로 조회 후 $request->validate()로 검증, $snack->update()로 수정, redirect()->route('snacks.index')
- destroy 메서드: Snack::findOrFail($id)->delete(), redirect()->route('snacks.index')
라우트 (routes/web.php):
- PUT/PATCH '/snacks/{id}' -> SnackController@update (name: 'snacks.update')
- DELETE '/snacks/{id}' -> SnackController@destroy (name: 'snacks.destroy')
프론트엔드 (Home.jsx):
- 각 간식 카드에 "수정" 및 "삭제" 버튼 추가
- 수정 기능:
- 수정 버튼 클릭 시 해당 간식의 정보가 폼에 채워지도록 (editingSnack state 사용)
- 폼 제출 시 useForm의 put() 메서드로 '/snacks/{id}' 엔드포인트에 전송
- 수정 모드일 때 "수정하기" 버튼, 일반 모드일 때 "추가하기" 버튼으로 텍스트 변경
- 삭제 기능:
- 삭제 버튼 클릭 시 확인 메시지 (confirm) 후 Inertia의 router.delete()로 '/snacks/{id}' 호출
UI 개선:
- 수정/삭제 버튼을 카드 우측 상단에 배치
- 버튼 스타일링 (수정: 파란색, 삭제: 빨간색)
- 호버 효과 추가
기대 결과: 간식 카드의 수정 버튼을 클릭하면 폼에 기존 정보가 채워지고, 수정 후 제출하면 목록이 업데이트됩니다. 삭제 버튼을 클릭하면 확인 후 해당 간식이 목록에서 사라집니다.
카테고리별 필터링과 UI 개선을 추가해주세요. 프론트엔드 (Home.jsx): - useState로 selectedCategory 상태 추가 (기본값: 'all') - 카테고리 필터 버튼 UI: - 전체, 과자, 초콜릿, 아이스크림, 음료, 기타 버튼을 상단에 가로로 배치 - 선택된 카테고리 버튼은 강조 표시 (배경색 변경) - 버튼 클릭 시 selectedCategory 업데이트 - 간식 목록 필터링: - selectedCategory가 'all'이 아니면 snacks.filter(snack => snack.category === selectedCategory) - 필터링된 결과를 표시 UI 개선: - 간식 카드를 그리드 레이아웃으로 배치 (grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4) - 카드 디자인 개선: - 카테고리별 배지 색상 차별화 (과자: 주황, 초콜릿: 갈색, 아이스크림: 하늘색, 음료: 초록, 기타: 회색) - 그림자 효과 및 호버 시 확대 애니메이션 - 별점을 큰 이모지로 표시 - 빈 상태 메시지: - 간식이 없을 때: "아직 추가된 간식이 없습니다. 첫 간식을 평가해보세요! 🍪" - 필터링 결과가 없을 때: "이 카테고리에는 간식이 없습니다." 추가 기능: - 전체 간식 개수와 평균 별점을 상단에 표시 - 평균 별점 계산: snacks.reduce((sum, s) => sum + s.rating, 0) / snacks.length
기대 결과: 카테고리 필터 버튼을 클릭하면 해당 카테고리의 간식만 표시됩니다. 간식 카드가 그리드로 예쁘게 배치되고, 카테고리별로 색상이 다른 배지가 표시됩니다. 상단에 전체 통계(개수, 평균 별점)가 표시됩니다.