"use client"; import { useEffect, useState, useCallback } from "react"; import { useRouter } from "next/navigation"; import { useAuth } from "@/lib/auth"; import { useTranslation } from "@/lib/i18n"; import { getGoals, getGoal, createGoal, updateGoal, deleteGoal, generateGoalPlan, getGoalReport, getGroups, Goal, GoalPlanResult, GoalReport, Group, } from "@/lib/api"; import PageActionBar from "@/components/features/PageActionBar"; import GoalActionButtons from "@/components/features/GoalActionButtons"; import IconButton from "@/components/features/IconButton"; export default function GoalsPage() { const { token } = useAuth(); const { t, locale } = useTranslation(); const router = useRouter(); const [goals, setGoals] = useState([]); const [groups, setGroups] = useState([]); const [loading, setLoading] = useState(true); const [showForm, setShowForm] = useState(false); const [selectedGoal, setSelectedGoal] = useState<(Goal & { tasks?: unknown[] }) | null>(null); const [planResult, setPlanResult] = useState(null); const [report, setReport] = useState(null); const [aiLoading, setAiLoading] = useState(null); const [error, setError] = useState(null); const [formTitle, setFormTitle] = useState(""); const [formDate, setFormDate] = useState(""); const [formGroup, setFormGroup] = useState(""); const dateLocale = locale === "ua" ? "uk-UA" : locale === "cs" ? "cs-CZ" : locale === "he" ? "he-IL" : "ru-RU"; const loadData = useCallback(async () => { if (!token) return; setLoading(true); try { const [goalsRes, groupsRes] = await Promise.all([ getGoals(token), getGroups(token), ]); setGoals(goalsRes.data || []); setGroups(groupsRes.data || []); } catch (err) { console.error("Load error:", err); setError(t("common.error")); } finally { setLoading(false); } }, [token, t]); useEffect(() => { if (!token) { router.replace("/login"); return; } loadData(); }, [token, router, loadData]); async function handleCreate(e: React.FormEvent) { e.preventDefault(); if (!token || !formTitle.trim()) return; try { await createGoal(token, { title: formTitle.trim(), target_date: formDate || null, group_id: formGroup || null, }); setFormTitle(""); setFormDate(""); setFormGroup(""); setShowForm(false); loadData(); } catch (err) { console.error("Create error:", err); setError(t("common.error")); } } async function handleSelectGoal(goal: Goal) { if (!token) return; try { const res = await getGoal(token, goal.id); setSelectedGoal(res.data); setPlanResult(null); setReport(null); } catch (err) { console.error("Load goal error:", err); } } async function handleGeneratePlan(goalId: string) { if (!token) return; setAiLoading("plan"); setError(null); try { const res = await generateGoalPlan(token, goalId); setPlanResult(res.data); const updated = await getGoal(token, goalId); setSelectedGoal(updated.data); loadData(); } catch (err) { console.error("Plan error:", err); setError(t("common.error")); } finally { setAiLoading(null); } } async function handleGetReport(goalId: string) { if (!token) return; setAiLoading("report"); setError(null); try { const res = await getGoalReport(token, goalId); setReport(res.data); } catch (err) { console.error("Report error:", err); setError(t("common.error")); } finally { setAiLoading(null); } } async function handleUpdateProgress(goalId: string, pct: number) { if (!token) return; try { await updateGoal(token, goalId, { progress_pct: pct } as Partial); loadData(); if (selectedGoal && selectedGoal.id === goalId) { setSelectedGoal({ ...selectedGoal, progress_pct: pct }); } } catch (err) { console.error("Update error:", err); } } async function handleDelete(goalId: string) { if (!token) return; if (!confirm(t("tasks.confirmDelete"))) return; try { await deleteGoal(token, goalId); setSelectedGoal(null); loadData(); } catch (err) { console.error("Delete error:", err); } } function formatDate(d: string | null) { if (!d) return t("tasks.noDue"); return new Date(d).toLocaleDateString(dateLocale, { day: "numeric", month: "short", year: "numeric" }); } function progressColor(pct: number) { if (pct >= 80) return "bg-green-500"; if (pct >= 50) return "bg-blue-500"; if (pct >= 20) return "bg-yellow-500"; return "bg-gray-400"; } if (!token) return null; return (
setShowForm(!showForm)} addOpen={showForm} t={t} /> {error && (
{error}
)} {showForm && (
setFormTitle(e.target.value)} className="w-full px-3 py-2 border rounded-lg dark:bg-gray-800 dark:border-gray-700 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-blue-500 min-h-[44px]" required />
setFormDate(e.target.value)} className="w-full px-3 py-2 border rounded-lg dark:bg-gray-800 dark:border-gray-700 dark:text-white focus:ring-2 focus:ring-blue-500 min-h-[44px]" />
)} {loading ? (
) : goals.length === 0 ? (
🎯

{t("goals.title")}

) : (
{goals.map((goal) => ( ))}
)} {/* Goal detail panel */} {selectedGoal && (

{selectedGoal.title}

{formatDate(selectedGoal.target_date)} | {t("goals.progress")}: {selectedGoal.progress_pct}%

} label={t("tasks.close")} onClick={() => setSelectedGoal(null)} variant="default" size="md" />
{/* Progress slider */}
handleUpdateProgress(selectedGoal.id, parseInt(e.target.value))} className="w-full h-2 bg-gray-200 dark:bg-gray-700 rounded-lg appearance-none cursor-pointer accent-blue-600" />
{/* AI Action buttons - icon only */} handleGeneratePlan(selectedGoal.id)} onReport={() => handleGetReport(selectedGoal.id)} onDelete={() => handleDelete(selectedGoal.id)} planLoading={aiLoading === "plan"} reportLoading={aiLoading === "report"} t={t} /> {/* Plan result */} {planResult && (

{t("goals.plan")} ({planResult.tasks_created})

{planResult.plan.weeks ? (
{(planResult.plan.weeks as Array<{ week_number: number; focus: string; tasks: Array<{ title: string; duration_hours?: number; day_of_week?: string }> }>).map((week, i) => (

#{week.week_number}: {week.focus}

    {(week.tasks || []).map((wt, j) => (
  • {wt.title} {wt.duration_hours && ({wt.duration_hours}h)} {wt.day_of_week && [{wt.day_of_week}]}
  • ))}
))}
) : (
                  {JSON.stringify(planResult.plan, null, 2)}
                
)}
)} {/* AI Report */} {report && (

{t("goals.report")}

{report.stats.done}/{report.stats.total} ({report.stats.pct}%)

{report.report}

)} {/* Existing plan */} {selectedGoal.plan && Object.keys(selectedGoal.plan).length > 0 && !planResult && (

{t("goals.plan")}

{(selectedGoal.plan as Record).weeks ? (
{((selectedGoal.plan as Record).weeks as Array<{ week_number: number; focus: string; tasks: Array<{ title: string; duration_hours?: number; day_of_week?: string }> }>).map((week, i) => (

#{week.week_number}: {week.focus}

    {(week.tasks || []).map((wt, j) => (
  • {wt.title}
  • ))}
))}
) : (
                  {JSON.stringify(selectedGoal.plan, null, 2)}
                
)}
)} {/* Related tasks */} {selectedGoal.tasks && selectedGoal.tasks.length > 0 && (

{t("nav.tasks")} ({selectedGoal.tasks.length})

{(selectedGoal.tasks as Array<{ id: string; title: string; status: string }>).map((task) => (
{task.title} {t(`tasks.status.${task.status}`)}
))}
)}
)}
); }