Edit profile page

This commit is contained in:
2024-09-13 19:09:51 +02:00
parent 3b90f9acd2
commit 172208a978
16 changed files with 414 additions and 100 deletions
+3 -2
View File
@@ -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
View File
@@ -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>
+73
View File
@@ -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;
+93
View File
@@ -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;
}
}
+10
View File
@@ -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
View File
@@ -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;
+15
View File
@@ -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;
-43
View File
@@ -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;
+59
View File
@@ -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;
+88
View File
@@ -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;
+50
View File
@@ -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;
}
}
+4 -10
View File
@@ -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,
},
];
+2 -2
View File
@@ -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);
}
}