Browse Source

feat: add layout

hover-contact
ntasicc 3 years ago
parent
commit
9221d455d9

+ 12
- 0
components/layout/base-layout/Layout.jsx View File

@@ -0,0 +1,12 @@
import Navbar from '../navbar/Navbar';

function Layout(props) {
return (
<>
<Navbar />
<main>{props.children}</main>
</>
);
}

export default Layout;

+ 7
- 0
components/layout/base-layout/Layout.mock.js View File

@@ -0,0 +1,7 @@
const base = {
children: <h1>Test</h1>,
};

export const mockLayoutProps = {
base,
};

+ 20
- 0
components/layout/base-layout/Layout.stories.jsx View File

@@ -0,0 +1,20 @@
import Layout from './Layout';
import { mockLayoutProps } from './Layout.mock';

const obj = {
title: 'layout/Navbar',
component: Layout,
// More on argTypes: https://storybook.js.org/docs/react/api/argtypes
argTypes: {},
}; //eslint-disable-line

export default obj;
// More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args
const Template = (args) => <Layout {...args} />;

export const Base = Template.bind({});
// More on args: https://storybook.js.org/docs/react/writing-stories/args

Base.args = {
...mockLayoutProps.base,
};

+ 203
- 0
components/layout/navbar/Navbar.jsx View File

@@ -0,0 +1,203 @@
import AdbIcon from '@mui/icons-material/Adb';
import MenuIcon from '@mui/icons-material/Menu';
import AppBar from '@mui/material/AppBar';
import Avatar from '@mui/material/Avatar';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import Container from '@mui/material/Container';
import IconButton from '@mui/material/IconButton';
import Menu from '@mui/material/Menu';
import MenuItem from '@mui/material/MenuItem';
import Toolbar from '@mui/material/Toolbar';
import Tooltip from '@mui/material/Tooltip';
import Typography from '@mui/material/Typography';
import { signOut, useSession } from 'next-auth/react';
import Link from 'next/link';
import { useState } from 'react';
import { LOGIN_PAGE, PROFILE_PAGE } from '../../../constants/pages';

const pages = ['Link 1', 'Link 2', 'Link 3'];

const Navbar = () => {
const { data: session } = useSession();
const [anchorElNav, setAnchorElNav] = useState(null);
const [anchorElUser, setAnchorElUser] = useState(null);

const handleOpenNavMenu = (event) => {
setAnchorElNav(event.currentTarget);
};
const handleOpenUserMenu = (event) => {
setAnchorElUser(event.currentTarget);
};

const handleCloseNavMenu = () => {
setAnchorElNav(null);
};

const handleCloseUserMenu = () => {
setAnchorElUser(null);
};

function logoutHandler() {
signOut();
}

console.log(session);
return (
<AppBar position="static">
<Container maxWidth="xl">
<Toolbar disableGutters>
<AdbIcon sx={{ display: { xs: 'none', md: 'flex' }, mr: 1 }} />
<Typography
variant="h6"
noWrap
sx={{
mr: 2,
display: { xs: 'none', md: 'flex' },
fontFamily: 'monospace',
fontWeight: 700,
letterSpacing: '.3rem',
color: 'inherit',
textDecoration: 'none',
}}
>
LOGO
</Typography>

<Box sx={{ flexGrow: 1, display: { xs: 'flex', md: 'none' } }}>
<IconButton
size="large"
aria-label="account of current user"
aria-controls="menu-appbar"
aria-haspopup="true"
onClick={handleOpenNavMenu}
color="inherit"
>
<MenuIcon />
</IconButton>
<Menu
id="menu-appbar"
anchorEl={anchorElNav}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
keepMounted
transformOrigin={{
vertical: 'top',
horizontal: 'left',
}}
open={Boolean(anchorElNav)}
onClose={handleCloseNavMenu}
sx={{
display: { xs: 'block', md: 'none' },
}}
>
{pages.map((page) => (
<MenuItem key={page} onClick={handleCloseNavMenu}>
<Typography textAlign="center">{page}</Typography>
</MenuItem>
))}
</Menu>
</Box>
<AdbIcon sx={{ display: { xs: 'flex', md: 'none' }, mr: 1 }} />
<Typography
variant="h5"
noWrap
component="a"
href=""
sx={{
mr: 2,
display: { xs: 'flex', md: 'none' },
flexGrow: 1,
fontFamily: 'monospace',
fontWeight: 700,
letterSpacing: '.3rem',
color: 'inherit',
textDecoration: 'none',
}}
>
LOGO
</Typography>
<Box sx={{ flexGrow: 1, display: { xs: 'none', md: 'flex' } }}>
{pages.map((page) => (
<Button
key={page}
onClick={handleCloseNavMenu}
sx={{ my: 2, color: 'white', display: 'block' }}
>
{page}
</Button>
))}
</Box>

<Box sx={{ flexGrow: 0 }}>
{session ? (
<>
<Tooltip title="Open settings">
<IconButton onClick={handleOpenUserMenu} sx={{ p: 0 }}>
<Avatar
alt="Profile picture"
src="https://www.business2community.com/wp-content/uploads/2017/08/blank-profile-picture-973460_640.png"
/>
</IconButton>
</Tooltip>
<Menu
sx={{ mt: '45px' }}
id="menu-appbar"
anchorEl={anchorElUser}
anchorOrigin={{
vertical: 'top',
horizontal: 'right',
}}
keepMounted
transformOrigin={{
vertical: 'top',
horizontal: 'right',
}}
open={Boolean(anchorElUser)}
onClose={handleCloseUserMenu}
>
<MenuItem onClick={handleCloseUserMenu}>
<Link href={PROFILE_PAGE}>
<a
style={{
textDecoration: 'none',
color: 'inherit',
fontSize: 15,
marginLeft: 6,
}}
>
PROFILE
</a>
</Link>
</MenuItem>
<MenuItem onClick={handleCloseUserMenu}>
<Button color="inherit" onClick={logoutHandler}>
Logout
</Button>
</MenuItem>
</Menu>
</>
) : (
<Button color="inherit">
<Link href={LOGIN_PAGE}>
<a
style={{
textDecoration: 'none',
color: 'inherit',
fontSize: 17,
}}
>
Login
</a>
</Link>
</Button>
)}
</Box>
</Toolbar>
</Container>
</AppBar>
);
};
export default Navbar;

+ 5
- 0
components/layout/navbar/Navbar.mock.js View File

@@ -0,0 +1,5 @@
const base = {};

export const mockNavbarProps = {
base,
};

+ 20
- 0
components/layout/navbar/Navbar.stories.jsx View File

@@ -0,0 +1,20 @@
import Navbar from './Navbar';
import { mockNavbarProps } from './Navbar.mock';

const obj = {
title: 'layout/Navbar',
component: Navbar,
// More on argTypes: https://storybook.js.org/docs/react/api/argtypes
argTypes: {},
}; //eslint-disable-line

export default obj;
// More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args
const Template = (args) => <Navbar {...args} />;

export const Base = Template.bind({});
// More on args: https://storybook.js.org/docs/react/writing-stories/args

Base.args = {
...mockNavbarProps.base,
};

+ 11
- 1
pages/_app.js View File

@@ -6,7 +6,9 @@ import {
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import { SessionProvider } from 'next-auth/react';
import { appWithTranslation } from 'next-i18next';
import Head from 'next/head';
import { useState } from 'react';
import Layout from '../components/layout/base-layout/Layout';
import '../styles/globals.css';

function MyApp({ Component, pageProps: { session, ...pageProps } }) {
@@ -16,7 +18,15 @@ function MyApp({ Component, pageProps: { session, ...pageProps } }) {
<QueryClientProvider client={queryClient}>
<Hydrate state={pageProps.dehydratedState}>
<SessionProvider session={session}>
<Component {...pageProps} />
<Layout>
<Head>
<meta
name="viewport"
content="width=device-width, initial-scale=1"
/>
</Head>
<Component {...pageProps} />
</Layout>
</SessionProvider>
<ReactQueryDevtools initialIsOpen={false} />
</Hydrate>

+ 17
- 0
pages/_document.js View File

@@ -0,0 +1,17 @@
import Document, { Head, Html, Main, NextScript } from 'next/document';

class MyDocument extends Document {
render() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}

export default MyDocument;

+ 0
- 5
pages/index.js View File

@@ -1,16 +1,11 @@
import { dehydrate, QueryClient } from '@tanstack/react-query';
import { signOut } from 'next-auth/react';
import PaginationComponentRQ from '../components/pagination/react-query/PaginationComponentRQ';
import { getData } from '../requests/dataRequest';

const Home = () => {
function logoutHandler() {
signOut();
}
return (
<>
<h1>Home</h1>
<button onClick={logoutHandler}>Logout</button>
<PaginationComponentRQ></PaginationComponentRQ>
</>
);

+ 1
- 0
styles/globals.css View File

@@ -2,6 +2,7 @@

* {
box-sizing: border-box;
margin: 0;
}

body {

Loading…
Cancel
Save