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

@@ -4,27 +4,30 @@
*/
export const STAFF_FEATURE_GROUPS = [
{ label: 'Today', read: 'TAB_TODAY_READ', edit: 'TAB_TODAY_EDIT' },
{ label: 'Staff', read: 'TAB_STAFF_READ', edit: 'TAB_STAFF_EDIT' },
{ label: 'Organizations', read: 'TAB_ORGANIZATIONS_READ', edit: 'TAB_ORGANIZATIONS_EDIT' },
{ label: 'Patients', read: 'TAB_PATIENTS_READ', edit: 'TAB_PATIENTS_EDIT' },
{ label: 'Appointment', read: 'TAB_APPOINTMENTS_READ', edit: 'TAB_APPOINTMENTS_EDIT' },
{ label: 'Treatment', read: 'TAB_TREATMENT_READ', edit: 'TAB_TREATMENT_EDIT' },
{ label: 'Billing', read: 'TAB_BILLING_READ', edit: 'TAB_BILLING_EDIT' },
{ label: 'Reports', read: 'TAB_REPORTS_READ', edit: 'TAB_REPORTS_EDIT' },
{ labelKey: 'featureToday', read: 'TAB_TODAY_READ', edit: 'TAB_TODAY_EDIT' },
{ labelKey: 'featureStaff', read: 'TAB_STAFF_READ', edit: 'TAB_STAFF_EDIT' },
{ labelKey: 'featureOrganizations', read: 'TAB_ORGANIZATIONS_READ', edit: 'TAB_ORGANIZATIONS_EDIT' },
{ labelKey: 'featurePatients', read: 'TAB_PATIENTS_READ', edit: 'TAB_PATIENTS_EDIT' },
{ labelKey: 'featureAppointment', read: 'TAB_APPOINTMENTS_READ', edit: 'TAB_APPOINTMENTS_EDIT' },
{ labelKey: 'featureTreatment', read: 'TAB_TREATMENT_READ', edit: 'TAB_TREATMENT_EDIT' },
{ labelKey: 'featureBilling', read: 'TAB_BILLING_READ', edit: 'TAB_BILLING_EDIT' },
{ labelKey: 'featureReports', read: 'TAB_REPORTS_READ', edit: 'TAB_REPORTS_EDIT' },
] as const;
export type FeaturePermState = Record<string, { read: boolean; edit: boolean }>;
export type OrgType = 'CLINIC' | 'LAB' | null | undefined;
type StaffFeaturesTranslate = (key: string) => string;
export function resolveStaffFeatureLabel(
group: (typeof STAFF_FEATURE_GROUPS)[number],
organizationType: OrgType,
t: StaffFeaturesTranslate,
): string {
if (group.read === 'TAB_ORGANIZATIONS_READ') {
return organizationType === 'LAB' ? 'Clinics' : 'Labs';
return organizationType === 'LAB' ? t('featureClinics') : t('featureLabs');
}
return group.label;
return t(group.labelKey);
}
export function emptyFeaturePermissionState(): FeaturePermState {
@@ -64,17 +67,18 @@ export function featureStateHasTreatmentEdit(state: FeaturePermState): boolean {
/** Human-readable access for the team table — feature name, or "Feature (Read only)" */
export function formatAccessSummary(
permissionNames: string[] | null | undefined,
organizationType?: OrgType,
organizationType: OrgType,
t: StaffFeaturesTranslate,
): string {
if (!permissionNames?.length) return 'No tab access';
if (!permissionNames?.length) return t('noTabAccess');
const set = new Set(permissionNames);
const parts: string[] = [];
for (const g of STAFF_FEATURE_GROUPS) {
const hasEdit = set.has(g.edit);
const hasRead = set.has(g.read) || hasEdit;
if (!hasRead) continue;
const label = resolveStaffFeatureLabel(g, organizationType);
parts.push(hasEdit ? label : `${label} (Read only)`);
const label = resolveStaffFeatureLabel(g, organizationType, t);
parts.push(hasEdit ? label : `${label} ${t('readOnlySuffix')}`);
}
return parts.length ? parts.join(' · ') : 'No tab access';
return parts.length ? parts.join(' · ') : t('noTabAccess');
}