From 49c7f7abd70b74bb26d645d6c2024ac4ee74e0d9 Mon Sep 17 00:00:00 2001 From: Gabriel Kaszewski Date: Fri, 20 Mar 2026 00:30:44 +0100 Subject: [PATCH] feat(frontend): add useLibrarySearch, useLibrarySyncStatus, useTriggerSync, useAdminSettings hooks --- k-tv-frontend/hooks/use-admin-settings.ts | 28 +++++++++++++++++++ k-tv-frontend/hooks/use-library-search.ts | 34 +++++++++++++++++++++++ k-tv-frontend/hooks/use-library-sync.ts | 28 +++++++++++++++++++ 3 files changed, 90 insertions(+) create mode 100644 k-tv-frontend/hooks/use-admin-settings.ts create mode 100644 k-tv-frontend/hooks/use-library-search.ts create mode 100644 k-tv-frontend/hooks/use-library-sync.ts diff --git a/k-tv-frontend/hooks/use-admin-settings.ts b/k-tv-frontend/hooks/use-admin-settings.ts new file mode 100644 index 0000000..688111c --- /dev/null +++ b/k-tv-frontend/hooks/use-admin-settings.ts @@ -0,0 +1,28 @@ +"use client"; + +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { api } from "@/lib/api"; +import { useAuthContext } from "@/context/auth-context"; +import type { AdminSettings } from "@/lib/types"; + +export function useAdminSettings() { + const { token } = useAuthContext(); + return useQuery({ + queryKey: ["admin", "settings"], + queryFn: () => api.admin.getSettings(token!), + enabled: !!token, + staleTime: 5 * 60 * 1000, + }); +} + +export function useUpdateAdminSettings() { + const { token } = useAuthContext(); + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: (patch: Partial) => + api.admin.updateSettings(token!, patch), + onSuccess: (data: AdminSettings) => { + queryClient.setQueryData(["admin", "settings"], data); + }, + }); +} diff --git a/k-tv-frontend/hooks/use-library-search.ts b/k-tv-frontend/hooks/use-library-search.ts new file mode 100644 index 0000000..026c32c --- /dev/null +++ b/k-tv-frontend/hooks/use-library-search.ts @@ -0,0 +1,34 @@ +"use client"; + +import { useQuery } from "@tanstack/react-query"; +import { api } from "@/lib/api"; +import { useAuthContext } from "@/context/auth-context"; + +export interface LibrarySearchParams { + q?: string; + type?: string; + series?: string[]; + collection?: string; + provider?: string; + decade?: number; + min_duration?: number; + max_duration?: number; + genres?: string[]; + offset?: number; + limit?: number; +} + +/** + * Paginated library search — always enabled, DB-backed (fast). + * Separate from useLibraryItems in use-library.ts which is snapshot-based + * and used only for block editor filter preview. + */ +export function useLibrarySearch(params: LibrarySearchParams) { + const { token } = useAuthContext(); + return useQuery({ + queryKey: ["library", "search", params], + queryFn: () => api.library.itemsPage(token!, params), + enabled: !!token, + staleTime: 2 * 60 * 1000, + }); +} diff --git a/k-tv-frontend/hooks/use-library-sync.ts b/k-tv-frontend/hooks/use-library-sync.ts new file mode 100644 index 0000000..82b9256 --- /dev/null +++ b/k-tv-frontend/hooks/use-library-sync.ts @@ -0,0 +1,28 @@ +"use client"; + +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { api } from "@/lib/api"; +import { useAuthContext } from "@/context/auth-context"; + +export function useLibrarySyncStatus() { + const { token } = useAuthContext(); + return useQuery({ + queryKey: ["library", "sync"], + queryFn: () => api.library.syncStatus(token!), + enabled: !!token, + staleTime: 30 * 1000, + refetchInterval: 10 * 1000, + }); +} + +export function useTriggerSync() { + const { token } = useAuthContext(); + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: () => api.library.triggerSync(token!), + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ["library", "search"] }); + queryClient.invalidateQueries({ queryKey: ["library", "sync"] }); + }, + }); +}