fix: 지정판매소 리스트 기본 10행 표시 + 스크롤(#25 일부)
리스트 스크롤 영역을 헤더+약 10행(424px)으로 제한하고 나머지는 스크롤. 스크롤 시 헤더 고정(sticky), 좌측 패널을 내용 높이로 맞춰(align-self) 리스트 아래 빈 공간 방지. 좁은 화면(1024px 이하)에선 기존 동작 유지.
This commit is contained in:
@@ -11,27 +11,37 @@ if ($currentPath === 'bag/designated-shops') {
|
||||
?>
|
||||
<?= view('components/print_header', ['printTitle' => $readOnly ? '지정판매소 조회 목록' : '지정판매소 목록']) ?>
|
||||
<style>
|
||||
/* 목록 위 → 지정판매소 정보 아래 (가로 2열 없음) */
|
||||
/* 목록 왼쪽 → 지정판매소 정보 오른쪽 (좌우 2열) */
|
||||
.ds-split {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-direction: row;
|
||||
gap: 0.5rem;
|
||||
min-height: 0;
|
||||
flex: 1 1 auto;
|
||||
align-items: stretch;
|
||||
}
|
||||
.ds-list-panel {
|
||||
flex: 0 1 auto;
|
||||
width: 100%;
|
||||
max-height: 42vh;
|
||||
flex: 1 1 55%;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
border: 1px solid #ccc;
|
||||
background: #fff;
|
||||
/* 기본은 내용 높이만 차지(리스트를 10행 정도로 제한하고 아래 빈 공간 없이). */
|
||||
align-self: flex-start;
|
||||
}
|
||||
/* 지정판매소 리스트: 헤더 + 약 10행만 보이고 나머지는 스크롤 */
|
||||
.ds-list-scroll { max-height: 424px; }
|
||||
.ds-list-panel thead th {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
background: #f8f9fa;
|
||||
z-index: 2;
|
||||
box-shadow: inset 0 -1px 0 #e5e7eb;
|
||||
}
|
||||
.ds-detail-panel {
|
||||
flex: 1 1 auto;
|
||||
width: 100%;
|
||||
flex: 1 1 45%;
|
||||
min-width: 0;
|
||||
min-height: 12rem;
|
||||
border: 1px solid #ccc;
|
||||
@@ -39,6 +49,12 @@ if ($currentPath === 'bag/designated-shops') {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
/* 좁은 화면에서는 다시 위·아래로 쌓아 가독성 확보 */
|
||||
@media (max-width: 1024px) {
|
||||
.ds-split { flex-direction: column; }
|
||||
.ds-list-panel { flex: 0 1 auto; max-height: 42vh; align-self: stretch; }
|
||||
.ds-detail-panel { flex: 1 1 auto; }
|
||||
}
|
||||
.ds-panel-title {
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
@@ -222,21 +238,14 @@ $sc = $stateCounts ?? ['total' => 0, 1 => 0, 2 => 0, 3 => 0];
|
||||
<div class="ds-split no-print mx-2 mb-2 mt-2 flex-1 min-h-0">
|
||||
<div class="ds-list-panel">
|
||||
<div class="ds-panel-title shrink-0">지정판매소 리스트</div>
|
||||
<div class="overflow-auto flex-1 min-h-0">
|
||||
<div class="ds-list-scroll overflow-auto flex-1 min-h-0">
|
||||
<table class="w-full text-[13px]">
|
||||
<thead>
|
||||
<tr class="text-left text-[11px] font-semibold text-gray-500 border-b border-gray-200">
|
||||
<th class="py-2.5 px-2 w-14 text-left">번호</th>
|
||||
<th class="py-2.5 px-2 w-24">구·군</th>
|
||||
<th class="py-2.5 px-2 w-24 text-left">지정일</th>
|
||||
<th class="py-2.5 px-2 w-24">구역</th>
|
||||
<th class="py-2.5 px-2 ds-col-tight">대표자명</th>
|
||||
<th class="py-2.5 px-2 ds-col-tight">상호명</th>
|
||||
<th class="py-2.5 px-2 ds-col-zip text-left">우편번호</th>
|
||||
<th class="py-2.5 px-2 text-left">주소</th>
|
||||
<th class="py-2.5 px-2 w-28">사업자번호</th>
|
||||
<th class="py-2.5 px-2 w-28">전화</th>
|
||||
<th class="py-2.5 px-2 w-16 text-left">상태</th>
|
||||
<th class="ds-sort-th py-2.5 px-2 w-14 text-left cursor-pointer select-none" data-sort-key="no" data-sort-type="num">번호<span class="ds-sort-ind"></span></th>
|
||||
<th class="ds-sort-th py-2.5 px-2 cursor-pointer select-none" data-sort-key="rep" data-sort-type="str">대표자명<span class="ds-sort-ind"></span></th>
|
||||
<th class="ds-sort-th py-2.5 px-2 cursor-pointer select-none" data-sort-key="name" data-sort-type="str">상호명<span class="ds-sort-ind"></span></th>
|
||||
<th class="ds-sort-th py-2.5 px-2 w-16 text-left cursor-pointer select-none" data-sort-key="state" data-sort-type="num">상태<span class="ds-sort-ind"></span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="ds-list-body">
|
||||
@@ -267,17 +276,15 @@ $sc = $stateCounts ?? ['total' => 0, 1 => 0, 2 => 0, 3 => 0];
|
||||
$addrCombinedList = $addrMainList;
|
||||
}
|
||||
?>
|
||||
<tr class="ds-list-row cursor-pointer border-b border-gray-200 last:border-0 hover:bg-blue-50/60" data-row-index="<?= (int) $i ?>" role="button" tabindex="0">
|
||||
<tr class="ds-list-row cursor-pointer border-b border-gray-200 last:border-0 hover:bg-blue-50/60"
|
||||
data-row-index="<?= (int) $i ?>" role="button" tabindex="0"
|
||||
data-sort-no="<?= esc((string) (preg_match('/\d+/', $shortNo, $mn) ? (int) $mn[0] : 0), 'attr') ?>"
|
||||
data-sort-rep="<?= esc($row->ds_rep_name ?? '', 'attr') ?>"
|
||||
data-sort-name="<?= esc($row->ds_name ?? '', 'attr') ?>"
|
||||
data-sort-state="<?= (int) $st ?>">
|
||||
<td class="py-2.5 px-2 text-left font-mono text-gray-700"><?= esc($shortNo) ?></td>
|
||||
<td class="py-2.5 px-2 text-gray-600"><?= esc($ggLabel) ?></td>
|
||||
<td class="py-2.5 px-2 text-left text-gray-500 text-[12px]"><?= esc($daDisp) ?></td>
|
||||
<td class="py-2.5 px-2 text-gray-600"><?= esc($zone) ?></td>
|
||||
<td class="py-2.5 px-2 text-gray-600 ds-col-tight" title="<?= esc($row->ds_rep_name ?? '') ?>"><?= esc($row->ds_rep_name ?? '') ?></td>
|
||||
<td class="py-2.5 px-2 font-medium text-gray-900 ds-col-tight" title="<?= esc($row->ds_name ?? '') ?>"><?= esc($row->ds_name ?? '') ?></td>
|
||||
<td class="py-2.5 px-2 text-left font-mono text-gray-700 ds-col-zip" title="<?= esc($zipList) ?>"><?= esc($zipList) ?></td>
|
||||
<td class="py-2.5 px-2 text-gray-600 ds-col-addr-list" title="<?= esc($addrCombinedList) ?>"><?= esc($addrCombinedList) ?></td>
|
||||
<td class="py-2.5 px-2 font-mono text-gray-700"><?= esc($row->ds_biz_no ?? '') ?></td>
|
||||
<td class="py-2.5 px-2 font-mono text-gray-700"><?= esc($row->ds_tel ?? '') ?></td>
|
||||
<td class="py-2.5 px-2 text-left">
|
||||
<?php if ($st === 1): ?>
|
||||
<span class="inline-block px-2 py-0.5 rounded-full text-[11px] font-medium bg-emerald-50 text-emerald-700">정상</span>
|
||||
@@ -297,69 +304,89 @@ $sc = $stateCounts ?? ['total' => 0, 1 => 0, 2 => 0, 3 => 0];
|
||||
<div class="ds-detail-inner" id="ds-detail-box">
|
||||
<p id="ds-detail-placeholder" class="text-sm text-gray-500 py-6 text-center">위 목록에서 행을 선택하세요.</p>
|
||||
<div id="ds-detail-fields" class="hidden">
|
||||
<div class="ds-detail-info-wrap">
|
||||
<table class="w-full data-table text-sm" id="ds-detail-info-table" aria-label="지정판매소 상세">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>판매소번호</th>
|
||||
<th class="ds-col-tight-head">상호명</th>
|
||||
<th>우편번호</th>
|
||||
<th>사업자번호</th>
|
||||
<th>일반전화</th>
|
||||
<th class="ds-col-tight-head">대표자명</th>
|
||||
<th>이메일</th>
|
||||
<th>업태</th>
|
||||
<th>업종</th>
|
||||
<th>지정일자</th>
|
||||
<th>지자체</th>
|
||||
<th>도로명주소</th>
|
||||
<th>지번주소</th>
|
||||
<th>상세주소</th>
|
||||
<th>개인전화</th>
|
||||
<th>구·군</th>
|
||||
<th>구역</th>
|
||||
<th>가상계좌(은행)</th>
|
||||
<th>계좌번호</th>
|
||||
<th>종사업장번호</th>
|
||||
<th>변경일자</th>
|
||||
<th>영업상태</th>
|
||||
<th>등록일시</th>
|
||||
<th>변경사유</th>
|
||||
<th class="no-print w-14 text-center">지도</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="text-left" data-ro="ds_shop_no">—</td>
|
||||
<td class="text-left ds-col-tight-cell" data-ro="ds_name">—</td>
|
||||
<td class="text-left" data-ro="ds_zip">—</td>
|
||||
<td class="text-left" data-ro="ds_biz_no">—</td>
|
||||
<td class="text-left" data-ro="ds_tel">—</td>
|
||||
<td class="text-left ds-col-tight-cell" data-ro="ds_rep_name">—</td>
|
||||
<td class="text-left" data-ro="ds_email">—</td>
|
||||
<td class="text-left" data-ro="ds_biz_type">—</td>
|
||||
<td class="text-left" data-ro="ds_biz_kind">—</td>
|
||||
<td class="text-left" data-ro="ds_designated_at">—</td>
|
||||
<td class="text-left" data-ro="lg_name">—</td>
|
||||
<td class="text-left min-w-[10rem]"><span data-ro="ds_addr">—</span></td>
|
||||
<td class="text-left" data-ro="ds_addr_jibun">—</td>
|
||||
<td class="text-left" data-ro="ds_addr_detail">—</td>
|
||||
<td class="text-left" data-ro="ds_rep_phone">—</td>
|
||||
<td class="text-left" data-ro="gugun_name">—</td>
|
||||
<td class="text-left" data-ro="ds_zone_code">—</td>
|
||||
<td class="text-left" data-ro="ds_va_bank">—</td>
|
||||
<td class="text-left" data-ro="ds_va_account">—</td>
|
||||
<td class="text-left" data-ro="ds_branch_no">—</td>
|
||||
<td class="text-left" data-ro="ds_state_changed_at">—</td>
|
||||
<td class="text-left" data-ro="state_label">—</td>
|
||||
<td class="text-left" data-ro="ds_regdate">—</td>
|
||||
<td class="text-left min-w-[8rem]" data-ro="ds_change_reason">—</td>
|
||||
<td class="text-center no-print">
|
||||
<button type="button" class="border border-btn-print-border text-gray-700 px-2 py-0.5 rounded-sm text-xs hover:bg-gray-50" id="ds-ro-map-btn">지도</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<!-- 제목 왼쪽 · 내용 오른쪽 (라벨/값) 폼 형태 -->
|
||||
<div class="ds-detail-form" id="ds-detail-info-table" aria-label="지정판매소 상세">
|
||||
<div class="ds-row ds-row-wide">
|
||||
<div class="ds-field-label">판매소번호</div>
|
||||
<div class="ds-field-value ds-value-shop-wide" data-ro="ds_shop_no">—</div>
|
||||
</div>
|
||||
<div class="ds-row ds-row-4-even">
|
||||
<div class="ds-field-label">상호명</div>
|
||||
<div class="ds-field-value" data-ro="ds_name">—</div>
|
||||
<div class="ds-field-label">우편번호</div>
|
||||
<div class="ds-field-value" data-ro="ds_zip">—</div>
|
||||
</div>
|
||||
<div class="ds-row ds-row-4-even">
|
||||
<div class="ds-field-label">사업자번호</div>
|
||||
<div class="ds-field-value" data-ro="ds_biz_no">—</div>
|
||||
<div class="ds-field-label">일반전화</div>
|
||||
<div class="ds-field-value" data-ro="ds_tel">—</div>
|
||||
</div>
|
||||
<div class="ds-row ds-row-4-even">
|
||||
<div class="ds-field-label">대표자명</div>
|
||||
<div class="ds-field-value" data-ro="ds_rep_name">—</div>
|
||||
<div class="ds-field-label">이메일</div>
|
||||
<div class="ds-field-value" data-ro="ds_email">—</div>
|
||||
</div>
|
||||
<div class="ds-row ds-row-wide">
|
||||
<div class="ds-field-label">도로명주소</div>
|
||||
<div class="ds-field-value ds-field-value-with-map">
|
||||
<span class="ds-addr-text" data-ro="ds_addr">—</span>
|
||||
<button type="button" class="no-print border border-btn-print-border text-gray-700 px-2 py-0.5 rounded-sm text-xs hover:bg-gray-50 shrink-0" id="ds-ro-map-btn">지도 보기</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ds-row ds-row-wide">
|
||||
<div class="ds-field-label">지번주소</div>
|
||||
<div class="ds-field-value" data-ro="ds_addr_jibun">—</div>
|
||||
</div>
|
||||
<div class="ds-row ds-row-wide">
|
||||
<div class="ds-field-label">상세주소</div>
|
||||
<div class="ds-field-value" data-ro="ds_addr_detail">—</div>
|
||||
</div>
|
||||
<div class="ds-row ds-row-wide">
|
||||
<div class="ds-field-label">개인전화</div>
|
||||
<div class="ds-field-value" data-ro="ds_rep_phone">—</div>
|
||||
</div>
|
||||
<div class="ds-row ds-row-4-even">
|
||||
<div class="ds-field-label">지정일자</div>
|
||||
<div class="ds-field-value" data-ro="ds_designated_at">—</div>
|
||||
<div class="ds-field-label">업태</div>
|
||||
<div class="ds-field-value" data-ro="ds_biz_type">—</div>
|
||||
</div>
|
||||
<div class="ds-row ds-row-4-even">
|
||||
<div class="ds-field-label">업종</div>
|
||||
<div class="ds-field-value" data-ro="ds_biz_kind">—</div>
|
||||
<div class="ds-field-label">구·군</div>
|
||||
<div class="ds-field-value" data-ro="gugun_name">—</div>
|
||||
</div>
|
||||
<div class="ds-row ds-row-4-even">
|
||||
<div class="ds-field-label">구역</div>
|
||||
<div class="ds-field-value" data-ro="ds_zone_code">—</div>
|
||||
<div class="ds-field-label">종사업장번호</div>
|
||||
<div class="ds-field-value" data-ro="ds_branch_no">—</div>
|
||||
</div>
|
||||
<div class="ds-row ds-row-4-even">
|
||||
<div class="ds-field-label">가상계좌</div>
|
||||
<div class="ds-field-value" data-ro="ds_va_bank">—</div>
|
||||
<div class="ds-field-label">계좌번호</div>
|
||||
<div class="ds-field-value" data-ro="ds_va_account">—</div>
|
||||
</div>
|
||||
<div class="ds-row ds-row-4-even">
|
||||
<div class="ds-field-label">영업상태</div>
|
||||
<div class="ds-field-value" data-ro="state_label">—</div>
|
||||
<div class="ds-field-label">변경일자</div>
|
||||
<div class="ds-field-value" data-ro="ds_state_changed_at">—</div>
|
||||
</div>
|
||||
<div class="ds-row ds-row-wide">
|
||||
<div class="ds-field-label">변경사유</div>
|
||||
<div class="ds-field-value" data-ro="ds_change_reason">—</div>
|
||||
</div>
|
||||
<div class="ds-row ds-row-4-even">
|
||||
<div class="ds-field-label">지자체</div>
|
||||
<div class="ds-field-value" data-ro="lg_name">—</div>
|
||||
<div class="ds-field-label">등록일시</div>
|
||||
<div class="ds-field-value" data-ro="ds_regdate">—</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -469,6 +496,44 @@ $sc = $stateCounts ?? ['total' => 0, 1 => 0, 2 => 0, 3 => 0];
|
||||
});
|
||||
}
|
||||
|
||||
// ── 컬럼 헤더 클릭 정렬 (DOM 행 재배치 — data-row-index 유지) ──
|
||||
(function initSort() {
|
||||
if (!body) return;
|
||||
var ths = document.querySelectorAll('.ds-sort-th');
|
||||
var curKey = null, curDir = 'asc';
|
||||
function apply(key, type, dir) {
|
||||
var trs = Array.prototype.slice.call(body.querySelectorAll('tr.ds-list-row'));
|
||||
trs.sort(function (a, b) {
|
||||
var va = a.getAttribute('data-sort-' + key) || '';
|
||||
var vb = b.getAttribute('data-sort-' + key) || '';
|
||||
var r;
|
||||
if (type === 'num') {
|
||||
r = (parseFloat(va) || 0) - (parseFloat(vb) || 0);
|
||||
} else {
|
||||
r = String(va).localeCompare(String(vb), 'ko');
|
||||
}
|
||||
return dir === 'asc' ? r : -r;
|
||||
});
|
||||
trs.forEach(function (tr) { body.appendChild(tr); });
|
||||
}
|
||||
ths.forEach(function (th) {
|
||||
th.addEventListener('click', function () {
|
||||
var key = th.getAttribute('data-sort-key');
|
||||
var type = th.getAttribute('data-sort-type') || 'str';
|
||||
if (curKey === key) {
|
||||
curDir = curDir === 'asc' ? 'desc' : 'asc';
|
||||
} else {
|
||||
curKey = key; curDir = 'asc';
|
||||
}
|
||||
apply(key, type, curDir);
|
||||
ths.forEach(function (t) {
|
||||
var ind = t.querySelector('.ds-sort-ind');
|
||||
if (ind) ind.textContent = (t === th) ? (curDir === 'asc' ? ' ▲' : ' ▼') : '';
|
||||
});
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
||||
var mapBtnRo = document.getElementById('ds-ro-map-btn');
|
||||
if (mapBtnRo) {
|
||||
mapBtnRo.addEventListener('click', function (ev) {
|
||||
|
||||
Reference in New Issue
Block a user