Area 1 (tv/page.tsx 964→423 lines): - hooks: use-fullscreen, use-idle, use-volume, use-quality, use-subtitles, use-channel-input, use-channel-passwords, use-tv-keyboard - components: SubtitlePicker, VolumeControl, QualityPicker, TopControlBar, LogoWatermark, AutoplayPrompt, ChannelNumberOverlay, TvBaseLayer Area 2 (edit-channel-sheet.tsx 1244→678 lines): - hooks: use-channel-form (all form state + reset logic) - lib/schemas.ts: extracted Zod schemas + extractErrors - components: AlgorithmicFilterEditor, RecyclePolicyEditor, WebhookEditor, AccessSettingsEditor, LogoEditor Area 3 (dashboard/page.tsx 406→261 lines): - hooks: use-channel-order, use-import-channel, use-regenerate-all - lib/channel-export.ts: pure export utility - components: DashboardHeader
86 lines
2.3 KiB
TypeScript
86 lines
2.3 KiB
TypeScript
import { Plus, Upload, RefreshCw, Antenna, Settings2 } from "lucide-react";
|
|
import { Button } from "@/components/ui/button";
|
|
import type { ProviderCapabilities } from "@/lib/types";
|
|
|
|
interface DashboardHeaderProps {
|
|
hasChannels: boolean;
|
|
canTranscode: boolean;
|
|
canRescan: boolean;
|
|
isRegeneratingAll: boolean;
|
|
isRescanPending: boolean;
|
|
capabilities: ProviderCapabilities | undefined;
|
|
onTranscodeOpen: () => void;
|
|
onRescan: () => void;
|
|
onRegenerateAll: () => void;
|
|
onIptvOpen: () => void;
|
|
onImportOpen: () => void;
|
|
onCreateOpen: () => void;
|
|
}
|
|
|
|
export function DashboardHeader({
|
|
hasChannels,
|
|
canTranscode,
|
|
canRescan,
|
|
isRegeneratingAll,
|
|
isRescanPending,
|
|
onTranscodeOpen,
|
|
onRescan,
|
|
onRegenerateAll,
|
|
onIptvOpen,
|
|
onImportOpen,
|
|
onCreateOpen,
|
|
}: DashboardHeaderProps) {
|
|
return (
|
|
<div className="flex items-center justify-between">
|
|
<div>
|
|
<h1 className="text-xl font-semibold text-zinc-100">My Channels</h1>
|
|
<p className="mt-0.5 text-sm text-zinc-500">Build your broadcast lineup</p>
|
|
</div>
|
|
<div className="flex gap-2">
|
|
{canTranscode && (
|
|
<Button onClick={onTranscodeOpen} title="Transcode settings">
|
|
<Settings2 className="size-4" />
|
|
Transcode
|
|
</Button>
|
|
)}
|
|
{canRescan && (
|
|
<Button
|
|
onClick={onRescan}
|
|
disabled={isRescanPending}
|
|
title="Rescan local files directory"
|
|
>
|
|
<RefreshCw
|
|
className={`size-4 ${isRescanPending ? "animate-spin" : ""}`}
|
|
/>
|
|
Rescan library
|
|
</Button>
|
|
)}
|
|
{hasChannels && (
|
|
<Button
|
|
onClick={onRegenerateAll}
|
|
disabled={isRegeneratingAll}
|
|
title="Regenerate schedules for all channels"
|
|
>
|
|
<RefreshCw
|
|
className={`size-4 ${isRegeneratingAll ? "animate-spin" : ""}`}
|
|
/>
|
|
Regenerate all
|
|
</Button>
|
|
)}
|
|
<Button onClick={onIptvOpen}>
|
|
<Antenna className="size-4" />
|
|
IPTV
|
|
</Button>
|
|
<Button onClick={onImportOpen}>
|
|
<Upload className="size-4" />
|
|
Import
|
|
</Button>
|
|
<Button onClick={onCreateOpen}>
|
|
<Plus className="size-4" />
|
|
New channel
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|