Files
dbx-main/app/modules/cupang/templates/cupang/index.html
T
king ba2478d461 style(cupang): 달 이동 화살표를 짧고 굵은 SVG 로 교체
글꼴 글리프는 두께 조절이 안 돼 stroke-width 5.5 SVG 로 대체

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-02 14:34:33 +09:00

232 lines
9.5 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% extends "erp_base.html" %}
{% block head_extra %}<link rel="stylesheet" href="/static/cupang.css?v=20260903k" />{% endblock %}
{% block content %}
<section class="cpg">
<!-- 페이지 액션 (달력 컬럼 폭에 맞춤: 신규 좌측 / 설정 달력 오른쪽 끝) -->
<div class="cpg-actions-grid">
<div class="cpg-actions-main">
<a class="erp-btn erp-btn-primary" href="/cupang/box-calc">+ 신규 등록</a>
<span class="cpg-settings-btns">
<a class="erp-btn erp-btn-outline" href="/cupang/products">제품명 설정</a>
<a class="erp-btn erp-btn-outline" href="/cupang/box-rules">상자 입수량 설정</a>
</span>
</div>
<div class="cpg-actions-spacer"></div>
</div>
<div class="cpg-layout">
<!-- ── 왼쪽: 2개월 월간 달력 ── -->
<div class="erp-card cpg-cal-card">
<div class="cpg-mcal-bar">
<a class="cpg-mcal-navbtn" title="이전 달" aria-label="이전 달"
href="/cupang/?year={{ prev_y }}&month={{ prev_m }}">
<svg class="cpg-mcal-arrow" viewBox="0 0 28 24" aria-hidden="true">
<path d="M23 12 H8" /><path d="M14 5 L7 12 L14 19" />
</svg>
</a>
<h2 class="cpg-mcal-range">{{ months[0].label }} {{ months[1].label }}</h2>
<a class="cpg-mcal-navbtn" title="다음 달" aria-label="다음 달"
href="/cupang/?year={{ next_y }}&month={{ next_m }}">
<svg class="cpg-mcal-arrow" viewBox="0 0 28 24" aria-hidden="true">
<path d="M5 12 H20" /><path d="M14 5 L21 12 L14 19" />
</svg>
</a>
</div>
<div class="cpg-mcal-months">
<a class="cpg-mcal-todaybtn" href="/cupang/">오늘</a>
{% for m in months %}
<section class="cpg-mcal{% if loop.first %} is-current{% endif %}">
<header class="cpg-mcal-h">
<span class="cpg-mcal-mname">{{ m.month }}월</span>
<span class="cpg-mcal-myear">{{ m.year }}</span>
{% if m.ship_total %}
<span class="cpg-mcal-total">출고 {{ m.ship_total }}건</span>
{% endif %}
</header>
<div class="cpg-mcal-grid">
{% for wd in weekdays %}
<div class="cpg-mcal-wd {% if loop.index0 == 0 %}is-sun{% elif loop.index0 == 6 %}is-sat{% endif %}">{{ wd }}</div>
{% endfor %}
{% for week in m.weeks %}
{% for cell in week %}
<a class="cpg-mcal-cell
{% if not cell.in_month %}is-out{% endif %}
{% if cell.is_today %}is-today{% endif %}
{% if cell.is_selected %}is-selected{% endif %}
{% if cell.counts.ship %}has-ship{% endif %}
{% if cell.is_sunday or cell.is_holiday %}is-red{% elif cell.is_saturday %}is-blue{% endif %}"
href="/cupang/?year={{ year }}&month={{ month }}&date={{ cell.date }}"
title="{{ cell.date }}{% if cell.holiday_name %} — {{ cell.holiday_name }}{% endif %}{% if cell.counts.ship %} — 출고 {{ cell.counts.ship }}건 / 센터 {{ cell.counts.centers }}곳{% endif %}">
<span class="cpg-mcal-day">{{ cell.day }}</span>
{% if cell.holiday_name %}
<span class="cpg-mcal-holi">{{ cell.holiday_name }}</span>
{% endif %}
{% if cell.counts.ship %}
<span class="cpg-mcal-tag">{{ cell.counts.ship }}건<em>{{ cell.counts.centers }}곳</em></span>
{% endif %}
</a>
{% endfor %}
{% endfor %}
</div>
</section>
{% endfor %}
</div>
<div class="cpg-mcal-legend">
<span><i class="cpg-lg-dot"></i>출고 있는 날</span>
<span><i class="cpg-lg-today"></i>오늘</span>
<span><i class="cpg-lg-sel"></i>선택한 날</span>
</div>
</div>
<!-- ── 오른쪽: 선택일 출고 묶음 리스트 ── -->
<div class="erp-card cpg-list-card">
<div class="cpg-list-head">
<h2>{{ selected_date }} 출고</h2>
<span class="erp-muted">{{ sel_shipments|length }}건</span>
{% if sel_shipments %}
<button type="button" class="erp-btn erp-btn-danger cpg-btn-sm cpg-day-del"
data-day-del="{{ selected_date }}" data-count="{{ sel_shipments|length }}">이 날짜 전체 삭제</button>
{% endif %}
</div>
{% if sel_shipments %}
<ul class="cpg-list">
{% for s in sel_shipments %}
{# ③ 센터 분배 카드와 같은 형식 — 혼합 상자는 내용물까지 펼쳐 보여준다 #}
<li class="cpg-list-item cpg-dist-center has-items">
<div class="cpg-dist-head">
<a class="cpg-ship-name" href="/cupang/{{ s.id }}">{{ s.center_name_snapshot or '센터 미지정' }}</a>
<span class="erp-badge erp-badge-neutral">{{ s.ship_method }}</span>
<span class="cpg-dist-sum">
<span class="erp-badge erp-badge-neutral">{{ s.total_boxes }}상자</span>
<span class="erp-badge erp-badge-neutral">{{ s.total_qty }}개</span>
<button type="button" class="cpg-icon-btn is-danger" title="이 출고 삭제"
data-del="{{ s.id }}" data-name="{{ s.center_name_snapshot }}">삭제</button>
</span>
</div>
<ul class="cpg-dist-items">
{% if s.box_plan %}
{% for e in s.box_plan %}
<li class="cpg-dist-item{% if e.kind == 'mix' %} is-mix{% endif %}">
<div class="cpg-dist-line">
<span class="cpg-dist-name">{{ e.name }}</span>
<span class="cpg-dist-unit">{{ e.count }}상자 · {{ e.quantity }}개</span>
</div>
{% if e.kind == 'mix' and e['items'] %}
<ul class="cpg-dist-tree">
{% for it in e['items'] %}
<li><span class="cpg-tree-name">{{ it.product_name }}</span>
<span class="cpg-tree-qty">{{ it.quantity }}개</span></li>
{% endfor %}
</ul>
{% endif %}
</li>
{% endfor %}
{% else %}
{# 예전에 만든 출고(상자 구성 미저장) — 제품 합계만 표시 #}
{% for it in s['items'] %}
<li class="cpg-dist-item">
<div class="cpg-dist-line">
<span class="cpg-dist-name">{{ it.name }}</span>
<span class="cpg-dist-unit">{{ it.boxes }}상자 · {{ it.qty }}개</span>
</div>
</li>
{% endfor %}
{% endif %}
</ul>
<div class="cpg-ship-meta erp-muted">출고 {{ s.ship_date }} · 센터입고 {{ s.center_arrival_date }}</div>
</li>
{% endfor %}
</ul>
{% else %}
<p class="erp-muted cpg-empty">선택한 날짜의 출고 묶음이 없습니다.
<a href="/cupang/box-calc">상자 계산에서 등록</a></p>
{% endif %}
</div>
</div>
<!-- 삭제 확인 팝업 -->
<div class="cpg-modal" id="cpg-del-dlg" hidden>
<div class="cpg-modal-back" data-del-close></div>
<div class="cpg-modal-box cpg-del-box" role="dialog" aria-modal="true" aria-labelledby="cpg-del-title">
<h3 id="cpg-del-title">출고 삭제</h3>
<p class="cpg-del-msg" id="cpg-del-msg"></p>
<div class="cpg-del-act">
<button type="button" class="erp-btn erp-btn-outline" data-del-close>취소</button>
<button type="button" class="erp-btn erp-btn-danger" id="cpg-del-ok">삭제</button>
</div>
</div>
</div>
<form method="post" id="cpg-del-form" hidden>
<input type="hidden" name="date" id="cpg-del-date" />
<input type="hidden" name="next" id="cpg-del-next" />
</form>
</section>
{% endblock %}
{% block scripts %}
<script>
(function () {
var dlg = document.getElementById("cpg-del-dlg");
if (!dlg) return;
var msgEl = document.getElementById("cpg-del-msg");
var okBtn = document.getElementById("cpg-del-ok");
var form = document.getElementById("cpg-del-form");
var dateEl = document.getElementById("cpg-del-date");
var nextEl = document.getElementById("cpg-del-next");
var pending = null; // {action, date}
function close() { dlg.hidden = true; pending = null; }
function open(message, action, day) {
msgEl.textContent = message;
pending = { action: action, date: day || "" };
dlg.hidden = false;
okBtn.focus();
}
Array.prototype.forEach.call(dlg.querySelectorAll("[data-del-close]"), function (el) {
el.addEventListener("click", close);
});
document.addEventListener("keydown", function (e) {
if (e.key === "Escape" && !dlg.hidden) close();
});
okBtn.addEventListener("click", function () {
if (!pending) return;
form.action = pending.action;
dateEl.value = pending.date;
nextEl.value = window.location.pathname + window.location.search;
form.submit();
});
document.addEventListener("click", function (e) {
var one = e.target.closest("[data-del]");
if (one) {
open('"' + (one.dataset.name || "이 센터") + '" 출고를 삭제할까요?',
"/cupang/" + one.dataset.del + "/delete", "");
return;
}
var day = e.target.closest("[data-day-del]");
if (day) {
open(day.dataset.dayDel + " 출고 " + day.dataset.count + "건을 모두 삭제할까요?",
"/cupang/day-delete", day.dataset.dayDel);
}
});
})();
</script>
{% endblock %}