"use client"; import { useState } from "react"; import { Plus, Upload } from "lucide-react"; import { Button } from "@/components/ui/button"; import { useChannels, useCreateChannel, useUpdateChannel, useDeleteChannel, useGenerateSchedule, } from "@/hooks/use-channels"; import { useAuthContext } from "@/context/auth-context"; import { api } from "@/lib/api"; import { useQueryClient } from "@tanstack/react-query"; import { ChannelCard } from "./components/channel-card"; import { CreateChannelDialog } from "./components/create-channel-dialog"; import { DeleteChannelDialog } from "./components/delete-channel-dialog"; import { EditChannelSheet } from "./components/edit-channel-sheet"; import { ScheduleSheet } from "./components/schedule-sheet"; import { ImportChannelDialog, type ChannelImportData } from "./components/import-channel-dialog"; import type { ChannelResponse, ProgrammingBlock, RecyclePolicy } from "@/lib/types"; export default function DashboardPage() { const { token } = useAuthContext(); const queryClient = useQueryClient(); const { data: channels, isLoading, error } = useChannels(); const createChannel = useCreateChannel(); const updateChannel = useUpdateChannel(); const deleteChannel = useDeleteChannel(); const generateSchedule = useGenerateSchedule(); const [createOpen, setCreateOpen] = useState(false); const [importOpen, setImportOpen] = useState(false); const [importPending, setImportPending] = useState(false); const [importError, setImportError] = useState(null); const [editChannel, setEditChannel] = useState(null); const [deleteTarget, setDeleteTarget] = useState(null); const [scheduleChannel, setScheduleChannel] = useState(null); const handleCreate = (data: { name: string; timezone: string; description: string; }) => { createChannel.mutate( { name: data.name, timezone: data.timezone, description: data.description || undefined }, { onSuccess: () => setCreateOpen(false) }, ); }; const handleEdit = ( id: string, data: { name: string; description: string; timezone: string; schedule_config: { blocks: ProgrammingBlock[] }; recycle_policy: RecyclePolicy; }, ) => { updateChannel.mutate( { id, data }, { onSuccess: () => setEditChannel(null) }, ); }; const handleImport = async (data: ChannelImportData) => { if (!token) return; setImportPending(true); setImportError(null); try { const created = await api.channels.create( { name: data.name, timezone: data.timezone, description: data.description }, token, ); await api.channels.update( created.id, { schedule_config: { blocks: data.blocks }, recycle_policy: data.recycle_policy }, token, ); await queryClient.invalidateQueries({ queryKey: ["channels"] }); setImportOpen(false); } catch (e) { setImportError(e instanceof Error ? e.message : "Import failed"); } finally { setImportPending(false); } }; const handleExport = (channel: ChannelResponse) => { const payload = { name: channel.name, description: channel.description ?? undefined, timezone: channel.timezone, blocks: channel.schedule_config.blocks, recycle_policy: channel.recycle_policy, }; const blob = new Blob([JSON.stringify(payload, null, 2)], { type: "application/json" }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = `${channel.name.toLowerCase().replace(/\s+/g, "-")}.json`; a.click(); URL.revokeObjectURL(url); }; const handleDelete = () => { if (!deleteTarget) return; deleteChannel.mutate(deleteTarget.id, { onSuccess: () => setDeleteTarget(null), }); }; return (
{/* Header */}

My Channels

Build your broadcast lineup

{/* Content */} {isLoading && (
)} {error && (
{error.message}
)} {channels && channels.length === 0 && (

No channels yet

)} {channels && channels.length > 0 && (
{channels.map((channel) => ( setEditChannel(channel)} onDelete={() => setDeleteTarget(channel)} onGenerateSchedule={() => generateSchedule.mutate(channel.id)} onViewSchedule={() => setScheduleChannel(channel)} onExport={() => handleExport(channel)} /> ))}
)} {/* Dialogs / sheets */} { if (!open) { setImportOpen(false); setImportError(null); } }} onSubmit={handleImport} isPending={importPending} error={importError} /> { if (!open) setEditChannel(null); }} onSubmit={handleEdit} isPending={updateChannel.isPending} error={updateChannel.error?.message} /> { if (!open) setScheduleChannel(null); }} /> {deleteTarget && ( { if (!open) setDeleteTarget(null); }} onConfirm={handleDelete} isPending={deleteChannel.isPending} /> )}
); }