97 lines
3.6 KiB
TypeScript
97 lines
3.6 KiB
TypeScript
"use client"
|
|
|
|
import { useState, useEffect } from "react"
|
|
import { Button } from "@/components/ui/button"
|
|
import { Zap, BookOpen } from "lucide-react"
|
|
import { getFullBookPrice, getAllSections } from "@/lib/book-data"
|
|
import { useStore } from "@/lib/store"
|
|
import { AuthModal } from "./modules/auth/auth-modal"
|
|
import { PaymentModal } from "./modules/payment/payment-modal"
|
|
|
|
export function PurchaseSection() {
|
|
const [fullBookPrice, setFullBookPrice] = useState(9.9)
|
|
const [sectionsCount, setSectionsCount] = useState(55)
|
|
const [isAuthOpen, setIsAuthOpen] = useState(false)
|
|
const [isPaymentOpen, setIsPaymentOpen] = useState(false)
|
|
const { isLoggedIn } = useStore()
|
|
|
|
useEffect(() => {
|
|
const sections = getAllSections()
|
|
setSectionsCount(sections.length)
|
|
setFullBookPrice(getFullBookPrice(sections.length))
|
|
}, [])
|
|
|
|
const handlePurchase = () => {
|
|
if (!isLoggedIn) {
|
|
setIsAuthOpen(true)
|
|
return
|
|
}
|
|
setIsPaymentOpen(true)
|
|
}
|
|
|
|
return (
|
|
<section className="py-8 px-4 bg-app-bg">
|
|
<div className="max-w-sm mx-auto">
|
|
{/* Pricing cards - stacked on mobile */}
|
|
<div className="space-y-3">
|
|
{/* Single section */}
|
|
<div className="bg-app-card/60 backdrop-blur-xl rounded-xl p-4 border border-app-border">
|
|
<div className="flex items-center justify-between">
|
|
<div className="flex items-center gap-3">
|
|
<BookOpen className="w-5 h-5 text-app-text-muted" />
|
|
<div>
|
|
<h3 className="text-app-text font-medium text-sm">单节购买</h3>
|
|
<p className="text-app-text-muted text-xs">按兴趣选择</p>
|
|
</div>
|
|
</div>
|
|
<div className="text-right">
|
|
<span className="text-xl font-bold text-app-text">¥1</span>
|
|
<span className="text-app-text-muted text-xs">/节</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Full book - highlighted */}
|
|
<div className="bg-gradient-to-br from-app-brand/20 to-app-card backdrop-blur-xl rounded-xl p-4 border border-app-brand/30 relative">
|
|
<span className="absolute -top-2 right-3 bg-app-brand text-white text-xs px-2 py-0.5 rounded-full">
|
|
推荐
|
|
</span>
|
|
|
|
<div className="flex items-center justify-between mb-3">
|
|
<div className="flex items-center gap-3">
|
|
<Zap className="w-5 h-5 text-app-brand" />
|
|
<div>
|
|
<h3 className="text-app-text font-medium text-sm">整本购买</h3>
|
|
<p className="text-app-text-muted text-xs">全部{sectionsCount}节 · 后续更新免费</p>
|
|
</div>
|
|
</div>
|
|
<div className="text-right">
|
|
<span className="text-xl font-bold text-app-text">¥{fullBookPrice.toFixed(1)}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<Button
|
|
onClick={handlePurchase}
|
|
className="w-full bg-app-brand hover:bg-app-brand-hover text-white rounded-lg h-10 text-sm"
|
|
>
|
|
立即购买
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Dynamic pricing note */}
|
|
<p className="mt-3 text-center text-app-text-muted text-xs">动态定价: 每新增一章节,整本价格+¥1</p>
|
|
</div>
|
|
|
|
<AuthModal isOpen={isAuthOpen} onClose={() => setIsAuthOpen(false)} />
|
|
<PaymentModal
|
|
isOpen={isPaymentOpen}
|
|
onClose={() => setIsPaymentOpen(false)}
|
|
type="fullbook"
|
|
amount={fullBookPrice}
|
|
onSuccess={() => window.location.reload()}
|
|
/>
|
|
</section>
|
|
)
|
|
}
|