feat: request optimizations
This commit is contained in:
@@ -3,17 +3,17 @@ import { LuUser, LuMenu, LuSearch, LuLogOut, LuUsers, LuMail, LuGraduationCap, L
|
||||
import { useEffect, useState } from "react";
|
||||
import { useNavigate, Link } from "react-router";
|
||||
import { Button, NavLink, Offcanvas } from "react-bootstrap";
|
||||
import type { User, Workshop } from "../../types";
|
||||
import type { Workshop } from "../../types";
|
||||
import type { Video } from "../../types";
|
||||
import { CgSpinner } from "react-icons/cg";
|
||||
import { useDebounce } from "../../hooks/useDebounce";
|
||||
import { useGetVideos } from "../../hooks/useGetVideos";
|
||||
import { useGetVideosLength } from "../../hooks/useGetVideosLength";
|
||||
import { useGetVideosSearch } from "../../hooks/useGetVideosSearch";
|
||||
import { PiCheckCircleFill } from "react-icons/pi";
|
||||
import { useGetWorkshopsSearch } from "../../hooks/useGetWorkshopsSearch";
|
||||
import { imageSkeletonFadeStyle, onImageSkeletonLoad } from "../../utils/imageSkeleton";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
import { useGetCurrentUser } from "../../hooks/useGetCurrentUser";
|
||||
|
||||
export default function Header() {
|
||||
const [showMenu, setShowMenu] = useState(false);
|
||||
@@ -23,31 +23,28 @@ export default function Header() {
|
||||
const [searchCompleted, setSearchCompleted] = useState(false);
|
||||
const [videosSearched, setVideosSearched] = useState<Video[]>([]);
|
||||
const [workshopsSearched, setWorkshopsSearched] = useState<Workshop[]>([]);
|
||||
const user = JSON.parse(localStorage.getItem("user") || "{}") as User;
|
||||
const isAdmin = user.role_id === 1;
|
||||
const debouncedSearch = useDebounce(search, 500);
|
||||
const [showDropdown, setShowDropdown] = useState(false);
|
||||
const { getVideos } = useGetVideos();
|
||||
const { getVideosLength } = useGetVideosLength();
|
||||
const { getVideosSearch } = useGetVideosSearch();
|
||||
const { getWorkshopsSearch } = useGetWorkshopsSearch();
|
||||
const [videosStats, setVideosStats] = useState({
|
||||
videos: 0,
|
||||
videosWatched: 0
|
||||
});
|
||||
|
||||
const { getCurrentUser } = useGetCurrentUser();
|
||||
const [role, setRole] = useState(0);
|
||||
const [videosWatched, setVideosWatched] = useState(0);
|
||||
const [videosCount, setVideosCount] = useState(0);
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (isAdmin) return;
|
||||
|
||||
const fetchProgressVideos = async () => {
|
||||
const videosLengthData = await getVideosLength();
|
||||
if ("videos" in videosLengthData) {
|
||||
setVideosStats(videosLengthData as { videos: number, videosWatched: number });
|
||||
}
|
||||
const fetchAll = async () => {
|
||||
const videosWatched = localStorage.getItem("videosWatched");
|
||||
setVideosWatched(videosWatched ? parseInt(videosWatched) : 0);
|
||||
const videosCount = localStorage.getItem("videosCount");
|
||||
setVideosCount(videosCount ? parseInt(videosCount) : 0);
|
||||
const userData = await getCurrentUser();
|
||||
setRole(userData.data.role_id);
|
||||
};
|
||||
fetchProgressVideos();
|
||||
fetchAll();
|
||||
}, []);
|
||||
|
||||
const handleCloseMenu = () => setShowMenu(false);
|
||||
@@ -132,7 +129,13 @@ export default function Header() {
|
||||
<Offcanvas.Header >
|
||||
<Offcanvas.Title className={"w-100 d-flex justify-content-between"}>
|
||||
<Link className={`${styles.logoLink} justify-content-start`} to="/dashboard">
|
||||
<img className={styles.logo} src="/src/assets/logo.png" alt="Logo" />
|
||||
<img
|
||||
className={styles.logo}
|
||||
src="/src/assets/logo.png"
|
||||
alt="Logo"
|
||||
style={imageSkeletonFadeStyle}
|
||||
onLoad={onImageSkeletonLoad}
|
||||
/>
|
||||
</Link>
|
||||
<button type="button" className={`${styles.sidebarClose} align-items-center justify-content-center d-xl-none`} onClick={handleCloseMenu}> <LuPanelLeftClose size={24} /> </button>
|
||||
</Offcanvas.Title>
|
||||
@@ -150,7 +153,7 @@ export default function Header() {
|
||||
<li className={`${styles.navItem} text-start`}>
|
||||
<NavLink className={styles.navLink} href="/workshops"> <LuGraduationCap className="me-2" size={24} />Workshops</NavLink>
|
||||
</li>
|
||||
{isAdmin && (
|
||||
{role === 1 && (
|
||||
<li className={`${styles.navItem} text-start`}>
|
||||
<NavLink className={styles.navLink} href="/admin/users"> <LuUsers className="me-2" size={24} />Utilizadores</NavLink>
|
||||
</li>
|
||||
@@ -161,10 +164,10 @@ export default function Header() {
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
{!isAdmin && videosStats.videos > 0 && (
|
||||
{role !== 1 && videosCount > 0 && (
|
||||
<div className="d-flex d-sm-none justify-content-center">
|
||||
<span className="fw-semibold">Vídeos assistidos</span>
|
||||
<span className={`${styles.badge} badge align-content-center ms-3`}>{videosStats.videosWatched}/{videosStats.videos}</span>
|
||||
<span className={`${styles.badge} badge align-content-center ms-3`}>{videosWatched}/{videosCount}</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -177,11 +180,11 @@ export default function Header() {
|
||||
|
||||
<nav className="navbar px-3">
|
||||
<div className={styles.headerRight}>
|
||||
{!isAdmin && videosStats.videos > 0 && (
|
||||
{role !== 1 && videosCount > 0 && (
|
||||
<>
|
||||
<div className="d-none d-sm-flex align-items-center gap-1 text-muted">
|
||||
<span className="fw-semibold">Vídeos assistidos</span>
|
||||
<span className={`${styles.badge} badge align-content-center`}>{videosStats.videosWatched}/{videosStats.videos}</span>
|
||||
<span className={`${styles.badge} badge align-content-center`}>{videosWatched}/{videosCount}</span>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user