78 lines
2.0 KiB
TypeScript
78 lines
2.0 KiB
TypeScript
import React from 'react'
|
|
import { Button, Center, Group, Stack, Text } from '@mantine/core'
|
|
import { ExternalLink } from 'lucide-react'
|
|
|
|
interface EmptyStateProps {
|
|
icon: React.ComponentType<{ size?: number; strokeWidth?: number }>
|
|
title: string
|
|
description: React.ReactNode
|
|
action?: string
|
|
onAction?: () => void
|
|
actionIcon?: React.ReactNode
|
|
actionLoading?: boolean
|
|
secondaryText?: React.ReactNode
|
|
docsHref?: string
|
|
compact?: boolean
|
|
}
|
|
|
|
export function EmptyState({
|
|
icon,
|
|
title,
|
|
description,
|
|
action,
|
|
onAction,
|
|
actionIcon,
|
|
actionLoading,
|
|
secondaryText,
|
|
docsHref,
|
|
compact = false,
|
|
}: EmptyStateProps) {
|
|
const Icon = icon
|
|
|
|
return (
|
|
<Center flex={1}>
|
|
<Stack
|
|
align="center"
|
|
justify="center"
|
|
gap={compact ? 'sm' : 'md'}
|
|
py={compact ? 'lg' : 'xl'}
|
|
style={{ minHeight: compact ? undefined : '60vh', width: '100%' }}
|
|
>
|
|
<Icon size={compact ? 36 : 48} strokeWidth={1} />
|
|
<Text size={compact ? 'lg' : 'xl'} fw={600}>
|
|
{title}
|
|
</Text>
|
|
<Text c="dimmed" ta="center" maw={500}>
|
|
{description}
|
|
</Text>
|
|
{docsHref || (action && onAction) ? (
|
|
<Group justify="center">
|
|
{docsHref ? (
|
|
<Button
|
|
component="a"
|
|
href={docsHref}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
variant="default"
|
|
leftSection={<ExternalLink size={16} />}
|
|
>
|
|
Docs
|
|
</Button>
|
|
) : null}
|
|
{action && onAction ? (
|
|
<Button onClick={onAction} loading={actionLoading} leftSection={actionIcon}>
|
|
{action}
|
|
</Button>
|
|
) : null}
|
|
</Group>
|
|
) : null}
|
|
{secondaryText ? (
|
|
<Text c="dimmed" size="sm" ta="center" maw={500}>
|
|
{secondaryText}
|
|
</Text>
|
|
) : null}
|
|
</Stack>
|
|
</Center>
|
|
)
|
|
}
|