UNPKG

@ieltsrealtest/ui

Version:

Reusable UI components for IELTS Real Test platform, built with React and TypeScript.

120 lines (119 loc) 7.06 kB
/* eslint-disable @typescript-eslint/no-unused-vars */ "use client"; import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; import NavBar from "./Navbar"; import MobileNavbar from "../MobileNavbar/Navbar"; import DropdownMenu from "./DropdownMenu"; import { useState, useEffect, useMemo } from "react"; import Image from "next/image"; import { BsDropletFill } from "react-icons/bs"; import NotificationsDropdown from "./NotificationsDropdown"; const logo = "https://ieltsrealtest.s3.us-east-1.amazonaws.com/public/common/Logo+ngang_.png"; const Header = ({ isDev = false }) => { const [isLoggedIn, setIsLoggedIn] = useState(false); const [userName, setUserName] = useState(""); const [avatar, setAvatar] = useState(""); const [isLoading, setIsLoading] = useState(false); const [nutrientsCount, setNutrientsCount] = useState(0); const [notificationsCount, setNotificationsCount] = useState(0); const [logoError, setLogoError] = useState(false); const { USER_API_BASE_URL } = useMemo(() => { if (isDev) { return { USER_API_BASE_URL: "https://devapi.youready.net/ielts/user/api/", }; } return { USER_API_BASE_URL: "https://api.youready.net/ielts/user/api/", }; }, [isDev]); useEffect(() => { const userStr = sessionStorage.getItem("user"); const cachedUser = userStr ? JSON.parse(userStr) : null; let userFields = ["nutrients"]; // always refetch nutrients if (!cachedUser?.avatar) userFields.push("avatar"); if (!cachedUser?.first_name || !cachedUser?.last_name) { userFields.push("first_name", "last_name"); } if (cachedUser?.avatar) setAvatar(cachedUser.avatar); if (cachedUser?.first_name && cachedUser?.last_name) { setUserName(`${cachedUser.first_name} ${cachedUser.last_name}`); } const userAPIUrl = `${USER_API_BASE_URL}profile/users/?fields=${userFields.join(",")}`; const handleSessionExpired = () => { sessionStorage.removeItem("user"); setIsLoggedIn(false); setIsLoading(false); }; const fetchUserData = async () => { try { let res = await fetch(userAPIUrl, { method: "GET", headers: { "Content-Type": "application/json" }, credentials: "include", }); // If token expired, try refreshing once if (res.status === 401 || res.status === 400) { const refreshUrl = `${USER_API_BASE_URL}auth/refresh_Token/`; const refreshRes = await fetch(refreshUrl, { method: "POST", credentials: "include", }); if (refreshRes.ok) { // Retry original request with new token res = await fetch(userAPIUrl, { method: "GET", headers: { "Content-Type": "application/json" }, credentials: "include", }); } else { handleSessionExpired(); return; } } if (!res.ok) throw new Error("Failed to fetch user data"); const data = await res.json(); const user = data.data || {}; // Update nutrients every time setNutrientsCount(Number.isFinite(user.nutrients) ? user.nutrients : 0); // Only update cached info if it was missing const updatedUser = { ...cachedUser, ...user, }; sessionStorage.setItem("user", JSON.stringify(updatedUser)); // Also update UI if new avatar or name just arrived if (user.avatar && !cachedUser?.avatar) { setAvatar(user.avatar); } if (user.first_name && user.last_name && (!cachedUser?.first_name || !cachedUser?.last_name)) { setUserName(`${user.first_name} ${user.last_name}`); } setIsLoggedIn(true); setIsLoading(false); } catch (error) { setIsLoggedIn(false); setIsLoading(true); } }; fetchUserData(); }, []); return (_jsxs("div", { children: [_jsx("header", { className: "bg-[#FFF9F1] shadow-md py-0 px-8 text-black", children: _jsxs("div", { className: "mx-auto grid grid-cols-[auto_1fr_auto] items-center", children: [_jsx("div", { className: "text-xl font-bold justify-self-start", children: _jsx("a", { href: isDev ? `https://dev.youready.net/ielts/` : "https://www.youready.net/ielts/", children: _jsx(Image, { src: logoError ? "/ielts/assets/youReady.jpg" : logo, alt: "Logo", width: 140, height: 60, priority: true, onError: () => setLogoError(true) }) }) }), _jsx("div", { className: "justify-self-center min-w-0", children: _jsx(NavBar, { isDev: isDev }) }), _jsx("div", { className: "flex justify-end items-center gap-4 relative justify-self-end", children: isLoggedIn ? (isLoading ? (_jsx("div", { className: "w-full flex items-center justify-end text-gray-500", children: "Loading..." })) : (_jsxs(_Fragment, { children: [_jsx(NotificationsDropdown, { count: notificationsCount, isDev: isDev }), _jsxs("div", { className: "flex items-center gap-1 text-sm leading-none", children: [_jsx(BsDropletFill, { className: "text-[#1E90FF] text-lg" }), _jsx("span", { className: "text-black", children: nutrientsCount })] }), _jsx("span", { className: "h-6 w-px bg-gray-300" }), _jsx(DropdownMenu, { items: [ { label: "Profile", path: "profile" }, { label: "Payment", path: "payment" }, { label: "Performance", path: "performance" }, // { label: 'Logout', path: 'auth/signin' }, ], userName: userName, avatar: avatar, isDev: isDev })] }))) : (_jsx("button", { className: "border bg-red-600 text-white px-4 py-1 rounded-md transition duration-200 hover:bg-red-700", onClick: () => { isDev ? (window.location.href = "https://dev.youready.net/ielts/user/pages/auth/signin/") : (window.location.href = "https://www.youready.net/ielts/user/pages/auth/signin/"); }, children: "SIGN IN" })) })] }) }), _jsx(MobileNavbar, { isDev: isDev })] })); }; export default Header;