Client UX: toast system, confirm dialogs, load-error banners, nav fix, 404 page
- New ToastProvider/useToast (self-built, no dep): success/error toasts replace
all five alert() calls, with server error messages surfaced
- New ConfirmProvider/useConfirm promise-based dialog replaces all six
window.confirm sites, showing what is being deleted; Escape/overlay cancels
- Dashboard + BreedingCalendar loaders use Promise.allSettled with a
danger banner + Retry instead of silently blanking on fetch failure
- Settings load failure now surfaces a toast instead of vanishing
- Fix BreedingCalendar females list: read paginated {data} shape (was .dogs,
so 'Start Heat Cycle' never listed any females)
- Nav links highlight on detail routes (/dogs/123, /pedigree/5)
- Catch-all 404 route with link back to Dashboard
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -9,13 +9,18 @@ export function SettingsProvider({ children }) {
|
||||
kennel_tagline: '',
|
||||
})
|
||||
const [loading, setLoading] = useState(true)
|
||||
// Surfaced by consumers inside the ToastProvider (this provider sits above it)
|
||||
const [loadError, setLoadError] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
axios.get('/api/settings')
|
||||
.then(res => {
|
||||
setSettings(prev => ({ ...prev, ...res.data }))
|
||||
})
|
||||
.catch(() => {})
|
||||
.catch((err) => {
|
||||
console.error('Failed to load settings:', err)
|
||||
setLoadError(true)
|
||||
})
|
||||
.finally(() => setLoading(false))
|
||||
}, [])
|
||||
|
||||
@@ -25,7 +30,7 @@ export function SettingsProvider({ children }) {
|
||||
}
|
||||
|
||||
return (
|
||||
<SettingsContext.Provider value={{ settings, saveSettings, loading }}>
|
||||
<SettingsContext.Provider value={{ settings, saveSettings, loading, loadError }}>
|
||||
{children}
|
||||
</SettingsContext.Provider>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user