구현 코드 및 설명
route.ts
import { createClient } from "@/supabase/server";
import { NextResponse } from "next/server";
export async function GET() {
const supabase = createClient();
const { data: allFood , error } = await supabase.from("recommend").select("*");
if (!allFood) {
return NextResponse.json({ error: "전체 데이터 가져오기 실패" }, { status: 404 });
}
return NextResponse.json(allFood);
}
- Supabase 클라이언트를 생성하고, recommend 테이블에서 모든 데이터를 선택하여 allFood 변수에 저장한다.
- 만약 요청 중에 에러가 발생하면 error 변수에 저장된다.
FoodWorldCup.tsx
const FoodWorldCup = () => {
const getWorldCupFood = async () => {
const response = await fetch("/api/worldcup");
if (!response.ok) {
Report.failure("음식 추천에 오류가 있습니다", "잠시 후 다시 시도해주세요.", "확인");
}
return response.json();
};
- getWorldCupFood 함수
- 서버에서 음식 데이터를 가져오는 비동기 함수이다.
- API 요청이 성공하면 응답을 JSON 형식으로 반환하고, 실패하면 알림을 표시한다.
const { data: food } = useQuery<Recommend[]>({
queryKey: ["getAllFood"],
queryFn: getWorldCupFood,
});
- useQuery를 사용해 getWorldCupFood 함수를 호출하여 데이터를 패칭한다. 가져온 음식 데이터는 food 변수에 저장된다.
const [currentRound, setCurrentRound] = useState<Recommend[]>([]);
const [currentPair, setCurrentPair] = useState<number>(0);
const [winners, setWinners] = useState<Recommend[]>([]);
const [_, setSelectedMenuIndex] = useState<number | null>(null);
- currentRound: 현재 라운드에서 비교할 음식 목록을 저장한다.
- currentPair: 현재 비교할 음식 쌍의 인덱스를 저장한다.
- winners: 각 라운드에서 선택된 승자들을 저장한다.
- setSelectedMenuIndex: 사용자가 선택한 메뉴의 인덱스를 저장하지만, 이 상태는 이후의 로직에 의해 관리된다.
useEffect(() => {
if (food) {
setCurrentRound(food);
}
}, [food]);
- 음식 데이터를 패칭한 후, 이 데이터를 현재 라운드로 설정한다.
const handleSelect = (winnerIndex: number) => {
const selectedWinner = currentRound[currentPair + winnerIndex];
setWinners((prevWinners) => [...prevWinners, selectedWinner]);
setSelectedMenuIndex(winnerIndex);
- handleSelect 함수
- 사용자가 선택한 음식을 winners 배열에 추가한다.
- 현재 라운드의 쌍 중에서 사용자가 선택한 인덱스(winnerIndex)를 기반으로 승자를 결정한다.
if (currentPair + 2 < currentRound.length) {
setCurrentPair(currentPair + 2);
} else {
if (currentRound.length === 2) {
Report.success(`최종 우승: ${selectedWinner.menu}`, "", "확인");
} else {
setCurrentRound([...winners, selectedWinner]);
setCurrentPair(0);
setWinners([]);
}
}
};
- 다음 쌍을 설정하거나, 만약 현재 라운드의 마지막 쌍이라면, 새로운 라운드를 시작한다.
- 만약 최종 우승자가 결정되면, 성공 메시지를 표시한다.
let currentRoundPairs: Recommend[] = [];
if (currentPair < currentRound.length) {
currentRoundPairs = [currentRound[currentPair], currentRound[currentPair + 1]];
}
const handleReset = () => {
setCurrentRound(food || []);
setCurrentPair(0);
setWinners([]);
setSelectedMenuIndex(null);
};
- handleReset 함수
- 게임을 초기화한다.
- 모든 상태를 초기 상태로 되돌려 게임을 다시 시작할 수 있게 한다.