feat: V2-7 Admin 콘솔 리디자인 + 3단계 권한 + SaaS 전환 + 코드 정리

- Admin CRM: D3RO Console 스타일 전체 적용 (panelSx/tableSx/filterBtnSx)
- 3단계 권한: manager/admin/super_admin (DB + Edge Functions + Frontend)
- 랜딩 페이지: 1회 결제 → 월간/연간 구독 SaaS 모델 (10개 언어)
- SSE 스트리밍: VoiceConversation Premium LLM 라우팅 + fallback
- Supabase 클라이언트: packages/api-client 공통 추출 (browser+server)
- RPC 함수 타입: 9개 정의 (admin_usage_by_feature 등)
- callAdminApi 401 버그 수정 (getUser() 선행 토큰 갱신)
This commit is contained in:
윤찬 2026-04-13 01:28:10 +09:00
parent d0e854c255
commit 8af75a0a1e
50 changed files with 2185 additions and 950 deletions

View file

@ -0,0 +1,84 @@
/* D3RO Console — Global Styles */
:root {
--sys-base: #000000;
--sys-panel: #09090b;
--sys-panel-hover: #121214;
--sys-border: #1f1f22;
--sys-border-hl: #27272a;
--text-dim: #71717a;
--text-base: #a1a1aa;
--text-bright: #ffffff;
--accent: #ff5c28;
}
body {
background-color: var(--sys-base);
color: var(--text-bright);
font-family: 'JetBrains Mono', ui-monospace, monospace;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* Scanline */
.console-scanline {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 4px;
background: linear-gradient(to bottom, transparent, rgba(255, 92, 40, 0.2), transparent);
opacity: 0.5;
animation: scan 8s linear infinite;
pointer-events: none;
z-index: 9999;
}
@keyframes scan {
0% { transform: translateY(-100%); }
100% { transform: translateY(100vh); }
}
/* Grid pattern overlay */
.bg-grid {
background-image:
linear-gradient(to right, rgba(255, 255, 255, 0.02) 1px, transparent 1px),
linear-gradient(to bottom, rgba(255, 255, 255, 0.02) 1px, transparent 1px);
background-size: 24px 24px;
}
/* Glow effects */
.glow-white { text-shadow: 0 0 15px rgba(255, 255, 255, 0.5), 0 0 30px rgba(255, 255, 255, 0.2); }
.glow-green { text-shadow: 0 0 15px rgba(34, 197, 94, 0.6), 0 0 30px rgba(34, 197, 94, 0.3); }
.glow-orange { text-shadow: 0 0 15px rgba(249, 115, 22, 0.6), 0 0 30px rgba(249, 115, 22, 0.3); }
.glow-red { text-shadow: 0 0 15px rgba(239, 68, 68, 0.6), 0 0 30px rgba(239, 68, 68, 0.3); }
.glow-accent { text-shadow: 0 0 15px rgba(255, 92, 40, 0.6), 0 0 30px rgba(255, 92, 40, 0.3); }
/* Scrollbar */
::-webkit-scrollbar { width: 4px; height: 4px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--sys-border-hl); border-radius: 2px; }
::-webkit-scrollbar-thumb:hover { background: var(--text-dim); }
/* Pulse animation for status dot */
@keyframes pulse-ring {
0% { transform: scale(0.8); opacity: 1; }
100% { transform: scale(2); opacity: 0; }
}
.status-dot-pulse {
position: relative;
}
.status-dot-pulse::before {
content: '';
position: absolute;
inset: 0;
border-radius: 50%;
background: #22c55e;
animation: pulse-ring 1.5s ease-out infinite;
}
/* Selection */
::selection {
background: var(--accent);
color: white;
}