mirror of
https://github.com/lone-cloud/gerbil
synced 2026-06-03 19:54:44 -07:00
186 lines
4.4 KiB
TypeScript
186 lines
4.4 KiB
TypeScript
import {
|
|
Card,
|
|
Stack,
|
|
Group,
|
|
Text,
|
|
Badge,
|
|
Button,
|
|
Loader,
|
|
Progress,
|
|
rem,
|
|
useComputedColorScheme,
|
|
} from '@mantine/core';
|
|
import { Download } from 'lucide-react';
|
|
import { MouseEvent } from 'react';
|
|
import styles from '@/styles/layout.module.css';
|
|
|
|
interface DownloadCardProps {
|
|
name: string;
|
|
size: string;
|
|
version?: string;
|
|
description?: string;
|
|
isCurrent?: boolean;
|
|
isInstalled?: boolean;
|
|
isDownloading?: boolean;
|
|
downloadProgress?: number;
|
|
disabled?: boolean;
|
|
hasUpdate?: boolean;
|
|
newerVersion?: string;
|
|
onDownload: (e: MouseEvent<HTMLButtonElement>) => void;
|
|
onMakeCurrent?: () => void;
|
|
onUpdate?: (e: MouseEvent<HTMLButtonElement>) => void;
|
|
}
|
|
|
|
export const DownloadCard = ({
|
|
name,
|
|
size,
|
|
version,
|
|
description,
|
|
isCurrent = false,
|
|
isInstalled = false,
|
|
isDownloading = false,
|
|
downloadProgress = 0,
|
|
disabled = false,
|
|
hasUpdate = false,
|
|
newerVersion,
|
|
onDownload,
|
|
onMakeCurrent,
|
|
onUpdate,
|
|
}: DownloadCardProps) => {
|
|
const computedColorScheme = useComputedColorScheme('light', {
|
|
getInitialValueInEffect: false,
|
|
});
|
|
const isDark = computedColorScheme === 'dark';
|
|
const renderActionButtons = () => {
|
|
const buttons = [];
|
|
|
|
if (!isInstalled) {
|
|
buttons.push(
|
|
<Button
|
|
key="download"
|
|
variant="filled"
|
|
size="xs"
|
|
onClick={onDownload}
|
|
loading={isDownloading}
|
|
disabled={disabled}
|
|
leftSection={
|
|
isDownloading ? (
|
|
<Loader size="1rem" />
|
|
) : (
|
|
<Download style={{ width: rem(14), height: rem(14) }} />
|
|
)
|
|
}
|
|
>
|
|
{isDownloading ? 'Downloading...' : 'Download'}
|
|
</Button>
|
|
);
|
|
}
|
|
|
|
if (isInstalled && !isCurrent && onMakeCurrent) {
|
|
buttons.push(
|
|
<Button
|
|
key="makeCurrent"
|
|
variant="light"
|
|
size="xs"
|
|
onClick={onMakeCurrent}
|
|
>
|
|
Make Current
|
|
</Button>
|
|
);
|
|
}
|
|
|
|
if (hasUpdate && onUpdate) {
|
|
buttons.push(
|
|
<Button
|
|
key="update"
|
|
variant="filled"
|
|
size="xs"
|
|
onClick={onUpdate}
|
|
loading={isDownloading}
|
|
disabled={disabled}
|
|
color="orange"
|
|
leftSection={
|
|
isDownloading ? (
|
|
<Loader size="1rem" />
|
|
) : (
|
|
<Download style={{ width: rem(14), height: rem(14) }} />
|
|
)
|
|
}
|
|
>
|
|
{isDownloading ? 'Updating...' : `Update to ${newerVersion}`}
|
|
</Button>
|
|
);
|
|
}
|
|
|
|
return buttons.length > 0 ? <Stack gap="xs">{buttons}</Stack> : null;
|
|
};
|
|
|
|
return (
|
|
<Card
|
|
withBorder
|
|
radius="sm"
|
|
padding="sm"
|
|
{...(isCurrent && {
|
|
bg: isDark ? 'dark.6' : 'gray.0',
|
|
bd: `2px solid var(--mantine-color-${isDark ? 'blue-4' : 'blue-6'})`,
|
|
})}
|
|
>
|
|
<Group justify="space-between" align="center">
|
|
<div className={styles.flex1}>
|
|
<Group gap="xs" align="center" mb="xs">
|
|
<Text fw={500} size="sm">
|
|
{name}
|
|
</Text>
|
|
{isCurrent && (
|
|
<Badge variant="light" color="blue" size="sm">
|
|
Current
|
|
</Badge>
|
|
)}
|
|
{hasUpdate && (
|
|
<Badge variant="light" color="orange" size="sm">
|
|
Update Available
|
|
</Badge>
|
|
)}
|
|
</Group>
|
|
{description && (
|
|
<Text size="xs" c="dimmed" mb="xs">
|
|
{description}
|
|
</Text>
|
|
)}
|
|
<Group gap="xs" align="center">
|
|
{version && (
|
|
<Text size="xs" c="dimmed">
|
|
Version {version}
|
|
</Text>
|
|
)}
|
|
{size && (
|
|
<>
|
|
<Text size="xs" c="dimmed">
|
|
•
|
|
</Text>
|
|
<Badge variant="light" color="gray" size="xs">
|
|
{size}
|
|
</Badge>
|
|
</>
|
|
)}
|
|
</Group>
|
|
</div>
|
|
|
|
{renderActionButtons()}
|
|
</Group>
|
|
|
|
{isDownloading && downloadProgress !== undefined && (
|
|
<Stack gap="xs" mt="sm">
|
|
<Progress
|
|
value={Math.min(downloadProgress, 100)}
|
|
color="blue"
|
|
radius="xl"
|
|
/>
|
|
<Text size="xs" c="dimmed" ta="center">
|
|
{Math.min(downloadProgress, 100).toFixed(1)}% complete
|
|
</Text>
|
|
</Stack>
|
|
)}
|
|
</Card>
|
|
);
|
|
};
|