From e86f643c26a7822c02d720315a03f822ade252fd Mon Sep 17 00:00:00 2001 From: kurihada Date: Thu, 26 Feb 2026 15:18:22 +0800 Subject: [PATCH] =?UTF-8?q?ui:=20=E4=B8=AA=E4=BA=BA=E4=B8=AD=E5=BF=83?= =?UTF-8?q?=E7=A9=BA=E7=8A=B6=E6=80=81=E6=8F=92=E5=9B=BE=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=8C=E6=9B=BF=E6=8D=A2=E7=BA=AF=E6=96=87=E5=AD=97=E4=B8=BA?= =?UTF-8?q?=E5=9B=BE=E6=A0=87=E5=8A=A8=E7=94=BB=20+=20CTA=20=E6=8C=89?= =?UTF-8?q?=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 提取可复用 EmptyState 组件,决策记录和收藏餐厅空状态 增加浮动图标、光晕动画和"去创建第一个房间"引导按钮 --- src/app/profile/page.tsx | 25 +++++++++++---- src/components/EmptyState.tsx | 58 +++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 6 deletions(-) create mode 100644 src/components/EmptyState.tsx diff --git a/src/app/profile/page.tsx b/src/app/profile/page.tsx index f6296c8..fbb50ac 100644 --- a/src/app/profile/page.tsx +++ b/src/app/profile/page.tsx @@ -20,7 +20,10 @@ import { Eye, EyeOff, Zap, + ClipboardList, + Heart, } from "lucide-react"; +import EmptyState from "@/components/EmptyState"; import { getUserId, getCachedProfile, setCachedProfile, setCachedPreferences, logout } from "@/lib/userId"; import { getAvatarBg, AVATARS } from "@/lib/avatars"; import type { UserProfile, UserPreferences, DecisionRecord, FavoriteRecord, Restaurant } from "@/types"; @@ -534,9 +537,14 @@ export default function ProfilePage() { ) : history.length === 0 ? ( -

- 还没有决策记录 -

+ router.push("/blindbox")} + color="purple" + /> ) : (
{history.map((d) => ( @@ -612,9 +620,14 @@ export default function ProfilePage() {
) : favorites.length === 0 ? ( -

- 还没有收藏的餐厅 -

+ router.push("/blindbox")} + color="amber" + /> ) : (
{favorites.map((f) => { diff --git a/src/components/EmptyState.tsx b/src/components/EmptyState.tsx new file mode 100644 index 0000000..8593294 --- /dev/null +++ b/src/components/EmptyState.tsx @@ -0,0 +1,58 @@ +"use client"; + +import { motion } from "framer-motion"; +import type { LucideIcon } from "lucide-react"; + +interface EmptyStateProps { + icon: LucideIcon; + title: string; + subtitle?: string; + ctaLabel?: string; + onCta?: () => void; + color?: string; +} + +export default function EmptyState({ + icon: Icon, + title, + subtitle, + ctaLabel, + onCta, + color = "purple", +}: EmptyStateProps) { + const colorMap: Record = { + purple: { glow: "bg-purple-600/15", icon: "text-purple-400/60", btn: "bg-purple-600 hover:bg-purple-500", btnHover: "" }, + amber: { glow: "bg-amber-500/15", icon: "text-amber-400/60", btn: "bg-amber-600 hover:bg-amber-500", btnHover: "" }, + rose: { glow: "bg-rose-500/15", icon: "text-rose-400/60", btn: "bg-rose-600 hover:bg-rose-500", btnHover: "" }, + sky: { glow: "bg-sky-500/15", icon: "text-sky-400/60", btn: "bg-sky-600 hover:bg-sky-500", btnHover: "" }, + }; + const c = colorMap[color] ?? colorMap.purple; + + return ( +
+ +
+ + + +

{title}

+ {subtitle && ( +

{subtitle}

+ )} + + {ctaLabel && onCta && ( + + {ctaLabel} + + )} +
+ ); +}