const appState = { data: null, userId: localStorage.getItem("nht:userId") || "", view: localStorage.getItem("nht:view") || "weekly", date: localStorage.getItem("nht:date") || new Date().toISOString().slice(0, 10), }; const accentChoices = ["green", "blue", "red", "pink", "orange"]; const $ = (selector, root = document) => root.querySelector(selector); const $$ = (selector, root = document) => Array.from(root.querySelectorAll(selector)); function escapeHtml(value) { return String(value ?? "") .replaceAll("&", "&") .replaceAll("<", "<") .replaceAll(">", ">") .replaceAll('"', """) .replaceAll("'", "'"); } function number(value, digits = 0) { const numeric = Number(value || 0); return numeric.toLocaleString(undefined, { maximumFractionDigits: digits, minimumFractionDigits: digits, }); } function shortDate(value) { const date = new Date(`${value}T00:00:00`); return date.toLocaleDateString(undefined, { month: "short", day: "numeric" }); } function longDate(value) { const date = new Date(`${value}T00:00:00`); return date.toLocaleDateString(undefined, { weekday: "short", month: "short", day: "numeric", year: "numeric", }); } function addDays(dateString, days) { const date = new Date(`${dateString}T00:00:00`); date.setDate(date.getDate() + days); return date.toISOString().slice(0, 10); } function dateRange(start, end) { const days = []; let cursor = start; while (cursor <= end) { days.push(cursor); cursor = addDays(cursor, 1); } return days; } function showToast(message) { const toast = $("#toast"); toast.textContent = message; toast.classList.add("show"); window.clearTimeout(showToast.timer); showToast.timer = window.setTimeout(() => toast.classList.remove("show"), 2400); } async function api(action, payload = null, method = "POST") { const options = { method }; if (payload) { options.headers = { "Content-Type": "application/json" }; options.body = JSON.stringify(payload); } const response = await fetch(`/api.php?action=${encodeURIComponent(action)}`, options); const json = await response.json(); if (!response.ok || json.error) { throw new Error(json.error || "Request failed."); } return json; } async function loadState() { const params = new URLSearchParams({ action: "state", view: appState.view, date: appState.date, }); if (appState.userId) { params.set("user_id", appState.userId); } const response = await fetch(`/api.php?${params.toString()}`); const json = await response.json(); if (!response.ok || json.error) { throw new Error(json.error || "Unable to load tracker state."); } appState.data = json; appState.userId = String(json.currentUser.id); appState.view = json.view; appState.date = json.range.anchor; localStorage.setItem("nht:userId", appState.userId); localStorage.setItem("nht:view", appState.view); localStorage.setItem("nht:date", appState.date); render(); } function render() { if (!appState.data) return; applyTheme(); renderControls(); renderSummaries(); renderMedical(); renderTimeline(); renderNutrition(); renderRoutines(); renderSupplements(); renderAdmin(); renderLibraries(); populateForms(); } function applyTheme() { const user = appState.data.currentUser; const mode = user.theme_mode || "dark"; const accent = accentChoices.includes(user.theme_accent) ? user.theme_accent : "green"; document.body.dataset.theme = mode; document.body.dataset.accent = accent; $("#darkModeButton").classList.toggle("active", mode === "dark"); $("#lightModeButton").classList.toggle("active", mode === "light"); $$("[data-accent]").forEach((button) => { button.classList.toggle("active", button.dataset.accent === accent); }); } function renderControls() { const data = appState.data; const user = data.currentUser; $("#profileFocus").textContent = user.fitness_focus || "Multi-profile medical dashboard"; if (data.currentUserIsAdmin) { $("#profileFocus").textContent += " / admin"; } $("#rangeCopy").textContent = `${data.view[0].toUpperCase()}${data.view.slice(1)} view: ${longDate(data.range.start)} to ${longDate(data.range.end)}`; $("#datePicker").value = data.range.anchor; $("#profileSelect").innerHTML = data.users .map((profile) => ``) .join(""); $$("[data-view]").forEach((button) => { button.classList.toggle("active", button.dataset.view === data.view); }); } function renderSummaries() { const { latestVitals, medicationLogs, labResults, symptomLogs, allergyRecords, appointments } = appState.data; const medicationTaken = medicationLogs.filter((item) => item.status === "taken").length; const bp = latestVitals && Number(latestVitals.systolic) > 0 ? `${latestVitals.systolic}/${latestVitals.diastolic}` : "No BP"; const highestSeverity = symptomLogs.reduce((max, item) => Math.max(max, Number(item.severity || 0)), 0); const activeAllergies = allergyRecords.filter((item) => item.status === "active").length; const scheduledAppointments = appointments.filter((item) => item.status === "scheduled").length; const cards = [ ["Medications", `${number(medicationLogs.length)}`, `${number(medicationTaken)} taken in range`], ["Blood Pressure", bp, latestVitals ? `${number(latestVitals.pulse)} pulse` : "No vitals log"], ["Glucose", latestVitals && Number(latestVitals.glucose_mg_dl) > 0 ? `${number(latestVitals.glucose_mg_dl)} mg/dL` : "No glucose", latestVitals ? `${number(latestVitals.oxygen_pct, 1)}% oxygen` : "No oxygen log"], ["Labs", `${number(labResults.length)}`, "results in range"], ["Symptoms", `${number(symptomLogs.length)}`, `highest severity ${number(highestSeverity)}`], ["Allergies", `${number(activeAllergies)}`, `${number(allergyRecords.length)} total records`], ["Appointments", `${number(scheduledAppointments)}`, "scheduled in range"], ]; $("#summaryGrid").innerHTML = cards .map(([label, value, detail]) => `
${escapeHtml(label)} ${escapeHtml(value)} ${escapeHtml(detail)}
`) .join(""); } function renderTimeline() { const { range, workouts } = appState.data; const byDate = new Map(); workouts.forEach((workout) => { if (!byDate.has(workout.scheduled_on)) byDate.set(workout.scheduled_on, []); byDate.get(workout.scheduled_on).push(workout); }); const html = dateRange(range.start, range.end).map((date) => { const entries = byDate.get(date) || []; const volume = entries.reduce((sum, workout) => sum + Number(workout.sets || 0) * Number(workout.reps || 0) * Number(workout.weight_lbs || 0), 0); const minutes = entries.reduce((sum, workout) => sum + Number(workout.duration_min || 0), 0); return `
${longDate(date)} ${entries.length} workouts / ${number(minutes)} min / ${number(volume)} lb
${entries.length ? entries.map(renderWorkoutItem).join("") : `
No workouts scheduled
`}
`; }).join(""); $("#workoutTimeline").innerHTML = html || `
No planner days found
`; } function renderWorkoutItem(workout) { const liftLine = Number(workout.weight_lbs) > 0 ? `${number(workout.sets)} x ${number(workout.reps)} @ ${number(workout.weight_lbs, 1)} lb` : ""; const cardioLine = Number(workout.duration_min) || Number(workout.distance_mi) ? `${number(workout.duration_min)} min${Number(workout.distance_mi) ? ` / ${number(workout.distance_mi, 2)} mi` : ""}` : ""; const details = [workout.workout_type, workout.exercise_name, liftLine, cardioLine, workout.intensity] .filter(Boolean) .join(" | "); return `

${escapeHtml(workout.title)}

${escapeHtml(details || "Open workout")}

${workout.routine_name ? `

${escapeHtml(workout.routine_name)}

` : ""}
${escapeHtml(workout.status)}
${workout.notes ? `

${escapeHtml(workout.notes)}

` : ""}
${["planned", "complete", "skipped"].map((status) => ` `).join("")}
`; } function renderMedical() { renderMedicationLogs(); renderVitalLogs(); renderLabResults(); renderSymptomLogs(); renderAllergyRecords(); renderAppointments(); renderImmunizationRecords(); renderStudies(); } function renderMedicationLogs() { const logs = appState.data.medicationLogs || []; $("#medicationLogList").innerHTML = logs.length ? logs.map((log) => `

${escapeHtml(log.medication_name)}

${shortDate(log.taken_on)} | ${escapeHtml(log.dose || "open dose")} | ${escapeHtml(log.route || "route not set")} | ${escapeHtml(log.frequency || "frequency not set")}

${log.class_name ? `

${escapeHtml(log.class_name)}

` : ""}
${escapeHtml(log.status)}

${escapeHtml([log.prescriber, log.notes].filter(Boolean).join(" | ") || "No notes")}

${log.rxnorm_url ? `RxNorm` : ""}
`).join("") : `
No medication logs in this range
`; } function renderVitalLogs() { const logs = appState.data.vitalLogs || []; $("#vitalLogList").innerHTML = logs.length ? logs.map((log) => { const bp = Number(log.systolic) > 0 ? `${log.systolic}/${log.diastolic}` : "No BP"; return `
${shortDate(log.measured_on)} ${bp}

${number(log.pulse)} pulse / ${number(log.temperature_f, 1)} F / ${number(log.oxygen_pct, 1)}% O2 / ${number(log.glucose_mg_dl)} glucose / pain ${number(log.pain_score)}

${escapeHtml([log.symptoms, log.notes].filter(Boolean).join(" | ") || "No symptoms noted")}

`; }).join("") : `
No vitals in this range
`; } function renderLabResults() { const labs = appState.data.labResults || []; $("#labResultList").innerHTML = labs.length ? labs.map((lab) => `
${escapeHtml(lab.test_name)} ${escapeHtml(lab.result_value)} ${escapeHtml(lab.unit || "")}

${shortDate(lab.collected_on)} / ${escapeHtml(lab.reference_range || "No reference range")}

${escapeHtml([lab.ordering_clinician, lab.notes].filter(Boolean).join(" | ") || "No notes")}

`).join("") : `
No lab results in this range
`; } function renderSymptomLogs() { const logs = appState.data.symptomLogs || []; $("#symptomLogList").innerHTML = logs.length ? logs.map((log) => `
${escapeHtml(log.symptom)} severity ${number(log.severity)}

${shortDate(log.observed_on)} / ${escapeHtml(log.body_area || "body area not set")} / ${escapeHtml(log.duration || "duration not set")}

${escapeHtml([log.triggers, log.action_taken, log.notes].filter(Boolean).join(" | ") || "No notes")}

`).join("") : `
No symptom logs in this range
`; } function renderAllergyRecords() { const records = appState.data.allergyRecords || []; $("#allergyRecordList").innerHTML = records.length ? records.map((record) => `
${escapeHtml(record.allergen)} ${escapeHtml(record.severity)}

${escapeHtml(record.reaction || "Reaction not set")} / ${escapeHtml(record.status)}

${escapeHtml([record.first_noted_on ? `first noted ${shortDate(record.first_noted_on)}` : "", record.notes].filter(Boolean).join(" | ") || "No notes")}

`).join("") : `
No allergy records yet
`; } function renderAppointments() { const appointments = appState.data.appointments || []; $("#appointmentList").innerHTML = appointments.length ? appointments.map((appointment) => `
${escapeHtml(appointment.reason)} ${escapeHtml(appointment.status)}

${shortDate(appointment.appointment_on)} / ${escapeHtml(appointment.clinician || "clinician not set")} / ${escapeHtml(appointment.specialty || "specialty not set")}

${escapeHtml([appointment.location, appointment.follow_up_notes].filter(Boolean).join(" | ") || "No follow-up notes")}

`).join("") : `
No appointments in this range
`; } function renderImmunizationRecords() { const records = appState.data.immunizationRecords || []; $("#immunizationRecordList").innerHTML = records.length ? records.slice(0, 8).map((record) => `
${escapeHtml(record.vaccine_name)} ${shortDate(record.administered_on)}

${escapeHtml(record.dose || "dose not set")} / ${escapeHtml(record.clinician_or_site || "site not set")}

${escapeHtml([record.next_due_on ? `next due ${shortDate(record.next_due_on)}` : "", record.lot_number ? `lot ${record.lot_number}` : "", record.notes].filter(Boolean).join(" | ") || "No notes")}

`).join("") : `
No immunization records yet
`; } function renderStudies() { const studies = (appState.data.researchStudies || []).slice(0, 6); $("#studyList").innerHTML = studies.length ? studies.map((study) => `

${escapeHtml(study.title)}

${escapeHtml(study.category)} | ${escapeHtml(study.related_medicine || "general")}

${escapeHtml(study.study_type || "research")}

${escapeHtml(study.summary)}

NIH/NLM PubMed ClinicalTrials.gov
`).join("") : `
No study links seeded
`; } function renderNutrition() { const { nutritionSummary, nutritionLogs } = appState.data; const target = nutritionSummary.target; const actual = nutritionSummary.actual; const macros = [ ["Calories", "calories", "kcal"], ["Protein", "protein_g", "g"], ["Carbs", "carbs_g", "g"], ["Fat", "fat_g", "g"], ["Water", "water_ml", "ml"], ]; const macroHtml = macros.map(([label, key, unit]) => { const targetValue = Number(target[key] || 0); const actualValue = Number(actual[key] || 0); const percent = targetValue > 0 ? Math.min((actualValue / targetValue) * 100, 140) : 0; return `
${label} ${number(actualValue)} / ${number(targetValue)} ${unit}
`; }).join(""); const logHtml = nutritionLogs.length ? nutritionLogs.map((log) => `
${shortDate(log.logged_on)} ${number(log.calories)} kcal

${number(log.protein_g)}g protein / ${number(log.carbs_g)}g carbs / ${number(log.fat_g)}g fat / ${number(log.water_ml)}ml water

${log.notes ? `

${escapeHtml(log.notes)}

` : ""}
`).join("") : `
No nutrition logs in this range
`; $("#nutritionCompare").innerHTML = `
${macroHtml}

Selected Target

${escapeHtml(target.label)} (${escapeHtml(target.scope)})

${escapeHtml(target.scaled_from)} basis
${logHtml}
`; } function renderRoutines() { const routines = appState.data.routines; $("#routineList").innerHTML = routines.length ? routines.map((routine) => `

${escapeHtml(routine.name)}

${escapeHtml(routine.workout_type)} / ${escapeHtml(routine.planner_scope)} / ${escapeHtml(routine.intensity || "open intensity")}

${routine.active ? "active" : "paused"}

Nutrition: ${escapeHtml(routine.nutrition_goal_label || "separate target")}

${routine.notes ? `

${escapeHtml(routine.notes)}

` : ""}
`).join("") : `
No routines yet
`; } function renderSupplements() { const logs = appState.data.supplementLogs; $("#supplementLogList").innerHTML = logs.length ? logs.map((log) => `

${escapeHtml(log.supplement_name || "Custom supplement")}

${shortDate(log.taken_on)} / ${escapeHtml(log.timing)} / ${escapeHtml(log.dose || "open dose")}

${escapeHtml(log.status)}
${log.supplement_purpose ? `

${escapeHtml(log.supplement_purpose)}

` : ""} ${log.notes ? `

${escapeHtml(log.notes)}

` : ""}
`).join("") : `
No supplement logs in this range
`; } function renderAdmin() { const panel = $("#adminPanel"); if (!panel) return; const isAdminUser = Boolean(appState.data.currentUserIsAdmin); panel.hidden = !isAdminUser; if (!isAdminUser) { return; } const summary = appState.data.adminSummary || {}; const statCards = [ ["Total", summary.total_users || 0], ["Active", summary.active_users || 0], ["Inactive", summary.inactive_users || 0], ["Admins", summary.admins || 0], ["Members", summary.members || 0], ]; $("#adminStats").innerHTML = statCards.map(([label, value]) => `
${escapeHtml(label)} ${number(value)}
`).join(""); const currentId = Number(appState.data.currentUser.id); const rows = appState.data.adminUsers || []; $("#adminUserList").innerHTML = rows.length ? rows.map((user) => { const isCurrent = Number(user.id) === currentId; const toggleStatus = user.status === "active" ? "inactive" : "active"; const training = user.training_level ? ` / ${user.training_level}` : ""; const height = Number(user.height_in) > 0 ? ` / ${number(user.height_in, 1)} in` : ""; return `

${escapeHtml(user.name)}${isCurrent ? " (current)" : ""}

${escapeHtml(user.email || "No email")}

${escapeHtml(user.fitness_focus || "No care focus set")}

${escapeHtml(user.phone || "No phone")}${escapeHtml(training)}${escapeHtml(height)}

${escapeHtml(user.role)} ${escapeHtml(user.status)}
${number(user.routine_count)} routines ${number(user.workout_count)} workouts ${number(user.nutrition_log_count)} nutrition logs ${number(user.supplement_log_count)} supplement logs ${number(user.metric_count)} metrics ${number(user.medication_log_count)} meds ${number(user.vital_log_count)} vitals ${number(user.lab_result_count)} labs ${number(user.appointment_count)} appointments
`; }).join("") : `
No profiles found
`; } function resetAdminUserForm() { const form = $("#adminUserForm"); if (!form) return; form.reset(); form.elements.target_user_id.value = ""; form.elements.role.value = "member"; form.elements.status.value = "active"; form.elements.theme_mode.value = "dark"; form.elements.theme_accent.value = "green"; $("#adminUserFormTitle").textContent = "Create Profile"; } function fillAdminUserForm(user) { const form = $("#adminUserForm"); if (!form || !user) return; form.elements.target_user_id.value = user.id || ""; form.elements.name.value = user.name || ""; form.elements.email.value = user.email || ""; form.elements.role.value = user.role || "member"; form.elements.status.value = user.status || "active"; form.elements.phone.value = user.phone || ""; form.elements.birthday.value = user.birthday || ""; form.elements.height_in.value = Number(user.height_in || 0) > 0 ? user.height_in : ""; form.elements.training_level.value = user.training_level || ""; form.elements.theme_mode.value = user.theme_mode || "dark"; form.elements.theme_accent.value = user.theme_accent || "green"; form.elements.fitness_focus.value = user.fitness_focus || ""; form.elements.emergency_contact.value = user.emergency_contact || ""; $("#adminUserFormTitle").textContent = `Edit ${user.name}`; } function renderLibraries() { $("#exerciseLibrary").innerHTML = appState.data.exercises.map((exercise) => ` ${escapeHtml(exercise.name)} ${escapeHtml(exercise.category)} / ${escapeHtml(exercise.default_unit || "custom")} `).join(""); $("#supplementLibrary").innerHTML = appState.data.supplements.map((supplement) => ` ${escapeHtml(supplement.name)} ${escapeHtml(supplement.timing)} / ${escapeHtml(supplement.default_dose || "custom")} `).join(""); } function option(value, label, selected = false) { return ``; } function populateForms() { const { routines, exercises, supplements, nutritionGoals, medicationCatalog, range } = appState.data; const routineOptions = option("", "No routine") + routines.map((routine) => option(routine.id, `${routine.name} (${routine.planner_scope})`)).join(""); const goalOptions = option("", "Separate target") + nutritionGoals.map((goal) => option(goal.id, `${goal.label} (${goal.scope})`)).join(""); const exerciseOptions = option("", "Choose exercise") + exercises.map((exercise) => option(exercise.id, `${exercise.name} (${exercise.category})`)).join(""); const supplementOptions = option("", "Choose supplement") + supplements.map((supplement) => option(supplement.id, `${supplement.name} (${supplement.timing})`)).join(""); const medicationOptions = option("", "Choose medication") + medicationCatalog.map((medicine) => option(medicine.id, `${medicine.generic_name} (${medicine.class_name})`)).join(""); $$("#workoutForm [name='routine_id']").forEach((select) => select.innerHTML = routineOptions); $$("#routineForm [name='nutrition_goal_id']").forEach((select) => select.innerHTML = goalOptions); $$("#workoutForm [name='exercise_id']").forEach((select) => select.innerHTML = exerciseOptions); $$("#supplementLogForm [name='supplement_id']").forEach((select) => select.innerHTML = supplementOptions); $$("#medicationLogForm [name='medication_id']").forEach((select) => select.innerHTML = medicationOptions); const dateFields = [ "#medicationLogForm [name='taken_on']", "#vitalLogForm [name='measured_on']", "#labResultForm [name='collected_on']", "#symptomLogForm [name='observed_on']", "#appointmentForm [name='appointment_on']", "#immunizationRecordForm [name='administered_on']", "#workoutForm [name='scheduled_on']", "#routineForm [name='start_date']", "#nutritionGoalForm [name='start_date']", "#nutritionLogForm [name='logged_on']", "#supplementLogForm [name='taken_on']", "#metricForm [name='measured_on']", ]; dateFields.forEach((selector) => { const input = $(selector); if (input && !input.value) input.value = range.anchor; }); } function formPayload(form) { const payload = Object.fromEntries(new FormData(form).entries()); payload.user_id = appState.data.currentUser.id; return payload; } function adminUserPayload(form) { const payload = Object.fromEntries(new FormData(form).entries()); payload.acting_user_id = appState.data.currentUser.id; return payload; } function wireForm(selector, action, message, afterSave = null) { const form = $(selector); form.addEventListener("submit", async (event) => { event.preventDefault(); try { const result = await api(action, formPayload(form)); if (afterSave) afterSave(result); form.reset(); await loadState(); showToast(message); } catch (error) { showToast(error.message); } }); } function wireControls() { $("#profileSelect").addEventListener("change", async (event) => { appState.userId = event.target.value; localStorage.setItem("nht:userId", appState.userId); await loadState(); }); $("#datePicker").addEventListener("change", async (event) => { appState.date = event.target.value; localStorage.setItem("nht:date", appState.date); await loadState(); }); $$("[data-view]").forEach((button) => { button.addEventListener("click", async () => { appState.view = button.dataset.view; localStorage.setItem("nht:view", appState.view); await loadState(); }); }); $("#darkModeButton").addEventListener("click", () => saveTheme("dark")); $("#lightModeButton").addEventListener("click", () => saveTheme("light")); $$("[data-accent]").forEach((button) => { button.addEventListener("click", () => saveTheme(null, button.dataset.accent)); }); $("#workoutTimeline").addEventListener("click", async (event) => { const button = event.target.closest("[data-workout-id]"); if (!button) return; try { await api("update_workout", { id: button.dataset.workoutId, status: button.dataset.status, }); await loadState(); showToast("Workout updated"); } catch (error) { showToast(error.message); } }); document.addEventListener("click", (event) => { const jump = event.target.closest("[data-jump]"); if (!jump) return; const target = $(jump.dataset.jump); if (target) { target.scrollIntoView({ behavior: "smooth", block: "start" }); } }); $("#workoutForm [name='exercise_id']").addEventListener("change", (event) => { const exercise = appState.data.exercises.find((item) => String(item.id) === event.target.value); const title = $("#workoutForm [name='title']"); const type = $("#workoutForm [name='workout_type']"); if (exercise && !title.value) title.value = exercise.name; if (exercise) type.value = exercise.category; }); $("#supplementLogForm [name='supplement_id']").addEventListener("change", (event) => { const supplement = appState.data.supplements.find((item) => String(item.id) === event.target.value); if (!supplement) return; $("#supplementLogForm [name='timing']").value = supplement.timing; $("#supplementLogForm [name='dose']").value = supplement.default_dose; }); $("#medicationLogForm [name='medication_id']").addEventListener("change", (event) => { const medicine = appState.data.medicationCatalog.find((item) => String(item.id) === event.target.value); if (!medicine) return; $("#medicationLogForm [name='medication_name']").value = medicine.generic_name; if (!$("#medicationLogForm [name='notes']").value) { $("#medicationLogForm [name='notes']").value = medicine.tracking_note; } }); $("#newAdminUserButton").addEventListener("click", () => { resetAdminUserForm(); $("#adminUserForm").scrollIntoView({ behavior: "smooth", block: "start" }); }); $("#clearAdminUserFormButton").addEventListener("click", resetAdminUserForm); $("#adminUserList").addEventListener("click", async (event) => { const button = event.target.closest("[data-admin-action]"); if (!button) return; const user = (appState.data.adminUsers || []).find((item) => String(item.id) === button.dataset.adminUserId); if (!user) return; if (button.dataset.adminAction === "edit") { fillAdminUserForm(user); $("#adminUserForm").scrollIntoView({ behavior: "smooth", block: "start" }); return; } if (button.dataset.adminAction === "status") { try { await api("update_user", { acting_user_id: appState.data.currentUser.id, target_user_id: user.id, status: button.dataset.nextStatus, }); await loadState(); showToast("Profile status updated"); } catch (error) { showToast(error.message); } return; } if (button.dataset.adminAction === "delete") { const ok = window.confirm(`Delete ${user.name} and all of this profile's tracker data?`); if (!ok) return; try { await api("delete_user", { acting_user_id: appState.data.currentUser.id, target_user_id: user.id, }); await loadState(); showToast("Profile deleted"); } catch (error) { showToast(error.message); } } }); } async function saveTheme(mode = null, accent = null) { const current = appState.data.currentUser; try { await api("update_theme", { user_id: current.id, theme_mode: mode || current.theme_mode || "dark", theme_accent: accent || current.theme_accent || "green", }); await loadState(); } catch (error) { showToast(error.message); } } function wireForms() { wireForm("#medicationLogForm", "create_medication_log", "Medication logged"); wireForm("#vitalLogForm", "create_vital_log", "Vitals logged"); wireForm("#labResultForm", "create_lab_result", "Lab result logged"); wireForm("#symptomLogForm", "create_symptom_log", "Symptom logged"); wireForm("#allergyRecordForm", "create_allergy_record", "Allergy saved"); wireForm("#appointmentForm", "create_appointment", "Appointment saved"); wireForm("#immunizationRecordForm", "create_immunization_record", "Immunization saved"); wireForm("#workoutForm", "create_workout", "Workout saved"); wireForm("#routineForm", "create_routine", "Routine saved"); wireForm("#nutritionGoalForm", "create_nutrition_goal", "Nutrition target saved"); wireForm("#nutritionLogForm", "create_nutrition_log", "Nutrition logged"); wireForm("#supplementLogForm", "create_supplement_log", "Supplement logged"); wireForm("#metricForm", "create_body_metric", "Metrics logged"); wireForm("#exerciseForm", "create_exercise", "Exercise added"); wireForm("#supplementForm", "create_supplement", "Supplement added"); $("#adminUserForm").addEventListener("submit", async (event) => { event.preventDefault(); const form = event.currentTarget; const payload = adminUserPayload(form); const action = payload.target_user_id ? "update_user" : "create_user"; try { await api(action, payload); resetAdminUserForm(); await loadState(); showToast(action === "create_user" ? "Profile created" : "Profile updated"); } catch (error) { showToast(error.message); } }); } document.addEventListener("DOMContentLoaded", async () => { wireControls(); wireForms(); try { await loadState(); } catch (error) { showToast(error.message); } });