DataScope26/WEB
0
1import { useState, useEffect } from "react";2import { useNavigate, useLocation, Link } from "react-router-dom";3 4import "./Header.css";5 6import { useTheme } from "../context/ThemeContext.jsx";7import { useAuth } from "../context/AuthContext.jsx";8 9import LoginModal from "../components/LoginModal.jsx";10import RegisterModal from "../components/RegisterModal.jsx";11 12import perfilGenerico from "../assets/perfilGenerico.png";13import imgLogo from "../assets/imgLogo.webp";14import imgLogoBlanco from "../assets/imgLogoBlanco.png";15import { Bell } from "lucide-react";16import ButtonPrimary from "./ButtonPrimary.jsx";17import ButtonSecondary from "./ButtonSecondary.jsx";18 19// Secciones que ahora viven todas dentro de la misma página ("/")20const SCROLL_SECTIONS = ["home", "about", "tutorial"];21 22const Header = () => {23 const [scrolled, setScrolled] = useState(false);24 const [activeSection, setActiveSection] = useState("home");25 26 const { theme } = useTheme();27 28 const {29 isLogged,30 user,31 logout,32 setShowRegister,33 setShowLogin,34 showLogin,35 showRegister,36 } = useAuth();37 38 const navigate = useNavigate();39 const location = useLocation();40 41 const rutaActual = location.pathname;42 const enHome = rutaActual === "/";43 44 useEffect(() => {45 const onScroll = () => setScrolled(window.scrollY > 10);46 47 window.addEventListener("scroll", onScroll);48 49 return () => window.removeEventListener("scroll", onScroll);50 }, []);51 52 // Scroll-spy53 useEffect(() => {54 if (!enHome) return;55 56 const observer = new IntersectionObserver(57 (entries) => {58 entries.forEach((entry) => {59 if (entry.isIntersecting) {60 setActiveSection(entry.target.id);61 }62 });63 },64 {65 rootMargin: "-40% 0px -55% 0px",66 threshold: 0,67 }68 );69 70 SCROLL_SECTIONS.forEach((id) => {71 const el = document.getElementById(id);72 73 if (el) {74 observer.observe(el);75 }76 });77 78 return () => observer.disconnect();79 }, [enHome, location.state]);80 81 const handleLogout = () => {82 logout();83 84 if (rutaActual !== "/") {85 navigate("/");86 }87 };88 89 // Home / About / Tutorial son secciones dentro de "/"90 const goToSection = (id) => (e) => {91 e.preventDefault();92 93 if (enHome) {94 const el = document.getElementById(id);95 96 if (el) {97 el.scrollIntoView({98 behavior: "smooth",99 block: "start",100 });101 }102 } else {103 navigate("/", {104 state: {105 scrollTo: id,106 },107 });108 }109 };110 111 const navLinkClass = (id) =>112 enHome && activeSection === id113 ? "header__nav-active"114 : "";115 116 return (117 <>118 <header119 className={`header ${120 scrolled ? "header--scrolled" : ""121 }`}122 >123 <Link124 to="/"125 className={enHome ? "header__nav-active" : ""}126 >127 <img128 src={129 theme === "dark"130 ? imgLogo131 : imgLogoBlanco132 }133 alt="DataScope"134 className="header__logo"135 />136 </Link>137 138 <nav>139 <ul className="header__nav">140 141 {/* HOME */}142 <li>143 <a144 href="#home"145 onClick={goToSection("home")}146 className={navLinkClass("home")}147 >148 Home149 </a>150 </li>151 152 {/* ABOUT */}153 <li>154 <a155 href="#about"156 onClick={goToSection("about")}157 className={navLinkClass("about")}158 >159 About160 </a>161 </li>162 163 {/* TUTORIAL */}164 <li>165 <a166 href="#tutorial"167 onClick={goToSection("tutorial")}168 className={navLinkClass("tutorial")}169 >170 Tutorial171 </a>172 </li>173 174 {/* OVERVIEW */}175 {isLogged && (176 <li>177 <Link178 to="/overview"179 className={180 rutaActual === "/overview"181 ? "header__nav-active"182 : ""183 }184 >185 Overview186 </Link>187 </li>188 )}189 190 </ul>191 </nav>192 193 {isLogged && user ? (194 <div className="header__actions">195 196 <Link197 to="/overview/mis-invitaciones"198 className={`header__mail-link ${199 rutaActual === "/overview/mis-invitaciones"200 ? "header__mail-link--active"201 : ""202 }`}203 >204 <Bell205 size={24}206 strokeWidth={1.6}207 color="#2ee88a"208 className="header__bell-icon"209 />210 </Link>211 212 <div className="header__profile-menu-container">213 214 <Link215 to="/overview/perfil"216 className="header__profile-link"217 >218 <img219 className="header__profile-img"220 src={221 user.profile_pic &&222 user.profile_pic?.trim() !== ""223 ? user.profile_pic224 : perfilGenerico225 }226 alt="Foto de perfil"227 />228 229 <p className="header__profile-text">230 {user?.username?.trim()231 ? user.username232 : "user"}233 </p>234 </Link>235 236 <div className="header__profile-menu">237 <ButtonSecondary238 onClick={handleLogout}239 className="header__profile-menu-button"240 >241 Cerrar Sesión242 </ButtonSecondary>243 </div>244 245 </div>246 </div>247 ) : (248 <div className="header__auth-actions">249 <ButtonSecondary250 onClick={() => setShowRegister(true)}251 className="btn--waitlist"252 >253 Acceso anticipado254 </ButtonSecondary>255 256 <ButtonPrimary257 onClick={() => setShowLogin(true)}258 className="btn--login"259 >260 Login261 </ButtonPrimary>262 </div>263 )}264 </header>265 266 {showLogin && (267 <div className="modal-root">268 <LoginModal269 onClose={() => setShowLogin(false)}270 onOpenRegister={() => setShowRegister(true)}271 />272 </div>273 )}274 275 {showRegister && (276 <div className="modal-root">277 <RegisterModal278 onClose={() => setShowRegister(false)}279 onOpenLogin={() => setShowLogin(true)}280 />281 </div>282 )}283 </>284 );285};286 287export default Header;