Skip to content

Commit 6830e72

Browse files
fix: 4 bugs — Detail key, ReflectionChecklist data loss, AutoSaveTextarea double-save, scripture-card min-height
- Add key={activeSectionId} to <Detail>: without it React reused the same component instance across sections, causing ReflectionChecklist/Journal save effects to fire with stale state + new storageKey, briefly writing the wrong step's data to another step's localStorage slot - ReflectionChecklist: replace load useEffect + useState({}) with a lazy useState initializer that reads localStorage directly. Eliminates the bug where the save effect fired on initial mount with checked={}, overwriting real user data before the load effect could restore it - AutoSaveTextarea: add dedicated handleManualSave for the Save button. Previously onClick={handleBlur} caused a double-save on every click: textarea blur fires handleBlur, then the click event fires it again - styles.css: add min-height: var(--min-tap) to .scripture-card to restore accessible tap-target size (was on .scripture-card__toggle, now removed)
1 parent 591521c commit 6830e72

2 files changed

Lines changed: 16 additions & 11 deletions

File tree

src/App.jsx

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -169,18 +169,13 @@ function ScriptureCard({ scripture }) {
169169

170170
function ReflectionChecklist({ items, sectionId }) {
171171
const storageKey = `hiswillguide-checklist-${sectionId}`;
172-
const [checked, setChecked] = useState({});
173-
174-
useEffect(() => {
175-
const raw = window.localStorage.getItem(storageKey);
172+
const [checked, setChecked] = useState(() => {
173+
const raw = window.localStorage.getItem(`hiswillguide-checklist-${sectionId}`);
176174
if (raw) {
177-
try {
178-
setChecked(JSON.parse(raw));
179-
} catch {
180-
setChecked({});
181-
}
175+
try { return JSON.parse(raw); } catch { /* ignore */ }
182176
}
183-
}, [storageKey]);
177+
return {};
178+
});
184179

185180
useEffect(() => {
186181
window.localStorage.setItem(storageKey, JSON.stringify(checked));
@@ -327,6 +322,14 @@ function AutoSaveTextarea({ storageKey, placeholder }) {
327322
doSave(valueRef.current);
328323
};
329324

325+
const handleManualSave = () => {
326+
if (timerRef.current) {
327+
clearTimeout(timerRef.current);
328+
timerRef.current = null;
329+
}
330+
doSave(valueRef.current);
331+
};
332+
330333
useEffect(() => {
331334
return () => {
332335
if (timerRef.current) {
@@ -349,7 +352,7 @@ function AutoSaveTextarea({ storageKey, placeholder }) {
349352
placeholder={placeholder}
350353
/>
351354
<div className="journal-actions">
352-
<button className="primary-button" onClick={handleBlur} type="button">
355+
<button className="primary-button" onClick={handleManualSave} type="button">
353356
{label}
354357
</button>
355358
</div>
@@ -972,6 +975,7 @@ export default function App() {
972975
if (activeSectionId && VALID_SECTION_IDS.has(activeSectionId)) {
973976
return (
974977
<Detail
978+
key={activeSectionId}
975979
activeId={activeSectionId}
976980
onBack={navigateHome}
977981
onNavigate={navigateTo}

src/styles.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,7 @@ button, a, [role="checkbox"] {
746746
.scripture-card {
747747
padding: 16px;
748748
cursor: pointer;
749+
min-height: var(--min-tap);
749750
}
750751

751752
.scripture-card:focus-visible {

0 commit comments

Comments
 (0)