Files
soul/app/my/page.tsx
v0 6afb9a143a refactor: redesign homepage and navigation based on trends
Update homepage layout and navigation to match current trends.

#VERCEL_SKIP

Co-authored-by: null <4804959+fnvtk@users.noreply.github.com>
2026-01-14 07:32:08 +00:00

415 lines
17 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client"
import { useState, useEffect } from "react"
import { useRouter } from "next/navigation"
import { User, ChevronRight, Copy, Check, Home, List, Sparkles, Clock } from "lucide-react"
import { useStore } from "@/lib/store"
import { AuthModal } from "@/components/modules/auth/auth-modal"
import { getFullBookPrice, getTotalSectionCount } from "@/lib/book-data"
export default function MyPage() {
const router = useRouter()
const { user, isLoggedIn, logout, getAllPurchases, settings } = useStore()
const [showAuthModal, setShowAuthModal] = useState(false)
const [mounted, setMounted] = useState(false)
const [copied, setCopied] = useState(false)
useEffect(() => {
setMounted(true)
}, [])
if (!mounted) {
return (
<div className="min-h-screen bg-black flex items-center justify-center">
<div className="animate-spin rounded-full h-8 w-8 border-t-2 border-b-2 border-[#00CED1]" />
</div>
)
}
const fullBookPrice = getFullBookPrice()
const totalSections = getTotalSectionCount()
const purchasedCount = user?.hasFullBook ? totalSections : user?.purchasedSections?.length || 0
const readingMinutes = Math.floor(Math.random() * 100)
const bookmarks = user?.purchasedSections?.length || 0
const authorInfo = settings?.authorInfo || {
name: "卡若",
description: "连续创业者,私域运营专家",
liveTime: "06:00-09:00",
platform: "Soul派对房",
}
const handleCopyCode = () => {
if (user?.referralCode) {
navigator.clipboard.writeText(user.referralCode)
setCopied(true)
setTimeout(() => setCopied(false), 2000)
}
}
// 底部导航组件
const BottomNavBar = () => (
<nav className="fixed bottom-0 left-0 right-0 bg-[#1c1c1e]/95 backdrop-blur-xl border-t border-white/5 pb-safe-bottom">
<div className="px-4 py-2">
<div className="flex items-center justify-around">
<button onClick={() => router.push("/")} className="flex flex-col items-center py-2 px-4">
<Home className="w-5 h-5 text-gray-500 mb-1" />
<span className="text-gray-500 text-xs"></span>
</button>
<button onClick={() => router.push("/chapters")} className="flex flex-col items-center py-2 px-4">
<List className="w-5 h-5 text-gray-500 mb-1" />
<span className="text-gray-500 text-xs"></span>
</button>
{/* 匹配按钮 - 更大更突出 */}
<button onClick={() => router.push("/match")} className="flex flex-col items-center py-2 px-6 -mt-4">
<div className="w-14 h-14 rounded-full bg-gradient-to-br from-[#00CED1] to-[#20B2AA] flex items-center justify-center shadow-lg shadow-[#00CED1]/30">
<Sparkles className="w-6 h-6 text-white" />
</div>
<span className="text-gray-500 text-xs mt-1"></span>
</button>
<button className="flex flex-col items-center py-2 px-4">
<User className="w-5 h-5 text-[#00CED1] mb-1" />
<span className="text-[#00CED1] text-xs font-medium"></span>
</button>
</div>
</div>
</nav>
)
// 未登录状态
if (!isLoggedIn) {
return (
<main className="min-h-screen bg-black text-white pb-24">
<div className="text-center py-4 border-b border-white/10">
<h1 className="text-lg font-medium text-[#00CED1]"></h1>
</div>
<div className="mx-4 mt-4 p-4 rounded-2xl bg-[#1c1c1e] border border-[#00CED1]/20">
<div className="flex items-center gap-3 mb-4">
<div className="w-14 h-14 rounded-full border-2 border-[#00CED1]/50 flex items-center justify-center">
<User className="w-7 h-7 text-white/30" />
</div>
<div>
<button onClick={() => setShowAuthModal(true)} className="text-[#00CED1] font-medium text-lg">
</button>
<p className="text-white/30 text-sm">ID: ---</p>
</div>
</div>
<div className="grid grid-cols-3 gap-4 pt-4 border-t border-white/10">
<div className="text-center">
<p className="text-[#00CED1] text-xl font-bold">0</p>
<p className="text-white/40 text-xs"></p>
</div>
<div className="text-center">
<p className="text-[#00CED1] text-xl font-bold">0</p>
<p className="text-white/40 text-xs">()</p>
</div>
<div className="text-center">
<p className="text-[#00CED1] text-xl font-bold">0</p>
<p className="text-white/40 text-xs"></p>
</div>
</div>
</div>
{/* 关于作者入口 */}
<div className="mx-4 mt-4 p-4 rounded-2xl bg-gradient-to-r from-[#00CED1]/10 to-transparent border border-[#00CED1]/20">
<div className="flex items-center gap-4">
<div className="w-14 h-14 rounded-full bg-gradient-to-br from-[#00CED1] to-[#20B2AA] flex items-center justify-center text-xl font-bold text-white">
{authorInfo.name.charAt(0)}
</div>
<div className="flex-1">
<h3 className="text-white font-semibold">{authorInfo.name}</h3>
<p className="text-gray-400 text-sm">{authorInfo.description}</p>
<div className="flex items-center gap-3 mt-1">
<span className="flex items-center gap-1 text-[#00CED1] text-xs">
<Clock className="w-3 h-3" />
{authorInfo.liveTime}
</span>
<span className="text-gray-500 text-xs">{authorInfo.platform}</span>
</div>
</div>
<button
onClick={() => router.push("/about")}
className="px-3 py-2 rounded-lg bg-[#00CED1] text-black text-sm font-medium"
>
</button>
</div>
</div>
{/* 分销中心 */}
<div className="mx-4 mt-4 p-4 rounded-2xl bg-[#1c1c1e] border border-white/5">
<div className="flex items-center justify-between mb-4">
<div className="flex items-center gap-2">
<span className="text-xl">💰</span>
<span className="text-white font-medium"></span>
</div>
<span className="text-[#00CED1] text-sm bg-[#00CED1]/10 px-2 py-1 rounded">佣金比例: 90%</span>
</div>
<div className="bg-[#2c2c2e] rounded-xl p-4 mb-4">
<p className="text-white/50 text-sm text-center mb-2"></p>
<p className="text-[#FFD700] text-3xl font-bold text-center">¥0.00</p>
<div className="grid grid-cols-2 gap-4 mt-4 pt-4 border-t border-white/10">
<div className="text-center">
<p className="text-white/50 text-xs"></p>
<p className="text-white font-medium">¥0.00</p>
</div>
<div className="text-center">
<p className="text-white/50 text-xs"></p>
<p className="text-white font-medium">¥0.00</p>
</div>
</div>
</div>
<div className="grid grid-cols-2 gap-3 mb-4">
<button
onClick={() => setShowAuthModal(true)}
className="py-3 rounded-xl bg-[#00CED1] text-white font-medium"
>
广
</button>
<button
onClick={() => setShowAuthModal(true)}
className="py-3 rounded-xl bg-[#2c2c2e] text-white font-medium border border-white/10"
>
</button>
</div>
<div className="grid grid-cols-3 gap-4 pt-4 border-t border-white/10">
<div className="text-center">
<p className="text-[#00CED1] text-xl font-bold">0</p>
<p className="text-white/40 text-xs"></p>
</div>
<div className="text-center">
<p className="text-[#00CED1] text-xl font-bold">0</p>
<p className="text-white/40 text-xs"></p>
</div>
<div className="text-center">
<p className="text-[#00CED1] text-xl font-bold">90%</p>
<p className="text-white/40 text-xs"></p>
</div>
</div>
<div className="mt-4 pt-4 border-t border-white/10">
<div className="flex items-center justify-between">
<div>
<p className="text-white/50 text-xs"></p>
<p className="text-[#00CED1] font-mono text-lg">- - -</p>
</div>
<button
onClick={() => setShowAuthModal(true)}
className="px-4 py-2 rounded-lg bg-[#2c2c2e] text-white text-sm"
>
</button>
</div>
</div>
</div>
{/* 菜单列表 */}
<div className="mx-4 mt-4 rounded-2xl bg-[#1c1c1e] border border-white/5 overflow-hidden">
<button
onClick={() => setShowAuthModal(true)}
className="w-full flex items-center justify-between p-4 border-b border-white/5 active:bg-white/5"
>
<div className="flex items-center gap-3">
<span className="text-xl">📦</span>
<span className="text-white"></span>
</div>
<ChevronRight className="w-5 h-5 text-white/30" />
</button>
<button
onClick={() => setShowAuthModal(true)}
className="w-full flex items-center justify-between p-4 active:bg-white/5"
>
<div className="flex items-center gap-3">
<span className="text-xl">🏷</span>
<span className="text-white"></span>
</div>
<ChevronRight className="w-5 h-5 text-white/30" />
</button>
</div>
<BottomNavBar />
<AuthModal isOpen={showAuthModal} onClose={() => setShowAuthModal(false)} />
</main>
)
}
// 已登录状态
const userPurchases = getAllPurchases().filter((p) => p.userId === user?.id)
const completedOrders = userPurchases.filter((p) => p.status === "completed").length
return (
<main className="min-h-screen bg-black text-white pb-24">
<div className="text-center py-4 border-b border-white/10">
<h1 className="text-lg font-medium text-[#00CED1]"></h1>
</div>
<div className="mx-4 mt-4 p-4 rounded-2xl bg-[#1c1c1e] border border-[#00CED1]/20">
<div className="flex items-center gap-3 mb-4">
<div className="w-14 h-14 rounded-full border-2 border-[#00CED1] flex items-center justify-center bg-gradient-to-br from-[#00CED1]/20 to-transparent">
<User className="w-7 h-7 text-[#00CED1]" />
</div>
<div>
<p className="text-white font-medium text-lg">{user?.nickname || "用户"}</p>
<p className="text-white/30 text-sm">ID: {user?.id?.slice(-8) || "---"}</p>
</div>
</div>
<div className="grid grid-cols-3 gap-4 pt-4 border-t border-white/10">
<div className="text-center">
<p className="text-[#00CED1] text-xl font-bold">{purchasedCount}</p>
<p className="text-white/40 text-xs"></p>
</div>
<div className="text-center">
<p className="text-[#00CED1] text-xl font-bold">{readingMinutes}</p>
<p className="text-white/40 text-xs">()</p>
</div>
<div className="text-center">
<p className="text-[#00CED1] text-xl font-bold">{bookmarks}</p>
<p className="text-white/40 text-xs"></p>
</div>
</div>
</div>
{/* 关于作者入口 */}
<div className="mx-4 mt-4 p-4 rounded-2xl bg-gradient-to-r from-[#00CED1]/10 to-transparent border border-[#00CED1]/20">
<div className="flex items-center gap-4">
<div className="w-14 h-14 rounded-full bg-gradient-to-br from-[#00CED1] to-[#20B2AA] flex items-center justify-center text-xl font-bold text-white">
{authorInfo.name.charAt(0)}
</div>
<div className="flex-1">
<h3 className="text-white font-semibold">{authorInfo.name}</h3>
<p className="text-gray-400 text-sm">{authorInfo.description}</p>
<div className="flex items-center gap-3 mt-1">
<span className="flex items-center gap-1 text-[#00CED1] text-xs">
<Clock className="w-3 h-3" />
{authorInfo.liveTime}
</span>
<span className="text-gray-500 text-xs">{authorInfo.platform}</span>
</div>
</div>
<button
onClick={() => router.push("/about")}
className="px-3 py-2 rounded-lg bg-[#00CED1] text-black text-sm font-medium"
>
</button>
</div>
</div>
{/* 分销中心 */}
<div className="mx-4 mt-4 p-4 rounded-2xl bg-[#1c1c1e] border border-white/5">
<div className="flex items-center justify-between mb-4">
<div className="flex items-center gap-2">
<span className="text-xl">💰</span>
<span className="text-white font-medium"></span>
</div>
<span className="text-[#00CED1] text-sm bg-[#00CED1]/10 px-2 py-1 rounded">佣金比例: 90%</span>
</div>
<div className="bg-[#2c2c2e] rounded-xl p-4 mb-4">
<p className="text-white/50 text-sm text-center mb-2"></p>
<p className="text-[#FFD700] text-3xl font-bold text-center">¥{(user?.earnings || 0).toFixed(2)}</p>
<div className="grid grid-cols-2 gap-4 mt-4 pt-4 border-t border-white/10">
<div className="text-center">
<p className="text-white/50 text-xs"></p>
<p className="text-white font-medium">¥{(user?.pendingEarnings || 0).toFixed(2)}</p>
</div>
<div className="text-center">
<p className="text-white/50 text-xs"></p>
<p className="text-white font-medium">¥{(user?.withdrawnEarnings || 0).toFixed(2)}</p>
</div>
</div>
</div>
<div className="grid grid-cols-2 gap-3 mb-4">
<button
onClick={() => router.push("/my/referral")}
className="py-3 rounded-xl bg-[#00CED1] text-white font-medium"
>
广
</button>
<button
onClick={() => router.push("/my/referral")}
className="py-3 rounded-xl bg-[#2c2c2e] text-white font-medium border border-white/10"
>
</button>
</div>
<div className="grid grid-cols-3 gap-4 pt-4 border-t border-white/10">
<div className="text-center">
<p className="text-[#00CED1] text-xl font-bold">{user?.referralCount || 0}</p>
<p className="text-white/40 text-xs"></p>
</div>
<div className="text-center">
<p className="text-[#00CED1] text-xl font-bold">{completedOrders}</p>
<p className="text-white/40 text-xs"></p>
</div>
<div className="text-center">
<p className="text-[#00CED1] text-xl font-bold">90%</p>
<p className="text-white/40 text-xs"></p>
</div>
</div>
<div className="mt-4 pt-4 border-t border-white/10">
<div className="flex items-center justify-between">
<div>
<p className="text-white/50 text-xs"></p>
<p className="text-[#00CED1] font-mono text-lg">{user?.referralCode || "---"}</p>
</div>
<button
onClick={handleCopyCode}
className="px-4 py-2 rounded-lg bg-[#2c2c2e] text-white text-sm flex items-center gap-2"
>
{copied ? <Check className="w-4 h-4 text-[#00CED1]" /> : <Copy className="w-4 h-4" />}
{copied ? "已复制" : "复制"}
</button>
</div>
</div>
</div>
{/* 菜单列表 */}
<div className="mx-4 mt-4 rounded-2xl bg-[#1c1c1e] border border-white/5 overflow-hidden">
<button
onClick={() => router.push("/my/purchases")}
className="w-full flex items-center justify-between p-4 border-b border-white/5 active:bg-white/5"
>
<div className="flex items-center gap-3">
<span className="text-xl">📦</span>
<span className="text-white"></span>
</div>
<ChevronRight className="w-5 h-5 text-white/30" />
</button>
<button
onClick={() => router.push("/my/bookmarks")}
className="w-full flex items-center justify-between p-4 active:bg-white/5"
>
<div className="flex items-center gap-3">
<span className="text-xl">🏷</span>
<span className="text-white"></span>
</div>
<ChevronRight className="w-5 h-5 text-white/30" />
</button>
</div>
<div className="mx-4 mt-4">
<button
onClick={logout}
className="w-full py-3 rounded-xl bg-[#1c1c1e] text-[#00CED1] font-medium border border-[#00CED1]/30"
>
退
</button>
</div>
<BottomNavBar />
</main>
)
}