diff --git a/.eslintrc.json b/.eslintrc.json index e9186ac..a7e87b3 100755 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -17,8 +17,46 @@ "ecmaVersion": 13, "sourceType": "module" }, - "plugins": ["react", "@typescript-eslint"], + "plugins": ["ordered-imports", "react", "@typescript-eslint"], "rules": { - "react/react-in-jsx-scope": "off" + "react/react-in-jsx-scope": "off", + "ordered-imports/ordered-imports": [ + "error", + { + "symbols-first": true, + "declaration-ordering": ["type", { + "ordering": ["namespace", "destructured", "default", "side-effect"], + "secondaryOrdering": ["name", "lowercase-last"] + }], + "specifier-ordering": "lowercase-last", + "group-ordering": [ + { + "name": "third-party named", + "match": "^@", + "order": 20 + }, + { + "name": "project", + "match": "^\\~", + "order": 30 + }, + { + "name": "parent directories", + "match": "^\\.\\.", + "order": 40 + }, + { + "name": "current directory", + "match": "^\\.", + "order": 50 + }, + { + "name": "third-party", + "match": ".*", + "order": 10 + } + ] + } + ] } } diff --git a/package.json b/package.json index d90c692..0a65ce2 100755 --- a/package.json +++ b/package.json @@ -9,6 +9,8 @@ "preview": "vite preview" }, "dependencies": { + "@emotion/react": "^11.10.4", + "@emotion/styled": "^11.10.4", "@mui/lab": "^5.0.0-alpha.103", "@mui/material": "^5.10.9", "@tanstack/react-query": "^4.12.0", @@ -39,6 +41,7 @@ "eslint": "8.22.0", "eslint-config-prettier": "^8.5.0", "eslint-plugin-compat": "^4.0.2", + "eslint-plugin-ordered-imports": "^0.6.0", "eslint-plugin-react": "^7.31.10", "prettier": "^2.7.1", "typescript": "^4.6.4", diff --git a/src/App.tsx b/src/App.tsx index 9db4840..d5bf329 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,24 +1,24 @@ -import {createBrowserRouter, RouterProvider} from "react-router-dom"; -import RootRoute from "~/routes/Root"; -import React, {ReactElement} from "react"; -import {QueryClientProvider} from "@tanstack/react-query"; -import {queryClient} from "~/constants/react-query"; +import {RouterProvider, createBrowserRouter} from "react-router-dom" +import React, {ReactElement} from "react" + +import {QueryClientProvider} from "@tanstack/react-query" + +import {queryClient} from "~/constants/react-query" +import RootRoute from "~/routes/Root" const router = createBrowserRouter([ - { - path: "/", - element: , - }, -]); - + { + path: "/", + element: , + }, +]) export default function App(): ReactElement { - return ( - - - - - - ) + return ( + + + + + + ) } - diff --git a/src/LoadingScreen.tsx b/src/LoadingScreen.tsx index f283692..389c5fb 100644 --- a/src/LoadingScreen.tsx +++ b/src/LoadingScreen.tsx @@ -1,11 +1,15 @@ -import {Typography} from "@mui/material"; -import {ReactElement} from "react"; -import {SingleElementWrapper} from "~/components"; +import React, {ReactElement} from "react" + +import {Typography} from "@mui/material" + +import {SingleElementWrapper} from "~/components" export default function LoadingScreen(): ReactElement { - return ( - - Loading... - - ) + return ( + + + Loading... + + + ) } diff --git a/src/apis/get-server-settings.ts b/src/apis/get-server-settings.ts index cdacf05..616048a 100644 --- a/src/apis/get-server-settings.ts +++ b/src/apis/get-server-settings.ts @@ -1,5 +1,6 @@ import axios from "axios" -import {ServerSettings} from "~/types"; + +import {ServerSettings} from "~/types" export default async function getServerSettings(): Promise { return ( diff --git a/src/apis/validate-token.ts b/src/apis/validate-token.ts index d7a1e88..43ce6af 100644 --- a/src/apis/validate-token.ts +++ b/src/apis/validate-token.ts @@ -1,6 +1,7 @@ -import {AuthenticationDetails} from "~/types" import axios from "axios" +import {AuthenticationDetails} from "~/types" + export interface ValidateTokenData { email: string token: string diff --git a/src/components/MultiStepForm.tsx b/src/components/MultiStepForm.tsx index 17dfdd3..ee1ae74 100644 --- a/src/components/MultiStepForm.tsx +++ b/src/components/MultiStepForm.tsx @@ -1,5 +1,13 @@ -import React, {forwardRef, ReactElement, useEffect, useRef, useState} from "react" +import React, { + ReactElement, + forwardRef, + useEffect, + useRef, + useState, +} from "react" + import {Paper} from "@mui/material" + import {whenElementHasBounds} from "~/utils" export interface MultiStepFormProps { diff --git a/src/components/MultiStepFormElement.tsx b/src/components/MultiStepFormElement.tsx index 9f90603..3609722 100644 --- a/src/components/MultiStepFormElement.tsx +++ b/src/components/MultiStepFormElement.tsx @@ -1,6 +1,7 @@ -import {Box, Container} from "@mui/material" import React, {ReactElement} from "react" +import {Box, Container} from "@mui/material" + export interface MultiStepFormElementProps { children: ReactElement } diff --git a/src/components/OpenMailButton.tsx b/src/components/OpenMailButton.tsx index 2f0edb2..41b24e2 100644 --- a/src/components/OpenMailButton.tsx +++ b/src/components/OpenMailButton.tsx @@ -1,8 +1,10 @@ -import {ReactElement} from "react" -import UAParser from "ua-parser-js" -import {Button} from "@mui/material" -import {APP_LINK_MAP} from "~/utils" import {IoMdMailOpen} from "react-icons/io" +import React, {ReactElement} from "react" +import UAParser from "ua-parser-js" + +import {Button} from "@mui/material" + +import {APP_LINK_MAP} from "~/utils" export interface OpenMailButtonProps { domain: string diff --git a/src/components/PasswordField.tsx b/src/components/PasswordField.tsx index a2c1fc4..d5c99c9 100644 --- a/src/components/PasswordField.tsx +++ b/src/components/PasswordField.tsx @@ -1,11 +1,12 @@ +import {MdVisibility, MdVisibilityOff} from "react-icons/md" +import React, {ReactElement, useState} from "react" + import { IconButton, InputAdornment, TextField, TextFieldProps, } from "@mui/material" -import {ReactElement, useState} from "react" -import {MdVisibility, MdVisibilityOff} from "react-icons/md" export interface PasswordFieldProps extends Omit {} diff --git a/src/components/SimpleForm.tsx b/src/components/SimpleForm.tsx index 9d1e515..137deb3 100644 --- a/src/components/SimpleForm.tsx +++ b/src/components/SimpleForm.tsx @@ -1,3 +1,7 @@ +import {MdChevronRight} from "react-icons/md" +import {TiCancel} from "react-icons/ti" +import React, {ReactElement, useEffect, useState} from "react" + import { Alert, Button, @@ -6,11 +10,8 @@ import { Typography, TypographyProps, } from "@mui/material" -import {ReactElement, useEffect, useState} from "react" import {LoadingButton} from "@mui/lab" -import {MdChevronRight} from "react-icons/md" import {OverrideProps} from "@mui/types" -import {TiCancel} from "react-icons/ti" export interface SimpleFormProps { title: string diff --git a/src/components/SingleElementWrapper.tsx b/src/components/SingleElementWrapper.tsx index 9556e2f..4488dd2 100644 --- a/src/components/SingleElementWrapper.tsx +++ b/src/components/SingleElementWrapper.tsx @@ -1,4 +1,5 @@ -import {ReactElement} from "react" +import React, {ReactElement} from "react" + import {Box} from "@mui/material" export interface SingleElementWrapperProps { diff --git a/src/constants/development.ts b/src/constants/development.ts new file mode 100644 index 0000000..b5f7344 --- /dev/null +++ b/src/constants/development.ts @@ -0,0 +1 @@ +export const isDev = true diff --git a/src/constants/react-query.ts b/src/constants/react-query.ts index eb58589..4a480d6 100644 --- a/src/constants/react-query.ts +++ b/src/constants/react-query.ts @@ -1 +1,3 @@ +import {QueryClient} from "@tanstack/react-query" + export const queryClient = new QueryClient() diff --git a/src/main.tsx b/src/main.tsx index e57dd4b..3707268 100755 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,17 +1,8 @@ -import React from "react"; -import ReactDOM from "react-dom/client"; -import {createBrowserRouter, RouterProvider,} from "react-router-dom"; -import RootRoute from "~/routes/Root"; +import React from "react" +import ReactDOM from "react-dom/client" -const router = createBrowserRouter([ - { - path: "/", - element: , - }, -]); +import App from "~/App" ReactDOM.createRoot(document.getElementById("root") as HTMLDivElement).render( - - - -); + , +) diff --git a/src/route-widgets/root/EmailForm/DetectEmailAutofillService.tsx b/src/route-widgets/root/EmailForm/DetectEmailAutofillService.tsx index 57f76ef..402bc04 100644 --- a/src/route-widgets/root/EmailForm/DetectEmailAutofillService.tsx +++ b/src/route-widgets/root/EmailForm/DetectEmailAutofillService.tsx @@ -1,7 +1,23 @@ -import {ReactElement, useCallback, useEffect, useRef, useState} from "react" -import {Alert, Button, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, Grid,} from "@mui/material" import {MdCheck} from "react-icons/md" import {useSessionStorage} from "react-use" +import React, { + ReactElement, + useCallback, + useEffect, + useRef, + useState, +} from "react" + +import { + Alert, + Button, + Dialog, + DialogActions, + DialogContent, + DialogContentText, + DialogTitle, + Grid, +} from "@mui/material" export interface DetectEmailAutofillServiceProps { domains: string[] diff --git a/src/route-widgets/root/EmailForm/index.tsx b/src/route-widgets/root/EmailForm/EmailForm.tsx similarity index 96% rename from src/route-widgets/root/EmailForm/index.tsx rename to src/route-widgets/root/EmailForm/EmailForm.tsx index e64840d..4d715c2 100644 --- a/src/route-widgets/root/EmailForm/index.tsx +++ b/src/route-widgets/root/EmailForm/EmailForm.tsx @@ -1,13 +1,16 @@ -import {ReactElement} from "react" import {useFormik} from "formik" -import useSchema, {Form} from "./use-schema" -import {signup} from "~/apis" import {MdEmail} from "react-icons/md" +import React, {ReactElement} from "react" + import {InputAdornment, TextField} from "@mui/material" -import DetectEmailAutofillService from "./DetectEmailAutofillService" -import {handleErrors} from "~/utils" + import {MultiStepFormElement, SimpleForm} from "~/components" -import {ServerSettings} from "~/types"; +import {ServerSettings} from "~/types" +import {signup} from "~/apis" +import {handleErrors} from "~/utils" + +import DetectEmailAutofillService from "./DetectEmailAutofillService" +import useSchema, {Form} from "./use-schema" interface EmailFormProps { serverSettings: ServerSettings diff --git a/src/route-widgets/root/EmailForm/index.ts b/src/route-widgets/root/EmailForm/index.ts new file mode 100644 index 0000000..43a7109 --- /dev/null +++ b/src/route-widgets/root/EmailForm/index.ts @@ -0,0 +1 @@ +export {default as EmailForm} from "./EmailForm" diff --git a/src/route-widgets/root/EmailForm/use-schema.ts b/src/route-widgets/root/EmailForm/use-schema.ts index 153d2fb..09e22dc 100644 --- a/src/route-widgets/root/EmailForm/use-schema.ts +++ b/src/route-widgets/root/EmailForm/use-schema.ts @@ -1,6 +1,7 @@ import * as yup from "yup" + import {checkIsDomainDisposable} from "~/apis" -import {ServerSettings} from "~/types"; +import {ServerSettings} from "~/types" export interface Form { email: string diff --git a/src/route-widgets/root/GenerateEmailReportsForm.tsx b/src/route-widgets/root/GenerateEmailReportsForm.tsx index 3a55947..c1bb1db 100644 --- a/src/route-widgets/root/GenerateEmailReportsForm.tsx +++ b/src/route-widgets/root/GenerateEmailReportsForm.tsx @@ -1,7 +1,8 @@ -import {ReactElement} from "react" -import {Box, Button, Grid, Typography} from "@mui/material" import {FaLongArrowAltRight} from "react-icons/fa" import {TiCancel} from "react-icons/ti" +import React, {ReactElement} from "react" + +import {Box, Button, Grid, Typography} from "@mui/material" export interface GenerateEmailReportsFormProps { onYes: () => void diff --git a/src/route-widgets/root/PasswordForm.tsx b/src/route-widgets/root/PasswordForm.tsx index 223afeb..1b914a5 100644 --- a/src/route-widgets/root/PasswordForm.tsx +++ b/src/route-widgets/root/PasswordForm.tsx @@ -1,12 +1,15 @@ -import {ReactElement, useMemo} from "react" import * as yup from "yup" import {useFormik} from "formik" -import {Box, Grid, InputAdornment, Typography} from "@mui/material" import {MdCheckCircle, MdChevronRight, MdLock} from "react-icons/md" -import {LoadingButton} from "@mui/lab" -import {PasswordField} from "components" -import {encryptString, handleErrors} from "~/utils" import {generateKey} from "openpgp" +import React, {ReactElement, useMemo} from "react" + +import {LoadingButton} from "@mui/lab" +import {Box, Grid, InputAdornment, Typography} from "@mui/material" + +import {PasswordField} from "~/components" +import {encryptString, handleErrors} from "~/utils" +import {isDev} from "~/constants/development" export interface PasswordFormProps { email: string diff --git a/src/route-widgets/root/YouGotMail.tsx b/src/route-widgets/root/YouGotMail.tsx index bd0d405..78d6e1d 100644 --- a/src/route-widgets/root/YouGotMail.tsx +++ b/src/route-widgets/root/YouGotMail.tsx @@ -1,5 +1,7 @@ -import {ReactElement} from "react" +import React, {ReactElement} from "react" + import {Grid, Typography} from "@mui/material" + import {MultiStepFormElement, OpenMailButton} from "~/components" export interface YouGotMailProps { diff --git a/src/routes/Root.tsx b/src/routes/Root.tsx index 84a1299..8884a95 100644 --- a/src/routes/Root.tsx +++ b/src/routes/Root.tsx @@ -1,29 +1,24 @@ -import {ReactElement} from "react"; -import SingleElementWrapper from "~/components/SingleElementWrapper"; -import MultiStepForm from "~/components/MultiStepForm"; -import EmailForm from "~/route-widgets/root/EmailForm"; -import YouGotMail from "~/route-widgets/root/YouGotMail"; -import LoadingScreen from "~/LoadingScreen"; +import React, {ReactElement} from "react" + +import {MultiStepForm, SingleElementWrapper} from "~/components" +import EmailForm from "~/route-widgets/root/EmailForm/EmailForm" +import LoadingScreen from "~/LoadingScreen" +import YouGotMail from "~/route-widgets/root/YouGotMail" export default function RootRoute(): ReactElement { - return ( - - ) + return - return ( - - ( - null} - /> - ), - () => , - ]} - index={0} - /> - - ); + return ( + + ( + null} /> + ), + () => , + ]} + index={0} + /> + + ) } diff --git a/vite.config.ts b/vite.config.ts index 0473645..2cb3c48 100755 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,13 +1,14 @@ -import { defineConfig } from 'vite' -import react from '@vitejs/plugin-react' -import * as path from "path"; +import * as path from "path" +import {defineConfig} from "vite" + +import react from "@vitejs/plugin-react" // https://vitejs.dev/config/ export default defineConfig({ - plugins: [react()], - resolve: { - alias: { - "~": path.resolve(__dirname, "src"), - } - } + plugins: [react()], + resolve: { + alias: { + "~": path.resolve(__dirname, "src"), + }, + }, })