Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | 65x 384x 384x 140x 244x | import type { ReactNode } from 'react'
import { Skeleton } from '@/components/ui/skeleton'
import { Button } from '@/components/ui/button'
import { Card, CardContent } from '@/components/ui/card'
export interface MetadataField {
I label: string
value?: ReactNode
render?: () => ReactNode
spanFull?: boolean
}
export interface MetadataCardProps {
fields: MetadataField[]
isLoading?: boolean
error?: Error | null
onRetry?: () => void
children?: ReactNode
}
export function MetadataCard({
fields,
isLoading,
error,
onRetry,
children,
}: MetadataCardProps) {
if (error) {
return (
<div className="flex flex-col items-center gap-4 rounded-lg border bg-card p-6 text-center">
<p className="text-sm text-destructive">
{error.message || 'Failed to load'}
</p>
{onRetry && (
<Button variant="outline" onClick={onRetry} type="button">
Retry
</Button>
)}
</div>
)
}
if (isLoading) {
return (
<div className="rounded-lg border bg-muted/50 p-6">
<div className="grid grid-cols-2 gap-4">
<div className="col-span-full flex flex-col gap-2">
<Skeleton className="h-3 w-16" />
<Skeleton className="h-5 w-48" />
</div>
<div className="flex flex-col gap-2">
<Skeleton className="h-3 w-12" />
<Skeleton className="h-5 w-32" />
</div>
<div className="flex flex-col gap-2">
<Skeleton className="h-3 w-14" />
<Skeleton className="h-5 w-28" />
</div>
</div>
</div>
)
}
if (children) {
return (
<Card>
<CardContent>{children}</CardContent>
</Card>
)
}
return (
<Card>
<CardContent>
<dl className="grid grid-cols-2 gap-4">
{fields.map((field, i) => (
<div
key={i}
className={field.spanFull ? 'col-span-full' : ''}
>
<dt className="text-sm font-medium text-muted-foreground">
{field.label}
</dt>
<dd className="text-sm">
{field.render ? (
field.render()
) : field.value !== undefined && field.value !== '' ? (
field.value
) : (
<span className="text-muted-foreground">{'\u2014'}</span>
)}
</dd>
</div>
))}
</dl>
</CardContent>
</Card>
)
}I
|