Skip to content

Commit f622088

Browse files
committed
Added more languages and picker
1 parent 2326a95 commit f622088

File tree

16 files changed

+432
-125
lines changed

16 files changed

+432
-125
lines changed

frontend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
"format": "yarn prettier -- --write",
6464
"lint:fix": "eslint --fix --ext .ts --ext .tsx .",
6565
"locale-extract": "formatjs extract 'src/**/*.tsx' --out-file src/locale/src/en.json",
66-
"locale-compile": "formatjs compile-folder src/locale/src src/locale/lang --ast"
66+
"locale-compile": "formatjs compile-folder src/locale/src src/locale/lang"
6767
},
6868
"browserslist": {
6969
"production": [

frontend/public/index.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@
5555
rel="stylesheet"
5656
href="https://unpkg.com/@tabler/[email protected]/dist/css/tabler.min.css"
5757
/>
58+
<link
59+
rel="stylesheet"
60+
href="https://unpkg.com/@tabler/[email protected]/dist/css/tabler-flags.min.css"
61+
/>
5862
</head>
5963
<body>
6064
<noscript>You need to enable JavaScript to run this app.</noscript>

frontend/src/App.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
import React from "react";
22

33
import Router from "components/Router";
4-
import { AuthProvider, HealthProvider } from "context";
4+
import { AuthProvider, HealthProvider, LocaleProvider } from "context";
55
import { intl } from "locale";
66
import { RawIntlProvider } from "react-intl";
77

88
function App() {
99
return (
1010
<RawIntlProvider value={intl}>
11-
<HealthProvider>
12-
<AuthProvider>
13-
<Router />
14-
</AuthProvider>
15-
</HealthProvider>
11+
<LocaleProvider>
12+
<HealthProvider>
13+
<AuthProvider>
14+
<Router />
15+
</AuthProvider>
16+
</HealthProvider>
17+
</LocaleProvider>
1618
</RawIntlProvider>
1719
);
1820
}

frontend/src/components/Dropdown/DropdownItem.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export const DropdownItem: React.FC<DropdownItemProps> = ({
4545
icon,
4646
href,
4747
onClick,
48+
...rest
4849
}) => {
4950
return divider ? (
5051
<div className={cn("dropdown-divider", className)} />
@@ -57,7 +58,8 @@ export const DropdownItem: React.FC<DropdownItemProps> = ({
5758
className,
5859
)}
5960
href={href}
60-
onClick={onClick}>
61+
onClick={onClick}
62+
{...rest}>
6163
{icon && <span className="dropdown-item-icon">{icon}</span>}
6264
{children}
6365
</a>

frontend/src/components/Flag/Flag.tsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import React from "react";
2+
3+
import cn from "classnames";
4+
5+
export interface FlagProps {
6+
/**
7+
* Additional Class
8+
*/
9+
className?: string;
10+
/**
11+
* Country code of flag
12+
*/
13+
country: string;
14+
/**
15+
* Size of the flag
16+
*/
17+
size?: string;
18+
}
19+
export const Flag: React.FC<FlagProps> = ({ className, country, size }) => {
20+
const classes = [
21+
`flag-country-${country.toLowerCase()}`,
22+
{
23+
[`flag-${size}`]: !!size,
24+
},
25+
];
26+
27+
return <span className={cn("flag", classes, className)} />;
28+
};

frontend/src/components/Flag/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./Flag";
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import React, { useState } from "react";
2+
3+
import { Button, Dropdown, Flag } from "components";
4+
import { useLocaleState } from "context";
5+
import { changeLocale, getFlagCodeForLocale, getLocale, intl } from "locale";
6+
7+
export interface LocalPickerProps {
8+
/**
9+
* On click handler
10+
*/
11+
onChange?: any;
12+
}
13+
14+
export const LocalePicker: React.FC<LocalPickerProps> = ({
15+
onChange,
16+
...rest
17+
}) => {
18+
const { locale, setLocale } = useLocaleState();
19+
20+
// const [locale, setLocale] = useState(getLocale());
21+
const [localeShown, setLocaleShown] = useState(false);
22+
23+
const handleOnChange = (e: any) => {
24+
changeLocale(e.currentTarget.rel);
25+
setLocale(e.currentTarget.rel);
26+
setLocaleShown(false);
27+
onChange && onChange(locale);
28+
};
29+
30+
const options = [
31+
["us", "en-US"],
32+
["de", "de-DE"],
33+
["ir", "fa-IR"],
34+
];
35+
36+
return (
37+
<div className="dropdown" {...rest}>
38+
<Button
39+
shape="ghost"
40+
onClick={(e: any) => {
41+
setLocaleShown(!localeShown);
42+
e.preventDefault();
43+
}}
44+
iconOnly>
45+
<Flag country={getFlagCodeForLocale(locale)} />
46+
</Button>
47+
<Dropdown
48+
className="dropdown-menu-end dropdown-menu-card"
49+
show={localeShown}>
50+
{options.map((item) => {
51+
return (
52+
<Dropdown.Item
53+
key={`locale-${item[0]}`}
54+
rel={item[1]}
55+
icon={<Flag country={item[0]} />}
56+
onClick={handleOnChange}>
57+
{intl.formatMessage({
58+
id: `locale-${item[1]}`,
59+
defaultMessage: item[1],
60+
})}
61+
</Dropdown.Item>
62+
);
63+
})}
64+
</Dropdown>
65+
</div>
66+
);
67+
};

frontend/src/components/SiteWrapper.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import React, { ReactNode } from "react";
22

33
import { Footer } from "components";
44
import { Avatar, Dropdown, Navigation } from "components";
5+
import { LocalePicker } from "components";
56
import { useAuthState, useUserState } from "context";
67
import { intl } from "locale";
7-
import { FormattedMessage } from "react-intl";
88
import styled from "styled-components";
99

1010
import { NavMenu } from "./NavMenu";
@@ -45,16 +45,20 @@ function SiteWrapper({ children }: Props) {
4545
defaultMessage: "Standard User",
4646
})
4747
}
48+
buttons={[<LocalePicker key="lp1" />]}
4849
profileItems={[
4950
<Dropdown.Item key="m1-2">
50-
<FormattedMessage
51-
id="profile.title"
52-
defaultMessage="Profile settings"
53-
/>
51+
{intl.formatMessage({
52+
id: "profile.title",
53+
defaultMessage: "Profile settings",
54+
})}
5455
</Dropdown.Item>,
5556
<Dropdown.Item divider key="m1-4" />,
5657
<Dropdown.Item key="m1-6" onClick={logout}>
57-
<FormattedMessage id="profile.logout" defaultMessage="Logout" />
58+
{intl.formatMessage({
59+
id: "profile.logout",
60+
defaultMessage: "Logout",
61+
})}
5862
</Dropdown.Item>,
5963
]}
6064
/>

frontend/src/components/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ export * from "./Badge";
55
export * from "./Button";
66
export * from "./ButtonList";
77
export * from "./Dropdown";
8+
export * from "./Flag";
89
export * from "./Footer";
910
export * from "./Loader";
1011
export * from "./Loading";
12+
export * from "./LocalePicker";
1113
export * from "./Navigation";
1214
export * from "./NavMenu";
1315
export * from "./Router";
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import React, { ReactNode, useState } from "react";
2+
3+
import { getLocale } from "locale";
4+
5+
// Context
6+
export interface LocaleContextType {
7+
setLocale: (locale: string) => void;
8+
locale?: string;
9+
}
10+
11+
const initalValue = null;
12+
const LocaleContext = React.createContext<LocaleContextType | null>(
13+
initalValue,
14+
);
15+
16+
// Provider
17+
interface Props {
18+
children?: ReactNode;
19+
}
20+
function LocaleProvider({ children }: Props) {
21+
const [locale, setLocaleValue] = useState(getLocale());
22+
23+
const setLocale = async (locale: string) => {
24+
setLocaleValue(locale);
25+
};
26+
27+
const value = { locale, setLocale };
28+
29+
return (
30+
<LocaleContext.Provider value={value}>{children}</LocaleContext.Provider>
31+
);
32+
}
33+
34+
function useLocaleState() {
35+
const context = React.useContext(LocaleContext);
36+
if (!context) {
37+
throw new Error(`useLocaleState must be used within a LocaleProvider`);
38+
}
39+
return context;
40+
}
41+
42+
export { LocaleProvider, useLocaleState };
43+
export default LocaleContext;

0 commit comments

Comments
 (0)