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>
This commit is contained in:
@@ -2,56 +2,33 @@
|
||||
|
||||
import { useState } from "react"
|
||||
import { useRouter } from "next/navigation"
|
||||
import { ChevronLeft, ChevronRight, Lock, Unlock, Book, BookOpen, Sparkles } from "lucide-react"
|
||||
import { ChevronRight, Lock, Unlock, Book, BookOpen, Home, List, Sparkles, User } from "lucide-react"
|
||||
import { useStore } from "@/lib/store"
|
||||
import { bookData, getTotalSectionCount, specialSections, getFullBookPrice } from "@/lib/book-data"
|
||||
import { AuthModal } from "@/components/modules/auth/auth-modal"
|
||||
import { PaymentModal } from "@/components/payment-modal"
|
||||
import { bookData, getTotalSectionCount, specialSections } from "@/lib/book-data"
|
||||
|
||||
export default function ChaptersPage() {
|
||||
const router = useRouter()
|
||||
const { user, isLoggedIn, hasPurchased } = useStore()
|
||||
const { user, hasPurchased } = useStore()
|
||||
const [expandedPart, setExpandedPart] = useState<string | null>("part-1")
|
||||
const [isAuthOpen, setIsAuthOpen] = useState(false)
|
||||
const [isPaymentOpen, setIsPaymentOpen] = useState(false)
|
||||
|
||||
const totalSections = getTotalSectionCount()
|
||||
const purchasedCount = user?.purchasedSections?.length || 0
|
||||
const hasFullBook = user?.hasFullBook || false
|
||||
const fullBookPrice = getFullBookPrice()
|
||||
|
||||
const handleSectionClick = (sectionId: string, isFree: boolean) => {
|
||||
const handleSectionClick = (sectionId: string) => {
|
||||
router.push(`/read/${sectionId}`)
|
||||
}
|
||||
|
||||
const handleBuyFullBook = () => {
|
||||
if (!isLoggedIn) {
|
||||
setIsAuthOpen(true)
|
||||
return
|
||||
}
|
||||
setIsPaymentOpen(true)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-black text-white pb-24">
|
||||
{/* 顶部导航 */}
|
||||
<header className="sticky top-0 z-40 bg-black/90 backdrop-blur-xl border-b border-white/5">
|
||||
<div className="px-4 py-3 flex items-center justify-between">
|
||||
<button
|
||||
onClick={() => router.push("/")}
|
||||
className="w-9 h-9 rounded-full bg-[#1c1c1e] flex items-center justify-center"
|
||||
>
|
||||
<ChevronLeft className="w-5 h-5 text-gray-400" />
|
||||
</button>
|
||||
<h1 className="text-lg font-semibold text-[#ffd700]">我要看</h1>
|
||||
<div className="w-9" />
|
||||
<div className="px-4 py-3 flex items-center justify-center">
|
||||
<h1 className="text-lg font-semibold text-[#00CED1]">目录</h1>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{/* 书籍信息卡片 */}
|
||||
<div className="mx-4 mt-4 p-4 rounded-2xl bg-gradient-to-br from-[#1c1c1e] to-[#2c2c2e] border border-white/5">
|
||||
<div className="mx-4 mt-4 p-4 rounded-2xl bg-gradient-to-br from-[#1c1c1e] to-[#2c2c2e] border border-[#00CED1]/20">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-12 h-12 rounded-xl bg-gradient-to-br from-[#ff3b5c] to-[#ff6b8a] flex items-center justify-center">
|
||||
<div className="w-12 h-12 rounded-xl bg-gradient-to-br from-[#00CED1] to-[#20B2AA] flex items-center justify-center">
|
||||
<Book className="w-6 h-6 text-white" />
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
@@ -59,44 +36,30 @@ export default function ChaptersPage() {
|
||||
<p className="text-gray-500 text-xs mt-0.5">来自Soul派对房的真实商业故事</p>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="text-xl font-bold text-[#ff3b5c]">{totalSections}</div>
|
||||
<div className="text-xl font-bold text-[#00CED1]">{totalSections}</div>
|
||||
<div className="text-[10px] text-gray-500">章节</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 购买全书按钮 */}
|
||||
{!hasFullBook && (
|
||||
<button
|
||||
onClick={handleBuyFullBook}
|
||||
className="w-full mt-4 py-3 rounded-xl bg-gradient-to-r from-[#ff3b5c] to-[#ff6b8a] text-white font-medium flex items-center justify-center gap-2 active:scale-[0.98] transition-transform"
|
||||
>
|
||||
<Sparkles className="w-4 h-4" />
|
||||
<span>解锁全部 {totalSections} 章</span>
|
||||
<span className="ml-1">¥{fullBookPrice}</span>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 目录内容 */}
|
||||
<main className="px-4 py-4">
|
||||
{/* 序言 */}
|
||||
<button
|
||||
onClick={() => handleSectionClick("preface", true)}
|
||||
onClick={() => handleSectionClick("preface")}
|
||||
className="w-full mb-3 p-3 rounded-xl bg-[#1c1c1e] flex items-center justify-between active:bg-[#2c2c2e] transition-colors border border-white/5"
|
||||
>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-8 h-8 rounded-lg bg-[#ff3b5c]/20 flex items-center justify-center">
|
||||
<BookOpen className="w-4 h-4 text-[#ff3b5c]" />
|
||||
<div className="w-8 h-8 rounded-lg bg-[#00CED1]/20 flex items-center justify-center">
|
||||
<BookOpen className="w-4 h-4 text-[#00CED1]" />
|
||||
</div>
|
||||
<span className="text-sm font-medium text-white">序言|为什么我每天早上6点在Soul开播?</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-xs text-[#00E5FF]">免费</span>
|
||||
<span className="text-xs text-[#00CED1]">免费</span>
|
||||
<ChevronRight className="w-4 h-4 text-gray-500" />
|
||||
</div>
|
||||
</button>
|
||||
|
||||
{/* 五篇目录 */}
|
||||
{bookData.map((part) => (
|
||||
<div key={part.id} className="mb-3">
|
||||
<button
|
||||
@@ -104,7 +67,7 @@ export default function ChaptersPage() {
|
||||
className="w-full p-3 rounded-xl bg-[#1c1c1e] flex items-center justify-between active:bg-[#2c2c2e] transition-colors border border-white/5"
|
||||
>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-8 h-8 rounded-lg bg-gradient-to-br from-[#ff3b5c] to-[#ff6b8a] flex items-center justify-center text-sm font-bold text-white">
|
||||
<div className="w-8 h-8 rounded-lg bg-gradient-to-br from-[#00CED1] to-[#20B2AA] flex items-center justify-center text-sm font-bold text-white">
|
||||
{part.number}
|
||||
</div>
|
||||
<div className="text-left">
|
||||
@@ -136,12 +99,12 @@ export default function ChaptersPage() {
|
||||
return (
|
||||
<button
|
||||
key={section.id}
|
||||
onClick={() => handleSectionClick(section.id, section.isFree)}
|
||||
onClick={() => handleSectionClick(section.id)}
|
||||
className="w-full px-3 py-2.5 flex items-center justify-between border-b border-white/5 last:border-0 active:bg-white/5 transition-colors"
|
||||
>
|
||||
<div className="flex items-center gap-2 flex-1 min-w-0">
|
||||
{canRead ? (
|
||||
<Unlock className="w-3.5 h-3.5 text-[#ff3b5c] flex-shrink-0" />
|
||||
<Unlock className="w-3.5 h-3.5 text-[#00CED1] flex-shrink-0" />
|
||||
) : (
|
||||
<Lock className="w-3.5 h-3.5 text-gray-500 flex-shrink-0" />
|
||||
)}
|
||||
@@ -151,11 +114,11 @@ export default function ChaptersPage() {
|
||||
</div>
|
||||
<div className="flex items-center gap-2 flex-shrink-0 ml-2">
|
||||
{section.isFree ? (
|
||||
<span className="text-[10px] text-[#00E5FF] px-1.5 py-0.5 rounded bg-[#00E5FF]/10">
|
||||
<span className="text-[10px] text-[#00CED1] px-1.5 py-0.5 rounded bg-[#00CED1]/10">
|
||||
免费
|
||||
</span>
|
||||
) : isPurchased ? (
|
||||
<span className="text-[10px] text-[#ff3b5c]">已购</span>
|
||||
<span className="text-[10px] text-[#00CED1]">已购</span>
|
||||
) : (
|
||||
<span className="text-[10px] text-gray-500">¥{section.price}</span>
|
||||
)}
|
||||
@@ -171,19 +134,18 @@ export default function ChaptersPage() {
|
||||
</div>
|
||||
))}
|
||||
|
||||
{/* 尾声 */}
|
||||
<button
|
||||
onClick={() => handleSectionClick("epilogue", true)}
|
||||
onClick={() => handleSectionClick("epilogue")}
|
||||
className="w-full mb-3 p-3 rounded-xl bg-[#1c1c1e] flex items-center justify-between active:bg-[#2c2c2e] transition-colors border border-white/5"
|
||||
>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-8 h-8 rounded-lg bg-[#ff3b5c]/20 flex items-center justify-center">
|
||||
<BookOpen className="w-4 h-4 text-[#ff3b5c]" />
|
||||
<div className="w-8 h-8 rounded-lg bg-[#00CED1]/20 flex items-center justify-center">
|
||||
<BookOpen className="w-4 h-4 text-[#00CED1]" />
|
||||
</div>
|
||||
<span className="text-sm font-medium text-white">尾声|这本书的真实目的</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-xs text-[#00E5FF]">免费</span>
|
||||
<span className="text-xs text-[#00CED1]">免费</span>
|
||||
<ChevronRight className="w-4 h-4 text-gray-500" />
|
||||
</div>
|
||||
</button>
|
||||
@@ -194,7 +156,7 @@ export default function ChaptersPage() {
|
||||
{specialSections.appendix.map((item) => (
|
||||
<button
|
||||
key={item.id}
|
||||
onClick={() => handleSectionClick(item.id, true)}
|
||||
onClick={() => handleSectionClick(item.id)}
|
||||
className="w-full py-2 flex items-center justify-between border-b border-white/5 last:border-0 active:bg-white/5"
|
||||
>
|
||||
<span className="text-xs text-gray-300">{item.title}</span>
|
||||
@@ -204,48 +166,31 @@ export default function ChaptersPage() {
|
||||
</div>
|
||||
</main>
|
||||
|
||||
{/* 底部导航 */}
|
||||
<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-3">
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<button
|
||||
onClick={() => router.push("/")}
|
||||
className="flex-1 py-2.5 rounded-xl bg-[#2c2c2e] text-white text-sm font-medium text-center active:bg-[#3c3c3e]"
|
||||
>
|
||||
首页
|
||||
<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 className="flex-1 py-2.5 rounded-xl bg-[#ff3b5c]/20 text-[#ff3b5c] text-sm font-medium text-center">
|
||||
目录
|
||||
<button className="flex flex-col items-center py-2 px-4">
|
||||
<List className="w-5 h-5 text-[#00CED1] mb-1" />
|
||||
<span className="text-[#00CED1] text-xs font-medium">目录</span>
|
||||
</button>
|
||||
<button
|
||||
onClick={() => router.push("/about")}
|
||||
className="flex-1 py-2.5 rounded-xl bg-[#2c2c2e] text-white text-sm font-medium text-center active:bg-[#3c3c3e]"
|
||||
>
|
||||
作者
|
||||
{/* 匹配按钮 - 更大更突出 */}
|
||||
<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
|
||||
onClick={() => router.push("/my")}
|
||||
className="flex-1 py-2.5 rounded-xl bg-[#2c2c2e] text-white text-sm font-medium text-center active:bg-[#3c3c3e]"
|
||||
>
|
||||
我的
|
||||
<button onClick={() => router.push("/my")} className="flex flex-col items-center py-2 px-4">
|
||||
<User className="w-5 h-5 text-gray-500 mb-1" />
|
||||
<span className="text-gray-500 text-xs">我的</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
{/* 登录弹窗 */}
|
||||
<AuthModal isOpen={isAuthOpen} onClose={() => setIsAuthOpen(false)} />
|
||||
|
||||
{/* 支付弹窗 */}
|
||||
<PaymentModal
|
||||
isOpen={isPaymentOpen}
|
||||
onClose={() => setIsPaymentOpen(false)}
|
||||
type="fullbook"
|
||||
sectionId=""
|
||||
sectionTitle=""
|
||||
amount={fullBookPrice}
|
||||
onSuccess={() => window.location.reload()}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user