Theme toggle, updated flag icons, custom font and some login page tweaks

This commit is contained in:
Chaptergy
2021-11-08 23:10:00 +01:00
parent fc831e7298
commit f416ff9afe
29 changed files with 203 additions and 2189 deletions

View File

@@ -20,6 +20,7 @@
"@typescript-eslint/parser": "^4.28.1", "@typescript-eslint/parser": "^4.28.1",
"babel-eslint": "^10.1.0", "babel-eslint": "^10.1.0",
"classnames": "^2.3.1", "classnames": "^2.3.1",
"country-flag-icons": "^1.4.11",
"date-fns": "2.22.1", "date-fns": "2.22.1",
"eslint": "^7.30.0", "eslint": "^7.30.0",
"eslint-config-prettier": "^8.3.0", "eslint-config-prettier": "^8.3.0",
@@ -46,6 +47,7 @@
"react": "^17.0.2", "react": "^17.0.2",
"react-async": "10.0.1", "react-async": "10.0.1",
"react-dom": "17.0.2", "react-dom": "17.0.2",
"react-icons": "^4.3.1",
"react-intl": "^5.20.6", "react-intl": "^5.20.6",
"react-router-dom": "^5.2.0", "react-router-dom": "^5.2.0",
"react-scripts": "4.0.3", "react-scripts": "4.0.3",
@@ -97,6 +99,7 @@
} }
}, },
"devDependencies": { "devDependencies": {
"@formatjs/cli": "^4.2.29" "@formatjs/cli": "^4.2.29",
"@types/country-flag-icons": "^1.2.0"
} }
} }

View File

@@ -47,10 +47,6 @@
content="/images/favicon/browserconfig.xml" content="/images/favicon/browserconfig.xml"
/> />
<meta name="theme-color" content="#ffffff" /> <meta name="theme-color" content="#ffffff" />
<link
rel="stylesheet"
href="https://unpkg.com/@tabler/core@1.0.0-beta3/dist/css/tabler-flags.min.css"
/>
</head> </head>
<body> <body>
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>You need to enable JavaScript to run this app.</noscript>

View File

@@ -6,11 +6,13 @@ import { AuthProvider, HealthProvider, LocaleProvider } from "context";
import { intl } from "locale"; import { intl } from "locale";
import { RawIntlProvider } from "react-intl"; import { RawIntlProvider } from "react-intl";
import lightTheme from "./theme/customTheme";
function App() { function App() {
return ( return (
<RawIntlProvider value={intl}> <RawIntlProvider value={intl}>
<LocaleProvider> <LocaleProvider>
<ChakraProvider> <ChakraProvider theme={lightTheme}>
<HealthProvider> <HealthProvider>
<AuthProvider> <AuthProvider>
<Router /> <Router />

View File

@@ -1,6 +1,9 @@
import React from "react"; import React from "react";
import cn from "classnames"; import { Box } from "@chakra-ui/layout";
import { hasFlag } from "country-flag-icons";
// @ts-ignore Creating a typing for a subfolder is not easily possible
import Flags from "country-flag-icons/react/3x2";
export interface FlagProps { export interface FlagProps {
/** /**
@@ -8,21 +11,21 @@ export interface FlagProps {
*/ */
className?: string; className?: string;
/** /**
* Country code of flag * Two letter country code of flag
*/ */
country: string; countryCode: string;
/**
* Size of the flag
*/
size?: string;
} }
export const Flag: React.FC<FlagProps> = ({ className, country, size }) => { export const Flag: React.FC<FlagProps> = ({ className, countryCode }) => {
const classes = [ countryCode = countryCode.toUpperCase();
`flag-country-${country.toLowerCase()}`,
{
[`flag-${size}`]: !!size,
},
];
return <span className={cn("flag", classes, className)} />; if (hasFlag(countryCode)) {
const FlagElement = Flags[countryCode];
return (
<Box as={FlagElement} title={countryCode} className={className} w={6} />
);
} else {
console.error(`No flag for country ${countryCode} found!`);
return <Box w={6} h={4} />;
}
}; };

View File

@@ -45,13 +45,13 @@ export const LocalePicker: React.FC<LocalPickerProps> = ({
<Box className={className}> <Box className={className}>
<Menu> <Menu>
<MenuButton as={Button}> <MenuButton as={Button}>
<Flag country={getFlagCodeForLocale(locale)} /> <Flag countryCode={getFlagCodeForLocale(locale)} />
</MenuButton> </MenuButton>
<MenuList> <MenuList>
{options.map((item) => { {options.map((item) => {
return ( return (
<MenuItem <MenuItem
icon={<Flag country={item[0]} />} icon={<Flag countryCode={getFlagCodeForLocale(item[0])} />}
onClick={() => changeTo(item[0])} onClick={() => changeTo(item[0])}
rel={item[1]} rel={item[1]}
key={`locale-${item[0]}`}> key={`locale-${item[0]}`}>

View File

@@ -0,0 +1,13 @@
import React from "react";
import { Button, Icon, useColorMode } from "@chakra-ui/react";
import { FiSun, FiMoon } from "react-icons/fi";
export const ThemeSwitcher: React.FC = () => {
const { colorMode, toggleColorMode } = useColorMode();
return (
<Button onClick={toggleColorMode}>
{colorMode === "light" ? <Icon as={FiMoon} /> : <Icon as={FiSun} />}
</Button>
);
};

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 163 KiB

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 342 KiB

View File

@@ -1,3 +1,5 @@
@import "styles/fonts.scss";
html, html,
body, body,
#root { #root {

View File

@@ -1,10 +1,11 @@
import * as React from "react"; import * as React from "react";
import { ColorModeScript } from "@chakra-ui/react";
import * as ReactDOM from "react-dom"; import * as ReactDOM from "react-dom";
import App from "./App"; import App from "./App";
import "./index.scss"; import "./index.scss";
import customTheme from "./theme/customTheme";
declare global { declare global {
interface Function { interface Function {
@@ -18,4 +19,10 @@ declare global {
} }
} }
ReactDOM.render(<App />, document.getElementById("root")); ReactDOM.render(
<>
<ColorModeScript initialColorMode={customTheme.config.initialColorMode} />
<App />
</>,
document.getElementById("root"),
);

View File

@@ -21,12 +21,12 @@ export const getFlagCodeForLocale = (locale?: string) => {
switch (locale) { switch (locale) {
case "de-DE": case "de-DE":
case "de": case "de":
return "de"; return "DE";
case "fa-IR": case "fa-IR":
case "fa": case "fa":
return "ir"; return "IR";
default: default:
return "us"; return "US";
} }
}; };

View File

@@ -10,11 +10,13 @@ import {
Button, Button,
useColorModeValue, useColorModeValue,
useToast, useToast,
Link,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { LocalePicker } from "components"; import { LocalePicker } from "components";
import { useAuthState } from "context"; import { useAuthState } from "context";
import { intl } from "locale"; import { intl } from "locale";
import { ThemeSwitcher } from "../../components/ThemeSwitcher";
import logo from "../../img/logo-256.png"; import logo from "../../img/logo-256.png";
function Login() { function Login() {
@@ -58,23 +60,28 @@ function Login() {
return ( return (
<Flex <Flex
minH={"100vh"} minH={"100vh"}
align={"center"} w={"100vw"}
justify={"center"} flexDir={"column"}
bg={useColorModeValue("gray.50", "gray.800")}> bg={useColorModeValue("gray.50", "gray.800")}>
<Stack spacing={8} mx={"auto"} maxW={"lg"} py={12} px={6}> <Stack h={10} m={4} justify={"end"} direction={"row"}>
<Stack align={"center"}> <ThemeSwitcher />
<img src={logo} width={100} alt="Logo" /> <LocalePicker className="text-right" />
</Stack> </Stack>
<Flex align={"center"} justify={"center"} flex={"1"}>
<Stack spacing={8} mx={"auto"} maxW={"md"} w={"full"} py={4} px={6}>
<Box align={"center"}>
<img src={logo} width={100} alt="Logo" />
</Box>
<Box <Box
rounded={"lg"} rounded={"lg"}
bg={useColorModeValue("white", "gray.700")} bg={useColorModeValue("white", "gray.700")}
boxShadow={"lg"} boxShadow={"lg"}
p={8}> p={8}>
<LocalePicker className="text-right" />
<Stack spacing={4}>
<form onSubmit={onSubmit}> <form onSubmit={onSubmit}>
<Stack spacing={4}>
<FormControl id="email"> <FormControl id="email">
<FormLabel> <FormLabel fontWeight={"bold"}>
{intl.formatMessage({ {intl.formatMessage({
id: "user.email", id: "user.email",
defaultMessage: "Email", defaultMessage: "Email",
@@ -96,7 +103,7 @@ function Login() {
/> />
</FormControl> </FormControl>
<FormControl id="password"> <FormControl id="password">
<FormLabel> <FormLabel fontWeight={"bold"}>
{intl.formatMessage({ {intl.formatMessage({
id: "user.password", id: "user.password",
defaultMessage: "Password", defaultMessage: "Password",
@@ -118,11 +125,9 @@ function Login() {
/> />
</FormControl> </FormControl>
<Stack spacing={10}> <Stack spacing={10}>
<Stack <Box textAlign={"end"}>
direction={{ base: "column", sm: "row" }} <Link color={"blue.400"}>Forgot password?</Link>
align={"start"} </Box>
justify={"space-between"}
/>
<Button <Button
type="submit" type="submit"
loading={loading} loading={loading}
@@ -137,11 +142,13 @@ function Login() {
})} })}
</Button> </Button>
</Stack> </Stack>
</form>
</Stack> </Stack>
</form>
</Box> </Box>
</Stack> </Stack>
</Flex> </Flex>
<Box h={10} m={4} />
</Flex>
); );
} }

View File

@@ -0,0 +1,47 @@
/* source-sans-pro-regular - latin */
@font-face {
font-family: "Source Sans Pro";
font-style: normal;
font-weight: 400;
src: local(""),
url("../fonts/source-sans-pro/source-sans-pro-v14-latin-regular.woff2")
format("woff2"),
url("../fonts/source-sans-pro/source-sans-pro-v14-latin-regular.woff")
format("woff");
}
/* source-sans-pro-italic - latin */
@font-face {
font-family: "Source Sans Pro";
font-style: italic;
font-weight: 400;
src: local(""),
url("../fonts/source-sans-pro/source-sans-pro-v14-latin-italic.woff2")
format("woff2"),
url("../fonts/source-sans-pro/source-sans-pro-v14-latin-italic.woff")
format("woff");
}
/* source-sans-pro-700 - latin */
@font-face {
font-family: "Source Sans Pro";
font-style: normal;
font-weight: 700;
src: local(""),
url("../fonts/source-sans-pro/source-sans-pro-v14-latin-700.woff2")
format("woff2"),
url("../fonts/source-sans-pro/source-sans-pro-v14-latin-700.woff")
format("woff");
}
/* source-sans-pro-700italic - latin */
@font-face {
font-family: "Source Sans Pro";
font-style: italic;
font-weight: 700;
src: local(""),
url("../fonts/source-sans-pro/source-sans-pro-v14-latin-700italic.woff2")
format("woff2"),
url("../fonts/source-sans-pro/source-sans-pro-v14-latin-700italic.woff")
format("woff");
}

View File

@@ -0,0 +1,16 @@
import { theme as chakraTheme, ThemeConfig } from "@chakra-ui/react";
import { extendTheme } from "@chakra-ui/react";
// declare a variable for fonts and set our fonts
const fonts = {
...chakraTheme.fonts,
body: `"Source Sans Pro",-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"`,
heading: `"Source Sans Pro",-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"`,
};
const config: ThemeConfig = {
initialColorMode: "system",
};
const lightTheme = extendTheme({ fonts, config });
export default lightTheme;