Added map

This commit is contained in:
2024-09-03 18:18:49 +02:00
parent 282ef00aa3
commit a4d77952de
24 changed files with 8075 additions and 0 deletions
+48
View File
@@ -0,0 +1,48 @@
// ---------------------------------------------------------------------------------------------------------------------
//! Imports
// ---------------------------------------------------------------------------------------------------------------------
// --------------------------------------------------- Components ------------------------------------------------------
import Image from 'next/image';
// ---------------------------------------------------------------------------------------------------------------------
// ------------------------------------------------- Assets & Styles ---------------------------------------------------
import '../styles.scss';
// ---------------------------------------------------------------------------------------------------------------------
const Forgot = () => {
return (
<div className='authContainer'>
<Image
src={'/logo-transparent.png'}
className='appLogo'
alt='appLogo'
width={1024}
height={1024}
/>
<div className='formContainer'>
<h1 className='formTitle'>Connexion</h1>
<div
role='form'
className='form'
>
<div className='inputContainer'>
<input
type='password'
name='password'
className='input'
required
/>
<label className='inputLabel'>Mot de passe</label>
</div>
</div>
<div className='buttonsContainer'>
<button className='submitButton'>Se connecter</button>
</div>
</div>
</div>
);
};
export default Forgot;
+7
View File
@@ -0,0 +1,7 @@
export const useActions = ({ emailRef, passwordRef }) => {
const handleSubmit = () => {};
return {
handleSubmit,
};
};
+11
View File
@@ -0,0 +1,11 @@
import { useRef } from 'react';
export const useData = () => {
const emailRef = useRef(null);
const passwordRef = useRef(null);
return {
emailRef,
passwordRef,
};
};
+88
View File
@@ -0,0 +1,88 @@
'use client';
// ---------------------------------------------------------------------------------------------------------------------
//! Imports
// ---------------------------------------------------------------------------------------------------------------------
// --------------------------------------------------- Components ------------------------------------------------------
import Image from 'next/image';
import Link from 'next/link';
// ---------------------------------------------------------------------------------------------------------------------
// -------------------------------------------------- Hooks & Utils ----------------------------------------------------
import { useData } from './hooks/useData';
import { useActions } from './hooks/useActions';
// ---------------------------------------------------------------------------------------------------------------------
// ------------------------------------------------- Assets & Styles ---------------------------------------------------
import '../styles.scss';
// ---------------------------------------------------------------------------------------------------------------------
const Login = () => {
const { emailRef, passwordRef } = useData();
const { handleSubmit } = useActions({ emailRef, passwordRef });
return (
<div className='authContainer'>
<Image
src={'/logo-transparent.png'}
className='appLogo'
alt='appLogo'
width={1024}
height={1024}
/>
<div className='formContainer'>
<h1 className='formTitle'>Connexion</h1>
<div
role='form'
className='form'
>
<div className='inputContainer'>
<input
ref={emailRef}
type='email'
name='email'
className='input'
required
/>
<label className='inputLabel'>Adresse e-mail</label>
</div>
<div className='inputContainer'>
<input
ref={passwordRef}
type='password'
name='password'
className='input'
required
/>
<label className='inputLabel'>Mot de passe</label>
</div>
<Link
href={'/auth/forgot'}
className='forgetLink'
>
Mot de passe oublié ?
</Link>
</div>
<div className='buttonsContainer'>
<button
className='submitButton'
onClick={handleSubmit}
>
Se connecter
</button>
<Link
href={'/auth/register'}
className='submitButton secondary'
>
S&apos;inscrire
</Link>
</div>
</div>
</div>
);
};
export default Login;
+12
View File
@@ -0,0 +1,12 @@
export const useActions = ({
usernameRef,
emailRef,
passwordRef,
confpasswordRef,
}) => {
const handleSubmit = () => {};
return {
handleSubmit,
};
};
+15
View File
@@ -0,0 +1,15 @@
import { useRef } from 'react';
export const useData = () => {
const usernameRef = useRef(null);
const emailRef = useRef(null);
const passwordRef = useRef(null);
const confpasswordRef = useRef(null);
return {
usernameRef,
emailRef,
passwordRef,
confpasswordRef,
};
};
+110
View File
@@ -0,0 +1,110 @@
'use client';
// ---------------------------------------------------------------------------------------------------------------------
//! Imports
// ---------------------------------------------------------------------------------------------------------------------
// --------------------------------------------------- Components ------------------------------------------------------
import Image from 'next/image';
import Link from 'next/link';
// ---------------------------------------------------------------------------------------------------------------------
// -------------------------------------------------- Hooks & Utils ----------------------------------------------------
import { useData } from './hooks/useData';
import { useActions } from './hooks/useActions';
// ---------------------------------------------------------------------------------------------------------------------
// ------------------------------------------------- Assets & Styles ---------------------------------------------------
import '../styles.scss';
// ---------------------------------------------------------------------------------------------------------------------
const Register = () => {
const { usernameRef, emailRef, passwordRef, confpasswordRef } = useData();
const { handleSubmit } = useActions({
usernameRef,
emailRef,
passwordRef,
confpasswordRef,
});
return (
<div className='authContainer'>
<Image
src={'/logo-transparent.png'}
className='appLogo'
alt='appLogo'
width={1024}
height={1024}
/>
<div className='formContainer'>
<h1 className='formTitle'>Inscription</h1>
<div
role='form'
className='form'
>
<div className='inputContainer'>
<input
ref={usernameRef}
type='text'
name='name'
className='input'
required
/>
<label className='inputLabel'>
Nom d&apos;utilisateur
</label>
</div>
<div className='inputContainer'>
<input
ref={emailRef}
type='email'
name='email'
className='input'
required
/>
<label className='inputLabel'>Adresse e-mail</label>
</div>
<div className='inputContainer'>
<input
ref={passwordRef}
type='password'
name='password'
className='input'
required
/>
<label className='inputLabel'>Mot de passe</label>
</div>
<div className='inputContainer'>
<input
ref={confpasswordRef}
type='password'
name='confpassword'
className='input'
required
/>
<label className='inputLabel'>
Confirmer le mot de passe
</label>
</div>
</div>
<div className='buttonsContainer'>
<button
className='submitButton'
onClick={handleSubmit}
>
S&apos;inscrire
</button>
<Link
href={'/auth/login'}
className='submitButton secondary'
>
Se connecter
</Link>
</div>
</div>
</div>
);
};
export default Register;
+131
View File
@@ -0,0 +1,131 @@
.authContainer {
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100svw;
height: 100svh;
& > .appLogo {
position: absolute;
top: 5svh;
width: 30svw;
height: auto;
}
& > .formContainer {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 10px;
padding: 30px 60px;
width: 95svw;
max-width: 450px;
border: 3px solid #fefefa;
border-radius: 7px;
background-color: #d94253;
& > .formTitle {
margin-bottom: 20px;
font-size: 2rem;
font-weight: 300;
text-align: center;
color: #fefefa;
}
& > .form {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 15px;
& > .inputContainer {
position: relative;
display: grid;
& > .inputLabel {
position: absolute;
top: 50%;
left: 15px;
transform: translateY(-50%);
padding: 5px;
background-color: #d94253;
color: #fefefa;
user-select: none;
pointer-events: none;
transition: top 0.3s ease, left 0.3s ease,
font-size 0.3s ease, transform 0.3s ease;
}
& > .input {
padding: 10px;
border: 2px solid #fefefa;
border-radius: 5px;
background-color: #d94253;
outline: none;
font-size: 1em;
color: #fefefa;
&:focus + .inputLabel {
top: 0;
left: 10px;
transform: translateY(-50%);
font-size: 0.9em;
}
}
}
& > .forgetLink {
position: relative;
width: max-content;
font-size: 0.8rem;
color: #dff8f2;
cursor: pointer;
&::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
display: block;
width: 0;
height: 1px;
background-color: #dff8f2;
transition: width 0.3s ease;
}
&:hover::after {
width: 100%;
}
}
}
& > .buttonsContainer {
display: grid;
grid-template-columns: repeat(2, 1fr);
align-items: center;
gap: 30px;
margin-top: 15px;
& > .submitButton {
display: flex;
justify-content: center;
align-items: center;
gap: 5px;
padding: 7px 21px;
border: 2px solid #fefefa;
border-radius: 5px;
background-color: #fefefa;
font-size: 0.9rem;
color: #d94253;
cursor: pointer;
&.secondary {
background-color: #d94253;
color: #fefefa;
}
}
}
}
}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

+23
View File
@@ -0,0 +1,23 @@
* {
box-sizing: border-box;
padding: 0;
margin: 0;
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
body {
position: relative;
width: 100svw;
height: 100svh;
background-color: #d94253;
}
a {
color: inherit;
text-decoration: none;
}
+43
View File
@@ -0,0 +1,43 @@
import { useEffect, useState } from 'react';
export const useData = () => {
const [canUseGeolocation, setCanUseGeolocation] = useState(false);
const [geoError, setGeoError] = useState(null);
const [initialState, setInitialState] = useState({
longitude: 2.209666999999996,
latitude: 46.232192999999995,
zoom: 5,
});
useEffect(() => {
if ('geolocation' in navigator == false) {
setCanUseGeolocation(false);
return;
}
setCanUseGeolocation(true);
navigator.geolocation.getCurrentPosition(
position => {
setInitialState(prev => ({
...prev,
latitude: position.coords.latitude,
longitude: position.coords.longitude,
}));
},
error => {
if (error.PERMISSION_DENIED) {
setGeoError('permission_denied');
console.warn(error.message);
}
}
);
}, []);
return {
initialState,
geoError,
canUseGeolocation,
};
};
+18
View File
@@ -0,0 +1,18 @@
import { Inter } from 'next/font/google';
import './globals.scss';
const inter = Inter({ subsets: ['latin'] });
export const metadata = {
title: 'Lovemap ❤️',
};
const RootLayout = ({ children }) => {
return (
<html lang='fr'>
<body className={inter.className}>{children}</body>
</html>
);
};
export default RootLayout;
+64
View File
@@ -0,0 +1,64 @@
'use client';
// ---------------------------------------------------------------------------------------------------------------------
// Imports
// ---------------------------------------------------------------------------------------------------------------------
// --------------------------------------------------- Components ------------------------------------------------------
import { DeckGL } from 'deck.gl';
import { Map } from 'react-map-gl';
// ---------------------------------------------------------------------------------------------------------------------
// -------------------------------------------------- Hooks & Utils ----------------------------------------------------
import { useData } from './hooks/useData';
// ---------------------------------------------------------------------------------------------------------------------
// ------------------------------------------------- Assets & Styles ---------------------------------------------------
import './styles.scss';
import 'mapbox-gl/dist/mapbox-gl.css';
// ---------------------------------------------------------------------------------------------------------------------
const Home = () => {
const { canUseGeolocation, geoError, initialState } = useData();
if (!canUseGeolocation && !geoError) {
return <p className='appMessage'>Chargement...</p>;
}
if (!canUseGeolocation && geoError) {
return (
<p className='appMessage'>
Nous avons besoin d&apos;accéder à votre position pour pouvoir
utiliser l&apos;application.
</p>
);
}
return (
<div className='mapContainer'>
<DeckGL
initialViewState={initialState}
layers={[]}
controller
useDevicePixels={false}
getCursor={({ isDragging }) =>
isDragging ? 'grabbing' : 'grab'
}
>
<Map
logoPosition='bottom-right'
style={{
width: '100%',
height: '100%',
}}
mapboxAccessToken={process.env.MAPBOX_TOKEN}
mapStyle={
'mapbox://styles/unepicier/cm0l8fydz009v01qkh9bvau16'
}
preserveDrawingBuffer
></Map>
</DeckGL>
</div>
);
};
export default Home;
+21
View File
@@ -0,0 +1,21 @@
.mapContainer {
position: relative;
width: 100svw;
height: 100svh;
}
.appMessage {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: block;
width: 90svw;
font-size: 2rem;
text-align: center;
color: #ffffff;
@media (max-width: 992px) {
font-size: 1.2rem;
}
}