| @@ -3,15 +3,23 @@ | |||
| "version": "0.1.0", | |||
| "private": true, | |||
| "dependencies": { | |||
| "@emotion/react": "^11.10.8", | |||
| "@emotion/styled": "^11.10.8", | |||
| "@mui/icons-material": "^5.11.16", | |||
| "@mui/material": "^5.12.2", | |||
| "@testing-library/jest-dom": "^5.14.1", | |||
| "@testing-library/react": "^13.0.0", | |||
| "@testing-library/user-event": "^13.2.1", | |||
| "@types/jest": "^27.0.1", | |||
| "@types/lodash": "^4.14.194", | |||
| "@types/node": "^16.7.13", | |||
| "@types/react": "^18.0.0", | |||
| "@types/react-dom": "^18.0.0", | |||
| "@types/react-router-dom": "^5.3.3", | |||
| "lodash": "^4.17.21", | |||
| "react": "^18.2.0", | |||
| "react-dom": "^18.2.0", | |||
| "react-router-dom": "^6.11.0", | |||
| "react-scripts": "5.0.1", | |||
| "typescript": "^4.4.2", | |||
| "web-vitals": "^2.1.0" | |||
| @@ -1,43 +1,23 @@ | |||
| <!DOCTYPE html> | |||
| <html lang="en"> | |||
| <head> | |||
| <meta charset="utf-8" /> | |||
| <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> | |||
| <meta name="viewport" content="width=device-width, initial-scale=1" /> | |||
| <meta name="theme-color" content="#000000" /> | |||
| <meta | |||
| name="description" | |||
| content="Web site created using create-react-app" | |||
| /> | |||
| <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> | |||
| <!-- | |||
| manifest.json provides metadata used when your web app is installed on a | |||
| user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/ | |||
| --> | |||
| <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> | |||
| <!-- | |||
| Notice the use of %PUBLIC_URL% in the tags above. | |||
| It will be replaced with the URL of the `public` folder during the build. | |||
| Only files inside the `public` folder can be referenced from the HTML. | |||
| Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will | |||
| work correctly both with client-side routing and a non-root public URL. | |||
| Learn how to configure a non-root public URL by running `npm run build`. | |||
| --> | |||
| <title>React App</title> | |||
| </head> | |||
| <body> | |||
| <noscript>You need to enable JavaScript to run this app.</noscript> | |||
| <div id="root"></div> | |||
| <!-- | |||
| This HTML file is a template. | |||
| If you open it directly in the browser, you will see an empty page. | |||
| <head> | |||
| <meta charset="utf-8" /> | |||
| <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> | |||
| <meta name="viewport" content="width=device-width, initial-scale=1" /> | |||
| <meta name="theme-color" content="#000000" /> | |||
| <meta name="description" content="Web site created using create-react-app" /> | |||
| <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> | |||
| You can add webfonts, meta tags, or analytics to this file. | |||
| The build step will place the bundled scripts into the <body> tag. | |||
| <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> | |||
| To begin the development, run `npm start` or `yarn start`. | |||
| To create a production bundle, use `npm run build` or `yarn build`. | |||
| --> | |||
| </body> | |||
| </html> | |||
| <title>SateReceipt</title> | |||
| </head> | |||
| <body> | |||
| <noscript>You need to enable JavaScript to run this app.</noscript> | |||
| <div id="root"></div> | |||
| </body> | |||
| </html> | |||
| @@ -0,0 +1,9 @@ | |||
| import { ReactNode } from "react"; | |||
| export type HasChildren = { | |||
| children: ReactNode; | |||
| }; | |||
| export type Dictionary = { | |||
| [key: string]: string; | |||
| }; | |||
| @@ -1,25 +1,24 @@ | |||
| import React from 'react'; | |||
| import logo from './logo.svg'; | |||
| import './App.css'; | |||
| import { CssBaseline } from "@mui/material"; | |||
| import { PageContextProvider } from "contexts/PageContext"; | |||
| import { WindowSizeContextProvider } from "contexts/WindowSizeContext"; | |||
| import { BrowserRouter } from "react-router-dom"; | |||
| import { Routes } from "routes"; | |||
| import { AppThemeProvider } from "theme"; | |||
| function App() { | |||
| return ( | |||
| <div className="App"> | |||
| <header className="App-header"> | |||
| <img src={logo} className="App-logo" alt="logo" /> | |||
| <p> | |||
| Edit <code>src/App.tsx</code> and save to reload. | |||
| </p> | |||
| <a | |||
| className="App-link" | |||
| href="https://reactjs.org" | |||
| target="_blank" | |||
| rel="noopener noreferrer" | |||
| > | |||
| Learn React | |||
| </a> | |||
| </header> | |||
| </div> | |||
| <> | |||
| <AppThemeProvider> | |||
| <PageContextProvider> | |||
| <WindowSizeContextProvider> | |||
| <BrowserRouter> | |||
| <CssBaseline /> | |||
| <Routes /> | |||
| </BrowserRouter> | |||
| </WindowSizeContextProvider> | |||
| </PageContextProvider> | |||
| </AppThemeProvider> | |||
| </> | |||
| ); | |||
| } | |||
| @@ -0,0 +1,8 @@ | |||
| export const PageID = { | |||
| NONE: "NONE", | |||
| DASHBOARD_CONTRACT_LIST: "DASHBOARD_CONTRACT_LIST", | |||
| DASHBOARD_CONTRACT_DETAIL: "DASHBOARD_CONTRACT_DETAIL", | |||
| } as const; | |||
| export type PageID = (typeof PageID)[keyof typeof PageID]; | |||
| @@ -0,0 +1,8 @@ | |||
| export const UserRole = { | |||
| NONE: 0, | |||
| NORMAL_ADMIN: 100, | |||
| CONTRACT_ADMIN: 200, | |||
| SUPER_ADMIN: 900, | |||
| } as const; | |||
| export type UserRole = (typeof UserRole)[keyof typeof UserRole]; | |||
| @@ -0,0 +1,5 @@ | |||
| import { Box } from "@mui/material"; | |||
| export default function LoadingScreen() { | |||
| return <Box>Loading...</Box>; | |||
| } | |||
| @@ -0,0 +1,65 @@ | |||
| import { HasChildren } from "@types"; | |||
| import { PageID } from "codes/page"; | |||
| import usePage from "hooks/usePage"; | |||
| import useWindowSize from "hooks/useWindowSize"; | |||
| import { ReactNode, createContext, useMemo, useState } from "react"; | |||
| type ContextProps = { | |||
| headerTitle: string; | |||
| setHeaderTitle: (title: string) => void; | |||
| drawerWidth: number; | |||
| innerHeight: number; | |||
| innerWidth: number; | |||
| contentsWidth: number; | |||
| tabs: ReactNode | null; | |||
| setTabs: (tabs: ReactNode | null) => void; | |||
| pageId: PageID; | |||
| setPageId: (tabs: PageID) => void; | |||
| }; | |||
| const contextInit: ContextProps = { | |||
| headerTitle: "", | |||
| setHeaderTitle: (title: string) => {}, | |||
| drawerWidth: 0, | |||
| innerHeight: 0, | |||
| innerWidth: 0, | |||
| contentsWidth: 0, | |||
| tabs: null, | |||
| setTabs: (tabs: ReactNode | null) => {}, | |||
| pageId: PageID.NONE, | |||
| setPageId: (tabs: PageID) => {}, | |||
| }; | |||
| export const DashboardLayoutContext = createContext(contextInit); | |||
| type Props = HasChildren; | |||
| export function DashboardLayoutContextProvider({ children }: Props) { | |||
| const drawerWidth = 256; | |||
| const [headerTitle, setHeaderTitle] = useState(""); | |||
| const [tabs, setTabs] = useState<ReactNode | null>(null); | |||
| const { width: innerWidth, height: innerHeight } = useWindowSize(); | |||
| const { pageId, setPageId } = usePage(); | |||
| const contentsWidth = useMemo(() => { | |||
| return innerWidth - drawerWidth; | |||
| }, [drawerWidth, innerWidth]); | |||
| return ( | |||
| <DashboardLayoutContext.Provider | |||
| value={{ | |||
| headerTitle, | |||
| setHeaderTitle, | |||
| drawerWidth, | |||
| innerWidth, | |||
| innerHeight, | |||
| contentsWidth, | |||
| tabs, | |||
| setTabs, | |||
| pageId, | |||
| setPageId, | |||
| }} | |||
| > | |||
| {children} | |||
| </DashboardLayoutContext.Provider> | |||
| ); | |||
| } | |||
| @@ -0,0 +1,30 @@ | |||
| import { HasChildren } from "@types"; | |||
| import { PageID } from "codes/page"; | |||
| import useWindowSize from "hooks/useWindowSize"; | |||
| import { ReactNode, createContext, useMemo, useState } from "react"; | |||
| type ContextProps = { | |||
| pageId: PageID; | |||
| setPageId: (pageId: PageID) => void; | |||
| }; | |||
| const contextInit: ContextProps = { | |||
| pageId: PageID.NONE, | |||
| setPageId: (pageId: PageID) => {}, | |||
| }; | |||
| export const PageContext = createContext(contextInit); | |||
| type Props = HasChildren; | |||
| export function PageContextProvider({ children }: Props) { | |||
| const [pageId, setPageId] = useState<PageID>(PageID.NONE); | |||
| return ( | |||
| <PageContext.Provider | |||
| value={{ | |||
| pageId, | |||
| setPageId, | |||
| }} | |||
| > | |||
| {children} | |||
| </PageContext.Provider> | |||
| ); | |||
| } | |||
| @@ -0,0 +1,31 @@ | |||
| import { HasChildren } from "@types"; | |||
| import { createContext, useLayoutEffect, useState } from "react"; | |||
| export const WindowSizeContext = createContext({ | |||
| width: 0, | |||
| height: 0, | |||
| }); | |||
| type Props = HasChildren; | |||
| export function WindowSizeContextProvider({ children }: Props) { | |||
| const [width, setWidth] = useState(window.innerWidth); | |||
| const [height, setHeight] = useState(window.innerHeight); | |||
| useLayoutEffect(() => { | |||
| const updateSize = () => { | |||
| setWidth(window.innerWidth); | |||
| setHeight(window.innerHeight); | |||
| }; | |||
| window.addEventListener("resize", updateSize); | |||
| updateSize(); | |||
| return () => window.removeEventListener("resize", updateSize); | |||
| }, []); | |||
| return ( | |||
| <WindowSizeContext.Provider value={{ width, height }}> | |||
| {children} | |||
| </WindowSizeContext.Provider> | |||
| ); | |||
| } | |||
| @@ -0,0 +1,16 @@ | |||
| import { useContext, useEffect } from "react"; | |||
| import { DashboardLayoutContext } from "contexts/DashboardLayoutContext"; | |||
| import { PageID } from "codes/page"; | |||
| export default function useDashboard(pageId?: PageID) { | |||
| const context = useContext(DashboardLayoutContext); | |||
| useEffect(() => { | |||
| if (pageId) { | |||
| context.setPageId(pageId ?? PageID.NONE); | |||
| // console.log("CURRENT", pageId); | |||
| } | |||
| }, []); | |||
| return context; | |||
| } | |||
| @@ -0,0 +1,44 @@ | |||
| import { useLocation, useNavigate } from "react-router"; | |||
| import { Dictionary } from "@types"; | |||
| export default function useNavigateCustom() { | |||
| const navigate = useNavigate(); | |||
| const { pathname, search } = useLocation(); | |||
| const navigateWhenChanged = ( | |||
| path: string, | |||
| param?: Dictionary | URLSearchParams | string, | |||
| context?: any | |||
| ) => { | |||
| const currentUrl = pathname + search; | |||
| let newPath = path; | |||
| if (typeof param === "string") { | |||
| if (!param.startsWith("?")) { | |||
| newPath += "?"; | |||
| } | |||
| newPath += param; | |||
| } else if (param instanceof URLSearchParams) { | |||
| const search = param.toString(); | |||
| if (search) { | |||
| newPath += "?"; | |||
| newPath += search; | |||
| } | |||
| } else if (typeof param === "object") { | |||
| const urlParam = new URLSearchParams(param); | |||
| const search = urlParam.toString(); | |||
| if (search) { | |||
| newPath += "?"; | |||
| newPath += search; | |||
| } | |||
| } | |||
| if (currentUrl !== newPath) { | |||
| if (context) { | |||
| console.log("navigate to", newPath, context); | |||
| } | |||
| navigate(newPath); | |||
| } | |||
| }; | |||
| return { navigate, navigateWhenChanged }; | |||
| } | |||
| @@ -0,0 +1,6 @@ | |||
| import { PageContext } from "contexts/PageContext"; | |||
| import { useContext } from "react"; | |||
| export default function usePage() { | |||
| return useContext(PageContext); | |||
| } | |||
| @@ -0,0 +1,39 @@ | |||
| // @mui | |||
| import { Breakpoint } from '@mui/material'; | |||
| import { useTheme } from '@mui/material/styles'; | |||
| import useMediaQuery from '@mui/material/useMediaQuery'; | |||
| // ---------------------------------------------------------------------- | |||
| type Query = 'up' | 'down' | 'between' | 'only'; | |||
| type Key = Breakpoint | number; | |||
| type Start = Breakpoint | number; | |||
| type End = Breakpoint | number; | |||
| export default function useResponsive(query: Query, key?: Key, start?: Start, end?: End) { | |||
| const theme = useTheme(); | |||
| const mediaUp = useMediaQuery(theme.breakpoints.up(key as Key)); | |||
| const mediaDown = useMediaQuery(theme.breakpoints.down(key as Key)); | |||
| const mediaBetween = useMediaQuery(theme.breakpoints.between(start as Start, end as End)); | |||
| const mediaOnly = useMediaQuery(theme.breakpoints.only(key as Breakpoint)); | |||
| if (query === 'up') { | |||
| return mediaUp; | |||
| } | |||
| if (query === 'down') { | |||
| return mediaDown; | |||
| } | |||
| if (query === 'between') { | |||
| return mediaBetween; | |||
| } | |||
| if (query === 'only') { | |||
| return mediaOnly; | |||
| } | |||
| } | |||
| @@ -0,0 +1,6 @@ | |||
| import { useContext } from "react"; | |||
| import { WindowSizeContext } from "contexts/WindowSizeContext"; | |||
| export default function useWindowSize() { | |||
| return useContext(WindowSizeContext); | |||
| } | |||
| @@ -0,0 +1,112 @@ | |||
| import MenuIcon from "@mui/icons-material/Menu"; | |||
| import { Box } from "@mui/material"; | |||
| import AppBar from "@mui/material/AppBar"; | |||
| import Grid from "@mui/material/Grid"; | |||
| import IconButton from "@mui/material/IconButton"; | |||
| import Toolbar from "@mui/material/Toolbar"; | |||
| import Typography from "@mui/material/Typography"; | |||
| import useDashboard from "hooks/useDashBoard"; | |||
| import * as React from "react"; | |||
| interface HeaderProps { | |||
| onDrawerToggle: () => void; | |||
| } | |||
| export default function Header(props: HeaderProps) { | |||
| const { onDrawerToggle } = props; | |||
| const { contentsWidth, headerTitle, tabs } = useDashboard(); | |||
| return ( | |||
| <React.Fragment> | |||
| <AppBar color="primary" position="sticky" elevation={0}> | |||
| <Toolbar> | |||
| <Grid container spacing={1} alignItems="center"> | |||
| <Grid sx={{ display: { sm: "none", xs: "block" } }} item> | |||
| <IconButton | |||
| color="inherit" | |||
| aria-label="open drawer" | |||
| onClick={onDrawerToggle} | |||
| edge="start" | |||
| > | |||
| <MenuIcon /> | |||
| </IconButton> | |||
| </Grid> | |||
| {/* <Grid item xs /> */} | |||
| {/* <Grid item> | |||
| <Link | |||
| href="/" | |||
| variant="body2" | |||
| sx={{ | |||
| textDecoration: "none", | |||
| color: lightColor, | |||
| "&:hover": { | |||
| color: "common.white", | |||
| }, | |||
| }} | |||
| rel="noopener noreferrer" | |||
| target="_blank" | |||
| > | |||
| Go to docs | |||
| </Link> | |||
| </Grid> */} | |||
| {/* <Grid item> | |||
| <Tooltip title="Alerts • No alerts"> | |||
| <IconButton color="inherit"> | |||
| <NotificationsIcon /> | |||
| </IconButton> | |||
| </Tooltip> | |||
| </Grid> */} | |||
| {/* <Grid item> | |||
| <IconButton color="inherit" sx={{ p: 0.5 }}> | |||
| <Avatar src="/static/images/avatar/1.jpg" alt="My Avatar" /> | |||
| </IconButton> | |||
| </Grid> */} | |||
| </Grid> | |||
| </Toolbar> | |||
| </AppBar> | |||
| <AppBar | |||
| component="div" | |||
| color="primary" | |||
| position="static" | |||
| elevation={0} | |||
| sx={{ zIndex: 0 }} | |||
| > | |||
| <Toolbar> | |||
| <Grid container alignItems="center" spacing={1}> | |||
| <Grid item xs> | |||
| <Typography color="inherit" variant="h5" component="h1"> | |||
| {headerTitle} | |||
| </Typography> | |||
| </Grid> | |||
| {/* <Grid item> | |||
| <Button | |||
| sx={{ borderColor: lightColor }} | |||
| variant="outlined" | |||
| color="inherit" | |||
| size="small" | |||
| > | |||
| Web setup | |||
| </Button> | |||
| </Grid> | |||
| <Grid item> | |||
| <Tooltip title="Help"> | |||
| <IconButton color="inherit"> | |||
| <HelpIcon /> | |||
| </IconButton> | |||
| </Tooltip> | |||
| </Grid> */} | |||
| </Grid> | |||
| </Toolbar> | |||
| </AppBar> | |||
| <AppBar | |||
| component="div" | |||
| position="static" | |||
| elevation={0} | |||
| sx={{ zIndex: 0 }} | |||
| > | |||
| {!!tabs && <Box sx={{ maxWidth: contentsWidth }}>{tabs}</Box>} | |||
| </AppBar> | |||
| </React.Fragment> | |||
| ); | |||
| } | |||
| @@ -0,0 +1,77 @@ | |||
| import { Box, Typography, styled } from "@mui/material"; | |||
| import { Outlet } from "react-router-dom"; | |||
| import Navigator from "./navigator"; | |||
| import useResponsive from "hooks/useResponsive"; | |||
| import { useContext, useEffect, useMemo, useState } from "react"; | |||
| import Header from "./header"; | |||
| import useWindowSize from "hooks/useWindowSize"; | |||
| import { | |||
| DashboardLayoutContext, | |||
| DashboardLayoutContextProvider, | |||
| } from "contexts/DashboardLayoutContext"; | |||
| import useDashboard from "hooks/useDashBoard"; | |||
| function Copyright() { | |||
| return ( | |||
| <Typography variant="body2" color="text.secondary" align="center"> | |||
| {"Copyright ©Satellite-Technologies Co., Ltd."} | |||
| {new Date().getFullYear()}. All Rights Reserved. | |||
| </Typography> | |||
| ); | |||
| } | |||
| function App() { | |||
| const [mobileOpen, setMobileOpen] = useState(false); | |||
| const isSmUp = useResponsive("up", "sm"); | |||
| const { drawerWidth, innerHeight, innerWidth, contentsWidth } = | |||
| useDashboard(); | |||
| const handleDrawerToggle = () => { | |||
| setMobileOpen(!mobileOpen); | |||
| }; | |||
| useEffect(() => { | |||
| console.log({ drawerWidth, innerWidth, contentsWidth }); | |||
| }, []); | |||
| return ( | |||
| <Box sx={{ display: "flex", minHeight: "100vh" }}> | |||
| <Box | |||
| component="nav" | |||
| sx={{ width: { sm: drawerWidth }, flexShrink: { md: 0 } }} | |||
| > | |||
| {isSmUp ? null : ( | |||
| <Navigator | |||
| PaperProps={{ style: { width: drawerWidth } }} | |||
| variant="temporary" | |||
| open={mobileOpen} | |||
| onClose={handleDrawerToggle} | |||
| /> | |||
| )} | |||
| <Navigator | |||
| PaperProps={{ style: { width: drawerWidth } }} | |||
| sx={{ display: { sm: "block", xs: "none" } }} | |||
| /> | |||
| </Box> | |||
| <Box sx={{ flex: 1, display: "flex", flexDirection: "column" }}> | |||
| <Header onDrawerToggle={handleDrawerToggle} /> | |||
| <Box component="main" sx={{ flex: 1, py: 6, px: 4 }}> | |||
| <Outlet /> | |||
| </Box> | |||
| <Box component="footer" sx={{ p: 2 }}> | |||
| <Copyright /> | |||
| </Box> | |||
| </Box> | |||
| </Box> | |||
| ); | |||
| } | |||
| export default function DashBoardLayout() { | |||
| return ( | |||
| <DashboardLayoutContextProvider> | |||
| <App /> | |||
| </DashboardLayoutContextProvider> | |||
| ); | |||
| } | |||
| @@ -0,0 +1,230 @@ | |||
| import * as React from "react"; | |||
| import Divider from "@mui/material/Divider"; | |||
| import Drawer, { DrawerProps } from "@mui/material/Drawer"; | |||
| import List from "@mui/material/List"; | |||
| import Box from "@mui/material/Box"; | |||
| import ListItem from "@mui/material/ListItem"; | |||
| import ListItemButton from "@mui/material/ListItemButton"; | |||
| import ListItemIcon from "@mui/material/ListItemIcon"; | |||
| import ListItemText from "@mui/material/ListItemText"; | |||
| import HomeIcon from "@mui/icons-material/Home"; | |||
| import PeopleIcon from "@mui/icons-material/People"; | |||
| import DnsRoundedIcon from "@mui/icons-material/DnsRounded"; | |||
| import PermMediaOutlinedIcon from "@mui/icons-material/PhotoSizeSelectActual"; | |||
| import PublicIcon from "@mui/icons-material/Public"; | |||
| import SettingsEthernetIcon from "@mui/icons-material/SettingsEthernet"; | |||
| import SettingsInputComponentIcon from "@mui/icons-material/SettingsInputComponent"; | |||
| import TimerIcon from "@mui/icons-material/Timer"; | |||
| import SettingsIcon from "@mui/icons-material/Settings"; | |||
| import PhonelinkSetupIcon from "@mui/icons-material/PhonelinkSetup"; | |||
| import { UserRole } from "codes/user"; | |||
| import { useLocation } from "react-router-dom"; | |||
| import { PATH, getPath } from "routes/path"; | |||
| import usePage from "hooks/usePage"; | |||
| import { PageID } from "codes/page"; | |||
| import { ExpandLess, ExpandMore } from "@mui/icons-material"; | |||
| import { Collapse } from "@mui/material"; | |||
| import useNavigateCustom from "hooks/useNavigateCustom"; | |||
| type Group = { | |||
| label: string; | |||
| children: SubGroup[]; | |||
| }; | |||
| type SubGroup = { | |||
| label: string; | |||
| icon: React.ReactNode; | |||
| children?: Child[]; | |||
| // 子要素を持たない場合は下記は必須 | |||
| id?: PageID; | |||
| role?: UserRole; | |||
| }; | |||
| type Child = { | |||
| label: string; | |||
| id: PageID; | |||
| role?: UserRole; | |||
| }; | |||
| const categories: Group[] = [ | |||
| { | |||
| label: "管理", | |||
| children: [ | |||
| { | |||
| label: "契約", | |||
| icon: <PeopleIcon />, | |||
| children: [ | |||
| { | |||
| id: PageID.DASHBOARD_CONTRACT_LIST, | |||
| label: "一覧", | |||
| }, | |||
| { | |||
| id: PageID.DASHBOARD_CONTRACT_DETAIL, | |||
| label: "詳細", | |||
| }, | |||
| ], | |||
| }, | |||
| // { id: "Database", icon: <DnsRoundedIcon />, navigate: "contract" }, | |||
| // { id: "Storage", icon: <PermMediaOutlinedIcon /> }, | |||
| // { id: "Hosting", icon: <PublicIcon /> }, | |||
| // { id: "Functions", icon: <SettingsEthernetIcon /> }, | |||
| // { | |||
| // id: "Machine learning", | |||
| // icon: <SettingsInputComponentIcon />, | |||
| // }, | |||
| ], | |||
| }, | |||
| // { | |||
| // id: "Quality", | |||
| // children: [ | |||
| // { id: "Analytics", icon: <SettingsIcon /> }, | |||
| // { id: "Performance", icon: <TimerIcon /> }, | |||
| // { id: "Test Lab", icon: <PhonelinkSetupIcon /> }, | |||
| // ], | |||
| // }, | |||
| ]; | |||
| const item = { | |||
| py: "2px", | |||
| px: 3, | |||
| color: "rgba(255, 255, 255, 0.7)", | |||
| "&:hover, &:focus": { | |||
| bgcolor: "rgba(255, 255, 255, 0.08)", | |||
| }, | |||
| }; | |||
| const itemCategory = { | |||
| boxShadow: "0 -1px 0 rgb(255,255,255,0.1) inset", | |||
| py: 1.5, | |||
| px: 3, | |||
| }; | |||
| export default function Navigator(props: DrawerProps) { | |||
| const { ...other } = props; | |||
| return ( | |||
| <Drawer variant="permanent" {...other}> | |||
| <List disablePadding> | |||
| <ListItem | |||
| sx={{ ...item, ...itemCategory, fontSize: 22, color: "#fff" }} | |||
| > | |||
| SateReceipt | |||
| </ListItem> | |||
| <ListItem sx={{ ...item, ...itemCategory }}> | |||
| <ListItemIcon> | |||
| <HomeIcon /> | |||
| </ListItemIcon> | |||
| <ListItemText>Project Overview</ListItemText> | |||
| </ListItem> | |||
| {categories.map((group, index) => { | |||
| return <Group {...group} key={index} />; | |||
| })} | |||
| </List> | |||
| </Drawer> | |||
| ); | |||
| } | |||
| function Group(group: Group) { | |||
| const { label, children } = group; | |||
| return ( | |||
| <Box sx={{ bgcolor: "#101F33" }}> | |||
| <ListItem sx={{ py: 2, px: 3 }}> | |||
| <ListItemText sx={{ color: "#fff" }}>{label}</ListItemText> | |||
| </ListItem> | |||
| {children.map((ele, index) => ( | |||
| <SubGroup {...ele} key={index} /> | |||
| ))} | |||
| <Divider sx={{ mt: 2 }} /> | |||
| </Box> | |||
| ); | |||
| } | |||
| function SubGroup({ icon, label, id, children, role }: SubGroup) { | |||
| const { pageId } = usePage(); | |||
| const { navigateWhenChanged } = useNavigateCustom(); | |||
| const { elements, shouldOpen } = useContents(children ?? []); | |||
| const [open, setOpen] = React.useState(false); | |||
| React.useEffect(() => { | |||
| setOpen(shouldOpen); | |||
| }, [shouldOpen]); | |||
| // 子要素ありの場合 | |||
| if (elements && elements.length !== 0) { | |||
| const handleClick = () => { | |||
| setOpen(!open); | |||
| }; | |||
| return ( | |||
| <> | |||
| <ListItemButton onClick={handleClick} sx={item} selected={false}> | |||
| <ListItemIcon>{icon}</ListItemIcon> | |||
| <ListItemText>{label}</ListItemText> | |||
| {open ? <ExpandLess /> : <ExpandMore />} | |||
| </ListItemButton> | |||
| <Collapse in={open} timeout="auto" unmountOnExit> | |||
| <List component="div" disablePadding> | |||
| {elements} | |||
| </List> | |||
| </Collapse> | |||
| </> | |||
| ); | |||
| } | |||
| // 子要素なしの場合 | |||
| const handleClick = () => { | |||
| if (id) { | |||
| const path = getPath(id); | |||
| navigateWhenChanged(path); | |||
| } | |||
| }; | |||
| const selected = id === pageId; | |||
| return ( | |||
| <ListItemButton onClick={handleClick} selected={selected}> | |||
| <ListItemIcon>{icon}</ListItemIcon> | |||
| <ListItemText>{label}</ListItemText> | |||
| </ListItemButton> | |||
| ); | |||
| } | |||
| function useContents(children: Child[]) { | |||
| const { pageId } = usePage(); | |||
| const { navigateWhenChanged } = useNavigateCustom(); | |||
| const [shouldOpen, setShouldOpen] = React.useState(false); | |||
| const elements = React.useMemo(() => { | |||
| setShouldOpen(false); | |||
| return children.map(({ label, id }, index) => { | |||
| const selected = id === pageId; | |||
| if (selected) { | |||
| setShouldOpen(true); | |||
| } | |||
| const handleClick = () => { | |||
| const path = getPath(id); | |||
| navigateWhenChanged(path); | |||
| }; | |||
| return ( | |||
| <ListItemButton | |||
| selected={selected} | |||
| sx={{ ...item, pl: 4 }} | |||
| key={index} | |||
| onClick={handleClick} | |||
| > | |||
| <ListItemText primary={label} /> | |||
| </ListItemButton> | |||
| ); | |||
| }); | |||
| }, [pageId]); | |||
| return { | |||
| elements, | |||
| shouldOpen, | |||
| }; | |||
| } | |||
| @@ -0,0 +1,31 @@ | |||
| import { Tabs } from "@mui/material"; | |||
| import { TabProps, useTab } from "./tabutil"; | |||
| import { PageID } from "codes/page"; | |||
| import { getPath } from "routes/path"; | |||
| const tabs: TabProps[] = [ | |||
| { | |||
| label: "一覧", | |||
| pageId: PageID.DASHBOARD_CONTRACT_LIST, | |||
| }, | |||
| { | |||
| label: "詳細", | |||
| pageId: PageID.DASHBOARD_CONTRACT_DETAIL, | |||
| }, | |||
| ]; | |||
| export default function ContractTabs() { | |||
| const { elements, getTabIndex } = useTab(tabs); | |||
| return ( | |||
| <Tabs | |||
| value={getTabIndex} | |||
| textColor="inherit" | |||
| // scrollButtons | |||
| // allowScrollButtonsMobile | |||
| variant="scrollable" | |||
| > | |||
| {elements} | |||
| </Tabs> | |||
| ); | |||
| } | |||
| @@ -0,0 +1,17 @@ | |||
| import { Tab as MuiTab, TabProps as MuiTabProps } from "@mui/material"; | |||
| import useNavigateCustom from "hooks/useNavigateCustom"; | |||
| export type TabProps = { | |||
| navigate?: string; | |||
| } & MuiTabProps; | |||
| export function Tab({ navigate, ...others }: TabProps) { | |||
| const { navigateWhenChanged } = useNavigateCustom(); | |||
| const handleClick = () => { | |||
| if (navigate) { | |||
| navigateWhenChanged(navigate); | |||
| } | |||
| }; | |||
| return <MuiTab onClick={handleClick} {...others} />; | |||
| } | |||
| @@ -0,0 +1,34 @@ | |||
| import { PageID } from "codes/page"; | |||
| import usePage from "hooks/usePage"; | |||
| import { useMemo } from "react"; | |||
| import { Tab } from "."; | |||
| import { getPath } from "routes/path"; | |||
| export type TabProps = { | |||
| label: string; | |||
| pageId: PageID; | |||
| }; | |||
| export function useTab(tabs: TabProps[]) { | |||
| const { pageId } = usePage(); | |||
| const elements = useMemo(() => { | |||
| return tabs.map(({ label, pageId: elementPageId }, index) => { | |||
| const path = getPath(elementPageId); | |||
| return <Tab {...{ label, navigate: path, key: index }} />; | |||
| }); | |||
| }, [tabs]); | |||
| const getTabIndex = useMemo(() => { | |||
| return ( | |||
| tabs.findIndex((tab) => { | |||
| return tab.pageId === pageId; | |||
| }) ?? 0 | |||
| ); | |||
| }, [pageId, tabs]); | |||
| return { | |||
| elements, | |||
| getTabIndex, | |||
| }; | |||
| } | |||
| @@ -0,0 +1,5 @@ | |||
| import { Box } from "@mui/material"; | |||
| export default function TestB() { | |||
| return <Box>NotFound.</Box>; | |||
| } | |||
| @@ -0,0 +1,17 @@ | |||
| import { Box } from "@mui/material"; | |||
| import { PageID } from "codes/page"; | |||
| import useDashboard from "hooks/useDashBoard"; | |||
| import ContractTabs from "layouts/dashbord/tab/ContractTabs"; | |||
| import { useEffect } from "react"; | |||
| export default function ContractDetail() { | |||
| const { setHeaderTitle, setTabs } = useDashboard( | |||
| PageID.DASHBOARD_CONTRACT_DETAIL | |||
| ); | |||
| useEffect(() => { | |||
| setHeaderTitle("契約者詳細"); | |||
| setTabs(<ContractTabs />); | |||
| }, []); | |||
| return <Box>ContractDetail</Box>; | |||
| } | |||
| @@ -0,0 +1,17 @@ | |||
| import { Box } from "@mui/material"; | |||
| import { PageID } from "codes/page"; | |||
| import useDashboard from "hooks/useDashBoard"; | |||
| import ContractTabs from "layouts/dashbord/tab/ContractTabs"; | |||
| import { useEffect } from "react"; | |||
| export default function ContractList() { | |||
| const { setHeaderTitle, setTabs } = useDashboard( | |||
| PageID.DASHBOARD_CONTRACT_LIST | |||
| ); | |||
| useEffect(() => { | |||
| setHeaderTitle("契約者一覧"); | |||
| setTabs(<ContractTabs />); | |||
| }, []); | |||
| return <Box>ContractList</Box>; | |||
| } | |||
| @@ -0,0 +1,17 @@ | |||
| import { Box } from "@mui/material"; | |||
| import { PageID } from "codes/page"; | |||
| import useDashboard from "hooks/useDashBoard"; | |||
| import ContractTabs from "layouts/dashbord/tab/ContractTabs"; | |||
| import { useEffect } from "react"; | |||
| export default function TestA() { | |||
| const { setHeaderTitle, setTabs } = useDashboard( | |||
| PageID.DASHBOARD_CONTRACT_LIST | |||
| ); | |||
| useEffect(() => { | |||
| setHeaderTitle("契約者一覧"); | |||
| setTabs(<ContractTabs />); | |||
| }, []); | |||
| return <Box>TestA</Box>; | |||
| } | |||
| @@ -0,0 +1,12 @@ | |||
| import { Box } from "@mui/material"; | |||
| import useDashboard from "hooks/useDashBoard"; | |||
| import { useEffect } from "react"; | |||
| export default function TestB() { | |||
| const { setHeaderTitle } = useDashboard(); | |||
| useEffect(() => { | |||
| setHeaderTitle("契約者詳細"); | |||
| }, []); | |||
| return <Box>TestB</Box>; | |||
| } | |||
| @@ -0,0 +1,57 @@ | |||
| import LoadingScreen from "components/LoadingScreen"; | |||
| import DashboardLayout from "layouts/dashbord"; | |||
| import { ElementType, Suspense, lazy } from "react"; | |||
| import { useLocation, useRoutes } from "react-router-dom"; | |||
| import { PATH, getRoute } from "./path"; | |||
| import { PageID } from "codes/page"; | |||
| const Loadable = (Component: ElementType) => (props: any) => { | |||
| return ( | |||
| <Suspense fallback={<LoadingScreen />}> | |||
| <Component {...props} /> | |||
| </Suspense> | |||
| ); | |||
| }; | |||
| export function Routes() { | |||
| return useRoutes([ | |||
| { | |||
| path: "testa", | |||
| element: <TestAPage />, | |||
| }, | |||
| { | |||
| path: "testb", | |||
| element: <TestBPage />, | |||
| }, | |||
| { | |||
| path: "*", | |||
| element: <Page404 />, | |||
| }, | |||
| { | |||
| path: PATH.dashboard.root, | |||
| element: <DashboardLayout />, | |||
| children: [ | |||
| { | |||
| path: getRoute(PageID.DASHBOARD_CONTRACT_LIST, PATH.dashboard.root), | |||
| element: <ContractList />, | |||
| }, | |||
| { | |||
| path: getRoute(PageID.DASHBOARD_CONTRACT_DETAIL, PATH.dashboard.root), | |||
| element: <ContractDetail />, | |||
| }, | |||
| ], | |||
| }, | |||
| ]); | |||
| } | |||
| const TestAPage = Loadable(lazy(() => import("pages/test/TestA"))); | |||
| const TestBPage = Loadable(lazy(() => import("pages/test/TestB"))); | |||
| const ContractList = Loadable( | |||
| lazy(() => import("pages/dashboard/contract/list")) | |||
| ); | |||
| const ContractDetail = Loadable( | |||
| lazy(() => import("pages/dashboard/contract/detail")) | |||
| ); | |||
| const Page404 = Loadable(lazy(() => import("pages/common/Page404"))); | |||
| @@ -0,0 +1,91 @@ | |||
| import { Dictionary } from "@types"; | |||
| import { PageID } from "codes/page"; | |||
| import { get, isNumber, isString, replace } from "lodash"; | |||
| const DASHBOARD = "dashboard"; | |||
| const PREFIX = { | |||
| list: "list", | |||
| detail: "detail", | |||
| }; | |||
| export const PATH = { | |||
| dashboard: { | |||
| root: "dashboard", | |||
| contract: "contract", | |||
| }, | |||
| }; | |||
| const makePath = (paths: string[]): string => { | |||
| return "/" + paths.join("/"); | |||
| }; | |||
| const makeListPageCallback = (path: string) => { | |||
| return (page: number) => { | |||
| return [path, "/", PREFIX.list, String(page)].join("/"); | |||
| }; | |||
| }; | |||
| const makeDashboardPath = (paths: string[]): string => { | |||
| return makePath([PATH.dashboard.root, ...paths]); | |||
| }; | |||
| export const PATH_DASHBOARD = { | |||
| contract: { | |||
| list: makeListPageCallback(makeDashboardPath([PATH.dashboard.contract])), | |||
| detail: makeDashboardPath([PATH.dashboard.contract, "detail"]), | |||
| }, | |||
| sms: { | |||
| list: makePath([DASHBOARD, "sms"]), | |||
| }, | |||
| }; | |||
| const PATHS = { | |||
| [PageID.DASHBOARD_CONTRACT_LIST]: "/dashboard/contract/list/:page", | |||
| [PageID.DASHBOARD_CONTRACT_DETAIL]: "/dashboard/contract/detail", | |||
| }; | |||
| export type PathOption = { | |||
| page?: number; | |||
| query?: Dictionary; | |||
| }; | |||
| export function getPath(pageId: PageID, option?: PathOption) { | |||
| let path = getRoute(pageId); | |||
| // ページ番号解決 | |||
| path = replacePathParam(path, "page", option?.page ?? 0); | |||
| // その他URLパラメータ変換 | |||
| if (option?.query !== undefined) { | |||
| Object.keys(option.query).forEach((key) => { | |||
| const value = get(option.query, key); | |||
| if (value === undefined) return; | |||
| path = replacePathParam(path, key, value); | |||
| }); | |||
| } | |||
| return path; | |||
| } | |||
| export function getRoute(pageId: PageID, exclude?: string): string { | |||
| let path = get(PATHS, pageId); | |||
| if (!path) throw new Error("ルート未定義:" + pageId); | |||
| if (exclude) { | |||
| path = replace(path, "/" + exclude + "/", ""); | |||
| } | |||
| return path; | |||
| } | |||
| function replacePathParam( | |||
| sourceStr: string, | |||
| searchStr: string, | |||
| replacement: string | number | |||
| ): string { | |||
| return replace( | |||
| sourceStr, | |||
| ":" + searchStr, | |||
| isString(replacement) ? replacement : String(replacement) | |||
| ); | |||
| } | |||
| @@ -0,0 +1,150 @@ | |||
| import { ThemeProvider, createTheme } from "@mui/material"; | |||
| import { HasChildren } from "@types"; | |||
| let theme = createTheme({ | |||
| palette: { | |||
| primary: { | |||
| light: "#63ccff", | |||
| main: "#009be5", | |||
| dark: "#006db3", | |||
| }, | |||
| }, | |||
| typography: { | |||
| h5: { | |||
| fontWeight: 500, | |||
| fontSize: 26, | |||
| letterSpacing: 0.5, | |||
| }, | |||
| }, | |||
| shape: { | |||
| borderRadius: 8, | |||
| }, | |||
| components: { | |||
| MuiTab: { | |||
| defaultProps: { | |||
| disableRipple: true, | |||
| }, | |||
| }, | |||
| }, | |||
| mixins: { | |||
| toolbar: { | |||
| minHeight: 48, | |||
| }, | |||
| }, | |||
| }); | |||
| theme = { | |||
| ...theme, | |||
| components: { | |||
| MuiDrawer: { | |||
| styleOverrides: { | |||
| paper: { | |||
| backgroundColor: "#081627", | |||
| }, | |||
| }, | |||
| }, | |||
| MuiButton: { | |||
| styleOverrides: { | |||
| root: { | |||
| textTransform: "none", | |||
| }, | |||
| contained: { | |||
| boxShadow: "none", | |||
| "&:active": { | |||
| boxShadow: "none", | |||
| }, | |||
| }, | |||
| }, | |||
| }, | |||
| MuiTabs: { | |||
| styleOverrides: { | |||
| root: { | |||
| marginLeft: theme.spacing(1), | |||
| }, | |||
| indicator: { | |||
| height: 3, | |||
| borderTopLeftRadius: 3, | |||
| borderTopRightRadius: 3, | |||
| backgroundColor: theme.palette.common.white, | |||
| }, | |||
| }, | |||
| }, | |||
| MuiTab: { | |||
| styleOverrides: { | |||
| root: { | |||
| textTransform: "none", | |||
| margin: "0 16px", | |||
| minWidth: 0, | |||
| padding: 0, | |||
| [theme.breakpoints.up("md")]: { | |||
| padding: 0, | |||
| minWidth: 0, | |||
| }, | |||
| }, | |||
| }, | |||
| }, | |||
| MuiIconButton: { | |||
| styleOverrides: { | |||
| root: { | |||
| padding: theme.spacing(1), | |||
| }, | |||
| }, | |||
| }, | |||
| MuiTooltip: { | |||
| styleOverrides: { | |||
| tooltip: { | |||
| borderRadius: 4, | |||
| }, | |||
| }, | |||
| }, | |||
| MuiDivider: { | |||
| styleOverrides: { | |||
| root: { | |||
| backgroundColor: "rgb(255,255,255,0.15)", | |||
| }, | |||
| }, | |||
| }, | |||
| MuiListItemButton: { | |||
| styleOverrides: { | |||
| root: { | |||
| "&.Mui-selected": { | |||
| color: "#4fc3f7", | |||
| }, | |||
| }, | |||
| }, | |||
| }, | |||
| MuiListItemText: { | |||
| styleOverrides: { | |||
| primary: { | |||
| fontSize: 14, | |||
| fontWeight: theme.typography.fontWeightMedium, | |||
| }, | |||
| }, | |||
| }, | |||
| MuiListItemIcon: { | |||
| styleOverrides: { | |||
| root: { | |||
| color: "inherit", | |||
| minWidth: "auto", | |||
| marginRight: theme.spacing(2), | |||
| "& svg": { | |||
| fontSize: 20, | |||
| }, | |||
| }, | |||
| }, | |||
| }, | |||
| MuiAvatar: { | |||
| styleOverrides: { | |||
| root: { | |||
| width: 32, | |||
| height: 32, | |||
| }, | |||
| }, | |||
| }, | |||
| }, | |||
| }; | |||
| type Props = HasChildren; | |||
| export function AppThemeProvider({ children }: Props) { | |||
| return <ThemeProvider theme={theme}>{children}</ThemeProvider>; | |||
| } | |||
| @@ -18,9 +18,10 @@ | |||
| "resolveJsonModule": true, | |||
| "isolatedModules": true, | |||
| "noEmit": true, | |||
| "jsx": "react-jsx" | |||
| "jsx": "react-jsx", | |||
| "baseUrl": "src" | |||
| }, | |||
| "include": [ | |||
| "src" | |||
| ] | |||
| } | |||
| } | |||
| @@ -169,7 +169,7 @@ | |||
| dependencies: | |||
| "@babel/types" "^7.21.5" | |||
| "@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.18.6", "@babel/helper-module-imports@^7.21.4": | |||
| "@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.18.6", "@babel/helper-module-imports@^7.21.4": | |||
| version "7.21.4" | |||
| resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz#ac88b2f76093637489e718a90cec6cf8a9b029af" | |||
| integrity sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg== | |||
| @@ -1038,7 +1038,7 @@ | |||
| resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" | |||
| integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== | |||
| "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.20.7", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": | |||
| "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.18.3", "@babel/runtime@^7.20.7", "@babel/runtime@^7.21.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": | |||
| version "7.21.5" | |||
| resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.5.tgz#8492dddda9644ae3bda3b45eabe87382caee7200" | |||
| integrity sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q== | |||
| @@ -1195,6 +1195,113 @@ | |||
| resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz#2cbcf822bf3764c9658c4d2e568bd0c0cb748016" | |||
| integrity sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw== | |||
| "@emotion/babel-plugin@^11.10.8": | |||
| version "11.10.8" | |||
| resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.10.8.tgz#bae325c902937665d00684038fd5294223ef9e1d" | |||
| integrity sha512-gxNky50AJL3AlkbjvTARiwAqei6/tNUxDZPSKd+3jqWVM3AmdVTTdpjHorR/an/M0VJqdsuq5oGcFH+rjtyujQ== | |||
| dependencies: | |||
| "@babel/helper-module-imports" "^7.16.7" | |||
| "@babel/runtime" "^7.18.3" | |||
| "@emotion/hash" "^0.9.0" | |||
| "@emotion/memoize" "^0.8.0" | |||
| "@emotion/serialize" "^1.1.1" | |||
| babel-plugin-macros "^3.1.0" | |||
| convert-source-map "^1.5.0" | |||
| escape-string-regexp "^4.0.0" | |||
| find-root "^1.1.0" | |||
| source-map "^0.5.7" | |||
| stylis "4.1.4" | |||
| "@emotion/cache@^11.10.7", "@emotion/cache@^11.10.8": | |||
| version "11.10.8" | |||
| resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.10.8.tgz#3b39b4761bea0ae2f4f07f0a425eec8b6977c03e" | |||
| integrity sha512-5fyqGHi51LU95o7qQ/vD1jyvC4uCY5GcBT+UgP4LHdpO9jPDlXqhrRr9/wCKmfoAvh5G/F7aOh4MwQa+8uEqhA== | |||
| dependencies: | |||
| "@emotion/memoize" "^0.8.0" | |||
| "@emotion/sheet" "^1.2.1" | |||
| "@emotion/utils" "^1.2.0" | |||
| "@emotion/weak-memoize" "^0.3.0" | |||
| stylis "4.1.4" | |||
| "@emotion/hash@^0.9.0": | |||
| version "0.9.0" | |||
| resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.0.tgz#c5153d50401ee3c027a57a177bc269b16d889cb7" | |||
| integrity sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ== | |||
| "@emotion/is-prop-valid@^1.2.0": | |||
| version "1.2.0" | |||
| resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz#7f2d35c97891669f7e276eb71c83376a5dc44c83" | |||
| integrity sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg== | |||
| dependencies: | |||
| "@emotion/memoize" "^0.8.0" | |||
| "@emotion/memoize@^0.8.0": | |||
| version "0.8.0" | |||
| resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.0.tgz#f580f9beb67176fa57aae70b08ed510e1b18980f" | |||
| integrity sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA== | |||
| "@emotion/react@^11.10.8": | |||
| version "11.10.8" | |||
| resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.10.8.tgz#02e274ecb45e03ab9d7a8eb9f0f0c064613eaf7b" | |||
| integrity sha512-ZfGfiABtJ1P1OXqOBsW08EgCDp5fK6C5I8hUJauc/VcJBGSzqAirMnFslhFWnZJ/w5HxPI36XbvMV0l4KZHl+w== | |||
| dependencies: | |||
| "@babel/runtime" "^7.18.3" | |||
| "@emotion/babel-plugin" "^11.10.8" | |||
| "@emotion/cache" "^11.10.8" | |||
| "@emotion/serialize" "^1.1.1" | |||
| "@emotion/use-insertion-effect-with-fallbacks" "^1.0.0" | |||
| "@emotion/utils" "^1.2.0" | |||
| "@emotion/weak-memoize" "^0.3.0" | |||
| hoist-non-react-statics "^3.3.1" | |||
| "@emotion/serialize@^1.1.1": | |||
| version "1.1.1" | |||
| resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.1.tgz#0595701b1902feded8a96d293b26be3f5c1a5cf0" | |||
| integrity sha512-Zl/0LFggN7+L1liljxXdsVSVlg6E/Z/olVWpfxUTxOAmi8NU7YoeWeLfi1RmnB2TATHoaWwIBRoL+FvAJiTUQA== | |||
| dependencies: | |||
| "@emotion/hash" "^0.9.0" | |||
| "@emotion/memoize" "^0.8.0" | |||
| "@emotion/unitless" "^0.8.0" | |||
| "@emotion/utils" "^1.2.0" | |||
| csstype "^3.0.2" | |||
| "@emotion/sheet@^1.2.1": | |||
| version "1.2.1" | |||
| resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.1.tgz#0767e0305230e894897cadb6c8df2c51e61a6c2c" | |||
| integrity sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA== | |||
| "@emotion/styled@^11.10.8": | |||
| version "11.10.8" | |||
| resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.10.8.tgz#a3fd68efd90bd7e8a06b82b95adec643d386fa69" | |||
| integrity sha512-gow0lF4Uw/QEdX2REMhI8v6wLOabPKJ+4HKNF0xdJ2DJdznN6fxaXpQOx6sNkyBhSUL558Rmcu1Lq/MYlVo4vw== | |||
| dependencies: | |||
| "@babel/runtime" "^7.18.3" | |||
| "@emotion/babel-plugin" "^11.10.8" | |||
| "@emotion/is-prop-valid" "^1.2.0" | |||
| "@emotion/serialize" "^1.1.1" | |||
| "@emotion/use-insertion-effect-with-fallbacks" "^1.0.0" | |||
| "@emotion/utils" "^1.2.0" | |||
| "@emotion/unitless@^0.8.0": | |||
| version "0.8.0" | |||
| resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.0.tgz#a4a36e9cbdc6903737cd20d38033241e1b8833db" | |||
| integrity sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw== | |||
| "@emotion/use-insertion-effect-with-fallbacks@^1.0.0": | |||
| version "1.0.0" | |||
| resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz#ffadaec35dbb7885bd54de3fa267ab2f860294df" | |||
| integrity sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A== | |||
| "@emotion/utils@^1.2.0": | |||
| version "1.2.0" | |||
| resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.2.0.tgz#9716eaccbc6b5ded2ea5a90d65562609aab0f561" | |||
| integrity sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw== | |||
| "@emotion/weak-memoize@^0.3.0": | |||
| version "0.3.0" | |||
| resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz#ea89004119dc42db2e1dba0f97d553f7372f6fcb" | |||
| integrity sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg== | |||
| "@eslint-community/eslint-utils@^4.2.0": | |||
| version "4.4.0" | |||
| resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" | |||
| @@ -1548,6 +1655,99 @@ | |||
| resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" | |||
| integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== | |||
| "@mui/base@5.0.0-alpha.127": | |||
| version "5.0.0-alpha.127" | |||
| resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-alpha.127.tgz#bc61eaf1fd31094c939b6521cfea21643207c3b4" | |||
| integrity sha512-FoRQd0IOH9MnfyL5yXssyQRnC4vXI+1bwkU1idr+wNkP1ZfxE+JsThHcfl1dy5azLssVUGTtQFD9edQLdbyJog== | |||
| dependencies: | |||
| "@babel/runtime" "^7.21.0" | |||
| "@emotion/is-prop-valid" "^1.2.0" | |||
| "@mui/types" "^7.2.4" | |||
| "@mui/utils" "^5.12.0" | |||
| "@popperjs/core" "^2.11.7" | |||
| clsx "^1.2.1" | |||
| prop-types "^15.8.1" | |||
| react-is "^18.2.0" | |||
| "@mui/core-downloads-tracker@^5.12.2": | |||
| version "5.12.2" | |||
| resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.12.2.tgz#4a0186d25b01d693171366e1c00de0e7c8c35f6a" | |||
| integrity sha512-Qn7dy8tql6T0hY6gTFPkpWlnqVVFGu5Z6QzEzUSzzmLZpfAx4kf8sFz0PHiB7gU5yrqcZF9picMx1shpRY/rXw== | |||
| "@mui/icons-material@^5.11.16": | |||
| version "5.11.16" | |||
| resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.11.16.tgz#417fa773c56672e39d6ccfed9ac55591985f0d38" | |||
| integrity sha512-oKkx9z9Kwg40NtcIajF9uOXhxiyTZrrm9nmIJ4UjkU2IdHpd4QVLbCc/5hZN/y0C6qzi2Zlxyr9TGddQx2vx2A== | |||
| dependencies: | |||
| "@babel/runtime" "^7.21.0" | |||
| "@mui/material@^5.12.2": | |||
| version "5.12.2" | |||
| resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.12.2.tgz#c3fcc94e523d9e673e2e045dfad04d12ab454a80" | |||
| integrity sha512-XOVy6fVC0rI2dEwDq/1s4Te2hewTUe6lznzeVnruyATGkdmM06WnHqkZOoLVIWo9hWwAxpcgTDcAIVpFtt1nrw== | |||
| dependencies: | |||
| "@babel/runtime" "^7.21.0" | |||
| "@mui/base" "5.0.0-alpha.127" | |||
| "@mui/core-downloads-tracker" "^5.12.2" | |||
| "@mui/system" "^5.12.1" | |||
| "@mui/types" "^7.2.4" | |||
| "@mui/utils" "^5.12.0" | |||
| "@types/react-transition-group" "^4.4.5" | |||
| clsx "^1.2.1" | |||
| csstype "^3.1.2" | |||
| prop-types "^15.8.1" | |||
| react-is "^18.2.0" | |||
| react-transition-group "^4.4.5" | |||
| "@mui/private-theming@^5.12.0": | |||
| version "5.12.0" | |||
| resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.12.0.tgz#5f1e6fd09b1447c387fdac1eef7f23efca5c6d69" | |||
| integrity sha512-w5dwMen1CUm1puAtubqxY9BIzrBxbOThsg2iWMvRJmWyJAPdf3Z583fPXpqeA2lhTW79uH2jajk5Ka4FuGlTPg== | |||
| dependencies: | |||
| "@babel/runtime" "^7.21.0" | |||
| "@mui/utils" "^5.12.0" | |||
| prop-types "^15.8.1" | |||
| "@mui/styled-engine@^5.12.0": | |||
| version "5.12.0" | |||
| resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.12.0.tgz#44640cad961adcc9413ae32116237cd1c8f7ddb0" | |||
| integrity sha512-frh8L7CRnvD0RDmIqEv6jFeKQUIXqW90BaZ6OrxJ2j4kIsiVLu29Gss4SbBvvrWwwatR72sBmC3w1aG4fjp9mQ== | |||
| dependencies: | |||
| "@babel/runtime" "^7.21.0" | |||
| "@emotion/cache" "^11.10.7" | |||
| csstype "^3.1.2" | |||
| prop-types "^15.8.1" | |||
| "@mui/system@^5.12.1": | |||
| version "5.12.1" | |||
| resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.12.1.tgz#8452bc03159f0a6725b96bde1dee1316e308231b" | |||
| integrity sha512-Po+sicdV3bbRYXdU29XZaHPZrW7HUYUqU1qCu77GCCEMbahC756YpeyefdIYuPMUg0OdO3gKIUfDISBrkjJL+w== | |||
| dependencies: | |||
| "@babel/runtime" "^7.21.0" | |||
| "@mui/private-theming" "^5.12.0" | |||
| "@mui/styled-engine" "^5.12.0" | |||
| "@mui/types" "^7.2.4" | |||
| "@mui/utils" "^5.12.0" | |||
| clsx "^1.2.1" | |||
| csstype "^3.1.2" | |||
| prop-types "^15.8.1" | |||
| "@mui/types@^7.2.4": | |||
| version "7.2.4" | |||
| resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.4.tgz#b6fade19323b754c5c6de679a38f068fd50b9328" | |||
| integrity sha512-LBcwa8rN84bKF+f5sDyku42w1NTxaPgPyYKODsh01U1fVstTClbUoSA96oyRBnSNyEiAVjKm6Gwx9vjR+xyqHA== | |||
| "@mui/utils@^5.12.0": | |||
| version "5.12.0" | |||
| resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.12.0.tgz#284db48b36ac26f3d34076379072c1dc8aed1ad0" | |||
| integrity sha512-RmQwgzF72p7Yr4+AAUO6j1v2uzt6wr7SWXn68KBsnfVpdOHyclCzH2lr/Xu6YOw9su4JRtdAIYfJFXsS6Cjkmw== | |||
| dependencies: | |||
| "@babel/runtime" "^7.21.0" | |||
| "@types/prop-types" "^15.7.5" | |||
| "@types/react-is" "^16.7.1 || ^17.0.0" | |||
| prop-types "^15.8.1" | |||
| react-is "^18.2.0" | |||
| "@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1": | |||
| version "5.1.1-v1" | |||
| resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz#dbf733a965ca47b1973177dc0bb6c889edcfb129" | |||
| @@ -1591,6 +1791,16 @@ | |||
| schema-utils "^3.0.0" | |||
| source-map "^0.7.3" | |||
| "@popperjs/core@^2.11.7": | |||
| version "2.11.7" | |||
| resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.7.tgz#ccab5c8f7dc557a52ca3288c10075c9ccd37fff7" | |||
| integrity sha512-Cr4OjIkipTtcXKjAsm8agyleBuDHvxzeBoa1v543lbv1YaIwQjESsVcmjiWiPEbC1FIeHOG/Op9kdCmAmiS3Kw== | |||
| "@remix-run/router@1.6.0": | |||
| version "1.6.0" | |||
| resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.6.0.tgz#45010e1826f4d81a1b2cfaf874f1aac93998cd28" | |||
| integrity sha512-N13NRw3T2+6Xi9J//3CGLsK2OqC8NMme3d/YX+nh05K9YHWGcv8DycHJrqGScSP4T75o8IN6nqIMhVFU8ohg8w== | |||
| "@rollup/plugin-babel@^5.2.0": | |||
| version "5.3.1" | |||
| resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz#04bc0608f4aa4b2e4b1aebf284344d0f68fda283" | |||
| @@ -1946,6 +2156,11 @@ | |||
| dependencies: | |||
| "@types/node" "*" | |||
| "@types/history@^4.7.11": | |||
| version "4.7.11" | |||
| resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.11.tgz#56588b17ae8f50c53983a524fc3cc47437969d64" | |||
| integrity sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA== | |||
| "@types/html-minifier-terser@^6.0.0": | |||
| version "6.1.0" | |||
| resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35" | |||
| @@ -2003,6 +2218,11 @@ | |||
| resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" | |||
| integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== | |||
| "@types/lodash@^4.14.194": | |||
| version "4.14.194" | |||
| resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.194.tgz#b71eb6f7a0ff11bff59fc987134a093029258a76" | |||
| integrity sha512-r22s9tAS7imvBt2lyHC9B8AGwWnXaYb1tY09oyLkXDs4vArpYJzw09nj8MLx5VfciBPGIb+ZwG0ssYnEPJxn/g== | |||
| "@types/mime@*": | |||
| version "3.0.1" | |||
| resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10" | |||
| @@ -2033,7 +2253,7 @@ | |||
| resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.2.tgz#6c2324641cc4ba050a8c710b2b251b377581fbf0" | |||
| integrity sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg== | |||
| "@types/prop-types@*": | |||
| "@types/prop-types@*", "@types/prop-types@^15.7.5": | |||
| version "15.7.5" | |||
| resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" | |||
| integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== | |||
| @@ -2060,6 +2280,37 @@ | |||
| dependencies: | |||
| "@types/react" "*" | |||
| "@types/react-is@^16.7.1 || ^17.0.0": | |||
| version "17.0.4" | |||
| resolved "https://registry.yarnpkg.com/@types/react-is/-/react-is-17.0.4.tgz#3cccd02851f7f7a75b21d6e922da26bc7f8f44ad" | |||
| integrity sha512-FLzd0K9pnaEvKz4D1vYxK9JmgQPiGk1lu23o1kqGsLeT0iPbRSF7b76+S5T9fD8aRa0B8bY7I/3DebEj+1ysBA== | |||
| dependencies: | |||
| "@types/react" "^17" | |||
| "@types/react-router-dom@^5.3.3": | |||
| version "5.3.3" | |||
| resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.3.3.tgz#e9d6b4a66fcdbd651a5f106c2656a30088cc1e83" | |||
| integrity sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw== | |||
| dependencies: | |||
| "@types/history" "^4.7.11" | |||
| "@types/react" "*" | |||
| "@types/react-router" "*" | |||
| "@types/react-router@*": | |||
| version "5.1.20" | |||
| resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-5.1.20.tgz#88eccaa122a82405ef3efbcaaa5dcdd9f021387c" | |||
| integrity sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q== | |||
| dependencies: | |||
| "@types/history" "^4.7.11" | |||
| "@types/react" "*" | |||
| "@types/react-transition-group@^4.4.5": | |||
| version "4.4.5" | |||
| resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.5.tgz#aae20dcf773c5aa275d5b9f7cdbca638abc5e416" | |||
| integrity sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA== | |||
| dependencies: | |||
| "@types/react" "*" | |||
| "@types/react@*", "@types/react@^18.0.0": | |||
| version "18.2.0" | |||
| resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.0.tgz#15cda145354accfc09a18d2f2305f9fc099ada21" | |||
| @@ -2069,6 +2320,15 @@ | |||
| "@types/scheduler" "*" | |||
| csstype "^3.0.2" | |||
| "@types/react@^17": | |||
| version "17.0.58" | |||
| resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.58.tgz#c8bbc82114e5c29001548ebe8ed6c4ba4d3c9fb0" | |||
| integrity sha512-c1GzVY97P0fGxwGxhYq989j4XwlcHQoto6wQISOC2v6wm3h0PORRWJFHlkRjfGsiG3y1609WdQ+J+tKxvrEd6A== | |||
| dependencies: | |||
| "@types/prop-types" "*" | |||
| "@types/scheduler" "*" | |||
| csstype "^3.0.2" | |||
| "@types/resolve@1.17.1": | |||
| version "1.17.1" | |||
| resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6" | |||
| @@ -3109,6 +3369,11 @@ cliui@^7.0.2: | |||
| strip-ansi "^6.0.0" | |||
| wrap-ansi "^7.0.0" | |||
| clsx@^1.2.1: | |||
| version "1.2.1" | |||
| resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12" | |||
| integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== | |||
| co@^4.6.0: | |||
| version "4.6.0" | |||
| resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" | |||
| @@ -3251,7 +3516,7 @@ content-type@~1.0.4: | |||
| resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" | |||
| integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== | |||
| convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: | |||
| convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: | |||
| version "1.9.0" | |||
| resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" | |||
| integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== | |||
| @@ -3514,7 +3779,7 @@ cssstyle@^2.3.0: | |||
| dependencies: | |||
| cssom "~0.3.6" | |||
| csstype@^3.0.2: | |||
| csstype@^3.0.2, csstype@^3.1.2: | |||
| version "3.1.2" | |||
| resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" | |||
| integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== | |||
| @@ -3721,6 +3986,14 @@ dom-converter@^0.2.0: | |||
| dependencies: | |||
| utila "~0.4" | |||
| dom-helpers@^5.0.1: | |||
| version "5.2.1" | |||
| resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902" | |||
| integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA== | |||
| dependencies: | |||
| "@babel/runtime" "^7.8.7" | |||
| csstype "^3.0.2" | |||
| dom-serializer@0: | |||
| version "0.2.2" | |||
| resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" | |||
| @@ -4457,6 +4730,11 @@ find-cache-dir@^3.3.1: | |||
| make-dir "^3.0.2" | |||
| pkg-dir "^4.1.0" | |||
| find-root@^1.1.0: | |||
| version "1.1.0" | |||
| resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" | |||
| integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== | |||
| find-up@^3.0.0: | |||
| version "3.0.0" | |||
| resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" | |||
| @@ -4819,6 +5097,13 @@ he@^1.2.0: | |||
| resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" | |||
| integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== | |||
| hoist-non-react-statics@^3.3.1: | |||
| version "3.3.2" | |||
| resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" | |||
| integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== | |||
| dependencies: | |||
| react-is "^16.7.0" | |||
| hoopy@^0.1.4: | |||
| version "0.1.4" | |||
| resolved "https://registry.yarnpkg.com/hoopy/-/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d" | |||
| @@ -7397,7 +7682,7 @@ prompts@^2.0.1, prompts@^2.4.2: | |||
| kleur "^3.0.3" | |||
| sisteransi "^1.0.5" | |||
| prop-types@^15.8.1: | |||
| prop-types@^15.6.2, prop-types@^15.8.1: | |||
| version "15.8.1" | |||
| resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" | |||
| integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== | |||
| @@ -7530,7 +7815,7 @@ react-error-overlay@^6.0.11: | |||
| resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.11.tgz#92835de5841c5cf08ba00ddd2d677b6d17ff9adb" | |||
| integrity sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg== | |||
| react-is@^16.13.1: | |||
| react-is@^16.13.1, react-is@^16.7.0: | |||
| version "16.13.1" | |||
| resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" | |||
| integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== | |||
| @@ -7540,7 +7825,7 @@ react-is@^17.0.1: | |||
| resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" | |||
| integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== | |||
| react-is@^18.0.0: | |||
| react-is@^18.0.0, react-is@^18.2.0: | |||
| version "18.2.0" | |||
| resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" | |||
| integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== | |||
| @@ -7550,6 +7835,21 @@ react-refresh@^0.11.0: | |||
| resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.11.0.tgz#77198b944733f0f1f1a90e791de4541f9f074046" | |||
| integrity sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A== | |||
| react-router-dom@^6.11.0: | |||
| version "6.11.0" | |||
| resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.11.0.tgz#e9507327dad2dfdd3c4815810dbd8de8fc2ee211" | |||
| integrity sha512-Q3mK1c/CYoF++J6ZINz7EZzwlgSOZK/kc7lxIA7PhtWhKju4KfF1WHqlx0kVCIFJAWztuYVpXZeljEbds8z4Og== | |||
| dependencies: | |||
| "@remix-run/router" "1.6.0" | |||
| react-router "6.11.0" | |||
| react-router@6.11.0: | |||
| version "6.11.0" | |||
| resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.11.0.tgz#2e9008e40f8ce69e381373a7916ebadfbf2ff184" | |||
| integrity sha512-hTm6KKNpj9SDG4syIWRjCU219O0RZY8RUPobCFt9p+PlF7nnkRgMoh2DieTKvw3F3Mw6zg565HGnSv8BuoY5oQ== | |||
| dependencies: | |||
| "@remix-run/router" "1.6.0" | |||
| react-scripts@5.0.1: | |||
| version "5.0.1" | |||
| resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-5.0.1.tgz#6285dbd65a8ba6e49ca8d651ce30645a6d980003" | |||
| @@ -7605,6 +7905,16 @@ react-scripts@5.0.1: | |||
| optionalDependencies: | |||
| fsevents "^2.3.2" | |||
| react-transition-group@^4.4.5: | |||
| version "4.4.5" | |||
| resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1" | |||
| integrity sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g== | |||
| dependencies: | |||
| "@babel/runtime" "^7.5.5" | |||
| dom-helpers "^5.0.1" | |||
| loose-envify "^1.4.0" | |||
| prop-types "^15.6.2" | |||
| react@^18.2.0: | |||
| version "18.2.0" | |||
| resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" | |||
| @@ -8123,6 +8433,11 @@ source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, sourc | |||
| resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" | |||
| integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== | |||
| source-map@^0.5.7: | |||
| version "0.5.7" | |||
| resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" | |||
| integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== | |||
| source-map@^0.7.3: | |||
| version "0.7.4" | |||
| resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" | |||
| @@ -8355,6 +8670,11 @@ stylehacks@^5.1.1: | |||
| browserslist "^4.21.4" | |||
| postcss-selector-parser "^6.0.4" | |||
| stylis@4.1.4: | |||
| version "4.1.4" | |||
| resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.1.4.tgz#9cb60e7153d8ac6d02d773552bf51c7a0344535b" | |||
| integrity sha512-USf5pszRYwuE6hg9by0OkKChkQYEXfkeTtm0xKw+jqQhwyjCVLdYyMBK7R+n7dhzsblAWJnGxju4vxq5eH20GQ== | |||
| sucrase@^3.32.0: | |||
| version "3.32.0" | |||
| resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.32.0.tgz#c4a95e0f1e18b6847127258a75cf360bc568d4a7" | |||