frontend: Page d'inscription + Hotfix backend
This commit is contained in:
parent
2239df70b3
commit
7d49422108
@ -10,7 +10,7 @@ const { EMAIL_INFO, HOST } = require('../assets/config/config');
|
|||||||
const { signupEmail } = require('../assets/config/emails');
|
const { signupEmail } = require('../assets/config/emails');
|
||||||
const Users = require('../models/users');
|
const Users = require('../models/users');
|
||||||
|
|
||||||
exports.signup = async (req, res, next) => {
|
exports.register = async (req, res, next) => {
|
||||||
const { name, email, password } = req.body;
|
const { name, email, password } = req.body;
|
||||||
const errors = validationResult(req);
|
const errors = validationResult(req);
|
||||||
if (!errors.isEmpty()) {
|
if (!errors.isEmpty()) {
|
||||||
@ -47,7 +47,7 @@ exports.login = async (req, res, next) => {
|
|||||||
const token = jwt.sign({
|
const token = jwt.sign({
|
||||||
email: user.email, userId: user.id
|
email: user.email, userId: user.id
|
||||||
}, JWT_SECRET, { expiresIn: '1h' });
|
}, 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) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
errorHandling(next, serverError);
|
errorHandling(next, serverError);
|
||||||
|
@ -9,7 +9,7 @@ const UsersRouter = Router();
|
|||||||
UsersRouter.post('/login', usersController.login);
|
UsersRouter.post('/login', usersController.login);
|
||||||
|
|
||||||
// Permet de s'inscrire
|
// Permet de s'inscrire
|
||||||
UsersRouter.post('/signup', [
|
UsersRouter.post('/register', [
|
||||||
body('email')
|
body('email')
|
||||||
.isEmail()
|
.isEmail()
|
||||||
.withMessage("Veuillez rentré une adresse mail valide.")
|
.withMessage("Veuillez rentré une adresse mail valide.")
|
||||||
@ -31,7 +31,7 @@ UsersRouter.post('/signup', [
|
|||||||
.trim()
|
.trim()
|
||||||
.not()
|
.not()
|
||||||
.isEmpty()
|
.isEmpty()
|
||||||
.withMessage("Votre nom ne peut pas être vide.")
|
.withMessage("Vous devez avoir un nom (ou pseudo).")
|
||||||
.isAlphanumeric()
|
.isAlphanumeric()
|
||||||
.withMessage("Votre nom ne peut contenir que des lettres ou/et des nombres.")
|
.withMessage("Votre nom ne peut contenir que des lettres ou/et des nombres.")
|
||||||
.custom((async (name) => {
|
.custom((async (name) => {
|
||||||
@ -44,7 +44,7 @@ UsersRouter.post('/signup', [
|
|||||||
return console.log(error);
|
return console.log(error);
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
], usersController.signup);
|
], usersController.register);
|
||||||
|
|
||||||
// Confirme l'inscription
|
// Confirme l'inscription
|
||||||
UsersRouter.get('/confirm-email/:tempToken', usersController.confirmEmail);
|
UsersRouter.get('/confirm-email/:tempToken', usersController.confirmEmail);
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import Loader from '../Loader';
|
import Loader from './Loader';
|
||||||
import './FunctionForm.css';
|
|
||||||
import htmlParser from 'html-react-parser';
|
import htmlParser from 'html-react-parser';
|
||||||
import api from '../../utils/api';
|
import api from '../utils/api';
|
||||||
|
|
||||||
const FunctionForm = (props) => {
|
const FunctionForm = (props) => {
|
||||||
// console.log(props);
|
// console.log(props);
|
||||||
@ -48,24 +47,24 @@ const FunctionForm = (props) => {
|
|||||||
let inputResult;
|
let inputResult;
|
||||||
switch(input.type) {
|
switch(input.type) {
|
||||||
case "text" || "number":
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
inputResult = (<p>Erreur, l'input n'est pas valide...</p>);
|
inputResult = (<p>Erreur, l'input n'est pas valide...</p>);
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div key={index} className="FunctionForm__group">
|
<div key={index} className="form-group">
|
||||||
<label className="FunctionForm__label" htmlFor={input.name}>{input.label}</label>
|
<label className="form-label" htmlFor={input.name}>{input.label}</label>
|
||||||
{inputResult}
|
{inputResult}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
||||||
<div className="FunctionForm__submit text-center">
|
<div className="form-group text-center">
|
||||||
<button type="submit" className="btn btn-dark">Envoyer</button>
|
<button type="submit" className="btn btn-dark">Envoyer</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<div className="FunctionForm__result text-center">
|
<div className="form-result text-center">
|
||||||
{
|
{
|
||||||
(isLoading) ?
|
(isLoading) ?
|
||||||
<Loader />
|
<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() {
|
export default function Header() {
|
||||||
|
|
||||||
const [hamburgerIcon, setHamburgerIcon] = useState("");
|
const [isActive, setIsActive] = useState(false);
|
||||||
const [navbarList, setNavbarList] = useState("");
|
|
||||||
|
|
||||||
const toggleNavbar = () => {
|
const toggleNavbar = () => {
|
||||||
if (hamburgerIcon) {
|
setIsActive(!isActive);
|
||||||
setHamburgerIcon("");
|
|
||||||
setNavbarList("");
|
|
||||||
} else {
|
|
||||||
setHamburgerIcon("Header__hamburger-active");
|
|
||||||
setNavbarList("navbar__list-active");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -31,15 +24,17 @@ export default function Header() {
|
|||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
{/* Hamburger icon on Mobile */}
|
{/* Hamburger icon on Mobile */}
|
||||||
<div onClick={toggleNavbar} className={"Header__hamburger " + hamburgerIcon}>
|
<div onClick={toggleNavbar} className={`Header__hamburger ${(isActive) ? "Header__hamburger-active" : ""}`}>
|
||||||
<span></span>
|
<span></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Navigation */}
|
{/* Navigation */}
|
||||||
<nav className="Header__navbar">
|
<nav className="Header__navbar">
|
||||||
<ul className={"navbar__list " + navbarList}>
|
<ul className={`navbar__list ${(isActive) ? "navbar__list-active" : ""}`}>
|
||||||
<NavigationLink name="Accueil" path="/" />
|
<NavigationLink name="Accueil" path="/" />
|
||||||
<NavigationLink name="Fonctions" path="/functions" />
|
<NavigationLink name="Fonctions" path="/functions" />
|
||||||
|
<NavigationLink name="S'inscrire" path="/register" />
|
||||||
|
<NavigationLink name="Connexion" path="/login" />
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ import HeadTag from '../../components/HeadTag';
|
|||||||
import FunctionComponentTop from '../../components/FunctionComponentTop';
|
import FunctionComponentTop from '../../components/FunctionComponentTop';
|
||||||
import FunctionTabsTop from '../../components/FunctionTabs/FunctionTabsTop';
|
import FunctionTabsTop from '../../components/FunctionTabs/FunctionTabsTop';
|
||||||
import FunctionTabs from '../../components/FunctionTabs/FunctionTabs';
|
import FunctionTabs from '../../components/FunctionTabs/FunctionTabs';
|
||||||
import FunctionForm from '../../components/FunctionForm/FunctionForm';
|
import FunctionForm from '../../components/FunctionForm';
|
||||||
import redirect from '../../utils/redirect';
|
import redirect from '../../utils/redirect';
|
||||||
import api from '../../utils/api';
|
import api from '../../utils/api';
|
||||||
import { API_URL } from '../../utils/config';
|
import { API_URL } from '../../utils/config';
|
||||||
|
@ -82,13 +82,13 @@ const Functions = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="Functions__search-container row justify-content-center">
|
<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>
|
<option value="0">Toutes catégories</option>
|
||||||
{categories.map((category) => (
|
{categories.map((category) => (
|
||||||
<option key={category.id} value={category.id} className="Functions__select-option" style={{ backgroundColor: category.color }}>{category.name}</option>
|
<option key={category.id} value={category.id} className="Functions__select-option" style={{ backgroundColor: category.color }}>{category.name}</option>
|
||||||
))}
|
))}
|
||||||
</select>
|
</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>
|
||||||
|
|
||||||
<div className="row justify-content-center">
|
<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 {
|
.d-none {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
.form-group {
|
||||||
|
margin-top: 1.4rem;
|
||||||
|
}
|
||||||
.form-control {
|
.form-control {
|
||||||
display: block;
|
display: block;
|
||||||
|
width: 100%;
|
||||||
height: calc(1.5em + .75rem + 2px);
|
height: calc(1.5em + .75rem + 2px);
|
||||||
padding: .375rem .75rem;
|
padding: .375rem .75rem;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
@ -95,5 +99,37 @@ a, .important {
|
|||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
background-clip: padding-box;
|
background-clip: padding-box;
|
||||||
border: 1px solid #ced4da;
|
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;
|
padding: 20px 0 20px 0;
|
||||||
margin-bottom: 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 {
|
.Functions__search-container {
|
||||||
margin-bottom: 50px;
|
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