diff --git a/src/app/components/NavigationBar.js b/src/app/components/NavigationBar.js index c173f59bba8b0a32c4f86ba96aa8c575dc1840a7..d387ed9b983fad643bc777d5a50bf6731b37a59f 100644 --- a/src/app/components/NavigationBar.js +++ b/src/app/components/NavigationBar.js @@ -1,7 +1,17 @@ -import * as React from 'react'; -import { useState, useEffect } from 'react'; -import NeedLoginModal from './needLoginModal'; +"use client"; + +import Link from "next/link"; +import { useEffect, useState } from "react"; +import { usePathname, useSearchParams } from "next/navigation"; + +import NeedLoginModal from "./needLoginModal"; import { isLoggedIn } from "../handlers/loginHandler"; +import { + getStoredValue, + removeFromLocalStorage, +} from "../handlers/localStorageHandler"; + +// Ícones import FileUploadIcon from '@mui/icons-material/FileUpload'; import CollectionsBookmarkIcon from "@mui/icons-material/CollectionsBookmark"; import SubjectIcon from "@mui/icons-material/Subject"; @@ -11,108 +21,123 @@ import HelpIcon from "@mui/icons-material/Help"; import VerifiedIcon from "@mui/icons-material/Verified"; import { Person } from "@mui/icons-material"; import SearchIcon from '@mui/icons-material/Search'; -import { usePathname, useRouter, useSearchParams } from "next/navigation"; -import { - getStoredValue, - removeFromLocalStorage, - } from "../handlers/localStorageHandler"; - - -export default function NavigationBar({ mobileSearch}) { - - const [needLoginOpen, setNeedLoginOpen] = useState(false); - const pathname = usePathname(); - let searchParams = useSearchParams(); - const page = searchParams.get('page'); - const [id, setId] = useState(null); - - useEffect(() => { - if (isLoggedIn()) { - let data = JSON.parse(getStoredValue("user_data")); - setId(data["id"]); - } - }, []); - - const handleOpenLoggin = (e) => { - - if (!isLoggedIn()) { - e.preventDefault(); - setNeedLoginOpen(true); - } - }; - - const handleLogout = () => { - removeFromLocalStorage("access_token"); - removeFromLocalStorage("user_data"); - removeFromLocalStorage("uid"); - removeFromLocalStorage("expiry"); - removeFromLocalStorage("token-type"); - removeFromLocalStorage("client"); - window.location.reload(); - }; - - const navItems = [ - { label: "Pesquisar", href: "#", icon: SearchIcon }, - { label: "Perfil", href: "/perfil", icon: Person }, - { label: "Coleções", href: "/busca?page=Collection", icon: CollectionsBookmarkIcon }, - { label: "Recursos", href: "/busca?page=LearningObject", icon: SubjectIcon }, - { label: "Sobre", href: "/sobre", icon: HelpIcon }, - { label: "MEC", href: "/busca?page=MEC", icon: VerifiedIcon }, - { label: "Publicar", href: "/publicar", icon: FileUploadIcon }, - { label: "Contato", href: "/contato", icon: EmailRoundedIcon }, - { label: "Sair", href: "", icon: LogoutRounded}, - ] - - const handleToggleMobileSearch = (e) => { - e.preventDefault(); - mobileSearch.setSearchIsClicked((prevState) => !prevState); // Alterna a exibição da pesquisa - }; - - return ( - <> - <NeedLoginModal open={needLoginOpen} setOpen={setNeedLoginOpen} /> - - <nav className="bg-lightGray h-50 outline outline-1 outline-ice-HC-white text-darkGray-HC-white font-light fixed bottom-0 left-0 w-full z-10"> - <ul className="flex justify-between overflow-x-auto no-scrollbar animate-scrollHint"> - {navItems.map((item, index) => { - const isPublishRoute = item.href === "/publicar"; - const isPerfilRoute = item.href === "/perfil"; - const isSearchButton = item.label === "Pesquisar"; - const isLogout = item.label === "Sair"; - - const isActive = - (page === item.href.split("page=")[1]) || - (pathname === item.href) || - (mobileSearch.searchIsClicked && item.label === "Pesquisar"); - - return ( - <li key={index} className="flex w-20 flex-col items-center justify-center p-3"> - <a - href={isLogout ? "#" : ( - isPublishRoute ? (isLoggedIn() ? "/publicar" : "") : - isPerfilRoute ? (isLoggedIn() ? `/perfil/${id}` : "") : - item.href - )} - onClick={ - isLogout ? (e) => { e.preventDefault(); handleLogout(); } : - isPublishRoute || isPerfilRoute ? (e) => handleOpenLoggin(e) : - isSearchButton ? (e) => handleToggleMobileSearch(e) : - undefined - } - className={`text-center rounded-md transition-all ${ - isActive ? "font-bold text-black" : "" - }`} - > - <item.icon className={`cursor-pointer text-3xl ${isActive ? "text-black font-bold" : ""}`} /> - <span className={`cursor-pointer text-xs ${isActive ? "text-black font-bold" : ""}`}> - {item.label} - </span> - </a> - </li> - ); - })} - </ul> - </nav> - </> - ) -} \ No newline at end of file + +/** + * @param {Object} props + * @param {Function} props.mobileSearch + */ +const navItems = [ + { label: "Pesquisar", href: "#", icon: SearchIcon }, + { label: "perfil", href: "/perfil", icon: Person }, + { label: "Coleções", href: "Collection", icon: CollectionsBookmarkIcon }, + { label: "Recursos", href: "LearningObject", icon: SubjectIcon }, + { label: "Sobre", href: "/sobre", icon: HelpIcon }, + { label: "MEC", href: "MEC", icon: VerifiedIcon }, + { label: "Publicar", href: "/publicar", icon: FileUploadIcon }, + { label: "Contato", href: "/contato", icon: EmailRoundedIcon }, + { label: "Sair", href: "/logout", icon: LogoutRounded }, +]; + +export default function NavigationBar({ mobileSearch }) { + const [id, setId] = useState(null); + const [needLoginOpen, setNeedLoginOpen] = useState(false); + + const pathname = usePathname(); + const searchParams = useSearchParams(); + const page = searchParams.get('page'); + + useEffect(() => { + if (isLoggedIn()) { + const userData = getStoredValue("user_data"); + if (userData) { + const data = JSON.parse(userData); + setId(data["id"]); + } + } + }, []); + + const handleLogout = () => { + removeFromLocalStorage("access_token"); + removeFromLocalStorage("user_data"); + removeFromLocalStorage("uid"); + removeFromLocalStorage("expiry"); + removeFromLocalStorage("token-type"); + removeFromLocalStorage("client"); + window.location.reload(); + }; + + const handleOpenLogin = () => { + if (!isLoggedIn()) { + setNeedLoginOpen(true); + } + }; + + const handleToggleMobileSearch = () => { + mobileSearch.setSearchIsClicked((prev) => !prev); + }; + + const getHref = (href) => { + if (href === "/publicar" || href === "/sobre" || href === "/contato") return href; + if (href === "/perfil") return `/perfil/${id}`; + if (href === "#") return "#"; + return `/busca?page=${href}`; + }; + + return ( + <> + <NeedLoginModal open={needLoginOpen} setOpen={setNeedLoginOpen} /> + + <nav className="bg-lightGray-HC-dark h-50 outline outline-1 outline-ice-HC-white text-darkGray-HC-white-underline font-light fixed bottom-0 left-0 w-full z-10"> + <ul className="flex justify-between overflow-x-auto no-scrollbar animate-scrollHint"> + {navItems.map((item, index) => { + const isActive = + page === item.href || + pathname === item.href || + pathname.startsWith(item.href) || + (mobileSearch.searchIsClicked && item.label === "Pesquisar"); + + const isProtected = item.href === "/publicar" || item.href === "/perfil"; + + const handleClick = (e) => { + if (item.label === "Sair") { + e.preventDefault(); + handleLogout(); + } else if (item.label === "Pesquisar") { + e.preventDefault(); + handleToggleMobileSearch(); + } else if (isProtected && !isLoggedIn()) { + e.preventDefault(); + handleOpenLogin(); + } + }; + + return ( + <li key={index} className="flex w-20 flex-col items-center justify-center p-3"> + <Link + href={ + item.label === "Publicar" && !isLoggedIn() + ? "#" + : item.label === "perfil" && isLoggedIn() + ? `/perfil/${id}` + : getHref(item.href) + } + onClick={handleClick} + className={`text-center rounded-md transition-all ${ + isActive ? "text-lightGray-HC-dark-underline font-bold" : "" + }`} + > + <item.icon + className={`cursor-pointer text-3xl ${isActive ? "text-darkGray-HC-white-underline" : ""}`} + /> + <span className={`cursor-pointer text-xs ${isActive ? "text-darkGray-HC-white-underline font-bold" : ""}`}> + {item.label} + </span> + </Link> + </li> + ); + })} + </ul> + </nav> + </> + ); +} diff --git a/src/app/components/ShareButton.js b/src/app/components/ShareButton.js index 4b146c7882168ee090ee85db8dc1d5b896b29030..db07e073d844cd4481c538051296b10ca8aa4026 100644 --- a/src/app/components/ShareButton.js +++ b/src/app/components/ShareButton.js @@ -18,7 +18,7 @@ export default function ShareButton({ type, id }) { return ( <> <button - className="p-2 text-sm rounded-[10px] w-48 h-11 max-md:my-3 hover:bg-darkGray-HC-white hover:text-darkGray-HC-dark outline outline-1 outline-lightGray-HC-white text-darkGray-HC-white-underline hover:text-white-HC-dark-underline font-bold normal-case flex justify-center items-center gap-2" + className="p-2 text-sm rounded-[10px] max-md:w-44 w-48 h-11 hover:bg-darkGray-HC-white hover:text-darkGray-HC-dark outline outline-1 outline-lightGray-HC-white text-darkGray-HC-white-underline hover:text-white-HC-dark-underline font-bold normal-case flex justify-center items-center gap-2" onClick={() => setShareOpen(true)} aria-label="Compartilhar" > diff --git a/src/app/globals.css b/src/app/globals.css index 8e751398eec0ad33112bd183ae227f233c315e69..ef4ead286723e464e56f0860687ac6678ac5b59a 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -73,6 +73,8 @@ --lightGray: #d8e6e6; --lightGray-HC-dark: #d8e6e6; --lightGray-HC-white: #d8e6e6; + --lightGray-HC-white-underline:#d8e6e6; + --lightGray-HC-dark-underline:#d8e6e6; --red-HC-white: #dc2626; --mediumGray-HC-white: #b9cccc; --mediumGray-HC-dark: #b9cccc; diff --git a/src/app/perfil/[id]/components/SelectionButtons.js b/src/app/perfil/[id]/components/SelectionButtons.js index e4cfa8e841c9d29b0950bc6b1884c3232ef0759c..caf31a80e128794457bd932c703821108c3a2e55 100644 --- a/src/app/perfil/[id]/components/SelectionButtons.js +++ b/src/app/perfil/[id]/components/SelectionButtons.js @@ -27,7 +27,7 @@ export default function SelectionButtons({ setOptButton, verifyCurator, idProfil // o usuário só consegue ver seguidores e seguindos quando logado const buttons = options.map(obj => obj.name) - + return ( <div className="" > @@ -40,7 +40,7 @@ export default function SelectionButtons({ setOptButton, verifyCurator, idProfil TabIndicatorProps={{ style: { background: "var(--turquoise-HC-white)" } }} > {buttons.map((item, index) => { - + return ( <Tab className="text-[16px] py-5 normal-case text-darkGray-HC-white" key={index} value={index} label={<p className="text-darkGray-HC-white-underline">{item}</p>} /> ) @@ -59,16 +59,22 @@ export default function SelectionButtons({ setOptButton, verifyCurator, idProfil variant="scrollable" scrollButtons="auto" allowScrollButtonsMobile + TabIndicatorProps={{ style: { background: "var(--turquoise-HC-white)" } }} className="text-darkGray-HC-white" > {buttons.map((item, index) => { return ( - <Tab key={index} value={index} label={item} /> + <Tab + key={index} + value={index} + label={<p className="text-darkGray-HC-white-underline">{item}</p>} + /> ) })} </Tabs> + <hr style={{ borderTop: "1px solid var(--lightGray-HC-white)" }} /> </div> </div> diff --git a/src/app/perfil/[id]/components/Stats.js b/src/app/perfil/[id]/components/Stats.js index 3c30e1c4404fa1e7bc8fdb541fe8d679752c108e..38bc6a5f8656b76c27da6ed936fbda9f48dd643c 100644 --- a/src/app/perfil/[id]/components/Stats.js +++ b/src/app/perfil/[id]/components/Stats.js @@ -51,7 +51,7 @@ export default function ProfileStats({ profileData, achievements, progresses, it <> <div className='flex flex-row justify-between px-1 max-xl:grid max-xl:grid-cols-3 max-xl:gap-5 max-md:flex max-md:flex-nowrap max-md:overflow-x-auto mt-[42px] max-md:scrollbar-none max-md:animate-scrollHint'> {statsArray.map((item, index) => ( - <div key={index} className='flex justify-center px-4 2xl:w-[210px] h-[60px] gap-0.5 items-center bg-white-HC-dark rounded-[10px] whitespace-nowrap text-[80%%] font-light text-darkGray-HC-white outline outline-1 outline-ice-HC-white'> + <div key={index} className='flex justify-center px-4 2xl:w-[210px] h-[60px] gap-0.5 items-center bg-white-HC-dark rounded-[10px] whitespace-nowrap text-[80%%] font-light text-darkGray-HC-white max-md:my-1 outline outline-1 outline-ice-HC-white'> <img className="flex h-[26px] px-1 invertLogo-HC-white" src={item.src} alt={item.name} diff --git a/src/app/perfil/[id]/components/UserCard.js b/src/app/perfil/[id]/components/UserCard.js index 7cc3a1d0b4832118fc623af0f67706aadd70b7be..9019411433caf5a3183cba6e68edfa56d2bfe7c5 100644 --- a/src/app/perfil/[id]/components/UserCard.js +++ b/src/app/perfil/[id]/components/UserCard.js @@ -218,7 +218,7 @@ export default function UserCard({ profileData, idLogin, achievements, progresse return ( <div className='overflow-y-auto min-h-dvh ml-[30px] mr-[80px] max-md:mx-[20px] max-md:mb-24 '> <div className='flex flex-col'> - <div className='flex max-lg:flex-col rounded-2xl gap-4 max-sm:gap-0 max-lg:items-center bg-white-HC-dark outline outline-1 outline-ice-HC-white' > + <div className='flex max-md:mx-1 mx-0.5 mt-2 max-lg:flex-col rounded-2xl gap-4 max-sm:gap-0 max-lg:items-center bg-white-HC-dark outline outline-1 outline-ice-HC-white' > <div className='p-10 max-sm:p-0 h-full items-center'> {/*a imagem do usuário tem nomes diferentes no backend se for usuário público ou não */} {profileData["avatar"] ? @@ -245,7 +245,7 @@ export default function UserCard({ profileData, idLogin, achievements, progresse {profileData["email"] && profileData["id"] !== 35342 && ( <div className='mb-3 truncate flex flex-row items-center text-darkGray-HC-white max-sm:text-base text-2xl'> <img src="/usuario-verificado.svg" alt="ocupacao" className='flex aspect-square mr-4 max-lg:mx-4 w-[28px] h-[28px] rounded-full' /> - <div className='shrink-0 h-[28px] max-lg:w-[20px] max-lg:h-[20px] max-lg:mx-4' /> + <div className='shrink-0 h-[28px] max-lg:w-[20px] max-lg:h-[20px]' /> {profileData["email"]} </div> )} @@ -271,7 +271,7 @@ export default function UserCard({ profileData, idLogin, achievements, progresse {/* Botões de recursos, sobre, coleções e homologação, mostra quais botões para cada usuário */} - <div className='rounded-2xl min-w-[200px] mt-10 bg-white-HC-dark outline outline-1 outline-ice-HC-white'> + <div className='max-md:mx-1 max-md:mb-1 rounded-2xl min-w-[200px] mt-10 bg-white-HC-dark outline outline-1 outline-ice-HC-white'> {<SelectionButtons options={options} setOptButton={setOptButton} verifyCurator={verifyCurator} idLogin={idLogin} idProfile={profileData["id"]} />} {/* Faz a escolha correta de qual botão o usuário clicou */} <ProfileOptions diff --git a/src/app/themes/theme_high_contrast.css b/src/app/themes/theme_high_contrast.css index 0a02a1dabc39a46201d7b6d34d9ffcc87a65e85e..eac8be81dfc12693c142038b1883a42ef0a95eb9 100644 --- a/src/app/themes/theme_high_contrast.css +++ b/src/app/themes/theme_high_contrast.css @@ -66,6 +66,12 @@ html[data-theme="theme_high_contrast"] { .text-black-HC-white-underline[data-theme="theme_high_contrast"] { text-decoration: underline; } +.text-lightGray-HC-white-underline[data-theme="theme_high_contrast"] { + text-decoration: underline; +} +.text-lightGray-HC-dark-underline[data-theme="theme_high_contrast"] { + text-decoration: underline; +} /* Em alto contraste: Icones pretos */ .invertIcon-HC-black[data-theme="theme_high_contrast"] { diff --git a/tailwind.config.js b/tailwind.config.js index dbbbab7ffb7348bc183c8762f49ce85c78ba8a8d..cda00e6e480204ccc23c586dc0ac8c9d346c374c 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -65,6 +65,8 @@ module.exports = { "lightGray": 'var(--lightGray)', "lightGray-HC-dark": 'var(--lightGray-HC-dark)', "lightGray-HC-white": 'var(--lightGray-HC-white)', + "lightGray-HC-white-underline": 'var(--lightGray-HC-white-underline)', + "lightGray-HC-dark-underline": 'var(--lightGray-HC-dark-underline)', "red-HC-white": 'var(--red-HC-white)', "mediumGray-HC-white": 'var(--mediumGray-HC-white)', "mediumGray-HC-dark": 'var(--mediumGray-HC-dark)', @@ -133,6 +135,12 @@ module.exports = { '.text-black-HC-white-underline': { 'text-decoration': 'var(--underline)', }, + '.text-lightGray-HC-white-underline': { + 'text-decoration': 'var(--underline)', + }, + '.text-lightGray-HC-dark-underline': { + 'text-decoration': 'var(--underline)', + }, '.invertLogo-HC-white': { 'filter': 'var(--filter)' }