File size: 2,097 Bytes
41366c7
 
 
 
3399231
41366c7
3399231
 
41366c7
 
 
 
 
 
 
 
 
 
 
3399231
 
 
 
 
 
 
 
 
 
 
 
 
41366c7
3399231
41366c7
 
 
 
 
 
4ec763e
 
 
 
 
3399231
4ec763e
3399231
 
4ec763e
3399231
4ec763e
 
 
 
 
3399231
4ec763e
 
 
 
 
 
3399231
4ec763e
3399231
 
4ec763e
3399231
4ec763e
 
 
 
 
 
 
 
 
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
interface LoadingProps {
  message?: string
}

export function LoadingSpinner({ message = 'Loading' }: LoadingProps) {
  return (
    <div className="py-16">
      <p className="eyebrow">{message}</p>
    </div>
  )
}

interface ErrorProps {
  message?: string
  onRetry?: () => void
}

export function ErrorState({ message = 'Failed to load data', onRetry }: ErrorProps) {
  return (
    <div className="py-16">
      <p className="eyebrow" style={{ color: '#c71f48' }}>Error</p>
      <p
        style={{
          fontFamily: '"Space Grotesk", system-ui, sans-serif',
          fontSize: '14px',
          color: '#606373',
          marginTop: '8px',
          marginBottom: '16px',
        }}
      >
        {message}
      </p>
      {onRetry && (
        <button onClick={onRetry} className="btn-secondary">
          Retry
        </button>
      )}
    </div>
  )
}

/* ── Skeleton loaders ── */

export function DashboardSkeleton() {
  return (
    <div className="animate-fade-in space-y-10">
      <div className="pt-2 pb-6">
        <div className="skeleton-title mb-3" />
        <div className="skeleton-text" style={{ width: '40%' }} />
      </div>
      <div className="grid grid-cols-2 md:grid-cols-4 gap-8">
        <div className="skeleton-metric" />
        <div className="skeleton-metric" />
        <div className="skeleton-metric" />
        <div className="skeleton-metric" />
      </div>
      <div className="skeleton-chart" style={{ height: 200 }} />
    </div>
  )
}

export function TableSkeleton() {
  return (
    <div className="animate-fade-in space-y-8">
      <div className="pt-2 pb-6">
        <div className="skeleton-title mb-3" />
        <div className="skeleton-text" style={{ width: '40%' }} />
      </div>
      <div className="grid grid-cols-2 md:grid-cols-4 gap-8">
        <div className="skeleton-metric" />
        <div className="skeleton-metric" />
        <div className="skeleton-metric" />
        <div className="skeleton-metric" />
      </div>
      <div className="skeleton-chart" style={{ height: 300 }} />
    </div>
  )
}