From f35a07efc182031ab3936911103bd97a6770716b Mon Sep 17 00:00:00 2001 From: Myzel394 <50424412+Myzel394@users.noreply.github.com> Date: Fri, 14 Oct 2022 16:41:14 +0200 Subject: [PATCH] development; fixes; added basic loading screen --- package.json | 1 + src/App.tsx | 10 ++++- src/LoadCriticalContent.tsx | 44 +++++++++++++++++++ src/ServerSettingsContext.ts | 12 +++++ src/apis/get-server-settings.ts | 5 +-- src/apis/signup.ts | 2 +- src/apis/validate-token.ts | 2 +- src/components/MultiStepForm.tsx | 41 +++++++++-------- src/constants/themes.ts | 11 +++++ src/hooks/index.ts | 2 + src/hooks/use-server-settings.ts | 10 +++++ .../root/EmailForm/EmailForm.tsx | 9 ++-- src/route-widgets/root/EmailForm/index.ts | 2 +- src/routes/Root.tsx | 22 ++++++---- 14 files changed, 134 insertions(+), 39 deletions(-) create mode 100644 src/LoadCriticalContent.tsx create mode 100644 src/ServerSettingsContext.ts create mode 100644 src/constants/themes.ts create mode 100644 src/hooks/index.ts create mode 100644 src/hooks/use-server-settings.ts diff --git a/package.json b/package.json index 0a65ce2..738ddaa 100755 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "axios": "^1.1.2", "crypto-js": "^4.1.1", "formik": "^2.2.9", + "in-seconds": "^1.2.0", "openpgp": "^5.5.0", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/src/App.tsx b/src/App.tsx index d5bf329..c2462a8 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,8 +2,11 @@ import {RouterProvider, createBrowserRouter} from "react-router-dom" import React, {ReactElement} from "react" import {QueryClientProvider} from "@tanstack/react-query" +import {CssBaseline, ThemeProvider} from "@mui/material" import {queryClient} from "~/constants/react-query" +import {lightTheme} from "~/constants/themes" +import LoadCriticalContent from "~/LoadCriticalContent" import RootRoute from "~/routes/Root" const router = createBrowserRouter([ @@ -17,7 +20,12 @@ export default function App(): ReactElement { return ( - + + + + + + ) diff --git a/src/LoadCriticalContent.tsx b/src/LoadCriticalContent.tsx new file mode 100644 index 0000000..212cde6 --- /dev/null +++ b/src/LoadCriticalContent.tsx @@ -0,0 +1,44 @@ +import * as inSeconds from "in-seconds" +import {AxiosError} from "axios" +import React, {ReactElement} from "react" + +import {useQuery} from "@tanstack/react-query" + +import {getServerSettings} from "~/apis" +import LoadingScreen from "~/LoadingScreen" + +import ServerSettingsContext, { + ServerSettingsContextType, +} from "./ServerSettingsContext" + +export interface LoadCriticalContentProps { + children: ReactElement +} + +export default function LoadCriticalContent({ + children, +}: LoadCriticalContentProps): ReactElement { + const {data} = useQuery( + ["server-settings"], + async () => { + const settings = await getServerSettings() + + return { + serverSettings: settings, + } + }, + { + staleTime: inSeconds.days(20), + }, + ) + + if (!data) { + return + } + + return ( + + {children} + + ) +} diff --git a/src/ServerSettingsContext.ts b/src/ServerSettingsContext.ts new file mode 100644 index 0000000..6520a04 --- /dev/null +++ b/src/ServerSettingsContext.ts @@ -0,0 +1,12 @@ +import {createContext} from "react" + +import {ServerSettings} from "~/types" + +export interface ServerSettingsContextType { + serverSettings: ServerSettings +} + +// @ts-ignore +const ServerSettingsContext = createContext() + +export default ServerSettingsContext diff --git a/src/apis/get-server-settings.ts b/src/apis/get-server-settings.ts index 616048a..81d8ef0 100644 --- a/src/apis/get-server-settings.ts +++ b/src/apis/get-server-settings.ts @@ -3,7 +3,6 @@ import axios from "axios" import {ServerSettings} from "~/types" export default async function getServerSettings(): Promise { - return ( - await axios.get(`${process.env.NEXT_PUBLIC_SERVER_BASE_URL}/settings`) - ).data + return (await axios.get(`${import.meta.env.VITE_SERVER_BASE_URL}/settings`)) + .data } diff --git a/src/apis/signup.ts b/src/apis/signup.ts index 7c8aecf..67065b1 100644 --- a/src/apis/signup.ts +++ b/src/apis/signup.ts @@ -6,7 +6,7 @@ export interface SignupResult { export default async function signup(email: string): Promise { const {data} = await axios.post( - `${process.env.NEXT_PUBLIC_SERVER_BASE_URL}/auth/signup`, + `${import.meta.env.VITE_SERVER_BASE_URL}/auth/signup`, { email, }, diff --git a/src/apis/validate-token.ts b/src/apis/validate-token.ts index 43ce6af..36e15e6 100644 --- a/src/apis/validate-token.ts +++ b/src/apis/validate-token.ts @@ -12,7 +12,7 @@ export default async function validateToken({ token, }: ValidateTokenData): Promise { const {data} = await axios.post( - `${process.env.NEXT_PUBLIC_SERVER_BASE_URL}/auth/verify-email`, + `${import.meta.env.VITE_SERVER_BASE_URL}/auth/verify-email`, { email: email, token: token, diff --git a/src/components/MultiStepForm.tsx b/src/components/MultiStepForm.tsx index ee1ae74..bf7f49d 100644 --- a/src/components/MultiStepForm.tsx +++ b/src/components/MultiStepForm.tsx @@ -1,27 +1,23 @@ -import React, { - ReactElement, - forwardRef, - useEffect, - useRef, - useState, -} from "react" +import React, {ReactElement, useEffect, useRef, useState} from "react" import {Paper} from "@mui/material" import {whenElementHasBounds} from "~/utils" export interface MultiStepFormProps { - steps: (() => ReactElement)[] + steps: ReactElement[] index: number duration?: number easing?: string } -function MultiStepForm( - {steps, index, duration = 900, easing = "ease-in-out"}: MultiStepFormProps, - ref: any, -): ReactElement { +function MultiStepForm({ + steps, + index, + duration = 900, + easing = "ease-in-out", +}: MultiStepFormProps): ReactElement { const $currentElement = useRef(null) const $timeout = useRef() @@ -44,6 +40,11 @@ function MultiStepForm( return $timeout.current?.cancel! }, [index, currentIndex]) + const hasSize = Boolean( + (currentSize?.width || nextSize?.width) && + (currentSize?.height || nextSize?.height), + ) + return (
- {steps[currentIndex]()} + {steps[currentIndex]}
{currentIndex === steps.length - 1 ? null - : steps[currentIndex + 1]()} + : steps[currentIndex + 1]}
) } -export default forwardRef(MultiStepForm) +export default MultiStepForm diff --git a/src/constants/themes.ts b/src/constants/themes.ts new file mode 100644 index 0000000..2438f6c --- /dev/null +++ b/src/constants/themes.ts @@ -0,0 +1,11 @@ +import {createTheme} from "@mui/material" + +export const lightTheme = createTheme({ + palette: { + mode: "dark", + secondary: { + main: "#ACF", + contrastText: "#FFF", + }, + }, +}) diff --git a/src/hooks/index.ts b/src/hooks/index.ts new file mode 100644 index 0000000..91eaee6 --- /dev/null +++ b/src/hooks/index.ts @@ -0,0 +1,2 @@ +export * from "./use-server-settings" +export {default as useServerSettings} from "./use-server-settings" diff --git a/src/hooks/use-server-settings.ts b/src/hooks/use-server-settings.ts new file mode 100644 index 0000000..3e2b7d0 --- /dev/null +++ b/src/hooks/use-server-settings.ts @@ -0,0 +1,10 @@ +import {useContext} from "react" + +import {ServerSettings} from "~/types" +import ServerSettingsContext from "~/ServerSettingsContext" + +export default function useServerSettings(): ServerSettings { + const {serverSettings} = useContext(ServerSettingsContext) + + return serverSettings +} diff --git a/src/route-widgets/root/EmailForm/EmailForm.tsx b/src/route-widgets/root/EmailForm/EmailForm.tsx index 4d715c2..a434753 100644 --- a/src/route-widgets/root/EmailForm/EmailForm.tsx +++ b/src/route-widgets/root/EmailForm/EmailForm.tsx @@ -5,22 +5,19 @@ import React, {ReactElement} from "react" import {InputAdornment, TextField} from "@mui/material" import {MultiStepFormElement, SimpleForm} from "~/components" -import {ServerSettings} from "~/types" import {signup} from "~/apis" import {handleErrors} from "~/utils" +import {useServerSettings} from "~/hooks" import DetectEmailAutofillService from "./DetectEmailAutofillService" import useSchema, {Form} from "./use-schema" interface EmailFormProps { - serverSettings: ServerSettings onSignUp: (email: string) => void } -export default function EmailForm({ - serverSettings, - onSignUp, -}: EmailFormProps): ReactElement { +export default function EmailForm({onSignUp}: EmailFormProps): ReactElement { + const serverSettings = useServerSettings() const schema = useSchema(serverSettings) const formik = useFormik
({ validationSchema: schema, diff --git a/src/route-widgets/root/EmailForm/index.ts b/src/route-widgets/root/EmailForm/index.ts index 43a7109..c21ee9e 100644 --- a/src/route-widgets/root/EmailForm/index.ts +++ b/src/route-widgets/root/EmailForm/index.ts @@ -1 +1 @@ -export {default as EmailForm} from "./EmailForm" +export {default} from "./EmailForm" diff --git a/src/routes/Root.tsx b/src/routes/Root.tsx index 8884a95..8e0bf4f 100644 --- a/src/routes/Root.tsx +++ b/src/routes/Root.tsx @@ -1,23 +1,29 @@ +import {useLocalStorage} from "react-use" import React, {ReactElement} from "react" import {MultiStepForm, SingleElementWrapper} from "~/components" -import EmailForm from "~/route-widgets/root/EmailForm/EmailForm" -import LoadingScreen from "~/LoadingScreen" +import EmailForm from "~/route-widgets/root/EmailForm" import YouGotMail from "~/route-widgets/root/YouGotMail" export default function RootRoute(): ReactElement { - return + const [email, setEmail] = useLocalStorage( + "signup-form-state-email", + "", + ) + + const index = email ? 1 : 0 return ( ( - null} /> - ), - () => , + , + , ]} - index={0} + index={index} /> )