Files
homarr/apps/nextjs/src/components/backup/restore-progress-panel.tsx
T

93 lines
2.8 KiB
TypeScript

"use client";
import { Button, Group, Loader, Paper, Stack, Text, ThemeIcon } from "@mantine/core";
import { useReducedMotion } from "@mantine/hooks";
import { IconAlertTriangle, IconCheck, IconDatabaseImport, IconRefresh } from "@tabler/icons-react";
import { useI18n } from "@homarr/translation/client";
export type RestoreProgressStatus = "restoring" | "restarting" | "timedOut";
interface RestoreProgressPanelProps {
active: boolean;
status: RestoreProgressStatus;
reloginRequired?: boolean;
onRetry: () => void;
onReload: () => void;
}
export const RestoreProgressPanel = ({
active,
status,
reloginRequired = false,
onRetry,
onReload,
}: RestoreProgressPanelProps) => {
const t = useI18n("management.page.tool.backup.restore");
const tCommon = useI18n("common");
const reduceMotion = useReducedMotion();
if (!active) return null;
const isRestoring = status === "restoring";
const isTimedOut = status === "timedOut";
const statusLabel = isRestoring ? t("progress.title") : isTimedOut ? t("timeout.message") : t("progress.restarting");
return (
<Paper
component="output"
p="lg"
radius="md"
bg="var(--mantine-color-dark-7)"
aria-live="polite"
aria-atomic="true"
aria-busy={!isTimedOut}
>
<Stack gap="md">
<Group gap="sm">
{isTimedOut ? (
<ThemeIcon size="lg" radius="xl" color="orange" variant="light" aria-hidden="true">
<IconAlertTriangle size={18} />
</ThemeIcon>
) : !isRestoring ? (
<ThemeIcon size="lg" radius="xl" color="green" variant="light" aria-hidden="true">
<IconCheck size={18} />
</ThemeIcon>
) : reduceMotion ? (
<ThemeIcon size="lg" radius="xl" color="blue" variant="light" aria-hidden="true">
<IconDatabaseImport size={18} />
</ThemeIcon>
) : (
<Loader size="sm" color="blue" aria-hidden="true" />
)}
<div>
<Text size="sm" fw={600}>
{isTimedOut ? t("timeout.title") : t("progress.title")}
</Text>
<Text size="xs" c="dimmed">
{statusLabel}
</Text>
</div>
</Group>
{reloginRequired && !isRestoring ? (
<Text size="sm" c="dimmed">
{t("progress.relogin")}
</Text>
) : null}
{isTimedOut ? (
<Group>
<Button variant="light" onClick={onRetry} leftSection={<IconRefresh size={16} />}>
{tCommon("action.tryAgain")}
</Button>
<Button variant="default" onClick={onReload}>
{tCommon("action.refresh")}
</Button>
</Group>
) : null}
</Stack>
</Paper>
);
};