Changeset 0c6b92a for imaps-frontend/src/components/Profile
- Timestamp:
- 12/12/24 17:06:06 (5 weeks ago)
- Branches:
- main
- Parents:
- d565449
- Location:
- imaps-frontend/src/components/Profile
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
imaps-frontend/src/components/Profile/Profile.jsx
rd565449 r0c6b92a 1 import React, { useState, useRef, useEffect } from "react"; 1 import React, { useState, useRef, useEffect, useContext } from "react"; 2 import { useNavigate, Link } from "react-router-dom"; 2 3 import profile from "../../assets/person_icon.png"; 3 4 import styles from "./Profile.module.css"; 5 import { useAppContext } from "../AppContext/AppContext.jsx"; 4 6 5 function Profile() { 6 const menus = ["Profile", "Settings", "Support", "Logout"]; 7 const [open, setOpen] = useState(false); 8 const menuRef = useRef(null); 9 const imgRef = useRef(null); 7 function Profile({ position = "fixed" }) { 8 const { username, isAuthenticated } = useAppContext(); 9 const [open, setOpen] = useState(false); 10 const menuRef = useRef(null); 11 const imgRef = useRef(null); 12 const navigate = useNavigate(); 10 13 11 useEffect(() => { 12 const handleClickOutside = (e) => { 13 if (menuRef.current && imgRef.current) { 14 if (!menuRef.current.contains(e.target) && !imgRef.current.contains(e.target)) { 15 setOpen(false); 14 const menus = isAuthenticated ? ["My Maps", "Logout"] : ["Login"]; 15 16 useEffect(() => { 17 const handleClickOutside = (e) => { 18 if (menuRef.current && imgRef.current) { 19 if (!menuRef.current.contains(e.target) && !imgRef.current.contains(e.target)) { 20 setOpen(false); 21 } 22 } 23 }; 24 25 document.addEventListener("click", handleClickOutside); 26 27 return () => { 28 document.removeEventListener("click", handleClickOutside); 29 }; 30 }, []); 31 32 const handleMenuClick = (menu) => { 33 if (menu === "My Maps") { 34 navigate("/MyMaps"); 35 } else if (menu === "Logout") { 36 localStorage.removeItem("token"); 37 window.location.reload(); 16 38 } 17 }39 setOpen(false); 18 40 }; 19 41 20 document.addEventListener("click", handleClickOutside); 21 22 return () => { 23 document.removeEventListener("click", handleClickOutside); 24 }; 25 }, []); 26 27 return ( 28 <div className={styles.profileContainer}> 29 <div className={styles.profileWrapper}> 30 <img 31 onClick={() => setOpen(!open)} 32 src={profile} 33 alt="profile" 34 className={styles.profileImage} 35 ref={imgRef} 36 /> 37 {open && ( 38 <div ref={menuRef} className={styles.dropdownMenu}> 39 <ul className={styles.menuList}> 40 {menus.map((menu) => ( 41 <li key={menu} onClick={() => setOpen(false)} className={styles.menuItem}> 42 {menu} 43 </li> 44 ))} 45 </ul> 46 </div> 47 )} 48 </div> 49 </div> 50 ); 42 return ( 43 <div className={position === "fixed" ? styles.fixedProfileContainer : styles.inlineProfileContainer}> 44 <div className={styles.profileWrapper}> 45 <div className={styles.profileIconContainer} onClick={() => setOpen(!open)}> 46 <img src={profile} alt="profile" className={styles.profileImage} ref={imgRef} /> 47 </div> 48 {open && ( 49 <div ref={menuRef} className={styles.dropdownMenu}> 50 {isAuthenticated && <div className={styles.username}>{username}</div>} 51 <ul className={styles.menuList}> 52 {menus.map((menu) => 53 menu === "Login" ? ( 54 <li key={menu} className={styles.menuItem}> 55 <Link to="/login" className={styles.linkStyle}>{menu}</Link> 56 </li> 57 ) : ( 58 <li key={menu} onClick={() => handleMenuClick(menu)} className={styles.menuItem}> 59 {menu} 60 </li> 61 ) 62 )} 63 </ul> 64 </div> 65 )} 66 </div> 67 </div> 68 ); 51 69 } 52 70 -
imaps-frontend/src/components/Profile/Profile.module.css
rd565449 r0c6b92a 1 img:hover, 2 .menuItem:hover { 1 .fixedProfileContainer { 2 position: fixed; 3 top: 1em; 4 right: 2.5em; 5 z-index: 1000; 6 } 7 8 .inlineProfileContainer { 9 display: inline-block; 3 10 cursor: pointer; 4 11 } 5 12 6 .menuList { 7 list-style: none; 8 padding: 0; 9 margin: 0; 10 text-align: center; 13 .profileWrapper { 14 display: flex; 15 align-items: center; 16 cursor: pointer; 11 17 } 12 18 13 .profileContainer { 14 display: flex; 15 justify-content: center; 16 } 17 18 .profileWrapper { 19 position: relative; 19 .profileIconContainer { 20 position: relative; /* Makes dropdown position relative to this container */ 21 cursor: pointer; 20 22 } 21 23 22 24 .profileImage { 23 height: 48px;24 width: 48px;25 width: 60px; 26 height: 60px; 25 27 border-radius: 50%; 26 /* border: 4px solid #d1d5db; */ 27 object-fit: cover; 28 transition: box-shadow 0.3s ease; 28 29 } 29 30 30 /* Dropdown Menu */ 31 .profileImage:hover { 32 box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.2); 33 } 34 31 35 .dropdownMenu { 32 36 position: absolute; 33 top: 50px; /* Adjust according to image size and spacing */ 34 left: 50%; 35 transform: translateX(-50%); /* Center the menu below the image */ 36 width: 13rem; 37 background-color: white; 38 padding: 1rem; 39 box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); 37 top: 70px; 38 margin-left: 1.8em; 39 transform: translateX(-50%); 40 background-color: #ffffff; 41 box-shadow: 0 8px 16px rgba(0, 0, 0, 0.15); 42 border-radius: 12px; 43 padding: 12px; 44 width: 180px; 45 transition: opacity 0.3s ease; 46 opacity: 1; 40 47 } 41 48 42 /* Menu List and Items */ 49 .username { 50 padding: 10px 0; 51 font-weight: 600; 52 text-align: center; 53 color: #333; 54 border-bottom: 1px solid #eee; 55 } 56 43 57 .menuList { 44 58 list-style-type: none; … … 49 63 .menuItem { 50 64 padding: 10px; 65 cursor: pointer; 66 transition: background-color 0.2s ease, color 0.2s ease; 51 67 text-align: center; 52 border-radius: 5px; 53 transition: background-color 0.3s ease; 68 color: #333; 69 font-weight: 500; 70 border-radius: 8px; 54 71 } 55 72 56 73 .menuItem:hover { 57 background-color: #f0f0f0; 74 background-color: #f5f5f5; 75 color: #007bff; /* Optional: Adds a blue highlight on hover */ 58 76 }
Note:
See TracChangeset
for help on using the changeset viewer.