diff --git a/aima-front/app/history/page.tsx b/aima-front/app/history/page.tsx index 25fff09..7fddf5e 100644 --- a/aima-front/app/history/page.tsx +++ b/aima-front/app/history/page.tsx @@ -25,9 +25,6 @@ export default function HistoryPage() { const [error, setError] = useState(null); useEffect(() => { - setLoading(true); - setError(null); - getActivityLogs(100) .then(({ activity_logs }) => setLogs(activity_logs)) .catch((e) => { diff --git a/aima-front/app/page.tsx b/aima-front/app/page.tsx index 702ce02..650f503 100644 --- a/aima-front/app/page.tsx +++ b/aima-front/app/page.tsx @@ -10,12 +10,24 @@ export default function HomePage() { const [checked, setChecked] = useState(false); useEffect(() => { - const id = getUserId(); - if (!id) { - router.replace("/onboarding"); - return; - } - setChecked(true); + let cancelled = false; + + const checkAuth = async () => { + const id = await getUserId(); + if (!id) { + router.replace("/onboarding"); + return; + } + if (!cancelled) { + setChecked(true); + } + }; + + void checkAuth(); + + return () => { + cancelled = true; + }; }, [router]); const handleLogout = () => { diff --git a/aima-front/app/recipes/page.tsx b/aima-front/app/recipes/page.tsx index f716eb7..2782e48 100644 --- a/aima-front/app/recipes/page.tsx +++ b/aima-front/app/recipes/page.tsx @@ -4,7 +4,7 @@ import { useEffect, useMemo, useState } from "react"; import { useRouter, useSearchParams } from "next/navigation"; import { createRecommendation } from "@/lib/api"; -import type { Recipe, DurationMin, Mood } from "@/lib/types"; +import type { Recipe, DurationMin, Mood, Weather } from "@/lib/types"; function parseDuration(v: string | null): DurationMin { const n = Number(v); @@ -13,6 +13,9 @@ function parseDuration(v: string | null): DurationMin { function parseMood(v: string | null): Mood { return v === "energetic" || v === "neutral" || v === "calm" ? v : "neutral"; } +function parseWeather(v: string | null): Weather { + return v === "sunny" || v === "rainy" || v === "cloudy" ? v : "sunny"; +} const moodLabel: Record = { energetic: "元気に動きたい", @@ -30,10 +33,7 @@ export default function RecipesPage() { [params] ); const mood = useMemo(() => parseMood(params.get("mood")), [params]); - const weather = useMemo( - () => (params.get("weather") as import("@/lib/types").Weather) ?? "sunny", - [params] - ); + const weather = useMemo(() => parseWeather(params.get("weather")), [params]); const [recipes, setRecipes] = useState([]); const [loading, setLoading] = useState(true); @@ -43,28 +43,33 @@ export default function RecipesPage() { useEffect(() => { let cancelled = false; - setLoading(true); - setError(null); - setSelectedRecipeId(null); - - createRecommendation({ duration_min: duration, mood, weather }) - .then((res) => { - if (cancelled) return; - setRecipes(res.recipes); - }) - .catch(() => { - if (cancelled) return; - setError("レシピの取得に失敗しました"); - }) - .finally(() => { - if (cancelled) return; - setLoading(false); - }); + const fetchRecipes = async () => { + setLoading(true); + setError(null); + setSelectedRecipeId(null); + + try { + const res = await createRecommendation({ duration_min: duration, mood, weather }); + if (!cancelled) { + setRecipes(res.recipes); + } + } catch { + if (!cancelled) { + setError("レシピの取得に失敗しました"); + } + } finally { + if (!cancelled) { + setLoading(false); + } + } + }; + + void fetchRecipes(); return () => { cancelled = true; }; - }, [duration, mood]); + }, [duration, mood, weather]); const goReview = () => { if (!selectedRecipeId) return;