1+ 'use client' ;
2+
3+ import React from 'react' ;
4+
5+ interface BadgeProps {
6+ variant : 'type' | 'updateable' | 'privileged' | 'status' | 'note' | 'execution-mode' ;
7+ type ?: string ;
8+ noteType ?: 'info' | 'warning' | 'error' ;
9+ status ?: 'success' | 'failed' | 'in_progress' ;
10+ executionMode ?: 'local' | 'ssh' ;
11+ children : React . ReactNode ;
12+ className ?: string ;
13+ }
14+
15+ export function Badge ( { variant, type, noteType, status, executionMode, children, className = '' } : BadgeProps ) {
16+ const getTypeStyles = ( scriptType : string ) => {
17+ switch ( scriptType . toLowerCase ( ) ) {
18+ case 'ct' :
19+ return 'bg-blue-100 dark:bg-blue-900/30 text-blue-800 dark:text-blue-200 border-blue-200 dark:border-blue-700' ;
20+ case 'addon' :
21+ return 'bg-purple-100 dark:bg-purple-900/30 text-purple-800 dark:text-purple-200 border-purple-200 dark:border-purple-700' ;
22+ case 'vm' :
23+ return 'bg-green-100 dark:bg-green-900/30 text-green-800 dark:text-green-200 border-green-200 dark:border-green-700' ;
24+ case 'pve' :
25+ return 'bg-orange-100 dark:bg-orange-900/30 text-orange-800 dark:text-orange-200 border-orange-200 dark:border-orange-700' ;
26+ default :
27+ return 'bg-gray-100 dark:bg-gray-700 text-gray-800 dark:text-gray-200 border-gray-200 dark:border-gray-600' ;
28+ }
29+ } ;
30+
31+ const getVariantStyles = ( ) => {
32+ switch ( variant ) {
33+ case 'type' :
34+ return `inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium border ${ type ? getTypeStyles ( type ) : getTypeStyles ( 'unknown' ) } ` ;
35+
36+ case 'updateable' :
37+ return 'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 dark:bg-green-900/30 text-green-800 dark:text-green-200 border border-green-200 dark:border-green-700' ;
38+
39+ case 'privileged' :
40+ return 'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-100 dark:bg-red-900/30 text-red-800 dark:text-red-200 border border-red-200 dark:border-red-700' ;
41+
42+ case 'status' :
43+ switch ( status ) {
44+ case 'success' :
45+ return 'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 dark:bg-green-900/30 text-green-800 dark:text-green-200 border border-green-200 dark:border-green-700' ;
46+ case 'failed' :
47+ return 'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-100 dark:bg-red-900/30 text-red-800 dark:text-red-200 border border-red-200 dark:border-red-700' ;
48+ case 'in_progress' :
49+ return 'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-100 dark:bg-yellow-900/30 text-yellow-800 dark:text-yellow-200 border border-yellow-200 dark:border-yellow-700' ;
50+ default :
51+ return 'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 dark:bg-gray-700 text-gray-800 dark:text-gray-200 border border-gray-200 dark:border-gray-600' ;
52+ }
53+
54+ case 'execution-mode' :
55+ switch ( executionMode ) {
56+ case 'local' :
57+ return 'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 dark:bg-blue-900/30 text-blue-800 dark:text-blue-200 border border-blue-200 dark:border-blue-700' ;
58+ case 'ssh' :
59+ return 'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-purple-100 dark:bg-purple-900/30 text-purple-800 dark:text-purple-200 border border-purple-200 dark:border-purple-700' ;
60+ default :
61+ return 'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 dark:bg-gray-700 text-gray-800 dark:text-gray-200 border border-gray-200 dark:border-gray-600' ;
62+ }
63+
64+ case 'note' :
65+ switch ( noteType ) {
66+ case 'warning' :
67+ return 'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-100 dark:bg-yellow-900/30 text-yellow-800 dark:text-yellow-200 border border-yellow-200 dark:border-yellow-700' ;
68+ case 'error' :
69+ return 'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-100 dark:bg-red-900/30 text-red-800 dark:text-red-200 border border-red-200 dark:border-red-700' ;
70+ default :
71+ return 'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 dark:bg-blue-900/30 text-blue-800 dark:text-blue-200 border border-blue-200 dark:border-blue-700' ;
72+ }
73+
74+ default :
75+ return 'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 dark:bg-gray-700 text-gray-800 dark:text-gray-200 border border-gray-200 dark:border-gray-600' ;
76+ }
77+ } ;
78+
79+ // Format the text for type badges
80+ const formatText = ( ) => {
81+ if ( variant === 'type' && type ) {
82+ switch ( type . toLowerCase ( ) ) {
83+ case 'ct' :
84+ return 'LXC' ;
85+ case 'addon' :
86+ return 'ADDON' ;
87+ case 'vm' :
88+ return 'VM' ;
89+ case 'pve' :
90+ return 'PVE' ;
91+ default :
92+ return type . toUpperCase ( ) ;
93+ }
94+ }
95+ return children ;
96+ } ;
97+
98+ return (
99+ < span className = { `${ getVariantStyles ( ) } ${ className } ` } >
100+ { formatText ( ) }
101+ </ span >
102+ ) ;
103+ }
104+
105+ // Convenience components for common use cases
106+ export const TypeBadge = ( { type, className } : { type : string ; className ?: string } ) => (
107+ < Badge variant = "type" type = { type } className = { className } >
108+ { type }
109+ </ Badge >
110+ ) ;
111+
112+ export const UpdateableBadge = ( { className } : { className ?: string } ) => (
113+ < Badge variant = "updateable" className = { className } >
114+ Updateable
115+ </ Badge >
116+ ) ;
117+
118+ export const PrivilegedBadge = ( { className } : { className ?: string } ) => (
119+ < Badge variant = "privileged" className = { className } >
120+ Privileged
121+ </ Badge >
122+ ) ;
123+
124+ export const StatusBadge = ( { status, children, className } : { status : 'success' | 'failed' | 'in_progress' ; children : React . ReactNode ; className ?: string } ) => (
125+ < Badge variant = "status" status = { status } className = { className } >
126+ { children }
127+ </ Badge >
128+ ) ;
129+
130+ export const ExecutionModeBadge = ( { mode, children, className } : { mode : 'local' | 'ssh' ; children : React . ReactNode ; className ?: string } ) => (
131+ < Badge variant = "execution-mode" executionMode = { mode } className = { className } >
132+ { children }
133+ </ Badge >
134+ ) ;
135+
136+ export const NoteBadge = ( { noteType, children, className } : { noteType : 'info' | 'warning' | 'error' ; children : React . ReactNode ; className ?: string } ) => (
137+ < Badge variant = "note" noteType = { noteType } className = { className } >
138+ { children }
139+ </ Badge >
140+ ) ;
0 commit comments