import React, { useEffect, useMemo, useRef, useState } from 'react'; import { useParams, useNavigate, useSearchParams, Link } from 'react-router-dom'; import { format } from 'date-fns'; import { ResponsiveContainer, BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, } from 'recharts'; import { experimentsApi, dailyStatusesApi } from '../api/client'; import Button from '../components/ui/Button'; import Modal from '../components/ui/Modal'; import DailyStatusForm from '../components/DailyStatusForm'; import Alert from '../components/ui/Alert'; const BUILTIN_KEYS_SET = new Set(['experiment_description', 'vitals', 'treatment', 'notes']); function getFieldValue(status, field) { if (field.builtin) return status[field.key]; return status.custom_fields?.[field.fieldId]; } function cellText(value) { if (value === null || value === undefined || String(value).trim() === '') return null; return String(value); } // ── Inline cell editor ──────────────────────────────────────────────────────── function CellEdit({ value, field, saving, onSave, onCancel }) { const [val, setVal] = useState(value ?? ''); const ref = useRef(null); useEffect(() => { ref.current?.focus(); ref.current?.select(); }, []); function handleKey(e) { if (e.key === 'Escape') { e.preventDefault(); onCancel(); } if (e.key === 'Enter' && field.type !== 'textarea') { e.preventDefault(); onSave(val); } } const cls = 'w-full text-sm border border-blue-400 rounded px-1.5 py-0.5 focus:outline-none focus:ring-2 focus:ring-blue-500 bg-white disabled:opacity-60'; if (field.type === 'textarea') { return (