feat: implement secure multi-tenancy, RBAC, and premium dark mode
All checks were successful
Build and Deploy / build-and-push (push) Successful in 1m54s

- Enforced tenant isolation and Role-Based Access Control across all API routes

- Implemented secure profile avatar upload using multer and UUIDs

- Redesigned UI with a premium "Onyx & Gold" Charcoal dark mode

- Added Funnel Stage and Origin filters to Dashboard and User Detail pages

- Replaced "Referral" with "Indicação" across the platform and database

- Optimized Dockerfile and local environment setup for reliable deployments

- Fixed frontend syntax errors and improved KPI/Chart visualizations
This commit is contained in:
Cauê Faleiros
2026-03-03 17:16:55 -03:00
parent b7e73fce3d
commit 20bdf510fd
32 changed files with 2810 additions and 1140 deletions

View File

@@ -11,21 +11,19 @@ interface KPICardProps {
colorClass?: string;
}
export const KPICard: React.FC<KPICardProps> = ({ title, value, subValue, trend, trendValue, icon: Icon, colorClass = "bg-blue-500" }) => {
export const KPICard: React.FC<KPICardProps> = ({ title, value, subValue, trend, trendValue, icon: Icon, colorClass = "text-blue-600" }) => {
// Extract base color from colorClass (e.g., 'text-yellow-600' -> 'yellow')
const baseColor = colorClass.split('-')[1] || 'blue';
return (
<div className="bg-white p-6 rounded-2xl shadow-sm border border-slate-100 flex flex-col justify-between hover:shadow-md transition-shadow duration-300">
<div className="bg-white dark:bg-dark-card p-6 rounded-2xl shadow-sm border border-zinc-100 dark:border-dark-border flex flex-col justify-between hover:shadow-md transition-all duration-300">
<div className="flex justify-between items-start mb-4">
<div>
<h3 className="text-slate-500 text-sm font-medium mb-1">{title}</h3>
<div className="text-3xl font-bold text-slate-800 tracking-tight">{value}</div>
<h3 className="text-zinc-500 dark:text-dark-muted text-sm font-medium mb-1">{title}</h3>
<div className="text-3xl font-bold text-zinc-800 dark:text-dark-text tracking-tight">{value}</div>
</div>
<div className={`p-3 rounded-xl ${colorClass} bg-opacity-10 text-opacity-100`}>
{/* Note: In Tailwind bg-opacity works if colorClass is like 'bg-blue-500'.
Here we assume the consumer passes specific utility classes or we construct them.
Simpler approach: Use a wrapper */}
<div className={`w-8 h-8 flex items-center justify-center rounded-lg ${colorClass.replace('text', 'bg').replace('500', '100')} ${colorClass}`}>
<Icon size={20} />
</div>
<div className={`p-3 rounded-xl bg-${baseColor}-100 dark:bg-${baseColor}-500/20 flex items-center justify-center transition-colors border border-transparent dark:border-${baseColor}-500/30`}>
<Icon size={20} className={`${colorClass} dark:text-${baseColor}-400`} />
</div>
</div>
@@ -33,7 +31,7 @@ export const KPICard: React.FC<KPICardProps> = ({ title, value, subValue, trend,
<div className="flex items-center gap-2 text-sm mt-auto">
{trend === 'up' && <span className="text-green-500 flex items-center font-medium"> {trendValue}</span>}
{trend === 'down' && <span className="text-red-500 flex items-center font-medium"> {trendValue}</span>}
{subValue && <span className="text-slate-400">{subValue}</span>}
{subValue && <span className="text-zinc-400 dark:text-dark-muted">{subValue}</span>}
</div>
)}
</div>