Layout extraction refactoring

This commit is contained in:
David
2021-03-18 14:18:29 +01:00
parent eafad585fc
commit a3ae493c25
5 changed files with 120 additions and 115 deletions

View File

@@ -1,9 +1,7 @@
import { FC } from "react"; import { FC } from "react";
import Head from "next/head"; import { Stack, HStack, Heading, Text, Icon, useColorModeValue } from "@chakra-ui/react";
import { Stack, VStack, HStack, Heading, Text, Icon, useColorModeValue } from "@chakra-ui/react";
import { FaSadTear } from "react-icons/fa"; import { FaSadTear } from "react-icons/fa";
import Header from "./Header"; import Layout from "./Layout";
import Footer from "./Footer";
const statusTexts: { const statusTexts: {
[key: string]: string [key: string]: string
@@ -20,38 +18,26 @@ type Props = {
}; };
const CustomError: FC<Props> = ({ statusCode }) => ( const CustomError: FC<Props> = ({ statusCode }) => (
<> <Layout customTitle={`${statusCode} - ${statusTexts?.[statusCode] ?? statusTexts.fallback}`}>
<Head> <Stack
<title> color={useColorModeValue("lingva.900", "lingva.100")}
{statusCode} - {statusTexts?.[statusCode] ?? statusTexts.fallback} direction={["column", null, "row"]}
</title> justify="center"
<link rel="icon" href="/favicon.svg" /> align="center"
</Head> spacing={4}
w="full"
<VStack h="100vh"> >
<Header/> <HStack align="center" spacing={5}>
<Stack <Heading as="h1" size="3xl">
as="main" {statusCode}
flexGrow={1} </Heading>
color={useColorModeValue("lingva.900", "lingva.100")} <Icon as={FaSadTear} boxSize={10} />
direction={["column", null, "row"]} </HStack>
justify="center" <Text as="h2" fontSize="xl">
align="center" {statusTexts?.[statusCode] ?? statusTexts.fallback}
spacing={4} </Text>
> </Stack>
<HStack align="center" spacing={5}> </Layout>
<Heading as="h1" size="3xl">
{statusCode}
</Heading>
<Icon as={FaSadTear} boxSize={10} />
</HStack>
<Text as="h2" fontSize="xl">
{statusTexts?.[statusCode] ?? statusTexts.fallback}
</Text>
</Stack>
<Footer/>
</VStack>
</>
); );
export default CustomError; export default CustomError;

View File

@@ -1,7 +1,6 @@
import { FC, ChangeEvent } from "react"; import { FC, ChangeEvent } from "react";
import { Select } from "@chakra-ui/react"; import { Select } from "@chakra-ui/react";
type Props = { type Props = {
value: string, value: string,
onChange: (e: ChangeEvent<any>) => void, onChange: (e: ChangeEvent<any>) => void,

52
components/Layout.tsx Normal file
View File

@@ -0,0 +1,52 @@
import { FC } from "react";
import { Flex, VStack, Button, Link } from "@chakra-ui/react";
import Head from "next/head";
import Header from "./Header";
import Footer from "./Footer";
type Props = {
customTitle?: string
[key: string]: any
};
const title = "Lingva Translate";
const Layout: FC<Props> = ({ customTitle, children }) => (
<>
<Head>
<title>
{customTitle ?? title}
</title>
<link rel="icon" href="/favicon.svg" />
</Head>
<Button
as={Link}
href="#main"
userSelect="none"
position="absolute"
top="-100px"
left="0"
_focus={{
top: "0"
}}
>
Skip to content
</Button>
<VStack minH="100vh" spacing={8}>
<Header />
<Flex
as="main"
id="main"
flexGrow={1}
w="full"
>
{children}
</Flex>
<Footer />
</VStack>
</>
);
export default Layout;

View File

@@ -1,5 +1,4 @@
export { default as CustomError } from "./CustomError"; export { default as CustomError } from "./CustomError";
export { default as Header } from "./Header"; export { default as Layout } from "./Layout";
export { default as Footer } from "./Footer";
export { default as LangSelect } from "./LangSelect"; export { default as LangSelect } from "./LangSelect";
export { default as TranslationArea } from "./TranslationArea"; export { default as TranslationArea } from "./TranslationArea";

View File

@@ -1,10 +1,9 @@
import { useState, useEffect, useReducer, FC, ChangeEvent } from "react"; import { useState, useEffect, useReducer, FC, ChangeEvent } from "react";
import { GetStaticPaths, GetStaticProps, InferGetStaticPropsType } from "next"; import { GetStaticPaths, GetStaticProps, InferGetStaticPropsType } from "next";
import Head from "next/head";
import Router from "next/router"; import Router from "next/router";
import { Stack, VStack, HStack, IconButton, Button, Link } from "@chakra-ui/react"; import { Stack, VStack, HStack, IconButton } from "@chakra-ui/react";
import { FaExchangeAlt } from "react-icons/fa"; import { FaExchangeAlt } from "react-icons/fa";
import { CustomError, Header, Footer, LangSelect, TranslationArea } from "../components"; import { CustomError, Layout, LangSelect, TranslationArea } from "../components";
import { useToastOnLoad } from "../hooks"; import { useToastOnLoad } from "../hooks";
import { googleScrape, extractSlug } from "../utils/translate"; import { googleScrape, extractSlug } from "../utils/translate";
import { retrieveFiltered } from "../utils/language"; import { retrieveFiltered } from "../utils/language";
@@ -55,80 +54,50 @@ const Page: FC<InferGetStaticPropsType<typeof getStaticProps>> = ({ translation,
return statusCode ? ( return statusCode ? (
<CustomError statusCode={statusCode} /> <CustomError statusCode={statusCode} />
) : ( ) : (
<> <Layout>
<Head> <VStack px={[8, null, 24, 40]} w="full">
<title> <HStack px={[1, null, 3, 4]} w="full">
Lingva Translate <LangSelect
</title> id="source"
<link rel="icon" href="/favicon.svg" /> aria-label="Source language"
</Head> value={source}
onChange={handleChange}
<Button langs={sourceLangs}
as={Link} />
href="#main" <IconButton
userSelect="none" aria-label="Switch languages"
position="absolute" icon={<FaExchangeAlt />}
top="-100px" colorScheme="lingva"
left="0" variant="ghost"
_focus={{ onClick={() => dispatch({ type: Actions.SWITCH_LANGS })}
top: "0" isDisabled={source === "auto"}
}} />
> <LangSelect
Skip to content id="target"
</Button> aria-label="Target language"
value={target}
<VStack minH="100vh" spacing={8}> onChange={handleChange}
<Header /> langs={targetLangs}
<VStack />
as="main" </HStack>
id="main" <Stack direction={["column", null, "row"]} w="full">
px={[8, null, 24, 40]} <TranslationArea
flexGrow={1} id="query"
w="full"> aria-label="Translation query"
<HStack px={[1, null, 3, 4]} w="full"> placeholder="Text"
<LangSelect value={query}
id="source" onChange={handleChange}
aria-label="Source language" />
value={source} <TranslationArea
onChange={handleChange} id="translation"
langs={sourceLangs} aria-label="Translation result"
/> placeholder="Translation"
<IconButton value={translation ?? ""}
aria-label="Switch languages" readOnly={true}
icon={<FaExchangeAlt />} />
colorScheme="lingva" </Stack>
variant="ghost"
onClick={() => dispatch({ type: Actions.SWITCH_LANGS })}
isDisabled={source === "auto"}
/>
<LangSelect
id="target"
aria-label="Target language"
value={target}
onChange={handleChange}
langs={targetLangs}
/>
</HStack>
<Stack direction={["column", null, "row"]} w="full">
<TranslationArea
id="query"
aria-label="Translation query"
placeholder="Text"
value={query}
onChange={handleChange}
/>
<TranslationArea
id="translation"
aria-label="Translation result"
placeholder="Translation"
value={translation ?? ""}
readOnly={true}
/>
</Stack>
</VStack>
<Footer />
</VStack> </VStack>
</> </Layout>
); );
} }