Files
frontend/apps/sn/app/(map-layout)/map/components/analysisMenu/AnalysisPopupMenu.tsx
T

104 lines
4.2 KiB
TypeScript

"use client";
import { useState } from "react";
import {
ChartColumnBig,
ChevronLeft,
ChevronRight,
History,
PanelsTopLeft,
PencilRuler,
Search,
Settings2,
TriangleAlert,
Waves,
} from "lucide-react";
import type { WindowPopupKey } from "@/features/windowPopup/model/popupDefinitions";
type Props = {
onOpenPopup: (popupKey: WindowPopupKey) => void;
onOpenInfoSearch: () => void;
};
const ANALYSIS_POPUP_ITEMS: Array<{
key: WindowPopupKey | "infoSearch";
label: string;
icon: typeof ChartColumnBig;
}> = [
{ key: "infoSearch", label: "정보검색", icon: Search },
{ key: "pipeAnalysisPopup", label: "관로분석", icon: ChartColumnBig },
{ key: "floodPredictionMapPopup", label: "침수예측지도", icon: Waves },
{ key: "floodHistoryPopup", label: "침수발생이력", icon: History },
{ key: "gisEditPopup", label: "GIS 편집", icon: PencilRuler },
{ key: "gisManagementPopup", label: "GIS 관리", icon: Settings2 },
{ key: "flowRiskPopup", label: "통수 위험", icon: TriangleAlert },
];
export default function AnalysisPopupMenu({ onOpenPopup, onOpenInfoSearch }: Props) {
const [isOpen, setIsOpen] = useState(true);
const [activeKey, setActiveKey] = useState<WindowPopupKey | "infoSearch" | null>(null);
return (
<div className="absolute right-[0.55rem] top-[20px] z-[45]">
<div className="relative">
{isOpen ? (
<div className="absolute right-[28px] w-[132px] overflow-hidden rounded-[6px] border border-[#d8dee8] bg-[rgba(255,255,255,0.96)] shadow-[0_8px_18px_rgba(15,23,42,0.14)]">
<div className="flex h-[36px] items-center gap-2 border-b border-[#e5eaf1] bg-[#f8fafc] px-[10px] text-[13px] font-bold text-[#1f2937]">
<div className="flex items-center gap-2">
<PanelsTopLeft className="h-4 w-4 text-[#1e88e5]" />
<span>분석도구</span>
</div>
</div>
<div className="flex flex-col gap-1 p-[6px]">
{ANALYSIS_POPUP_ITEMS.map((item) => {
const Icon = item.icon;
const isActive = activeKey === item.key;
return (
<button
key={item.key}
type="button"
className={`relative flex h-[34px] items-center gap-[7px] rounded-[5px] border px-[8px] pl-[10px] text-left text-[12px] font-semibold transition ${
isActive
? "border-[#b9dcff] bg-[#eaf4ff] font-bold text-[#0f5fa8] before:absolute before:left-0 before:top-[7px] before:bottom-[7px] before:w-[3px] before:rounded-r-[2px] before:bg-[#1e88e5]"
: "border-transparent bg-white text-[#374151] hover:border-[#cfe5ff] hover:bg-[#eef6ff] hover:text-[#1e3a5f]"
}`}
onClick={() => {
setActiveKey(item.key);
if (item.key === "infoSearch") {
onOpenInfoSearch();
return;
}
onOpenPopup(item.key);
}}
>
<Icon
className={`h-[15px] w-[15px] shrink-0 ${
isActive ? "text-[#1e88e5]" : "text-[#64748b]"
}`}
/>
<span className="break-keep whitespace-normal">{item.label}</span>
</button>
);
})}
</div>
</div>
) : null}
<button
type="button"
className="absolute right-0 top-0 flex h-[36px] w-[20px] items-center justify-center rounded-[4px] border border-[#d8dee8] bg-[rgba(255,255,255,0.96)] text-[#64748b] shadow-[0_8px_18px_rgba(15,23,42,0.14)] transition hover:bg-[#eaf4ff] hover:text-[#1e88e5]"
onClick={() => setIsOpen((value) => !value)}
title={isOpen ? "분석 메뉴 접기" : "분석 메뉴 펼치기"}
aria-label={isOpen ? "분석 메뉴 접기" : "분석 메뉴 펼치기"}
>
{isOpen ? <ChevronRight className="h-4 w-4" /> : <ChevronLeft className="h-4 w-4" />}
</button>
</div>
</div>
);
}