-
Notifications
You must be signed in to change notification settings - Fork 2
[Feature] 데이트 취향 테스트 api 연결 완료 #101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
0d7ab0a
fead417
b531ea4
1ea7fb0
c720731
1f86f50
5da88ec
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| import type { TDateTestQuestion, TRelationTypeResponse } from '@/types/datetest/datetest'; | ||
|
|
||
| import { axiosInstance } from '../axiosInstance'; | ||
|
|
||
| export const getDateQuestions = async () => { | ||
| const res = await axiosInstance.get<TDateTestQuestion>('/api/v1/dates/preferences/questions'); | ||
| return res.data.result.questions; | ||
| }; | ||
yujin5959 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| export const submitDateTestAnswers = async (payload: { answers: number[] }) => { | ||
| const { data } = await axiosInstance.post('/api/v1/dates/preferences/tests', payload); | ||
| return data; | ||
| }; | ||
yeonjin719 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| export const postDateTestResult = async (answers: number[]): Promise<TDateTestQuestion> => { | ||
| const res = await axiosInstance.post('/api/v1/dates/preferences/tests', { answers }); | ||
| return res.data.result; | ||
| }; | ||
yujin5959 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| export const getRelationTypes = async (type: string): Promise<TRelationTypeResponse> => { | ||
| const res = await axiosInstance.get(`/api/v1/dates/preferences/relations`, { | ||
| params: { type }, | ||
| }); | ||
| return res.data; | ||
| }; | ||
yujin5959 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -1,18 +1,12 @@ | ||||||||
| import { useEffect, useState } from 'react'; | ||||||||
| import { useNavigate, useParams } from 'react-router-dom'; | ||||||||
| import { useQuery } from '@tanstack/react-query'; | ||||||||
|
|
||||||||
| interface IQuestion { | ||||||||
| id: number; | ||||||||
| title: string; | ||||||||
| options: string[]; | ||||||||
| } | ||||||||
| import type { IDateTestQuestion } from '@/types/datetest/datetest'; | ||||||||
|
|
||||||||
| import { getDateQuestions, submitDateTestAnswers } from '@/api/datetest/datetest'; | ||||||||
|
|
||||||||
| const TOTAL_QUESTIONS = 40; | ||||||||
| const dummyQuestions: IQuestion[] = Array.from({ length: TOTAL_QUESTIONS }, (_, i) => ({ | ||||||||
| id: i + 1, | ||||||||
| title: `당신의 데이트 스타일은 어떤가요?`, | ||||||||
| options: ['야외 활동 좋아해요', '집에서 쉬는 게 좋아요'], | ||||||||
| })); | ||||||||
|
|
||||||||
| function ProgressBar({ step, total }: { step: number; total: number }) { | ||||||||
| const percentage = (step / total) * 100; | ||||||||
|
|
@@ -26,19 +20,29 @@ function ProgressBar({ step, total }: { step: number; total: number }) { | |||||||
| export default function DateTestStep() { | ||||||||
| const { step } = useParams<{ step: string }>(); | ||||||||
| const navigate = useNavigate(); | ||||||||
|
|
||||||||
| const currentStep = Number(step); | ||||||||
| const question = dummyQuestions[currentStep - 1]; | ||||||||
| const currentStep = parseInt(step ?? '1', 10); | ||||||||
|
|
||||||||
| const [selectedOptions, setSelectedOptions] = useState<number[]>([]); | ||||||||
| const [allAnswers, setAllAnswers] = useState<number[]>(Array(TOTAL_QUESTIONS).fill(0)); | ||||||||
|
|
||||||||
| const { data, isLoading, isError } = useQuery<IDateTestQuestion[]>({ | ||||||||
| queryKey: ['dateTestQuestions'], | ||||||||
| queryFn: getDateQuestions, | ||||||||
| staleTime: 1000 * 60 * 5, | ||||||||
| }); | ||||||||
|
|
||||||||
| useEffect(() => { | ||||||||
| setSelectedOptions([]); | ||||||||
| const prevAnswer = allAnswers[currentStep - 1]; | ||||||||
| setSelectedOptions(prevAnswer ? [prevAnswer - 1] : []); | ||||||||
| window.scrollTo(0, 0); | ||||||||
| }, [currentStep]); | ||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. useEffect 의존성 배열 누락
- }, [currentStep]);
+ }, [currentStep, allAnswers]);📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||
|
|
||||||||
| const handleSelect = (idx: number) => { | ||||||||
| setSelectedOptions([idx]); // 항상 하나만 선택되도록 | ||||||||
| const answerValue = idx + 1; // 0 -> 1, 1 -> 2 | ||||||||
| const updatedAnswers = [...allAnswers]; | ||||||||
| updatedAnswers[currentStep - 1] = answerValue; | ||||||||
| setAllAnswers(updatedAnswers); | ||||||||
| setSelectedOptions([idx]); | ||||||||
| }; | ||||||||
|
|
||||||||
| const handlePrev = () => { | ||||||||
|
|
@@ -49,18 +53,27 @@ export default function DateTestStep() { | |||||||
| } | ||||||||
| }; | ||||||||
|
|
||||||||
| const handleNext = () => { | ||||||||
| const handleNext = async () => { | ||||||||
| if (selectedOptions.length !== 1) return; | ||||||||
|
|
||||||||
| if (currentStep < TOTAL_QUESTIONS) { | ||||||||
| navigate(`/datetest/${currentStep + 1}`); | ||||||||
| } else { | ||||||||
| navigate('/datetest/result'); | ||||||||
| try { | ||||||||
| const response = await submitDateTestAnswers({ answers: allAnswers }); | ||||||||
| console.log('결과 응답:', response); | ||||||||
yujin5959 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||
| navigate('/datetest/result', { state: response.result }); | ||||||||
yujin5959 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
| } catch (error) { | ||||||||
| console.error('결과 제출 실패:', error); | ||||||||
| alert('결과를 제출하는 중 오류가 발생했습니다.'); | ||||||||
| } | ||||||||
| } | ||||||||
| }; | ||||||||
|
|
||||||||
| if (!question) { | ||||||||
| return <div>질문을 불러올 수 없습니다.</div>; | ||||||||
| } | ||||||||
| if (isLoading) return <div className="text-center mt-20">질문을 불러오는 중입니다...</div>; | ||||||||
| if (isError || !data || !data[currentStep - 1]) return <div>질문을 불러올 수 없습니다.</div>; | ||||||||
yujin5959 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
|
|
||||||||
| const question = data[currentStep - 1]; | ||||||||
|
|
||||||||
| return ( | ||||||||
| <div className="flex flex-col px-6 max-w-3xl mx-auto py-[156px]"> | ||||||||
|
|
@@ -88,16 +101,19 @@ export default function DateTestStep() { | |||||||
| </div> | ||||||||
|
|
||||||||
| {/* 질문 */} | ||||||||
| <h2 className="text-2xl font-bold mb-6 text-left w-full">{question.title}</h2> | ||||||||
| <h2 className="text-2xl font-bold mb-6 text-left w-full">{question.question}</h2> | ||||||||
|
|
||||||||
| {/* 선택지 */} | ||||||||
| <div className="flex flex-col gap-4 w-full"> | ||||||||
| {question.options.map((opt, idx) => ( | ||||||||
| {[question.firstAnswer, question.secondAnswer].map((opt, idx) => ( | ||||||||
| <button | ||||||||
| key={idx} | ||||||||
| onClick={() => handleSelect(idx)} | ||||||||
| className={`w-full text-left px-5 py-3 rounded-lg border border-[#C3C3C3] | ||||||||
| ${selectedOptions.includes(idx) ? 'bg-primary-700 text-white border-primary-700' : 'bg-white text-gray-800 hover:bg-primary-100 border border-[#c3c3c3]'}`} | ||||||||
| className={`w-full text-left px-5 py-3 rounded-lg border ${ | ||||||||
| selectedOptions.includes(idx) | ||||||||
| ? 'bg-primary-700 text-white border-primary-700' | ||||||||
| : 'bg-white text-gray-800 hover:bg-primary-100 border-[#c3c3c3]' | ||||||||
| }`} | ||||||||
| aria-pressed={selectedOptions.includes(idx)} | ||||||||
| type="button" | ||||||||
| > | ||||||||
|
|
||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
응답 타입 import 보강 제안 (POST 결과 타입 명시용)
POST 응답 결과 타입을 명확히 다루기 위해
TDateTestResultResponse(존재한다면)를 함께 import하는 것을 권장합니다. 없다면 타입 정의에 추가하거나, 아래 다른 코멘트의 대안(인라인 결과 타입)으로 가도 됩니다.다음 diff는
TDateTestResultResponse가 이미 존재한다는 가정하에 제안합니다:🏁 Script executed:
Length of output: 161
🏁 Script executed:
Length of output: 1309
src/api/datetest/datetest.ts – POST 응답 타입 보강 제안
TDateTestResultResponse가 이미 정의되어 있으므로, 상단 import에 함께 추가한 뒤 POST 요청 시 제네릭으로 지정해 응답 타입 안정성을 높이는 것을 권장합니다:추가로, POST 호출부를 아래처럼 수정하면 좋습니다:
📝 Committable suggestion
🤖 Prompt for AI Agents