// hooks/useDisplays.ts "use client"; import useSWR from "swr"; import { mutate } from "swr"; import { Display, CreateDisplayData, UpdateDisplayData, } from "@/lib/types/types"; import { useAuth } from "@clerk/nextjs"; import { fetcher } from "@/lib/api/displays"; export function useDisplays() { const { getToken } = useAuth(); const swrFetcher = (url: string) => fetcher(url, getToken); const { data: displays, error, isLoading, isValidating, } = useSWR("/api/displays", swrFetcher, { revalidateOnFocus: true, refreshInterval: 30000, // 30 seconds dedupingInterval: 5000, // 5 seconds }); const createDisplay = async (displayData: CreateDisplayData) => { try { mutate( "/api/displays", (current: Display[] | undefined) => { const newDisplay: Display = { id: "temp-id", ...displayData, authToken: "generating...", organizationId: "temp-org", createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), twitchChannel: displayData.mode === "TWITCH" ? displayData.twitchChannel || "default_channel" : null, }; return current ? [...current, newDisplay] : [newDisplay]; }, false ); const newDisplay = await fetcher("/api/displays", getToken, { method: "POST", body: JSON.stringify(displayData), }); mutate("/api/displays", (current: Display[] | undefined) => { return current ? current.map((d) => (d.id === "temp-id" ? newDisplay : d)) : [newDisplay]; }); return newDisplay; } catch (error) { mutate("/api/displays"); throw error; } }; const updateDisplay = async (id: string, updates: UpdateDisplayData) => { try { // Optimistic update mutate( "/api/displays", (current: Display[] | undefined) => { if (!current) return current; return current.map((display) => display.id === id ? { ...display, ...updates } : display ); }, false ); const updatedDisplay = await fetcher(`/api/displays/${id}`, getToken, { method: "PUT", body: JSON.stringify(updates), }); mutate("/api/displays"); return updatedDisplay; } catch (error) { mutate("/api/displays"); throw error; } }; const deleteDisplay = async (id: string) => { try { // Optimistic update mutate( "/api/displays", (current: Display[] | undefined) => { if (!current) return current; return current.filter((display) => display.id !== id); }, false ); await fetcher(`/api/displays/${id}`, getToken, { method: "DELETE", }); mutate("/api/displays"); } catch (error) { mutate("/api/displays"); throw error; } }; return { displays: displays || [], isLoading, isValidating, error, createDisplay, updateDisplay, deleteDisplay, refreshDisplays: () => mutate("/api/displays"), }; }