mirror of
https://github.com/zvx-echo6/navi.git
synced 2026-05-20 22:54:42 +02:00
feat: add auth-state awareness and graceful degradation
- Add /api/auth/whoami endpoint check on app load - Store auth state in Zustand (authenticated, username, loaded) - Hide Contacts tab when unauthenticated - Gate fetchNearbyContacts calls on auth.authenticated - Replace Save button with Log in affordance when unauthenticated - Add Login/Logout buttons to panel header - Prevent any /api/contacts/* requests from firing when unauthenticated Public functionality (search, routing, place details) remains fully functional for unauthenticated users.
This commit is contained in:
parent
616d01623d
commit
0d4a807a05
29 changed files with 13091 additions and 317 deletions
|
|
@ -1,6 +1,6 @@
|
|||
import { useEffect, useState, useRef, useCallback } from 'react'
|
||||
import {
|
||||
X, Navigation, Plus, Bookmark, ChevronDown, ChevronUp, Copy,
|
||||
X, Navigation, Plus, Bookmark, ChevronDown, ChevronUp, Copy, LogIn,
|
||||
Clock, Phone, Globe, Mail, BookOpen, Info, Trees,
|
||||
} from 'lucide-react'
|
||||
import OpeningHours from 'opening_hours'
|
||||
|
|
@ -416,6 +416,7 @@ export default function PlaceDetail() {
|
|||
const userLocation = useStore((s) => s.userLocation)
|
||||
const contacts = useStore((s) => s.contacts)
|
||||
const setEditingContact = useStore((s) => s.setEditingContact)
|
||||
const auth = useStore((s) => s.auth)
|
||||
|
||||
const [elevResult, setElevResult] = useState({ lat: null, lon: null, value: null })
|
||||
const [isMobile, setIsMobile] = useState(false)
|
||||
|
|
@ -742,18 +743,30 @@ export default function PlaceDetail() {
|
|||
</button>
|
||||
)}
|
||||
|
||||
<button
|
||||
onClick={handleSave}
|
||||
className="p-2 rounded-lg"
|
||||
style={{
|
||||
background: savedContact ? 'var(--accent-muted)' : 'var(--tan-muted)',
|
||||
color: savedContact ? 'var(--accent)' : 'var(--tan)',
|
||||
border: '1px solid var(--border)',
|
||||
}}
|
||||
aria-label={savedContact ? 'Edit saved contact' : 'Save place'}
|
||||
>
|
||||
<Bookmark size={14} fill={savedContact ? 'currentColor' : 'none'} />
|
||||
</button>
|
||||
{auth.authenticated ? (
|
||||
<button
|
||||
onClick={handleSave}
|
||||
className="p-2 rounded-lg"
|
||||
style={{
|
||||
background: savedContact ? 'var(--accent-muted)' : 'var(--tan-muted)',
|
||||
color: savedContact ? 'var(--accent)' : 'var(--tan)',
|
||||
border: '1px solid var(--border)',
|
||||
}}
|
||||
aria-label={savedContact ? 'Edit saved contact' : 'Save place'}
|
||||
>
|
||||
<Bookmark size={14} fill={savedContact ? 'currentColor' : 'none'} />
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
onClick={() => { window.location.href = '/api/auth/whoami' }}
|
||||
className="flex items-center gap-1 px-2 py-1.5 rounded-lg text-xs"
|
||||
style={{ background: 'var(--accent-muted)', color: 'var(--accent)', border: '1px solid var(--border)' }}
|
||||
title="Log in to save places"
|
||||
>
|
||||
<LogIn size={12} />
|
||||
<span>Save</span>
|
||||
</button>
|
||||
)}
|
||||
|
||||
{/* Copy dropdown */}
|
||||
<div className="relative">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue