|
- import PropTypes from "prop-types";
- import React, { useState, useContext, useEffect, useRef } from "react";
- import { useDispatch, useSelector } from "react-redux";
- import { useNavigate, Link } from "react-router-dom";
- import { SysContext } from "components/SysSettingProvider";
-
- import { checkIsOnlyOnlinePayment } from "../../../utils/Utils";
-
- // material-ui
- import {
- AppBar,
- Typography,
- Box,
- Stack,
- Toolbar,
- Divider,
- IconButton,
- Drawer,
- Grid,
- } from "@mui/material";
- import MenuIcon from "@mui/icons-material/Menu";
- import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
-
- // project import
- import Logo from "components/Logo";
- import AdminLogo from "components/AdminLogo";
- import MobileLogo from "components/MobileLogo";
- import "assets/style/navbarStyles.css";
- import {
- isUserLoggedIn,
- isGLDLoggedIn,
- isPrimaryLoggedIn,
- isCreditorLoggedIn,
- isINDLoggedIn,
- isPasswordExpiry,
- haveOrgPaymentRecord,
- haveOrgDnRecord,
- isORGLoggedIn,
- checkSysEnv,
- } from "utils/Utils";
- import { handleLogoutFunction } from "auth/index";
- import { isGranted, isGrantedAny } from "auth/utils";
-
- import LocaleSelector from "./HeaderContent/LocaleSelector";
- import { FormattedMessage, useIntl } from "react-intl";
-
- const drawerWidth = 300;
- const isAfterAboutSwitchDate = checkIsOnlyOnlinePayment;
-
- const getAboutExternalUrlByLocale = () => {
- const locale = (localStorage.getItem("locale") || "").toLowerCase();
- if (locale === "zh-hk") return "https://www.gld.gov.hk/zh-hk/our-services/printing/advertising-gov-gazette/";
- if (locale === "zh-cn") return "https://www.gld.gov.hk/zh-cn/our-services/printing/advertising-gov-gazette/";
- return "https://www.gld.gov.hk/en/our-services/printing/advertising-gov-gazette/";
- };
-
- /**
- * Accessible dropdown trigger:
- * - button is always focusable
- * - opens on focus (keyboard tab) via CSS :focus-within + optional state
- * - supports Enter/Space/ArrowDown to jump to first submenu item
- * - supports Escape to close + return focus
- */
- function Header(props) {
- const { sysSetting } = useContext(SysContext);
- const { window } = props;
-
- /** Subscribe to auth changes (LOGIN/LOGOUT/cross-tab storage); Header reads localStorage and must re-render. */
- useSelector((state) => state.authRevision);
-
- const [mobileOpen, setMobileOpen] = useState(false);
- const dispatch = useDispatch();
- const navigate = useNavigate();
- const intl = useIntl();
-
- // which dropdown is open (optional but useful for aria-expanded + closing)
- const [openMenu, setOpenMenu] = useState({
- payment: false,
- client: false,
- report: false,
- settings: false,
- paymentHistory: false,
- userSetting: false,
- });
-
- const rootNavRef = useRef(null);
-
- const handleDrawerToggle = () => setMobileOpen((prev) => !prev);
-
- const handleLogout = async () => {
- await dispatch(handleLogoutFunction());
- await navigate("/login");
- };
-
- const openKey = (key) => setOpenMenu((p) => ({ ...p, [key]: true }));
- const closeKey = (key) => setOpenMenu((p) => ({ ...p, [key]: false }));
-
- const closeAll = () =>
- setOpenMenu({
- payment: false,
- client: false,
- report: false,
- settings: false,
- paymentHistory: false,
- userSetting: false,
- });
-
- // close dropdowns on outside click / focus
- useEffect(() => {
- const onDocMouseDown = (e) => {
- if (!rootNavRef.current) return;
- if (!rootNavRef.current.contains(e.target)) closeAll();
- };
- document.addEventListener("mousedown", onDocMouseDown, true);
- return () => document.removeEventListener("mousedown", onDocMouseDown, true);
- }, []);
-
- const onMenuKeyDown = (key) => (e) => {
- if (e.key === "Enter" || e.key === " " || e.key === "ArrowDown") {
- e.preventDefault();
- openKey(key);
- requestAnimationFrame(() => {
- const first = document.querySelector(
- `[data-submenu="${key}"] a, [data-submenu="${key}"] button`
- );
- first?.focus?.();
- });
- } else if (e.key === "Escape") {
- e.preventDefault();
- closeKey(key);
- e.currentTarget?.focus?.();
- } else if (e.key === "ArrowUp") {
- // optional: close on ArrowUp when on trigger
- closeKey(key);
- }
- };
-
- const onTriggerBlur = (key) => (e) => {
- // close only when focus leaves the whole LI (trigger + submenu)
- const li = e.currentTarget.closest("li");
- if (li && li.contains(e.relatedTarget)) return;
- closeKey(key);
- };
-
- // =============================
- // Desktop top nav content (login)
- // =============================
- const loginContent = isGLDLoggedIn() ? (
- <div id="adminContent">
- {isPasswordExpiry() ? (
- <div id="passwordExpiryedContent">
- <li>
- <Link className="manageUser" to={"/user/changePassword"}>
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
- <FormattedMessage id="userChangePassword" />
- </Typography>
- </Link>
- </li>
- </div>
- ) : (
- <div id="adminContentList" ref={rootNavRef}>
- <li>
- <Link className="dashboard" to="/dashboard">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
- Dashboard
- </Typography>
- </Link>
- </li>
-
- {isGrantedAny(["VIEW_APPLICATION", "MAINTAIN_APPLICATION"]) ? (
- <li>
- <Link className="application" to="/application/search">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
- Application
- </Typography>
- </Link>
- </li>
- ) : null}
-
- {isGrantedAny(["VIEW_PROOF", "MAINTAIN_PROOF"]) ? (
- <li>
- <Link className="proof" to="/proof/search">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
- Proof
- </Typography>
- </Link>
- </li>
- ) : null}
-
- {/* ===== Payment dropdown (admin) ===== */}
- {isGrantedAny([
- "MAINTAIN_PROOF",
- "MAINTAIN_PAYMENT",
- "MAINTAIN_RECON",
- "VIEW_DEMANDNOTE",
- "MAINTAIN_DEMANDNOTE",
- ]) ? (
- <li>
- <button
- type="button"
- className="navTrigger paymentTop"
- aria-haspopup="true"
- aria-expanded={openMenu.payment}
- onFocus={() => openKey("payment")}
- onBlur={onTriggerBlur("payment")}
- onKeyDown={onMenuKeyDown("payment")}
- >
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
- Payment
- </Typography>
- <KeyboardArrowDownIcon sx={{ fontSize: "1vw" }} />
- </button>
-
- <ul className="dropdown" data-submenu="payment">
- {isGranted("MAINTAIN_PROOF") ? (
- <li>
- <Link className="payment" to="/paymentPage/exportGDN">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
- Export for GDN
- </Typography>
- </Link>
- </li>
- ) : null}
-
- {isGranted("MAINTAIN_PAYMENT") ? (
- <li>
- <Link className="payment" to="/application/markAsPaid/search">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
- Mark Payment
- </Typography>
- </Link>
- </li>
- ) : null}
-
- {isGranted("MAINTAIN_PAYMENT") ? (
- <li>
- <Link className="payment" to="/paymentPage/search">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
- Online Payment Record
- </Typography>
- </Link>
- </li>
- ) : null}
-
- {isGranted("MAINTAIN_RECON") ? (
- <li>
- <Link className="payment" to="/gfmis/search">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
- GFMIS Generate XML
- </Typography>
- </Link>
- </li>
- ) : null}
-
- {isGranted("MAINTAIN_DEMANDNOTE") ? (
- <li>
- <Link className="payment" to="/paymentPage/createDemandNote">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
- Create Demand Note
- </Typography>
- </Link>
- </li>
- ) : null}
-
- {isGrantedAny(["VIEW_DEMANDNOTE", "MAINTAIN_DEMANDNOTE"]) ? (
- <li>
- <Link className="payment" to="/paymentPage/demandNote">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
- Demand Note
- </Typography>
- </Link>
- </li>
- ) : null}
-
- {isGranted("MAINTAIN_RECON") ? (
- <li>
- <Link className="payment" to="/paymentPage/reconReport">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
- Recon Report
- </Typography>
- </Link>
- </li>
- ) : null}
- </ul>
- </li>
- ) : null}
-
- {/* ===== Client dropdown (admin) ===== */}
- {isGrantedAny([
- "VIEW_USER",
- "MAINTAIN_USER",
- "VIEW_ORG",
- "MAINTAIN_ORG",
- "VIEW_GROUP",
- "MAINTAIN_GROUP",
- "VIEW_GLD_USER",
- "VIEW_IND_USER",
- "VIEW_ORG_USER",
- "MAINTAIN_GLD_USER",
- "MAINTAIN_IND_USER",
- "MAINTAIN_ORG_USER",
- ]) ? (
- <li>
- <button
- type="button"
- className="navTrigger client"
- aria-haspopup="true"
- aria-expanded={openMenu.client}
- onFocus={() => openKey("client")}
- onBlur={onTriggerBlur("client")}
- onKeyDown={onMenuKeyDown("client")}
- >
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
- Client
- </Typography>
- <KeyboardArrowDownIcon sx={{ fontSize: "1vw" }} />
- </button>
-
- <ul className="dropdown" data-submenu="client">
- {isGrantedAny(["VIEW_USER", "MAINTAIN_USER"]) ? (
- <>
- <li>
- <Link className="user" to="/userSearchview">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>
- Users (GLD)
- </Typography>
- </Link>
- </li>
- <li>
- <Link className="user" to="/indUser">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>
- Users (Individual)
- </Typography>
- </Link>
- </li>
- <li>
- <Link className="user" to="/orgUser">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>
- Users (Organisation)
- </Typography>
- </Link>
- </li>
- </>
- ) : (
- <>
- {isGrantedAny(["VIEW_GLD_USER", "MAINTAIN_GLD_USER"]) ? (
- <li>
- <Link className="user" to="/userSearchview">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>
- Users (GLD)
- </Typography>
- </Link>
- </li>
- ) : null}
- {isGrantedAny(["VIEW_IND_USER", "MAINTAIN_IND_USER"]) ? (
- <li>
- <Link className="user" to="/indUser">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>
- Users (Individual)
- </Typography>
- </Link>
- </li>
- ) : null}
- {isGrantedAny(["VIEW_ORG_USER", "MAINTAIN_ORG_USER"]) ? (
- <li>
- <Link className="user" to="/orgUser">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>
- Users (Organisation)
- </Typography>
- </Link>
- </li>
- ) : null}
- </>
- )}
-
- {isGrantedAny(["VIEW_ORG", "MAINTAIN_ORG"]) ? (
- <li>
- <Link className="user" to="/org">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>
- Organisation
- </Typography>
- </Link>
- </li>
- ) : null}
-
- {isGrantedAny(["VIEW_GROUP", "MAINTAIN_GROUP"]) ? (
- <li>
- <Link className="user" to="/usergroupSearchview">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>
- User Group
- </Typography>
- </Link>
- </li>
- ) : null}
- </ul>
- </li>
- ) : null}
-
- {/* ===== Report dropdown (admin) ===== */}
- <li>
- <button
- type="button"
- className="navTrigger setting"
- aria-haspopup="true"
- aria-expanded={openMenu.report}
- onFocus={() => openKey("report")}
- onBlur={onTriggerBlur("report")}
- onKeyDown={onMenuKeyDown("report")}
- >
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
- Report
- </Typography>
- <KeyboardArrowDownIcon sx={{ fontSize: "1vw" }} />
- </button>
-
- <ul className="dropdown" data-submenu="report">
- <li>
- <Link className="report" to="/setting/report/summary">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
- Summary of Gazette Notice
- </Typography>
- </Link>
- </li>
- <li>
- <Link className="report" to="/setting/report/fullList">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
- Gazette Notice Full List
- </Typography>
- </Link>
- </li>
- </ul>
- </li>
-
- {/* ===== Settings dropdown (admin) ===== */}
- <li>
- <button
- type="button"
- className="navTrigger setting"
- aria-haspopup="true"
- aria-expanded={openMenu.settings}
- onFocus={() => openKey("settings")}
- onBlur={onTriggerBlur("settings")}
- onKeyDown={onMenuKeyDown("settings")}
- >
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
- Settings
- </Typography>
- <KeyboardArrowDownIcon sx={{ fontSize: "1vw" }} />
- </button>
-
- <ul className="dropdown" data-submenu="settings">
- <li>
- <Link className="systemSetting" to="/user/profile">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>
- My Profile
- </Typography>
- </Link>
- </li>
-
- <li>
- <Link className="manageUser" to={"/user/changePassword"}>
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
- <FormattedMessage id="userChangePassword" />
- </Typography>
- </Link>
- </li>
-
- {isGranted("VIEW_GAZETTE_ISSUE", "MAINTAIN_GAZETTE_ISSUE") ? (
- <>
- <li>
- <Link className="systemSetting" to="/setting/holiday">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>
- Holiday Settings
- </Typography>
- </Link>
- </li>
- <li>
- <Link className="systemSetting" to="/setting/gazetteissuepage">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>
- Gazette Issues
- </Typography>
- </Link>
- </li>
- </>
- ) : null}
-
- {isGranted("MAINTAIN_ANNOUNCEMENT") ? (
- <li>
- <Link className="systemSetting" to="/setting/announcement">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>
- Announcement
- </Typography>
- </Link>
- </li>
- ) : null}
-
- {isGranted("MAINTAIN_EMAIL") ? (
- <li>
- <Link className="systemSetting" to="/setting/emailTemplate">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>
- Email Template
- </Typography>
- </Link>
- </li>
- ) : null}
-
- {isGranted("MAINTAIN_DR") ? (
- <li>
- <Link className="systemSetting" to="/setting/drImport">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>
- DR Import
- </Typography>
- </Link>
- </li>
- ) : null}
-
- {isGranted("MAINTAIN_SETTING") ? (
- <>
- <li>
- <Link className="systemSetting" to="/setting/sys">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>
- System Settings
- </Typography>
- </Link>
- </li>
- <li>
- <Link className="systemSetting" to="/setting/auditLog">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>
- Audit Log
- </Typography>
- </Link>
- </li>
- </>
- ) : null}
- </ul>
- </li>
-
- <Box sx={{ display: { xs: "none", sm: "none", md: "block" } }}>
- <li>
- <Link className="logout" onClick={handleLogout}>
- <Typography variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
- Logout
- </Typography>
- </Link>
- </li>
- </Box>
- </div>
- )}
- </div>
- ) : (
- // ===== Non-GLD login content (your original logic, only dropdown triggers changed to <button>) =====
- <div id="individualUserContent" ref={rootNavRef}>
- {isPasswordExpiry() ? (
- <div id="passwordExpiryedContent">
- <li>
- <Link className="manageUser" to={"/user/changePassword"}>
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
- <FormattedMessage id="userChangePassword" />
- </Typography>
- </Link>
- </li>
- </div>
- ) : (
- <div id="individualUserContentList">
- <li>
- <Link className="dashboard" to="/dashboard">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
- <FormattedMessage id="mainPage" />
- </Typography>
- </Link>
- </li>
-
- <li>
- <Link className="myDocumet" to="/publicNotice">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
- <FormattedMessage id="myPublicNotice" />
- </Typography>
- </Link>
- </li>
-
- <li>
- <Link className="documentRecord" to="/proof/search">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
- <FormattedMessage id="proofRecord" />
- </Typography>
- </Link>
- </li>
-
- {/* ===== Payment History dropdown (non-admin) ===== */}
- <li>
- {(isCreditorLoggedIn() && haveOrgPaymentRecord()) ||
- (isORGLoggedIn() && haveOrgPaymentRecord()) ||
- (!isCreditorLoggedIn() && !isORGLoggedIn()) ? (
- <>
- <button
- type="button"
- className="navTrigger paymentRecord"
- aria-haspopup="true"
- aria-expanded={openMenu.paymentHistory}
- onFocus={() => openKey("paymentHistory")}
- onBlur={onTriggerBlur("paymentHistory")}
- onKeyDown={onMenuKeyDown("paymentHistory")}
- >
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
- <FormattedMessage id="paymentHistory" />
- </Typography>
- <KeyboardArrowDownIcon sx={{ fontSize: "1.0rem" }} />
- </button>
-
- <ul className="dropdown" data-submenu="paymentHistory">
- <li>
- <Link className="manageOrgUser" to="/paymentPage/search">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
- <FormattedMessage id="onlinePaymentHistory" />
- </Typography>
- </Link>
- </li>
-
- {(isCreditorLoggedIn() && haveOrgPaymentRecord()) ||
- (isORGLoggedIn() && haveOrgPaymentRecord() && haveOrgDnRecord()) ||
- (!isCreditorLoggedIn() && !isORGLoggedIn() && haveOrgDnRecord()) ? (
- <li>
- <Link className="manageOrgUser" to="/paymentPage/demandNote">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
- <FormattedMessage id="paymentInfoRecord" />
- </Typography>
- </Link>
- </li>
- ) : null}
- </ul>
- </>
- ) : (
- <Link className="manageOrgUser" to="/paymentPage/demandNote">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
- <FormattedMessage id="paymentInfoRecord" />
- </Typography>
- </Link>
- )}
- </li>
-
- {/* ===== User Setting dropdown (non-admin) ===== */}
- <li>
- <button
- type="button"
- className="navTrigger userSetting"
- aria-haspopup="true"
- aria-expanded={openMenu.userSetting}
- onFocus={() => openKey("userSetting")}
- onBlur={onTriggerBlur("userSetting")}
- onKeyDown={onMenuKeyDown("userSetting")}
- >
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
- <FormattedMessage id="setting" />
- </Typography>
- <KeyboardArrowDownIcon sx={{ fontSize: "1.0rem" }} />
- </button>
-
- <ul className="dropdown" style={{ width: "max-content" }} data-submenu="userSetting">
- {isPrimaryLoggedIn() ? (
- <>
- <li>
- <Link className="manageOrgUser" to="setting/manageUser">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
- <FormattedMessage id="companyOrUserRecord" />
- </Typography>
- </Link>
- </li>
- <li>
- <Link className="manageUser" to={"/org"}>
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
- <FormattedMessage id="organizationProfile" />
- </Typography>
- </Link>
- </li>
- <li>
- <Link className="manageUser" to={"/orgUser"}>
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
- <FormattedMessage id="userProfile" />
- </Typography>
- </Link>
- </li>
- </>
- ) : isINDLoggedIn() ? (
- <li>
- <Link className="manageUser" to={"/indUser"}>
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
- <FormattedMessage id="userProfile" />
- </Typography>
- </Link>
- </li>
- ) : (
- <li>
- <Link className="manageUser" to={"/orgUser"}>
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
- <FormattedMessage id="userProfile" />
- </Typography>
- </Link>
- </li>
- )}
-
- <li>
- <Link className="manageUser" to={"/user/changePassword"}>
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
- <FormattedMessage id="userChangePassword" />
- </Typography>
- </Link>
- </li>
- </ul>
- </li>
- </div>
- )}
-
- <Box sx={{ display: { xs: "none", sm: "none", md: "block" } }}>
- <li>
- <Link className="logout" onClick={handleLogout}>
- <Typography variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
- <FormattedMessage id="logout" />
- </Typography>
- </Link>
- </li>
- </Box>
- </div>
- );
-
- // =============================
- // Logged-out top nav content
- // =============================
- const logoutContent = (
- <div>
- <li>
- {!isAfterAboutSwitchDate() ? (
- <Link className="login" to="/aboutUs">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
- <FormattedMessage id="aboutUs" />
- </Typography>
- </Link>
- ) : (
- <a className="login" href={getAboutExternalUrlByLocale()} target="_blank" rel="noopener noreferrer">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
- <FormattedMessage id="aboutUs" />
- </Typography>
- </a>
- )}
- </li>
-
- <li>
- <Link className="login" to={"/userGuidePub"}>
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
- <FormattedMessage id="userGuide" />
- </Typography>
- </Link>
- </li>
-
- <li>
- <Link className="login" to="/login">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
- <FormattedMessage id="login" />
- </Typography>
- </Link>
- </li>
-
- {sysSetting?.allowRegistration ? (
- <li>
- <Link className="register" to="/register">
- <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
- <FormattedMessage id="register" />
- </Typography>
- </Link>
- </li>
- ) : null}
- </div>
- );
-
- const drawer = isUserLoggedIn() ? (
- <Stack id="sidebar" direction="column" justifyContent="center" alignItems="center" sx={{ textAlign: "center", width: "300px" }}>
- <Box sx={{ mr: 2, mt: 1, display: { md: "none" } }}>
- <MobileLogo />
- <span style={{ color: checkSysEnv() !== "" ? "red" : "#1976d2" }} id="mobileTitle">
- PNSPS
- </span>
- </Box>
- <Divider />
- <ul id="sidebartop">{loginContent}</ul>
- <Divider />
- <ul id="sidebarbottom">
- <li>
- <Link className="logout" onClick={handleLogout}>
- <FormattedMessage id="logout" />
- </Link>
- </li>
- </ul>
- </Stack>
- ) : (
- <Stack id="sidebar" direction="column" justifyContent="center" alignItems="center" onClick={handleDrawerToggle} sx={{ textAlign: "center" }}>
- <Box sx={{ mr: 2, mt: 1, display: { md: "none" } }}>
- <MobileLogo />
- <span style={{ color: checkSysEnv() !== "" ? "red" : "#1976d2" }} id="mobileTitle">
- PNSPS
- </span>
- </Box>
- <Divider />
- <ul id="logoutContent">{logoutContent}</ul>
- <Divider />
- </Stack>
- );
-
- const container = window !== undefined ? () => window().document.body : undefined;
-
- // =============================
- // Render (your layout kept)
- // =============================
- return isUserLoggedIn() ? (
- <Box>
- <AppBar component="nav" elevation={0}>
- <Toolbar id="nav" width="100%">
- {isGLDLoggedIn() ? (
- <Stack direction="row" justifyContent="flex-start" alignItems="center" spacing={0} sx={{ width: { xs: "100%", md: "5%" } }}>
- <Box mt={0.5} sx={{ flexGrow: 1, display: { xs: "none", sm: "none", md: "block" } }}>
- <AdminLogo />
- </Box>
- <IconButton
- color="inherit"
- aria-label={intl.formatMessage({ id: "openMenu" })}
- aria-expanded={mobileOpen}
- edge="start"
- onClick={handleDrawerToggle}
- sx={{ mr: 2, display: { md: "none" } }}
- >
- <MenuIcon style={{ color: "#1976d2" }} />
- </IconButton>
- <Box sx={{ flexGrow: 1, mr: 2, display: { sm: "block", md: "none" } }}>
- <Stack direction="row" justifyContent="space-between" alignItems="center" width="100%">
- <MobileLogo />
- <Stack justifyContent="flex-start" alignItems="flex-start" width="100%" ml={2}>
- <span style={{ color: checkSysEnv() !== "" ? "red" : "#1976d2" }} id="mobileTitle">
- PNSPS
- </span>
- </Stack>
- <Stack justifyContent="flex-end" alignItems="center">
- <span style={{ color: "#B11B1B", fontWeight: "bold", fontSize: "15px" }}>RESTRICTED</span>
- </Stack>
- </Stack>
- </Box>
- </Stack>
- ) : (
- <Stack direction="row" justifyContent="flex-start" alignItems="center" spacing={0} sx={{ width: { xs: "100%", md: "25%" } }}>
- <Box sx={{ width: "450px", flexGrow: 1, display: { xs: "none", sm: "none", md: "block" } }}>
- <Stack direction="row" justifyContent="flex-start" alignItems="center">
- <Logo />
- <Stack justifyContent="flex-start" alignItems="center">
- <span style={{ color: checkSysEnv() !== "" ? "#B00020" : "#1976d2" }} id="systemTitle">
- <FormattedMessage id="PNSPS" />
- </span>
- </Stack>
- </Stack>
- </Box>
-
- <IconButton
- color="inherit"
- aria-label={intl.formatMessage({ id: "openMenu" })}
- aria-expanded={mobileOpen}
- edge="start"
- onClick={handleDrawerToggle}
- sx={{ mr: 2, display: { md: "none" } }}
- >
- <MenuIcon style={{ color: "#1976d2" }} />
- </IconButton>
-
- <Box sx={{ flexGrow: 1, mr: 2, display: { sm: "block", md: "none" } }}>
- <Stack direction="row" justifyContent="space-between" alignItems="center" width="100%">
- <MobileLogo />
- <Stack justifyContent="flex-start" alignItems="flex-start" width="100%" ml={2}>
- <span style={{ color: checkSysEnv() !== "" ? "red" : "#1976d2" }} id="mobileTitle">
- <FormattedMessage id="PNSPS" />
- </span>
- </Stack>
- <Stack justifyContent="flex-end" alignItems="center">
- <LocaleSelector />
- </Stack>
- </Stack>
- </Box>
- </Stack>
- )}
-
- <Box sx={{ display: { xs: "none", sm: "none", md: "block" }, width: "100%" }}>
- <Stack direction="row" justifyContent="space-between" alignItems="center" spacing={1}>
- <ul id="navbar" width="100%">
- {loginContent}
- </ul>
-
- <Grid item>
- <Grid container direction="column" justifyContent="flex-end" alignItems="center">
- {isGLDLoggedIn() ? (
- <Grid item>
- <span style={{ color: "#B11B1B", fontWeight: "bold", fontSize: "15px" }}>RESTRICTED</span>
- </Grid>
- ) : (
- <Grid item>
- <LocaleSelector />
- </Grid>
- )}
- </Grid>
- </Grid>
- </Stack>
- </Box>
- </Toolbar>
- </AppBar>
-
- <Box component="nav">
- <Drawer
- container={container}
- variant="temporary"
- open={mobileOpen}
- onClose={handleDrawerToggle}
- ModalProps={{ keepMounted: true }}
- sx={{
- display: { sm: "block", md: "none" },
- "& .MuiDrawer-paper": { boxSizing: "border-box", width: drawerWidth },
- }}
- >
- {drawer}
- </Drawer>
- </Box>
- </Box>
- ) : (
- <Box>
- <AppBar component="nav" elevation={0}>
- <Toolbar id="nav" width="100%">
- <Stack direction="row" justifyContent="flex-start" alignItems="center" spacing={0} sx={{ width: { xs: "100%", md: "25%" } }}>
- <Box sx={{ flexGrow: 1, display: { xs: "none", sm: "none", md: "block" } }}>
- <Stack direction="row" justifyContent="flex-start" alignItems="center">
- <Logo />
- <Stack justifyContent="flex-start" alignItems="center">
- <span id="systemTitle">
- <FormattedMessage id="PNSPS" />
- </span>
- </Stack>
- </Stack>
- </Box>
-
- <IconButton
- color="inherit"
- aria-label={intl.formatMessage({ id: "openMenu" })}
- aria-expanded={mobileOpen}
- edge="start"
- onClick={handleDrawerToggle}
- sx={{ mr: 2, display: { md: "none" } }}
- >
- <MenuIcon style={{ color: "#1976d2" }} />
- </IconButton>
-
- <Box sx={{ flexGrow: 1, mr: 2, display: { sm: "block", md: "none" } }}>
- <Stack direction="row" justifyContent="space-between" alignItems="center" width="100%">
- <MobileLogo />
- <Stack justifyContent="flex-start" alignItems="flex-start" width="100%" ml={2}>
- <span style={{ color: checkSysEnv() !== "" ? "red" : "#1976d2" }} id="mobileTitle">
- <FormattedMessage id="PNSPS" />
- </span>
- </Stack>
- <Stack justifyContent="flex-end" alignItems="center">
- <LocaleSelector />
- </Stack>
- </Stack>
- </Box>
- </Stack>
-
- <Box sx={{ display: { xs: "none", sm: "none", md: "block" }, width: "75%" }}>
- <Stack direction="row" justifyContent="space-between" alignItems="center" spacing={1}>
- <ul id="navbar" width="100%">
- {logoutContent}
- </ul>
- <LocaleSelector />
- </Stack>
- </Box>
- </Toolbar>
- </AppBar>
-
- <Box component="nav">
- <Drawer
- container={container}
- variant="temporary"
- open={mobileOpen}
- onClose={handleDrawerToggle}
- ModalProps={{ keepMounted: true }}
- sx={{
- display: { sm: "block", md: "none" },
- "& .MuiDrawer-paper": { boxSizing: "border-box", width: drawerWidth },
- }}
- >
- {drawer}
- </Drawer>
- </Box>
- </Box>
- );
- }
-
- Header.propTypes = {
- window: PropTypes.func,
- };
-
- export default Header;
|