106 lines
3.9 KiB
TypeScript
106 lines
3.9 KiB
TypeScript
"use client"
|
||
|
||
import {
|
||
AlertDialog,
|
||
AlertDialogAction,
|
||
AlertDialogCancel,
|
||
AlertDialogContent,
|
||
AlertDialogDescription,
|
||
AlertDialogFooter,
|
||
AlertDialogHeader,
|
||
AlertDialogMedia,
|
||
AlertDialogTitle,
|
||
} from "@/components/ui/alert-dialog"
|
||
import { Alert, AlertDescription, AlertTitle } from "@/components/reui/alert"
|
||
import type { Backup } from "@/lib/data"
|
||
import { AlertCircleIcon, LoaderCircleIcon, TriangleAlertIcon } from "lucide-react"
|
||
|
||
export function BackupDeleteDialog({
|
||
backup,
|
||
busy,
|
||
error,
|
||
onConfirm,
|
||
onCancel,
|
||
}: {
|
||
backup: Backup | null
|
||
busy: boolean
|
||
error?: string | null
|
||
onConfirm: () => void
|
||
onCancel: () => void
|
||
}) {
|
||
return (
|
||
<AlertDialog open={Boolean(backup)} onOpenChange={(v) => { if (!v && !busy) onCancel() }}>
|
||
<AlertDialogContent>
|
||
<AlertDialogHeader>
|
||
<AlertDialogMedia className="bg-destructive/10 text-destructive">
|
||
<AlertCircleIcon />
|
||
</AlertDialogMedia>
|
||
<AlertDialogTitle>Удалить бэкап?</AlertDialogTitle>
|
||
<AlertDialogDescription>
|
||
Файл <span className="font-mono text-foreground">{backup?.filename}</span> будет удалён
|
||
{backup?.storage === "s3" || backup?.storage === "both" ? " локально; объект S3 — через текущее подключение к хранилищу" : " с диска"}.
|
||
</AlertDialogDescription>
|
||
</AlertDialogHeader>
|
||
{error && <p role="alert" className="text-sm text-destructive break-words">{error}</p>}
|
||
<AlertDialogFooter>
|
||
<AlertDialogCancel disabled={busy} onClick={onCancel}>Отмена</AlertDialogCancel>
|
||
<AlertDialogAction variant="destructive" disabled={busy} onClick={onConfirm}>
|
||
{busy ? <LoaderCircleIcon className="size-4 animate-spin" /> : null}
|
||
Удалить
|
||
</AlertDialogAction>
|
||
</AlertDialogFooter>
|
||
</AlertDialogContent>
|
||
</AlertDialog>
|
||
)
|
||
}
|
||
|
||
export function BackupRestoreDialog({
|
||
backup,
|
||
busy,
|
||
blocked = false,
|
||
error,
|
||
onConfirm,
|
||
onCancel,
|
||
}: {
|
||
backup: Backup | null
|
||
busy: boolean
|
||
blocked?: boolean
|
||
error?: string | null
|
||
onConfirm: () => void
|
||
onCancel: () => void
|
||
}) {
|
||
return (
|
||
<AlertDialog open={Boolean(backup)} onOpenChange={(v) => { if (!v && !busy) onCancel() }}>
|
||
<AlertDialogContent>
|
||
<AlertDialogHeader>
|
||
<AlertDialogMedia className="bg-warning/10 text-warning">
|
||
<TriangleAlertIcon />
|
||
</AlertDialogMedia>
|
||
<AlertDialogTitle>Восстановить конфигурацию?</AlertDialogTitle>
|
||
<AlertDialogDescription>
|
||
<span>
|
||
Файл <span className="font-mono text-foreground">{backup?.filename}</span> будет загружен
|
||
на <span className="text-foreground">{backup?.server}</span> и импортирован.
|
||
</span>
|
||
</AlertDialogDescription>
|
||
<Alert variant="warning">
|
||
<TriangleAlertIcon />
|
||
<AlertTitle>Это изменит рабочую конфигурацию роутера</AlertTitle>
|
||
<AlertDescription>
|
||
Сессия может оборваться. Убедитесь, что выбран именно этот сервер и этот снимок.
|
||
</AlertDescription>
|
||
</Alert>
|
||
</AlertDialogHeader>
|
||
{error && <p role="alert" className="text-sm text-destructive break-words">{error}</p>}
|
||
<AlertDialogFooter>
|
||
<AlertDialogCancel disabled={busy} onClick={onCancel}>{blocked && !busy ? "Закрыть" : "Отмена"}</AlertDialogCancel>
|
||
<AlertDialogAction disabled={busy || blocked} onClick={onConfirm}>
|
||
{busy ? <LoaderCircleIcon className="size-4 animate-spin" /> : null}
|
||
Восстановить
|
||
</AlertDialogAction>
|
||
</AlertDialogFooter>
|
||
</AlertDialogContent>
|
||
</AlertDialog>
|
||
)
|
||
}
|