mirror of
https://github.com/ershisan99/DevToysWeb.git
synced 2025-12-18 04:59:23 +00:00
feat: add layout component
This commit is contained in:
@@ -4,7 +4,7 @@ A web clone of [DevToys](https://github.com/veler/DevToys)
|
|||||||
|
|
||||||
## Todo
|
## Todo
|
||||||
|
|
||||||
- [ ] Add site layout
|
- [x] Add site layout
|
||||||
- [ ] Add all tools page mock
|
- [ ] Add all tools page mock
|
||||||
- [ ] Implement tools
|
- [ ] Implement tools
|
||||||
- [ ] Converters
|
- [ ] Converters
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
"@fontsource/roboto": "^4.5.3",
|
"@fontsource/roboto": "^4.5.3",
|
||||||
"@mui/icons-material": "^5.5.1",
|
"@mui/icons-material": "^5.5.1",
|
||||||
"@mui/material": "^5.5.1",
|
"@mui/material": "^5.5.1",
|
||||||
|
"fast-deep-equal": "^3.1.3",
|
||||||
"next": "12.1.0",
|
"next": "12.1.0",
|
||||||
"react": "17.0.2",
|
"react": "17.0.2",
|
||||||
"react-dom": "17.0.2",
|
"react-dom": "17.0.2",
|
||||||
|
|||||||
116
src/components/layout/Drawer.tsx
Normal file
116
src/components/layout/Drawer.tsx
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
import CodeIcon from "@mui/icons-material/Code";
|
||||||
|
import DataObjectIcon from "@mui/icons-material/DataObject";
|
||||||
|
import DragHandleIcon from "@mui/icons-material/DragHandle";
|
||||||
|
import FilterIcon from "@mui/icons-material/Filter";
|
||||||
|
import FingerprintIcon from "@mui/icons-material/Fingerprint";
|
||||||
|
import HomeIcon from "@mui/icons-material/Home";
|
||||||
|
import ImageIcon from "@mui/icons-material/Image";
|
||||||
|
import KeyIcon from "@mui/icons-material/Key";
|
||||||
|
import LinkIcon from "@mui/icons-material/Link";
|
||||||
|
import NoteAddIcon from "@mui/icons-material/NoteAdd";
|
||||||
|
import NumbersIcon from "@mui/icons-material/Numbers";
|
||||||
|
import SortIcon from "@mui/icons-material/Sort";
|
||||||
|
import SyncAltIcon from "@mui/icons-material/SyncAlt";
|
||||||
|
import TextFieldsIcon from "@mui/icons-material/TextFields";
|
||||||
|
import TextIncreaseIcon from "@mui/icons-material/TextIncrease";
|
||||||
|
import TransformIcon from "@mui/icons-material/Transform";
|
||||||
|
import { Box, css, Divider, Drawer, List, Stack } from "@mui/material";
|
||||||
|
import { memo } from "react";
|
||||||
|
|
||||||
|
import { pagesPath } from "@/libs/$path";
|
||||||
|
|
||||||
|
import DrawerCollapseItem from "./DrawerCollapseItem";
|
||||||
|
import DrawerItem from "./DrawerItem";
|
||||||
|
import SearchBar from "./SearchBar";
|
||||||
|
|
||||||
|
export const drawerWidth = 300;
|
||||||
|
|
||||||
|
const drawer = css`
|
||||||
|
width: ${drawerWidth}px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
& .MuiDrawer-paper {
|
||||||
|
position: relative;
|
||||||
|
border: none;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const divider = css`
|
||||||
|
border-color: rgba(0, 0, 0, 0.08);
|
||||||
|
`;
|
||||||
|
|
||||||
|
const toolGroups = [
|
||||||
|
{
|
||||||
|
icon: <TransformIcon />,
|
||||||
|
title: "Converters",
|
||||||
|
tools: [
|
||||||
|
{ icon: <TransformIcon />, title: "Json <> Yaml", href: pagesPath.$url(), disabled: true },
|
||||||
|
{ icon: <NumbersIcon />, title: "Number Base", href: pagesPath.$url(), disabled: true },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <SyncAltIcon />,
|
||||||
|
title: "Encoders / Decoders",
|
||||||
|
tools: [
|
||||||
|
{ icon: <CodeIcon />, title: "HTML", href: pagesPath.$url(), disabled: true },
|
||||||
|
{ icon: <LinkIcon />, title: "URL", href: pagesPath.$url(), disabled: true },
|
||||||
|
{ icon: <DragHandleIcon />, title: "Base 64", href: pagesPath.$url(), disabled: true },
|
||||||
|
{ icon: <KeyIcon />, title: "JWT", href: pagesPath.$url(), disabled: true },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <SortIcon />,
|
||||||
|
title: "Formatters",
|
||||||
|
tools: [{ icon: <DataObjectIcon />, title: "Json", href: pagesPath.$url(), disabled: true }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <NoteAddIcon />,
|
||||||
|
title: "Generators",
|
||||||
|
tools: [
|
||||||
|
{ icon: <FingerprintIcon />, title: "Hash", href: pagesPath.$url(), disabled: true },
|
||||||
|
{ icon: <NumbersIcon />, title: "UUID", href: pagesPath.$url(), disabled: true },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <TextFieldsIcon />,
|
||||||
|
title: "Text",
|
||||||
|
tools: [
|
||||||
|
{ icon: <TextIncreaseIcon />, title: "Regex Tester", href: pagesPath.$url(), disabled: true },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <ImageIcon />,
|
||||||
|
title: "Graphic",
|
||||||
|
tools: [
|
||||||
|
{
|
||||||
|
icon: <FilterIcon />,
|
||||||
|
title: "PNG / JPEG Compressor",
|
||||||
|
href: pagesPath.$url(),
|
||||||
|
disabled: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const StyledComponent = () => (
|
||||||
|
<Drawer variant="permanent" css={drawer}>
|
||||||
|
<Box paddingLeft={2} paddingRight={2} marginTop="1px">
|
||||||
|
<SearchBar />
|
||||||
|
</Box>
|
||||||
|
<List component="nav">
|
||||||
|
<Stack spacing={1}>
|
||||||
|
<DrawerItem icon={<HomeIcon />} title="All tools" href={pagesPath.$url()} />
|
||||||
|
<Divider css={divider} />
|
||||||
|
<Box>
|
||||||
|
{toolGroups.map(({ icon, title, tools }) => (
|
||||||
|
<DrawerCollapseItem key={title} {...{ icon, title, tools }} />
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
|
</Stack>
|
||||||
|
</List>
|
||||||
|
</Drawer>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const Component = memo(StyledComponent);
|
||||||
|
|
||||||
|
export default Component;
|
||||||
56
src/components/layout/DrawerCollapseItem.tsx
Normal file
56
src/components/layout/DrawerCollapseItem.tsx
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import ExpandLess from "@mui/icons-material/ExpandLess";
|
||||||
|
import ExpandMore from "@mui/icons-material/ExpandMore";
|
||||||
|
import { Collapse, List, ListItemButton, ListItemText } from "@mui/material";
|
||||||
|
import equal from "fast-deep-equal";
|
||||||
|
import { ComponentPropsWithoutRef, memo, MouseEventHandler, useCallback, useState } from "react";
|
||||||
|
|
||||||
|
import DrawerItem from "./DrawerItem";
|
||||||
|
import DrawerItemIcon from "./DrawerItemIcon";
|
||||||
|
|
||||||
|
type ContainerProps = {
|
||||||
|
title: string;
|
||||||
|
tools: ComponentPropsWithoutRef<typeof DrawerItem>[];
|
||||||
|
} & ComponentPropsWithoutRef<typeof DrawerItemIcon>;
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
open: boolean;
|
||||||
|
onClick: MouseEventHandler<HTMLDivElement>;
|
||||||
|
} & ContainerProps;
|
||||||
|
|
||||||
|
const StyledComponent = ({ icon, title, tools, open, onClick }: Props) => (
|
||||||
|
<>
|
||||||
|
<ListItemButton {...{ onClick }}>
|
||||||
|
<DrawerItemIcon {...{ icon }} />
|
||||||
|
<ListItemText primary={title} />
|
||||||
|
{open ? <ExpandLess /> : <ExpandMore />}
|
||||||
|
</ListItemButton>
|
||||||
|
<Collapse in={open} timeout="auto" unmountOnExit>
|
||||||
|
<List component="div" disablePadding>
|
||||||
|
{tools.map(tool => (
|
||||||
|
<DrawerItem
|
||||||
|
key={tool.title}
|
||||||
|
icon={tool.icon}
|
||||||
|
title={tool.title}
|
||||||
|
href={tool.href}
|
||||||
|
disabled={tool.disabled}
|
||||||
|
subItem
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</List>
|
||||||
|
</Collapse>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const Component = memo(StyledComponent, equal);
|
||||||
|
|
||||||
|
const Container = ({ icon, title, tools }: ContainerProps) => {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
|
const onClick = useCallback(() => {
|
||||||
|
setOpen(!open);
|
||||||
|
}, [open]);
|
||||||
|
|
||||||
|
return <Component {...{ icon, title, tools, open, onClick }} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Container;
|
||||||
47
src/components/layout/DrawerItem.tsx
Normal file
47
src/components/layout/DrawerItem.tsx
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import { Box, css, ListItemButton, ListItemText, Tooltip } from "@mui/material";
|
||||||
|
import NextLink, { LinkProps } from "next/link";
|
||||||
|
import { ComponentPropsWithoutRef, memo } from "react";
|
||||||
|
|
||||||
|
import DrawerItemIcon from "./DrawerItemIcon";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
title: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
subItem?: true;
|
||||||
|
} & Pick<LinkProps, "href"> &
|
||||||
|
ComponentPropsWithoutRef<typeof DrawerItemIcon>;
|
||||||
|
|
||||||
|
const indent = css`
|
||||||
|
text-indent: 40px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const StyledComponent = ({ href, icon, title, disabled, subItem }: Props) => {
|
||||||
|
const wrappedIcon = subItem ? (
|
||||||
|
<Box css={indent}>
|
||||||
|
<DrawerItemIcon {...{ icon }} />
|
||||||
|
</Box>
|
||||||
|
) : (
|
||||||
|
<DrawerItemIcon {...{ icon }} />
|
||||||
|
);
|
||||||
|
|
||||||
|
const link = (
|
||||||
|
<NextLink {...{ href }} passHref>
|
||||||
|
<ListItemButton {...{ disabled }}>
|
||||||
|
{wrappedIcon}
|
||||||
|
<ListItemText primary={title} />
|
||||||
|
</ListItemButton>
|
||||||
|
</NextLink>
|
||||||
|
);
|
||||||
|
|
||||||
|
return disabled ? (
|
||||||
|
<Tooltip title="coming soon!" placement="right" arrow>
|
||||||
|
<span>{link}</span>
|
||||||
|
</Tooltip>
|
||||||
|
) : (
|
||||||
|
link
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Component = memo(StyledComponent);
|
||||||
|
|
||||||
|
export default Component;
|
||||||
17
src/components/layout/DrawerItemIcon.tsx
Normal file
17
src/components/layout/DrawerItemIcon.tsx
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { css, ListItemIcon } from "@mui/material";
|
||||||
|
import { memo, ReactNode } from "react";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
icon: ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
const itemIcon = css`
|
||||||
|
min-width: 40px;
|
||||||
|
vertical-align: middle;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const StyledComponent = ({ icon }: Props) => <ListItemIcon css={itemIcon}>{icon}</ListItemIcon>;
|
||||||
|
|
||||||
|
export const Component = memo(StyledComponent);
|
||||||
|
|
||||||
|
export default Component;
|
||||||
85
src/components/layout/Header.tsx
Normal file
85
src/components/layout/Header.tsx
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
import GitHubIcon from "@mui/icons-material/GitHub";
|
||||||
|
import {
|
||||||
|
AppBar,
|
||||||
|
css,
|
||||||
|
IconButton,
|
||||||
|
Link as MuiLink,
|
||||||
|
Stack,
|
||||||
|
Theme,
|
||||||
|
Toolbar,
|
||||||
|
Typography,
|
||||||
|
} from "@mui/material";
|
||||||
|
import NextLink from "next/link";
|
||||||
|
import { memo } from "react";
|
||||||
|
|
||||||
|
import { site } from "@/data";
|
||||||
|
import { pagesPath } from "@/libs/$path";
|
||||||
|
|
||||||
|
export const headerHeight = 48;
|
||||||
|
|
||||||
|
const appBar = css`
|
||||||
|
background-color: transparent;
|
||||||
|
box-shadow: none;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const toolbar = (theme: Theme) => css`
|
||||||
|
padding: 0 ${theme.spacing(2)} !important;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const topLink = css`
|
||||||
|
color: black;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: 400;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const description = (theme: Theme) => css`
|
||||||
|
color: black;
|
||||||
|
font-size: ${theme.typography.fontSize * 1.4}px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const gitHubLink = (theme: Theme) => css`
|
||||||
|
color: black;
|
||||||
|
margin-left: auto;
|
||||||
|
width: ${theme.typography.fontSize * 3}px;
|
||||||
|
height: ${theme.typography.fontSize * 3}px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const gitHubIcon = (theme: Theme) => css`
|
||||||
|
width: ${theme.typography.fontSize * 3};
|
||||||
|
height: ${theme.typography.fontSize * 3};
|
||||||
|
`;
|
||||||
|
|
||||||
|
const StyledComponent = () => (
|
||||||
|
<AppBar position="relative" css={appBar}>
|
||||||
|
<Toolbar variant="dense" css={toolbar}>
|
||||||
|
<Stack direction="row" spacing={1} alignItems="baseline" flexGrow={1}>
|
||||||
|
<NextLink href={pagesPath.$url()} passHref>
|
||||||
|
<MuiLink variant="h6" css={topLink}>
|
||||||
|
{site.title}
|
||||||
|
</MuiLink>
|
||||||
|
</NextLink>
|
||||||
|
<Typography css={description}>
|
||||||
|
web clone of{" "}
|
||||||
|
<a href="https://devtoys.app" target="_blank" rel="noreferrer">
|
||||||
|
DevToys
|
||||||
|
</a>
|
||||||
|
</Typography>
|
||||||
|
</Stack>
|
||||||
|
<IconButton>
|
||||||
|
<a
|
||||||
|
href="https://github.com/rusconn/DevToysWeb"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
css={gitHubLink}
|
||||||
|
>
|
||||||
|
<GitHubIcon css={gitHubIcon} />
|
||||||
|
</a>
|
||||||
|
</IconButton>
|
||||||
|
</Toolbar>
|
||||||
|
</AppBar>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const Component = memo(StyledComponent);
|
||||||
|
|
||||||
|
export default Component;
|
||||||
41
src/components/layout/Layout.tsx
Normal file
41
src/components/layout/Layout.tsx
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import { Box, css, Stack } from "@mui/material";
|
||||||
|
import Head from "next/head";
|
||||||
|
import { memo, PropsWithChildren } from "react";
|
||||||
|
|
||||||
|
import { site } from "@/data";
|
||||||
|
import { staticPath } from "@/libs/$path";
|
||||||
|
|
||||||
|
import Drawer, { drawerWidth } from "./Drawer";
|
||||||
|
import Header, { headerHeight } from "./Header";
|
||||||
|
|
||||||
|
type Props = PropsWithChildren<unknown>;
|
||||||
|
|
||||||
|
const content = css`
|
||||||
|
width: calc(100vw - ${drawerWidth}px);
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
overflow: auto;
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.08);
|
||||||
|
border-top-left-radius: 8px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const StyledComponent = ({ children }: Props) => (
|
||||||
|
<>
|
||||||
|
<Head>
|
||||||
|
<title>{site.title}</title>
|
||||||
|
<link rel="icon" href={staticPath.favicon_ico} />
|
||||||
|
<meta name="description" content="DevToys web clone" />
|
||||||
|
<meta name="og:title" content={site.title} />
|
||||||
|
<meta name="og:site_name" content={site.title} />
|
||||||
|
<meta name="og:type" content="website" />
|
||||||
|
</Head>
|
||||||
|
<Header />
|
||||||
|
<Stack direction="row" height={`calc(100vh - ${headerHeight}px)`}>
|
||||||
|
<Drawer />
|
||||||
|
<Box css={content}>{children}</Box>
|
||||||
|
</Stack>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const Component = memo(StyledComponent);
|
||||||
|
|
||||||
|
export default Component;
|
||||||
67
src/components/layout/SearchBar.tsx
Normal file
67
src/components/layout/SearchBar.tsx
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
import SearchIcon from "@mui/icons-material/Search";
|
||||||
|
import { Box, css, InputBase, Paper, Theme } from "@mui/material";
|
||||||
|
import { useRouter } from "next/router";
|
||||||
|
import { ChangeEventHandler, memo, useCallback } from "react";
|
||||||
|
import { useRecoilState } from "recoil";
|
||||||
|
|
||||||
|
import { pagesPath } from "@/libs/$path";
|
||||||
|
|
||||||
|
import { searchTextState } from "./states";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
text: string;
|
||||||
|
onChange: ChangeEventHandler<HTMLInputElement>;
|
||||||
|
};
|
||||||
|
|
||||||
|
const container = css`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const input = (theme: Theme) => css`
|
||||||
|
flex: 1;
|
||||||
|
margin-left: ${theme.spacing(1)};
|
||||||
|
`;
|
||||||
|
|
||||||
|
const iconWrapper = (theme: Theme) => css`
|
||||||
|
padding: ${theme.spacing(1)};
|
||||||
|
> * {
|
||||||
|
color: rgba(0, 0, 0, 0.54);
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const StyledComponent = ({ text, onChange }: Props) => (
|
||||||
|
<Paper css={container}>
|
||||||
|
<InputBase
|
||||||
|
placeholder="Type to search for tools..."
|
||||||
|
value={text}
|
||||||
|
{...{ onChange }}
|
||||||
|
css={input}
|
||||||
|
/>
|
||||||
|
<Box css={iconWrapper}>
|
||||||
|
<SearchIcon />
|
||||||
|
</Box>
|
||||||
|
</Paper>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const Component = memo(StyledComponent);
|
||||||
|
|
||||||
|
const Container = () => {
|
||||||
|
const [text, setText] = useRecoilState(searchTextState);
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const onChange: Props["onChange"] = useCallback(
|
||||||
|
({ currentTarget: { value } }) => {
|
||||||
|
setText(value);
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
|
router.push(pagesPath.$url());
|
||||||
|
},
|
||||||
|
[setText, router]
|
||||||
|
);
|
||||||
|
|
||||||
|
return <Component {...{ text, onChange }} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Container;
|
||||||
3
src/components/layout/index.ts
Normal file
3
src/components/layout/index.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import Layout from "./Layout";
|
||||||
|
|
||||||
|
export { Layout };
|
||||||
1
src/components/layout/states/index.ts
Normal file
1
src/components/layout/states/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from "./searchText";
|
||||||
6
src/components/layout/states/searchText.ts
Normal file
6
src/components/layout/states/searchText.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { atom } from "recoil";
|
||||||
|
|
||||||
|
export const searchTextState = atom({
|
||||||
|
key: "searchText",
|
||||||
|
default: "",
|
||||||
|
});
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
export * as emotion from "./emotion";
|
export * as emotion from "./emotion";
|
||||||
export * as mui from "./mui";
|
export * as mui from "./mui";
|
||||||
|
export * as site from "./site";
|
||||||
|
|||||||
@@ -1,3 +1,20 @@
|
|||||||
import { createTheme } from "@mui/material";
|
import { createTheme } from "@mui/material";
|
||||||
|
|
||||||
export const theme = createTheme();
|
export const theme = createTheme({
|
||||||
|
palette: {
|
||||||
|
background: {
|
||||||
|
default: "#f0f3f8",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
typography: {
|
||||||
|
htmlFontSize: 10,
|
||||||
|
fontSize: 8,
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
MuiButtonBase: {
|
||||||
|
defaultProps: {
|
||||||
|
disableRipple: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|||||||
1
src/data/site.ts
Normal file
1
src/data/site.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const title = "DevToysWeb";
|
||||||
@@ -4,6 +4,7 @@ import type { AppProps } from "next/app";
|
|||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import { RecoilRoot } from "recoil";
|
import { RecoilRoot } from "recoil";
|
||||||
|
|
||||||
|
import { Layout } from "@/components/layout";
|
||||||
import { emotion, mui } from "@/data";
|
import { emotion, mui } from "@/data";
|
||||||
|
|
||||||
import "@fontsource/roboto/300.css";
|
import "@fontsource/roboto/300.css";
|
||||||
@@ -23,7 +24,9 @@ const MyApp = ({ Component, emotionCache = emotion.cache, pageProps }: MyAppProp
|
|||||||
<ThemeProvider theme={mui.theme}>
|
<ThemeProvider theme={mui.theme}>
|
||||||
<CssBaseline />
|
<CssBaseline />
|
||||||
<RecoilRoot>
|
<RecoilRoot>
|
||||||
|
<Layout>
|
||||||
<Component {...pageProps} />
|
<Component {...pageProps} />
|
||||||
|
</Layout>
|
||||||
</RecoilRoot>
|
</RecoilRoot>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
</CacheProvider>
|
</CacheProvider>
|
||||||
|
|||||||
@@ -1,16 +1,5 @@
|
|||||||
import type { NextPage } from "next";
|
import type { NextPage } from "next";
|
||||||
import Head from "next/head";
|
|
||||||
|
|
||||||
import { staticPath } from "@/libs/$path";
|
const Page: NextPage = () => <p>hello</p>;
|
||||||
|
|
||||||
const Page: NextPage = () => (
|
|
||||||
<>
|
|
||||||
<Head>
|
|
||||||
<title>DevToysWeb</title>
|
|
||||||
<link rel="icon" href={staticPath.favicon_ico} />
|
|
||||||
</Head>
|
|
||||||
<p>hello</p>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
|
|
||||||
export default Page;
|
export default Page;
|
||||||
|
|||||||
Reference in New Issue
Block a user