345cbed6d2
- Created 04-06-PLAN.md outlining persistence improvements phases - Phase 04-06-01: Draft persistence via localStorage - Added useDraftWorkout hook for auto-saving/loading drafts - Integrated hook into WorkoutEditPage - Added draft recovery prompt UI - Drafts cleared after successful save - Phase 04-06-02: Save error handling & retry (scaffolding) - Added error state and syncStatus tracking - Added handleRetry() for failed saves - Error banner with retry button - Phase 04-06-03: Sync status UI (scaffolding) - Added visual feedback for save progress - Status indicators: saving, saved, error - Disabled UI during save to prevent conflicts - Created comprehensive styles for new UI components Status: 04-06-01 complete and integrated. Ready for testing.
66 lines
1.7 KiB
JavaScript
66 lines
1.7 KiB
JavaScript
import { useEffect, useState } from 'react'
|
|
|
|
/**
|
|
* useDraftWorkout - Manages draft workout state with localStorage persistence
|
|
*
|
|
* @param {number} workoutId - Unique workout ID (used as localStorage key)
|
|
* @param {array} initialExercises - Initial exercise list
|
|
* @returns {object} { exercises, setExercises, clearDraft, hasDraft, restoreDraft }
|
|
*/
|
|
export function useDraftWorkout(workoutId, initialExercises = []) {
|
|
const [exercises, setExercises] = useState(initialExercises)
|
|
const [hasDraft, setHasDraft] = useState(false)
|
|
|
|
const draftKey = `workout-draft-${workoutId}`
|
|
|
|
// Load draft from localStorage on mount
|
|
useEffect(() => {
|
|
const saved = localStorage.getItem(draftKey)
|
|
if (saved) {
|
|
try {
|
|
const draft = JSON.parse(saved)
|
|
setExercises(draft)
|
|
setHasDraft(true)
|
|
} catch (err) {
|
|
console.error('Failed to parse draft:', err)
|
|
localStorage.removeItem(draftKey) // Clear corrupted draft
|
|
}
|
|
}
|
|
}, [workoutId, draftKey])
|
|
|
|
// Auto-save to localStorage whenever exercises change
|
|
useEffect(() => {
|
|
if (exercises.length > 0) {
|
|
localStorage.setItem(draftKey, JSON.stringify(exercises))
|
|
}
|
|
}, [exercises, draftKey])
|
|
|
|
const clearDraft = () => {
|
|
localStorage.removeItem(draftKey)
|
|
setHasDraft(false)
|
|
}
|
|
|
|
const restoreDraft = () => {
|
|
const saved = localStorage.getItem(draftKey)
|
|
if (saved) {
|
|
try {
|
|
const draft = JSON.parse(saved)
|
|
setExercises(draft)
|
|
return true
|
|
} catch (err) {
|
|
console.error('Failed to restore draft:', err)
|
|
return false
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
return {
|
|
exercises,
|
|
setExercises,
|
|
clearDraft,
|
|
hasDraft,
|
|
restoreDraft
|
|
}
|
|
}
|