Files
k-tv/k-tv-frontend/app/(main)/dashboard/components/config-history-sheet.tsx

120 lines
4.2 KiB
TypeScript

'use client'
import { useState } from 'react'
import { Sheet, SheetContent, SheetHeader, SheetTitle } from '@/components/ui/sheet'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { useConfigHistory, usePinSnapshot, useRestoreConfig } from '@/hooks/use-channels'
import { cn } from '@/lib/utils'
interface Props {
channelId: string
open: boolean
onOpenChange: (open: boolean) => void
}
export function ConfigHistorySheet({ channelId, open, onOpenChange }: Props) {
const { data: snapshots } = useConfigHistory(channelId)
const pin = usePinSnapshot()
const restore = useRestoreConfig()
const [pinningId, setPinningId] = useState<string | null>(null)
const [pinLabel, setPinLabel] = useState('')
return (
<Sheet open={open} onOpenChange={onOpenChange}>
<SheetContent>
<SheetHeader>
<SheetTitle>Config history</SheetTitle>
</SheetHeader>
<div className="flex flex-col gap-2 mt-4 overflow-y-auto px-4 pb-4">
{(snapshots ?? []).map((snap, i) => (
<div
key={snap.id}
className={cn(
'flex items-center gap-3 p-3 rounded border',
i === 0 ? 'border-green-700 bg-green-950/30' : 'border-border'
)}
>
<div className="flex-1 min-w-0">
<div className="text-sm font-medium">
v{snap.version_num} {' '}
{new Date(snap.created_at).toLocaleString()}
{i === 0 && (
<span className="ml-2 text-xs text-green-400 bg-green-950 px-1.5 py-0.5 rounded">
current
</span>
)}
</div>
{snap.label ? (
<div className="text-xs text-amber-400 mt-0.5">📌 {snap.label}</div>
) : (
<div className="text-xs text-muted-foreground">Auto-saved</div>
)}
</div>
{i === 0 && (
pinningId === snap.id ? (
<div className="flex gap-1 items-center">
<Input
value={pinLabel}
onChange={e => setPinLabel(e.target.value)}
className="h-7 text-xs w-32"
placeholder="label…"
onKeyDown={e => {
if (e.key === 'Enter') {
pin.mutate({ channelId, snapId: snap.id, label: pinLabel })
setPinningId(null)
}
if (e.key === 'Escape') setPinningId(null)
}}
/>
<Button
size="sm"
onClick={() => {
pin.mutate({ channelId, snapId: snap.id, label: pinLabel })
setPinningId(null)
}}
>
Save
</Button>
<Button size="sm" variant="ghost" onClick={() => setPinningId(null)}>
</Button>
</div>
) : (
<Button
variant="outline"
size="sm"
onClick={() => {
setPinningId(snap.id)
setPinLabel(snap.label ?? '')
}}
>
Pin
</Button>
)
)}
{i > 0 && (
<Button
variant="outline"
size="sm"
onClick={() => restore.mutate({ channelId, snapId: snap.id })}
disabled={restore.isPending}
>
Restore
</Button>
)}
</div>
))}
{(snapshots ?? []).length === 0 && (
<p className="text-sm text-muted-foreground text-center py-8">
No history yet. History is created automatically when you save changes.
</p>
)}
</div>
</SheetContent>
</Sheet>
)
}