feat: complete UI/UX refinement, email flow updates, and deep black theme
All checks were successful
Build and Deploy / build-and-push (push) Successful in 2m18s
All checks were successful
Build and Deploy / build-and-push (push) Successful in 2m18s
- Updated all email templates to a clean light theme and changed button text to 'Finalizar Cadastro'. - Enforced a strict 15-minute expiration on all auth/reset tokens. - Created SetupAccount flow distinct from ResetPassword to capture user name during admin init. - Refined dark mode to a premium True Black (Onyx) palette using Zinc. - Fixed Dashboard KPI visibility and true period-over-period trend logic. - Enhanced TeamManagement with global tenant filtering for Super Admins. - Implemented secure User URL routing via slugs instead of raw UUIDs. - Enforced strict Agent-level RBAC for viewing attendances.
This commit is contained in:
@@ -12,9 +12,10 @@ interface KPICardProps {
|
||||
}
|
||||
|
||||
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';
|
||||
|
||||
// Extract base color from colorClass (e.g., 'text-brand-yellow' -> 'brand-yellow' or 'text-blue-600' -> 'blue-600')
|
||||
// Safer extraction:
|
||||
const baseColor = colorClass.replace('text-', '').split(' ')[0]; // gets 'brand-yellow' or 'zinc-500'
|
||||
|
||||
return (
|
||||
<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">
|
||||
@@ -22,8 +23,8 @@ export const KPICard: React.FC<KPICardProps> = ({ title, value, subValue, trend,
|
||||
<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 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 className={`p-3 rounded-xl bg-${baseColor.split('-')[0]}-100 dark:bg-zinc-800 flex items-center justify-center transition-colors border border-transparent dark:border-dark-border`}>
|
||||
<Icon size={20} className={`${colorClass} dark:text-${baseColor.split('-')[0]}-400`} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -31,6 +32,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>}
|
||||
{trend === 'neutral' && <span className="text-zinc-500 dark:text-dark-muted flex items-center font-medium">- {trendValue}</span>}
|
||||
{subValue && <span className="text-zinc-400 dark:text-dark-muted">{subValue}</span>}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -106,7 +106,7 @@ export const SellersTable: React.FC<SellersTableProps> = ({ data }) => {
|
||||
<tr
|
||||
key={item.user.id}
|
||||
className="hover:bg-yellow-50/10 dark:hover:bg-yellow-400/5 transition-colors cursor-pointer group"
|
||||
onClick={() => navigate(`/users/${item.user.id}`)}
|
||||
onClick={() => navigate(`/users/${item.user.slug || item.user.id}`)}
|
||||
>
|
||||
<td className="px-6 py-4">
|
||||
<div className="flex items-center gap-3">
|
||||
|
||||
Reference in New Issue
Block a user