Adiciona o frontend Next.js em frontend/ (setup, design system, autenticação/tema, layout/navegação, área master, área tenant completa: clientes, produtos, vendas, recebimentos, whatsapp, e-mail, alertas, equipe e perfil). Estende o backend de forma aditiva e autorizada: cookie httpOnly para refresh token (Etapa 13) e CRUD de equipe + edição de perfil do tenant (Etapa 18, módulo src/modules/equipe/ novo e PUT /tenant/perfil). Detalhes completos em Etapas/V2/*. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
59 lines
1.9 KiB
TypeScript
59 lines
1.9 KiB
TypeScript
import { cn } from '@/lib/utils';
|
||
|
||
export const STATUS_PILL_TONES = ['success', 'warning', 'danger', 'primary', 'neutral'] as const;
|
||
type StatusPillTone = (typeof STATUS_PILL_TONES)[number];
|
||
|
||
/**
|
||
* Status de negócio já existentes no backend (Etapas 1–8) → cor semântica
|
||
* + label em português, resolvidos uma única vez aqui para não repetir
|
||
* esse mapeamento em cada tela (Etapa 12).
|
||
*/
|
||
export const STATUS_PILL_MAP = {
|
||
pendente: { tone: 'warning', label: 'Pendente' },
|
||
pago: { tone: 'success', label: 'Pago' },
|
||
atrasado: { tone: 'danger', label: 'Atrasado' },
|
||
cancelado: { tone: 'neutral', label: 'Cancelado' },
|
||
ativo: { tone: 'success', label: 'Ativo' },
|
||
inadimplente: { tone: 'danger', label: 'Inadimplente' },
|
||
suspenso: { tone: 'warning', label: 'Suspenso' },
|
||
trial: { tone: 'primary', label: 'Trial' },
|
||
confirmada: { tone: 'primary', label: 'Confirmada' },
|
||
concluida: { tone: 'success', label: 'Concluída' },
|
||
orcamento: { tone: 'neutral', label: 'Orçamento' },
|
||
cancelada: { tone: 'neutral', label: 'Cancelada' },
|
||
} as const satisfies Record<string, { tone: StatusPillTone; label: string }>;
|
||
|
||
export type BusinessStatus = keyof typeof STATUS_PILL_MAP;
|
||
|
||
const toneClasses: Record<StatusPillTone, string> = {
|
||
success: 'bg-success/10 text-success',
|
||
warning: 'bg-warning/10 text-warning',
|
||
danger: 'bg-danger/10 text-danger',
|
||
primary: 'bg-primary/10 text-primary',
|
||
neutral: 'bg-neutral-500/10 text-neutral-500',
|
||
};
|
||
|
||
interface StatusPillProps {
|
||
status: BusinessStatus;
|
||
className?: string;
|
||
}
|
||
|
||
function StatusPill({ status, className }: StatusPillProps) {
|
||
const config = STATUS_PILL_MAP[status];
|
||
|
||
return (
|
||
<span
|
||
data-slot="status-pill"
|
||
className={cn(
|
||
'inline-flex h-5 w-fit shrink-0 items-center justify-center rounded-full px-2 py-0.5 text-xs font-medium whitespace-nowrap',
|
||
toneClasses[config.tone],
|
||
className,
|
||
)}
|
||
>
|
||
{config.label}
|
||
</span>
|
||
);
|
||
}
|
||
|
||
export { StatusPill };
|