132 lines
4.1 KiB
TypeScript
132 lines
4.1 KiB
TypeScript
import "./header.css";
|
|
|
|
import { useEffect, useCallback } from "react";
|
|
import { useQuery } from "@tanstack/react-query";
|
|
import { images } from "@common/assets";
|
|
import { getConfig } from "@common/config";
|
|
import { ENDPOINT } from "../../config";
|
|
import { setCookie, getCookie } from "../../lib";
|
|
import {
|
|
getPopupInfo,
|
|
getPopupList,
|
|
getSiteInfo,
|
|
getUserInfo,
|
|
type PopupInfo,
|
|
} from "../../api";
|
|
import {
|
|
DropdownMenu,
|
|
DropdownMenuTrigger,
|
|
DropdownMenuContent,
|
|
DropdownMenuItem,
|
|
} from "../dropdown-menu";
|
|
import { Button } from "../button";
|
|
|
|
const { SITE_ID } = getConfig();
|
|
|
|
export function Header({ viewOnly }: { viewOnly?: boolean }) {
|
|
const { data: userInfo } = useQuery({
|
|
queryKey: [ENDPOINT.USER_SERVICE.USERS],
|
|
queryFn: () => getUserInfo(),
|
|
enabled: !viewOnly,
|
|
});
|
|
|
|
const { data: siteInfo } = useQuery({
|
|
queryKey: [ENDPOINT.CMS_SERVICE.SITES, SITE_ID],
|
|
queryFn: () => getSiteInfo(SITE_ID ?? ""),
|
|
select: (data) => {
|
|
if (data.siteSkn) {
|
|
const siteSkin = data.siteSkn.toLowerCase();
|
|
setCookie("site-theme-key", siteSkin);
|
|
document.documentElement.setAttribute("data-theme", siteSkin);
|
|
}
|
|
return data;
|
|
},
|
|
enabled: !viewOnly,
|
|
});
|
|
|
|
const { data: popupList } = useQuery({
|
|
queryKey: [ENDPOINT.CMS_SERVICE.POPUPS],
|
|
queryFn: () => getPopupList(),
|
|
});
|
|
|
|
const openPopup = useCallback(async (popup: PopupInfo) => {
|
|
try {
|
|
const cookieName = `cs-popup-hide-for-day-${popup.popupSn}`;
|
|
const hasCookie = getCookie(cookieName);
|
|
if (hasCookie) return;
|
|
|
|
const response = await getPopupInfo(popup.popupSn);
|
|
if (!response) return;
|
|
|
|
const width = response.popupWdth || 400;
|
|
const height = response.popupHgt || 300;
|
|
const left = (response.popupHrzntltyPstn || 0) + window.screenX;
|
|
const top = (response.popupVtclPstn || 0) + window.screenY;
|
|
|
|
const popupWindow = window.open(
|
|
`/view-popup/${popup.popupSn}`,
|
|
"",
|
|
`width=${width},height=${height},left=${left},top=${top},resizable=yes,scrollbars=yes,status=no,location=no,menubar=no`,
|
|
);
|
|
|
|
if (popupWindow) {
|
|
popupWindow.focus();
|
|
}
|
|
} catch (error) {
|
|
console.error(`Failed to open popup ${popup.popupSn}:`, error);
|
|
}
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (!popupList?.content.length) return;
|
|
|
|
const timer = setTimeout(() => {
|
|
popupList.content.forEach((popup) => {
|
|
openPopup(popup);
|
|
});
|
|
}, 500);
|
|
|
|
return () => clearTimeout(timer);
|
|
}, [popupList, openPopup]);
|
|
|
|
return (
|
|
<header className="sticky top-0 z-30 box-border flex h-[5rem] w-full items-center justify-between border-b border-solid border-border bg-background">
|
|
<div className="flex items-center">
|
|
<div className="MobMenuBtn">
|
|
<img src={images.menuBtn} />
|
|
</div>
|
|
<h1 className="flex items-center gap-4">
|
|
<img src={images.logo} className="h-[3rem]" alt="logo" />
|
|
<span className="text-[1.8rem] font-semibold text-foreground">
|
|
{siteInfo?.siteNm}
|
|
</span>
|
|
</h1>
|
|
</div>
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger asChild>
|
|
<Button
|
|
className="group m-0 flex h-[3rem] items-center !bg-background px-4 py-0 text-label"
|
|
data-trigger="dropdown"
|
|
>
|
|
<i className="diveicon di-account-circle static translate-y-0.5 pr-2 text-3xl" />
|
|
{userInfo?.userName}
|
|
<i className="diveicon di-chevron-down static p-0 transition-transform group-data-[state=open]:rotate-180" />
|
|
</Button>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent>
|
|
<DropdownMenuItem>프로필 설정</DropdownMenuItem>
|
|
<div className="flex flex-col items-start gap-0 px-4 py-3">
|
|
<p className="text-base text-label">최종접속일</p>
|
|
<p>{userInfo?.lastLoginDate}</p>
|
|
</div>
|
|
<div className="flex flex-col items-start gap-0 px-4 py-3">
|
|
<p className="text-base text-label">접속 IP</p>
|
|
<p></p>
|
|
</div>
|
|
<DropdownMenuItem>로그아웃</DropdownMenuItem>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
</header>
|
|
);
|
|
}
|