Skip to content
Open
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
19 changes: 11 additions & 8 deletions web/pages/_app.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import { useState } from 'react';
import '../styles/globals.css';
import '../styles/utilities.css';
import { ChakraProvider } from '@chakra-ui/react';
import Footer from '../components/Footer';
import NavBar from '../components/Navbar';
import { UserContext } from '../utils/UserContext';

function MyApp({ Component, pageProps }) {
export default function MyApp({ Component, pageProps }) {
const [user, setUser] = useState(null);
return (
<ChakraProvider>
<NavBar />
<Component {...pageProps} />
<Footer />
</ChakraProvider>
<UserContext.Provider value={{ user, setUser }}>
<ChakraProvider>
<NavBar />
<Component {...pageProps} />
<Footer />
</ChakraProvider>
</UserContext.Provider>
);
}

export default MyApp;
198 changes: 109 additions & 89 deletions web/pages/signin.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useState, useEffect, useContext } from 'react';
import { useRouter } from 'next/router';
import { Formik, Form } from 'formik';
import * as Yup from 'yup';
Expand All @@ -14,6 +14,7 @@ import {
Link,
Box,
} from '@chakra-ui/react';
import { UserContext } from '../utils/UserContext';

const initialValues = {
email: '',
Expand All @@ -26,10 +27,17 @@ const validationSchema = Yup.object().shape({
password: Yup.string().required('Required'),
});

export default function SignIn() {
export default function SignIn({ serverSideUser }) {
const Router = useRouter();
const [response, setResponse] = useState();
const { user, setUser } = useContext(UserContext);

// checks if there exists an already logged-in user
useEffect(() => {
if (serverSideUser) setUser(serverSideUser);
}, [serverSideUser]);

// on-click handler
async function onSignIn(values) {
const body = {
email: values.email,
Expand All @@ -43,10 +51,9 @@ export default function SignIn() {
body: JSON.stringify(body),
});

res = await res.json();
if (res.message == 'Login Success!') {
if (res.status === 200) {
setTimeout(() => {
Router.push('/profile');
Router.reload();
}, 1000);
}
setResponse(res);
Expand All @@ -63,92 +70,105 @@ export default function SignIn() {
spacing="1rem"
color="black"
>
<Heading>Sign In</Heading>

{response && response.message && (
<Alert
status="success"
rounded="1.5rem"
p="0.75rem 1rem"
justify="center"
align="center"
width="fit-content"
maxWidth="100%"
>
<AlertIcon />
<AlertDescription>{response.message}</AlertDescription>
</Alert>
)}

{response && response.error && (
<Alert
status="error"
rounded="1rem"
justify="center"
align="center"
width="fit-content"
>
<AlertIcon />
<AlertDescription>{response.error}</AlertDescription>
</Alert>
)}

<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={async (values, actions) => {
await onSignIn(values);
actions.setSubmitting(false);
}}
>
{({ errors, touched, isSubmitting, isValid }) => (
<Form>
<VStack justify="center" align="flex-start" spacing="0.5rem">
<CustomInputField
name="email"
label="Email"
error={errors.email}
touched={touched.email}
bg="white"
/>
<CustomInputField
name="password"
type="password"
label="Password"
error={errors.password}
touched={touched.password}
bg="white"
/>
<Box w="100%" align="center">
<Button
disabled={!isValid}
isLoading={isSubmitting}
mt="0.5rem"
colorScheme="red"
type="submit"
>
Sign In
</Button>
</Box>
</VStack>
</Form>
)}
</Formik>

<Flex justify="space-between" width="100%" direction="row">
<p>
<Link
style={{ textDecoration: 'inherit' }}
onClick={() => Router.push('/signup')}
{(user && (
<>
<Heading>Signed in as {user.email}</Heading>
<Button colorScheme="red">Sign Out</Button>
</>
)) || (
<>
<Heading>Sign In</Heading>
{response && response.message && (
<Alert
status="success"
rounded="1.5rem"
p="0.75rem 1rem"
justify="center"
align="center"
width="fit-content"
maxWidth="100%"
>
<AlertIcon />
<AlertDescription>{response.message}</AlertDescription>
</Alert>
)}
{response && response.error && (
<Alert
status="error"
rounded="1rem"
justify="center"
align="center"
width="fit-content"
>
<AlertIcon />
<AlertDescription>{response.error}</AlertDescription>
</Alert>
)}
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={async (values, actions) => {
await onSignIn(values);
actions.setSubmitting(false);
}}
>
Sign Up
</Link>
</p>
<p>
<Link style={{ textDecoration: 'inherit' }}>Forgot Password</Link>
</p>
</Flex>
{({ errors, touched, isSubmitting, isValid }) => (
<Form>
<VStack justify="center" align="flex-start" spacing="0.5rem">
<CustomInputField
name="email"
label="Email"
error={errors.email}
touched={touched.email}
bg="white"
/>
<CustomInputField
name="password"
type="password"
label="Password"
error={errors.password}
touched={touched.password}
bg="white"
/>
<Box w="100%" align="center">
<Button
disabled={!isValid}
isLoading={isSubmitting}
mt="0.5rem"
colorScheme="red"
type="submit"
>
Sign In
</Button>
</Box>
</VStack>
</Form>
)}
</Formik>
<Flex justify="space-between" width="100%" direction="row">
<p>
<Link
style={{ textDecoration: 'inherit' }}
onClick={() => Router.push('/signup')}
>
Sign Up
</Link>
</p>
<p>
<Link style={{ textDecoration: 'inherit' }}>Forgot Password</Link>
</p>
</Flex>
</>
)}
</VStack>
</Flex>
);
}

export function getServerSideProps({ req }) {
const user = req.user;
if (!user) return { props: { user: null } };
delete user.password;
delete user.createTime;
return { props: { serverSideUser: user } };
}
3 changes: 3 additions & 0 deletions web/utils/UserContext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { createContext } from 'react';

export const UserContext = createContext(null);