mirror of
https://github.com/Luchexx/wacrm.git
synced 2026-11-02 17:29:45 +00:00
The legal brief on third-party trademark use says: avoid the WhatsApp teal/green palette and any visual treatment that could read as a WhatsApp/Meta product. Emerald-500 was used as the primary brand colour across hero, CTAs, sidebar, charts, badges, and the favicon — close enough in hue to WhatsApp's signature green to muddy the line. Swapping to Tailwind violet (which matches the Hostinger brand purple #7c3aed) makes the visual identity unambiguously ours. Scope: - Mechanical Tailwind class swap: emerald-* → violet-* across src/. - src/app/globals.css: --primary, --ring, --sidebar-primary, --sidebar-ring, --chart-1 oklch tokens swapped from emerald (oklch 0.696 0.17 162) to Hostinger-aligned violet (oklch 0.526 0.247 293). - src/app/icon.tsx: favicon background #10b981 → #7c3aed. - src/app/opengraph-image.tsx: badge bg, accent text, gradient. - src/components/landing/hero.tsx + cta-banner.tsx: radial-gradient hex. - src/components/landing/mock/analytics-mock.tsx: marketing chart line. - src/components/dashboard/conversations-chart.tsx + response-time-chart.tsx: "Outgoing" series colour. Distinguishable from "Incoming" blue at a glance; we can revisit the chart pair later for stronger colourblind contrast (separate concern). - README.md: license badge colour parameter. Out of scope: - src/components/settings/tag-manager.tsx still offers "Emerald" as one of the user-pickable contact-tag colours alongside Blue / Yellow / Red / etc. — that's a user data choice, not a brand mark. Contrast check: white text on #7c3aed measures ~4.78:1 (WCAG AA passing for normal body text). Violet-400 (#a78bfa) on slate-950 measures ~10:1 for accent text, well clear of AA. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
92 lines
2.4 KiB
TypeScript
92 lines
2.4 KiB
TypeScript
/**
|
|
* Shared status badge config for broadcasts + recipients.
|
|
*
|
|
* Previously `statusConfig` was defined inline in both
|
|
* /broadcasts/page.tsx and /broadcasts/[id]/page.tsx with slight
|
|
* drift risk. One source of truth now.
|
|
*
|
|
* Dark-theme only — bg-*-500/10 + text-*-400 + border-*-500/20.
|
|
*/
|
|
|
|
import type { BroadcastStatus, RecipientStatus } from "@/types";
|
|
|
|
export interface StatusDisplay {
|
|
label: string;
|
|
classes: string;
|
|
/**
|
|
* Set true for statuses that should pulse in the UI to convey
|
|
* "live / in-flight" — currently only `sending`.
|
|
*/
|
|
pulse?: boolean;
|
|
}
|
|
|
|
export const broadcastStatusConfig: Record<BroadcastStatus, StatusDisplay> = {
|
|
draft: {
|
|
label: "Draft",
|
|
classes: "bg-slate-500/10 text-slate-400 border-slate-500/20",
|
|
},
|
|
scheduled: {
|
|
label: "Scheduled",
|
|
classes: "bg-blue-500/10 text-blue-400 border-blue-500/20",
|
|
},
|
|
sending: {
|
|
label: "Sending",
|
|
classes: "bg-yellow-500/10 text-yellow-400 border-yellow-500/20",
|
|
pulse: true,
|
|
},
|
|
sent: {
|
|
label: "Sent",
|
|
classes: "bg-violet-500/10 text-violet-400 border-violet-500/20",
|
|
},
|
|
failed: {
|
|
label: "Failed",
|
|
classes: "bg-red-500/10 text-red-400 border-red-500/20",
|
|
},
|
|
};
|
|
|
|
export const recipientStatusConfig: Record<RecipientStatus, StatusDisplay> = {
|
|
pending: {
|
|
label: "Pending",
|
|
classes: "bg-slate-500/10 text-slate-400 border-slate-500/20",
|
|
},
|
|
sent: {
|
|
label: "Sent",
|
|
classes: "bg-blue-500/10 text-blue-400 border-blue-500/20",
|
|
},
|
|
delivered: {
|
|
label: "Delivered",
|
|
classes: "bg-violet-500/10 text-violet-400 border-violet-500/20",
|
|
},
|
|
read: {
|
|
label: "Read",
|
|
classes: "bg-violet-500/10 text-violet-300 border-violet-500/20",
|
|
},
|
|
replied: {
|
|
label: "Replied",
|
|
classes: "bg-purple-500/10 text-purple-400 border-purple-500/20",
|
|
},
|
|
failed: {
|
|
label: "Failed",
|
|
classes: "bg-red-500/10 text-red-400 border-red-500/20",
|
|
},
|
|
};
|
|
|
|
/**
|
|
* Tolerant lookup — callers often have a generic string status
|
|
* coming from Supabase. Falls back to the "draft" / "pending"
|
|
* entry so the UI never crashes on an unknown value.
|
|
*/
|
|
export function getBroadcastStatus(status: string): StatusDisplay {
|
|
return (
|
|
broadcastStatusConfig[status as BroadcastStatus] ??
|
|
broadcastStatusConfig.draft
|
|
);
|
|
}
|
|
|
|
export function getRecipientStatus(status: string): StatusDisplay {
|
|
return (
|
|
recipientStatusConfig[status as RecipientStatus] ??
|
|
recipientStatusConfig.pending
|
|
);
|
|
}
|