#TIL 48일차(월드컵 기능)

앙꼬·2024년 7월 12일

부트캠프

목록 보기
47/59

구현 코드 및 설명

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 함수
    • 게임을 초기화한다.
    • 모든 상태를 초기 상태로 되돌려 게임을 다시 시작할 수 있게 한다.
profile
프론트 개발자 꿈꾸는 중

0개의 댓글