mirror of
https://github.com/zvx-echo6/navi.git
synced 2026-05-20 22:54:42 +02:00
feat(navi): GPS origin + place detail panel + basic actions
Adds synthetic "Your location" stop A when GPS granted; place detail panel slides in on search result click with Directions / Add stop / Save (stub) / Share actions; elevation via Valhalla /height; react-hot-toast for feedback; pendingDestination state for GPS-denied Directions flow. Phase 3 Step 5 C1 of Navi. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
6983e2655b
commit
02f2b25db3
18 changed files with 1207 additions and 274 deletions
45
src/hooks/useTheme.js
Normal file
45
src/hooks/useTheme.js
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import { useEffect } from 'react'
|
||||
import { useStore } from '../store'
|
||||
|
||||
/**
|
||||
* Initializes and manages the theme system.
|
||||
* Call once in App — it handles:
|
||||
* - Reading localStorage override on mount
|
||||
* - Listening to system prefers-color-scheme
|
||||
* - Applying data-theme to <html>
|
||||
* - Updating store.theme (resolved value)
|
||||
*/
|
||||
export function useTheme() {
|
||||
const setTheme = useStore((s) => s.setTheme)
|
||||
const themeOverride = useStore((s) => s.themeOverride)
|
||||
|
||||
// Initialize override from localStorage on first mount
|
||||
useEffect(() => {
|
||||
const stored = localStorage.getItem('navi-theme-override')
|
||||
if (stored === 'dark' || stored === 'light') {
|
||||
useStore.getState().setThemeOverride(stored)
|
||||
}
|
||||
}, [])
|
||||
|
||||
// Resolve and apply theme
|
||||
useEffect(() => {
|
||||
function resolve() {
|
||||
if (themeOverride) return themeOverride
|
||||
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
|
||||
}
|
||||
|
||||
function apply() {
|
||||
const resolved = resolve()
|
||||
document.documentElement.setAttribute('data-theme', resolved)
|
||||
setTheme(resolved)
|
||||
}
|
||||
|
||||
apply()
|
||||
|
||||
// Listen for system changes (only matters when no override)
|
||||
const mq = window.matchMedia('(prefers-color-scheme: dark)')
|
||||
const handler = () => { if (!themeOverride) apply() }
|
||||
mq.addEventListener('change', handler)
|
||||
return () => mq.removeEventListener('change', handler)
|
||||
}, [themeOverride, setTheme])
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue