Files
frontend/apps/sn/app/(map-layout)/map/components/gisEdit/GisEditSessionPanel.tsx
T

141 lines
5.0 KiB
TypeScript

"use client";
import type { GisEditSessionSnapshot, GisEditTool } from "./gisEditTypes";
type Props = GisEditSessionSnapshot & {
onRemoveFocusedChange: () => void;
onRemoveLastChange: () => void;
onClearChanges: () => void;
onFocusChange: (changeId: string) => void;
className?: string;
};
const TOOL_LABELS: Record<GisEditTool, string> = {
ADD: "추가",
MOVE: "이동",
VERTEX_EDIT: "꼭지점편집",
DELETE: "삭제",
};
const buildChangeItemClassName = (isFocused: boolean) =>
`block w-full rounded border px-3 py-3 text-left text-[12px] transition ${
isFocused
? "border-[#5a9bd5] bg-[#eef7ff] shadow-[inset_0_0_0_1px_rgba(90,155,213,0.2)]"
: "border-[#d8dee8] bg-[#fbfcfe] hover:border-[#bfd2e5] hover:bg-white"
}`;
const getChangeLabel = (change: GisEditSessionSnapshot["changes"][number]) =>
change.attributeOnly ? "상세정보수정" : TOOL_LABELS[change.editType];
type ChangeListProps = {
changes: GisEditSessionSnapshot["changes"];
focusedChangeId: string | null;
onFocusChange: (changeId: string) => void;
};
const ChangeList = ({ changes, focusedChangeId, onFocusChange }: ChangeListProps) => (
<>
{changes.map((change, index) => (
<button
key={change.changeId}
type="button"
className={buildChangeItemClassName(focusedChangeId === change.changeId)}
onClick={() => onFocusChange(change.changeId)}
>
<div className="flex items-center justify-between gap-3">
<div className="font-semibold text-[#173f67]">
{index + 1}. {getChangeLabel(change)} / {change.objectLabel}
</div>
<div className="flex items-center gap-1.5">
{change.basicInfoSavedAt ? (
<span className="rounded-full border border-[#a9d9bd] bg-white px-2 py-0.5 text-[10px] font-semibold text-[#16834f]">
기본정보 세션저장
</span>
) : null}
{focusedChangeId === change.changeId ? (
<span className="rounded-full border border-[#b8d3ef] bg-white px-2 py-0.5 text-[10px] font-semibold text-[#176db8]">
지도 미리보기 선택
</span>
) : null}
</div>
</div>
<div className="mt-1 text-[#526173]">{change.summary}</div>
</button>
))}
</>
);
export default function GisEditSessionPanel({
isEditMode,
selectedLayerName,
activeTool,
changes,
canUndo,
focusedChangeId,
onRemoveFocusedChange,
onRemoveLastChange,
onClearChanges,
onFocusChange,
className = "",
}: Props) {
return (
<div
className={`rounded-lg border border-[#d8dee8] bg-[rgba(255,255,255,0.98)] p-4 text-sm text-[#304255] shadow-[0_10px_26px_rgba(23,42,70,0.14)] ${className}`.trim()}
>
<div className="mb-3 flex items-center justify-between gap-3">
<div className="text-[12px] text-[#667485]">
레이어: {selectedLayerName || "미선택"} / 모드: {isEditMode ? (activeTool ? TOOL_LABELS[activeTool] : "대기") : "편집 모드 종료"}
</div>
</div>
<div className="mb-3 flex flex-wrap items-center gap-2">
<button
type="button"
className="rounded border border-[#d8dee8] bg-white px-3 py-1.5 text-[12px] font-semibold text-[#304255] transition hover:bg-[#f8fafc] disabled:cursor-not-allowed disabled:text-[#9aa8b7]"
disabled={!focusedChangeId}
onClick={onRemoveFocusedChange}
>
취소
</button>
<button
type="button"
className="rounded border border-[#d8dee8] bg-white px-3 py-1.5 text-[12px] font-semibold text-[#304255] transition hover:bg-[#f8fafc] disabled:cursor-not-allowed disabled:text-[#9aa8b7]"
disabled={!canUndo}
onClick={onRemoveLastChange}
>
뒤로가기
</button>
<button
type="button"
className="rounded border border-[#f3d0d0] bg-white px-3 py-1.5 text-[12px] font-semibold text-[#b42318] transition hover:bg-[#fff5f5] disabled:cursor-not-allowed disabled:text-[#d0a5a5]"
disabled={!canUndo}
onClick={onClearChanges}
>
초기화
</button>
<div className="ml-auto rounded-full border border-[#d8dee8] bg-white px-2.5 py-1 text-[11px] font-semibold text-[#526173]">
총 {changes.length}건
</div>
</div>
<div className="space-y-2">
{changes.length === 0 ? (
<div className="rounded border border-dashed border-[#d8dee8] bg-[#fbfcfe] px-3 py-4 text-[12px] text-[#667485]">
저장할 편집 변경분이 없습니다.
</div>
) : (
<div className="max-h-[calc(100vh-190px)] overflow-y-auto pr-1">
<div className="space-y-2">
<ChangeList
changes={changes}
focusedChangeId={focusedChangeId}
onFocusChange={onFocusChange}
/>
</div>
</div>
)}
</div>
</div>
);
}