diff --git a/src/assets/bell.svg b/src/assets/bell.svg new file mode 100644 index 0000000..54defaf --- /dev/null +++ b/src/assets/bell.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/close.svg b/src/assets/close.svg new file mode 100644 index 0000000..2c9f443 --- /dev/null +++ b/src/assets/close.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/logo.png b/src/assets/logo.png new file mode 100644 index 0000000..cfe8d7c Binary files /dev/null and b/src/assets/logo.png differ diff --git a/src/assets/person.svg b/src/assets/person.svg new file mode 100644 index 0000000..22c4d5d --- /dev/null +++ b/src/assets/person.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/Header/Header.jsx b/src/components/Header/Header.jsx new file mode 100644 index 0000000..e698d86 --- /dev/null +++ b/src/components/Header/Header.jsx @@ -0,0 +1,129 @@ +import styles from "./Header.module.css" +import { Link, NavLink } from "react-router"; +import { useEffect, useRef, useState } from "react"; + +function Header() { + const [notificationMenu, setnotificationMenu] = useState(false); + const [unreadNotification, setunreadNotification] = useState(true); + const [mobileMenu, setMobileMenu] = useState(false); + const notificationRef = useRef(null); + + const [notifications, setNotifications] = useState([ + "Vous avez un nouveau message !", + "Jean Paul est en attente de validation !", + "Vous avez un nouveau message !" + ]); + + useEffect(() => { + const handleClickOutside = (event) => { + if ( + notificationRef.current && + !notificationRef.current.contains(event.target) && + !event.target.closest(`.${styles.bellBtn}`) + ) { + setnotificationMenu(false); + } + }; + + document.addEventListener("mousedown", handleClickOutside); + return () => { + document.removeEventListener("mousedown", handleClickOutside); + }; + }, []); + + return ( +
+
+ + + + + + +
+ + + + +
+ {notifications.length === 0 ? ( +

Vous n'avez aucune notification !

+ ) : ( + notifications.map((notification, index) => ( +
+

{notification}

+ +
+ )) + )} +
+
+ ); +} + +export default Header; \ No newline at end of file diff --git a/src/components/Header/Header.module.css b/src/components/Header/Header.module.css new file mode 100644 index 0000000..9aa046a --- /dev/null +++ b/src/components/Header/Header.module.css @@ -0,0 +1,272 @@ +.headerContainer { + position: relative; + height: fit-content; + overflow: visible; +} + + +.header{ + display: flex; + align-items: center; + padding: 0.8rem; + height: fit-content; + z-index: 2; + position: relative; + justify-content: space-between; +} + + + +.activeHeaderContent { + display: flex; + justify-content: space-between; + width: 100%; + opacity: 1; + transition: opacity 0.3s ease; + pointer-events: auto; +} +.inactiveHeaderContent{ + opacity: 0; + pointer-events: none; + transition: opacity 0.3s ease; + position: absolute; + top: 0.8rem; + left: 0.8rem; +} + + +.inactiveMobileMenu{ + max-height: 0; + position: absolute; + top: 100%; + left: 0; +} + +.activeMobileMenu{ + transition: max-height 3s ease; + max-height: 500px; + display: flex; + flex-direction: column; + align-items: start; + gap: 0.5rem; +} + + + + +.headerLeftContent { + display: flex; + width: fit-content; + align-items: center; + gap: 1.5rem; + font-size: 1.2rem; +} + +.headerRightContent { + width: fit-content; + display: flex; + align-items: center; +} + +.logo { + height: 4rem; + width: auto; + flex-shrink: 0; +} + +.logoLink { + display: inline-flex; + align-items: center; + justify-content: center; + width: fit-content; + height: fit-content; + flex-shrink: 0; +} + + +.link { + color: #000000; + width: fit-content; + text-align: center; + font-weight: bold; + border-bottom: 2px solid transparent; +} + +.link:hover{ + border-bottom: 2px solid #019AFF; + +} + +.activeLink { + width: fit-content; + text-align: center; + font-weight: bold; + color: #019AFF; + border-bottom: 2px solid #019AFF; +} + +svg { + width: fit-content; +} + +.bellBtn, .profileLink { + display: flex; + align-items: center; + justify-content: center; + border: none; + cursor: pointer; + transition: transform 0.5s ease; + background: none; + padding: 7px; + border-radius: 50%; + width: 55px; + height: 55px; + position: relative; +} + +.bellBtn svg { + stroke: black; + stroke-width: 3.5; + stroke-linecap: round; + stroke-linejoin: round; +} + +.bellBtn:focus { + outline: none; +} +.bellBtn:focus-visible { + outline: 2px solid black; +} + +.activeBellBtn { + transform: translateY(-4px); + background: rgba(191, 191, 191, 0.5); + svg { + stroke: #019AFF; + } +} + +.bellBtn:hover { + transform: translateY(-4px); + background: rgba(191, 191, 191, 0.5); + svg { + stroke: #019AFF; + } +} + + +.profileLink:hover { + transform: translateY(-4px); + background: rgba(191, 191, 191, 0.5); + svg { + fill: #019AFF; + } +} + +.bellBtn svg { + height: 28px; +} + +.profileLink svg { + height: 40px; +} + +.notificationDiv { + position: absolute; + width: 250px; + top: 105%; + right: 2rem; + opacity: 0; + transform: translateY(-10px); + transition: opacity 0.3s ease, transform 0.3s ease; + z-index: 1; +} + +.activeNotificationDiv { + opacity: 1; + transform: translateY(0); + z-index: 3; +} + + +.notification{ + margin-bottom: 7%; + display: flex; + justify-content: space-between; + align-items: center; +} + +.notificationBadge { + position: absolute; + top: 6px; + right: 9px; + width: 15px; + height: 15px; + background-color: red; + border-radius: 50%; +} + +.closeBtn { + display: flex; + align-items: center; + justify-content: center; + border: none; + cursor: pointer; + background: none; + margin: 0; + width: fit-content; +} + +.closeBtn:focus { + outline: none; +} +.closeBtn:focus-visible { + outline: 2px solid black; +} + +.burgerBtn { + flex-direction: column; + justify-content: space-between; + width: 30px; + height: 22px; + border: none; + cursor: pointer; + display: none; + z-index: 10; +} + +.burgerBar { + width: 100%; + height: 3px; + background-color: #000000; + border-radius: 2px; + transition: all 0.3s ease; +} + +.activeBurgerBtn .burgerBar:nth-child(1) { + transform: translateY(10px) rotate(45deg); +} +.activeBurgerBtn .burgerBar:nth-child(2) { + opacity: 0; +} +.activeBurgerBtn .burgerBar:nth-child(3) { + transform: translateY(-9px) rotate(-45deg); +} + + +.navLinks{ + display: flex; + align-items: center; + justify-content: center; + gap: 1rem; +} + + +@media screen and (max-width: 768px) { + .navLinks { + display: none; + } + .burgerBtn { + display: flex; + } +} \ No newline at end of file diff --git a/src/components/background/background.module.css b/src/components/background/background.module.css index 41d0a05..9c009a5 100644 --- a/src/components/background/background.module.css +++ b/src/components/background/background.module.css @@ -1,5 +1,6 @@ /* BACKGROUND ////////////////////////////////////////////////////////*/ .background-container { + z-index: 0; margin: 0; padding: 0; min-height: 100vh; @@ -47,8 +48,8 @@ width: 500px; height: 500px; background-color: rgb(244, 244, 172); - bottom: 0%; - right: 0%; + bottom: 0; + right: 0; } .circle-5 { diff --git a/src/index.css b/src/index.css index 413d12d..a61b4fd 100644 --- a/src/index.css +++ b/src/index.css @@ -24,6 +24,7 @@ .content { padding: 1.5rem; + z-index: 1; } @@ -34,9 +35,6 @@ a { color: #646cff; text-decoration: inherit; } -a:hover { - color: #535bf2; -} body { margin: 0; @@ -51,7 +49,7 @@ body { .glassCard { width: 100%; padding: 10px 20px 10px 20px; - height: 360px; + height: fit-content; background: rgba(255, 255, 255, 0.65); backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); diff --git a/src/layout.jsx b/src/layout.jsx index 082488d..b159981 100644 --- a/src/layout.jsx +++ b/src/layout.jsx @@ -1,15 +1,20 @@ import { Outlet } from "react-router"; import Footer from "./components/Footer/Footer.jsx" +import Header from "./components/Header/Header.jsx"; +import Background from "./components/background/background.jsx"; function Layout(){ return (
-
- -
-
+ +
+
+ +
+
) }