frontend: Preloader & 404 Error page
This commit is contained in:
		@@ -1,6 +1,6 @@
 | 
				
			|||||||
import Link from 'next/link';
 | 
					import Link from 'next/link';
 | 
				
			||||||
import { useState, forwardRef } from 'react';
 | 
					import { useState, forwardRef } from 'react';
 | 
				
			||||||
import Loader from '../Loader/Loader';
 | 
					import Loader from '../Loader';
 | 
				
			||||||
import './FunctionCard.css';
 | 
					import './FunctionCard.css';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const FunctionCard = forwardRef((props, ref) => {
 | 
					const FunctionCard = forwardRef((props, ref) => {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,33 +1,36 @@
 | 
				
			|||||||
import Head from 'next/head';
 | 
					import Head from 'next/head';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const HeadTag = (props) => (
 | 
					const HeadTag = ({ title, image, description }) => (
 | 
				
			||||||
    <Head>
 | 
					    <Head>
 | 
				
			||||||
        <title>{props.title}</title>
 | 
					        <title>{title}</title>
 | 
				
			||||||
        <link rel="icon" type="image/png" href={props.image} />
 | 
					        <link rel="icon" type="image/png" href={image} />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        {/* Meta Tag */}
 | 
					        {/* Meta Tag */}
 | 
				
			||||||
        <meta name="viewport" content="width=device-width, initial-scale=1" />
 | 
					        <meta name="viewport" content="width=device-width, initial-scale=1" />
 | 
				
			||||||
        <meta name="description" content={props.description} /> 
 | 
					        <meta name="description" content={description} /> 
 | 
				
			||||||
        <link rel="canonical" href="function.divlo.fr"/> 
 | 
					        <link rel="canonical" href="function.divlo.fr"/> 
 | 
				
			||||||
        <meta name="Language" content="fr" /> 
 | 
					        <meta name="Language" content="fr" /> 
 | 
				
			||||||
        <meta name="theme-color" content="#ffd800" />
 | 
					        <meta name="theme-color" content="#ffd800" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        {/* Open Graph Metadata */}
 | 
					        {/* Open Graph Metadata */}
 | 
				
			||||||
        <meta property="og:title" content={props.title} />
 | 
					        <meta property="og:title" content={title} />
 | 
				
			||||||
        <meta property="og:type" content="website" /> 
 | 
					        <meta property="og:type" content="website" /> 
 | 
				
			||||||
        <meta property="og:url" content="https://function.divlo.fr/" /> 
 | 
					        <meta property="og:url" content="https://function.divlo.fr/" /> 
 | 
				
			||||||
        <meta property="og:image" content={props.image} /> 
 | 
					        <meta property="og:image" content={image} /> 
 | 
				
			||||||
        <meta property="og:description" content={props.description} /> 
 | 
					        <meta property="og:description" content={description} /> 
 | 
				
			||||||
        <meta property="og:locale" content="fr_FR" />
 | 
					        <meta property="og:locale" content="fr_FR" />
 | 
				
			||||||
        <meta property="og:site_name" content="FunctionProject" /> 
 | 
					        <meta property="og:site_name" content="FunctionProject" /> 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        {/* Twitter card Metadata */}
 | 
					        {/* Twitter card Metadata */}
 | 
				
			||||||
        <meta name="twitter:card" content="summary" />
 | 
					        <meta name="twitter:card" content="summary" />
 | 
				
			||||||
        <meta name="twitter:description" content={props.description} />
 | 
					        <meta name="twitter:description" content={description} />
 | 
				
			||||||
        <meta name="twitter:title" content={props.title} />
 | 
					        <meta name="twitter:title" content={title} />
 | 
				
			||||||
        <meta name="twitter:site" content="@Divlo_FR" />
 | 
					        <meta name="twitter:site" content="@Divlo_FR" />
 | 
				
			||||||
        <meta name="twitter:image:src" content={props.image} />
 | 
					        <meta name="twitter:image:src" content={image} />
 | 
				
			||||||
        <meta name="twitter:creator" content="@Divlo_FR" />
 | 
					        <meta name="twitter:creator" content="@Divlo_FR" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        {/* Preloader script */}
 | 
				
			||||||
 | 
					        <script src="/js/preloader.js"></script>
 | 
				
			||||||
    </Head>
 | 
					    </Head>
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										15
									
								
								frontend/components/Loader.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								frontend/components/Loader.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					const Loader = ({ width, height, speed }) => (
 | 
				
			||||||
 | 
					    <svg width={width} height={height} viewBox="0 0 100 100">
 | 
				
			||||||
 | 
					        <g transform="translate(50 50) rotate(0) scale(1 1) translate(-50 -50)">
 | 
				
			||||||
 | 
					            <image style={{transformOrigin: "50% 50%", animation: `${speed} linear 0s infinite normal forwards running Loader__spin`}} x="0" y="0" width="100" height="100" href="/images/FunctionProject_icon.png"></image>
 | 
				
			||||||
 | 
					        </g>
 | 
				
			||||||
 | 
					    </svg>
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Loader.defaultProps = {
 | 
				
			||||||
 | 
					    width: "100px",
 | 
				
			||||||
 | 
					    height: "100px",
 | 
				
			||||||
 | 
					    speed: ".9s"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default Loader;
 | 
				
			||||||
@@ -1,13 +0,0 @@
 | 
				
			|||||||
.Loader {
 | 
					 | 
				
			||||||
    transform-origin: 50% 50%; animation: .9s linear 0s infinite normal forwards running Loader__spin;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@keyframes Loader__spin {
 | 
					 | 
				
			||||||
    0% {
 | 
					 | 
				
			||||||
        animation-timing-function: cubic-bezier(0.5856,0.0703,0.4143,0.9297);
 | 
					 | 
				
			||||||
        transform: rotate(0deg);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    100% {
 | 
					 | 
				
			||||||
        transform: rotate(360deg);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,11 +0,0 @@
 | 
				
			|||||||
import './Loader.css';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const Loader = ({ width, height }) => (
 | 
					 | 
				
			||||||
    <svg width={width} height={height} viewBox="0 0 100 100">
 | 
					 | 
				
			||||||
        <g transform="translate(50 50) rotate(0) scale(1 1) translate(-50 -50)">
 | 
					 | 
				
			||||||
            <image className="Loader" x="0" y="0" width="100" height="100" href="/images/FunctionProject_icon.png"></image>
 | 
					 | 
				
			||||||
        </g>
 | 
					 | 
				
			||||||
    </svg>
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default Loader;
 | 
					 | 
				
			||||||
							
								
								
									
										29
									
								
								frontend/pages/404.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								frontend/pages/404.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					import { Fragment } from 'react';
 | 
				
			||||||
 | 
					import Link from 'next/link';
 | 
				
			||||||
 | 
					import HeadTag from '../components/HeadTag';
 | 
				
			||||||
 | 
					import '../public/css/pages/404.css';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Error404 = () => (
 | 
				
			||||||
 | 
					    <Fragment>
 | 
				
			||||||
 | 
					        <HeadTag 
 | 
				
			||||||
 | 
					            title="Erreur 404" 
 | 
				
			||||||
 | 
					            description="Cette page n'existe pas!" 
 | 
				
			||||||
 | 
					            image="/images/error404.png" 
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
 | 
					        <div className="Error404__container">
 | 
				
			||||||
 | 
					            <h1>Erreur <span className="important">404</span></h1>
 | 
				
			||||||
 | 
					            <p className="text-center">
 | 
				
			||||||
 | 
					                Cette page n'existe pas! <Link href={"/"}><a>Revenir à la page d'accueil ?</a></Link>
 | 
				
			||||||
 | 
					            </p>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <style>
 | 
				
			||||||
 | 
					            {`
 | 
				
			||||||
 | 
					                #__next {
 | 
				
			||||||
 | 
					                    padding-top: 0;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            `}
 | 
				
			||||||
 | 
					        </style>
 | 
				
			||||||
 | 
					    </Fragment>
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default Error404;
 | 
				
			||||||
@@ -1,4 +1,5 @@
 | 
				
			|||||||
import Document, { Html, Head, Main, NextScript } from "next/document";
 | 
					import Document, { Html, Head, Main, NextScript } from "next/document";
 | 
				
			||||||
 | 
					import Loader from '../components/Loader';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MyDocument extends Document {
 | 
					class MyDocument extends Document {
 | 
				
			||||||
    static async getInitialProps(ctx) {
 | 
					    static async getInitialProps(ctx) {
 | 
				
			||||||
@@ -11,7 +12,12 @@ class MyDocument extends Document {
 | 
				
			|||||||
            <Html lang="fr">
 | 
					            <Html lang="fr">
 | 
				
			||||||
                <Head />
 | 
					                <Head />
 | 
				
			||||||
                <body>
 | 
					                <body>
 | 
				
			||||||
 | 
					                    <div id="preloader">
 | 
				
			||||||
 | 
					                        <Loader />
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                    <div className="isLoading">
 | 
				
			||||||
                        <Main />
 | 
					                        <Main />
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
                    <NextScript />
 | 
					                    <NextScript />
 | 
				
			||||||
                </body>
 | 
					                </body>
 | 
				
			||||||
            </Html>
 | 
					            </Html>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
import { Fragment, useState, useEffect, useRef, useCallback } from 'react';
 | 
					import { Fragment, useState, useEffect, useRef, useCallback } from 'react';
 | 
				
			||||||
import HeadTag from '../components/HeadTag';
 | 
					import HeadTag from '../components/HeadTag';
 | 
				
			||||||
import FunctionCard from '../components/FunctionCard/FunctionCard';
 | 
					import FunctionCard from '../components/FunctionCard/FunctionCard';
 | 
				
			||||||
import Loader from '../components/Loader/Loader';
 | 
					import Loader from '../components/Loader';
 | 
				
			||||||
import '../public/css/pages/functions.css';
 | 
					import '../public/css/pages/functions.css';
 | 
				
			||||||
import { API_URL } from '../config/config';
 | 
					import { API_URL } from '../config/config';
 | 
				
			||||||
import api from '../config/api';
 | 
					import api from '../config/api';
 | 
				
			||||||
@@ -91,7 +91,7 @@ const Functions = () => {
 | 
				
			|||||||
                        return <FunctionCard key={f.id} slug={f.slug} image={API_URL + f.image} title={f.title} description={f.description} category={f.categorie} publicationDate={new Date(f.createdAt).toLocaleDateString('fr-FR')} />;
 | 
					                        return <FunctionCard key={f.id} slug={f.slug} image={API_URL + f.image} title={f.title} description={f.description} category={f.categorie} publicationDate={new Date(f.createdAt).toLocaleDateString('fr-FR')} />;
 | 
				
			||||||
                    })}
 | 
					                    })}
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
                {isLoadingFunctions && <Loader width="100px" height="100px" />}
 | 
					                {isLoadingFunctions && <Loader />}
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </Fragment>
 | 
					        </Fragment>
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -45,6 +45,26 @@ a:hover {
 | 
				
			|||||||
    align-items: center;
 | 
					    align-items: center;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* LOADING */
 | 
				
			||||||
 | 
					.isLoading {
 | 
				
			||||||
 | 
					    display: none;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#preloader {
 | 
				
			||||||
 | 
					    min-height: 100vh;
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    justify-content: center;
 | 
				
			||||||
 | 
					    align-items: center;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					@keyframes Loader__spin {
 | 
				
			||||||
 | 
					    0% {
 | 
				
			||||||
 | 
					        animation-timing-function: cubic-bezier(0.5856, 0.0703, 0.4143, 0.9297);
 | 
				
			||||||
 | 
					        transform: rotate(0deg);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    100% {
 | 
				
			||||||
 | 
					        transform: rotate(360deg);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* UTILITIES */
 | 
					/* UTILITIES */
 | 
				
			||||||
.text-center {
 | 
					.text-center {
 | 
				
			||||||
    text-align: center;
 | 
					    text-align: center;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										7
									
								
								frontend/public/css/pages/404.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								frontend/public/css/pages/404.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					.Error404__container {
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    flex-direction: column;
 | 
				
			||||||
 | 
					    justify-content: center;
 | 
				
			||||||
 | 
					    align-items: center;
 | 
				
			||||||
 | 
					    min-width: 100%;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								frontend/public/images/error404.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								frontend/public/images/error404.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 168 KiB  | 
							
								
								
									
										4
									
								
								frontend/public/js/preloader.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								frontend/public/js/preloader.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					window.addEventListener('load', () => {
 | 
				
			||||||
 | 
					    document.querySelector('.isLoading').classList.remove('isLoading');
 | 
				
			||||||
 | 
					    document.getElementById('preloader').remove();
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
		Reference in New Issue
	
	Block a user