import { useState, useEffect, useReducer, FC, ChangeEvent } from "react"; import { GetStaticPaths, GetStaticProps, InferGetStaticPropsType } from "next"; import Router from "next/router"; import { Stack, VStack, HStack, IconButton } from "@chakra-ui/react"; import { FaExchangeAlt } from "react-icons/fa"; import { CustomError, Layout, LangSelect, TranslationArea } from "../components"; import { useToastOnLoad } from "../hooks"; import { googleScrape, extractSlug } from "../utils/translate"; import { retrieveFiltered } from "../utils/language"; import langReducer, { Actions, initialState } from "../utils/reducer"; const Page: FC> = ({ translation, statusCode, errorMsg, initial }) => { const [{ source, target, query }, dispatch] = useReducer(langReducer, initialState); const [delayedQuery, setDelayedQuery] = useState(initialState.query); const handleChange = (e: ChangeEvent) => { dispatch({ type: Actions.SET_FIELD, payload: { key: e.target.id, value: e.target.value } }); }; useEffect(() => { initial && dispatch({ type: Actions.SET_ALL, payload: { state: initial }}); }, [initial]); useEffect(() => { const timeout = setTimeout(() => setDelayedQuery(query), 1000); return () => clearTimeout(timeout); }, [query]); useEffect(() => { const queryIsEmpty = !delayedQuery || delayedQuery === initialState.query; const queryIsInitial = delayedQuery === initial?.query; const sourceIsInitial = source === initialState.source || source === initial?.source; const targetIsInitial = target === initialState.target || target === initial?.target; const allAreInitials = queryIsInitial && sourceIsInitial && targetIsInitial; queryIsEmpty || allAreInitials || Router.push(`/${source}/${target}/${encodeURIComponent(delayedQuery)}`); }, [source, target, delayedQuery, initial]); const { sourceLangs, targetLangs } = retrieveFiltered(source, target); useToastOnLoad({ title: "Unexpected error", description: errorMsg, status: "error", updateDeps: initial }); return statusCode ? ( ) : ( } colorScheme="lingva" variant="ghost" onClick={() => dispatch({ type: Actions.SWITCH_LANGS })} isDisabled={source === "auto"} /> ); } export default Page; export const getStaticPaths: GetStaticPaths = async () => ({ paths: [ { params: { slug: [] } } ], fallback: true }); export const getStaticProps: GetStaticProps = async ({ params }) => { if (!params?.slug || !Array.isArray(params.slug)) return { props: {} }; const { source, target, query } = extractSlug(params.slug); if (!query) return { notFound: true }; if (!source || !target) return { redirect: { destination: `/${source ?? "auto"}/${target ?? "en"}/${query}`, permanent: true } } const scrapeRes = await googleScrape(source, target, query); return { props: { ...scrapeRes, initial: { source, target, query } }, revalidate: !scrapeRes.errorMsg && !scrapeRes.statusCode ? 2 * 30 * 24 * 60 * 60 // 2 months : 1 }; }