feat(ui): view-by-view UX redesign and accessibility pass

- Overview: limits hero with progress states, spend pill, primary quick-add, mobile FAB
- Logbook: day-grouped entries with subtotals, unified filter bar, Log again,
  human source labels
- Trends: unified chart cards, tick thinning, chart aria summaries, radiogroup
  forecast control
- Settings: sectioned layout with separated danger zone, ThemePicker aria fix
- EntryModal: fieldset grouping, Field primitive, safe date validation
- AuthView: autoComplete, password visibility toggle
- StatHint popover replacing title-only tooltips; mobile stacked import preview
- Remaining inline hex styles converted to theme tokens
This commit is contained in:
nh9961
2026-07-19 20:34:10 +00:00
parent 733c6cbae8
commit 3706021326
19 changed files with 945 additions and 299 deletions
+26
View File
@@ -1,4 +1,5 @@
import { AnimatePresence, motion } from "framer-motion";
import { Plus } from "lucide-react";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { flavourMeta, mergedFlavours } from "./data/flavours";
import { QUICK_ADDS, type QuickAddItem } from "./data/quickAdds";
@@ -323,6 +324,24 @@ function App() {
setIsEntryModalOpen(true);
}
function logEntryAgain(entry: RedBullEntry) {
setEditingEntry(null);
setEntryInitialDraft({
cans: entry.cans,
flavour: entry.flavour,
flavourAccent: entry.flavourAccent,
sizeMl: entry.sizeMl,
pricePerCan: entry.pricePerCan,
dateTime: new Date().toISOString(),
notes: entry.notes ?? "",
store: entry.store ?? "",
sugarFree: entry.sugarFree,
caffeineMgPerCan: entry.caffeineMgPerCan,
source: entry.source,
});
setIsEntryModalOpen(true);
}
async function saveUserLimits(next: UserLimits) {
if (!user) return;
setBusyAction("save-limits");
@@ -677,6 +696,7 @@ function App() {
setIsEntryModalOpen(true);
}}
onDelete={(id) => setPendingDeleteId(id)}
onLogAgain={logEntryAgain}
/>
)}
@@ -727,6 +747,12 @@ function App() {
<MobileNav activeView={activeView} onChange={setActiveView} />
{activeView === "overview" && (
<button className="fab-add" type="button" onClick={openNewEntry} aria-label="Add intake">
<Plus size={26} aria-hidden="true" />
</button>
)}
<EntryModal
entry={editingEntry}
initialDraft={entryInitialDraft}