// 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<Display[]>("/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"),
};
}