From d5df83f35b7885586c03a1274b3b576fa81a04dd Mon Sep 17 00:00:00 2001 From: v0 Date: Wed, 14 Jan 2026 06:39:23 +0000 Subject: [PATCH] feat: refactor homepage and navigation structure Remove unused pages, redesign author page, update homepage with new chapter display, and modify bottom navigation. #VERCEL_SKIP Co-authored-by: null <4804959+fnvtk@users.noreply.github.com> --- app/about/page.tsx | 183 +++++++------ app/chapters/page.tsx | 273 ++++++++++++++++--- app/my/page.tsx | 209 ++++++--------- app/my/settings/page.tsx | 96 ------- app/page.tsx | 565 +++++++++++++++++---------------------- 5 files changed, 664 insertions(+), 662 deletions(-) delete mode 100644 app/my/settings/page.tsx diff --git a/app/about/page.tsx b/app/about/page.tsx index e8b129e..3177ebe 100644 --- a/app/about/page.tsx +++ b/app/about/page.tsx @@ -1,15 +1,16 @@ "use client" -import Link from "next/link" -import { ChevronLeft, Clock, MessageCircle, BookOpen, Users, Award, TrendingUp } from "lucide-react" -import { Button } from "@/components/ui/button" import { useState } from "react" +import { useRouter } from "next/navigation" +import { ChevronLeft, Clock, MessageCircle, BookOpen, Users, Award, TrendingUp } from "lucide-react" import { QRCodeModal } from "@/components/modules/marketing/qr-code-modal" import { useStore } from "@/lib/store" export default function AboutPage() { + const router = useRouter() const [showQRModal, setShowQRModal] = useState(false) const { settings } = useStore() + const authorInfo = settings?.authorInfo || { name: "卡若", description: "连续创业者,私域运营专家", @@ -17,6 +18,13 @@ export default function AboutPage() { platform: "Soul派对房", } + const stats = [ + { icon: BookOpen, value: "55+", label: "真实案例" }, + { icon: Users, value: "10000+", label: "派对房听众" }, + { icon: Award, value: "15年", label: "创业经验" }, + { icon: TrendingUp, value: "3000万", label: "最高年流水" }, + ] + const milestones = [ { year: "2012", event: "开始做游戏推广,从魔兽世界外挂代理起步" }, { year: "2015", event: "转型电商,做天猫虚拟充值,月流水380万" }, @@ -26,126 +34,129 @@ export default function AboutPage() { { year: "2024", event: "在Soul派对房每日直播,分享真实商业故事" }, ] - const stats = [ - { icon: BookOpen, value: "55+", label: "真实案例" }, - { icon: Users, value: "10000+", label: "派对房听众" }, - { icon: Award, value: "15年", label: "创业经验" }, - { icon: TrendingUp, value: "3000万", label: "最高年流水" }, - ] - return ( -
- {/* Header */} -
-
- - - 返回 - -

关于作者

-
+
+ {/* 顶部导航 */} +
+
+ +

关于作者

+
-
- {/* Author Card */} -
-
-
+
+ {/* 作者头像卡片 */} +
+
+
{authorInfo.name.charAt(0)}
-
-

{authorInfo.name}

-

{authorInfo.description}

-
- - +
+

{authorInfo.name}

+

{authorInfo.description}

+
+ + 每日 {authorInfo.liveTime} - - + + {authorInfo.platform}
-
- {/* Stats */} -
+ {/* 数据统计 */} +
{stats.map((stat, index) => ( -
- -

{stat.value}

-

{stat.label}

+
+ +

{stat.value}

+

{stat.label}

))}
- {/* Introduction */} -
-

关于这本书

-
+ {/* 关于这本书 */} +
+

关于这本书

+

"这不是一本教你成功的鸡汤书。"

-

- 这是我每天早上6点到9点,在Soul派对房和几百个陌生人分享的真实故事。 有人来找项目,有人来找钱,有人来找方向。 -

-

- 我见过凌晨四点还在撸运费险的年轻人,见过七十岁还在开滴滴做生意的老人, - 见过一个月赚七八块却拼命倒卖游戏金币的大学生。 -

-

"社会不是靠努力,是靠洞察与选择。"

-

- 这本书,就是把那些在派对房里讲过的、能让人清醒的故事,整理成文字。每个案例都真实发生过,每个教训都是用钱换来的。 -

+

这是我每天早上6点到9点,在Soul派对房和几百个陌生人分享的真实故事。

+

"社会不是靠努力,是靠洞察与选择。"

- {/* Timeline */} -
-

创业历程

+ {/* 创业历程 */} +
+

创业历程

{milestones.map((item, index) => ( -
+
-
- {index < milestones.length - 1 &&
} +
+ {index < milestones.length - 1 &&
}
-
-

{item.year}

-

{item.event}

+
+

{item.year}

+

{item.event}

))}
- {/* CTA */} -
-

想听更多真实故事?

-

每天早上6-9点,卡若在Soul派对房免费分享

-
- - - - -
+ {/* 行动引导 */} +
+

想听更多真实故事?

+

每天早上6-9点,卡若在Soul派对房免费分享

+
+ {/* 底部导航 */} + + setShowQRModal(false)} />
) diff --git a/app/chapters/page.tsx b/app/chapters/page.tsx index 3dd4247..6fe8658 100644 --- a/app/chapters/page.tsx +++ b/app/chapters/page.tsx @@ -1,54 +1,251 @@ -import Link from "next/link" -import { ChevronLeft } from "lucide-react" -import { Button } from "@/components/ui/button" -import { specialSections, FULL_BOOK_PRICE } from "@/lib/book-data" -import { getBookStructure } from "@/lib/book-file-system" -import { ChaptersList } from "@/components/chapters-list" +"use client" -import { BuyFullBookButton } from "@/components/buy-full-book-button" +import { useState } from "react" +import { useRouter } from "next/navigation" +import { ChevronLeft, ChevronRight, Lock, Unlock, Book, BookOpen, Sparkles } 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" -export const dynamic = 'force-dynamic'; +export default function ChaptersPage() { + const router = useRouter() + const { user, isLoggedIn, hasPurchased } = useStore() + const [expandedPart, setExpandedPart] = useState("part-1") + const [isAuthOpen, setIsAuthOpen] = useState(false) + const [isPaymentOpen, setIsPaymentOpen] = useState(false) -export default async function ChaptersPage() { - const parts = getBookStructure() + const totalSections = getTotalSectionCount() + const purchasedCount = user?.purchasedSections?.length || 0 + const hasFullBook = user?.hasFullBook || false + const fullBookPrice = getFullBookPrice() - // Format special sections for the client component - const specialSectionsData = { - preface: { title: specialSections.preface.title }, - epilogue: { title: specialSections.epilogue.title } + const handleSectionClick = (sectionId: string, isFree: boolean) => { + router.push(`/read/${sectionId}`) + } + + const handleBuyFullBook = () => { + if (!isLoggedIn) { + setIsAuthOpen(true) + return + } + setIsPaymentOpen(true) } return ( -
- {/* Header */} -
-
- - - 返回 - -

目录

- +
+ {/* 顶部导航 */} +
+
+ +

我要看

+
- {/* Content */} -
- - - {/* Bottom CTA */} -
-
-
-

购买整本书,省82%

-

全部55节内容,永久阅读,后续更新免费获取

-
- - 立即购买 ¥9.9 - + {/* 书籍信息卡片 */} +
+
+
+ +
+
+

一场SOUL的创业实验场

+

来自Soul派对房的真实商业故事

+
+
+
{totalSections}
+
章节
+ + {/* 购买全书按钮 */} + {!hasFullBook && ( + + )} +
+ + {/* 目录内容 */} +
+ {/* 序言 */} + + + {/* 五篇目录 */} + {bookData.map((part) => ( +
+ + + {expandedPart === part.id && ( +
+ {part.chapters.map((chapter) => ( +
+
+ {chapter.title} +
+ {chapter.sections.map((section) => { + const isPurchased = hasFullBook || hasPurchased(section.id) + const canRead = section.isFree || isPurchased + + return ( + + ) + })} +
+ ))} +
+ )} +
+ ))} + + {/* 尾声 */} + + + {/* 附录 */} +
+
附录
+ {specialSections.appendix.map((item) => ( + + ))} +
+ + {/* 底部导航 */} + + + {/* 登录弹窗 */} + setIsAuthOpen(false)} /> + + {/* 支付弹窗 */} + setIsPaymentOpen(false)} + type="fullbook" + sectionId="" + sectionTitle="" + amount={fullBookPrice} + onSuccess={() => window.location.reload()} + />
) } diff --git a/app/my/page.tsx b/app/my/page.tsx index db5b3fe..bbcc2e3 100644 --- a/app/my/page.tsx +++ b/app/my/page.tsx @@ -1,13 +1,14 @@ "use client" import { useState, useEffect } from "react" -import Link from "next/link" +import { useRouter } from "next/navigation" import { User, ChevronRight, Copy, Check } 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 } = useStore() const [showAuthModal, setShowAuthModal] = useState(false) const [mounted, setMounted] = useState(false) @@ -28,8 +29,6 @@ export default function MyPage() { const fullBookPrice = getFullBookPrice() const totalSections = getTotalSectionCount() const purchasedCount = user?.hasFullBook ? totalSections : user?.purchasedSections?.length || 0 - - // 计算阅读时长(模拟数据,实际应该从localStorage读取) const readingMinutes = Math.floor(Math.random() * 100) const bookmarks = user?.purchasedSections?.length || 0 @@ -47,7 +46,7 @@ export default function MyPage() {
{/* 顶部标题 */}
-

Soul派对·创业实验

+

我的

{/* 用户卡片 - 未登录 */} @@ -64,7 +63,6 @@ export default function MyPage() {
- {/* 统计数据 */}

0

@@ -91,7 +89,6 @@ export default function MyPage() { 佣金比例: 90%
- {/* 收益卡片 */}

累计收益

¥0.00

@@ -107,7 +104,6 @@ export default function MyPage() {
- {/* 按钮 */}
- {/* 统计 */}

0

@@ -139,7 +134,6 @@ export default function MyPage() {
- {/* 邀请码 */}
@@ -156,76 +150,58 @@ export default function MyPage() {
- {/* 菜单列表 */} + {/* 菜单列表 - 精简版 */}
- { - e.preventDefault() - setShowAuthModal(true) - }} - className="flex items-center justify-between p-4 border-b border-white/5 active:bg-white/5" + +
- {/* 设置菜单 */} -
- -
- ⚙️ - 设置 + {/* 底部导航 */} +
+ setShowAuthModal(false)} />
@@ -240,7 +216,7 @@ export default function MyPage() {
{/* 顶部标题 */}
-

Soul派对·创业实验

+

我的

{/* 用户卡片 */} @@ -255,7 +231,6 @@ export default function MyPage() {
- {/* 统计数据 */}

{purchasedCount}

@@ -282,7 +257,6 @@ export default function MyPage() { 佣金比例: 90%
- {/* 收益卡片 */}

累计收益

¥{(user?.earnings || 0).toFixed(2)}

@@ -298,20 +272,21 @@ export default function MyPage() {
- {/* 按钮 */}
- +
- {/* 统计 */}

{user?.referralCount || 0}

@@ -327,7 +302,6 @@ export default function MyPage() {
- {/* 邀请码 */}
@@ -345,66 +319,28 @@ export default function MyPage() {
- {/* 菜单列表 */} + {/* 菜单列表 - 精简版 */}
- router.push("/my/purchases")} + className="w-full flex items-center justify-between p-4 border-b border-white/5 active:bg-white/5" >
📦 我的订单
- - +
- - {/* 设置菜单 */} -
- -
- ⚙️ - 设置 -
- - - -
- 💬 - 联系客服 -
- - - -
- ℹ️ - 关于我们 -
- - +
{/* 退出登录 */} @@ -416,6 +352,35 @@ export default function MyPage() { 退出登录
+ + {/* 底部导航 */} + ) } diff --git a/app/my/settings/page.tsx b/app/my/settings/page.tsx deleted file mode 100644 index 16ab2a2..0000000 --- a/app/my/settings/page.tsx +++ /dev/null @@ -1,96 +0,0 @@ -"use client" - -import { useState } from "react" -import Link from "next/link" -import { ArrowLeft, Phone, Bell, Shield, HelpCircle } from "lucide-react" -import { useStore } from "@/lib/store" - -export default function SettingsPage() { - const { user, updateUser } = useStore() - const [nickname, setNickname] = useState(user?.nickname || "") - const [saved, setSaved] = useState(false) - - const handleSave = () => { - if (user) { - updateUser(user.id, { nickname }) - setSaved(true) - setTimeout(() => setSaved(false), 2000) - } - } - - return ( -
-
-
- - - -

账户设置

-
-
- -
-
- {/* Profile Settings */} -
-

个人信息

- -
-
- - setNickname(e.target.value)} - className="w-full bg-[#0a1628] border border-gray-700 rounded-lg px-4 py-3 text-white mt-1" - /> -
- -
- -
- - {user?.phone} -
-
-
- - -
- - {/* Other Settings */} -
-
-
- - 消息通知 -
-
-
-
-
- -
-
- - 隐私设置 -
-
- - -
- - 帮助文档 -
- -
-
-
-
- ) -} diff --git a/app/page.tsx b/app/page.tsx index 4daa317..062e91e 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,349 +1,274 @@ "use client" -import { useState } from "react" +import { useState, useEffect, useRef, useCallback } from "react" import { useRouter } from "next/navigation" +import { ChevronRight, Sparkles, Lock, Share2 } from "lucide-react" import { useStore } from "@/lib/store" -import { bookData, getTotalSectionCount, specialSections } from "@/lib/book-data" -import { Book, Lock, Unlock, ChevronRight, User, BookOpen } from "lucide-react" +import { getFullBookPrice, getTotalSectionCount } from "@/lib/book-data" +import { AuthModal } from "@/components/modules/auth/auth-modal" +import { PaymentModal } from "@/components/payment-modal" export default function HomePage() { const router = useRouter() const { user, isLoggedIn, hasPurchased } = useStore() - const [activeTab, setActiveTab] = useState<"home" | "me">("home") - const [expandedPart, setExpandedPart] = useState("part-1") + const [content, setContent] = useState("") + const [isLoading, setIsLoading] = useState(true) + const [showPaywall, setShowPaywall] = useState(false) + const [readingProgress, setReadingProgress] = useState(0) + const [isAuthOpen, setIsAuthOpen] = useState(false) + const [isPaymentOpen, setIsPaymentOpen] = useState(false) + const [paymentType, setPaymentType] = useState<"section" | "fullbook">("section") + const contentRef = useRef(null) + const fullBookPrice = getFullBookPrice() const totalSections = getTotalSectionCount() - const purchasedCount = user?.purchasedSections?.length || 0 const hasFullBook = user?.hasFullBook || false - // 点击章节 - const handleSectionClick = (sectionId: string, isFree: boolean) => { - if (isFree || hasFullBook || hasPurchased(sectionId)) { - router.push(`/read/${sectionId}`) - } else { - router.push(`/read/${sectionId}`) - } + // 最新章节 - 使用1.1作为示例 + const latestSection = { + id: "1.1", + title: "荷包:电动车出租的被动收入模式", + price: 1, + isFree: true, + filePath: "book/第一篇|真实的人/第1章|人与人之间的底层逻辑/1.1 荷包:电动车出租的被动收入模式.md", } + // 加载最新章节内容 + useEffect(() => { + async function loadContent() { + try { + const response = await fetch(`/api/content?path=${encodeURIComponent(latestSection.filePath)}`) + if (response.ok) { + const data = await response.json() + setContent(data.content || "") + } + } catch (error) { + console.error("Failed to load content:", error) + } finally { + setIsLoading(false) + } + } + loadContent() + }, []) + + // 监听滚动进度 + const handleScroll = useCallback(() => { + if (!contentRef.current) return + + const scrollTop = window.scrollY + const docHeight = document.documentElement.scrollHeight - window.innerHeight + const progress = docHeight > 0 ? Math.min((scrollTop / docHeight) * 100, 100) : 0 + setReadingProgress(progress) + + // 滚动超过20%时触发付费墙(非免费章节或未登录) + if (progress >= 20 && !hasFullBook && !latestSection.isFree) { + setShowPaywall(true) + } + }, [hasFullBook]) + + useEffect(() => { + window.addEventListener("scroll", handleScroll) + return () => window.removeEventListener("scroll", handleScroll) + }, [handleScroll]) + + const handlePurchaseClick = (type: "section" | "fullbook") => { + if (!isLoggedIn) { + setIsAuthOpen(true) + return + } + setPaymentType(type) + setIsPaymentOpen(true) + } + + const contentLines = content.split("\n").filter((line) => line.trim()) + // 如果需要付费墙,只显示前20%内容 + const displayContent = + showPaywall && !hasFullBook && !latestSection.isFree + ? contentLines.slice(0, Math.ceil(contentLines.length * 0.2)).join("\n") + : content + return ( -
- {/* 顶部固定区域 - 书籍信息 */} -
-
-
- -
-
-

一场SOUL的创业实验场

-

来自Soul派对房的真实商业故事

-
-
-
{totalSections}
-
章节
+
+ {/* 阅读进度条 */} +
+
+
+ + {/* 顶部标题区 */} +
+
+
+
+ Soul派对·创业实验 + 最新 +
+
- {/* 主内容区域 - 可滚动的目录 */} - {activeTab === "home" ? ( -
- {/* 序言入口 */} - + {/* 章节标题 */} +
+
+ + {latestSection.id} + + {latestSection.isFree && ( + 免费 + )} +
+

{latestSection.title}

+

第一篇|真实的人

+
- {/* 五篇目录 */} - {bookData.map((part) => ( -
- {/* 篇标题 */} - - - {/* 展开的章节列表 */} - {expandedPart === part.id && ( -
- {part.chapters.map((chapter) => ( -
-
- {chapter.title} -
- {chapter.sections.map((section) => { - const isPurchased = hasFullBook || hasPurchased(section.id) - const canRead = section.isFree || isPurchased - - return ( - - ) - })} -
- ))} -
- )} -
- ))} - - {/* 尾声入口 */} - - - {/* 附录 */} -
-
附录
- {specialSections.appendix.map((item) => ( - + {/* 内容区域 */} +
+ {isLoading ? ( +
+ {[...Array(8)].map((_, i) => ( +
))}
-
- ) : ( - - )} + ) : ( +
+ {displayContent.split("\n").map( + (paragraph, index) => + paragraph.trim() && ( +

+ {paragraph} +

+ ), + )} +
+ )} + + {/* 付费墙 - 只在非免费章节且滚动超过20%时显示 */} + {showPaywall && !hasFullBook && !latestSection.isFree && ( +
+ {/* 渐变遮罩 */} +
+ + {/* 付费卡片 */} +
+
+
+ +
+

解锁完整内容

+

{isLoggedIn ? "支付1元继续阅读" : "登录并支付1元继续阅读"}

+ +
+ + + +
+ +

分享给好友购买,你可获得90%佣金

+
+
+
+ )} + + {/* 底部引导 - 免费章节或已购买时显示 */} + {!showPaywall && ( +
+
+
+

想看更多内容?

+

共 {totalSections} 章精彩内容

+
+ +
+
+ )} +
{/* 底部导航 */} -