풀스택 온라인 투표 시스템 - 실시간 결과 차트
online-poll-realtime-chart
문제 설명
🗳️ 프로젝트 개요
간단한 설문조사와 투표를 만들고 실시간으로 결과를 차트로 확인할 수 있는 풀스택 웹 애플리케이션입니다. Laravel 13.x API 백엔드와 React 19 프론트엔드를 분리하여 구성하며, RESTful API를 통해 데이터를 주고받습니다.
사용자는 투표 주제를 만들고 여러 선택지를 추가할 수 있으며, 다른 사용자들은 투표에 참여할 수 있습니다. 투표 결과는 막대 차트로 시각화되어 실시간으로 업데이트됩니다.
✅ 필수 기능
- 투표 생성: 제목과 2개 이상의 선택지 입력
- 투표 목록 조회: 생성된 모든 투표 리스트 표시
- 투표 참여: 선택지 중 하나를 선택하여 투표
- 결과 시각화: Chart.js를 사용한 막대 차트로 투표 결과 표시
- 투표 결과 실시간 업데이트: 투표 후 자동으로 차트 갱신
- 중복 투표 방지: 브라우저 localStorage 활용
🎁 선택 추가 기능 (보너스)
- 투표 삭제 기능
- 투표 마감 기능 (종료일 설정)
- 투표 공유 링크 생성
- 투표 참여자 수 표시
- 다크 모드 지원
- 반응형 디자인 개선
제약 조건
- • Laravel 13.x 백엔드 (RESTful API 서버)
- • React 19 프론트엔드 (Vite 기반 별도 프로젝트)
- • SQLite 데이터베이스 사용
- • Chart.js 라이브러리로 차트 시각화
- • Tailwind CSS로 스타일링
- • fetch 또는 axios로 API 호출
- • 중복 투표 방지는 localStorage 활용 (간단한 방식)
- • useState만 사용 (복잡한 상태관리 라이브러리 금지)
프롬프트 레시피
아래 프롬프트를 순서대로 AI에게 보내면 됩니다. 복사 버튼을 눌러 바로 사용하세요.
mkdir online-poll-realtime-chart && cd online-poll-realtime-chart
이 폴더에서 Laravel 13.x API 백엔드 프로젝트를 시작합니다.
다음 작업을 수행해주세요:
1. Laravel 13.x 프로젝트 생성 (composer create-project laravel/laravel backend)
2. backend 폴더로 이동 후 .env 파일에서 DB_CONNECTION을 sqlite로 변경
3. database/database.sqlite 파일 생성 (touch database/database.sqlite)
4. Poll 모델과 마이그레이션 생성:
- php artisan make:model Poll -m
- polls 테이블: id, title (string), created_at, updated_at
5. Option 모델과 마이그레이션 생성:
- php artisan make:model Option -m
- options 테이블: id, poll_id (foreign key), text (string), votes (integer, default 0), created_at, updated_at
6. Poll과 Option 모델에 관계 설정:
- Poll 모델에 hasMany('App\Models\Option') 관계 추가
- Option 모델에 belongsTo('App\Models\Poll') 관계 추가
7. 마이그레이션 실행: php artisan migrate
8. PollController 생성:
- php artisan make:controller PollController
- index: 모든 투표 목록 반환 (옵션 포함)
- store: 새 투표 생성 (제목과 선택지 배열 받기)
- show: 특정 투표 상세 정보 반환
9. VoteController 생성:
- php artisan make:controller VoteController
- vote 메서드: 특정 옵션의 votes 컬럼 +1 증가
10. routes/api.php에 라우트 등록:
- GET /api/polls (모든 투표 목록)
- POST /api/polls (투표 생성)
- GET /api/polls/{id} (특정 투표 조회)
- POST /api/polls/{pollId}/vote/{optionId} (투표하기)
11. CORS 설정: config/cors.php에서 'paths' => ['api/*']로 설정하고 'allowed_origins' => ['http://localhost:5173'] 추가
12. php artisan serve로 서버 실행 확인 (http://localhost:8000)
모든 코드를 작성하고 테스트해주세요.
기대 결과: Laravel 백엔드 API 서버가 구축되고, polls와 options 테이블이 생성됩니다. API 엔드포인트가 정상 작동하며, Postman이나 curl로 테스트 가능한 상태입니다.
이제 React 19 프론트엔드 프로젝트를 생성합니다.
online-poll-realtime-chart 폴더(백엔드와 같은 레벨)에서 다음 작업을 수행해주세요:
1. React 프로젝트 생성:
- npm create vite@latest frontend -- --template react
- cd frontend && npm install
2. Tailwind CSS 설치 및 설정:
- npm install -D tailwindcss postcss autoprefixer
- npx tailwindcss init -p
- tailwind.config.js에서 content: ["./index.html", "./src/**/*.{js,jsx}"] 설정
- src/index.css에 @tailwind 지시어 추가
3. Chart.js 설치:
- npm install chart.js react-chartjs-2
4. src/App.jsx 초기 구조 작성:
- useState로 polls 상태 관리
- useEffect로 컴포넌트 마운트 시 GET /api/polls 호출하여 투표 목록 가져오기
- fetch('http://localhost:8000/api/polls')로 API 호출
- 투표 목록을 카드 형태로 표시 (제목만 우선)
5. Tailwind CSS로 기본 레이아웃 스타일링:
- 헤더: "📊 온라인 투표 시스템" 제목
- 투표 목록 그리드 레이아웃 (grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3)
6. npm run dev로 개발 서버 실행 (http://localhost:5173)
7. 브라우저에서 투표 목록이 표시되는지 확인
모든 코드를 작성하고 화면에 투표 목록이 렌더링되는지 확인해주세요.
기대 결과: React 프론트엔드가 실행되고, Tailwind CSS가 적용되며, Laravel API에서 투표 목록을 가져와 화면에 표시됩니다. Chart.js가 설치되어 다음 단계에서 사용할 준비가 완료됩니다.
투표 생성 폼을 추가합니다.
src/components/CreatePollForm.jsx 컴포넌트를 생성하고 다음 기능을 구현해주세요:
1. 폼 상태 관리:
- title (투표 제목)
- options (선택지 배열, 초기값 ['', ''])
2. 입력 필드:
- 제목 입력란 (input type="text")
- 선택지 입력란 (input type="text" 여러 개)
- "선택지 추가" 버튼 (options 배열에 빈 문자열 추가)
3. 폼 제출:
- POST /api/polls로 { title, options: [{ text: '...' }, { text: '...' }] } 전송
- 성공 시 부모 컴포넌트에 onPollCreated 콜백 호출하여 목록 새로고침
4. Tailwind CSS로 폼 스타일링:
- 카드 형태 (bg-white shadow-md rounded-lg p-6)
- 버튼: bg-blue-500 hover:bg-blue-600 text-white
5. App.jsx에 CreatePollForm 컴포넌트 추가:
- 헤더 아래에 배치
- onPollCreated 콜백으로 투표 목록 다시 가져오기
모든 코드를 작성하고 브라우저에서 투표를 생성할 수 있는지 테스트해주세요.
기대 결과: 투표 생성 폼이 화면에 표시되고, 제목과 선택지를 입력하여 새 투표를 생성할 수 있습니다. 생성 후 투표 목록이 자동으로 업데이트됩니다.
투표 카드에 차트와 투표 기능을 추가합니다.
src/components/PollCard.jsx 컴포넌트를 생성하고 다음 기능을 구현해주세요:
1. props로 poll 객체 받기 (id, title, options 포함)
2. Chart.js Bar 차트 렌더링:
- react-chartjs-2의 Bar 컴포넌트 사용
- data: { labels: options.map(o => o.text), datasets: [{ label: '투표 수', data: options.map(o => o.votes), backgroundColor: 'rgba(59, 130, 246, 0.5)' }] }
3. 투표 버튼:
- 각 선택지마다 버튼 표시
- 클릭 시 POST /api/polls/{pollId}/vote/{optionId} 호출
- 투표 후 GET /api/polls/{pollId}로 최신 데이터 가져와 차트 업데이트
4. 중복 투표 방지:
- localStorage에 voted_poll_{pollId} 키로 투표 여부 저장
- 이미 투표한 경우 버튼 비활성화 및 "이미 투표했습니다" 메시지 표시
5. Tailwind CSS로 카드 스타일링:
- 그림자, 둥근 모서리, 패딩
- 버튼: bg-green-500 hover:bg-green-600 disabled:bg-gray-300
6. App.jsx에서 PollCard 사용:
- polls.map(poll => <PollCard key={poll.id} poll={poll} />)
모든 코드를 작성하고 브라우저에서 투표하고 차트가 업데이트되는지 확인해주세요.
기대 결과: 투표 카드에 Chart.js 막대 차트가 표시되고, 선택지 버튼을 클릭하면 투표가 진행됩니다. 투표 후 차트가 실시간으로 업데이트되며, localStorage로 중복 투표가 방지됩니다.
제출된 작품 (0)
로그인 후 제출아직 제출된 작품이 없습니다. 첫 번째 도전자가 되어보세요!