Minor bug fixing

This commit is contained in:
Paulo Gustavo Veiga 2021-02-13 10:10:02 -08:00
parent 6091b6a7ad
commit 719623ea3a
7 changed files with 131 additions and 107 deletions

View File

@ -14,71 +14,76 @@ import { Provider } from 'react-redux';
import { QueryClient, QueryClientProvider } from 'react-query'; import { QueryClient, QueryClientProvider } from 'react-query';
import { CssBaseline, ThemeProvider } from '@material-ui/core'; import { CssBaseline, ThemeProvider } from '@material-ui/core';
import { theme } from './theme' import { theme } from './theme'
import AppI18n, { Locale, Locales } from './classes/app-i18n';
function loadLocaleData(language: string) {
switch (language) {
case 'es':
return require('./compiled-lang/es.json')
default:
return require('./compiled-lang/en.json')
}
}
const queryClient = new QueryClient({ const queryClient = new QueryClient({
defaultOptions: { defaultOptions: {
queries: { queries: {
refetchIntervalInBackground: false, refetchIntervalInBackground: false,
staleTime: 5*1000*60 // 10 minutes staleTime: 5 * 1000 * 60 // 10 minutes
} }
} }
}); });
const App = () => { const App = () => {
const [messages, setMessages] = useState(undefined); const [messages, setMessages] = useState(undefined);
// Boostrap i18n ... const [appi18n, setAppi18n] = useState<AppI18n>( new AppI18n('es'));
const locale = (navigator.languages && navigator.languages[0])
|| navigator.language
|| 'en-US';
useEffect(() => { useEffect(() => {
const language = locale.split('-')[0];
const fetchData = async () => { // @Todo: Why can not be dynamc ?
const messages = await loadLocaleData(language); const loadResourceBundle = async (locale: Locale) => {
setMessages(messages); let result;
console.log("Language:" + locale.code);
switch (locale.code) {
case 'en':
result = require('./compiled-lang/en.json');
break;
case 'es':
result = require('./compiled-lang/es.json');
break;
}
return result;
} }
const fetchData = async () => {
const locale = appi18n.getLocale();
const msg = await loadResourceBundle(locale);
setMessages(msg);
}
fetchData(); fetchData();
}, []); }, []);
return messages ? ( return messages ? (
<Provider store={store}> <Provider store={store}>
<GlobalStyle /> <GlobalStyle />
<QueryClientProvider client={queryClient}> <QueryClientProvider client={queryClient}>
<IntlProvider locale={locale} defaultLocale='en' messages={messages}> <IntlProvider locale={appi18n.getLocale().code} defaultLocale={Locales.EN.code} messages={messages}>
<ThemeProvider theme={theme}> <ThemeProvider theme={theme}>
<CssBaseline /> <CssBaseline />
<Router> <Router>
<Switch> <Switch>
<Route exact path="/"> <Route exact path="/">
<Redirect to="/c/login" /> <Redirect to="/c/login" />
</Route> </Route>
<Route path="/c/login" component={LoginPage} /> <Route path="/c/login" component={LoginPage} />
<Route path="/c/registration"> <Route path="/c/registration">
<RegistationPage /> <RegistationPage />
</Route> </Route>
<Route path="/c/registration-success" component={RegistrationSuccessPage} /> <Route path="/c/registration-success" component={RegistrationSuccessPage} />
<Route path="/c/forgot-password"> <Route path="/c/forgot-password">
<ForgotPasswordPage /> <ForgotPasswordPage />
</Route> </Route>
<Route path="/c/forgot-password-success" component={ForgotPasswordSuccessPage} /> <Route path="/c/forgot-password-success" component={ForgotPasswordSuccessPage} />
<Route path="/c/maps/"> <Route path="/c/maps/">
<MapsPage /> <MapsPage />
</Route> </Route>
</Switch> </Switch>
</Router> </Router>
</ThemeProvider> </ThemeProvider>
</IntlProvider> </IntlProvider>
</QueryClientProvider> </QueryClientProvider>
</Provider> </Provider>
) : <div>Loading ... </div> ) : <div>Loading ... </div>

View File

@ -0,0 +1,70 @@
export class Locale {
code: LocaleCode;
label: string;
constructor(code: LocaleCode, label: string) {
this.code = code;
this.label = label;
}
}
export default class AppI18n {
private locale: Locale = Locales.EN;
constructor(localeCode: string) {
try {
this.locale = localeFromStr(localeCode)
} catch {
this.locale = this.browserLocale();
}
}
getLocale(): Locale {
return this.locale;
}
resourceBundle(): string {
return `./compiled-lang/${this.locale.code}.json`;
}
private browserLocale(): Locale {
let localeCode = (navigator.languages && navigator.languages[0])
|| navigator.language;
// Just remove the variant ...
localeCode = localeCode.split('-')[0];
let result = Locales.EN;
try {
result = localeFromStr(localeCode)
} catch {
console.warn(`Unsupported languange code ${localeCode}`);
}
return result;
}
}
export type LocaleCode = 'en' | 'es' | 'fr' | 'de';
export const Locales =
{
EN: new Locale('en', 'English'),
ES: new Locale('es', 'Español'),
DE: new Locale('de', 'Français'),
FR: new Locale('fr', 'Deutsch'),
}
export const localeFromStr = (code: string): Locale => {
const locales: Locale[] = Object
.values(Locales);
const result = locales
.find((l) => l.code == code);
if (!result) {
throw `Langunage code could not be found in list of default supported: + ${code}`
}
return result;
}

View File

@ -1,51 +0,0 @@
export class Locale {
code: LocaleCode;
label: string;
constructor(code: LocaleCode) {
this.code = code;
const label = LocalToStr.get(code);
this.label = label ? label : 'Undefined';
}
}
export default class AppLocale {
private localeCode: LocaleCode = 'en';
constructor(locale?: LocaleCode) {
this.localeCode = locale ? locale : this.defaultLocale();
}
toString(): string {
const result = LocalToStr.get(this.localeCode);
if (result == null) {
throw `Locale could not be translated: ${this.localeCode}`
}
return result ? result : 'Undefined';
}
private defaultLocale(): LocaleCode {
const browserLocale = (navigator.languages && navigator.languages[0])
|| navigator.language;
// Is a supported language ?
let result:LocaleCode = 'en';
if (LocalToStr.get(browserLocale as LocaleCode)) {
result = browserLocale as LocaleCode;
}
return result;
}
}
const LocalToStr = new Map<LocaleCode, string>([["en", "English"], ["es", "Español"], ["fr", "Français"], ["de", "Deutsch"]]);
export type LocaleCode = 'en' | 'es' | 'fr' | 'de';
export const Locales =
{
EN: new Locale('en'),
ES: new Locale('es'),
DE: new Locale('de'),
FR: new Locale('fr'),
}

View File

@ -1,4 +1,4 @@
import { LocaleCode } from "../app-locale" import { Locale, LocaleCode } from "../app-i18n"
export type NewUser = { export type NewUser = {
email: string; email: string;
@ -61,7 +61,7 @@ export type AccountInfo = {
firstName: string; firstName: string;
lastName: string; lastName: string;
email: string; email: string;
language: LocaleCode; locale: Locale;
} }
interface Client { interface Client {

View File

@ -1,6 +1,5 @@
import { Language } from '@material-ui/icons';
import Client, { AccountInfo, BasicMapInfo, ChangeHistory, ImportMapInfo, Label, MapInfo, NewUser } from '..'; import Client, { AccountInfo, BasicMapInfo, ChangeHistory, ImportMapInfo, Label, MapInfo, NewUser } from '..';
import { LocaleCode } from '../../app-locale'; import { LocaleCode, localeFromStr, Locales } from '../../app-i18n';
class MockClient implements Client { class MockClient implements Client {
private maps: MapInfo[] = []; private maps: MapInfo[] = [];
private labels: Label[] = []; private labels: Label[] = [];
@ -51,9 +50,10 @@ class MockClient implements Client {
firstName: 'Costme', firstName: 'Costme',
lastName: 'Fulanito', lastName: 'Fulanito',
email: 'test@example.com', email: 'test@example.com',
language: locale ? locale : 'en' locale: localeFromStr(locale)
}); });
} }
deleteMaps(ids: number[]): Promise<void> { deleteMaps(ids: number[]): Promise<void> {
ids.forEach(id => this.deleteMap(id)); ids.forEach(id => this.deleteMap(id));
return Promise.resolve(); return Promise.resolve();

View File

@ -1,6 +1,6 @@
import axios from 'axios'; import axios from 'axios';
import Client, { ErrorInfo, MapInfo, BasicMapInfo, NewUser, Label, ChangeHistory, AccountInfo, ImportMapInfo } from '..'; import Client, { ErrorInfo, MapInfo, BasicMapInfo, NewUser, Label, ChangeHistory, AccountInfo, ImportMapInfo } from '..';
import { LocaleCode } from '../../app-locale'; import { LocaleCode, localeFromStr, Locales } from '../../app-i18n';
export default class RestClient implements Client { export default class RestClient implements Client {
private baseUrl: string; private baseUrl: string;
@ -45,7 +45,7 @@ export default class RestClient implements Client {
lastName: account.lastName ? account.lastName : '', lastName: account.lastName ? account.lastName : '',
firstName: account.fistName ? account.fistName : '', firstName: account.fistName ? account.fistName : '',
email: account.email, email: account.email,
language: locale ? locale : 'en' locale: locale ? localeFromStr(locale) : Locales.EN
}); });
}).catch(error => { }).catch(error => {
const errorInfo = this.parseResponseOnError(error.response); const errorInfo = this.parseResponseOnError(error.response);

View File

@ -6,7 +6,7 @@ import Client, { ErrorInfo, AccountInfo } from "../../../classes/client";
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import { activeInstance } from '../../../redux/clientSlice'; import { activeInstance } from '../../../redux/clientSlice';
import { FormattedMessage, useIntl } from 'react-intl'; import { FormattedMessage, useIntl } from 'react-intl';
import AppLocale, { LocaleCode, Locales } from '../../../classes/app-locale'; import AppI18n, { LocaleCode, Locales } from '../../../classes/app-i18n';
@ -44,7 +44,7 @@ const LanguageMenu = () => {
return client.fetchAccountInfo(); return client.fetchAccountInfo();
}); });
const locale = new AppLocale(data?.language); const locale = data?.locale;
return ( return (
<span> <span>
<Tooltip title={intl.formatMessage({ id: 'language.change', defaultMessage: 'Change Language' })}> <Tooltip title={intl.formatMessage({ id: 'language.change', defaultMessage: 'Change Language' })}>
@ -56,7 +56,7 @@ const LanguageMenu = () => {
onClick={handleMenu} onClick={handleMenu}
startIcon={<TranslateTwoTone />} startIcon={<TranslateTwoTone />}
> >
{locale.toString()} {locale?.label}
</Button> </Button>
</Tooltip> </Tooltip>
<Menu id="appbar-language" <Menu id="appbar-language"