Files
k-photos/k-photos-frontend/hooks/use-albums.ts
Gabriel Kaszewski 0077caa743 feat: safe deletion, album/asset delete, trash, README update
- volume-aware deletion: read-only volumes remove DB only, writable
  volumes soft-delete to trash with configurable grace period
- trash page with restore, worker purge sweep (TRASH_RETENTION_DAYS)
- album delete endpoint + sidebar trash icon
- asset delete from timeline selection toolbar
- all listing queries exclude trashed assets (deleted_at IS NULL)
- timeline ordered by EXIF capture date, date-summary endpoint
- README rewritten with features, setup, full env var table
2026-06-01 01:57:53 +02:00

76 lines
2.1 KiB
TypeScript

"use client"
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"
import api from "@/lib/api"
import type {
AlbumResponse,
CreateAlbumRequest,
UpdateAlbumRequest,
} from "@/lib/types"
export function useAlbums() {
const qc = useQueryClient()
const query = useQuery({
queryKey: ["albums"],
queryFn: async () => {
const { data } = await api.get<AlbumResponse[]>("/albums")
return data
},
})
const create = useMutation({
mutationFn: async (title: string) => {
const body: CreateAlbumRequest = { title }
const { data } = await api.post<AlbumResponse>("/albums", body)
return data
},
onSuccess: () => qc.invalidateQueries({ queryKey: ["albums"] }),
})
const update = useMutation({
mutationFn: async ({ id, ...updates }: UpdateAlbumRequest & { id: string }) => {
const { data } = await api.put<AlbumResponse>(`/albums/${id}`, updates)
return data
},
onSuccess: () => qc.invalidateQueries({ queryKey: ["albums"] }),
})
const deleteAlbum = useMutation({
mutationFn: async (id: string) => {
await api.delete(`/albums/${id}`)
},
onSuccess: () => qc.invalidateQueries({ queryKey: ["albums"] }),
})
const addEntry = useMutation({
mutationFn: async ({ albumId, assetId }: { albumId: string; assetId: string }) => {
await api.post(`/albums/${albumId}/entries`, { asset_id: assetId })
},
onSuccess: () => {
qc.invalidateQueries({ queryKey: ["albums"] })
qc.invalidateQueries({ queryKey: ["album"] })
},
})
const removeEntry = useMutation({
mutationFn: async ({ albumId, assetId }: { albumId: string; assetId: string }) => {
await api.delete(`/albums/${albumId}/entries/${assetId}`)
},
onSuccess: () => {
qc.invalidateQueries({ queryKey: ["albums"] })
qc.invalidateQueries({ queryKey: ["album"] })
},
})
return {
albums: query.data ?? [],
isLoading: query.isLoading,
createAlbum: create.mutateAsync,
deleteAlbum: deleteAlbum.mutateAsync,
updateAlbum: update.mutateAsync,
addEntry: addEntry.mutateAsync,
removeEntry: removeEntry.mutateAsync,
}
}