feat: rebuild fiscal clone architecture and harden coolify deployment
This commit is contained in:
27
frontend/components/ui/button.tsx
Normal file
27
frontend/components/ui/button.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
type ButtonVariant = 'primary' | 'ghost' | 'danger' | 'secondary';
|
||||
|
||||
type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {
|
||||
variant?: ButtonVariant;
|
||||
};
|
||||
|
||||
const variantMap: Record<ButtonVariant, string> = {
|
||||
primary: 'border-[color:var(--line-strong)] bg-[color:var(--accent)] text-[#001515] hover:bg-[color:var(--accent-strong)]',
|
||||
secondary: 'border-[color:var(--line-weak)] bg-[color:var(--panel-bright)] text-[color:var(--terminal-bright)] hover:border-[color:var(--line-strong)] hover:bg-[color:var(--panel)]',
|
||||
ghost: 'border-[color:var(--line-weak)] bg-transparent text-[color:var(--terminal-bright)] hover:border-[color:var(--line-strong)] hover:bg-[color:var(--panel-soft)]',
|
||||
danger: 'border-[color:var(--danger)] bg-[color:var(--danger-soft)] text-[#ffc9c9] hover:bg-[color:var(--danger)] hover:text-[#1e0d0d]'
|
||||
};
|
||||
|
||||
export function Button({ className, variant = 'primary', ...props }: ButtonProps) {
|
||||
return (
|
||||
<button
|
||||
className={cn(
|
||||
'inline-flex items-center justify-center gap-2 rounded-lg border px-3 py-2 text-sm font-medium transition duration-200 disabled:cursor-not-allowed disabled:opacity-50',
|
||||
variantMap[variant],
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
15
frontend/components/ui/input.tsx
Normal file
15
frontend/components/ui/input.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
type InputProps = React.InputHTMLAttributes<HTMLInputElement>;
|
||||
|
||||
export function Input({ className, ...props }: InputProps) {
|
||||
return (
|
||||
<input
|
||||
className={cn(
|
||||
'w-full rounded-lg border border-[color:var(--line-weak)] bg-[color:var(--panel-soft)] px-3 py-2 text-sm text-[color:var(--terminal-bright)] outline-none transition placeholder:text-[color:var(--terminal-muted)] focus:border-[color:var(--line-strong)] focus:shadow-[0_0_0_3px_rgba(0,255,180,0.14)]',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
31
frontend/components/ui/panel.tsx
Normal file
31
frontend/components/ui/panel.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
type PanelProps = {
|
||||
title?: string;
|
||||
subtitle?: string;
|
||||
actions?: React.ReactNode;
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
export function Panel({ title, subtitle, actions, children, className }: PanelProps) {
|
||||
return (
|
||||
<section
|
||||
className={cn(
|
||||
'rounded-2xl border border-[color:var(--line-weak)] bg-[color:var(--panel)] p-5 shadow-[0_0_0_1px_rgba(0,255,180,0.03),0_12px_30px_rgba(1,4,10,0.45)]',
|
||||
className
|
||||
)}
|
||||
>
|
||||
{(title || subtitle || actions) ? (
|
||||
<header className="mb-4 flex items-start justify-between gap-3">
|
||||
<div>
|
||||
{title ? <h3 className="text-base font-semibold text-[color:var(--terminal-bright)]">{title}</h3> : null}
|
||||
{subtitle ? <p className="mt-1 text-sm text-[color:var(--terminal-muted)]">{subtitle}</p> : null}
|
||||
</div>
|
||||
{actions ? <div>{actions}</div> : null}
|
||||
</header>
|
||||
) : null}
|
||||
{children}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
21
frontend/components/ui/status-pill.tsx
Normal file
21
frontend/components/ui/status-pill.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import { cn } from '@/lib/utils';
|
||||
import type { TaskStatus } from '@/lib/types';
|
||||
|
||||
type StatusPillProps = {
|
||||
status: TaskStatus;
|
||||
};
|
||||
|
||||
const classes: Record<TaskStatus, string> = {
|
||||
queued: 'border-[#33587a] bg-[#0a2c3f] text-[#7ecaf5]',
|
||||
running: 'border-[#4f7a33] bg-[#0f311d] text-[#99f085]',
|
||||
completed: 'border-[#1a7a53] bg-[#083a2a] text-[#8bf7cb]',
|
||||
failed: 'border-[#8f3d3d] bg-[#431616] text-[#ff9c9c]'
|
||||
};
|
||||
|
||||
export function StatusPill({ status }: StatusPillProps) {
|
||||
return (
|
||||
<span className={cn('inline-flex items-center rounded-full border px-2 py-1 text-xs uppercase tracking-[0.16em]', classes[status])}>
|
||||
{status}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user