-
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 all 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,34 @@ | ||||||||||||||||||||||||||||||
| 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'); | ||||||||||||||||||||||||||||||
| if (!res.data.isSuccess) { | ||||||||||||||||||||||||||||||
| throw new Error(res.data.message || '질문을 불러오는데 실패했습니다'); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| return res.data.result.questions; | ||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||
|
Comment on lines
+5
to
+11
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. 🧹 Nitpick (assertive) 성공/실패 분기 추가는 좋습니다. 반환 타입 명시로 API 계약을 더 분명히 해주세요 현재도 타입 추론은 되지만, 외부에 공개되는 함수 시그니처를 명시하면 유지보수성이 좋아집니다. 다음처럼 반환 타입을 명시해 주세요: -export const getDateQuestions = async () => {
+export const getDateQuestions = async (): Promise<TDateTestQuestion['result']['questions']> => {📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| export const submitDateTestAnswers = async (payload: { answers: number[] }) => { | ||||||||||||||||||||||||||||||
| const { data } = await axiosInstance.post('/api/v1/dates/preferences/tests', payload); | ||||||||||||||||||||||||||||||
| if (!data.isSuccess) { | ||||||||||||||||||||||||||||||
| throw new Error(data.message || '답변 제출에 실패했습니다'); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| return data; | ||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||
|
Comment on lines
+13
to
+19
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. 🛠️ Refactor suggestion 응답 처리 일관성: result만 반환하도록 통일 + POST 제네릭/반환 타입 지정 이 모듈에서 일부 함수는 다음 diff는 -export const submitDateTestAnswers = async (payload: { answers: number[] }) => {
- const { data } = await axiosInstance.post('/api/v1/dates/preferences/tests', payload);
- if (!data.isSuccess) {
- throw new Error(data.message || '답변 제출에 실패했습니다');
- }
- return data;
-};
+export const submitDateTestAnswers = async (
+ payload: { answers: number[] }
+): Promise<TDateTestResultResponse['result']> => {
+ const { data } = await axiosInstance.post<TDateTestResultResponse>(
+ '/api/v1/dates/preferences/tests',
+ payload
+ );
+ if (!data.isSuccess) {
+ throw new Error(data.message || '답변 제출에 실패했습니다');
+ }
+ return data.result;
+};대안: type DateTestSubmitResult = TDateTestQuestion['result']; // 혹은 실제 결과 스키마에 맞는 타입🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| 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 }, | ||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||
| if (!res.data.isSuccess) { | ||||||||||||||||||||||||||||||
| throw new Error(res.data.message || '관계 유형을 불러오는데 실패했습니다'); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| return res.data; | ||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||
|
Comment on lines
+26
to
+34
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. 🛠️ Refactor suggestion axios 제네릭 누락 및 반환 형태 일관성 개선 GET 응답 제네릭을 지정하면 내부에서도 정확한 타입을 얻을 수 있습니다. 또한 모듈 내 일관성을 위해 다음과 같이 수정해 주세요: -export const getRelationTypes = async (type: string): Promise<TRelationTypeResponse> => {
- const res = await axiosInstance.get(`/api/v1/dates/preferences/relations`, {
- params: { type },
- });
- if (!res.data.isSuccess) {
- throw new Error(res.data.message || '관계 유형을 불러오는데 실패했습니다');
- }
- return res.data;
-};
+export const getRelationTypes = async (
+ type: string
+): Promise<TRelionTypeResponse['result']> => {
+ const res = await axiosInstance.get<TRelationTypeResponse>(
+ `/api/v1/dates/preferences/relations`,
+ { params: { type } }
+ );
+ if (!res.data.isSuccess) {
+ throw new Error(res.data.message || '관계 유형을 불러오는데 실패했습니다');
+ }
+ return res.data.result;
+};참고: 위 변경이 어렵다면 최소한
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||
| 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,26 @@ 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 }); | ||||||||
| navigate('/datetest/result', { state: response.result }); | ||||||||
yujin5959 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
| } catch (error) { | ||||||||
| console.error('결과 제출 실패:', error); | ||||||||
| alert('결과를 제출하는 중 오류가 발생했습니다.'); | ||||||||
| } | ||||||||
yujin5959 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
| } | ||||||||
| }; | ||||||||
|
|
||||||||
| 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 +100,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