feature: localization's first implmentation done. all frontend hardcoded text is now localized.

This commit is contained in:
2026-06-20 14:51:43 +03:30
parent 284fbd08aa
commit b2f4dfa4ca
52 changed files with 3306 additions and 1041 deletions

View File

@@ -1,5 +1,6 @@
'use client';
import { useTranslations } from 'next-intl';
import { Button } from '@/components/ui/shared/Button';
import { DialogCloseButton } from '@/components/ui/shared/DialogCloseButton';
import { Input } from '@/components/ui/shared/Input';
@@ -31,26 +32,29 @@ function CreatePatientFormFields({
loading: boolean;
showCancel: boolean;
}) {
const t = useTranslations('patients');
const tCommon = useTranslations('common');
return (
<>
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
<Input
label="First name"
label={t('firstName')}
value={formData.firstName || ''}
onChange={(e) => onChange({ firstName: e.target.value })}
/>
<Input
label="Last name"
label={t('lastName')}
value={formData.lastName || ''}
onChange={(e) => onChange({ lastName: e.target.value })}
/>
<Input
label="Phone"
label={t('phone')}
value={formData.phone || ''}
onChange={(e) => onChange({ phone: e.target.value })}
/>
<Input
label="Email"
label={tCommon('email')}
type="email"
value={formData.email || ''}
onChange={(e) => onChange({ email: e.target.value })}
@@ -64,11 +68,11 @@ function CreatePatientFormFields({
isLoading={loading}
disabled={!formData.firstName || !formData.lastName}
>
Save Patient
{t('savePatient')}
</Button>
{showCancel && (
<Button variant="ghost" onClick={onClose}>
Cancel
{tCommon('cancel')}
</Button>
)}
</div>
@@ -85,6 +89,8 @@ export function CreatePatientModal({
loading = false,
variant = 'inline',
}: CreatePatientModalProps) {
const t = useTranslations('patients');
if (!isOpen) {
return null;
}
@@ -112,7 +118,7 @@ export function CreatePatientModal({
id="create-patient-dialog-title"
className="text-lg font-semibold text-text-primary pr-2"
>
New patient
{t('dialogTitle')}
</h2>
<DialogCloseButton onClick={onClose} />
</div>

View File

@@ -1,5 +1,6 @@
'use client';
import { useTranslations } from 'next-intl';
import { Search } from 'lucide-react';
import { Input } from '@/components/ui/shared/Input';
import { Patient } from '@/types/patient';
@@ -21,20 +22,22 @@ export function PatientSearchSelect({
onSelectPatient,
loading = false,
}: PatientSearchSelectProps) {
const t = useTranslations('patients');
return (
<div className="surface-card p-4 space-y-4">
<Input
placeholder="Search patients by name, phone, email"
placeholder={t('searchPlaceholder')}
value={search}
onChange={(e) => onSearchChange(e.target.value)}
icon={<Search className="h-4 w-4 icon-flat" />}
/>
<div className="space-y-2 max-h-80 overflow-y-auto">
{loading && <p className="text-sm text-text-muted">Loading patients...</p>}
{loading && <p className="text-sm text-text-muted">{t('loadingPatients')}</p>}
{!loading && patients.length === 0 && (
<p className="text-sm text-text-muted">No patients found for this search.</p>
<p className="text-sm text-text-muted">{t('noResults')}</p>
)}
{patients.map((patient) => {
@@ -53,7 +56,7 @@ export function PatientSearchSelect({
<p className="text-sm font-medium text-text-primary">
{patient.firstName} {patient.lastName}
</p>
<p className="text-xs text-text-muted">{patient.phone || patient.email || 'No contact'}</p>
<p className="text-xs text-text-muted">{patient.phone || patient.email || t('noContact')}</p>
</button>
);
})}

View File

@@ -1,3 +1,6 @@
'use client';
import { useTranslations } from 'next-intl';
import { Patient } from '@/types/patient';
interface PatientSummaryCardProps {
@@ -5,10 +8,12 @@ interface PatientSummaryCardProps {
}
export function PatientSummaryCard({ patient }: PatientSummaryCardProps) {
const t = useTranslations('patients');
if (!patient) {
return (
<div className="surface-card p-4">
<p className="text-sm text-text-muted">Select a patient to view details.</p>
<p className="text-sm text-text-muted">{t('selectPatient')}</p>
</div>
);
}
@@ -18,10 +23,15 @@ export function PatientSummaryCard({ patient }: PatientSummaryCardProps) {
<h2 className="text-lg font-semibold text-text-primary">
{patient.firstName} {patient.lastName}
</h2>
<p className="text-sm text-text-secondary">Phone: {patient.phone || '-'}</p>
<p className="text-sm text-text-secondary">Email: {patient.email || '-'}</p>
<p className="text-sm text-text-secondary">
Status: {patient.isActive ? 'Active' : 'Inactive'}
{t('phoneLabel')} {patient.phone || t('emptyValue')}
</p>
<p className="text-sm text-text-secondary">
{t('emailLabel')} {patient.email || t('emptyValue')}
</p>
<p className="text-sm text-text-secondary">
{t('statusLabel')}{' '}
{patient.isActive ? t('statusActive') : t('statusInactive')}
</p>
</div>
);