|
|
|
@@ -1,6 +1,6 @@
|
|
|
|
|
{% extends "erp_base.html" %}
|
|
|
|
|
|
|
|
|
|
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260831c" />{% endblock %}
|
|
|
|
|
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260831d" />{% endblock %}
|
|
|
|
|
|
|
|
|
|
{% block content %}
|
|
|
|
|
<section class="cpg">
|
|
|
|
@@ -27,32 +27,33 @@
|
|
|
|
|
<span class="erp-muted">지역별로 묶어 표시. 이름 변경은 지원하지 않음 — 삭제 후 새로 등록.</span>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 목록: 지역 그룹 카드, 위→아래로 읽고 열로 흐름 -->
|
|
|
|
|
<!-- 목록: 지역 그룹 패널, 위→아래로 읽고 열로 흐름 -->
|
|
|
|
|
<div class="cpg-center-cols" id="cpgCenterGrid">
|
|
|
|
|
{% for g in center_groups %}
|
|
|
|
|
<div class="cpg-center-group" data-group="{{ g.name|lower }}">
|
|
|
|
|
<div class="cpg-center-gtitle">
|
|
|
|
|
<section class="cpg-center-group" data-group="{{ g.name|lower }}">
|
|
|
|
|
<button type="button" class="cpg-center-gtitle" aria-expanded="true">
|
|
|
|
|
<span class="cpg-center-caret" aria-hidden="true"></span>
|
|
|
|
|
<span class="cpg-center-gname">{{ g.name }}</span>
|
|
|
|
|
<span class="cpg-center-gcount">{{ g.count }}</span>
|
|
|
|
|
</button>
|
|
|
|
|
<div class="cpg-center-glist">
|
|
|
|
|
{% for c in g["items"] %}
|
|
|
|
|
<div class="cpg-center-row {% if not c.active %}is-inactive{% endif %}" data-name="{{ c.name|lower }}">
|
|
|
|
|
<span class="cpg-center-dot" title="{% if c.active %}활성{% else %}비활성{% endif %}"></span>
|
|
|
|
|
<span class="cpg-center-name">{{ c.name }}</span>
|
|
|
|
|
<span class="cpg-center-acts">
|
|
|
|
|
<form method="post" action="/cupang/centers/{{ c.id }}/edit" class="cpg-inline-form">
|
|
|
|
|
<input type="hidden" name="active" value="{% if c.active %}0{% else %}1{% endif %}" />
|
|
|
|
|
<button type="submit" class="cpg-icon-btn"
|
|
|
|
|
title="{% if c.active %}비활성으로 전환{% else %}활성으로 전환{% endif %}">{% if c.active %}비활성{% else %}활성{% endif %}</button>
|
|
|
|
|
</form>
|
|
|
|
|
<button type="button" class="cpg-icon-btn is-danger" title="삭제"
|
|
|
|
|
data-del-url="/cupang/centers/{{ c.id }}/delete" data-del-name="{{ c.name }}">삭제</button>
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
{% endfor %}
|
|
|
|
|
</div>
|
|
|
|
|
{% for c in g["items"] %}
|
|
|
|
|
<div class="cpg-center-row {% if not c.active %}is-inactive{% endif %}" data-name="{{ c.name|lower }}">
|
|
|
|
|
<span class="cpg-center-dot" title="{% if c.active %}활성{% else %}비활성{% endif %}"></span>
|
|
|
|
|
<span class="cpg-center-name">{{ c.name }}</span>
|
|
|
|
|
<span class="cpg-center-acts">
|
|
|
|
|
<form method="post" action="/cupang/centers/{{ c.id }}/edit" class="cpg-inline-form">
|
|
|
|
|
<input type="hidden" name="active" value="{% if c.active %}0{% else %}1{% endif %}" />
|
|
|
|
|
<button type="submit" class="cpg-icon-btn"
|
|
|
|
|
title="{% if c.active %}비활성으로 전환{% else %}활성으로 전환{% endif %}">{% if c.active %}비활성{% else %}활성{% endif %}</button>
|
|
|
|
|
</form>
|
|
|
|
|
<form method="post" action="/cupang/centers/{{ c.id }}/delete" class="cpg-inline-form"
|
|
|
|
|
onsubmit="return confirm('{{ c.name }} 센터를 삭제할까요?');">
|
|
|
|
|
<button type="submit" class="cpg-icon-btn is-danger" title="삭제">삭제</button>
|
|
|
|
|
</form>
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
{% endfor %}
|
|
|
|
|
</div>
|
|
|
|
|
</section>
|
|
|
|
|
{% endfor %}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
@@ -61,20 +62,103 @@
|
|
|
|
|
</div>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<!-- 화면 가운데 알림/확인 팝업 -->
|
|
|
|
|
<div class="cpg-modal" id="cpgCenterDlg" hidden>
|
|
|
|
|
<div class="cpg-modal-back" data-dlg-close></div>
|
|
|
|
|
<div class="cpg-modal-box cpg-center-dlg" role="dialog" aria-modal="true" aria-labelledby="cpgCenterDlgTitle">
|
|
|
|
|
<h3 id="cpgCenterDlgTitle">알림</h3>
|
|
|
|
|
<p class="cpg-center-dlgmsg" id="cpgCenterDlgMsg"></p>
|
|
|
|
|
<div class="cpg-dlg-actions cpg-center-dlgact">
|
|
|
|
|
<button type="button" class="erp-btn erp-btn-outline" id="cpgCenterDlgCancel" data-dlg-close hidden>취소</button>
|
|
|
|
|
<button type="button" class="erp-btn erp-btn-primary" id="cpgCenterDlgOk">확인</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<form method="post" id="cpgCenterDelForm" hidden></form>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
(function () {
|
|
|
|
|
// 추가 결과 알림 (중복 등록 방지)
|
|
|
|
|
// ── 가운데 팝업 (alert/confirm 대체) ──
|
|
|
|
|
var dlg = document.getElementById('cpgCenterDlg');
|
|
|
|
|
var dlgTitle = document.getElementById('cpgCenterDlgTitle');
|
|
|
|
|
var dlgMsg = document.getElementById('cpgCenterDlgMsg');
|
|
|
|
|
var dlgOk = document.getElementById('cpgCenterDlgOk');
|
|
|
|
|
var dlgCancel = document.getElementById('cpgCenterDlgCancel');
|
|
|
|
|
var onConfirm = null;
|
|
|
|
|
var lastFocus = null;
|
|
|
|
|
|
|
|
|
|
function closeDlg() {
|
|
|
|
|
dlg.hidden = true;
|
|
|
|
|
onConfirm = null;
|
|
|
|
|
if (lastFocus && lastFocus.focus) lastFocus.focus();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function openDlg(opts) {
|
|
|
|
|
lastFocus = document.activeElement;
|
|
|
|
|
dlgTitle.textContent = opts.title || '알림';
|
|
|
|
|
dlgMsg.textContent = opts.message || '';
|
|
|
|
|
onConfirm = opts.onConfirm || null;
|
|
|
|
|
dlgCancel.hidden = !opts.onConfirm;
|
|
|
|
|
dlgOk.textContent = opts.okText || '확인';
|
|
|
|
|
dlgOk.classList.toggle('erp-btn-danger', !!opts.danger);
|
|
|
|
|
dlgOk.classList.toggle('erp-btn-primary', !opts.danger);
|
|
|
|
|
dlg.hidden = false;
|
|
|
|
|
dlgOk.focus();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dlgOk.addEventListener('click', function () {
|
|
|
|
|
var fn = onConfirm;
|
|
|
|
|
closeDlg();
|
|
|
|
|
if (fn) fn();
|
|
|
|
|
});
|
|
|
|
|
Array.prototype.forEach.call(dlg.querySelectorAll('[data-dlg-close]'), function (el) {
|
|
|
|
|
el.addEventListener('click', closeDlg);
|
|
|
|
|
});
|
|
|
|
|
document.addEventListener('keydown', function (e) {
|
|
|
|
|
if (e.key === 'Escape' && !dlg.hidden) closeDlg();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// ── 추가 결과 알림 (중복 등록 차단) ──
|
|
|
|
|
var flash = {{ flash|tojson }};
|
|
|
|
|
var fname = {{ flash_name|tojson }};
|
|
|
|
|
if (flash === 'dup') {
|
|
|
|
|
alert('"' + fname + '" 센터는 이미 등록되어 있습니다.');
|
|
|
|
|
openDlg({ title: '이미 등록된 센터', message: '"' + fname + '" 센터는 이미 목록에 있습니다.' });
|
|
|
|
|
} else if (flash === 'dup_inactive') {
|
|
|
|
|
alert('"' + fname + '" 센터는 이미 등록되어 있습니다. (현재 비활성 상태 — 목록에서 활성으로 전환하세요.)');
|
|
|
|
|
}
|
|
|
|
|
if (flash) {
|
|
|
|
|
history.replaceState(null, '', '/cupang/centers');
|
|
|
|
|
openDlg({
|
|
|
|
|
title: '이미 등록된 센터',
|
|
|
|
|
message: '"' + fname + '" 센터는 이미 목록에 있습니다. 지금은 비활성 상태이니 목록에서 [활성] 을 눌러 사용하세요.'
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
if (flash) history.replaceState(null, '', '/cupang/centers');
|
|
|
|
|
|
|
|
|
|
// ── 삭제 확인 ──
|
|
|
|
|
var delForm = document.getElementById('cpgCenterDelForm');
|
|
|
|
|
document.addEventListener('click', function (e) {
|
|
|
|
|
var btn = e.target.closest('[data-del-url]');
|
|
|
|
|
if (!btn) return;
|
|
|
|
|
openDlg({
|
|
|
|
|
title: '센터 삭제',
|
|
|
|
|
message: '"' + btn.dataset.delName + '" 센터를 삭제할까요?',
|
|
|
|
|
okText: '삭제',
|
|
|
|
|
danger: true,
|
|
|
|
|
onConfirm: function () {
|
|
|
|
|
delForm.action = btn.dataset.delUrl;
|
|
|
|
|
delForm.submit();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// ── 그룹 접기 ──
|
|
|
|
|
document.addEventListener('click', function (e) {
|
|
|
|
|
var head = e.target.closest('.cpg-center-gtitle');
|
|
|
|
|
if (!head) return;
|
|
|
|
|
var group = head.closest('.cpg-center-group');
|
|
|
|
|
var collapsed = group.classList.toggle('is-collapsed');
|
|
|
|
|
head.setAttribute('aria-expanded', collapsed ? 'false' : 'true');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// ── 검색 ──
|
|
|
|
|
var box = document.getElementById('cpgCenterSearch');
|
|
|
|
|
var grid = document.getElementById('cpgCenterGrid');
|
|
|
|
|
var count = document.getElementById('cpgCenterCount');
|
|
|
|
@@ -92,6 +176,7 @@
|
|
|
|
|
if (hit) shown += 1;
|
|
|
|
|
});
|
|
|
|
|
g.style.display = shown ? '' : 'none';
|
|
|
|
|
if (q && shown) g.classList.remove('is-collapsed');
|
|
|
|
|
n += shown;
|
|
|
|
|
});
|
|
|
|
|
if (count) count.textContent = '(' + n + ')';
|
|
|
|
|