풀스택 운동 챌린지 참여 앱 - 바이브코딩 레시피
입문 PHP + JavaScript Laravel + React AI: Claude

풀스택 운동 챌린지 참여 앱

리포지토리명 fitness-challenge-tracker
조회수 58 0건 제출

문제 설명

📋 프로젝트 개요

30일 운동 챌린지에 참여하고 매일 인증하는 간단한 풀스택 웹 앱을 만듭니다. Laravel 13.x로 RESTful API 백엔드를 구축하고, React 19로 사용자 친화적인 프론트엔드를 개발합니다.

✅ 필수 기능

  • 챌린지 목록 조회: 현재 진행 중인 챌린지 목록 표시 (예: 30일 플랭크, 스쿼트 100개 등)
  • 챌린지 생성: 새로운 챌린지 추가 (제목, 설명, 목표 일수)
  • 일일 인증 체크: 오늘 운동했는지 체크박스로 기록
  • 진행률 표시: 챌린지별 달성률을 프로그레스 바로 시각화
  • SQLite 데이터베이스: 간단한 로컬 DB로 챌린지와 인증 기록 저장

🎁 보너스 기능

  • 연속 인증 일수(Streak) 표시
  • 챌린지 완료 시 축하 메시지
  • 간단한 애니메이션 효과 (체크 시 confetti 등)
  • 다크 모드 지원

🛠 기술 스택

  • 백엔드: Laravel 13.x (API 모드, SQLite)
  • 프론트엔드: React 19 (Vite)
  • 스타일링: Tailwind CSS
  • HTTP 클라이언트: Axios

이 프로젝트를 통해 Laravel API 개발과 React 컴포넌트 구성, 그리고 두 시스템 간 데이터 통신의 기초를 배울 수 있습니다.

제약 조건

  • • Laravel 13.x 사용 (구버전 금지)
  • • React 19 사용 (구버전 금지)
  • • SQLite 데이터베이스 사용 (설치 불필요)
  • • Laravel은 API 전용 백엔드로 구성 (api.php 라우트 사용)
  • • React는 별도 Vite 프로젝트로 구성
  • • CORS 설정 필수 (Laravel에서 React 접근 허용)
  • • 복잡한 상태관리 라이브러리 사용 금지 (useState만 사용)
  • • 인증/로그인 기능 제외 (단순 CRUD에 집중)
  • • Tailwind CSS로 깔끔한 UI 구성

프롬프트 레시피

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

1
Step 1
mkdir fitness-challenge-tracker && cd fitness-challenge-tracker

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

# Laravel 13.x API 백엔드 프로젝트 생성

1. `backend` 폴더에 Laravel 13.x 프로젝트를 생성해주세요.
   - `composer create-project laravel/laravel:^13.0 backend` 명령 사용

2. `.env` 파일 설정:
   - DB_CONNECTION을 sqlite로 변경
   - database/database.sqlite 파일 생성

3. 다음 마이그레이션 파일 2개를 생성해주세요:

**challenges 테이블** (`create_challenges_table.php`):
- id (primary key)
- title (string, 챌린지 제목)
- description (text, 설명)
- target_days (integer, 목표 일수, 기본값 30)
- created_at, updated_at

**check_ins 테이블** (`create_check_ins_table.php`):
- id (primary key)
- challenge_id (foreign key → challenges.id)
- check_date (date, 인증 날짜, unique with challenge_id)
- created_at, updated_at

4. 마이그레이션 실행: `php artisan migrate`

5. CORS 설정:
   - `config/cors.php`에서 'paths' => ['api/*']로 설정
   - 'allowed_origins' => ['http://localhost:5173'] (Vite 기본 포트)
   - 'supports_credentials' => true

6. 서버 실행 확인:
   - `php artisan serve`로 http://127.0.0.1:8000에서 실행 확인

기대 결과: Laravel 13.x 프로젝트가 backend 폴더에 생성되고, SQLite 데이터베이스에 challenges와 check_ins 테이블이 생성됩니다. CORS가 설정되어 React에서 API 호출이 가능한 상태가 됩니다.

2
Step 2
# Laravel API 엔드포인트 구현

1. Challenge 모델 생성:
   - `php artisan make:model Challenge`
   - CheckIn과 hasMany 관계 설정
   - fillable: ['title', 'description', 'target_days']

2. CheckIn 모델 생성:
   - `php artisan make:model CheckIn`
   - Challenge와 belongsTo 관계 설정
   - fillable: ['challenge_id', 'check_date']

3. ChallengeController 생성 (`php artisan make:controller Api/ChallengeController --api`):
   - `index()`: 모든 챌린지 조회 (check_ins 카운트 포함, withCount 사용)
   - `store()`: 새 챌린지 생성 (title, description, target_days 검증)
   - `show($id)`: 특정 챌린지 상세 조회 (check_ins 관계 로드)
   - `destroy($id)`: 챌린지 삭제

4. CheckInController 생성 (`php artisan make:controller Api/CheckInController`):
   - `store()`: 특정 챌린지에 오늘 날짜로 체크인 생성
     - challenge_id와 오늘 날짜(Carbon::today())로 중복 체크
     - 이미 오늘 체크인했으면 에러 반환
   - `destroy($id)`: 체크인 삭제 (체크 취소)

5. `routes/api.php`에 라우트 등록:
```php
Route::apiResource('challenges', ChallengeController::class);
Route::post('challenges/{challenge}/check-in', [CheckInController::class, 'store']);
Route::delete('check-ins/{checkIn}', [CheckInController::class, 'destroy']);
```

6. Postman 또는 curl로 API 테스트:
   - POST /api/challenges (챌린지 생성)
   - GET /api/challenges (목록 조회)
   - POST /api/challenges/1/check-in (체크인)

기대 결과: Laravel API가 완성되어 챌린지 CRUD와 체크인 생성/삭제가 가능합니다. /api/challenges 엔드포인트에서 JSON 응답을 받을 수 있으며, 각 챌린지의 check_ins_count가 포함됩니다.

3
Step 3
# React 19 프론트엔드 프로젝트 생성

1. 프로젝트 루트에서 `frontend` 폴더에 React + Vite 프로젝트 생성:
   - `npm create vite@latest frontend -- --template react`
   - `cd frontend && npm install`

2. 필요한 패키지 설치:
   - `npm install axios`
   - `npm install -D tailwindcss postcss autoprefixer`
   - `npx tailwindcss init -p`

3. Tailwind CSS 설정:
   - `tailwind.config.js`의 content에 `"./index.html", "./src/**/*.{js,jsx}"`추가
   - `src/index.css`에 Tailwind directives 추가:
```css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

4. Axios 인스턴스 설정 (`src/api/axios.js`):
```javascript
import axios from 'axios';

const api = axios.create({
  baseURL: 'http://127.0.0.1:8000/api',
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
  },
});

export default api;
```

5. 기본 컴포넌트 구조 생성:
   - `src/components/ChallengeList.jsx` (빈 컴포넌트)
   - `src/components/ChallengeForm.jsx` (빈 컴포넌트)
   - `src/components/ChallengeCard.jsx` (빈 컴포넌트)

6. `src/App.jsx`를 다음과 같이 수정:
   - Tailwind 스타일 적용된 레이아웃
   - 헤더에 "운동 챌린지 트래커" 제목
   - ChallengeForm과 ChallengeList 컴포넌트 import 및 배치

7. 개발 서버 실행: `npm run dev` (http://localhost:5173)

기대 결과: React 프로젝트가 frontend 폴더에 생성되고, Tailwind CSS가 설정됩니다. Axios 인스턴스가 Laravel API와 통신할 준비가 되며, 기본 컴포넌트 구조가 갖춰집니다.

4
Step 4
# 챌린지 목록 조회 및 카드 UI 구현

1. `ChallengeList.jsx` 구현:
   - useState로 challenges 배열 상태 관리
   - useEffect에서 api.get('/challenges')로 데이터 fetch
   - loading 상태 추가 ("로딩 중..." 표시)
   - challenges.map()으로 각 챌린지를 ChallengeCard에 전달
   - 빈 상태일 때 "아직 챌린지가 없습니다" 메시지

2. `ChallengeCard.jsx` 구현:
   - props로 challenge 객체 받기 (title, description, target_days, check_ins_count)
   - Tailwind로 카드 스타일링:
     - 흰색 배경, 그림자, 둥근 모서리
     - 제목은 font-bold text-lg
     - 설명은 text-gray-600
   - 진행률 계산: `(check_ins_count / target_days) * 100`
   - 프로그레스 바 표시:
     - 전체 너비 회색 배경
     - 진행률만큼 파란색으로 채워진 바
     - 퍼센트 텍스트 표시 (예: "45%")
   - "오늘 인증하기" 버튼 (일단 클릭 이벤트는 비워둠)
   - "삭제" 버튼 (일단 클릭 이벤트는 비워둠)

3. 스타일링 개선:
   - 카드들을 grid로 배치 (grid-cols-1 md:grid-cols-2 lg:grid-cols-3)
   - 간격 gap-4
   - 반응형 디자인 적용

4. 브라우저에서 확인:
   - Laravel 서버와 React 서버 둘 다 실행 중인지 확인
   - 챌린지 목록이 표시되는지 확인 (아직 데이터가 없으면 빈 상태 메시지)

기대 결과: React 앱에서 Laravel API로부터 챌린지 목록을 불러와 카드 형태로 표시합니다. 각 카드에는 제목, 설명, 진행률 바가 표시되며, Tailwind CSS로 깔끔하게 스타일링됩니다.

5
Step 5
# 챌린지 생성 폼 및 체크인 기능 구현

1. `ChallengeForm.jsx` 구현:
   - useState로 폼 필드 관리 (title, description, targetDays)
   - targetDays 기본값은 30
   - 폼 제출 시:
     - api.post('/challenges', { title, description, target_days: targetDays })
     - 성공 시 폼 초기화
     - props로 받은 onChallengeCreated 콜백 호출 (목록 새로고침용)
   - Tailwind로 폼 스타일링:
     - input, textarea에 border, padding, rounded 적용
     - "챌린지 추가" 버튼은 파란색 배경

2. `App.jsx` 수정:
   - refreshChallenges 함수 생성 (ChallengeList의 데이터 새로고침)
   - ChallengeForm에 onChallengeCreated={refreshChallenges} 전달
   - ChallengeList에도 refresh 함수 전달

3. `ChallengeCard.jsx`에 체크인 기능 추가:
   - "오늘 인증하기" 버튼 클릭 시:
     - api.post(`/challenges/${challenge.id}/check-in`)
     - 성공 시 alert("오늘 운동 인증 완료!") 또는 토스트 메시지
     - props로 받은 onCheckIn 콜백 호출 (목록 새로고침)
   - 이미 오늘 체크인했으면 버튼 비활성화 또는 "완료" 표시
     - 이를 위해 API에서 today_checked 필드 추가 필요 (Laravel 컨트롤러 수정)

4. Laravel ChallengeController의 index() 메서드 수정:
   - 각 챌린지에 오늘 체크인 여부 추가:
```php
$challenges = Challenge::withCount('checkIns')
    ->get()
    ->map(function ($challenge) {
        $challenge->today_checked = $challenge->checkIns()
            ->whereDate('check_date', Carbon::today())
            ->exists();
        return $challenge;
    });
```

5. 체크인 삭제 기능:
   - 오늘 체크인한 경우 "취소" 버튼 표시
   - 클릭 시 해당 check_in id로 DELETE 요청

6. 챌린지 삭제 기능:
   - "삭제" 버튼 클릭 시 확인 다이얼로그
   - api.delete(`/challenges/${challenge.id}`)
   - 성공 시 목록 새로고침

기대 결과: 사용자가 새 챌린지를 추가하고, 매일 운동 인증을 체크할 수 있습니다. 체크인 시 진행률이 실시간으로 업데이트되며, 오늘 이미 체크인한 경우 버튼이 비활성화되거나 "완료" 상태로 표시됩니다. 챌린지 삭제도 가능합니다.

제출된 작품 (0)

로그인 후 제출

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

댓글 (0)

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