feat: 전화접수 관리 접수리스트↔지정판매소 정보 좌우 너비 조절

두 표 사이 드래그 손잡이로 너비를 조절(리스트 축소 시 정보 확대). 비율은
localStorage에 저장되어 재접속 시 유지되고, 더블클릭으로 기본값 복귀.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
taekyoungc
2026-07-06 18:27:29 +09:00
parent de15cc9e47
commit 249053412c

View File

@@ -15,8 +15,8 @@
</form> </form>
</section> </section>
<div class="grid grid-cols-1 xl:grid-cols-9 gap-3 mt-2"> <div id="order-split" class="flex flex-col xl:flex-row gap-3 mt-2 items-stretch">
<section class="xl:col-span-5 border border-gray-300 rounded-lg bg-white overflow-hidden flex flex-col"> <section id="list-card" class="border border-gray-300 rounded-lg bg-white overflow-hidden flex flex-col min-w-0 xl:shrink-0">
<div class="px-3 py-2 border-b border-gray-200 bg-gray-50 text-sm font-semibold text-gray-700">접수 리스트(전화)</div> <div class="px-3 py-2 border-b border-gray-200 bg-gray-50 text-sm font-semibold text-gray-700">접수 리스트(전화)</div>
<div id="list-scroll" class="overflow-auto"> <div id="list-scroll" class="overflow-auto">
<table class="w-full data-table text-sm"> <table class="w-full data-table text-sm">
@@ -43,7 +43,12 @@
</div> </div>
</section> </section>
<section id="detail-card" class="xl:col-span-4 border border-gray-300 rounded-lg bg-white overflow-hidden"> <!-- 드래그 가능한 너비 조절 손잡이 (xl 이상 좌우 배치일 때만 표시) -->
<div id="split-handle" class="hidden xl:flex items-center justify-center cursor-col-resize select-none shrink-0" style="width:8px;touch-action:none;" role="separator" aria-orientation="vertical" title="드래그하여 표 너비를 조절합니다">
<div class="w-1.5 h-16 rounded-full bg-gray-300 hover:bg-blue-400 transition-colors"></div>
</div>
<section id="detail-card" class="border border-gray-300 rounded-lg bg-white overflow-hidden min-w-0 xl:flex-1">
<div class="px-3 py-2 border-b border-gray-200 bg-gray-50 text-sm font-semibold text-gray-700">지정판매소 정보</div> <div class="px-3 py-2 border-b border-gray-200 bg-gray-50 text-sm font-semibold text-gray-700">지정판매소 정보</div>
<form id="order-detail-form" action="<?= base_url('bag/order/phone/manage/update') ?>" method="POST" class="p-3 space-y-3"> <form id="order-detail-form" action="<?= base_url('bag/order/phone/manage/update') ?>" method="POST" class="p-3 space-y-3">
@@ -494,6 +499,74 @@
new ResizeObserver(function () { syncListHeight(); }).observe(detailCardEl); new ResizeObserver(function () { syncListHeight(); }).observe(detailCardEl);
} }
// ── 접수 리스트 ↔ 지정판매소 정보 사이 너비 조절(드래그 스플리터) ──────
// 손잡이를 접수 리스트 쪽(왼쪽)으로 끌면 리스트 폭이 줄고 지정판매소 정보 폭이 넓어진다.
const splitEl = document.getElementById('order-split');
const listCardEl = document.getElementById('list-card');
const splitHandleEl = document.getElementById('split-handle');
const SPLIT_KEY = 'jrj_order_split_pct';
const SPLIT_MIN = 25, SPLIT_MAX = 75, SPLIT_DEFAULT = 55.5; // 기본값 ≈ 기존 5:4 비율
const xlMedia = window.matchMedia('(min-width: 1280px)');
function clampPct(p) { return Math.min(SPLIT_MAX, Math.max(SPLIT_MIN, p)); }
function currentPct() {
const saved = parseFloat(localStorage.getItem(SPLIT_KEY) || '');
return clampPct(isFinite(saved) ? saved : SPLIT_DEFAULT);
}
function applySplit(pct) {
if (!listCardEl) return;
if (xlMedia.matches) {
// 좌우 배치일 때만 폭 지정(세로로 쌓이는 좁은 화면에서는 전체폭 사용)
listCardEl.style.flex = '0 0 ' + pct + '%';
listCardEl.style.maxWidth = pct + '%';
} else {
listCardEl.style.flex = '';
listCardEl.style.maxWidth = '';
}
syncListHeight();
}
if (splitHandleEl && splitEl && listCardEl) {
let dragging = false, rafId = 0, pendingPct = null;
function onMove(clientX) {
const rect = splitEl.getBoundingClientRect();
if (rect.width <= 0) return;
pendingPct = clampPct((clientX - rect.left) / rect.width * 100);
if (!rafId) {
rafId = requestAnimationFrame(function () {
rafId = 0;
if (pendingPct != null) applySplit(pendingPct);
});
}
}
function pointerMove(e) { if (dragging) { e.preventDefault(); onMove(e.clientX); } }
function pointerUp() {
if (!dragging) return;
dragging = false;
document.body.style.userSelect = '';
document.body.style.cursor = '';
window.removeEventListener('pointermove', pointerMove);
window.removeEventListener('pointerup', pointerUp);
if (pendingPct != null) localStorage.setItem(SPLIT_KEY, String(Math.round(pendingPct * 10) / 10));
}
splitHandleEl.addEventListener('pointerdown', function (e) {
if (!xlMedia.matches) return; // 좁은 화면에서는 비활성
e.preventDefault();
dragging = true;
document.body.style.userSelect = 'none';
document.body.style.cursor = 'col-resize';
window.addEventListener('pointermove', pointerMove);
window.addEventListener('pointerup', pointerUp);
});
// 더블클릭 시 기본 비율로 초기화
splitHandleEl.addEventListener('dblclick', function () {
localStorage.removeItem(SPLIT_KEY);
applySplit(SPLIT_DEFAULT);
});
// 브레이크포인트 전환 시 폭 지정 적용/해제
(xlMedia.addEventListener ? xlMedia.addEventListener('change', function () { applySplit(currentPct()); })
: xlMedia.addListener(function () { applySplit(currentPct()); }));
applySplit(currentPct());
}
// ── 포장 명세 탭: 주문 품목을 박스/팩/낱장 단위 행으로 펼침 ────────── // ── 포장 명세 탭: 주문 품목을 박스/팩/낱장 단위 행으로 펼침 ──────────
const packingBody = document.getElementById('packing-body'); const packingBody = document.getElementById('packing-body');
const packingTotal = document.getElementById('packing-total'); const packingTotal = document.getElementById('packing-total');