backoffice i18n config

This commit is contained in:
mengstabketemaw
2026-06-16 11:40:38 +03:00
parent 398dbecf35
commit 9ae0f63424
4 changed files with 53 additions and 43 deletions

View File

@@ -29,6 +29,8 @@ export const am: Translations = {
home: 'መነሻ',
notifications: 'ማሳወቂያዎች',
administrator: 'አስተዳዳሪ',
collapse: 'ሰብስብ',
expand: 'ዘርጋ',
},
breadcrumbs: {

View File

@@ -27,6 +27,8 @@ export const en = {
home: 'Home',
notifications: 'Notifications',
administrator: 'Administrator',
collapse: 'Collapse',
expand: 'Expand',
},
breadcrumbs: {

View File

@@ -1,3 +1,4 @@
import { useState } from 'react';
import { AppShell } from '@mantine/core';
import { useDisclosure } from '@mantine/hooks';
import { Outlet } from 'react-router-dom';
@@ -6,11 +7,14 @@ import { AppSidebar } from './components/AppSidebar';
export function BackofficeLayout() {
const [opened, { toggle }] = useDisclosure();
const [collapsed, setCollapsed] = useState(false);
const handleToggleCollapse = () => setCollapsed((prev) => !prev);
return (
<AppShell
header={{ height: 64 }}
navbar={{ width: 264, breakpoint: 'sm', collapsed: { mobile: !opened } }}
navbar={{ width: collapsed ? 80 : 264, breakpoint: 'sm', collapsed: { mobile: !opened } }}
padding="lg"
styles={{ main: { backgroundColor: '#f5f7fb' } }}
>
@@ -18,7 +22,7 @@ export function BackofficeLayout() {
<AppHeader onToggle={toggle} />
</AppShell.Header>
<AppShell.Navbar p="md">
<AppSidebar />
<AppSidebar collapsed={collapsed} onToggleCollapse={handleToggleCollapse} />
</AppShell.Navbar>
<AppShell.Main>
<Outlet />

View File

@@ -1,7 +1,6 @@
import { useTranslation } from 'react-i18next';
import {
AppShell,
Box,
Group,
NavLink,
ScrollArea,
@@ -15,23 +14,21 @@ import {
IconLayoutDashboard,
IconUsers,
IconShieldCheck,
IconLogout,
IconChevronLeft,
IconChevronRight,
} from '@tabler/icons-react';
import { useNavigate, useLocation } from 'react-router-dom';
import { useDispatch } from 'react-redux';
import { logout } from '@ema-platform/auth';
export function AppSidebar() {
interface AppSidebarProps {
collapsed: boolean;
onToggleCollapse: () => void;
}
export function AppSidebar({ collapsed, onToggleCollapse }: AppSidebarProps) {
const { t } = useTranslation();
const navigate = useNavigate();
const dispatch = useDispatch();
const { pathname } = useLocation();
const handleLogout = () => {
dispatch(logout());
navigate('/login');
};
return (
<>
<AppShell.Section pb="md">
@@ -39,73 +36,78 @@ export function AppSidebar() {
<ThemeIcon size={42} radius="md" variant="gradient" gradient={{ from: 'blue', to: 'indigo', deg: 135 }}>
<IconShieldCheck size={22} />
</ThemeIcon>
<div>
<Text fw={700} lh={1.1}>
{t('app.name')}
</Text>
<Text size="xs" c="dimmed" lh={1.2}>
{t('app.tagline')}
</Text>
</div>
{!collapsed && (
<div>
<Text fw={700} lh={1.1}>
{t('app.name')}
</Text>
<Text size="xs" c="dimmed" lh={1.2}>
{t('app.tagline')}
</Text>
</div>
)}
</Group>
</AppShell.Section>
<AppShell.Section grow component={ScrollArea}>
<Stack gap={4}>
<Text size="xs" fw={700} c="dimmed" px="xs" mb={4} style={{ letterSpacing: 1 }}>
{t('nav.menu')}
</Text>
{!collapsed && (
<Text size="xs" fw={700} c="dimmed" px="xs" mb={4} style={{ letterSpacing: 1 }}>
{t('nav.menu')}
</Text>
)}
<NavLink
key="dashboard"
label={t('nav.dashboard')}
label={collapsed ? '' : t('nav.dashboard')}
leftSection={<IconLayoutDashboard size={19} stroke={1.6} />}
active={pathname.startsWith('/dashboard')}
onClick={() => navigate('/dashboard')}
variant="light"
color="blue"
styles={{ root: { borderRadius: rem(10) }, label: { fontWeight: 500 } }}
styles={{
root: { borderRadius: rem(10) },
label: { fontWeight: 500, display: collapsed ? 'none' : 'block' },
}}
/>
<NavLink
key="um"
label={t('nav.userManagement')}
label={collapsed ? '' : t('nav.userManagement')}
leftSection={<IconUsers size={19} stroke={1.6} />}
active={pathname.startsWith('/um')}
onClick={() => navigate('/um/user-management/dashboard')}
variant="light"
color="blue"
styles={{ root: { borderRadius: rem(10) }, label: { fontWeight: 500 } }}
styles={{
root: { borderRadius: rem(10) },
label: { fontWeight: 500, display: collapsed ? 'none' : 'block' },
}}
/>
</Stack>
</AppShell.Section>
<AppShell.Section>
<Group
gap="sm"
gap="xs"
wrap="nowrap"
p="xs"
style={{
borderRadius: rem(12),
background: 'var(--mantine-color-default-hover)',
cursor: 'pointer',
}}
onClick={onToggleCollapse}
>
<ThemeIcon size={38} radius="xl" variant="gradient" gradient={{ from: 'blue', to: 'indigo', deg: 135 }}>
<Text size="sm" fw={700} c="white">AD</Text>
</ThemeIcon>
<Box flex={1} style={{ minWidth: 0 }}>
<Text size="sm" fw={600} truncate>
Amanuel D.
{!collapsed && (
<Text size="sm" fw={500} style={{ flex: 1 }}>
{t('common.collapse')}
</Text>
<Text size="xs" c="dimmed">
{t('common.administrator')}
</Text>
</Box>
)}
<ActionIcon
variant="subtle"
color="gray"
aria-label={t('common.logout')}
onClick={handleLogout}
aria-label={collapsed ? t('common.expand') : t('common.collapse')}
style={{ marginLeft: collapsed ? 'auto' : undefined }}
>
<IconLogout size={18} />
{collapsed ? <IconChevronRight size={18} /> : <IconChevronLeft size={18} />}
</ActionIcon>
</Group>
</AppShell.Section>