'use client' import { useState, useEffect } from 'react' import { Trophy, Calendar, TrendingUp, ChevronRight, Flag, PartyPopper } from 'lucide-react' import { format, addDays, differenceInDays } from 'date-fns' import { Card, Button } from '@/components/ui' import { showToast } from '@/components/ui' interface Milestone { id: string cycleNumber: number date: string status: 'UPCOMING' | 'COMPLETED' | 'SKIPPED' notes?: string celebratedAt?: string } interface TreatmentPlan { id: string title: string totalCycles: number currentCycle: number startDate: string | null estimatedEnd: string | null status: 'ACTIVE' | 'PAUSED' | 'COMPLETED' cycleType: string cycleDays: number milestones: Milestone[] } interface TreatmentProgressProps { plan: TreatmentPlan | null workspaceId: string onUpdate?: () => void } export function TreatmentProgress({ plan, workspaceId, onUpdate }: TreatmentProgressProps) { const [showCelebration, setShowCelebration] = useState(false) const [celebratingMilestone, setCelebratingMilestone] = useState(null) useEffect(() => { // Check for uncelebrated completed milestones if (plan?.milestones) { const uncelebrated = plan.milestones.find( m => m.status === 'COMPLETED' && !m.celebratedAt ) if (uncelebrated) { setCelebratingMilestone(uncelebrated) setShowCelebration(true) // Mark as celebrated markCelebrated(uncelebrated.id) } } }, [plan]) const markCelebrated = async (milestoneId: string) => { try { await fetch(`/api/workspaces/${workspaceId}/treatment-plan/milestones/${milestoneId}/celebrate`, { method: 'POST' }) } catch (err) { console.error('Failed to mark celebration:', err) } } const handleCompleteCycle = async () => { if (!plan) return try { const response = await fetch(`/api/workspaces/${workspaceId}/treatment-plan/complete-cycle`, { method: 'POST' }) if (!response.ok) throw new Error('Failed to complete cycle') showToast('Cycle completed! Great job!', 'success') onUpdate?.() } catch { showToast('Failed to complete cycle', 'error') } } if (!plan) { return (

No Treatment Plan

Set up a treatment plan to track your progress

) } const progress = (plan.currentCycle / plan.totalCycles) * 100 const daysRemaining = plan.estimatedEnd ? differenceInDays(new Date(plan.estimatedEnd), new Date()) : null const milestones = plan.milestones || [] const completedCount = milestones.filter(m => m.status === 'COMPLETED').length return ( <> {/* Header */}

{plan.title}

Cycle {plan.currentCycle} of {plan.totalCycles}

{/* Progress Bar */}
{completedCount} completed {Math.round(progress)}%
{/* Stats */}

{plan.currentCycle}

Current

{plan.totalCycles - plan.currentCycle}

Remaining

{daysRemaining !== null ? Math.max(0, daysRemaining) : '?'}

Days Left

{/* Action Buttons */}
{plan.status === 'ACTIVE' && plan.currentCycle < plan.totalCycles && ( )}
{/* Milestone Preview */} {milestones.length > 0 && (

Upcoming Milestones

{milestones .filter(m => m.status === 'UPCOMING') .slice(0, 3) .map(milestone => (

Cycle {milestone.cycleNumber}

{format(new Date(milestone.date), 'MMM d, yyyy')}

))}
)} {/* Celebration Modal */} {showCelebration && celebratingMilestone && ( setShowCelebration(false)} /> )} ) } interface MilestoneCelebrationProps { milestone: Milestone plan: TreatmentPlan onClose: () => void } function MilestoneCelebration({ milestone, plan, onClose }: MilestoneCelebrationProps) { const messages = [ "You're doing amazing!", "One step closer to the finish line!", "Your strength is inspiring!", "Keep going, you've got this!", "Another milestone conquered!" ] const randomMessage = messages[Math.floor(Math.random() * messages.length)] const isHalfway = milestone.cycleNumber === Math.floor(plan.totalCycles / 2) const isFinal = milestone.cycleNumber === plan.totalCycles return (

{isFinal ? '🎉 Treatment Complete!' : isHalfway ? '🌟 Halfway There!' : 'Milestone Reached!'}

Cycle {milestone.cycleNumber} of {plan.totalCycles} completed!

{isFinal ? "You've done it! What an incredible journey." : randomMessage}

) }