나만의 명언 수집함 - 영감을 주는 문구 아카이브
inspirational-quote-vault
문제 설명
나만의 명언 수집함 - 영감을 주는 문구 아카이브
마음에 드는 명언이나 영감을 주는 문구를 발견할 때마다 저장하고, 나중에 다시 읽어볼 수 있는 개인 아카이브를 만듭니다. Laravel 12.x API 백엔드와 React 19 프론트엔드를 분리하여 구성하는 풀스택 프로젝트입니다.
필수 기능
- 명언 등록: 명언 내용과 작가명을 입력하여 저장
- 명언 목록 보기: 저장된 모든 명언을 카드 형태로 표시
- 명언 삭제: 더 이상 필요 없는 명언 제거
- 랜덤 명언: 저장된 명언 중 무작위로 하나를 보여주는 기능
- 반응형 디자인: 모바일과 데스크톱에서 모두 잘 보이는 UI
보너스 기능 (선택)
- 명언에 카테고리 태그 추가 (동기부여, 사랑, 성공 등)
- 즐겨찾기 기능 (좋아하는 명언에 별표)
- 검색 기능 (작가명이나 내용으로 필터링)
- 명언 카드 공유하기 (이미지로 내보내기)
기술 스택
- 백엔드: Laravel 12.x (RESTful API, SQLite)
- 프론트엔드: React 19 (Vite, fetch API)
- 스타일링: Tailwind CSS
이 프로젝트를 통해 Laravel의 라우팅, 컨트롤러, Eloquent 모델과 React의 컴포넌트, 상태 관리(useState), API 통신(fetch)을 학습할 수 있습니다.
제약 조건
- • Laravel 12.x 사용 (구버전 절대 금지)
- • React 19 사용 (Vite 번들러)
- • 데이터베이스는 SQLite 사용
- • Laravel은 API 서버로만 동작 (JSON 응답)
- • React는 별도 Vite 프로젝트로 구성
- • CORS 설정 필수
- • Tailwind CSS 사용 권장
- • 외부 라이브러리 최소화 (useState만 사용, 복잡한 상태관리 라이브러리 금지)
프롬프트 레시피
아래 프롬프트를 순서대로 AI에게 보내면 됩니다. 복사 버튼을 눌러 바로 사용하세요.
Laravel 12.x API 프로젝트를 생성하고 명언(Quote) 관리 API를 구축해줘.
요구사항:
1. Laravel 12.x 프로젝트 생성 (프로젝트명: quote-vault-api)
2. SQLite 데이터베이스 설정 (.env 파일 수정)
3. Quote 모델 및 마이그레이션 생성:
- 필드: id, content (text), author (string, nullable), created_at, updated_at
4. QuoteController 생성 및 RESTful API 라우트 구현:
- GET /api/quotes - 모든 명언 조회 (최신순 정렬)
- POST /api/quotes - 새 명언 생성 (content 필수, author 선택)
- DELETE /api/quotes/{id} - 명언 삭제
- GET /api/quotes/random - 랜덤 명언 1개 조회
5. CORS 설정:
- config/cors.php에서 localhost:5173 허용
- php artisan config:publish cors 실행하여 설정 파일 생성
6. 유효성 검사:
- content는 필수이며 최소 10자 이상
- author는 선택이며 최대 100자
7. API 응답은 모두 JSON 형식
8. 마이그레이션 실행 및 테스트 데이터 3개 시더 생성
명령어 실행 순서도 알려줘.
기대 결과: Laravel API 프로젝트가 생성되고, Quote 모델과 마이그레이션, QuoteController가 구현됩니다. /api/quotes 엔드포인트에서 CRUD 작업이 가능하고, /api/quotes/random 엔드포인트에서 랜덤 명언을 가져올 수 있습니다. CORS가 설정되어 React 앱에서 접근 가능합니다. 테스트 데이터가 데이터베이스에 추가됩니다.
React 19 + Vite 프론트엔드 프로젝트를 생성하고 명언 목록을 표시해줘.
요구사항:
1. Vite로 React 19 프로젝트 생성 (프로젝트명: quote-vault-frontend, 포트: 5173)
2. Tailwind CSS 설치 및 설정
3. App.jsx에서 명언 목록 표시:
- useState로 quotes 상태 관리
- useEffect로 컴포넌트 마운트 시 GET /api/quotes 호출 (fetch 사용)
- API URL: http://localhost:8000/api/quotes
- 로딩 상태 표시 ("명언을 불러오는 중...")
- 에러 처리 (API 호출 실패 시 메시지 표시)
4. 명언 카드 디자인:
- 각 명언을 카드 형태로 표시 (흰색 배경, 그림자, 둥근 모서리)
- 명언 내용은 큰 글씨, 이탤릭체
- 작가명은 작은 글씨, 오른쪽 정렬 ("- 작가명" 형식)
- 작가명이 없으면 "- 익명" 표시
5. 반응형 그리드 레이아웃:
- 모바일: 1열
- 태블릿: 2열
- 데스크톱: 3열
6. 전체 배경색은 연한 회색 (gray-100)
7. 상단에 제목 "나만의 명언 수집함" 표시 (크고 굵게)
컴포넌트 구조와 Tailwind 클래스를 자세히 작성해줘.
기대 결과: React 앱이 생성되고 Tailwind CSS가 설정됩니다. 앱을 실행하면 Laravel API에서 명언 목록을 가져와 카드 형태로 표시됩니다. 반응형 그리드 레이아웃이 적용되어 화면 크기에 따라 열 개수가 변경됩니다. 로딩과 에러 상태가 적절히 처리됩니다.
명언 등록 폼과 삭제 기능을 추가해줘.
요구사항:
1. 명언 등록 폼 컴포넌트 (QuoteForm.jsx):
- content (textarea, 필수, placeholder: "영감을 주는 명언을 입력하세요...")
- author (input, 선택, placeholder: "작가명 (선택사항)")
- 제출 버튼 ("명언 추가")
- useState로 폼 상태 관리
- 제출 시 POST /api/quotes로 데이터 전송 (fetch 사용)
- 제출 성공 시 폼 초기화 및 부모 컴포넌트에 알림 (콜백 함수)
- 유효성 검사: content가 10자 미만이면 경고 메시지 표시
2. App.jsx 수정:
- QuoteForm 컴포넌트를 상단에 배치
- 명언 추가 후 목록 새로고침 (fetchQuotes 함수 재호출)
3. 삭제 기능:
- 각 명언 카드에 삭제 버튼 (빨간색, 우측 상단 작은 X 아이콘)
- 클릭 시 DELETE /api/quotes/{id} 호출
- 삭제 성공 시 목록에서 해당 명언 제거 (상태 업데이트)
- 삭제 확인 대화상자 (confirm) 추가
4. 스타일링:
- 폼은 흰색 카드 형태, 그림자 효과
- textarea는 높이 100px, 리사이즈 가능
- 버튼은 파란색 배경, 호버 시 진하게
- 삭제 버튼은 호버 시 빨간색 배경
폼 컴포넌트와 삭제 로직을 자세히 구현해줘.
기대 결과: 명언 등록 폼이 추가되어 사용자가 새로운 명언을 입력하고 저장할 수 있습니다. 폼 제출 시 API로 데이터가 전송되고 목록이 자동으로 업데이트됩니다. 각 명언 카드에 삭제 버튼이 표시되어 클릭 시 해당 명언이 삭제됩니다. 유효성 검사와 확인 대화상자가 작동합니다.
랜덤 명언 표시 기능을 추가해줘.
요구사항:
1. RandomQuote 컴포넌트 생성 (RandomQuote.jsx):
- GET /api/quotes/random 호출하여 랜덤 명언 1개 가져오기
- 명언을 큰 카드 형태로 중앙에 표시
- 배경색은 그라데이션 (파란색에서 보라색)
- 텍스트는 흰색, 큰 글씨
- "새로운 명언 보기" 버튼 추가 (클릭 시 다른 랜덤 명언 로드)
2. App.jsx 수정:
- RandomQuote 컴포넌트를 제목 아래에 배치
- 명언이 없을 경우 "아직 저장된 명언이 없습니다" 메시지 표시
3. 스타일링:
- 랜덤 명언 카드는 전체 폭 사용
- 높이 200px, 중앙 정렬
- 버튼은 흰색 테두리, 투명 배경, 호버 시 흰색 배경으로 변경
- 부드러운 페이드 인 애니메이션 효과
4. 로딩 상태 표시 ("명언을 가져오는 중...")
랜덤 명언 컴포넌트를 자세히 구현하고 App.jsx 통합 방법도 알려줘.
기대 결과: 랜덤 명언을 표시하는 섹션이 추가됩니다. 페이지 로드 시 자동으로 랜덤 명언이 표시되고, 버튼을 클릭할 때마다 새로운 랜덤 명언이 로드됩니다. 그라데이션 배경과 애니메이션 효과가 적용되어 시각적으로 매력적입니다. 명언이 없을 때 적절한 메시지가 표시됩니다.