mirror of
https://github.com/Tria-plc/emaui.git
synced 2026-08-28 23:00:59 +00:00
added internationalization for backoffice
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { useState, type ElementType, type ReactNode } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
Paper,
|
||||
Text,
|
||||
@@ -64,21 +65,25 @@ const ROLES = [
|
||||
{ name: 'Guest', value: 10, color: '#93c5fd' },
|
||||
];
|
||||
|
||||
const KPIS = [
|
||||
{ label: 'Total Users', value: '9,431', icon: IconUsers, color: 'blue', trend: '+12.5%', up: true },
|
||||
{ label: 'Active Users', value: '7,218', icon: IconUserCheck, color: 'indigo', trend: '+8.2%', up: true },
|
||||
{ label: 'New This Month', value: '642', icon: IconUserPlus, color: 'cyan', trend: '+23.1%', up: true },
|
||||
{ label: 'Pending Approvals', value: '37', icon: IconClockHour4, color: 'orange', trend: '-4.0%', up: false },
|
||||
];
|
||||
function useKpis(t: (key: string) => string) {
|
||||
return [
|
||||
{ label: t('dashboard.kpis.totalUsers'), value: '9,431', icon: IconUsers, color: 'blue', trend: '+12.5%', up: true },
|
||||
{ label: t('dashboard.kpis.activeUsers'), value: '7,218', icon: IconUserCheck, color: 'indigo', trend: '+8.2%', up: true },
|
||||
{ label: t('dashboard.kpis.newThisMonth'), value: '642', icon: IconUserPlus, color: 'cyan', trend: '+23.1%', up: true },
|
||||
{ label: t('dashboard.kpis.pendingApprovals'), value: '37', icon: IconClockHour4, color: 'orange', trend: '-4.0%', up: false },
|
||||
];
|
||||
}
|
||||
|
||||
const QUICK_LINKS = [
|
||||
{ label: 'Add User', desc: 'Create a new account', icon: IconUserPlus, color: 'blue' },
|
||||
{ label: 'Roles & Permissions', desc: 'Manage access levels', icon: IconShieldLock, color: 'indigo' },
|
||||
{ label: 'Invite Members', desc: 'Send email invites', icon: IconMail, color: 'cyan' },
|
||||
{ label: 'Import Users', desc: 'Bulk CSV import', icon: IconUpload, color: 'violet' },
|
||||
{ label: 'Export Data', desc: 'Download reports', icon: IconDownload, color: 'blue' },
|
||||
{ label: 'Audit Log', desc: 'Review activity', icon: IconClipboardList, color: 'grape' },
|
||||
];
|
||||
function useQuickLinks(t: (key: string) => string) {
|
||||
return [
|
||||
{ label: t('dashboard.quickLinks.addUser'), desc: t('dashboard.quickLinks.addUserDesc'), icon: IconUserPlus, color: 'blue' },
|
||||
{ label: t('dashboard.quickLinks.rolesAndPermissions'), desc: t('dashboard.quickLinks.rolesAndPermissionsDesc'), icon: IconShieldLock, color: 'indigo' },
|
||||
{ label: t('dashboard.quickLinks.inviteMembers'), desc: t('dashboard.quickLinks.inviteMembersDesc'), icon: IconMail, color: 'cyan' },
|
||||
{ label: t('dashboard.quickLinks.importUsers'), desc: t('dashboard.quickLinks.importUsersDesc'), icon: IconUpload, color: 'violet' },
|
||||
{ label: t('dashboard.quickLinks.exportData'), desc: t('dashboard.quickLinks.exportDataDesc'), icon: IconDownload, color: 'blue' },
|
||||
{ label: t('dashboard.quickLinks.auditLog'), desc: t('dashboard.quickLinks.auditLogDesc'), icon: IconClipboardList, color: 'grape' },
|
||||
];
|
||||
}
|
||||
|
||||
type UserStatus = 'Active' | 'Pending' | 'Invited';
|
||||
const STATUS_COLOR: Record<UserStatus, string> = {
|
||||
@@ -214,16 +219,19 @@ function QuickLinkTile({
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
export function DashboardPage() {
|
||||
const { t } = useTranslation();
|
||||
const [range, setRange] = useState('week');
|
||||
const kpis = useKpis(t);
|
||||
const quickLinks = useQuickLinks(t);
|
||||
|
||||
return (
|
||||
<Stack gap="xl">
|
||||
{/* header */}
|
||||
<Group justify="space-between" align="flex-end" wrap="wrap">
|
||||
<Stack gap={4}>
|
||||
<Title order={2}>Overview</Title>
|
||||
<Title order={2}>{t('dashboard.title')}</Title>
|
||||
<Text c="dimmed" size="sm">
|
||||
Welcome back — here's what's happening across your platform.
|
||||
{t('dashboard.subtitle')}
|
||||
</Text>
|
||||
</Stack>
|
||||
<Group gap="sm">
|
||||
@@ -232,20 +240,20 @@ export function DashboardPage() {
|
||||
onChange={setRange}
|
||||
radius="md"
|
||||
data={[
|
||||
{ label: 'Today', value: 'today' },
|
||||
{ label: 'This Week', value: 'week' },
|
||||
{ label: 'This Month', value: 'month' },
|
||||
{ label: t('dashboard.timeRange.today'), value: 'today' },
|
||||
{ label: t('dashboard.timeRange.thisWeek'), value: 'week' },
|
||||
{ label: t('dashboard.timeRange.thisMonth'), value: 'month' },
|
||||
]}
|
||||
/>
|
||||
<Button leftSection={<IconDownload size={16} />} radius="md">
|
||||
Export
|
||||
{t('common.export')}
|
||||
</Button>
|
||||
</Group>
|
||||
</Group>
|
||||
|
||||
{/* KPIs */}
|
||||
<SimpleGrid cols={{ base: 1, sm: 2, lg: 4 }} spacing="lg">
|
||||
{KPIS.map((k) => (
|
||||
{kpis.map((k) => (
|
||||
<StatCard key={k.label} {...k} />
|
||||
))}
|
||||
</SimpleGrid>
|
||||
@@ -256,15 +264,15 @@ export function DashboardPage() {
|
||||
<SectionCard>
|
||||
<Group justify="space-between" align="flex-start" mb="lg">
|
||||
<CardHeading
|
||||
title="User Registrations"
|
||||
subtitle="New sign-ups over the last 8 months"
|
||||
title={t('dashboard.charts.userRegistrations')}
|
||||
subtitle={t('dashboard.charts.registrationsSubtitle')}
|
||||
/>
|
||||
<Stack gap={0} align="flex-end">
|
||||
<Text fw={700} c="teal">
|
||||
+18.2%
|
||||
</Text>
|
||||
<Text size="xs" c="dimmed">
|
||||
vs previous period
|
||||
{t('dashboard.charts.vsPreviousPeriod')}
|
||||
</Text>
|
||||
</Stack>
|
||||
</Group>
|
||||
@@ -309,7 +317,7 @@ export function DashboardPage() {
|
||||
|
||||
<Grid.Col span={{ base: 12, lg: 4 }}>
|
||||
<SectionCard>
|
||||
<CardHeading title="Users by Role" subtitle="Distribution across access levels" />
|
||||
<CardHeading title={t('dashboard.charts.usersByRole')} subtitle={t('dashboard.charts.roleDistribution')} />
|
||||
<Group mt="lg" justify="center" wrap="nowrap" gap="lg">
|
||||
<Box pos="relative" w={168} h={168} style={{ flexShrink: 0 }}>
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
@@ -348,7 +356,7 @@ export function DashboardPage() {
|
||||
9,431
|
||||
</Text>
|
||||
<Text size="xs" c="dimmed">
|
||||
Total users
|
||||
{t('dashboard.charts.totalUsers')}
|
||||
</Text>
|
||||
</Stack>
|
||||
</Box>
|
||||
@@ -376,9 +384,9 @@ export function DashboardPage() {
|
||||
<Grid gutter="lg" align="stretch">
|
||||
<Grid.Col span={{ base: 12, lg: 8 }}>
|
||||
<SectionCard>
|
||||
<CardHeading title="Quick Links" subtitle="Common administrative shortcuts" />
|
||||
<CardHeading title={t('dashboard.quickLinks.title')} subtitle={t('dashboard.quickLinks.subtitle')} />
|
||||
<SimpleGrid cols={{ base: 2, sm: 3 }} spacing="md" mt="lg">
|
||||
{QUICK_LINKS.map((q) => (
|
||||
{quickLinks.map((q) => (
|
||||
<QuickLinkTile key={q.label} {...q} />
|
||||
))}
|
||||
</SimpleGrid>
|
||||
@@ -389,11 +397,11 @@ export function DashboardPage() {
|
||||
<SectionCard>
|
||||
<Group justify="space-between" mb="md">
|
||||
<Text fw={700} fz="lg">
|
||||
Recent Users
|
||||
{t('dashboard.recentUsers.title')}
|
||||
</Text>
|
||||
<Anchor size="sm" fw={600}>
|
||||
<Group gap={4} wrap="nowrap">
|
||||
View all
|
||||
{t('common.viewAll')}
|
||||
<IconArrowRight size={14} />
|
||||
</Group>
|
||||
</Anchor>
|
||||
|
||||
Reference in New Issue
Block a user