Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create login page #10

Merged
merged 4 commits into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions __tests__/pages/landing.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import '@testing-library/jest-dom';
import { render, screen } from '@testing-library/react';
import Home from '@/app/page';

it('renders main page with the text "Get started by editing"', () => {
it('renders 6 change logs', () => {
render(<Home />);
const login = screen.getAllByText(/\bLogin\b/i).length;
expect(login).toBe(2);

const register = screen.getAllByText(/\bRegister\b/i).length;
expect(register).toBe(2);
// Finds all p tags with date logs
const numListItems = screen
.getByTestId('changelog')
.querySelectorAll('p').length;
expect(numListItems).toBe(6);
});
10 changes: 8 additions & 2 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import type { Metadata } from 'next';
import { AppRouterCacheProvider } from '@mui/material-nextjs/v13-appRouter';
import { ThemeProvider } from '@mui/material';
import { Container, ThemeProvider } from '@mui/material';
import theme from '../theme';
import './globals.css';
import Navigation from '@/components/Navigation';

export const metadata: Metadata = {
title: 'Bibimbap',
Expand All @@ -18,7 +19,12 @@ export default function RootLayout({
<html lang='en'>
<body>
<AppRouterCacheProvider>
<ThemeProvider theme={theme}>{children}</ThemeProvider>
<ThemeProvider theme={theme}>
<Container component='main'>
<Navigation />
{children}
</Container>
</ThemeProvider>
</AppRouterCacheProvider>
</body>
</html>
Expand Down
25 changes: 25 additions & 0 deletions src/app/login/SubmitBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
'use client';
import { FormEvent } from 'react';
import { Box } from '@mui/material';

// This file holds the handling logic for the login form submission.
export default function LoginSubmitBox({
children,
}: {
children: React.ReactNode;
}) {
const handleSubmit = (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
const data = new FormData(event.currentTarget);
console.log({
email: data.get('email'),
password: data.get('password'),
});
};

return (
<Box component='form' onSubmit={handleSubmit} noValidate sx={{ mt: 1 }}>
{children}
</Box>
);
}
83 changes: 83 additions & 0 deletions src/app/login/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import {
Avatar,
Box,
Button,
Checkbox,
FormControlLabel,
Grid,
TextField,
Typography,
} from '@mui/material';
import { LockOutlined } from '@mui/icons-material';
import Copyright from '@/components/Copyright';
import CustomLink from '@/components/CustomLink';
import LoginSubmitBox from './SubmitBox';

export default function Login() {
return (
<>
<Box
sx={{
mt: 8,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
}}
>
<Avatar sx={{ m: 1, bgcolor: 'secondary.main' }}>
<LockOutlined />
</Avatar>
<Typography component='h1' variant='h5'>
Login
</Typography>
<LoginSubmitBox>
<TextField
margin='normal'
required
fullWidth
id='email'
label='Email Address'
name='email'
autoComplete='email'
autoFocus
/>
<TextField
margin='normal'
required
fullWidth
name='password'
label='Password'
type='password'
id='password'
autoComplete='current-password'
/>
<FormControlLabel
control={<Checkbox value='remember' color='primary' />}
label='Remember me'
/>
<Button
type='submit'
fullWidth
variant='contained'
sx={{ mt: 3, mb: 2 }}
>
Login
</Button>
<Grid container>
<Grid item xs>
<CustomLink href='#' variant='body2'>
Forgot password?
</CustomLink>
</Grid>
<Grid item>
<CustomLink href='/register' variant='body2'>
{"Don't have an account? Sign Up"}
</CustomLink>
</Grid>
</Grid>
</LoginSubmitBox>
</Box>
<Copyright sx={{ mt: 8, mb: 4 }} />
</>
);
}
69 changes: 32 additions & 37 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import Navigation from '@/components/Navigation';
import { Container, Paper, Stack, Typography } from '@mui/material';
import { Paper, Stack, Typography } from '@mui/material';

export default function Home() {
const serviceSummary = {
Expand All @@ -17,45 +16,41 @@ export default function Home() {
];

return (
<Container component='main'>
<Navigation />
<Stack direction={{ sm: 'column', md: 'row' }} gap={2} mt={2}>
<Stack direction={{ sm: 'column', md: 'row' }} gap={2} mt={2}>
<Paper sx={{ p: 2 }} elevation={3}>
<Typography variant='body1'>
The mission of Polygon is to provide platform for creation of
programming contest problems. Polygon supports the whole development
cycle:
</Typography>
<ul className='list-disc list-inside'>
<li>problem statement writing</li>
<li>test data preparing (generators supported)</li>
<li>model solutions (including correct and wittingly incorrect)</li>
<li>judging</li>
<li>automatic validation</li>
</ul>
</Paper>
<Stack direction='column' gap={2}>
<Paper sx={{ p: 2 }} elevation={3}>
<Typography variant='body1'>
The mission of Polygon is to provide platform for creation of
programming contest problems. Polygon supports the whole development
cycle:
<Typography variant='body2'>
Registered users: {serviceSummary.numUsers}
</Typography>
<Typography variant='body2'>
Problems total: {serviceSummary.numProblems}
</Typography>
<Typography variant='body2'>
Invokers waiting: {serviceSummary.numInvokers}
</Typography>
{/* The following has to have a list using Tailwind CSS */}
<ul className='list-disc list-inside'>
<li>problem statement writing</li>
<li>test data preparing (generators supported)</li>
<li>model solutions (including correct and wittingly incorrect)</li>
<li>judging</li>
<li>automatic validation</li>
</ul>
</Paper>
<Stack direction='column' gap={2}>
<Paper sx={{ p: 2 }} elevation={3}>
<Typography variant='body2'>
Registered users: {serviceSummary.numUsers}
</Typography>
<Typography variant='body2'>
Problems total: {serviceSummary.numProblems}
<Paper sx={{ p: 2 }} elevation={3} data-testid='changelog'>
{changeLogs.map((log, index) => (
<Typography key={index} variant='body2'>
{log}
</Typography>
<Typography variant='body2'>
Invokers waiting: {serviceSummary.numInvokers}
</Typography>
</Paper>
<Paper sx={{ p: 2 }} elevation={3}>
{changeLogs.map((log, index) => (
<Typography key={index} variant='body2'>
{log}
</Typography>
))}
</Paper>
</Stack>
))}
</Paper>
</Stack>
</Container>
</Stack>
);
}
20 changes: 20 additions & 0 deletions src/components/Copyright.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Typography } from '@mui/material';
import CustomLink from '@/components/CustomLink';

export default function Copyright(props: any) {
return (
<Typography
variant='body2'
color='text.secondary'
align='center'
{...props}
>
{'Copyright © '}
<CustomLink color='inherit' href='https://mui.com/'>
Bibimbap
</CustomLink>{' '}
{new Date().getFullYear()}
{'.'}
</Typography>
);
}
18 changes: 18 additions & 0 deletions src/components/CustomLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import NextLink, { LinkProps as NextLinkProps } from 'next/link';
import { Link as MUILink, LinkProps as MUILinkProps } from '@mui/material';

type CustomLinkProps = NextLinkProps & MUILinkProps;

export default function CustomLink(props: CustomLinkProps) {
const { href, ...others } = props;

return (
<MUILink
color='inherit'
underline='none'
component={NextLink}
href={href}
{...others}
/>
);
}
33 changes: 23 additions & 10 deletions src/components/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
} from '@mui/material';
import Image from 'next/image';
import { useState } from 'react';
import CustomLink from './CustomLink';

interface Props {
/**
Expand All @@ -26,7 +27,11 @@ interface Props {
}

const drawerWidth = 240;
const navItems = ['Login', 'Register', 'Help'];
const navItems = [
{ name: 'Login', link: '/login' },
{ name: 'Register', link: '/register' },
{ name: 'Help', link: '/help' },
];

export default function Navigation(props: Props) {
const { window } = props;
Expand All @@ -44,9 +49,13 @@ export default function Navigation(props: Props) {
<Divider />
<List>
{navItems.map((item) => (
<ListItem key={item} disablePadding>
<ListItemButton sx={{ textAlign: 'center' }}>
<ListItemText primary={item} />
<ListItem key={item.name} disablePadding>
<ListItemButton
component='a'
href={item.link}
sx={{ textAlign: 'center' }}
>
<ListItemText primary={item.name} />
</ListItemButton>
</ListItem>
))}
Expand All @@ -70,18 +79,22 @@ export default function Navigation(props: Props) {
>
<Menu />
</IconButton>
<Image src='/logo.png' alt='logo' width={64} height={64} />
<Typography

<CustomLink href='/'>
{' '}
<Image src='/logo.png' alt='logo' width={64} height={64} />
</CustomLink>
<CustomLink
href='/'
variant='h6'
component='div'
sx={{ flexGrow: 1, display: { xs: 'none', sm: 'block' }, ml: 2 }}
>
Bibimbap
</Typography>
</CustomLink>
<Box sx={{ display: { xs: 'none', sm: 'block' } }}>
{navItems.map((item) => (
<Button key={item} sx={{ color: '#fff' }}>
{item}
<Button key={item.name} sx={{ color: '#fff' }} href={item.link}>
{item.name}
</Button>
))}
</Box>
Expand Down