Skip to content

Commit

Permalink
[000] add translations and ability to change languages
Browse files Browse the repository at this point in the history
  • Loading branch information
pro100Koss committed Dec 16, 2024
1 parent 34e0516 commit b9c8c5e
Show file tree
Hide file tree
Showing 9 changed files with 118 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ export function OrganizationRegistrationForm(props: Props) {
},
});

showSuccess({ description: 'Organisation successfully created' });
showSuccess(t('organization.registration.success'));
props.onSuccess();
} catch (e) {
console.error(e);
showError({ title: 'Error', description: 'Failed to register organization' });
showError(t('organization.registration.failed'));
}
}

Expand Down
2 changes: 1 addition & 1 deletion frontend/spa/src/components/views/InvoicesView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function InvoicesView() {
setInvoices(invoices);
} catch (e) {
console.error('Failed to load invoices:', e);
showError({ title: 'Failed to load invoices' });
showError(t('invoices.loadFailed'));
} finally {
setIsLoading(false);
}
Expand Down
15 changes: 8 additions & 7 deletions frontend/spa/src/components/views/OrganizationSettingsView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { Bommel } from '@/services/api/types/Bommel.ts';
import organizationTreeService from '@/services/OrganizationTreeService.ts';

function OrganizationSettingsView() {
const { toast } = useToast();
const { showSuccess, showError } = useToast();
const { t } = useTranslation();
const store = useStore();
const [isOrganizationError, setIsOrganizationError] = useState(false);
Expand All @@ -33,13 +33,14 @@ function OrganizationSettingsView() {
};

const onClickSave = async () => {
// sort tree by depth

const sortedTree = organizationTreeService.sortTreeByDepth(tree);
console.log('Sorted tree', sortedTree);

await organizationTreeService.saveOrganizationTree(sortedTree, rootBommel!.id!, originalBommels);
toast({ title: t('organizationSettings.saved'), variant: 'success' });
try {
await organizationTreeService.saveOrganizationTree(sortedTree, rootBommel!.id!, originalBommels);
showSuccess(t('organization.settings.saved'));
} catch (e) {
console.error(e);
showError(t('organization.settings.saveError'));
}
};

useEffect(() => {
Expand Down
29 changes: 23 additions & 6 deletions frontend/spa/src/components/views/ProfileSettingsView.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
import { useCallback, useState } from 'react';
import { useTranslation } from 'react-i18next';

import themeService, { Themes } from '@/services/ThemeService.ts';
import Radio from '@/components/ui/Radio.tsx';
import SettingsPageHeader from '@/components/SettingsPage/SettingsPageHeader.tsx';
import Select from '@/components/ui/Select.tsx';
import languageService from '@/services/LanguageService.ts';

function ProfileSettingsView() {
const [themes] = useState([
const { t } = useTranslation();
const themes = [
{ label: 'Light', value: 'light' },
{ label: 'Dark', value: 'dark' },
{ label: 'Auto', value: 'auto' },
]);
];
const languages = [
{ label: 'English', value: 'en' },
{ label: 'German', value: 'de' },
{ label: 'Ukrainian', value: 'uk' },
];
const [theme, setTheme] = useState(themeService.isAutoMode() ? 'auto' : themeService.getTheme());
const [currentLanguage, setCurrentLanguage] = useState(languageService.getLanguage());

const onThemeChanged = useCallback((value: string) => {
setTheme(value);
Expand All @@ -22,20 +32,27 @@ function ProfileSettingsView() {
}
}, []);

const onLanguageChanged = useCallback((value: string) => {
setCurrentLanguage(value);
languageService.setLanguage(value);
}, []);

return (
<>
<SettingsPageHeader />
<div>
<div className="mt-4">
<div className="flex flex-row">
<div className="min-w-[200px]">Theme:</div>
<div className="min-w-[200px]">{t('profile.settings.theme')}:</div>
<div>
<Radio items={themes} value={theme || 'auto'} layout="horizontal" onValueChange={onThemeChanged} />
</div>
</div>
<div className="flex flex-row">
<div className="min-w-[200px]">Other settings....</div>
<div>...</div>
<div className="flex flex-row my-2">
<div className="min-w-[200px] leading-10">{t('profile.settings.language')}:</div>
<div>
<Select items={languages} value={currentLanguage} onValueChanged={onLanguageChanged} />
</div>
</div>
</div>
</div>
Expand Down
20 changes: 13 additions & 7 deletions frontend/spa/src/components/views/SettingsView.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
import { useState, useEffect } from 'react';
import { useNavigate, useLocation } from 'react-router-dom';
import { useTranslation } from 'react-i18next';

import SettingsPage from '@/components/SettingsPage/SettingsPage.tsx';
import ProfileSettingsView from '@/components/views/ProfileSettingsView.tsx';
import OrganizationSettingsView from '@/components/views/OrganizationSettingsView.tsx';
import { MenuItem } from '@/components/SettingsPage/MenuItem.ts';
import InvoicesView from './InvoicesView';

const navigationItems: MenuItem[] = [
{ title: 'Profile', value: 'profile', icon: 'Avatar' },
{ title: 'Organization', value: 'organization', icon: 'Backpack' },
{ title: 'Invoices', value: 'invoices', icon: 'Archive' },
];
import languageService from '@/services/LanguageService.ts';

function SettingsView() {
const { t } = useTranslation();
const navigate = useNavigate();
const location = useLocation();
const [activeTab, setActiveTab] = useState(navigationItems[0].value);
const [navigationItems, setMenuItems] = useState<MenuItem[]>([]);
const [activeTab, setActiveTab] = useState('profile');

useEffect(() => {
setMenuItems([
{ title: t('settings.menu.profile'), value: 'profile', icon: 'Avatar' },
{ title: t('settings.menu.organization'), value: 'organization', icon: 'Backpack' },
{ title: t('settings.menu.invoices'), value: 'invoices', icon: 'Archive' },
]);
}, [languageService.getLanguage()]);

useEffect(() => {
const path = location.pathname.split('/').pop();
Expand Down
4 changes: 2 additions & 2 deletions frontend/spa/src/hooks/use-toast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,8 @@ function useToast() {
toast,
dismiss: (toastId?: string) => dispatch({ type: ActionType.DISMISS_TOAST, toastId }),
show: (props: Toast) => toast({ ...props, variant: 'success' }),
showSuccess: (props: Toast) => toast({ ...props, variant: 'success' }),
showError: (props: Toast) => toast({ ...props, variant: 'error' }),
showSuccess: (message: string, props?: Toast) => toast({ title: message, ...props, variant: 'success' }),
showError: (message: string, props?: Toast) => toast({ title: message, ...props, variant: 'error' }),
};
}

Expand Down
25 changes: 23 additions & 2 deletions frontend/spa/src/locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,31 @@
"register": "Registrieren"
},
"invoices": {
"loadFailed": "Rechnungen konnten nicht geladen werden",
"noInvoices": "Keine Rechnungen vorzulegen"
},
"organizationSettings": {
"saved": "Organisationsstruktur erfolgreich gespeichert"
"organization": {
"registration": {
"failed": "Organisation konnte nicht registriert werden",
"success": "Organisation erfolgreich erstellt"
},
"settings": {
"saveError": "Einstellung konnte nicht gespeichert werden",
"saved": "Einstellungen erfolgreich gespeichert"
}
},
"profile": {
"settings": {
"language": "Sprache",
"theme": "Thema"
}
},
"settings": {
"menu": {
"invoices": "Rechnungen",
"organization": "Organisation",
"profile": "Profil"
}
},
"settingsPage": {
"menu": "Speisekarte"
Expand Down
25 changes: 23 additions & 2 deletions frontend/spa/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,31 @@
"register": "Register"
},
"invoices": {
"loadFailed": "Failed to load invoices",
"noInvoices": "No invoices to show"
},
"organizationSettings": {
"saved": "Organization structure successfully saved"
"organization": {
"registration": {
"failed": "Failed to register organization",
"success": "Organisation successfully created"
},
"settings": {
"saveError": "Failed to save setting",
"saved": "Settings successfully saved"
}
},
"profile": {
"settings": {
"language": "Language",
"theme": "Theme"
}
},
"settings": {
"menu": {
"invoices": "Invoices",
"organization": "Organization",
"profile": "Profile"
}
},
"settingsPage": {
"menu": "Menu"
Expand Down
25 changes: 23 additions & 2 deletions frontend/spa/src/locales/uk.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,31 @@
"register": "Зареєструватися"
},
"invoices": {
"loadFailed": "Не вдалося завантажити рахунки-фактури",
"noInvoices": "Немає рахунків-фактур для показу"
},
"organizationSettings": {
"saved": "Струкрура організації успішно збережена"
"organization": {
"registration": {
"failed": "Не вдалося зареєструвати організацію",
"success": "Організацію успішно створено"
},
"settings": {
"saveError": "Не вдалося зберегти налаштування",
"saved": "Налаштування успішно збережені"
}
},
"profile": {
"settings": {
"language": "Мова",
"theme": "Тема"
}
},
"settings": {
"menu": {
"invoices": "Рахунки-фактури",
"organization": "організація",
"profile": "Профіль"
}
},
"settingsPage": {
"menu": "Меню"
Expand Down

0 comments on commit b9c8c5e

Please sign in to comment.