mirror of
https://github.com/Tria-plc/emaui.git
synced 2026-08-28 19:30:58 +00:00
feat: add i18n support and localized labels to certification and profession features commit
This commit is contained in:
@@ -35,7 +35,8 @@ export function LocationDetail({
|
||||
onEdit,
|
||||
onDelete,
|
||||
}: LocationDetailProps) {
|
||||
const { t } = useTranslation();
|
||||
const { t, i18n } = useTranslation();
|
||||
const locale = i18n.language as 'en' | 'am';
|
||||
const typeInfo = locationTypes.find(
|
||||
(lt) => lt.id === location.locationTypeId,
|
||||
);
|
||||
@@ -47,7 +48,7 @@ export function LocationDetail({
|
||||
return (
|
||||
<Paper p="lg" radius="md" withBorder>
|
||||
<Group justify="space-between" mb="xs">
|
||||
<Title order={4}>{location.names.en}</Title>
|
||||
<Title order={4}>{location.names[locale]}</Title>
|
||||
<Group gap="xs">
|
||||
<Button
|
||||
variant="light"
|
||||
@@ -89,7 +90,7 @@ export function LocationDetail({
|
||||
</Badge>
|
||||
{typeInfo && (
|
||||
<Badge size="lg" variant="light" color="teal">
|
||||
{typeInfo.names.en}
|
||||
{typeInfo.names[locale]}
|
||||
</Badge>
|
||||
)}
|
||||
</Group>
|
||||
@@ -99,15 +100,9 @@ export function LocationDetail({
|
||||
<Stack gap="sm">
|
||||
<div>
|
||||
<Text size="xs" c="dimmed" tt="uppercase" fw={600}>
|
||||
{t('location.nameEn')}
|
||||
{t('location.name')}
|
||||
</Text>
|
||||
<Text size="sm">{location.names.en}</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text size="xs" c="dimmed" tt="uppercase" fw={600}>
|
||||
{t('location.nameAm')}
|
||||
</Text>
|
||||
<Text size="sm">{location.names.am}</Text>
|
||||
<Text size="sm">{location.names[locale]}</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text size="xs" c="dimmed" tt="uppercase" fw={600}>
|
||||
@@ -120,7 +115,7 @@ export function LocationDetail({
|
||||
<Text size="xs" c="dimmed" tt="uppercase" fw={600}>
|
||||
{t('location.type')}
|
||||
</Text>
|
||||
<Text size="sm">{typeInfo.names.en} (Level {typeInfo.level})</Text>
|
||||
<Text size="sm">{typeInfo.names[locale]} ({t('location.level')} {typeInfo.level})</Text>
|
||||
</div>
|
||||
)}
|
||||
</Stack>
|
||||
|
||||
@@ -44,7 +44,8 @@ export function LocationForm({
|
||||
onCancel,
|
||||
isSubmitting,
|
||||
}: LocationFormProps) {
|
||||
const { t } = useTranslation();
|
||||
const { t, i18n } = useTranslation();
|
||||
const locale = i18n.language as 'en' | 'am';
|
||||
|
||||
const isEditing = !!editingLocation;
|
||||
|
||||
@@ -125,7 +126,7 @@ export function LocationForm({
|
||||
{parentLocation && !isEditing && (
|
||||
<TextInput
|
||||
label={t('location.parent')}
|
||||
value={parentLocation.names.en}
|
||||
value={parentLocation.names[locale]}
|
||||
disabled
|
||||
mb="sm"
|
||||
size="sm"
|
||||
@@ -139,7 +140,7 @@ export function LocationForm({
|
||||
placeholder={t('location.selectType')}
|
||||
data={allAtLevel.map((lt) => ({
|
||||
value: lt.id,
|
||||
label: lt.names.en,
|
||||
label: lt.names[locale],
|
||||
}))}
|
||||
{...form.getInputProps('locationTypeId')}
|
||||
size="sm"
|
||||
@@ -153,7 +154,7 @@ export function LocationForm({
|
||||
</Text>
|
||||
{type ? (
|
||||
<Badge size="lg" variant="light" color="blue">
|
||||
{type.names.en}
|
||||
{type.names[locale]}
|
||||
</Badge>
|
||||
) : (
|
||||
<Text size="sm" c="red">
|
||||
|
||||
@@ -32,7 +32,8 @@ interface LocationTypeFormValues {
|
||||
}
|
||||
|
||||
export function LocationTypeModal({ opened, onClose }: { opened: boolean; onClose: () => void }) {
|
||||
const { t } = useTranslation();
|
||||
const { t, i18n } = useTranslation();
|
||||
const locale = i18n.language as 'en' | 'am';
|
||||
const { data: locationTypes, isLoading } = useGetLocationTypesQuery();
|
||||
const [createType] = useCreateLocationTypeMutation();
|
||||
const [updateType] = useUpdateLocationTypeMutation();
|
||||
@@ -49,9 +50,9 @@ export function LocationTypeModal({ opened, onClose }: { opened: boolean; onClos
|
||||
level: 1,
|
||||
},
|
||||
validate: {
|
||||
code: (v) => (!v ? 'Code is required' : null),
|
||||
namesEn: (v) => (!v ? 'English name is required' : null),
|
||||
namesAm: (v) => (!v ? 'Amharic name is required' : null),
|
||||
code: (v) => (!v ? t('location.validation.codeRequired') : null),
|
||||
namesEn: (v) => (!v ? t('location.validation.nameEnRequired') : null),
|
||||
namesAm: (v) => (!v ? t('location.validation.nameAmRequired') : null),
|
||||
level: (v) => (v < 1 ? 'Level must be at least 1' : null),
|
||||
},
|
||||
});
|
||||
@@ -119,6 +120,7 @@ export function LocationTypeModal({ opened, onClose }: { opened: boolean; onClos
|
||||
variant="light"
|
||||
leftSection={<IconPlus size={16} />}
|
||||
onClick={() => setShowForm(true)}
|
||||
mt="md"
|
||||
mb="md"
|
||||
size="sm"
|
||||
>
|
||||
@@ -130,25 +132,25 @@ export function LocationTypeModal({ opened, onClose }: { opened: boolean; onClos
|
||||
<form onSubmit={handleSubmit}>
|
||||
<Stack gap="sm" mb="md">
|
||||
<TextInput
|
||||
label="Code"
|
||||
label={t('location.code')}
|
||||
placeholder="e.g., COUNTRY, REGION, CITY"
|
||||
{...form.getInputProps('code')}
|
||||
size="sm"
|
||||
/>
|
||||
<TextInput
|
||||
label="Name (English)"
|
||||
label={t('location.nameEn')}
|
||||
placeholder="English name"
|
||||
{...form.getInputProps('namesEn')}
|
||||
size="sm"
|
||||
/>
|
||||
<TextInput
|
||||
label="Name (Amharic)"
|
||||
label={t('location.nameAm')}
|
||||
placeholder="የአማርኛ ስም"
|
||||
{...form.getInputProps('namesAm')}
|
||||
size="sm"
|
||||
/>
|
||||
<NumberInput
|
||||
label="Level"
|
||||
label={t('location.level')}
|
||||
placeholder="1"
|
||||
min={1}
|
||||
max={10}
|
||||
@@ -179,10 +181,9 @@ export function LocationTypeModal({ opened, onClose }: { opened: boolean; onClos
|
||||
<Table striped highlightOnHover>
|
||||
<Table.Thead>
|
||||
<Table.Tr>
|
||||
<Table.Th>Level</Table.Th>
|
||||
<Table.Th>Code</Table.Th>
|
||||
<Table.Th>Name (EN)</Table.Th>
|
||||
<Table.Th>Name (AM)</Table.Th>
|
||||
<Table.Th>{t('location.level')}</Table.Th>
|
||||
<Table.Th>{t('location.code')}</Table.Th>
|
||||
<Table.Th>{t('location.name')}</Table.Th>
|
||||
<Table.Th />
|
||||
</Table.Tr>
|
||||
</Table.Thead>
|
||||
@@ -199,8 +200,7 @@ export function LocationTypeModal({ opened, onClose }: { opened: boolean; onClos
|
||||
{type.code}
|
||||
</Badge>
|
||||
</Table.Td>
|
||||
<Table.Td>{type.names.en}</Table.Td>
|
||||
<Table.Td>{type.names.am}</Table.Td>
|
||||
<Table.Td>{type.names[locale]}</Table.Td>
|
||||
<Table.Td>
|
||||
<Group gap="xs">
|
||||
<ActionIcon
|
||||
|
||||
@@ -31,7 +31,8 @@ import {
|
||||
import type { Location } from '../types/location';
|
||||
|
||||
export function LocationPage() {
|
||||
const { t } = useTranslation();
|
||||
const { t, i18n } = useTranslation();
|
||||
const locale = i18n.language as 'en' | 'am';
|
||||
const { data: locationTypesRes, isLoading: typesLoading } = useGetLocationTypesQuery();
|
||||
const [createLocation, { isLoading: isCreating }] = useCreateLocationMutation();
|
||||
const [updateLocation, { isLoading: isUpdating }] = useUpdateLocationMutation();
|
||||
@@ -221,7 +222,7 @@ export function LocationPage() {
|
||||
>
|
||||
<Text mb="md">
|
||||
{t('location.deleteConfirmText', {
|
||||
name: selectedLocation?.names.en ?? '',
|
||||
name: selectedLocation?.names[locale] ?? '',
|
||||
})}
|
||||
</Text>
|
||||
<Group justify="flex-end">
|
||||
|
||||
Reference in New Issue
Block a user