import { useState, useEffect } from 'react'; import { Routes, Route, useNavigate } from 'react-router-dom'; import { goalsApi, type Goal, type GoalStats } from '@/lib/api/goals'; import { GoalDetail } from './GoalDetail'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Progress } from '@/components/ui/progress'; import { Badge } from '@/components/ui/badge'; import { Plus, Target, TrendingUp, CheckCircle2, Loader2, Calendar, DollarSign } from 'lucide-react'; import { toast } from 'sonner'; import { CreateGoalDialog } from './goals/CreateGoalDialog'; import { useLanguage } from '@/contexts/LanguageContext'; function GoalsList() { const { t } = useLanguage(); const navigate = useNavigate(); const [goals, setGoals] = useState([]); const [stats, setStats] = useState(null); const [loading, setLoading] = useState(true); const [filter, setFilter] = useState('all'); const [createDialogOpen, setCreateDialogOpen] = useState(false); useEffect(() => { fetchGoals(); fetchStats(); }, [filter]); const fetchGoals = async () => { try { setLoading(true); const status = filter === 'all' ? undefined : filter; const data = await goalsApi.getAll(status); setGoals(data); } catch (error) { console.error('Failed to fetch goals:', error); toast.error(t.common.error); } finally { setLoading(false); } }; const fetchStats = async () => { try { const data = await goalsApi.getStats(); setStats(data); } catch (error) { console.error('Failed to fetch stats:', error); } }; const handleGoalCreated = () => { setCreateDialogOpen(false); fetchGoals(); fetchStats(); toast.success(t.goals.goalCreated); }; const getProgressColor = (progress: number) => { if (progress >= 100) return 'bg-green-500'; if (progress >= 75) return 'bg-blue-500'; if (progress >= 50) return 'bg-yellow-500'; return 'bg-gray-500'; }; const formatCurrency = (amount: number, currency: string) => { return new Intl.NumberFormat('id-ID', { style: 'currency', currency: currency || 'IDR', minimumFractionDigits: 0, maximumFractionDigits: 0, }).format(amount); }; const formatDate = (dateString?: string) => { if (!dateString) return t.goals.noDeadline; const date = new Date(dateString); const now = new Date(); const diffTime = date.getTime() - now.getTime(); const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)); if (diffDays < 0) return t.goals.overdue; if (diffDays === 0) return t.goals.today; if (diffDays === 1) return t.goals.tomorrow; if (diffDays < 30) return t.goals.daysLeft.replace('{days}', diffDays.toString()); return date.toLocaleDateString('id-ID', { day: 'numeric', month: 'short', year: 'numeric' }); }; const getStatusBadge = (status: string) => { const variants: Record = { active: { variant: 'default', label: t.goals.status.active }, completed: { variant: 'secondary', label: t.goals.status.completed }, archived: { variant: 'outline', label: t.goals.status.archived }, cancelled: { variant: 'destructive', label: t.goals.status.cancelled }, }; const config = variants[status] || variants.active; return {config.label}; }; if (loading && goals.length === 0) { return (
); } return (
{/* Header */}

{t.goals.title}

{t.goals.pageDescription}

{/* Stats Cards */} {stats && (
{t.goals.totalGoals}
{stats.totalGoals}

{stats.activeGoals} {t.goals.activeGoals.toLowerCase()}

{t.goals.completedGoals}
{stats.completedGoals}

{stats.totalGoals > 0 ? Math.round((stats.completedGoals / stats.totalGoals) * 100) : 0}% completion rate

{t.goals.totalTarget}
{formatCurrency(stats.totalTargetAmount, 'IDR')}

{t.goals.acrossAllActiveGoals}

{t.goals.overallProgress}
{stats.overallProgress.toFixed(1)}%
)} {/* Filter Tabs */}
{['all', 'active', 'completed', 'archived'].map((status) => ( ))}
{/* Goals Grid */} {goals.length === 0 ? (

{t.goals.noGoalsYet}

{t.goals.noGoalsDescription}

) : (
{goals.map((goal) => { const progress = goal.targetAmount > 0 ? (goal.currentAmount / goal.targetAmount) * 100 : 0; return ( navigate(`/goals/${goal.id}`)} >
{goal.name} {goal.description && ( {goal.description} )}
{getStatusBadge(goal.status)}
{/* Progress Circle */}
{Math.round(progress)}%
{/* Amount */}
Current {formatCurrency(goal.currentAmount, goal.currency)}
Target {formatCurrency(goal.targetAmount, goal.currency)}
{/* Target Date */} {goal.targetDate && (
{formatDate(goal.targetDate)}
)} {/* Milestones */}
{goal.milestones.map((milestone) => (
))}
); })}
)} {/* Create Goal Dialog */}
); } export function Goals() { return ( } /> } /> ); }