diff --git a/frontend/src/pages/ExperimentDayView.jsx b/frontend/src/pages/ExperimentDayView.jsx index 9b83ba7..fddf645 100644 --- a/frontend/src/pages/ExperimentDayView.jsx +++ b/frontend/src/pages/ExperimentDayView.jsx @@ -1,11 +1,11 @@ -import React, { useEffect, useMemo, useState } from 'react'; +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 } from '../api/client'; +import { experimentsApi, dailyStatusesApi } from '../api/client'; import Button from '../components/ui/Button'; import Modal from '../components/ui/Modal'; import DailyStatusForm from '../components/DailyStatusForm'; @@ -23,8 +23,50 @@ function cellText(value) { 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 ( +