[UI] v0.4.2.11 - CCTV Monitoring UI Revamp for design consistency

This commit is contained in:
choibk 2026-01-26 11:49:29 +09:00
parent 991ef773be
commit 93de44bc22
6 changed files with 41 additions and 11 deletions

View File

@ -0,0 +1,23 @@
# ==============================================
# [Common Settings]
# ==============================================
DB_HOST=sokuree.com
DB_USER=choibk
DB_PASSWORD=^Ocean1472bk
PORT=3005
# ==============================================
# [Development Environment] - Local Windows
# ==============================================
# 로컬 개발용 DB (분리됨: sokuree_platform_dev)
DB_NAME=sokuree_platform_dev
DB_PORT=3307
# Windows 환경 호환성 (tcp는 권한 오류 발생 가능)
CCTV_TRANSPORT_OVERRIDE=auto
# ==============================================
# [Production Environment] - Synology NAS
# ==============================================
# DB_NAME=sokuree_platform_prod
# DB_PORT=3307

View File

@ -3,7 +3,7 @@
**프로젝트명:** SOKUREE Platform - Smart Integrated Management System
**최초 작성일:** 2026-01-25
**최근 업데이트:** 2026-01-26
**버전:** v0.4.2.9
**버전:** v0.4.2.11
---
@ -46,6 +46,13 @@
- **업데이트 안정성**: 소스 교체 전 `.env`/`.env.local` 2중 백업 및 복구 시퀀스 적용
- **서버 가용성**: Synology NAS 등 저사양 환경에서의 블로킹 방지를 위한 `execSync` 차단 및 에러 핸들링 강화
#### 🏷️ Tag: `v0.4.2.11` (완료)
- [x] **CCTV 모니터링 UI 리뉴얼**
- 페이지 배경색을 플랫폼 표준인 연한 그레이(`var(--sokuree-bg-main)`)로 변경하여 일체감 형성
- 카메라 슬롯을 독립적인 카드(Card) 형태로 디자인하고 둥근 모서리(`rounded-xl`) 및 그림자(`shadow-sm`) 적용
- 고정된 검은색 배경 대신 브랜드 컬러인 다크 슬레이트(`var(--sokuree-brand-secondary)`) 배경 적용
- 빈 슬롯 디자인을 깔끔한 화이트 카드 형태로 개선하여 시각적 피로도 감소
#### 🏷️ Tag: `v0.4.3.0`
- [ ] **소모품 관리**

View File

@ -1,7 +1,7 @@
{
"name": "smartims",
"private": true,
"version": "0.4.2.10",
"version": "0.4.2.11",
"type": "module",
"scripts": {
"dev": "vite",

View File

@ -1,6 +1,6 @@
{
"name": "server",
"version": "0.4.2.10",
"version": "0.4.2.11",
"description": "",
"main": "index.js",
"scripts": {

View File

@ -64,7 +64,7 @@ export function JSMpegPlayer({ url, width, height, className }: JSMpegPlayerProp
}, [url, retryCount]); // Re-run when url or retryCount changes
return (
<div className={`video-container bg-black flex items-center justify-center overflow-hidden ${className || ''}`} style={{ width, height }}>
<div className={`video-container bg-transparent flex items-center justify-center overflow-hidden ${className || ''}`} style={{ width, height }}>
<canvas key={`${url}-${retryCount}`} ref={canvasRef} className="w-full h-full object-contain" />
</div>
);

View File

@ -40,7 +40,7 @@ function SortableCamera({ camera, children, disabled }: { camera: Camera, childr
};
return (
<div ref={setNodeRef} style={style} {...attributes} {...listeners} className={`relative bg-black overflow-hidden border ${disabled ? 'border-slate-800' : 'border-slate-700 hover:border-indigo-500'} transition-colors group h-full w-full`}>
<div ref={setNodeRef} style={style} {...attributes} {...listeners} className={`relative bg-[#0f172a] rounded-xl overflow-hidden border shadow-sm ${disabled ? 'border-slate-200' : 'border-slate-200 hover:border-indigo-500'} transition-all group h-full w-full`}>
{children}
</div>
);
@ -309,7 +309,7 @@ export function MonitoringPage() {
const slots = Array.from({ length: totalSlots }).map((_, i) => filteredCameras[i] || null);
return (
<div className="w-full h-full bg-[#0a0a0a] flex flex-col min-h-0">
<div className="w-full h-full bg-[#f1f5f9] flex flex-col min-h-0">
<HeaderDropdown />
<div className="flex-1 p-2 overflow-hidden flex flex-col min-h-0">
@ -323,7 +323,7 @@ export function MonitoringPage() {
strategy={rectSortingStrategy}
disabled={true}
>
<div className={`grid h-full w-full gap-1 ${layoutInfo.cols} ${totalSlots > layoutInfo.total ? 'overflow-y-auto' : ''}`}
<div className={`grid h-full w-full gap-4 ${layoutInfo.cols} ${totalSlots > layoutInfo.total ? 'overflow-y-auto' : ''}`}
style={{ gridAutoRows: (viewLayout === '1' || viewLayout === '1*2') ? '100%' : `${100 / Math.sqrt(layoutInfo.total)}%` }}>
{slots.map((camera, index) => (
<div key={camera ? camera.id : `empty-${index}`} className="h-full w-full">
@ -362,7 +362,7 @@ export function MonitoringPage() {
</div>
{/* Streaming Video */}
<div className="flex-1 bg-black flex items-center justify-center">
<div className="flex-1 bg-[#0f172a] flex items-center justify-center">
<JSMpegPlayer
key={`${camera.id}-${streamVersions[camera.id] || 0}`}
url={getStreamUrl(camera.id)}
@ -377,9 +377,9 @@ export function MonitoringPage() {
</div>
</SortableCamera>
) : (
<div className="h-full w-full bg-[#121212] border border-slate-900/50 flex flex-col items-center justify-center text-slate-700 select-none">
<Video size={32} className="opacity-10 mb-2" />
<span className="text-[11px] font-bold opacity-20 uppercase tracking-widest">No Buffer</span>
<div className="h-full w-full bg-white rounded-xl border border-slate-200 flex flex-col items-center justify-center text-slate-300 select-none shadow-sm">
<Video size={32} className="opacity-20 mb-2" />
<span className="text-[11px] font-bold opacity-40 uppercase tracking-widest">No Buffer</span>
</div>
)}
</div>