✨ Edit profile page
This commit is contained in:
+3
-2
@@ -8,13 +8,14 @@
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
body {
|
||||
--navSize: 60px;
|
||||
position: relative;
|
||||
display: grid;
|
||||
grid-template-rows: calc(100svh - var(--navSize)) var(--navSize);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100svw;
|
||||
height: 100svh;
|
||||
background-color: #d94253;
|
||||
|
||||
+1
-3
@@ -52,9 +52,7 @@ const Home = () => {
|
||||
height: '100%',
|
||||
}}
|
||||
mapboxAccessToken={process.env.MAPBOX_TOKEN}
|
||||
mapStyle={
|
||||
'mapbox://styles/unepicier/cm0o1bhc400gd01qkeubpb2za'
|
||||
}
|
||||
mapStyle={'mapbox://styles/mapbox/standard'}
|
||||
preserveDrawingBuffer
|
||||
></Map>
|
||||
</DeckGL>
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
//! Imports
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// --------------------------------------------------- Components ------------------------------------------------------
|
||||
import Link from 'next/link';
|
||||
import Input from '@/components/Input/Input';
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// ------------------------------------------------- Assets & Styles ---------------------------------------------------
|
||||
import ArrowRightIcon from '@/assets/ArrowRightIcon';
|
||||
import './styles.scss';
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
const Settings = () => {
|
||||
return (
|
||||
<div className='settings'>
|
||||
<div className='header'>
|
||||
<Link
|
||||
href={'/statistics'}
|
||||
className='backButton'
|
||||
>
|
||||
<ArrowRightIcon
|
||||
style={{
|
||||
rotate: '180deg',
|
||||
}}
|
||||
/>
|
||||
</Link>
|
||||
<p className='title'>Éditer le profil</p>
|
||||
</div>
|
||||
|
||||
<form className='form'>
|
||||
<Input
|
||||
label="Nom d'utilisateur"
|
||||
type='text'
|
||||
name='username'
|
||||
defaultValue='Un Épicier'
|
||||
autoComplete='off'
|
||||
required
|
||||
/>
|
||||
<Input
|
||||
label='Mot de passe'
|
||||
type='password'
|
||||
name='password'
|
||||
defaultValue='********'
|
||||
autoComplete='off'
|
||||
required
|
||||
/>
|
||||
|
||||
<div className='buttonsContainer'>
|
||||
<button
|
||||
type='reset'
|
||||
className='resetButton'
|
||||
>
|
||||
Annuler
|
||||
</button>
|
||||
<button
|
||||
type='submit'
|
||||
className='submitButton'
|
||||
>
|
||||
Appliquer
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div className='separator' />
|
||||
|
||||
<button className='deleteButton'>Supprimer mon compte</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Settings;
|
||||
@@ -0,0 +1,93 @@
|
||||
.settings {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
width: 100%;
|
||||
background-color: #d94253;
|
||||
|
||||
& > .header {
|
||||
display: grid;
|
||||
grid-template-columns: 25px 1fr;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
padding: 15px;
|
||||
color: #ffffff;
|
||||
box-shadow: 0 0 6px rgba(255, 255, 255, 0.2);
|
||||
|
||||
& > .backButton {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
& > .title {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
}
|
||||
|
||||
& > .form {
|
||||
display: grid;
|
||||
grid-template-rows: repeat(2, 1fr);
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
padding: 20px;
|
||||
padding-bottom: 0;
|
||||
|
||||
& > .buttonsContainer {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 20px;
|
||||
|
||||
& > .submitButton,
|
||||
& > .resetButton {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
padding: 10px;
|
||||
border: 1px solid #ffffff;
|
||||
border-radius: 5px;
|
||||
background-color: #ffffff;
|
||||
font-size: 1rem;
|
||||
color: #d94253;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
& > .resetButton {
|
||||
background-color: #d94253;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& > .separator {
|
||||
display: block;
|
||||
margin: 20px auto;
|
||||
width: 90%;
|
||||
height: 1px;
|
||||
background-color: rgb(254, 254, 250);
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(254, 254, 250, 0) 0%,
|
||||
rgba(254, 254, 250, 1) 10%,
|
||||
rgba(254, 254, 250, 1) 90%,
|
||||
rgba(254, 254, 250, 0) 100%
|
||||
);
|
||||
}
|
||||
|
||||
& > .deleteButton {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
margin: 0 20px;
|
||||
padding: 10px;
|
||||
border: 1px solid #d80135;
|
||||
border-radius: 5px;
|
||||
background-color: #d80135;
|
||||
font-size: 1rem;
|
||||
color: #ffffff;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { useState } from 'react';
|
||||
|
||||
export const useData = () => {
|
||||
const [settingsOpened, setSettingsOpened] = useState(false);
|
||||
|
||||
return {
|
||||
settingsOpened,
|
||||
setSettingsOpened,
|
||||
};
|
||||
};
|
||||
@@ -1,3 +1,5 @@
|
||||
'use client';
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
//! Imports
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
@@ -9,11 +11,10 @@ import SlotCounter from 'react-slot-counter';
|
||||
|
||||
// ------------------------------------------------- Assets & Styles ---------------------------------------------------
|
||||
import SettingsIcon from '@/assets/SettingsIcon';
|
||||
import ArrowRightIcon from '@/assets/ArrowRightIcon';
|
||||
import './styles.scss';
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
const Account = () => {
|
||||
const Statistics = () => {
|
||||
return (
|
||||
<div className='accountContainer'>
|
||||
<div className='header'>
|
||||
@@ -31,28 +32,6 @@ const Account = () => {
|
||||
</div>
|
||||
<div className='separator' />
|
||||
<div className='statistics'>
|
||||
<div className='statistic'>
|
||||
<SlotCounter
|
||||
value={'00'}
|
||||
startValue={'00'}
|
||||
startValueOnce
|
||||
dummyCharacterCount={10}
|
||||
direction='top-bottom'
|
||||
containerClassName='slotCounter'
|
||||
/>
|
||||
<p className='statName'>Followers</p>
|
||||
</div>
|
||||
<div className='statistic'>
|
||||
<SlotCounter
|
||||
value={'00'}
|
||||
startValue={'00'}
|
||||
startValueOnce
|
||||
dummyCharacterCount={10}
|
||||
direction='top-bottom'
|
||||
containerClassName='slotCounter'
|
||||
/>
|
||||
<p className='statName'>Suivis</p>
|
||||
</div>
|
||||
<div className='statistic'>
|
||||
<SlotCounter
|
||||
value={'00'}
|
||||
@@ -98,16 +77,8 @@ const Account = () => {
|
||||
<p className='statName'>Loves total</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className='buttonsContainer'>
|
||||
<button className='button'>
|
||||
Followers <ArrowRightIcon />
|
||||
</button>
|
||||
<button className='button'>
|
||||
Suivis <ArrowRightIcon />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Account;
|
||||
export default Statistics;
|
||||
@@ -1,4 +1,6 @@
|
||||
.accountContainer {
|
||||
flex-grow: 1;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
@@ -84,7 +86,7 @@
|
||||
align-items: stretch;
|
||||
gap: 2px;
|
||||
width: 100%;
|
||||
box-shadow: 0 0 6px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: 0 0 6px rgba(255, 255, 255, 0.2);
|
||||
|
||||
& > .button {
|
||||
display: flex;
|
||||
+2
-1
@@ -1,5 +1,6 @@
|
||||
.mapContainer {
|
||||
position: relative;
|
||||
flex-grow: 1;
|
||||
|
||||
& > .dropLove {
|
||||
z-index: 1;
|
||||
@@ -16,7 +17,7 @@
|
||||
border-radius: 300px;
|
||||
background-color: #d94253;
|
||||
color: #ffffff;
|
||||
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.6);
|
||||
box-shadow: 0 2px 6px rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const AccountIcon = (props) => {
|
||||
const EyeIcon = (props) => {
|
||||
return (
|
||||
<svg
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
@@ -6,15 +6,17 @@ const AccountIcon = (props) => {
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d='M344 144c-3.92 52.87-44 96-88 96s-84.15-43.12-88-96c-4-55 35-96 88-96s92 42 88 96z'
|
||||
d='M255.66 112c-77.94 0-157.89 45.11-220.83 135.33a16 16 0 00-.27 17.77C82.92 340.8 161.8 400 255.66 400c92.84 0 173.34-59.38 221.79-135.25a16.14 16.14 0 000-17.47C428.89 172.28 347.8 112 255.66 112z'
|
||||
fill='none'
|
||||
stroke='currentColor'
|
||||
strokeLinecap='round'
|
||||
strokeLinejoin='round'
|
||||
strokeWidth='32'
|
||||
/>
|
||||
<path
|
||||
d='M256 304c-87 0-175.3 48-191.64 138.6C62.39 453.52 68.57 464 80 464h352c11.44 0 17.62-10.48 15.65-21.4C431.3 352 343 304 256 304z'
|
||||
<circle
|
||||
cx='256'
|
||||
cy='256'
|
||||
r='80'
|
||||
fill='none'
|
||||
stroke='currentColor'
|
||||
strokeMiterlimit='10'
|
||||
@@ -24,4 +26,4 @@ const AccountIcon = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default AccountIcon;
|
||||
export default EyeIcon;
|
||||
@@ -0,0 +1,15 @@
|
||||
const EyeSlashIcon = (props) => {
|
||||
return (
|
||||
<svg
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
viewBox='0 0 512 512'
|
||||
{...props}
|
||||
fill='currentColor'
|
||||
>
|
||||
<path d='M432 448a15.92 15.92 0 01-11.31-4.69l-352-352a16 16 0 0122.62-22.62l352 352A16 16 0 01432 448zM255.66 384c-41.49 0-81.5-12.28-118.92-36.5-34.07-22-64.74-53.51-88.7-91v-.08c19.94-28.57 41.78-52.73 65.24-72.21a2 2 0 00.14-2.94L93.5 161.38a2 2 0 00-2.71-.12c-24.92 21-48.05 46.76-69.08 76.92a31.92 31.92 0 00-.64 35.54c26.41 41.33 60.4 76.14 98.28 100.65C162 402 207.9 416 255.66 416a239.13 239.13 0 0075.8-12.58 2 2 0 00.77-3.31l-21.58-21.58a4 4 0 00-3.83-1 204.8 204.8 0 01-51.16 6.47zM490.84 238.6c-26.46-40.92-60.79-75.68-99.27-100.53C349 110.55 302 96 255.66 96a227.34 227.34 0 00-74.89 12.83 2 2 0 00-.75 3.31l21.55 21.55a4 4 0 003.88 1 192.82 192.82 0 0150.21-6.69c40.69 0 80.58 12.43 118.55 37 34.71 22.4 65.74 53.88 89.76 91a.13.13 0 010 .16 310.72 310.72 0 01-64.12 72.73 2 2 0 00-.15 2.95l19.9 19.89a2 2 0 002.7.13 343.49 343.49 0 0068.64-78.48 32.2 32.2 0 00-.1-34.78z' />
|
||||
<path d='M256 160a95.88 95.88 0 00-21.37 2.4 2 2 0 00-1 3.38l112.59 112.56a2 2 0 003.38-1A96 96 0 00256 160zM165.78 233.66a2 2 0 00-3.38 1 96 96 0 00115 115 2 2 0 001-3.38z' />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default EyeSlashIcon;
|
||||
@@ -1,43 +0,0 @@
|
||||
const PeopleIcon = (props) => {
|
||||
return (
|
||||
<svg
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
viewBox='0 0 512 512'
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d='M402 168c-2.93 40.67-33.1 72-66 72s-63.12-31.32-66-72c-3-42.31 26.37-72 66-72s69 30.46 66 72z'
|
||||
fill='none'
|
||||
stroke='currentColor'
|
||||
strokeLinecap='round'
|
||||
strokeLinejoin='round'
|
||||
strokeWidth='32'
|
||||
/>
|
||||
<path
|
||||
d='M336 304c-65.17 0-127.84 32.37-143.54 95.41-2.08 8.34 3.15 16.59 11.72 16.59h263.65c8.57 0 13.77-8.25 11.72-16.59C463.85 335.36 401.18 304 336 304z'
|
||||
fill='none'
|
||||
stroke='currentColor'
|
||||
strokeMiterlimit='10'
|
||||
strokeWidth='32'
|
||||
/>
|
||||
<path
|
||||
d='M200 185.94c-2.34 32.48-26.72 58.06-53 58.06s-50.7-25.57-53-58.06C91.61 152.15 115.34 128 147 128s55.39 24.77 53 57.94z'
|
||||
fill='none'
|
||||
stroke='currentColor'
|
||||
strokeLinecap='round'
|
||||
strokeLinejoin='round'
|
||||
strokeWidth='32'
|
||||
/>
|
||||
<path
|
||||
d='M206 306c-18.05-8.27-37.93-11.45-59-11.45-52 0-102.1 25.85-114.65 76.2-1.65 6.66 2.53 13.25 9.37 13.25H154'
|
||||
fill='none'
|
||||
stroke='currentColor'
|
||||
strokeLinecap='round'
|
||||
strokeMiterlimit='10'
|
||||
strokeWidth='32'
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default PeopleIcon;
|
||||
@@ -0,0 +1,59 @@
|
||||
const StatsIcon = (props) => {
|
||||
return (
|
||||
<svg
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
viewBox='0 0 512 512'
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d='M32 32v432a16 16 0 0016 16h432'
|
||||
fill='none'
|
||||
stroke='currentColor'
|
||||
strokeLinecap='round'
|
||||
strokeLinejoin='round'
|
||||
strokeWidth='24'
|
||||
/>
|
||||
<rect
|
||||
x='96'
|
||||
y='224'
|
||||
width='80'
|
||||
height='192'
|
||||
rx='20'
|
||||
ry='20'
|
||||
fill='none'
|
||||
stroke='currentColor'
|
||||
strokeLinecap='round'
|
||||
strokeLinejoin='round'
|
||||
strokeWidth='24'
|
||||
/>
|
||||
<rect
|
||||
x='240'
|
||||
y='176'
|
||||
width='80'
|
||||
height='240'
|
||||
rx='20'
|
||||
ry='20'
|
||||
fill='none'
|
||||
stroke='currentColor'
|
||||
strokeLinecap='round'
|
||||
strokeLinejoin='round'
|
||||
strokeWidth='24'
|
||||
/>
|
||||
<rect
|
||||
x='383.64'
|
||||
y='112'
|
||||
width='80'
|
||||
height='304'
|
||||
rx='20'
|
||||
ry='20'
|
||||
fill='none'
|
||||
stroke='currentColor'
|
||||
strokeLinecap='round'
|
||||
strokeLinejoin='round'
|
||||
strokeWidth='24'
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default StatsIcon;
|
||||
@@ -0,0 +1,88 @@
|
||||
'use client';
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
//! Imports
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// ------------------------------------------------------ React --------------------------------------------------------
|
||||
import { forwardRef, useState } from 'react';
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// ------------------------------------------------- Assets & Styles ---------------------------------------------------
|
||||
import EyeSlashIcon from '@/assets/EyeSlashIcon';
|
||||
import EyeIcon from '@/assets/EyeIcon';
|
||||
import './styles.scss';
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
const Input = forwardRef(function InputComponent(
|
||||
{
|
||||
type = 'text',
|
||||
label,
|
||||
name,
|
||||
value,
|
||||
defaultValue,
|
||||
autoComplete,
|
||||
required = false,
|
||||
onChange,
|
||||
onKeyUp,
|
||||
onKeyDown,
|
||||
},
|
||||
ref
|
||||
) {
|
||||
const [isFocused, setIsFocused] = useState(
|
||||
defaultValue || value ? true : false
|
||||
);
|
||||
const [passwordVisibility, setPasswordVisibility] = useState(false);
|
||||
|
||||
const defaultOnBlur = (ev) => {
|
||||
if (ev.currentTarget.value != '') {
|
||||
return;
|
||||
}
|
||||
|
||||
setIsFocused(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className='inputContainer'>
|
||||
<input
|
||||
ref={ref}
|
||||
type={
|
||||
type == 'password'
|
||||
? passwordVisibility
|
||||
? 'text'
|
||||
: 'password'
|
||||
: type
|
||||
}
|
||||
name={name}
|
||||
id={name}
|
||||
value={value}
|
||||
defaultValue={defaultValue}
|
||||
autoComplete={autoComplete}
|
||||
required={required}
|
||||
onChange={onChange}
|
||||
onKeyUp={onKeyUp}
|
||||
onKeyDown={onKeyDown}
|
||||
className='input'
|
||||
onFocus={() => setIsFocused(true)}
|
||||
onBlur={defaultOnBlur}
|
||||
/>
|
||||
<label
|
||||
htmlFor={name}
|
||||
className={`inputLabel ${isFocused ? 'focused' : ''}`}
|
||||
>
|
||||
{label}
|
||||
</label>
|
||||
{type == 'password' && (
|
||||
<button
|
||||
type='button'
|
||||
className='passwordToggleButton'
|
||||
onClick={() => setPasswordVisibility((prev) => !prev)}
|
||||
>
|
||||
{passwordVisibility ? <EyeSlashIcon /> : <EyeIcon />}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export default Input;
|
||||
@@ -0,0 +1,50 @@
|
||||
.inputContainer {
|
||||
position: relative;
|
||||
font-size: 1.1rem;
|
||||
|
||||
& > .inputLabel {
|
||||
position: absolute;
|
||||
top: 48%;
|
||||
left: 10px;
|
||||
transform: translateY(-50%);
|
||||
padding: 0 4px;
|
||||
background-color: #d94253;
|
||||
font-size: 1em;
|
||||
font-weight: 300;
|
||||
color: #ffffff;
|
||||
transition: top 0.3s ease, font-size 0.3s ease;
|
||||
pointer-events: none;
|
||||
|
||||
&.focused {
|
||||
top: 0;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
}
|
||||
|
||||
& > .input {
|
||||
padding: 10px 20px;
|
||||
width: 100%;
|
||||
border: 1px solid #ffffff;
|
||||
border-radius: 5px;
|
||||
background-color: #d94253;
|
||||
font-size: 1em;
|
||||
font-weight: 300;
|
||||
color: #ffffff;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
& > .passwordToggleButton {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 7px;
|
||||
width: calc(20px + 1em);
|
||||
height: 100%;
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
import AccountIcon from '@/assets/AccountIcon';
|
||||
import StatsIcon from '@/assets/StatsIcon';
|
||||
import HeartIcon from '@/assets/HeartIcon';
|
||||
import MapIcon from '@/assets/MapIcon';
|
||||
import PeopleIcon from '@/assets/PeopleIcon';
|
||||
|
||||
const config = [
|
||||
{
|
||||
@@ -15,14 +14,9 @@ const config = [
|
||||
icon: HeartIcon,
|
||||
},
|
||||
{
|
||||
title: 'Partenaire',
|
||||
link: '/partner',
|
||||
icon: PeopleIcon,
|
||||
},
|
||||
{
|
||||
title: 'Profil',
|
||||
link: '/account',
|
||||
icon: AccountIcon,
|
||||
title: 'Stats',
|
||||
link: '/statistics',
|
||||
icon: StatsIcon,
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
width: 100svw;
|
||||
height: var(--navSize);
|
||||
background-color: #d94253;
|
||||
box-shadow: 0 0 6px rgba(0, 0, 0, 0.6);
|
||||
box-shadow: 0 0 6px rgba(255, 255, 255, 0.6);
|
||||
|
||||
& > .navButton {
|
||||
position: relative;
|
||||
@@ -39,7 +39,7 @@
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 6px rgba(0, 0, 0, 0.6);
|
||||
box-shadow: 0 0 6px rgba(255, 255, 255, 0.6);
|
||||
clip-path: inset(-6px -6px 42px -6px);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user