/
opt
/
mawid
/
apps
/
dashboard
/
components
/
/opt/mawid/apps/dashboard/components
mkdir
upload
Name
Size
Mode
Actions
ui.tsx
3789
0644
edit
dl
rm
Edit:
/opt/mawid/apps/dashboard/components/ui.tsx
(3789B)
'use client'; import { type ReactNode } from 'react'; export function Button({ children, onClick, variant = 'primary', type = 'button', disabled, className = '', }: { children: ReactNode; onClick?: () => void; variant?: 'primary' | 'secondary' | 'danger' | 'ghost'; type?: 'button' | 'submit'; disabled?: boolean; className?: string; }) { const styles = { primary: 'bg-emerald-600 text-white hover:bg-emerald-700', secondary: 'bg-slate-100 text-slate-700 hover:bg-slate-200', danger: 'bg-red-50 text-red-700 hover:bg-red-100', ghost: 'text-slate-500 hover:bg-slate-100', }[variant]; return ( <button type={type} onClick={onClick} disabled={disabled} className={`rounded-lg px-3 py-2 text-sm font-medium transition disabled:opacity-40 ${styles} ${className}`} > {children} </button> ); } export function Input(props: React.InputHTMLAttributes<HTMLInputElement>) { return ( <input {...props} className={`w-full rounded-lg border border-slate-200 bg-white px-3 py-2 text-sm outline-none focus:border-emerald-500 ${props.className ?? ''}`} /> ); } export function Select(props: React.SelectHTMLAttributes<HTMLSelectElement>) { return ( <select {...props} className={`w-full rounded-lg border border-slate-200 bg-white px-3 py-2 text-sm outline-none focus:border-emerald-500 ${props.className ?? ''}`} /> ); } export function Textarea(props: React.TextareaHTMLAttributes<HTMLTextAreaElement>) { return ( <textarea {...props} className={`w-full rounded-lg border border-slate-200 bg-white px-3 py-2 text-sm outline-none focus:border-emerald-500 ${props.className ?? ''}`} /> ); } export function Card({ children, className = '' }: { children: ReactNode; className?: string }) { return ( <div className={`rounded-xl border border-slate-200 bg-white p-4 shadow-sm ${className}`}> {children} </div> ); } export function Field({ label, children }: { label: string; children: ReactNode }) { return ( <label className="block"> <span className="mb-1 block text-xs font-medium text-slate-500">{label}</span> {children} </label> ); } export function Badge({ children, color = 'slate', }: { children: ReactNode; color?: 'slate' | 'emerald' | 'amber' | 'red' | 'blue'; }) { const styles = { slate: 'bg-slate-100 text-slate-600', emerald: 'bg-emerald-100 text-emerald-700', amber: 'bg-amber-100 text-amber-700', red: 'bg-red-100 text-red-700', blue: 'bg-blue-100 text-blue-700', }[color]; return ( <span className={`inline-block rounded-full px-2 py-0.5 text-xs font-medium ${styles}`}> {children} </span> ); } export function Modal({ open, onClose, title, children, }: { open: boolean; onClose: () => void; title: string; children: ReactNode; }) { if (!open) return null; return ( <div className="fixed inset-0 z-50 flex items-end justify-center bg-black/40 p-0 sm:items-center sm:p-4" onClick={onClose} > <div className="max-h-[90vh] w-full overflow-y-auto rounded-t-2xl bg-white p-5 sm:max-w-lg sm:rounded-2xl" onClick={(e) => e.stopPropagation()} > <div className="mb-4 flex items-center justify-between"> <h2 className="text-lg font-semibold">{title}</h2> <button onClick={onClose} className="text-slate-400 hover:text-slate-600"> ✕ </button> </div> {children} </div> </div> ); } export function Spinner() { return ( <div className="flex justify-center p-8"> <div className="h-6 w-6 animate-spin rounded-full border-2 border-slate-300 border-t-emerald-600" /> </div> ); }
Save
cmd:
run