'use client'; import { useState, useEffect } from 'react'; import { Box, Typography, Button, Paper, TextField, FormControl, InputLabel, Select, MenuItem, IconButton, Alert, CircularProgress, Card, CardContent, Dialog, DialogTitle, DialogContent, DialogContentText, DialogActions, Chip, Snackbar, } from '@mui/material'; import { ArrowBack, Save, MedicalServices, Delete, Refresh, ChildCare, Add, } from '@mui/icons-material'; import { useRouter } from 'next/navigation'; import { AppShell } from '@/components/layouts/AppShell/AppShell'; import { ProtectedRoute } from '@/components/common/ProtectedRoute'; import { withErrorBoundary } from '@/components/common/ErrorFallbacks'; import { useAuth } from '@/lib/auth/AuthContext'; import { trackingApi, Activity } from '@/lib/api/tracking'; import { childrenApi, Child } from '@/lib/api/children'; import { VoiceInputButton } from '@/components/voice/VoiceInputButton'; import { FormSkeleton, ActivityListSkeleton } from '@/components/common/LoadingSkeletons'; import { motion } from 'framer-motion'; import { useLocalizedDate } from '@/hooks/useLocalizedDate'; import { useTranslation } from '@/hooks/useTranslation'; interface MedicineData { medicineName: string; dosage: string; unit?: string; route?: 'oral' | 'topical' | 'injection' | 'other'; reason?: string; } function MedicineTrackPage() { const router = useRouter(); const { user } = useAuth(); const { t } = useTranslation('tracking'); const { formatDistanceToNow } = useLocalizedDate(); const [children, setChildren] = useState([]); const [selectedChild, setSelectedChild] = useState(''); // Medicine state const [medicineName, setMedicineName] = useState(''); const [dosage, setDosage] = useState(''); const [unit, setUnit] = useState('ml'); const [route, setRoute] = useState<'oral' | 'topical' | 'injection' | 'other'>('oral'); const [reason, setReason] = useState(''); // Common state const [notes, setNotes] = useState(''); const [recentMedicines, setRecentMedicines] = useState([]); const [loading, setLoading] = useState(false); const [childrenLoading, setChildrenLoading] = useState(true); const [medicinesLoading, setMedicinesLoading] = useState(false); const [error, setError] = useState(null); const [successMessage, setSuccessMessage] = useState(null); // Delete confirmation dialog const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); const [activityToDelete, setActivityToDelete] = useState(null); const familyId = user?.families?.[0]?.familyId; // Load children useEffect(() => { if (familyId) { loadChildren(); } }, [familyId]); // Load recent medicines when child is selected useEffect(() => { if (selectedChild) { loadRecentMedicines(); } }, [selectedChild]); const loadChildren = async () => { if (!familyId) return; try { setChildrenLoading(true); const childrenData = await childrenApi.getChildren(familyId); setChildren(childrenData); if (childrenData.length > 0) { setSelectedChild(childrenData[0].id); } } catch (err: any) { console.error('Failed to load children:', err); setError(err.response?.data?.message || 'Failed to load children'); } finally { setChildrenLoading(false); } }; const loadRecentMedicines = async () => { if (!selectedChild) return; try { setMedicinesLoading(true); const activities = await trackingApi.getActivities(selectedChild, 'medicine'); // Sort by timestamp descending and take last 10 const sorted = activities.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime() ).slice(0, 10); setRecentMedicines(sorted); } catch (err: any) { console.error('Failed to load recent medicines:', err); } finally { setMedicinesLoading(false); } }; const handleSubmit = async () => { if (!selectedChild) { setError('Please select a child'); return; } // Validation if (!medicineName) { setError('Please enter medicine name'); return; } if (!dosage) { setError('Please enter dosage'); return; } try { setLoading(true); setError(null); const data: MedicineData = { medicineName, dosage, unit, route, reason: reason || undefined, }; await trackingApi.createActivity(selectedChild, { type: 'medicine', timestamp: new Date().toISOString(), data, notes: notes || undefined, }); setSuccessMessage('Medicine logged successfully!'); // Reset form resetForm(); // Reload recent medicines await loadRecentMedicines(); } catch (err: any) { console.error('Failed to save medicine:', err); setError(err.response?.data?.message || 'Failed to save medicine'); } finally { setLoading(false); } }; const resetForm = () => { setMedicineName(''); setDosage(''); setUnit('ml'); setRoute('oral'); setReason(''); setNotes(''); }; const handleDeleteClick = (activityId: string) => { setActivityToDelete(activityId); setDeleteDialogOpen(true); }; const handleDeleteConfirm = async () => { if (!activityToDelete) return; try { setLoading(true); await trackingApi.deleteActivity(activityToDelete); setSuccessMessage('Medicine deleted successfully'); setDeleteDialogOpen(false); setActivityToDelete(null); await loadRecentMedicines(); } catch (err: any) { console.error('Failed to delete medicine:', err); setError(err.response?.data?.message || 'Failed to delete medicine'); } finally { setLoading(false); } }; const getMedicineDetails = (activity: Activity) => { const data = activity.data as MedicineData; let details = `${data.dosage} ${data.unit || ''}`; if (data.route) { details += ` - ${data.route.charAt(0).toUpperCase() + data.route.slice(1)}`; } if (data.reason) { details += ` - ${data.reason}`; } return details; }; if (childrenLoading) { return ( {t('activities.medicine')} {t('activities.medicine')} ); } if (!familyId || children.length === 0) { return ( No Children Added You need to add a child before you can track medicine activities ); } return ( router.back()} sx={{ mr: 2 }}> {t('activities.medicine')} { console.log('[Medicine] Voice transcript:', transcript); }} onClassifiedIntent={(result) => { if (result.intent === 'medicine' && result.structuredData) { const data = result.structuredData; // Auto-fill form with voice data if (data.medicineName) setMedicineName(data.medicineName); if (data.dosage) setDosage(data.dosage.toString()); if (data.unit) setUnit(data.unit); if (data.route) setRoute(data.route); if (data.reason) setReason(data.reason); } }} size="medium" /> {error && ( setError(null)}> {error} )} {/* Child Selector */} {children.length > 1 && ( Select Child )} {/* Main Form */} Medicine Information setMedicineName(e.target.value)} sx={{ mb: 3 }} placeholder="e.g., Acetaminophen, Ibuprofen" required /> setDosage(e.target.value)} placeholder="e.g., 5, 2.5" required /> Unit Route setReason(e.target.value)} sx={{ mb: 3 }} placeholder="e.g., Fever, Pain, Allergy" /> setNotes(e.target.value)} sx={{ mb: 3 }} placeholder={t('feeding.placeholders.notes')} /> {/* Recent Medicines */} {t('activities.medicine')} {medicinesLoading ? ( ) : recentMedicines.length === 0 ? ( {t('noEntries')} ) : ( {recentMedicines.map((activity, index) => { const data = activity.data as MedicineData; if (!data || !data.medicineName) { console.warn('[Medicine] Activity missing medicineName:', activity); return null; } return ( {data.medicineName} {getMedicineDetails(activity)} {activity.notes && ( {activity.notes} )} handleDeleteClick(activity.id)} disabled={loading} > ); })} )} {/* Delete Confirmation Dialog */} setDeleteDialogOpen(false)} > {t('deleteEntry')} {t('confirmDelete')} {/* Success Snackbar */} setSuccessMessage(null)} message={successMessage} /> ); } export default withErrorBoundary(MedicineTrackPage, 'form');