Generated by Spark: Make dashboard use translations

This commit is contained in:
2026-01-27 14:03:48 +00:00
committed by GitHub
parent c43e5a9bd8
commit e4dee19be7
4 changed files with 121 additions and 40 deletions

View File

@@ -14,42 +14,47 @@ import {
} from '@phosphor-icons/react'
import { cn } from '@/lib/utils'
import type { DashboardMetrics } from '@/lib/types'
import { useTranslation } from '@/hooks/use-translation'
interface DashboardViewProps {
metrics: DashboardMetrics
}
export function DashboardView({ metrics }: DashboardViewProps) {
const { t } = useTranslation()
return (
<div className="space-y-6">
<div>
<h2 className="text-3xl font-semibold tracking-tight">Dashboard</h2>
<p className="text-muted-foreground mt-1">Real-time overview of your workforce operations</p>
<h2 className="text-3xl font-semibold tracking-tight">{t('dashboard.title')}</h2>
<p className="text-muted-foreground mt-1">{t('dashboard.subtitle')}</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
<MetricCard
title="Pending Approvals"
title={t('dashboard.pendingApprovals')}
value={metrics.pendingApprovals}
icon={<ClockCounterClockwise size={20} className="text-warning" />}
trend={{ value: 12, direction: 'up' }}
trendText={t('dashboard.vsLastWeek', { value: '12' })}
variant="warning"
/>
<MetricCard
title="Pending Expenses"
title={t('dashboard.pendingExpenses')}
value={metrics.pendingExpenses}
icon={<Notepad size={20} className="text-info" />}
variant="default"
/>
<MetricCard
title="Overdue Invoices"
title={t('dashboard.overdueInvoices')}
value={metrics.overdueInvoices}
icon={<Receipt size={20} className="text-destructive" />}
trend={{ value: 5, direction: 'down' }}
trendText={t('dashboard.vsLastWeek', { value: '5' })}
variant="error"
/>
<MetricCard
title="Compliance Alerts"
title={t('dashboard.complianceAlerts')}
value={metrics.complianceAlerts}
icon={<Warning size={20} className="text-warning" />}
variant="warning"
@@ -59,8 +64,8 @@ export function DashboardView({ metrics }: DashboardViewProps) {
<div className="grid grid-cols-1 lg:grid-cols-3 gap-4">
<Card className="lg:col-span-1">
<CardHeader>
<CardTitle className="text-lg">Monthly Revenue</CardTitle>
<CardDescription>Total invoiced this month</CardDescription>
<CardTitle className="text-lg">{t('dashboard.monthlyRevenue')}</CardTitle>
<CardDescription>{t('dashboard.monthlyRevenueDescription')}</CardDescription>
</CardHeader>
<CardContent>
<div className="text-3xl font-semibold font-mono">
@@ -68,15 +73,15 @@ export function DashboardView({ metrics }: DashboardViewProps) {
</div>
<div className="flex items-center gap-1 mt-2 text-sm text-success">
<ArrowUp size={16} weight="bold" />
<span>12.5% from last month</span>
<span>{t('dashboard.vsLastMonth', { value: '12.5' })}</span>
</div>
</CardContent>
</Card>
<Card className="lg:col-span-1">
<CardHeader>
<CardTitle className="text-lg">Monthly Payroll</CardTitle>
<CardDescription>Total payroll costs</CardDescription>
<CardTitle className="text-lg">{t('dashboard.monthlyPayroll')}</CardTitle>
<CardDescription>{t('dashboard.monthlyPayrollDescription')}</CardDescription>
</CardHeader>
<CardContent>
<div className="text-3xl font-semibold font-mono">
@@ -84,15 +89,15 @@ export function DashboardView({ metrics }: DashboardViewProps) {
</div>
<div className="flex items-center gap-1 mt-2 text-sm text-muted-foreground">
<ArrowUp size={16} weight="bold" />
<span>8.3% from last month</span>
<span>{t('dashboard.vsLastMonth', { value: '8.3' })}</span>
</div>
</CardContent>
</Card>
<Card className="lg:col-span-1">
<CardHeader>
<CardTitle className="text-lg">Gross Margin</CardTitle>
<CardDescription>Revenue minus payroll</CardDescription>
<CardTitle className="text-lg">{t('dashboard.grossMargin')}</CardTitle>
<CardDescription>{t('dashboard.grossMarginDescription')}</CardDescription>
</CardHeader>
<CardContent>
<div className="text-3xl font-semibold font-mono">
@@ -100,7 +105,7 @@ export function DashboardView({ metrics }: DashboardViewProps) {
</div>
<div className="flex items-center gap-1 mt-2 text-sm text-success">
<ArrowUp size={16} weight="bold" />
<span>3.2% from last month</span>
<span>{t('dashboard.vsLastMonth', { value: '3.2' })}</span>
</div>
</CardContent>
</Card>
@@ -109,34 +114,34 @@ export function DashboardView({ metrics }: DashboardViewProps) {
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
<Card>
<CardHeader>
<CardTitle className="text-lg">Recent Activity</CardTitle>
<CardDescription>Latest timesheet and billing events</CardDescription>
<CardTitle className="text-lg">{t('dashboard.recentActivity')}</CardTitle>
<CardDescription>{t('dashboard.recentActivityDescription')}</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-4">
<ActivityItem
icon={<CheckCircle size={18} className="text-success" />}
title="Timesheet approved"
title={t('dashboard.timesheetApproved')}
description="John Smith - Week ending 15 Jan 2025"
time="5 minutes ago"
time={t('dashboard.minutesAgo', { value: '5' })}
/>
<ActivityItem
icon={<Receipt size={18} className="text-info" />}
title="Invoice generated"
title={t('dashboard.invoiceGenerated')}
description="INV-00234 - Acme Corp - £2,450"
time="12 minutes ago"
time={t('dashboard.minutesAgo', { value: '12' })}
/>
<ActivityItem
icon={<CheckCircle size={18} className="text-success" />}
title="Payroll completed"
title={t('dashboard.payrollCompleted')}
description="Weekly run - 45 workers - £28,900"
time="1 hour ago"
time={t('dashboard.hourAgo', { value: '1' })}
/>
<ActivityItem
icon={<Warning size={18} className="text-warning" />}
title="Document expiring soon"
description="DBS check for Sarah Johnson - 14 days"
time="2 hours ago"
title={t('dashboard.documentExpiringSoon')}
description={`DBS check for Sarah Johnson - ${t('dashboard.days', { value: '14' })}`}
time={t('dashboard.hoursAgo', { value: '2' })}
/>
</div>
</CardContent>
@@ -144,25 +149,25 @@ export function DashboardView({ metrics }: DashboardViewProps) {
<Card>
<CardHeader>
<CardTitle className="text-lg">Quick Actions</CardTitle>
<CardDescription>Common tasks and workflows</CardDescription>
<CardTitle className="text-lg">{t('dashboard.quickActions')}</CardTitle>
<CardDescription>{t('dashboard.quickActionsDescription')}</CardDescription>
</CardHeader>
<CardContent className="space-y-2">
<Button className="w-full justify-start" variant="outline">
<Clock size={18} className="mr-2" />
Create Timesheet
{t('dashboard.createTimesheet')}
</Button>
<Button className="w-full justify-start" variant="outline">
<Receipt size={18} className="mr-2" />
Generate Invoice
{t('dashboard.generateInvoice')}
</Button>
<Button className="w-full justify-start" variant="outline">
<CurrencyDollar size={18} className="mr-2" />
Run Payroll
{t('dashboard.runPayroll')}
</Button>
<Button className="w-full justify-start" variant="outline">
<Download size={18} className="mr-2" />
Export Reports
{t('dashboard.exportReports')}
</Button>
</CardContent>
</Card>
@@ -176,10 +181,11 @@ interface MetricCardProps {
value: number
icon: React.ReactNode
trend?: { value: number; direction: 'up' | 'down' }
trendText?: string
variant?: 'default' | 'success' | 'warning' | 'error'
}
function MetricCard({ title, value, icon, trend, variant = 'default' }: MetricCardProps) {
function MetricCard({ title, value, icon, trend, trendText, variant = 'default' }: MetricCardProps) {
const borderColors = {
default: 'border-border',
success: 'border-success/20',
@@ -207,7 +213,7 @@ function MetricCard({ title, value, icon, trend, variant = 'default' }: MetricCa
) : (
<ArrowDown size={14} weight="bold" />
)}
<span>{trend.value}% vs last week</span>
<span>{trendText || `${trend.value}% vs last week`}</span>
</div>
)}
</CardContent>

View File

@@ -80,13 +80,38 @@
},
"dashboard": {
"title": "Dashboard",
"subtitle": "Overview of key metrics and activities",
"subtitle": "Real-time overview of your workforce operations",
"welcomeBack": "Welcome back",
"recentActivity": "Recent Activity",
"recentActivityDescription": "Latest timesheet and billing events",
"quickActions": "Quick Actions",
"quickActionsDescription": "Common tasks and workflows",
"notifications": "Notifications",
"pendingApprovals": "Pending Approvals",
"upcomingDeadlines": "Upcoming Deadlines"
"pendingExpenses": "Pending Expenses",
"overdueInvoices": "Overdue Invoices",
"complianceAlerts": "Compliance Alerts",
"upcomingDeadlines": "Upcoming Deadlines",
"monthlyRevenue": "Monthly Revenue",
"monthlyRevenueDescription": "Total invoiced this month",
"monthlyPayroll": "Monthly Payroll",
"monthlyPayrollDescription": "Total payroll costs",
"grossMargin": "Gross Margin",
"grossMarginDescription": "Revenue minus payroll",
"createTimesheet": "Create Timesheet",
"generateInvoice": "Generate Invoice",
"runPayroll": "Run Payroll",
"exportReports": "Export Reports",
"timesheetApproved": "Timesheet approved",
"invoiceGenerated": "Invoice generated",
"payrollCompleted": "Payroll completed",
"documentExpiringSoon": "Document expiring soon",
"vsLastWeek": "{{value}}% vs last week",
"vsLastMonth": "{{value}}% from last month",
"minutesAgo": "{{value}} minutes ago",
"hourAgo": "{{value}} hour ago",
"hoursAgo": "{{value}} hours ago",
"days": "{{value}} days"
},
"timesheets": {
"title": "Timesheets",

View File

@@ -80,13 +80,38 @@
},
"dashboard": {
"title": "Panel de Control",
"subtitle": "Resumen de métricas y actividades clave",
"subtitle": "Vista general en tiempo real de sus operaciones de fuerza laboral",
"welcomeBack": "Bienvenido de nuevo",
"recentActivity": "Actividad Reciente",
"recentActivityDescription": "Últimos eventos de hojas de tiempo y facturación",
"quickActions": "Acciones Rápidas",
"quickActionsDescription": "Tareas y flujos de trabajo comunes",
"notifications": "Notificaciones",
"pendingApprovals": "Aprobaciones Pendientes",
"upcomingDeadlines": "Plazos Próximos"
"pendingExpenses": "Gastos Pendientes",
"overdueInvoices": "Facturas Vencidas",
"complianceAlerts": "Alertas de Cumplimiento",
"upcomingDeadlines": "Plazos Próximos",
"monthlyRevenue": "Ingresos Mensuales",
"monthlyRevenueDescription": "Total facturado este mes",
"monthlyPayroll": "Nómina Mensual",
"monthlyPayrollDescription": "Costos totales de nómina",
"grossMargin": "Margen Bruto",
"grossMarginDescription": "Ingresos menos nómina",
"createTimesheet": "Crear Hoja de Tiempo",
"generateInvoice": "Generar Factura",
"runPayroll": "Ejecutar Nómina",
"exportReports": "Exportar Informes",
"timesheetApproved": "Hoja de tiempo aprobada",
"invoiceGenerated": "Factura generada",
"payrollCompleted": "Nómina completada",
"documentExpiringSoon": "Documento por vencer pronto",
"vsLastWeek": "{{value}}% vs semana pasada",
"vsLastMonth": "{{value}}% desde el mes pasado",
"minutesAgo": "hace {{value}} minutos",
"hourAgo": "hace {{value}} hora",
"hoursAgo": "hace {{value}} horas",
"days": "{{value}} días"
},
"timesheets": {
"title": "Hojas de Tiempo",

View File

@@ -80,13 +80,38 @@
},
"dashboard": {
"title": "Tableau de Bord",
"subtitle": "Aperçu des métriques et activités clés",
"subtitle": "Aperçu en temps réel de vos opérations de main-d'œuvre",
"welcomeBack": "Bon retour",
"recentActivity": "Activité Récente",
"recentActivityDescription": "Derniers événements de feuilles de temps et de facturation",
"quickActions": "Actions Rapides",
"quickActionsDescription": "Tâches et flux de travail courants",
"notifications": "Notifications",
"pendingApprovals": "Approbations en Attente",
"upcomingDeadlines": "Échéances à Venir"
"pendingExpenses": "Dépenses en Attente",
"overdueInvoices": "Factures en Retard",
"complianceAlerts": "Alertes de Conformité",
"upcomingDeadlines": "Échéances à Venir",
"monthlyRevenue": "Revenus Mensuels",
"monthlyRevenueDescription": "Total facturé ce mois-ci",
"monthlyPayroll": "Paie Mensuelle",
"monthlyPayrollDescription": "Coûts totaux de la paie",
"grossMargin": "Marge Brute",
"grossMarginDescription": "Revenus moins paie",
"createTimesheet": "Créer une Feuille de Temps",
"generateInvoice": "Générer une Facture",
"runPayroll": "Exécuter la Paie",
"exportReports": "Exporter les Rapports",
"timesheetApproved": "Feuille de temps approuvée",
"invoiceGenerated": "Facture générée",
"payrollCompleted": "Paie terminée",
"documentExpiringSoon": "Document expirant bientôt",
"vsLastWeek": "{{value}}% par rapport à la semaine dernière",
"vsLastMonth": "{{value}}% par rapport au mois dernier",
"minutesAgo": "il y a {{value}} minutes",
"hourAgo": "il y a {{value}} heure",
"hoursAgo": "il y a {{value}} heures",
"days": "{{value}} jours"
},
"timesheets": {
"title": "Feuilles de Temps",