frontend: manageCategories et Hotfix date-and-time
This commit is contained in:
parent
42193066a8
commit
d902d40e6e
@ -3,8 +3,10 @@ import Link from 'next/link';
|
|||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { faStar } from '@fortawesome/free-solid-svg-icons';
|
import { faStar } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { faStar as farStar } from '@fortawesome/free-regular-svg-icons';
|
import { faStar as farStar } from '@fortawesome/free-regular-svg-icons';
|
||||||
|
import date from 'date-and-time';
|
||||||
import { UserContext } from '../contexts/UserContext';
|
import { UserContext } from '../contexts/UserContext';
|
||||||
import api from '../utils/api';
|
import api from '../utils/api';
|
||||||
|
import { API_URL } from '../utils/config';
|
||||||
import './FunctionCard/FunctionCard.css';
|
import './FunctionCard/FunctionCard.css';
|
||||||
|
|
||||||
const FunctionComponentTop = (props) => {
|
const FunctionComponentTop = (props) => {
|
||||||
@ -47,14 +49,14 @@ const FunctionComponentTop = (props) => {
|
|||||||
<FontAwesomeIcon onClick={toggleFavorite} { ...(isFavorite) ? { icon: faStar } : { icon: farStar } } title={(isFavorite) ? "Retirer la fonction des favoris" : "Ajouter la fonction aux favoris"} className="FunctionComponent__star-favorite" />
|
<FontAwesomeIcon onClick={toggleFavorite} { ...(isFavorite) ? { icon: faStar } : { icon: farStar } } title={(isFavorite) ? "Retirer la fonction des favoris" : "Ajouter la fonction aux favoris"} className="FunctionComponent__star-favorite" />
|
||||||
}
|
}
|
||||||
|
|
||||||
<img className="FunctionComponent__image" src={props.API_URL + props.image} alt={props.title} />
|
<img className="FunctionComponent__image" src={API_URL + props.image} alt={props.title} />
|
||||||
<h1 className="FunctionComponent__title title-important">{props.title}</h1>
|
<h1 className="FunctionComponent__title title-important">{props.title}</h1>
|
||||||
<p className="FunctionComponent__description">{props.description}</p>
|
<p className="FunctionComponent__description">{props.description}</p>
|
||||||
<div className="FunctionCard__info">
|
<div className="FunctionCard__info">
|
||||||
<Link href={`/functions?categoryId=${props.categorieId}`}>
|
<Link href={`/functions?categoryId=${props.categorieId}`}>
|
||||||
<a className="FunctionCard__category" style={{ backgroundColor: props.categorie.color, color: 'inherit' }}>{props.categorie.name}</a>
|
<a className="FunctionCard__category" style={{ backgroundColor: props.categorie.color, color: 'inherit' }}>{props.categorie.name}</a>
|
||||||
</Link>
|
</Link>
|
||||||
<p className="FunctionCard__publication-date">{props.publicationDate}</p>
|
<p className="FunctionCard__publication-date">{date.format(new Date(props.createdAt), 'DD/MM/YYYY', true)}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -3,15 +3,15 @@ import FunctionForm from './FunctionForm';
|
|||||||
import FunctionComments from './FunctionComments/FunctionComments';
|
import FunctionComments from './FunctionComments/FunctionComments';
|
||||||
|
|
||||||
const FunctionTabManager = (props) => {
|
const FunctionTabManager = (props) => {
|
||||||
if (props.functionInfo.type === "form") {
|
if (props.type === "form") {
|
||||||
return (
|
return (
|
||||||
<FunctionTabs type={props.functionInfo.type}>
|
<FunctionTabs type={props.type}>
|
||||||
<div className="FunctionComponent__slide">
|
<div className="FunctionComponent__slide">
|
||||||
<FunctionForm inputArray={ [...props.functionInfo.utilizationForm || []] } slug={props.functionInfo.slug} />
|
<FunctionForm inputArray={ [...props.utilizationForm || []] } slug={props.slug} />
|
||||||
</div>
|
</div>
|
||||||
<div className="FunctionComponent__slide text-center">Article</div>
|
<div className="FunctionComponent__slide text-center">Article</div>
|
||||||
<div className="FunctionComponent__slide">
|
<div className="FunctionComponent__slide">
|
||||||
<FunctionComments functionId={props.functionInfo.id} />
|
<FunctionComments functionId={props.id} />
|
||||||
</div>
|
</div>
|
||||||
</FunctionTabs>
|
</FunctionTabs>
|
||||||
);
|
);
|
||||||
@ -21,7 +21,7 @@ const FunctionTabManager = (props) => {
|
|||||||
<FunctionTabs type={props.type}>
|
<FunctionTabs type={props.type}>
|
||||||
<div className="FunctionComponent__slide text-center">Article</div>
|
<div className="FunctionComponent__slide text-center">Article</div>
|
||||||
<div className="FunctionComponent__slide">
|
<div className="FunctionComponent__slide">
|
||||||
<FunctionComments functionId={props.functionInfo.id} />
|
<FunctionComments functionId={props.id} />
|
||||||
</div>
|
</div>
|
||||||
</FunctionTabs>
|
</FunctionTabs>
|
||||||
);
|
);
|
||||||
|
@ -47,13 +47,13 @@ function UserContextProvider(props) {
|
|||||||
setIsAuth(true);
|
setIsAuth(true);
|
||||||
setMessageLogin('<p class="form-success"><b>Succès:</b> Connexion réussi!</p>');
|
setMessageLogin('<p class="form-success"><b>Succès:</b> Connexion réussi!</p>');
|
||||||
setLoginLoading(false);
|
setLoginLoading(false);
|
||||||
return next({ isSuccess: true, newUser });
|
return next();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setMessageLogin(`<p class="form-error"><b>Erreur:</b> ${error.response.data.message}</p>`);
|
setMessageLogin(`<p class="form-error"><b>Erreur:</b> ${error.response.data.message}</p>`);
|
||||||
setLoginLoading(false);
|
setLoginLoading(false);
|
||||||
setIsAuth(false);
|
setIsAuth(false);
|
||||||
setUser(null);
|
setUser(null);
|
||||||
return next({ isSuccess: false });
|
return next();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import Link from 'next/link';
|
||||||
import { Fragment, useState, useEffect } from 'react';
|
import { Fragment, useState, useEffect } from 'react';
|
||||||
import Cookies from "universal-cookie";
|
import Cookies from "universal-cookie";
|
||||||
import HeadTag from '../../components/HeadTag';
|
import HeadTag from '../../components/HeadTag';
|
||||||
@ -9,8 +10,8 @@ import redirect from '../../utils/redirect';
|
|||||||
import htmlParser from 'html-react-parser';
|
import htmlParser from 'html-react-parser';
|
||||||
import Loader from '../../components/Loader';
|
import Loader from '../../components/Loader';
|
||||||
import useAPI from '../../hooks/useAPI';
|
import useAPI from '../../hooks/useAPI';
|
||||||
import '../../public/css/pages/admin.css';
|
|
||||||
import api from '../../utils/api';
|
import api from '../../utils/api';
|
||||||
|
import '../../public/css/pages/admin.css';
|
||||||
|
|
||||||
const Admin = (props) => {
|
const Admin = (props) => {
|
||||||
|
|
||||||
@ -149,6 +150,9 @@ const Admin = (props) => {
|
|||||||
<div className="col-24">
|
<div className="col-24">
|
||||||
<h1 className="Functions__title">Administration</h1>
|
<h1 className="Functions__title">Administration</h1>
|
||||||
<button onClick={toggleModal} style={{ margin: '0 0 40px 0' }} className="btn btn-dark">Crée une nouvelle fonction</button>
|
<button onClick={toggleModal} style={{ margin: '0 0 40px 0' }} className="btn btn-dark">Crée une nouvelle fonction</button>
|
||||||
|
<Link href={"/admin/manageCategories"}>
|
||||||
|
<button style={{ margin: '0 0 0 20px' }} className="btn btn-dark">Gérer les catégories</button>
|
||||||
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</FunctionsList>
|
</FunctionsList>
|
||||||
}
|
}
|
||||||
|
82
website/pages/admin/manageCategories.js
Normal file
82
website/pages/admin/manageCategories.js
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
import { Fragment } from 'react';
|
||||||
|
import Cookies from "universal-cookie";
|
||||||
|
import date from 'date-and-time';
|
||||||
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
|
import { faPen, faTrash } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
import HeadTag from '../../components/HeadTag';
|
||||||
|
import redirect from '../../utils/redirect';
|
||||||
|
import useAPI from '../../hooks/useAPI';
|
||||||
|
import '../../public/css/pages/admin.css';
|
||||||
|
|
||||||
|
const manageCategories = (props) => {
|
||||||
|
|
||||||
|
const [, categories] = useAPI('/categories');
|
||||||
|
|
||||||
|
if (!props.user.isAdmin && typeof window != 'undefined') {
|
||||||
|
return redirect({}, '/404');
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<HeadTag title="Admin - FunctionProject" description="Page d'administration de FunctionProject. Gérer les catégories." />
|
||||||
|
|
||||||
|
<div className="container-fluid text-center">
|
||||||
|
<div className="row justify-content-center">
|
||||||
|
<div className="col-24">
|
||||||
|
<h1>Gérer les catégories</h1>
|
||||||
|
<button style={{ margin: '0 0 40px 0' }} className="btn btn-dark">Ajouter une catégorie</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="row justify-content-center">
|
||||||
|
<div className="container-fluid">
|
||||||
|
<div className="col-24 Admin__table-column">
|
||||||
|
<table className="Admin__table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th className="Admin__table-row Admin__table-head-row" scope="col">id</th>
|
||||||
|
<th className="Admin__table-row Admin__table-head-row" scope="col">name</th>
|
||||||
|
<th className="Admin__table-row Admin__table-head-row" scope="col">color</th>
|
||||||
|
<th className="Admin__table-row Admin__table-head-row" scope="col">createdAt</th>
|
||||||
|
<th className="Admin__table-row Admin__table-head-row" scope="col">updatedAt</th>
|
||||||
|
<th className="Admin__table-row Admin__table-head-row" scope="col">Modifier</th>
|
||||||
|
<th className="Admin__table-row Admin__table-head-row" scope="col">Supprimer</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{categories.map((category) => {
|
||||||
|
return (
|
||||||
|
<tr key={category.id} style={{ backgroundColor: category.color }}>
|
||||||
|
<td className="Admin__table-row">{category.id}</td>
|
||||||
|
<td className="Admin__table-row">{category.name}</td>
|
||||||
|
<td className="Admin__table-row">{category.color}</td>
|
||||||
|
<td className="Admin__table-row">{date.format(new Date(category.createdAt), 'DD/MM/YYYY à HH:mm', true)}</td>
|
||||||
|
<td className="Admin__table-row">{date.format(new Date(category.updatedAt), 'DD/MM/YYYY à HH:mm', true)}</td>
|
||||||
|
<td style={{ cursor: 'pointer' }}>
|
||||||
|
<FontAwesomeIcon icon={faPen} style={{ width: '1.5rem' }} />
|
||||||
|
</td>
|
||||||
|
<td style={{ cursor: 'pointer' }}>
|
||||||
|
<FontAwesomeIcon icon={faTrash} style={{ width: '1.5rem' }} />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getServerSideProps({ req }) {
|
||||||
|
const cookies = new Cookies(req.headers.cookie);
|
||||||
|
return {
|
||||||
|
props: {
|
||||||
|
user: { ...cookies.get('user') }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default manageCategories;
|
@ -2,8 +2,9 @@ import { Fragment, useState } from 'react';
|
|||||||
import htmlParser from 'html-react-parser';
|
import htmlParser from 'html-react-parser';
|
||||||
import Loader from '../components/Loader';
|
import Loader from '../components/Loader';
|
||||||
import HeadTag from '../components/HeadTag';
|
import HeadTag from '../components/HeadTag';
|
||||||
import '../public/css/pages/register-login.css';
|
|
||||||
import api from '../utils/api';
|
import api from '../utils/api';
|
||||||
|
import withoutAuth from '../hoc/withoutAuth';
|
||||||
|
import '../public/css/pages/register-login.css';
|
||||||
|
|
||||||
const forgotPassword = () => {
|
const forgotPassword = () => {
|
||||||
|
|
||||||
@ -70,4 +71,4 @@ const forgotPassword = () => {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default forgotPassword;
|
export default withoutAuth(forgotPassword);
|
@ -9,18 +9,13 @@ import { API_URL } from '../../utils/config';
|
|||||||
import '../../public/css/pages/FunctionComponent.css';
|
import '../../public/css/pages/FunctionComponent.css';
|
||||||
|
|
||||||
const FunctionComponent = (props) => {
|
const FunctionComponent = (props) => {
|
||||||
|
|
||||||
// Constantes
|
|
||||||
const createdAt = new Date(props.createdAt);
|
|
||||||
const publicationDate = `${('0'+createdAt.getDate()).slice(-2)}/${('0'+(createdAt.getMonth()+1)).slice(-2)}/${createdAt.getFullYear()}`;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FunctionTabsContextProvider>
|
<FunctionTabsContextProvider>
|
||||||
<HeadTag title={props.title} description={props.description} image={API_URL + props.image} />
|
<HeadTag title={props.title} description={props.description} image={API_URL + props.image} />
|
||||||
<div className="container-fluid">
|
<div className="container-fluid">
|
||||||
<FunctionTabsTop type={props.type} />
|
<FunctionTabsTop type={props.type} />
|
||||||
<FunctionComponentTop { ...props } API_URL={API_URL} publicationDate={publicationDate} />
|
<FunctionComponentTop { ...props } />
|
||||||
<FunctionTabManager functionInfo={props} />
|
<FunctionTabManager { ...props } />
|
||||||
</div>
|
</div>
|
||||||
</FunctionTabsContextProvider>
|
</FunctionTabsContextProvider>
|
||||||
);
|
);
|
||||||
|
@ -5,7 +5,7 @@ import htmlParser from 'html-react-parser';
|
|||||||
import Loader from '../components/Loader';
|
import Loader from '../components/Loader';
|
||||||
import HeadTag from '../components/HeadTag';
|
import HeadTag from '../components/HeadTag';
|
||||||
import { UserContext } from '../contexts/UserContext';
|
import { UserContext } from '../contexts/UserContext';
|
||||||
import redirect from '../utils/redirect';
|
import withoutAuth from '../hoc/withoutAuth';
|
||||||
import '../public/css/pages/register-login.css';
|
import '../public/css/pages/register-login.css';
|
||||||
|
|
||||||
const Login = () => {
|
const Login = () => {
|
||||||
@ -23,10 +23,7 @@ const Login = () => {
|
|||||||
const handleSubmit = async (event) => {
|
const handleSubmit = async (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
if (!isAuth) {
|
if (!isAuth) {
|
||||||
const loginObject = await loginUser(inputState);
|
await loginUser(inputState);
|
||||||
if (loginObject.isSuccess) {
|
|
||||||
redirect({}, `/profile/${loginObject.newUser.name}`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,4 +74,4 @@ const Login = () => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Login;
|
export default withoutAuth(Login);
|
@ -2,9 +2,10 @@ import { Fragment, useState } from 'react';
|
|||||||
import htmlParser from 'html-react-parser';
|
import htmlParser from 'html-react-parser';
|
||||||
import Loader from '../components/Loader';
|
import Loader from '../components/Loader';
|
||||||
import HeadTag from '../components/HeadTag';
|
import HeadTag from '../components/HeadTag';
|
||||||
import '../public/css/pages/register-login.css';
|
|
||||||
import api from '../utils/api';
|
import api from '../utils/api';
|
||||||
import redirect from '../utils/redirect';
|
import redirect from '../utils/redirect';
|
||||||
|
import withoutAuth from '../hoc/withoutAuth';
|
||||||
|
import '../public/css/pages/register-login.css';
|
||||||
|
|
||||||
const newPassword = (props) => {
|
const newPassword = (props) => {
|
||||||
|
|
||||||
@ -74,4 +75,4 @@ newPassword.getInitialProps = (context) => {
|
|||||||
return redirect(context, '/404');
|
return redirect(context, '/404');
|
||||||
}
|
}
|
||||||
|
|
||||||
export default newPassword;
|
export default withoutAuth(newPassword);
|
@ -16,10 +16,6 @@ import '../../public/css/pages/profile.css';
|
|||||||
|
|
||||||
const Profile = (props) => {
|
const Profile = (props) => {
|
||||||
|
|
||||||
// Constantes
|
|
||||||
const createdAt = new Date(props.createdAt);
|
|
||||||
const publicationDate = `${('0'+createdAt.getDate()).slice(-2)}/${('0'+(createdAt.getMonth()+1)).slice(-2)}/${createdAt.getFullYear()}`;
|
|
||||||
|
|
||||||
const { isAuth, user, logoutUser } = useContext(UserContext);
|
const { isAuth, user, logoutUser } = useContext(UserContext);
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [inputState, setInputState] = useState({});
|
const [inputState, setInputState] = useState({});
|
||||||
@ -148,7 +144,7 @@ const Profile = (props) => {
|
|||||||
<div className="col-24 text-center">
|
<div className="col-24 text-center">
|
||||||
{(props.biography != undefined) && <p>{props.biography}</p>}
|
{(props.biography != undefined) && <p>{props.biography}</p>}
|
||||||
{(props.email != undefined) && <p><span className="important">Email :</span> {props.email}</p>}
|
{(props.email != undefined) && <p><span className="important">Email :</span> {props.email}</p>}
|
||||||
<p><span className="important">Date de création :</span> {publicationDate}</p>
|
<p><span className="important">Date de création du compte :</span> {date.format(new Date(props.createdAt), 'DD/MM/YYYY à HH:mm', true)}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{(isAuth && user.name === props.name) &&
|
{(isAuth && user.name === props.name) &&
|
||||||
|
@ -19,4 +19,14 @@
|
|||||||
}
|
}
|
||||||
.Admin__Modal-select-option {
|
.Admin__Modal-select-option {
|
||||||
color: rgb(221, 220, 220);
|
color: rgb(221, 220, 220);
|
||||||
|
}
|
||||||
|
.Admin__table-column {
|
||||||
|
display: grid;
|
||||||
|
}
|
||||||
|
.Admin__table, th, td {
|
||||||
|
border: 1px solid var(--text-color);
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
.Admin__table-row {
|
||||||
|
padding: 15px;
|
||||||
}
|
}
|
Reference in New Issue
Block a user