refactor: streamline mobile interface for data analysis focus
Remove settings, optimize mobile layout, highlight data analysis features Use generic company names, simulate today's timeline, responsive design Co-authored-by: null <4804959+fnvtk@users.noreply.github.com>
This commit is contained in:
@@ -7,7 +7,6 @@ import { cn } from "@/lib/utils"
|
||||
import {
|
||||
Database,
|
||||
LayoutDashboard,
|
||||
Settings,
|
||||
Users,
|
||||
Target,
|
||||
X,
|
||||
@@ -28,7 +27,7 @@ interface MobileSidebarProps {
|
||||
export default function MobileSidebar({ isOpen, onClose }: MobileSidebarProps) {
|
||||
const pathname = usePathname()
|
||||
const [expandedSections, setExpandedSections] = useState({
|
||||
"user-portrait": true,
|
||||
"user-portrait": false,
|
||||
"user-value": false,
|
||||
})
|
||||
|
||||
@@ -53,55 +52,63 @@ export default function MobileSidebar({ isOpen, onClose }: MobileSidebarProps) {
|
||||
|
||||
const navItems = [
|
||||
{
|
||||
title: "概览",
|
||||
title: "数据概览",
|
||||
href: "/",
|
||||
icon: <LayoutDashboard className="h-5 w-5" />,
|
||||
icon: <LayoutDashboard className="h-4 w-4" />,
|
||||
primary: true,
|
||||
description: "平台整体数据分析",
|
||||
},
|
||||
{
|
||||
title: "数据集成",
|
||||
href: "/data-integration",
|
||||
icon: <Database className="h-5 w-5" />,
|
||||
icon: <Database className="h-4 w-4" />,
|
||||
primary: true,
|
||||
tag: "核心",
|
||||
description: "多源数据整合平台",
|
||||
},
|
||||
{
|
||||
title: "用户画像",
|
||||
href: "/user-portrait",
|
||||
icon: <Users className="h-5 w-5" />,
|
||||
icon: <Users className="h-4 w-4" />,
|
||||
primary: true,
|
||||
expandable: true,
|
||||
section: "user-portrait",
|
||||
description: "用户标签与分群分析",
|
||||
children: [
|
||||
{
|
||||
title: "用户词",
|
||||
href: "/user-portrait/user-keywords",
|
||||
icon: <Tag className="h-4 w-4" />,
|
||||
title: "流量关键词",
|
||||
href: "/user-portrait/keywords",
|
||||
icon: <Tag className="h-3 w-3" />,
|
||||
description: "关键词价值评估",
|
||||
},
|
||||
{
|
||||
title: "标签管理",
|
||||
href: "/user-portrait/tags",
|
||||
icon: <Tag className="h-4 w-4" />,
|
||||
icon: <Tag className="h-3 w-3" />,
|
||||
description: "用户标签分类",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "用户估值",
|
||||
title: "价值评估",
|
||||
href: "/user-value",
|
||||
icon: <Target className="h-5 w-5" />,
|
||||
icon: <Target className="h-4 w-4" />,
|
||||
primary: true,
|
||||
expandable: true,
|
||||
section: "user-value",
|
||||
description: "用户价值分析模型",
|
||||
children: [
|
||||
{
|
||||
title: "估值模型",
|
||||
href: "/user-value/model",
|
||||
icon: <BarChart3 className="h-4 w-4" />,
|
||||
icon: <BarChart3 className="h-3 w-3" />,
|
||||
description: "RFM价值模型",
|
||||
},
|
||||
{
|
||||
title: "用户升级路径",
|
||||
title: "升级路径",
|
||||
href: "/user-value/upgrade-paths",
|
||||
icon: <TrendingUp className="h-4 w-4" />,
|
||||
icon: <TrendingUp className="h-3 w-3" />,
|
||||
description: "用户价值提升",
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -110,9 +117,9 @@ export default function MobileSidebar({ isOpen, onClose }: MobileSidebarProps) {
|
||||
const getTagColor = (tag: string) => {
|
||||
switch (tag) {
|
||||
case "核心":
|
||||
return "glass-light text-orange-700 border-orange-200"
|
||||
return "bg-blue-100 text-blue-700 border-blue-200"
|
||||
default:
|
||||
return "glass-light text-gray-700 border-gray-200"
|
||||
return "bg-gray-100 text-gray-700 border-gray-200"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,56 +137,63 @@ export default function MobileSidebar({ isOpen, onClose }: MobileSidebarProps) {
|
||||
{/* 侧边栏 */}
|
||||
<div
|
||||
className={cn(
|
||||
"fixed left-0 top-0 h-full w-80 glass-nav safe-area-top safe-area-left z-50 transition-transform duration-300 ease-out",
|
||||
"fixed left-0 top-0 h-full w-72 glass-nav safe-area-top safe-area-left z-50 transition-transform duration-300 ease-out",
|
||||
isOpen ? "translate-x-0" : "-translate-x-full",
|
||||
)}
|
||||
>
|
||||
{/* 头部 */}
|
||||
<div className="flex items-center justify-between px-6 py-4 border-b border-white/20">
|
||||
<div className="flex items-center space-x-3">
|
||||
<div className="w-8 h-8 rounded-lg glass-light flex items-center justify-center">
|
||||
<Database className="h-5 w-5 text-blue-600" />
|
||||
<div className="flex items-center justify-between px-4 py-3 border-b border-white/20">
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="w-6 h-6 rounded-lg glass-light flex items-center justify-center">
|
||||
<Database className="h-4 w-4 text-blue-600" />
|
||||
</div>
|
||||
<h1 className="text-lg font-semibold bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent">
|
||||
用户数字资产中台
|
||||
<h1 className="text-sm font-semibold bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent">
|
||||
数据资产中台
|
||||
</h1>
|
||||
</div>
|
||||
<Button variant="ghost" size="icon" onClick={onClose} className="glass-light rounded-xl">
|
||||
<X className="h-5 w-5" />
|
||||
<Button variant="ghost" size="icon" onClick={onClose} className="glass-light rounded-lg h-8 w-8">
|
||||
<X className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{/* 导航菜单 */}
|
||||
<div className="flex-1 overflow-y-auto py-4">
|
||||
<nav className="space-y-2 px-4">
|
||||
<div className="flex-1 overflow-y-auto py-2">
|
||||
<nav className="space-y-1 px-3">
|
||||
{navItems.map((item) => (
|
||||
<div key={item.href}>
|
||||
<div
|
||||
className={cn(
|
||||
"flex items-center px-4 py-3 text-sm font-medium rounded-xl transition-all duration-300 group",
|
||||
"flex items-center px-3 py-2 text-xs font-medium rounded-lg transition-all duration-300 group",
|
||||
pathname === item.href
|
||||
? "glass-heavy text-blue-700 shadow-glass"
|
||||
: "glass-light text-gray-700 hover:glass-heavy hover:text-blue-600",
|
||||
)}
|
||||
>
|
||||
<Link href={item.href} onClick={onClose} className="flex items-center flex-1">
|
||||
<div className="transition-colors duration-300">{item.icon}</div>
|
||||
<div className="flex-1 flex items-center justify-between ml-3">
|
||||
<span className="font-medium">{item.title}</span>
|
||||
{item.tag && (
|
||||
<Badge className={cn("text-xs px-2 py-1 rounded-lg", getTagColor(item.tag))}>{item.tag}</Badge>
|
||||
)}
|
||||
<Link href={item.href} onClick={onClose} className="flex items-center flex-1 min-w-0">
|
||||
<div className="transition-colors duration-300 flex-shrink-0">{item.icon}</div>
|
||||
<div className="flex-1 ml-2 min-w-0">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="font-medium truncate">{item.title}</span>
|
||||
{item.tag && (
|
||||
<Badge
|
||||
className={cn("text-xs px-1.5 py-0.5 rounded ml-1 flex-shrink-0", getTagColor(item.tag))}
|
||||
>
|
||||
{item.tag}
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
<p className="text-xs text-gray-500 truncate mt-0.5">{item.description}</p>
|
||||
</div>
|
||||
</Link>
|
||||
{item.expandable && (
|
||||
<button
|
||||
onClick={() => toggleSection(item.section!)}
|
||||
className="ml-2 p-1 hover:bg-white/20 rounded-lg transition-colors duration-200"
|
||||
className="ml-1 p-1 hover:bg-white/20 rounded transition-colors duration-200 flex-shrink-0"
|
||||
>
|
||||
{expandedSections[item.section!] ? (
|
||||
<ChevronDown className="h-4 w-4" />
|
||||
<ChevronDown className="h-3 w-3" />
|
||||
) : (
|
||||
<ChevronRight className="h-4 w-4" />
|
||||
<ChevronRight className="h-3 w-3" />
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
@@ -187,21 +201,26 @@ export default function MobileSidebar({ isOpen, onClose }: MobileSidebarProps) {
|
||||
|
||||
{/* 子菜单 */}
|
||||
{item.children && expandedSections[item.section!] && (
|
||||
<div className="ml-6 mt-2 space-y-1">
|
||||
<div className="ml-4 mt-1 space-y-1">
|
||||
{item.children.map((subItem) => (
|
||||
<Link
|
||||
key={subItem.href}
|
||||
href={subItem.href}
|
||||
onClick={onClose}
|
||||
className={cn(
|
||||
"flex items-center px-3 py-2 text-sm rounded-lg transition-all duration-300",
|
||||
"flex items-center px-2 py-1.5 text-xs rounded transition-all duration-300",
|
||||
pathname === subItem.href
|
||||
? "glass-light text-blue-600 shadow-glass-sm"
|
||||
: "text-gray-600 hover:glass-light hover:text-blue-500",
|
||||
)}
|
||||
>
|
||||
<div className="mr-3 text-gray-400 transition-colors duration-300">{subItem.icon}</div>
|
||||
<span>{subItem.title}</span>
|
||||
<div className="mr-2 text-gray-400 transition-colors duration-300 flex-shrink-0">
|
||||
{subItem.icon}
|
||||
</div>
|
||||
<div className="min-w-0 flex-1">
|
||||
<p className="font-medium truncate">{subItem.title}</p>
|
||||
<p className="text-xs text-gray-500 truncate">{subItem.description}</p>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
@@ -211,21 +230,21 @@ export default function MobileSidebar({ isOpen, onClose }: MobileSidebarProps) {
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
{/* 底部设置 */}
|
||||
<div className="border-t border-white/20 p-4">
|
||||
<Link
|
||||
href="/settings"
|
||||
onClick={onClose}
|
||||
className={cn(
|
||||
"flex items-center px-4 py-2 text-xs font-medium rounded-lg transition-all duration-300 w-full",
|
||||
pathname === "/settings"
|
||||
? "glass-heavy text-blue-700 shadow-glass"
|
||||
: "glass-light text-gray-600 hover:glass-heavy hover:text-blue-500",
|
||||
)}
|
||||
>
|
||||
<Settings className="h-4 w-4 transition-colors duration-300" />
|
||||
<span className="ml-2">设置</span>
|
||||
</Link>
|
||||
{/* 底部信息 */}
|
||||
<div className="border-t border-white/20 p-3">
|
||||
<div className="glass-light rounded-lg p-2">
|
||||
<div className="flex items-center justify-between text-xs">
|
||||
<span className="text-gray-600">数据同步</span>
|
||||
<div className="flex items-center">
|
||||
<div className="w-2 h-2 bg-green-500 rounded-full mr-1"></div>
|
||||
<span className="text-green-600">正常</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center justify-between text-xs mt-1">
|
||||
<span className="text-gray-600">最后更新</span>
|
||||
<span className="text-gray-500">2分钟前</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user