diff --git a/src/pages/subscription/components/DistrictTierEditor.jsx b/src/pages/subscription/components/DistrictTierEditor.jsx new file mode 100644 index 0000000..21b5b1f --- /dev/null +++ b/src/pages/subscription/components/DistrictTierEditor.jsx @@ -0,0 +1,167 @@ +import { useEffect, useState } from "react"; + +const SEOUL_DISTRICTS = [ + "강남구","강동구","강북구","강서구","관악구", + "광진구","구로구","금천구","노원구","도봉구", + "동대문구","동작구","마포구","서대문구","서초구", + "성동구","성북구","송파구","양천구","영등포구", + "용산구","은평구","종로구","중구","중랑구", +]; + +const TIERS = [ + { key: "S", label: "S", weight: "100%" }, + { key: "A", label: "A", weight: "80%" }, + { key: "B", label: "B", weight: "60%" }, + { key: "C", label: "C", weight: "40%" }, + { key: "D", label: "D", weight: "20%" }, +]; + +const EMPTY_TIERS = { S: [], A: [], B: [], C: [], D: [] }; + +function useIsDesktop() { + const [isDesktop, setIsDesktop] = useState( + typeof window !== "undefined" && window.matchMedia("(min-width: 768px)").matches + ); + useEffect(() => { + if (typeof window === "undefined") return; + const mq = window.matchMedia("(min-width: 768px)"); + const handler = (e) => setIsDesktop(e.matches); + mq.addEventListener("change", handler); + return () => mq.removeEventListener("change", handler); + }, []); + return isDesktop; +} + +export default function DistrictTierEditor({ value, onChange }) { + const isDesktop = useIsDesktop(); + const [dragOver, setDragOver] = useState(null); // 현재 hover 중인 zone key + + const current = value && Object.keys(value).length > 0 ? value : EMPTY_TIERS; + + const unassigned = SEOUL_DISTRICTS.filter( + d => !TIERS.some(t => (current[t.key] || []).includes(d)) + ); + + const moveDistrict = (district, targetTier /* null = 미할당 */) => { + const next = { S: [], A: [], B: [], C: [], D: [] }; + for (const t of Object.keys(next)) { + next[t] = (current[t] || []).filter(d => d !== district); + } + if (targetTier) { + next[targetTier] = [...next[targetTier], district]; + } + onChange(next); + }; + + const onDragStart = (e, district) => { + e.dataTransfer.setData("text/district", district); + e.dataTransfer.effectAllowed = "move"; + }; + const onDragOver = (e, key) => { + e.preventDefault(); + e.dataTransfer.dropEffect = "move"; + if (dragOver !== key) setDragOver(key); + }; + const onDragLeave = () => setDragOver(null); + const onDrop = (e, targetTier /* null = 미할당 */) => { + e.preventDefault(); + const district = e.dataTransfer.getData("text/district"); + setDragOver(null); + if (district) moveDistrict(district, targetTier); + }; + + if (!isDesktop) { + return ( +
자치구 우선순위
+✏️ 자치구 분류는 PC에서 편집할 수 있어요
+자치구 우선순위
+미할당 ({unassigned.length})
+