'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, Tabs, Tab, } from '@mui/material'; import { ArrowBack, Save, MedicalServices, Delete, Refresh, ChildCare, Add, Thermostat, LocalHospital, Medication as MedicationIcon, } 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'; import { UnitInput } from '@/components/forms/UnitInput'; import { convertVolume, convertTemperature } from '@/lib/utils/unitConversion'; import { MeasurementSystem } from '@/hooks/useLocale'; type MedicalActivityType = 'medication' | 'temperature' | 'doctor'; interface MedicationData { medicineName: string; dosage: string; unit?: string; route?: 'oral' | 'topical' | 'injection' | 'other'; reason?: string; } interface TemperatureData { temperature: number; // stored in Celsius location?: 'oral' | 'rectal' | 'armpit' | 'ear' | 'forehead'; symptoms?: string; } interface DoctorVisitData { visitType: 'checkup' | 'emergency' | 'followup' | 'vaccination' | 'other'; diagnosis?: string; treatment?: string; doctorName?: string; } function MedicalTrackPage() { const router = useRouter(); const { user } = useAuth(); const { t } = useTranslation('tracking'); const { formatDistanceToNow } = useLocalizedDate(); const [children, setChildren] = useState([]); const [selectedChild, setSelectedChild] = useState(''); const [activityType, setActivityType] = useState('medication'); // Medication state const [medicineName, setMedicineName] = useState(''); const [dosage, setDosage] = useState(0); const [dosageText, setDosageText] = useState(''); const [unit, setUnit] = useState('ml'); const [route, setRoute] = useState<'oral' | 'topical' | 'injection' | 'other'>('oral'); const [reason, setReason] = useState(''); // Temperature state const [temperature, setTemperature] = useState(0); const [tempLocation, setTempLocation] = useState<'oral' | 'rectal' | 'armpit' | 'ear' | 'forehead'>('oral'); const [symptoms, setSymptoms] = useState(''); // Doctor visit state const [visitType, setVisitType] = useState<'checkup' | 'emergency' | 'followup' | 'vaccination' | 'other'>('checkup'); const [diagnosis, setDiagnosis] = useState(''); const [treatment, setTreatment] = useState(''); const [doctorName, setDoctorName] = useState(''); // Common state const [notes, setNotes] = useState(''); const [recentActivities, setRecentActivities] = useState([]); const [loading, setLoading] = useState(false); const [childrenLoading, setChildrenLoading] = useState(true); const [activitiesLoading, setActivitiesLoading] = 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; useEffect(() => { if (familyId) { loadChildren(); } }, [familyId]); useEffect(() => { if (selectedChild) { loadRecentActivities(); } }, [selectedChild, activityType]); 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 || t('common.error.loadChildrenFailed')); } finally { setChildrenLoading(false); } }; const loadRecentActivities = async () => { if (!selectedChild) return; try { setActivitiesLoading(true); // Load all medical-related activities (including legacy 'medicine' type) const medicalTypes = ['medication', 'temperature', 'doctor', 'medicine']; const allActivities = await Promise.all( medicalTypes.map(type => trackingApi.getActivities(selectedChild, type as any).catch(() => []) ) ); // Flatten and filter by current tab (but include legacy 'medicine' in medication tab) const flatActivities = allActivities.flat(); const filtered = flatActivities.filter(activity => { if (activityType === 'medication') { // Include both 'medication' and legacy 'medicine' types return activity.type === 'medication' || activity.type === 'medicine'; } return activity.type === activityType; }); const sorted = filtered.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime() ).slice(0, 10); setRecentActivities(sorted); } catch (err: any) { console.error('Failed to load recent activities:', err); } finally { setActivitiesLoading(false); } }; const handleSubmit = async () => { if (!selectedChild) { setError(t('common.selectChild')); return; } // Validation based on activity type if (activityType === 'medication') { if (!medicineName) { setError(t('health.medicineName.required')); return; } const dosageValue = unit === 'ml' ? dosage : dosageText; if (!dosageValue || (unit === 'ml' && dosage === 0) || (unit !== 'ml' && !dosageText)) { setError(t('health.dosage.required')); return; } } else if (activityType === 'temperature') { if (temperature === 0) { setError('Please enter temperature'); return; } } else if (activityType === 'doctor') { if (!visitType) { setError('Please select visit type'); return; } } try { setLoading(true); setError(null); let data: MedicationData | TemperatureData | DoctorVisitData; if (activityType === 'medication') { data = { medicineName, dosage: unit === 'ml' ? dosage.toString() : dosageText, unit, route, reason: reason || undefined, }; } else if (activityType === 'temperature') { data = { temperature, location: tempLocation, symptoms: symptoms || undefined, }; } else { data = { visitType, diagnosis: diagnosis || undefined, treatment: treatment || undefined, doctorName: doctorName || undefined, }; } await trackingApi.createActivity(selectedChild, { type: activityType, timestamp: new Date().toISOString(), data, notes: notes || undefined, }); setSuccessMessage(`${activityType.charAt(0).toUpperCase() + activityType.slice(1)} logged successfully!`); resetForm(); await loadRecentActivities(); } catch (err: any) { console.error('Failed to save activity:', err); setError(err.response?.data?.message || 'Failed to save activity'); } finally { setLoading(false); } }; const resetForm = () => { // Medication setMedicineName(''); setDosage(0); setDosageText(''); setUnit('ml'); setRoute('oral'); setReason(''); // Temperature setTemperature(0); setTempLocation('oral'); setSymptoms(''); // Doctor visit setVisitType('checkup'); setDiagnosis(''); setTreatment(''); setDoctorName(''); setNotes(''); }; const handleDeleteClick = (activityId: string) => { setActivityToDelete(activityId); setDeleteDialogOpen(true); }; const handleDeleteConfirm = async () => { if (!activityToDelete) return; try { setLoading(true); await trackingApi.deleteActivity(activityToDelete); setSuccessMessage('Activity deleted successfully'); setDeleteDialogOpen(false); setActivityToDelete(null); await loadRecentActivities(); } catch (err: any) { console.error('Failed to delete activity:', err); setError(err.response?.data?.message || 'Failed to delete activity'); } finally { setLoading(false); } }; const getActivityDetails = (activity: Activity) => { // Handle both 'medication' and legacy 'medicine' types if (activity.type === 'medication' || activity.type === 'medicine') { const data = activity.data as MedicationData; if (data.unit === 'ml') { const measurementSystem: MeasurementSystem = (user?.preferences?.measurementUnit as MeasurementSystem) || 'metric'; const converted = convertVolume(parseFloat(data.dosage), measurementSystem); const roundedValue = Math.round(converted.value * 10) / 10; let details = `${roundedValue} ${converted.unit}`; if (data.route) details += ` - ${data.route.charAt(0).toUpperCase() + data.route.slice(1)}`; if (data.reason) details += ` - ${data.reason}`; return details; } 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; } else if (activity.type === 'temperature') { const data = activity.data as TemperatureData; const measurementSystem: MeasurementSystem = (user?.preferences?.measurementUnit as MeasurementSystem) || 'metric'; const converted = convertTemperature(data.temperature, measurementSystem); const roundedValue = Math.round(converted.value * 10) / 10; let details = `${roundedValue}${converted.unit}`; if (data.location) details += ` - ${data.location.charAt(0).toUpperCase() + data.location.slice(1)}`; if (data.symptoms) details += ` - ${data.symptoms}`; return details; } else if (activity.type === 'doctor') { const data = activity.data as DoctorVisitData; let details = data.visitType.charAt(0).toUpperCase() + data.visitType.slice(1); if (data.doctorName) details += ` - Dr. ${data.doctorName}`; if (data.diagnosis) details += ` - ${data.diagnosis}`; return details; } return ''; }; const getActivityIcon = (type: string) => { switch (type) { case 'medication': case 'medicine': // Legacy type return ; case 'temperature': return ; case 'doctor': return ; default: return ; } }; const getActivityTitle = (activity: Activity) => { if (activity.type === 'medication' || activity.type === 'medicine') { const data = activity.data as MedicationData; return data.medicineName; } else if (activity.type === 'temperature') { return 'Temperature Reading'; } else if (activity.type === 'doctor') { return 'Doctor Visit'; } return 'Medical Record'; }; if (childrenLoading) { return ( Medical ); } if (!familyId || children.length === 0) { return ( {t('common.noChildrenAdded')} {t('common.noChildrenMessage')} ); } return ( router.back()} sx={{ mr: 2 }}> Medical { console.log('[Medical] Voice transcript:', transcript); }} onClassifiedIntent={(result) => { if (result.intent === 'medicine' && result.structuredData) { const data = result.structuredData; setActivityType('medication'); if (data.medicineName) setMedicineName(data.medicineName); if (data.unit) setUnit(data.unit); if (data.dosage) { if (data.unit === 'ml') { setDosage(typeof data.dosage === 'number' ? data.dosage : parseFloat(data.dosage)); } else { setDosageText(data.dosage.toString()); } } if (data.route) setRoute(data.route); if (data.reason) setReason(data.reason); } }} size="medium" /> {error && ( setError(null)}> {error} )} {/* Child Selector */} {children.length > 1 && ( {t('common.selectChild')} )} {/* Activity Type Tabs */} setActivityType(newValue)} variant="fullWidth"> } iconPosition="start" label="Medication" value="medication" /> } iconPosition="start" label="Temperature" value="temperature" /> } iconPosition="start" label="Doctor Visit" value="doctor" /> {/* Main Form */} {activityType === 'medication' && ( <> {t('health.medicineInfo')} setMedicineName(e.target.value)} sx={{ mb: 3 }} placeholder={t('health.medicineName.placeholder')} required /> {unit === 'ml' ? ( setDosage(metricValue)} required /> ) : ( setDosageText(e.target.value)} placeholder={t('health.dosage.placeholder')} required /> )} {t('health.unit')} {t('health.route.label')} setReason(e.target.value)} sx={{ mb: 3 }} placeholder={t('health.reason.placeholder')} /> )} {activityType === 'temperature' && ( <> Temperature Reading setTemperature(metricValue)} required sx={{ mb: 3 }} /> Measurement Location setSymptoms(e.target.value)} sx={{ mb: 3 }} placeholder="e.g., Fever, Cough, Runny nose" /> )} {activityType === 'doctor' && ( <> Doctor Visit Visit Type setDoctorName(e.target.value)} sx={{ mb: 3 }} placeholder="Dr. Smith" /> setDiagnosis(e.target.value)} sx={{ mb: 3 }} placeholder="Enter diagnosis or findings" /> setTreatment(e.target.value)} sx={{ mb: 3 }} placeholder="Enter prescribed treatment" /> )} setNotes(e.target.value)} sx={{ mb: 3 }} placeholder={t('feeding.placeholders.notes')} /> {/* Recent Activities */} Recent {activityType.charAt(0).toUpperCase() + activityType.slice(1)} Records {activitiesLoading ? ( ) : recentActivities.length === 0 ? ( {t('noEntries')} ) : ( {recentActivities.map((activity, index) => ( {getActivityIcon(activity.type)} {getActivityTitle(activity)} {getActivityDetails(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(MedicalTrackPage, 'form');