diff --git a/src/App.md b/src/App.md new file mode 100644 index 0000000000000000000000000000000000000000..2f0c205bd7beeed9e23ceded925f6a131e6efa9c --- /dev/null +++ b/src/App.md @@ -0,0 +1,5 @@ +The folders are divided basing on if the user is authenticated or not authenticated. +For this, the pages are organized as: +- AuthUser: private pages (for authenticated users). + Those pages must be covered by a PrivateRoute except for SignInForm and SignUpForm. +- NonAuthUser: public pages, require a normal Route. \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx index ca7cc5c6f16bbfbd147a2af13f9ccb88051bbdc6..fcee4551d310dcfc39201a1e3b865b0aafa0b482 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,14 +1,14 @@ import React, { FC, useEffect, useState } from 'react'; import { BrowserRouter as Router, Switch, Route } from 'react-router-dom'; -import { HomePage } from 'components/HomePage/HomePage'; +import { HomePage } from 'components/AuthUser/HomePage/HomePage'; import { AuthUser } from 'components/AuthUser/AuthUser'; -import { LandingPage } from 'components/LandingPage/LandingPage'; -import { PrivateRoute } from 'components/api/PrivateRoute/PrivateRoute'; -import { AuthRoutes, NonAuthRoutes } from 'components/api/routes'; -import { NotFound } from 'components/NotFound/NotFound'; -import { ProfilePage } from 'components/ProfilePage/ProfilePage'; -import { Roles } from 'components/api/userRoles'; -import { Unauthorized } from 'components/Unauthorized/Unauthorized'; +import { LandingPage } from 'components/NonAuthUser/LandingPage/LandingPage'; +import { PrivateRoute } from 'api/PrivateRoute/PrivateRoute'; +import { AuthRoutes, NonAuthRoutes } from 'api/routes'; +import { NotFound } from 'components/NonAuthUser/NotFound/NotFound'; +import { ProfilePage } from 'components/AuthUser/ProfilePage/ProfilePage'; +import { Roles } from 'api/userRoles'; +import { Unauthorized } from 'components/NonAuthUser/Unauthorized/Unauthorized'; import axios from 'axios'; const configDjangoCookieName = (): void => { @@ -30,7 +30,7 @@ export const App: FC = () => { return null; }; if (!isCookieFetched) fetchCookie(); - }, []); + }, [isCookieFetched]); return ( <Router> diff --git a/src/api/EntryPoint.ts b/src/api/EntryPoint.ts new file mode 100644 index 0000000000000000000000000000000000000000..c3ef802d60c206998c340867a068aa11769eff33 --- /dev/null +++ b/src/api/EntryPoint.ts @@ -0,0 +1,8 @@ +/** + * Contains server api entrypoints. + * Every server api call must be defined here and then used in the code. + */ +export enum EntryPoint { + login = '/api/web/login', + seniors = 'api/web/seniors/', +} diff --git a/src/components/api/PrivateRoute/PrivateRoute.tsx b/src/api/PrivateRoute/PrivateRoute.tsx similarity index 96% rename from src/components/api/PrivateRoute/PrivateRoute.tsx rename to src/api/PrivateRoute/PrivateRoute.tsx index e9e431cbf88b9a481bc95016c3729a2f30a0c9e9..95065f08148704ad25986fd8cfd369e73ed5e387 100644 --- a/src/components/api/PrivateRoute/PrivateRoute.tsx +++ b/src/api/PrivateRoute/PrivateRoute.tsx @@ -1,7 +1,7 @@ import React, { useState, useEffect } from 'react'; import axios from 'axios'; import { Route, Redirect, RouteProps } from 'react-router-dom'; -import { NonAuthRoutes } from 'components/api/routes'; +import { NonAuthRoutes } from 'api/routes'; /** * A wrapper for <Route> that redirects to the login screen if you're not yet authenticated. diff --git a/src/components/api/routes.ts b/src/api/routes.ts similarity index 100% rename from src/components/api/routes.ts rename to src/api/routes.ts diff --git a/src/components/api/userRoles.ts b/src/api/userRoles.ts similarity index 100% rename from src/components/api/userRoles.ts rename to src/api/userRoles.ts diff --git a/src/components/AuthUser/AuthUser.tsx b/src/components/AuthUser/AuthUser.tsx index 7ce456866dba108167b96450887eeb910db605a1..dbac120b9f286d191b9d771a329786e62823407f 100644 --- a/src/components/AuthUser/AuthUser.tsx +++ b/src/components/AuthUser/AuthUser.tsx @@ -1,7 +1,7 @@ import React, { FC } from 'react'; import Container from '@material-ui/core/Container'; import { Route, useRouteMatch } from 'react-router-dom'; -import { NonAuthRoutes } from 'components/api/routes'; +import { NonAuthRoutes } from 'api/routes'; import { SignInForm } from 'components/AuthUser/SignInForm/SignInForm'; import { SignUpForm } from 'components/AuthUser/SignUpForm/SignUpForm'; diff --git a/src/components/HomePage/HomePage.tsx b/src/components/AuthUser/HomePage/HomePage.tsx similarity index 100% rename from src/components/HomePage/HomePage.tsx rename to src/components/AuthUser/HomePage/HomePage.tsx diff --git a/src/components/ProfilePage/ProfilePage.test.tsx b/src/components/AuthUser/ProfilePage/ProfilePage.test.tsx similarity index 100% rename from src/components/ProfilePage/ProfilePage.test.tsx rename to src/components/AuthUser/ProfilePage/ProfilePage.test.tsx diff --git a/src/components/ProfilePage/ProfilePage.tsx b/src/components/AuthUser/ProfilePage/ProfilePage.tsx similarity index 90% rename from src/components/ProfilePage/ProfilePage.tsx rename to src/components/AuthUser/ProfilePage/ProfilePage.tsx index 2fe6808acc4b7876ad3bc9730c53f78b1d11547d..bf861488aa174e961acf0ed49550801a956b4249 100644 --- a/src/components/ProfilePage/ProfilePage.tsx +++ b/src/components/AuthUser/ProfilePage/ProfilePage.tsx @@ -1,7 +1,7 @@ import React, { FC } from 'react'; import Button from '@material-ui/core/Button'; import axios from 'axios'; -import { NonAuthRoutes } from 'components/api/routes'; +import { NonAuthRoutes } from 'api/routes'; import { useHistory } from 'react-router-dom'; export const ProfilePage: FC = () => { diff --git a/src/components/AuthUser/SignInForm/SignInForm.tsx b/src/components/AuthUser/SignInForm/SignInForm.tsx index 87895d6421d7b4145c12a1f6acb8c3837eeca1ac..841da5cfe07dadc39bb09406e0381d903730e96b 100644 --- a/src/components/AuthUser/SignInForm/SignInForm.tsx +++ b/src/components/AuthUser/SignInForm/SignInForm.tsx @@ -4,19 +4,19 @@ import { SubmitHandler, useForm } from 'react-hook-form'; import { Button } from '@material-ui/core'; import { InputField } from 'components/AuthUser/InputField/InputField'; import { useHistory } from 'react-router-dom'; -import { AuthRoutes } from 'components/api/routes'; +import { AuthRoutes } from 'api/routes'; import { useStyles } from './useStyles'; export const SignInForm: FC = () => { const history = useHistory(); interface FormData { - email: string; + username: string; password: string; } const defaultValues: FormData = { - email: '', + username: '', password: '', }; @@ -29,8 +29,9 @@ export const SignInForm: FC = () => { .post( '/api/web/login', { - username: values.email, + username: values.username, password: values.password, + csrfmiddlewaretoken: sessionStorage.getItem('X-CSRFTOKEN'), }, { headers: { @@ -40,9 +41,9 @@ export const SignInForm: FC = () => { ) .then((response) => { if (response.data.status === 'fail') { - setError('email', { + setError('username', { type: 'server', - message: 'Something went wrong with email', + message: 'Something went wrong with username', }); setError('password', { type: 'server', @@ -63,19 +64,17 @@ export const SignInForm: FC = () => { data-testid="Form" > <InputField - name="email" + name="username" control={control} rules={{ - validate: (value: string) => - /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(value), required: { value: true, - message: 'Email is not valid', + message: 'Username is not valid', }, }} - label="Email" - error={!!errors.email} - errorMessage="Insert email" + label="username" + error={!!errors.username} + errorMessage="Insert username" /> <InputField diff --git a/src/components/AuthUser/SignUpForm/SignUpForm.tsx b/src/components/AuthUser/SignUpForm/SignUpForm.tsx index b38fdabc87a838ad7838bf22f93bc0ab395eb6cf..0cf10dcf6197041be8469483c4536807e9956ec7 100644 --- a/src/components/AuthUser/SignUpForm/SignUpForm.tsx +++ b/src/components/AuthUser/SignUpForm/SignUpForm.tsx @@ -13,48 +13,42 @@ export const SignUpForm: FC = () => { firstName: string; lastName: string; email: string; + phoneNumber: number; + address: number; + name: string; + memberCardNumber: number; + notes: string; }; - const defaultValues: FormData = { - username: '', - password: '', - firstName: '', - lastName: '', - email: '', - }; - - const { control, errors, handleSubmit } = useForm<FormData>({ - defaultValues, - }); + const { control, errors, handleSubmit } = useForm<FormData>(); const onSubmit: SubmitHandler<FormData> = (values: FormData) => { - axios - .post( - '/api/web/seniors/', - { - user: { - username: 'test', - password: values.password, - firstName: 'a', - lastName: 'b', - email: values.email, - }, - phone_number: '213432234', - home_address: { - address: 'test street, 3', - }, - member_card_issuer: { - name: 'test issuer', - }, - member_card_number: '33333333333', + axios.post( + '/api/web/seniors/', + { + user: { + username: values.username, + password: values.password, + firstName: values.firstName, + lastName: values.lastName, + email: values.email, + }, + phone_number: values.phoneNumber, + home_address: { + address: values.address, }, - { - headers: { - 'Content-Type': 'application/json', - }, + member_card_issuer: { + name: values.memberCardNumber, }, - ) - .then((res) => console.log(res)); + member_card_number: values.memberCardNumber, + notes: values.notes, + }, + { + headers: { + 'Content-Type': 'application/json', + }, + }, + ); }; const classes = useStyles(); @@ -96,6 +90,110 @@ export const SignUpForm: FC = () => { error={!!errors.password} errorMessage="Insert valid password" /> + + <InputField + name="username" + control={control} + rules={{ + maxLength: 150, + required: { + value: true, + message: 'Insert valid username', + }, + }} + label="Username" + error={!!errors.username} + errorMessage="Insert valid username" + /> + + <InputField + name="firstName" + control={control} + rules={{ + maxLength: 150, + required: { + value: true, + message: 'Insert valid first name', + }, + }} + label="First name" + error={!!errors.firstName} + errorMessage="Insert valid first name" + /> + + <InputField + name="lastName" + control={control} + rules={{ + maxLength: 150, + required: { + value: true, + message: 'Insert valid last name', + }, + }} + label="Last name" + error={!!errors.lastName} + errorMessage="Insert valid last name" + /> + + <InputField + name="address" + control={control} + rules={{ + required: { + value: true, + message: 'Insert valid address', + }, + }} + label="Address" + error={!!errors.address} + errorMessage="Insert valid address" + /> + + <InputField + name="phoneNumber" + control={control} + rules={{ + maxLength: 15, + required: { + value: true, + message: 'Insert valid phone number', + }, + }} + label="Phone number" + error={!!errors.phoneNumber} + errorMessage="Insert valid phone number" + /> + + <InputField + name="memberCardNumber" + control={control} + rules={{ + maxLength: 20, + required: { + value: true, + message: 'Insert valid card number', + }, + }} + label="Card number" + error={!!errors.memberCardNumber} + errorMessage="Insert valid card number" + /> + + <InputField + name="notes" + control={control} + rules={{ + required: { + value: true, + message: 'Add notes', + }, + }} + label="Notes" + error={!!errors.notes} + errorMessage="Insert notes" + /> + <Button data-testid="Submit" type="submit" diff --git a/src/components/LandingPage/LandingPage.tsx b/src/components/NonAuthUser/LandingPage/LandingPage.tsx similarity index 96% rename from src/components/LandingPage/LandingPage.tsx rename to src/components/NonAuthUser/LandingPage/LandingPage.tsx index 77107dedc7f704634c0fda81ff3e32fd625ca3e2..cb738bf659d8ef754038cc5aa8b0f4aba6e0af80 100644 --- a/src/components/LandingPage/LandingPage.tsx +++ b/src/components/NonAuthUser/LandingPage/LandingPage.tsx @@ -1,7 +1,7 @@ import React, { FC } from 'react'; import Button from '@material-ui/core/Button'; import { Link } from 'react-router-dom'; -import { NonAuthRoutes } from 'components/api/routes'; +import { NonAuthRoutes } from 'api/routes'; export const LandingPage: FC = () => ( <> diff --git a/src/components/LandingPage/TeamPage.tsx b/src/components/NonAuthUser/LandingPage/TeamPage.tsx similarity index 100% rename from src/components/LandingPage/TeamPage.tsx rename to src/components/NonAuthUser/LandingPage/TeamPage.tsx diff --git a/src/components/LandingPage/assets/alberto.png b/src/components/NonAuthUser/LandingPage/assets/alberto.png similarity index 100% rename from src/components/LandingPage/assets/alberto.png rename to src/components/NonAuthUser/LandingPage/assets/alberto.png diff --git a/src/components/LandingPage/assets/logo04Circle.png b/src/components/NonAuthUser/LandingPage/assets/logo04Circle.png similarity index 100% rename from src/components/LandingPage/assets/logo04Circle.png rename to src/components/NonAuthUser/LandingPage/assets/logo04Circle.png diff --git a/src/components/LandingPage/assets/pp.jpg b/src/components/NonAuthUser/LandingPage/assets/pp.jpg similarity index 100% rename from src/components/LandingPage/assets/pp.jpg rename to src/components/NonAuthUser/LandingPage/assets/pp.jpg diff --git a/src/components/NotFound/NotFound.tsx b/src/components/NonAuthUser/NotFound/NotFound.tsx similarity index 100% rename from src/components/NotFound/NotFound.tsx rename to src/components/NonAuthUser/NotFound/NotFound.tsx diff --git a/src/components/Unauthorized/Unauthorized.tsx b/src/components/NonAuthUser/Unauthorized/Unauthorized.tsx similarity index 100% rename from src/components/Unauthorized/Unauthorized.tsx rename to src/components/NonAuthUser/Unauthorized/Unauthorized.tsx