ui phase 2

This commit is contained in:
hamid
2026-07-17 19:05:17 +03:30
parent 370c1beefa
commit 222856d600
42 changed files with 1354 additions and 451 deletions
@@ -99,6 +99,7 @@ import ForwardIcon from '@mui/icons-material/ArrowForwardRounded';
import ShareIcon from '@mui/icons-material/ShareRounded';
import CopyIcon from '@mui/icons-material/ContentCopyRounded';
import AttachmentIcon from '@mui/icons-material/AttachFileRounded';
import LanguageIcon from '@mui/icons-material/TranslateRounded';
/**
* List of all available Icon names
@@ -202,6 +203,7 @@ export const ICONS /* Note: Setting type disables property autocomplete :( was -
share: ShareIcon,
copy: CopyIcon,
attachment: AttachmentIcon,
language: LanguageIcon,
};
/**
@@ -0,0 +1,40 @@
import { render, screen, fireEvent } from '@testing-library/react';
import { ThemeProvider } from '../../../theme';
const replace = jest.fn();
jest.mock('next-intl', () => ({
useLocale: () => 'fa',
useTranslations: () => (key: string, params?: Record<string, unknown>) =>
params ? `${key}:${params.locale}` : key,
}));
jest.mock('@/i18n/navigation', () => ({
usePathname: () => '/nurse/earnings',
useRouter: () => ({ replace }),
}));
import LocaleSwitcher from './LocaleSwitcher';
describe('<LocaleSwitcher/> component', () => {
beforeEach(() => replace.mockClear());
it('renders a single icon button', () => {
render(
<ThemeProvider>
<LocaleSwitcher />
</ThemeProvider>,
);
expect(screen.getAllByRole('button')).toHaveLength(1);
});
it('replaces the current path with the other locale on click, preserving the route', () => {
render(
<ThemeProvider>
<LocaleSwitcher />
</ThemeProvider>,
);
fireEvent.click(screen.getByRole('button'));
expect(replace).toHaveBeenCalledWith('/nurse/earnings', { locale: 'en' });
});
});
@@ -0,0 +1,32 @@
'use client';
import { FunctionComponent } from 'react';
import { useLocale, useTranslations } from 'next-intl';
import { usePathname, useRouter } from '@/i18n/navigation';
import type { Locale } from '@/i18n/routing';
import AppIconButton from '../AppIconButton';
const LOCALE_LABEL: Record<Locale, string> = { fa: 'فارسی', en: 'English' };
/**
* Switches between `fa`/`en` while preserving the current route — `router.replace(pathname,
* { locale })` via the `@/i18n/navigation` wrapper, so a deep link (e.g. `/fa/nurse/earnings`)
* lands on the same page in the other locale rather than resetting to home.
* @component LocaleSwitcher
*/
const LocaleSwitcher: FunctionComponent = () => {
const locale = useLocale() as Locale;
const pathname = usePathname();
const router = useRouter();
const t = useTranslations('common');
const nextLocale: Locale = locale === 'fa' ? 'en' : 'fa';
return (
<AppIconButton
icon="language"
title={t('switch_locale', { locale: LOCALE_LABEL[nextLocale] })}
onClick={() => router.replace(pathname, { locale: nextLocale })}
/>
);
};
export default LocaleSwitcher;
@@ -0,0 +1,3 @@
import LocaleSwitcher from './LocaleSwitcher';
export default LocaleSwitcher;
+2
View File
@@ -16,6 +16,7 @@ import Money from './Money';
import StatusTimeline from './StatusTimeline';
import JalaliDatePicker from './JalaliDatePicker';
import JalaliDateField from './JalaliDateField';
import LocaleSwitcher from './LocaleSwitcher';
export {
ErrorBoundary,
@@ -36,6 +37,7 @@ export {
StatusTimeline,
JalaliDatePicker,
JalaliDateField,
LocaleSwitcher,
};
export type { EmptyStateProps } from './EmptyState';
export type { ErrorStateProps } from './ErrorState';