feat: DB-backed favorites replace localStorage
- New clip_favorites table (clip_id, user_id DEFAULT 'default', created_at) - API: POST /clips/:id/favorite (toggle), GET /favorites, GET /clips/:id/favorite - Frontend: loads favorites on mount from API, toggles via POST - Removes localStorage dependency - favorites survive cache clears - Ready for multi-user: just add real user_id when auth arrives
This commit is contained in:
1 parent
ba4d4a95fe
commit
b008a6790a
3 files changed
+110
-19
No files matched your search
@@ -98,24 +98,32 @@ export default function Gallery({ clips, onPlay, onDelete, onRename, onSelect, o
|
||||
const [showFavorites, setShowFavorites] = useState(false)
|
||||
const debouncedSearch = useDebounce(search, 300)
|
||||
|
||||
// Favorites
|
||||
const [favorites, setFavorites] = useState<Set<string>>(() => {
|
||||
try {
|
||||
const raw = localStorage.getItem('kithara-favorites')
|
||||
return raw ? new Set(JSON.parse(raw)) : new Set()
|
||||
} catch {
|
||||
return new Set()
|
||||
}
|
||||
})
|
||||
// Favorites (DB-backed)
|
||||
const [favorites, setFavorites] = useState<Set<string>>(new Set())
|
||||
|
||||
const toggleFavorite = useCallback((id: string) => {
|
||||
setFavorites(prev => {
|
||||
const next = new Set(prev)
|
||||
if (next.has(id)) next.delete(id)
|
||||
else next.add(id)
|
||||
localStorage.setItem('kithara-favorites', JSON.stringify([...next]))
|
||||
return next
|
||||
})
|
||||
// Load favorites on mount
|
||||
useEffect(() => {
|
||||
fetch('/api/favorites')
|
||||
.then(res => res.json())
|
||||
.then(data => setFavorites(new Set(data.ids || [])))
|
||||
.catch(() => {}) // silently fail
|
||||
}, [])
|
||||
|
||||
const toggleFavorite = useCallback(async (id: string) => {
|
||||
try {
|
||||
const res = await fetch(`/api/clips/${id}/favorite`, { method: 'POST' })
|
||||
if (res.ok) {
|
||||
const data = await res.json()
|
||||
setFavorites(prev => {
|
||||
const next = new Set(prev)
|
||||
if (data.favorited) next.add(id)
|
||||
else next.delete(id)
|
||||
return next
|
||||
})
|
||||
}
|
||||
} catch {
|
||||
// silently fail
|
||||
}
|
||||
}, [])
|
||||
|
||||
// Pagination + view
|
||||
|
||||
Reference in new issue
Block a user