import React, { useState, useEffect, useRef } from "react"; import { useNavigate, useLocation, Link } from "react-router-dom"; import logo from "../assets/img/getgo.svg"; import { useAppDispatch, useAppSelector } from "../hooks/useRedux"; import { useMutation } from "@tanstack/react-query"; import { startLoading, startSmallLoading, stopLoading, stopSmallLoading, } from "../features/loading/loadingSlice"; import { productApi } from "../apis/productApi"; import { Area } from "../services/product/type"; import { accountLogout } from "../features/account/accuntSlice"; import { useSelector } from "react-redux"; import { setAreas } from "../features/areas/areasSlice"; import i18n from "../i18n"; import { useTranslation } from "react-i18next"; import { getWithExpiry, setWithExpiry } from "../logic/loigicUtils"; const Header: React.FC = () => { const navigate = useNavigate(); // const areas = useSelector((state: any) => state.areas.areas); const areas = getWithExpiry("areas"); const { t } = useTranslation(); const location = useLocation(); const [isMenuOpen, setIsMenuOpen] = useState(false); const [isBuySimExpanded, setIsBuySimExpanded] = useState(false); const [isGuideExpanded, setIsGuideExpanded] = useState(false); const [isUserMenuOpen, setIsUserMenuOpen] = useState(false); const [isBuySimMegaVisible, setIsBuySimMegaVisible] = useState(false); const [isGuideMegaVisible, setIsGuideMegaVisible] = useState(false); const [isLangMenuOpen, setIsLangMenuOpen] = useState(false); const lang = localStorage.getItem("lang") || "en"; const [selectedLang, setSelectedLang] = useState<"en" | "vi">(lang); const [activeDesktopTab, setActiveDesktopTab] = useState< "popular" | "region" >("popular"); const [isScrolled, setIsScrolled] = useState(false); const [products, setProducts] = useState([]); const dispatch = useAppDispatch(); const langMenuRef = useRef(null); const userMenuRef = useRef(null); const account = localStorage.getItem("accountInfo"); const guideItems = [ { label: t("whatEsim"), path: "/support" }, { label: t("installationInstructions"), path: "/support" }, { label: t("supportSupport"), path: "/support" }, { label: t("orderSearch"), path: "/support" }, ]; const dropdownRef = useRef(null); const [areasList, setAreasList] = useState([]); const [searchQuery, setSearchQuery] = useState(""); const [isSearchDropdownOpen, setIsSearchDropdownOpen] = useState(false); const languages = [ { code: "en", label: "English", flag: "us" }, { code: "vi", label: "Tiếng Việt", flag: "vn" }, ]; // load product by country/region or popularity const getProductMutation = useMutation({ mutationFn: async () => { dispatch(startLoading({})); const res = await productApi.loadArea( activeDesktopTab === "popular" ? { isCountry: "-1", isPopular: "1" } : { isCountry: "0", isPopular: "-1" } ); return res; }, onSuccess: (data) => { dispatch(stopLoading()); if (data && data.errorCode === "0") { setProducts(data.data); } else { console.error("Get area failed, no token received"); } }, onError: (error: any) => { dispatch(stopLoading()); console.error("Get area error:", error.response.data); }, }); useEffect(() => { const handleScroll = () => { setIsScrolled(window.scrollY > 300); }; window.addEventListener("scroll", handleScroll); return () => window.removeEventListener("scroll", handleScroll); }, []); const handleAreaClick = (c: { id: number }) => { navigate(`/product/${c.id}`, { state: { ...c, }, }); setIsBuySimMegaVisible(false); setIsMenuOpen(false); }; useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if ( langMenuRef.current && !langMenuRef.current.contains(event.target as Node) ) { setIsLangMenuOpen(false); } }; document.addEventListener("mousedown", handleClickOutside); return () => document.removeEventListener("mousedown", handleClickOutside); }, []); useEffect(() => { const handleResize = () => { if (window.innerWidth >= 1024) setIsMenuOpen(false); }; window.addEventListener("resize", handleResize); return () => window.removeEventListener("resize", handleResize); }, []); const currentLangObj = languages.find((l) => l.code === selectedLang) || languages[0]; const isActive = (path: string) => location.pathname === path; useEffect(() => { getProductMutation.mutate(); }, [activeDesktopTab]); useEffect(() => { if (!areas || areas.length === 0) getAreaMutation.mutate(); else { setAreasList(areas); console.log("Areas loaded from store:", areas); } }, []); const getAreaMutation = useMutation({ mutationFn: async () => { dispatch(startLoading({})); const res = await productApi.loadArea({ isCountry: "-1", isPopular: "-1", }); return res; }, onSuccess: (data) => { dispatch(stopLoading()); console.log("Get area response data:", data); if (data && data.errorCode === "0") { console.log("Get area successful"); setWithExpiry("areas", JSON.stringify(data.data)); setAreasList(data.data as Area[]); } else { console.error("Get area failed, no token received"); } }, onError: (error: any) => { dispatch(stopLoading()); console.error("Get area error:", error.response.data); }, }); const handleSelect = (area: Area) => { console.log("Selected area:", area); setIsSearchDropdownOpen(false); navigate(`/product/${area.id}`, { state: { ...area, }, }); }; const handleSearch = (query: string) => { setSearchQuery(query); if (query.trim() === "") { setAreasList(areas); } else { const filtered = areas.filter((area: Area) => area.coverageArea.toLowerCase().includes(query.toLowerCase()) ); setAreasList(filtered); } }; useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if ( dropdownRef.current && !dropdownRef.current.contains(event.target as Node) ) { setIsSearchDropdownOpen(false); } }; document.addEventListener("mousedown", handleClickOutside); return () => { document.removeEventListener("mousedown", handleClickOutside); }; }, []); return ( <>
{/* Logo */}
{/* */} Getgo Logo {/* Infi Gate */}
{/* Desktop Search on Scroll */}
{ handleSearch(e.target.value); }} onFocus={() => setIsSearchDropdownOpen(true)} placeholder={t("searchCountry")} className="w-full bg-slate-50 border border-slate-200 rounded-full py-2.5 px-6 pl-12 text-sm focus:outline-none focus:ring-2 focus:ring-red-100 focus:border-[#EE0434] transition-all" /> {/* Dropdown Menu */} {isSearchDropdownOpen && (

{t("mostPopular")}

{areasList.length > 0 ? ( areasList.map((p) => ( )) ) : (
{t("noMatchesFound")}
)}
)}
{/* Desktop Nav */} {/* Icons */}
{/* Account Dropdown */}
{isUserMenuOpen && (
{account !== null && (
)} {account === null && (
)}
)}
{/* */}
{isLangMenuOpen && (
{languages.map((lang) => ( ))}
)}
{/* Full-Screen Mobile Menu with Slide-Right Transition */}
{/* Mobile Menu Header */}
setIsMenuOpen(false)} className="flex items-center space-x-1" > Get Go
setIsMenuOpen(false)} className={`w-full text-center py-5 px-6 rounded-3xl text-2xl font-black transition-all ${ isActive("/") ? "bg-red-50 text-[#EE0434]" : "text-slate-800 hover:bg-slate-50" }`} > {t("home")}
{products.map((c) => ( ))}
{guideItems.map((item) => ( ))}
setIsMenuOpen(false)} className={`w-full text-center py-5 px-6 rounded-3xl text-2xl font-black transition-all ${ isActive("/news") ? "bg-red-50 text-[#EE0434]" : "text-slate-800 hover:bg-slate-50" }`} > {t("news")} setIsMenuOpen(false)} className={`w-full text-center py-5 px-6 rounded-3xl text-2xl font-black transition-all ${ isActive("/contact") ? "bg-red-50 text-[#EE0434]" : "text-slate-800 hover:bg-slate-50" }`} > {t("contact")} {account !== null && ( )}

{t("selectLanguage")}

{languages.map((lang) => ( ))}
{account === null && ( { setIsMenuOpen(false); dispatch(accountLogout()); }} className="w-full bg-gradient-to-r from-[#E21c34] to-[#500B28] text-white py-5 rounded-[40px] font-black text-2xl shadow-xl active:scale-[0.98] transition-all flex justify-center" > {t("login")} / {t("register")} )} {account !== null && ( { setIsMenuOpen(false); dispatch(accountLogout()); }} className="w-full bg-gradient-to-r from-[#E21c34] to-[#500B28] text-white py-5 rounded-[40px] font-black text-2xl shadow-xl active:scale-[0.98] transition-all flex justify-center" > {t("logout")} )}
); }; export default Header;