index.tsx103 lines · main
1'use client'
2
3import { cn } from 'ui'
4
5export interface StatusCodeProps {
6 method?: string
7 statusCode: number | string | undefined
8 className?: string
9}
10
11export function getStatusColor(
12 value?: number | string,
13 method?: string
14): Record<'text' | 'bg' | 'border', string> {
15 if (!method && value !== undefined) {
16 const statusNum = Number(value)
17
18 const isValidHttpStatus = !isNaN(statusNum) && statusNum >= 100 && statusNum < 600
19
20 if (!isValidHttpStatus) {
21 return {
22 text: 'text-foreground-lighter',
23 bg: 'bg-surface-200',
24 border: '',
25 }
26 }
27 }
28
29 const normalized =
30 typeof value === 'number'
31 ? value < 100
32 ? String(value)
33 : String(Math.floor(value / 100))
34 : typeof value === 'string' && /^\d+$/.test(value) && value.length >= 3
35 ? String(Math.floor(Number(value) / 100))
36 : value
37
38 switch (normalized) {
39 case '1':
40 case '2':
41 case '3':
42 case 'info':
43 case 'success':
44 case undefined:
45 return {
46 text: 'text-foreground-lighter',
47 bg: 'bg-surface-200',
48 border: '',
49 }
50 case '4':
51 case 'warning':
52 case 'redirect':
53 return {
54 text: 'text-warning',
55 bg: 'bg-warning-300',
56 border: 'border-warning-500/50',
57 }
58 case '5':
59 case 'error':
60 return {
61 text: 'text-destructive',
62 bg: 'bg-destructive-300',
63 border: 'border-destructive-500/50',
64 }
65 default:
66 return {
67 text: 'text-foreground-lighter',
68 bg: 'bg-surface-200',
69 border: '',
70 }
71 }
72}
73
74export const StatusCode = ({ method, statusCode, className }: StatusCodeProps) => {
75 const colors = getStatusColor(statusCode, method)
76
77 return (
78 <div className={cn('flex items-center gap-2', className)}>
79 <span className="shrink-0 flex text-xs font-mono items-start justify-start">
80 {method && (
81 <span className="flex items-center justify-end">
82 <span className="select-text py-0.5 px-2 text-right rounded-l rounded-r-none bg-surface-75 text-foreground-light border border-r-0 w-auto">
83 {method}
84 </span>
85 </span>
86 )}
87 <span className="flex items-center justify-start">
88 <span
89 className={cn(
90 'py-0.5 px-2 border rounded-l-0 rounded-r tabular-nums text-left w-auto',
91 !method && 'rounded-l',
92 colors.text,
93 colors.bg,
94 colors.border
95 )}
96 >
97 {statusCode}
98 </span>
99 </span>
100 </span>
101 </div>
102 )
103}