frontend: Page d'inscription + Hotfix backend
This commit is contained in:
		| @@ -10,7 +10,7 @@ const { EMAIL_INFO, HOST }          = require('../assets/config/config'); | ||||
| const { signupEmail }               = require('../assets/config/emails'); | ||||
| const Users                         = require('../models/users'); | ||||
|  | ||||
| exports.signup = async (req, res, next) => { | ||||
| exports.register = async (req, res, next) => { | ||||
|     const { name, email, password } = req.body; | ||||
|     const errors = validationResult(req); | ||||
|     if (!errors.isEmpty()) { | ||||
| @@ -47,7 +47,7 @@ exports.login = async (req, res, next) => { | ||||
|         const token = jwt.sign({  | ||||
|             email: user.email, userId: user.id | ||||
|         }, JWT_SECRET, { expiresIn: '1h' }); | ||||
|         return res.status(200).json({ token, id: user.id, name: user.name, email: user.email, logo: user.logo, isAdmin: user.isAdmin, createdAt: user.createdAt }); | ||||
|         return res.status(200).json({ token, id: user.id, name: user.name, email: user.email, biography: user.biography, logo: user.logo, isPublicEmail: user.isPublicEmail, isAdmin: user.isAdmin, createdAt: user.createdAt }); | ||||
|     } catch (error) { | ||||
|         console.log(error); | ||||
|         errorHandling(next, serverError); | ||||
|   | ||||
| @@ -9,7 +9,7 @@ const UsersRouter = Router(); | ||||
| UsersRouter.post('/login', usersController.login); | ||||
|  | ||||
| // Permet de s'inscrire | ||||
| UsersRouter.post('/signup', [ | ||||
| UsersRouter.post('/register', [ | ||||
|     body('email') | ||||
|         .isEmail() | ||||
|         .withMessage("Veuillez rentré une adresse mail valide.") | ||||
| @@ -31,7 +31,7 @@ UsersRouter.post('/signup', [ | ||||
|         .trim() | ||||
|         .not() | ||||
|         .isEmpty() | ||||
|         .withMessage("Votre nom ne peut pas être vide.") | ||||
|         .withMessage("Vous devez avoir un nom (ou pseudo).") | ||||
|         .isAlphanumeric() | ||||
|         .withMessage("Votre nom ne peut contenir que des lettres ou/et des nombres.") | ||||
|         .custom((async (name) => { | ||||
| @@ -44,7 +44,7 @@ UsersRouter.post('/signup', [ | ||||
|                 return console.log(error); | ||||
|             } | ||||
|         })) | ||||
| ], usersController.signup); | ||||
| ], usersController.register); | ||||
|  | ||||
| // Confirme l'inscription | ||||
| UsersRouter.get('/confirm-email/:tempToken', usersController.confirmEmail); | ||||
|   | ||||
| @@ -1,8 +1,7 @@ | ||||
| import { useState } from 'react'; | ||||
| import Loader from '../Loader'; | ||||
| import './FunctionForm.css'; | ||||
| import Loader from './Loader'; | ||||
| import htmlParser from 'html-react-parser'; | ||||
| import api from '../../utils/api'; | ||||
| import api from '../utils/api'; | ||||
| 
 | ||||
| const FunctionForm = (props) => { | ||||
|     // console.log(props);
 | ||||
| @@ -48,24 +47,24 @@ const FunctionForm = (props) => { | ||||
|                     let inputResult; | ||||
|                     switch(input.type) { | ||||
|                         case "text" || "number": | ||||
|                             inputResult = (<input onChange={handleChange} type={input.type} name={input.name} id={input.name} placeholder={input.placeholder} className="FunctionForm__control" />); | ||||
|                             inputResult = (<input onChange={handleChange} type={input.type} name={input.name} id={input.name} placeholder={input.placeholder} className="form-control" />); | ||||
|                             break; | ||||
|                         default: | ||||
|                             inputResult = (<p>Erreur, l'input n'est pas valide...</p>); | ||||
|                     } | ||||
|                     return ( | ||||
|                         <div key={index} className="FunctionForm__group"> | ||||
|                             <label className="FunctionForm__label"  htmlFor={input.name}>{input.label}</label> | ||||
|                         <div key={index} className="form-group"> | ||||
|                             <label className="form-label"  htmlFor={input.name}>{input.label}</label> | ||||
|                             {inputResult} | ||||
|                         </div> | ||||
|                     ); | ||||
|                 })} | ||||
|                  | ||||
|                 <div className="FunctionForm__submit text-center"> | ||||
|                 <div className="form-group text-center"> | ||||
|                     <button type="submit" className="btn btn-dark">Envoyer</button> | ||||
|                 </div> | ||||
|             </form> | ||||
|             <div className="FunctionForm__result text-center"> | ||||
|             <div className="form-result text-center"> | ||||
|                 { | ||||
|                     (isLoading) ?  | ||||
|                         <Loader /> | ||||
| @@ -1,41 +0,0 @@ | ||||
| .FunctionForm__control { | ||||
|     display: block; | ||||
|     width: 100%; | ||||
|     height: calc(1.5em + .75rem + 2px); | ||||
|     padding: .375rem .75rem; | ||||
|     font-size: 1rem; | ||||
|     font-weight: 400; | ||||
|     line-height: 1.5; | ||||
|     color: #495057; | ||||
|     background-color: #fff; | ||||
|     background-clip: padding-box; | ||||
|     border: 1px solid #ced4da; | ||||
|     border-radius: .25rem; | ||||
| } | ||||
| .FunctionForm__label { | ||||
|     display: inline-block; | ||||
|     margin-bottom: .5em; | ||||
|     font-size: 16px; | ||||
| } | ||||
| .FunctionForm__submit, .FunctionForm__result { | ||||
|     margin-top: 25px; | ||||
| } | ||||
| .btn { | ||||
|     cursor: pointer; | ||||
|     border: 1px solid transparent; | ||||
|     padding: .375rem .75rem; | ||||
|     font-size: 1rem; | ||||
|     line-height: 1.5; | ||||
|     border-radius: .25rem; | ||||
|     transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out; | ||||
| } | ||||
| .btn-dark:hover { | ||||
|     color: #fff; | ||||
|     background-color: #23272b; | ||||
|     border-color: #1d2124; | ||||
| } | ||||
| .btn-dark { | ||||
|     color: #fff; | ||||
|     background-color: #343a40; | ||||
|     border-color: #343a40; | ||||
| } | ||||
| @@ -5,17 +5,10 @@ import './Header.css'; | ||||
|  | ||||
| export default function Header() { | ||||
|  | ||||
|     const [hamburgerIcon, setHamburgerIcon] = useState(""); | ||||
|     const [navbarList, setNavbarList] = useState(""); | ||||
|     const [isActive, setIsActive] = useState(false); | ||||
|  | ||||
|     const toggleNavbar = () => { | ||||
|         if (hamburgerIcon) { | ||||
|             setHamburgerIcon(""); | ||||
|             setNavbarList(""); | ||||
|         } else { | ||||
|             setHamburgerIcon("Header__hamburger-active"); | ||||
|             setNavbarList("navbar__list-active"); | ||||
|         } | ||||
|         setIsActive(!isActive); | ||||
|     } | ||||
|  | ||||
|     return ( | ||||
| @@ -31,15 +24,17 @@ export default function Header() { | ||||
|                 </Link> | ||||
|  | ||||
|                 {/* Hamburger icon on Mobile */} | ||||
|                 <div onClick={toggleNavbar} className={"Header__hamburger " + hamburgerIcon}> | ||||
|                 <div onClick={toggleNavbar} className={`Header__hamburger ${(isActive) ? "Header__hamburger-active" : ""}`}> | ||||
|                     <span></span> | ||||
|                 </div> | ||||
|  | ||||
|                 {/* Navigation */} | ||||
|                 <nav className="Header__navbar"> | ||||
|                     <ul className={"navbar__list " + navbarList}> | ||||
|                     <ul className={`navbar__list ${(isActive) ? "navbar__list-active" : ""}`}> | ||||
|                         <NavigationLink name="Accueil" path="/" /> | ||||
|                         <NavigationLink name="Fonctions" path="/functions" /> | ||||
|                         <NavigationLink name="S'inscrire" path="/register" /> | ||||
|                         <NavigationLink name="Connexion" path="/login" /> | ||||
|                     </ul> | ||||
|                 </nav> | ||||
|  | ||||
|   | ||||
| @@ -3,7 +3,7 @@ import HeadTag from '../../components/HeadTag'; | ||||
| import FunctionComponentTop from '../../components/FunctionComponentTop'; | ||||
| import FunctionTabsTop from '../../components/FunctionTabs/FunctionTabsTop'; | ||||
| import FunctionTabs from '../../components/FunctionTabs/FunctionTabs'; | ||||
| import FunctionForm from '../../components/FunctionForm/FunctionForm'; | ||||
| import FunctionForm from '../../components/FunctionForm'; | ||||
| import redirect from '../../utils/redirect'; | ||||
| import api from '../../utils/api'; | ||||
| import { API_URL } from '../../utils/config'; | ||||
|   | ||||
| @@ -82,13 +82,13 @@ const Functions = () => { | ||||
|                 </div> | ||||
|  | ||||
|                 <div className="Functions__search-container row justify-content-center"> | ||||
|                     <select name="selectedCategory" value={inputSearch.selectedCategory} onChange={handleChange} className="Functions__select form-control"> | ||||
|                     <select name="selectedCategory" value={inputSearch.selectedCategory} onChange={handleChange} className="Functions__select Functions__form-control"> | ||||
|                         <option value="0">Toutes catégories</option> | ||||
|                         {categories.map((category) => ( | ||||
|                             <option key={category.id} value={category.id} className="Functions__select-option" style={{ backgroundColor: category.color }}>{category.name}</option> | ||||
|                         ))} | ||||
|                     </select> | ||||
|                     <input value={inputSearch.search} onChange={handleChange} type="search" className="form-control Functions__search-input" name="search" id="search" placeholder="🔎 Rechercher..."></input> | ||||
|                     <input value={inputSearch.search} onChange={handleChange} type="search" className="Functions__form-control Functions__search-input" name="search" id="search" placeholder="🔎 Rechercher..."></input> | ||||
|                 </div> | ||||
|      | ||||
|                 <div className="row justify-content-center"> | ||||
|   | ||||
							
								
								
									
										75
									
								
								website/pages/register.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								website/pages/register.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | ||||
| import { Fragment, useState } from 'react'; | ||||
| import htmlParser from 'html-react-parser'; | ||||
| import Loader from '../components/Loader'; | ||||
| import HeadTag from '../components/HeadTag'; | ||||
| import '../public/css/pages/register-login.css'; | ||||
| import api from '../utils/api'; | ||||
|  | ||||
| const Register = () => { | ||||
|      | ||||
|     const [inputState, setInputState] = useState({}); | ||||
|     const [message, setMessage] = useState(""); | ||||
|     const [isLoading, setIsLoading] = useState(false); | ||||
|      | ||||
|     const handleChange = () => { | ||||
|         const inputStateNew = { ...inputState }; | ||||
|         inputStateNew[event.target.name] = event.target.value; | ||||
|         setInputState(inputStateNew); | ||||
|     } | ||||
|  | ||||
|     const handleSubmit = (event) => { | ||||
|         event.preventDefault(); | ||||
|         api.post('/users/register', inputState) | ||||
|             .then(({ data }) => { | ||||
|                 setMessage(`<p class="form-success"><b>Succès:</b> ${data.result}</p>`); | ||||
|             }) | ||||
|             .catch((error) => { | ||||
|                 setMessage(`<p class="form-error"><b>Erreur:</b> ${error.response.data.message}</p>`); | ||||
|             }); | ||||
|     } | ||||
|  | ||||
|     return ( | ||||
|         <Fragment> | ||||
|             <HeadTag  | ||||
|                 title="S'inscrire"  | ||||
|                 description="Créer un compte."  | ||||
|             /> | ||||
|             <div className="container Register-Login__container"> | ||||
|                 <div className="row Register-Login__row justify-content-center"> | ||||
|                     <div className="col-20"> | ||||
|                         <h1 className="Register-Login__title">S'inscrire</h1> | ||||
|                         <form onSubmit={handleSubmit}> | ||||
|                             <div className="form-group"> | ||||
|                                 <label className="form-label" htmlFor="name">Nom :</label> | ||||
|                                 <input onChange={handleChange} type="text" name="name" id="name" className="form-control" placeholder="Divlo" /> | ||||
|                             </div> | ||||
|  | ||||
|                             <div className="form-group"> | ||||
|                                 <label className="form-label" htmlFor="name">Email :</label> | ||||
|                                 <input onChange={handleChange} type="email" name="email" id="email" className="form-control" placeholder="email@gmail.com" /> | ||||
|                             </div> | ||||
|  | ||||
|                             <div className="form-group"> | ||||
|                                 <label className="form-label" htmlFor="name">Mot de passe :</label> | ||||
|                                 <input onChange={handleChange} type="password" name="password" id="password" className="form-control" placeholder="******" /> | ||||
|                             </div> | ||||
|  | ||||
|                             <div className="form-group text-center"> | ||||
|                                 <button type="submit" className="btn btn-dark">Envoyer</button> | ||||
|                             </div> | ||||
|                         </form> | ||||
|                         <div className="form-result text-center"> | ||||
|                             { | ||||
|                                 (isLoading) ?  | ||||
|                                     <Loader /> | ||||
|                                 : | ||||
|                                     htmlParser(message) | ||||
|                             } | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </Fragment> | ||||
|     ); | ||||
| } | ||||
| export default Register; | ||||
| @@ -84,8 +84,12 @@ a, .important { | ||||
| .d-none { | ||||
|     display: none !important; | ||||
| } | ||||
| .form-group { | ||||
|     margin-top: 1.4rem; | ||||
| } | ||||
| .form-control { | ||||
|     display: block; | ||||
|     width: 100%; | ||||
|     height: calc(1.5em + .75rem + 2px); | ||||
|     padding: .375rem .75rem; | ||||
|     font-size: 1rem; | ||||
| @@ -95,5 +99,37 @@ a, .important { | ||||
|     background-color: #fff; | ||||
|     background-clip: padding-box; | ||||
|     border: 1px solid #ced4da; | ||||
|     border-radius: .5em; | ||||
|     border-radius: .25rem; | ||||
| } | ||||
| .form-label { | ||||
|     display: inline-block; | ||||
|     margin-bottom: .5em; | ||||
| } | ||||
| .form-result { | ||||
|     margin-top: 25px; | ||||
| } | ||||
| .form-success { | ||||
|     color: #90EE90; | ||||
| } | ||||
| .form-error { | ||||
|     color: #ff7f7f; | ||||
| } | ||||
| .btn { | ||||
|     cursor: pointer; | ||||
|     border: 1px solid transparent; | ||||
|     padding: .375rem .75rem; | ||||
|     font-size: 1rem; | ||||
|     line-height: 1.5; | ||||
|     border-radius: .25rem; | ||||
|     transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out; | ||||
| } | ||||
| .btn-dark:hover { | ||||
|     color: #fff; | ||||
|     background-color: #23272b; | ||||
|     border-color: #1d2124; | ||||
| } | ||||
| .btn-dark { | ||||
|     color: #fff; | ||||
|     background-color: #343a40; | ||||
|     border-color: #343a40; | ||||
| } | ||||
| @@ -2,7 +2,19 @@ | ||||
|     padding: 20px 0 20px 0; | ||||
|     margin-bottom: 0; | ||||
| } | ||||
|  | ||||
| .Functions__form-control { | ||||
|     display: block; | ||||
|     height: calc(1.5em + .75rem + 2px); | ||||
|     padding: .375rem .75rem; | ||||
|     font-size: 1rem; | ||||
|     font-weight: 400; | ||||
|     line-height: 1.5; | ||||
|     color: #495057; | ||||
|     background-color: #fff; | ||||
|     background-clip: padding-box; | ||||
|     border: 1px solid #ced4da; | ||||
|     border-radius: .5em; | ||||
| } | ||||
| .Functions__search-container { | ||||
|     margin-bottom: 50px; | ||||
| } | ||||
|   | ||||
							
								
								
									
										14
									
								
								website/public/css/pages/register-login.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								website/public/css/pages/register-login.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| .Register-Login__container { | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     justify-content: center; | ||||
| } | ||||
| .Register-Login__row { | ||||
|     padding: 30px; | ||||
|     box-shadow: 0px 0px 6px 6px rgba(0, 0, 0, .25); | ||||
|     border: 1px solid black; | ||||
|     border-radius: 1rem; | ||||
| } | ||||
| .Register-Login__title { | ||||
|     text-align: center; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user