feat: 주문리스트를 /orderlist/ 리버스 프록시 경로로 통합
- 메뉴 카드 새 탭 열기 + /orderlist/health/db 헬스 배지 (온라인/오프라인) 추가 - CUSTOMER_ORDER_LIST_URL 기본값을 /orderlist/ 로 (NPM 같은 도메인 하위 경로) - orderlist 측 compose 정리 스크립트 추가 (ports 제거, npm_default 외부 네트워크 attach)
This commit is contained in:
+3
-1
@@ -113,11 +113,13 @@ async def home(request: Request) -> HTMLResponse:
|
||||
"title": "CS 발주 업무",
|
||||
"description": "CS 발주 업무 페이지로 이동",
|
||||
"url": env("CS_ORDER_URL", "#"),
|
||||
"health_url": "",
|
||||
},
|
||||
{
|
||||
"title": "고객 주문리스트 프로그램",
|
||||
"description": "고객 주문리스트 프로그램으로 이동",
|
||||
"url": env("CUSTOMER_ORDER_LIST_URL", "#"),
|
||||
"url": env("CUSTOMER_ORDER_LIST_URL", "/orderlist/"),
|
||||
"health_url": "/orderlist/health/db",
|
||||
},
|
||||
]
|
||||
return render_template(
|
||||
|
||||
@@ -789,3 +789,37 @@ a { color: inherit; text-decoration: none; }
|
||||
.header-portal { display: none; }
|
||||
.btn-logout span { display: none; }
|
||||
}
|
||||
|
||||
/* ── 상태 배지 ─────────────────────────────────── */
|
||||
.status-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
margin-left: 8px;
|
||||
padding: 2px 8px;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
border-radius: 999px;
|
||||
vertical-align: middle;
|
||||
line-height: 1.4;
|
||||
background: #eef2f7;
|
||||
color: var(--muted);
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
.status-badge::before {
|
||||
content: "";
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: currentColor;
|
||||
}
|
||||
.status-badge[data-status="online"] {
|
||||
background: #e7f6ee;
|
||||
color: var(--success);
|
||||
border-color: #b6e0c6;
|
||||
}
|
||||
.status-badge[data-status="offline"] {
|
||||
background: #fdecec;
|
||||
color: var(--danger);
|
||||
border-color: #f1c2c2;
|
||||
}
|
||||
|
||||
+29
-2
@@ -55,7 +55,8 @@
|
||||
|
||||
<div class="card-grid">
|
||||
{% for item in menu_items %}
|
||||
<a class="menu-card" href="{{ item.url }}">
|
||||
<a class="menu-card" href="{{ item.url }}" target="_blank" rel="noopener noreferrer"
|
||||
{% if item.health_url %}data-health-url="{{ item.health_url }}"{% endif %}>
|
||||
<div class="card-icon">
|
||||
{% if loop.index == 1 %}
|
||||
<!-- 클립보드 / 발주 아이콘 -->
|
||||
@@ -98,7 +99,12 @@
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<p class="card-title">{{ item.title }}</p>
|
||||
<p class="card-title">
|
||||
{{ item.title }}
|
||||
{% if item.health_url %}
|
||||
<span class="status-badge" data-status="checking" aria-live="polite">확인 중</span>
|
||||
{% endif %}
|
||||
</p>
|
||||
<p class="card-desc">{{ item.description }}</p>
|
||||
</div>
|
||||
|
||||
@@ -123,6 +129,27 @@
|
||||
const days = ["일요일","월요일","화요일","수요일","목요일","금요일","토요일"];
|
||||
document.getElementById("today-date").textContent =
|
||||
d.getFullYear() + "년 " + (d.getMonth()+1) + "월 " + d.getDate() + "일 " + days[d.getDay()];
|
||||
|
||||
// 헬스 배지 — data-health-url 이 있는 카드만 갱신
|
||||
async function refreshHealthBadges() {
|
||||
const cards = document.querySelectorAll(".menu-card[data-health-url]");
|
||||
await Promise.all(Array.from(cards).map(async (card) => {
|
||||
const url = card.getAttribute("data-health-url");
|
||||
const badge = card.querySelector(".status-badge");
|
||||
if (!badge) return;
|
||||
try {
|
||||
const res = await fetch(url, { cache: "no-store", credentials: "omit" });
|
||||
const ok = res.ok;
|
||||
badge.dataset.status = ok ? "online" : "offline";
|
||||
badge.textContent = ok ? "온라인" : "오프라인";
|
||||
} catch {
|
||||
badge.dataset.status = "offline";
|
||||
badge.textContent = "오프라인";
|
||||
}
|
||||
}));
|
||||
}
|
||||
refreshHealthBadges();
|
||||
setInterval(refreshHealthBadges, 30000);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user