407da15e6d
- 타이포 스케일: body 12→14px, caption 9.6→12px, display 25.6→32px, 위계 강화 - 헤더 우측 3그룹화 (대시보드액션 | 테마/알림/설정 | 모드+프로필), v5-hdr-sep 구분자 추가 - 사이드바 SUPER_ADMIN 회사 카드 borderless slim 라벨로 압축 - 메뉴명 빈 텍스트 방어 + title 속성 추가 - 빈 대시보드(EmptyDashboard) 리디자인: 탭없음/위젯없음 2상태 분리, 2-CTA 카드 - 로그인 코스믹 공연 축소: 별 150→30, 파티클 20→0, 카피 한글화 (로그인 버튼/서브타이틀) - 모드 전환 burst/sweep/badge-zoom 제거, sidebar stagger morph만 유지 (handleModeSwitch 100→25줄) - View transitions duration 1800ms → 500ms Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
81 lines
3.7 KiB
TypeScript
81 lines
3.7 KiB
TypeScript
"use client";
|
|
|
|
import { LayoutGrid, Plus, Sparkles } from "lucide-react";
|
|
import { useDashboardStore } from "@/stores/dashboardStore";
|
|
|
|
export function EmptyDashboard() {
|
|
const activeDashboardId = useDashboardStore((s) => s.activeDashboardId);
|
|
const openLib = useDashboardStore((s) => s.openLib);
|
|
|
|
const hasDashboard = !!activeDashboardId;
|
|
|
|
// 탭이 없는 상태: 메뉴 선택 유도
|
|
if (!hasDashboard) {
|
|
return (
|
|
<div className="flex h-full items-center justify-center px-6">
|
|
<div className="flex max-w-md flex-col items-center gap-4 text-center">
|
|
<div className="flex h-14 w-14 items-center justify-center rounded-2xl bg-[var(--v5-primary)]/8 text-[var(--v5-primary)]">
|
|
<LayoutGrid className="h-7 w-7" />
|
|
</div>
|
|
<div className="space-y-1.5">
|
|
<h2 className="text-[1.125rem] font-semibold text-foreground">열린 탭이 없습니다</h2>
|
|
<p className="text-sm text-muted-foreground">
|
|
왼쪽 사이드바에서 메뉴를 선택해 시작하세요.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// 대시보드는 있으나 위젯이 없는 상태: 3가지 CTA 제시
|
|
return (
|
|
<div className="flex h-full items-center justify-center bg-white px-6 dark:bg-transparent">
|
|
<div className="flex w-full max-w-xl flex-col items-center gap-6 text-center">
|
|
<div className="flex h-16 w-16 items-center justify-center rounded-full bg-gradient-to-br from-[var(--v5-primary)]/20 to-[var(--v5-cyan)]/15 text-[var(--v5-primary)] ring-1 ring-[var(--v5-primary)]/25">
|
|
<Sparkles className="h-8 w-8" />
|
|
</div>
|
|
<div className="space-y-2">
|
|
<h2 className="text-[1.25rem] font-semibold text-foreground">
|
|
새 대시보드가 준비됐습니다
|
|
</h2>
|
|
<p className="max-w-sm text-sm text-muted-foreground">
|
|
템플릿으로 빠르게 시작하거나, 위젯을 직접 배치해 대시보드를 구성하세요.
|
|
</p>
|
|
</div>
|
|
<div className="grid w-full grid-cols-1 gap-3 sm:grid-cols-2">
|
|
<button
|
|
type="button"
|
|
onClick={openLib}
|
|
className="group flex flex-col items-start gap-1.5 rounded-xl border border-[var(--v5-primary)]/25 bg-[var(--v5-primary)]/[0.04] px-4 py-3.5 text-left transition-all hover:border-[var(--v5-primary)]/60 hover:bg-[var(--v5-primary)]/[0.08] hover:-translate-y-0.5"
|
|
>
|
|
<div className="flex items-center gap-2 text-[var(--v5-primary)]">
|
|
<LayoutGrid className="h-4 w-4" />
|
|
<span className="text-sm font-semibold">템플릿에서 시작</span>
|
|
</div>
|
|
<p className="text-xs text-muted-foreground">
|
|
미리 만들어진 레이아웃과 위젯 조합으로 빠르게 구성
|
|
</p>
|
|
</button>
|
|
<button
|
|
type="button"
|
|
onClick={openLib}
|
|
className="group flex flex-col items-start gap-1.5 rounded-xl border border-border bg-card px-4 py-3.5 text-left transition-all hover:border-[var(--v5-primary)]/50 hover:-translate-y-0.5"
|
|
>
|
|
<div className="flex items-center gap-2 text-foreground">
|
|
<Plus className="h-4 w-4" />
|
|
<span className="text-sm font-semibold">위젯 직접 추가</span>
|
|
</div>
|
|
<p className="text-xs text-muted-foreground">
|
|
빈 캔버스에 원하는 위젯을 하나씩 배치
|
|
</p>
|
|
</button>
|
|
</div>
|
|
<p className="text-[0.7rem] text-muted-foreground/70">
|
|
팁: 상단의 '편집' 버튼으로 언제든 레이아웃을 바꿀 수 있어요.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|