This repository has been archived by the owner on May 24, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #135 from SELab-2/development
merge frontend code with production
- Loading branch information
Showing
25 changed files
with
950 additions
and
284 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/** | ||
* IMPORTANT NOTE | ||
* | ||
* A certain feature of NextJS (at the time of writing, it is unclear which feature this is) causes | ||
* Recoil to throw errors because of duplicate atom keys. This of course isn't the case and it doesn't break when used. | ||
* To get around this issue, we are generating a random uuid every time this file is re-run, that way we won't get the | ||
* duplicate key warning. This seems like an unsafe way to fix this, but I can assure you, it works as intended. | ||
*/ | ||
import { atom, GetCallback, GetRecoilValue, selector } from 'recoil'; | ||
import { v4 } from 'uuid'; | ||
|
||
type UniqueAtomParams<T> = { | ||
name: string; | ||
defaultValue: T; | ||
}; | ||
|
||
export const uniqueAtom = <T>({ name, defaultValue }: UniqueAtomParams<T>) => | ||
atom({ | ||
key: `${name}/${v4()}`, | ||
default: defaultValue, | ||
}); | ||
|
||
type UniqueSelectorParams = { | ||
name: string; | ||
getter: (opts: { get: GetRecoilValue; getCallback: GetCallback }) => unknown; | ||
}; | ||
|
||
export const uniqueSelector = ({ name, getter }: UniqueSelectorParams) => | ||
selector({ | ||
key: `${name}/${v4()}`, | ||
get: getter, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { uniqueAtom, uniqueSelector } from '.'; | ||
import { customPasswordRegex, emailRegex, nameRegex } from '../lib/regex'; | ||
|
||
export const nameState = uniqueAtom({ | ||
name: 'registerNameState', | ||
defaultValue: '', | ||
}); | ||
|
||
export const validNameState = uniqueSelector({ | ||
name: 'validNameState', | ||
getter: ({ get }) => { | ||
const name = get(nameState); | ||
|
||
// we use a name Regex to check if the name is valid | ||
return nameRegex.test(name); | ||
}, | ||
}); | ||
|
||
export const emailState = uniqueAtom({ | ||
name: 'registerEmailState', | ||
defaultValue: '', | ||
}); | ||
|
||
export const validEmailState = uniqueSelector({ | ||
name: 'validEmailState', | ||
getter: ({ get }) => { | ||
const email = get(emailState); | ||
|
||
// we use an email Regex to check if the email is valid | ||
return emailRegex.test(email); | ||
}, | ||
}); | ||
|
||
export const passwordState = uniqueAtom({ | ||
name: 'registerPasswordState', | ||
defaultValue: '', | ||
}); | ||
|
||
export const validPasswordState = uniqueSelector({ | ||
name: 'validPasswordState', | ||
getter: ({ get }) => { | ||
const password = get(passwordState); | ||
|
||
// we use a password Regex to check if we are dealing with a valid password | ||
return customPasswordRegex.test(password); | ||
}, | ||
}); | ||
|
||
export const repeatPasswordState = uniqueAtom({ | ||
name: 'registerRepeatPasswordState', | ||
defaultValue: '', | ||
}); | ||
|
||
export const validRepeatPasswordState = uniqueSelector({ | ||
name: 'validRepeatPasswordState', | ||
getter: ({ get }) => { | ||
const password = get(passwordState); | ||
const repeatPassword = get(repeatPasswordState); | ||
|
||
// check if it's a valid password and the same as the first password | ||
return ( | ||
customPasswordRegex.test(repeatPassword) && password === repeatPassword | ||
); | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import type { FC, PropsWithChildren } from 'react'; | ||
|
||
/** | ||
* Parameters for FormContainer Component | ||
* {@label FormContainerProps} | ||
* | ||
* @see PropsWithChildren | ||
*/ | ||
type FormContainerProps = PropsWithChildren<{ | ||
/** | ||
* Title of the page that is being displayed | ||
*/ | ||
pageTitle: string; | ||
}>; | ||
|
||
/** | ||
* Container for register and login forms | ||
* | ||
* @remarks | ||
* This is a container with 2 colums with 2 images on either side of a central form, | ||
* which is passed as a child component. | ||
* | ||
* {@label FormContainer} | ||
* | ||
* @see {@link FormContainerProps} | ||
*/ | ||
const FormContainer: FC<FormContainerProps> = ({ pageTitle, children }) => { | ||
return ( | ||
<> | ||
<div className="h-screen bg-[url('../public/img/login.png')] bg-center"> | ||
{/* Left side images */} | ||
<div | ||
className="lg:rounded-5xl relative top-1/2 m-auto flex w-11/12 max-w-md -translate-y-1/2 flex-col items-center | ||
rounded-md bg-[#F3F3f3] px-4 py-4 text-center | ||
md:w-11/12 lg:grid lg:w-10/12 lg:max-w-7xl lg:grid-cols-2 lg:gap-2 xl:grid-cols-3" | ||
> | ||
<div className="hidden max-w-lg place-self-center xl:block"> | ||
<img | ||
src="https://osoc.be/img/pictures/osoc17-1.jpg" | ||
alt="image of 4 people posing in front of a wall with post-its" | ||
className="object-scale-down shadow-sm shadow-gray-600 xl:mb-4" | ||
/> | ||
<img | ||
src="https://i0.wp.com/blog.okfn.org/files/2018/08/image3.jpg?fit=1200%2C800&ssl=1" | ||
alt="Group of people cheering on OSOC" | ||
className="object-scale-down shadow-sm shadow-gray-600" | ||
/> | ||
</div> | ||
{/* Main form component */} | ||
<div className="flex max-h-full max-w-full flex-col items-center justify-center"> | ||
<header className="flex flex-row items-center justify-center gap-4 pb-5 lg:align-top"> | ||
<h1 className="float-left text-3xl font-bold text-osoc-blue sm:text-4xl"> | ||
{pageTitle} | ||
</h1> | ||
<img | ||
src="https://osoc.be/img/logo/logo-osoc-color.svg" | ||
className="hidden h-16 w-16 sm:inline-block md:h-24 md:w-24 lg:h-32 lg:w-32" | ||
alt="The OSOC logo" | ||
/> | ||
</header> | ||
|
||
{children} | ||
</div> | ||
{/* Right side images */} | ||
<div className="hidden max-w-lg place-self-center lg:block"> | ||
<img | ||
src="https://osoc.be/img/pictures/osoc17-2.jpg" | ||
alt="image of 4 people standing around a wall with post-its" | ||
className="object-scale-down shadow-sm shadow-gray-600 lg:mb-4" | ||
/> | ||
<img | ||
src="https://osoc.be/img/pictures/osoc17-3.jpg" | ||
alt="image of someone trying to give you a fistbump" | ||
className="object-scale-down shadow-sm shadow-gray-600" | ||
/> | ||
</div> | ||
</div> | ||
</div> | ||
</> | ||
); | ||
}; | ||
|
||
export default FormContainer; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
const envURL: string = process.env.NEXT_PUBLIC_API_ENDPOINT || ''; | ||
const baseURL = envURL.replace(/\/$/, ''); | ||
|
||
/** | ||
* Typescript doesn't allow computed enums, this is a little work-around to get the required functionality | ||
*/ | ||
type Endpoints = typeof Endpoints[keyof typeof Endpoints]; | ||
const Endpoints = { | ||
USERS: baseURL + '/users', | ||
LOGIN: baseURL + '/login', | ||
} as const; | ||
|
||
export default Endpoints; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
// source: https://stackoverflow.com/questions/2385701/regular-expression-for-first-and-last-name | ||
export const nameRegex = | ||
/^[a-zA-ZàáâäãåąčćęèéêëėįìíîïłńòóôöõøùúûüųūÿýżźñçčšžÀÁÂÄÃÅĄĆČĖĘÈÉÊËÌÍÎÏĮŁŃÒÓÔÖÕØÙÚÛÜŲŪŸÝŻŹÑßÇŒÆČŠŽ∂ð ,.'-]+$/u; | ||
// source: https://stackoverflow.com/questions/201323/how-can-i-validate-an-email-address-using-a-regular-expression | ||
/* eslint-disable */ | ||
export const emailRegex = | ||
/(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/; | ||
|
||
// A password can exist out of any characters, as long as it is between length 8 and 64 | ||
export const customPasswordRegex = /^.{8,64}$/; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,19 @@ | ||
import '../styles/globals.css'; | ||
import '../styles/line.css'; | ||
import type { AppProps } from 'next/app'; | ||
import { RecoilRoot } from 'recoil'; | ||
import { Toaster } from 'react-hot-toast'; | ||
|
||
function MyApp({ Component, pageProps }: AppProps) { | ||
return <Component {...pageProps} />; | ||
function App({ Component, pageProps: { pageProps } }: AppProps) { | ||
return ( | ||
<> | ||
{/* RecoilRoot exposes the whole application to the Recoil state manager */} | ||
<RecoilRoot> | ||
<Component {...pageProps} /> | ||
<Toaster position="top-right" /> | ||
</RecoilRoot> | ||
</> | ||
); | ||
} | ||
|
||
export default MyApp; | ||
export default App; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { NextApiRequest } from 'next'; | ||
import { NextRequest, NextResponse } from 'next/server'; | ||
|
||
/* | ||
* A 'hacky' way to get around the next typing issues for middelware | ||
*/ | ||
type NextMiddlewareRequest = NextApiRequest & NextRequest; | ||
|
||
/** | ||
* Middleware for every Next request | ||
* | ||
* @param req - the incoming Next request | ||
* @returns a NextResponse object containing the next step | ||
*/ | ||
export async function middleware(req: NextMiddlewareRequest) { | ||
// Token will exist if user is logged in | ||
const token = ''; | ||
console.log(req); | ||
|
||
const { pathname } = req.nextUrl; | ||
|
||
/** | ||
* We allow the request to be made if: | ||
* - It contains a valid token (which means the user is logged in) | ||
*/ | ||
|
||
// clone the url to use in the redirect because NextJS 12.1 does not allow relative URLs anymore | ||
const url = req.nextUrl.clone(); | ||
url.pathname = '/login'; | ||
|
||
// if the request is trying to access protected resources, we redirect them to the login | ||
// TODO: remove /wait page filter when accounts are working | ||
if ( | ||
!token && | ||
!(pathname === '/login' || pathname === '/register' || pathname === '/wait') | ||
) { | ||
return NextResponse.redirect(url); | ||
} | ||
} |
Oops, something went wrong.