141 lines
5.0 KiB
TypeScript
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>
|
|
);
|
|
}
|