主要更新: 1. 按H5网页端完全重构匹配功能(match页面) - 4种匹配类型: 创业合伙/资源对接/导师顾问/团队招募 - 资源对接等类型弹出手机号/微信号输入框 - 去掉重新匹配按钮,改为返回按钮 2. 修复所有卡片对齐和宽度问题 - 目录页附录卡片居中 - 首页阅读进度卡片满宽度 - 我的页面菜单卡片对齐 - 推广中心分享卡片统一宽度 3. 修复目录页图标和文字对齐 - section-icon固定40rpx宽高 - section-title与图标垂直居中 4. 更新真实完整文章标题(62篇) - 从book目录读取真实markdown文件名 - 替换之前的简化标题 5. 新增文章数据API - /api/db/chapters - 获取完整书籍结构 - 支持按ID获取单篇文章内容
556 lines
24 KiB
TypeScript
556 lines
24 KiB
TypeScript
"use client"
|
|
|
|
import { useState, useEffect } from "react"
|
|
import { useRouter } from "next/navigation"
|
|
import { User, ChevronRight, Home, List, Gift, Star, Info, Users, Wallet, Footprints, Eye, BookOpen, Clock, ArrowUpRight, Phone, MessageCircle, CreditCard, X, Check, Loader2, Settings } 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, updateUser } = useStore()
|
|
const [showAuthModal, setShowAuthModal] = useState(false)
|
|
const [mounted, setMounted] = useState(false)
|
|
const [activeTab, setActiveTab] = useState<"overview" | "footprint">("overview")
|
|
|
|
// 绑定弹窗状态
|
|
const [showBindModal, setShowBindModal] = useState(false)
|
|
const [bindType, setBindType] = useState<"phone" | "wechat" | "alipay">("phone")
|
|
const [bindValue, setBindValue] = useState("")
|
|
const [isBinding, setIsBinding] = useState(false)
|
|
const [bindError, setBindError] = useState("")
|
|
|
|
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 totalSections = getTotalSectionCount()
|
|
const purchasedCount = user?.hasFullBook ? totalSections : user?.purchasedSections?.length || 0
|
|
|
|
// 绑定账号
|
|
const handleBind = async () => {
|
|
if (!bindValue.trim()) {
|
|
setBindError("请输入内容")
|
|
return
|
|
}
|
|
|
|
if (bindType === "phone" && !/^1[3-9]\d{9}$/.test(bindValue)) {
|
|
setBindError("请输入正确的手机号")
|
|
return
|
|
}
|
|
|
|
if (bindType === "wechat" && bindValue.length < 6) {
|
|
setBindError("微信号至少6位")
|
|
return
|
|
}
|
|
|
|
if (bindType === "alipay" && !bindValue.includes("@") && !/^1[3-9]\d{9}$/.test(bindValue)) {
|
|
setBindError("请输入正确的支付宝账号")
|
|
return
|
|
}
|
|
|
|
setIsBinding(true)
|
|
setBindError("")
|
|
|
|
try {
|
|
// 模拟API调用
|
|
await new Promise(resolve => setTimeout(resolve, 1000))
|
|
|
|
// 更新用户信息
|
|
if (updateUser && user) {
|
|
const updates: any = {}
|
|
if (bindType === "phone") updates.phone = bindValue
|
|
if (bindType === "wechat") updates.wechat = bindValue
|
|
if (bindType === "alipay") updates.alipay = bindValue
|
|
updateUser(user.id, updates)
|
|
}
|
|
|
|
setShowBindModal(false)
|
|
setBindValue("")
|
|
alert("绑定成功!")
|
|
} catch (error) {
|
|
setBindError("绑定失败,请重试")
|
|
} finally {
|
|
setIsBinding(false)
|
|
}
|
|
}
|
|
|
|
// 打开绑定弹窗
|
|
const openBindModal = (type: "phone" | "wechat" | "alipay") => {
|
|
setBindType(type)
|
|
setBindValue("")
|
|
setBindError("")
|
|
setShowBindModal(true)
|
|
}
|
|
|
|
// 底部导航组件
|
|
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">
|
|
<Users className="w-7 h-7 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-gradient-to-br from-[#1c1c1e] to-[#2c2c2e] border border-[#00CED1]/20">
|
|
<div className="flex items-center gap-3 mb-4">
|
|
<div className="w-16 h-16 rounded-full border-2 border-dashed border-[#00CED1]/50 flex items-center justify-center bg-gradient-to-br from-[#00CED1]/10 to-transparent">
|
|
<User className="w-8 h-8 text-white/30" />
|
|
</div>
|
|
<div className="flex-1">
|
|
<button onClick={() => setShowAuthModal(true)} className="text-[#00CED1] font-semibold text-lg">
|
|
点击登录
|
|
</button>
|
|
<p className="text-white/30 text-sm">解锁专属权益</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-3 gap-2 pt-4 border-t border-white/10">
|
|
<div className="text-center p-2 rounded-lg bg-white/5">
|
|
<p className="text-[#00CED1] text-xl font-bold">0</p>
|
|
<p className="text-white/40 text-xs">已购章节</p>
|
|
</div>
|
|
<div className="text-center p-2 rounded-lg bg-white/5">
|
|
<p className="text-[#00CED1] text-xl font-bold">0</p>
|
|
<p className="text-white/40 text-xs">推荐好友</p>
|
|
</div>
|
|
<div className="text-center p-2 rounded-lg bg-white/5">
|
|
<p className="text-[#FFD700] text-xl font-bold">--</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-[#FFD700]/10 via-[#1c1c1e] to-[#1c1c1e] border border-[#FFD700]/20">
|
|
<div className="flex items-center justify-between">
|
|
<div className="flex items-center gap-3">
|
|
<div className="w-10 h-10 rounded-full bg-gradient-to-br from-[#FFD700] to-[#FFA500] flex items-center justify-center">
|
|
<Gift className="w-5 h-5 text-black" />
|
|
</div>
|
|
<div>
|
|
<p className="text-white font-medium">推广赚收益</p>
|
|
<p className="text-white/40 text-xs">登录后查看详情</p>
|
|
</div>
|
|
</div>
|
|
<button
|
|
onClick={() => setShowAuthModal(true)}
|
|
className="px-4 py-2 rounded-lg bg-[#FFD700]/20 text-[#FFD700] text-sm font-medium"
|
|
>
|
|
立即登录
|
|
</button>
|
|
</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={() => router.push("/about")}
|
|
className="w-full flex items-center justify-between p-4 active:bg-white/5"
|
|
>
|
|
<div className="flex items-center gap-3">
|
|
<div className="w-6 h-6 rounded-full bg-gradient-to-br from-[#00CED1] to-[#20B2AA] flex items-center justify-center">
|
|
<Info className="w-3 h-3 text-white" />
|
|
</div>
|
|
<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
|
|
|
|
// 模拟足迹数据(实际应从数据库获取)
|
|
const footprintData = {
|
|
recentChapters: user?.purchasedSections?.slice(-5) || [],
|
|
matchHistory: [], // 匹配历史
|
|
totalReadTime: Math.floor(Math.random() * 200) + 50, // 阅读时长(分钟)
|
|
}
|
|
|
|
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-gradient-to-br from-[#1c1c1e] to-[#2c2c2e] border border-[#00CED1]/20">
|
|
<div className="flex items-center gap-3 mb-4">
|
|
<div className="w-16 h-16 rounded-full border-2 border-[#00CED1] flex items-center justify-center bg-gradient-to-br from-[#00CED1]/20 to-transparent">
|
|
<span className="text-2xl font-bold text-[#00CED1]">{user?.nickname?.charAt(0) || "U"}</span>
|
|
</div>
|
|
<div className="flex-1">
|
|
<p className="text-white font-semibold text-lg">{user?.nickname || "用户"}</p>
|
|
<p className="text-white/30 text-sm">ID: {user?.id?.slice(-8) || "---"}</p>
|
|
</div>
|
|
<div className="px-3 py-1 rounded-full bg-[#00CED1]/20 border border-[#00CED1]/30">
|
|
<span className="text-[#00CED1] text-xs flex items-center gap-1">
|
|
<Star className="w-3 h-3" />
|
|
创业伙伴
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-3 gap-2 pt-4 border-t border-white/10">
|
|
<div className="text-center p-2 rounded-lg bg-white/5">
|
|
<p className="text-[#00CED1] text-xl font-bold">{purchasedCount}</p>
|
|
<p className="text-white/40 text-xs">已购章节</p>
|
|
</div>
|
|
<div className="text-center p-2 rounded-lg bg-white/5">
|
|
<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-2 rounded-lg bg-white/5">
|
|
<p className="text-[#FFD700] text-xl font-bold">
|
|
{(user?.earnings || 0) > 0 ? `¥${(user?.earnings || 0).toFixed(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-br from-[#1a1a2e] via-[#16213e] to-[#0f3460] border border-[#00CED1]/20 relative overflow-hidden">
|
|
{/* 背景装饰 */}
|
|
<div className="absolute top-0 right-0 w-32 h-32 bg-gradient-to-br from-[#FFD700]/10 to-transparent rounded-full -translate-y-1/2 translate-x-1/2" />
|
|
<div className="absolute bottom-0 left-0 w-24 h-24 bg-gradient-to-tr from-[#00CED1]/10 to-transparent rounded-full translate-y-1/2 -translate-x-1/2" />
|
|
|
|
<div className="relative">
|
|
<div className="flex items-center justify-between mb-4">
|
|
<div className="flex items-center gap-2">
|
|
<Wallet className="w-5 h-5 text-[#FFD700]" />
|
|
<span className="text-white font-medium">我的收益</span>
|
|
</div>
|
|
<button
|
|
onClick={() => router.push("/my/referral")}
|
|
className="text-[#00CED1] text-xs flex items-center gap-1"
|
|
>
|
|
推广中心
|
|
<ArrowUpRight className="w-3 h-3" />
|
|
</button>
|
|
</div>
|
|
|
|
<div className="flex items-end gap-6 mb-4">
|
|
<div>
|
|
<p className="text-white/50 text-xs mb-1">累计收益</p>
|
|
<p className="text-3xl font-bold bg-gradient-to-r from-[#FFD700] to-[#FFA500] bg-clip-text text-transparent">
|
|
¥{(user?.earnings || 0).toFixed(2)}
|
|
</p>
|
|
</div>
|
|
<div className="flex-1">
|
|
<p className="text-white/50 text-xs mb-1">可提现</p>
|
|
<p className="text-xl font-semibold text-white">
|
|
¥{(user?.pendingEarnings || 0).toFixed(2)}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<button
|
|
onClick={() => router.push("/my/referral")}
|
|
className="w-full py-2.5 rounded-xl bg-gradient-to-r from-[#FFD700]/80 to-[#FFA500]/80 text-black text-sm font-bold flex items-center justify-center gap-2"
|
|
>
|
|
<Gift className="w-4 h-4" />
|
|
推广中心 / 提现
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Tab切换 */}
|
|
<div className="mx-4 mt-4 flex gap-2">
|
|
<button
|
|
onClick={() => setActiveTab("overview")}
|
|
className={`flex-1 py-2.5 rounded-xl text-sm font-medium transition-colors ${
|
|
activeTab === "overview"
|
|
? "bg-[#00CED1]/20 text-[#00CED1] border border-[#00CED1]/30"
|
|
: "bg-[#1c1c1e] text-white/60"
|
|
}`}
|
|
>
|
|
概览
|
|
</button>
|
|
<button
|
|
onClick={() => setActiveTab("footprint")}
|
|
className={`flex-1 py-2.5 rounded-xl text-sm font-medium transition-colors flex items-center justify-center gap-1 ${
|
|
activeTab === "footprint"
|
|
? "bg-[#00CED1]/20 text-[#00CED1] border border-[#00CED1]/30"
|
|
: "bg-[#1c1c1e] text-white/60"
|
|
}`}
|
|
>
|
|
<Footprints className="w-4 h-4" />
|
|
我的足迹
|
|
</button>
|
|
</div>
|
|
|
|
{activeTab === "overview" ? (
|
|
<>
|
|
{/* 菜单列表 */}
|
|
<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>
|
|
<div className="flex items-center gap-2">
|
|
<span className="text-white/40 text-sm">{completedOrders}笔</span>
|
|
<ChevronRight className="w-5 h-5 text-white/30" />
|
|
</div>
|
|
</button>
|
|
<button
|
|
onClick={() => router.push("/my/referral")}
|
|
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">
|
|
<div className="w-6 h-6 rounded-full bg-gradient-to-br from-[#FFD700] to-[#FFA500] flex items-center justify-center">
|
|
<Gift className="w-3 h-3 text-black" />
|
|
</div>
|
|
<span className="text-white">推广中心</span>
|
|
</div>
|
|
<div className="flex items-center gap-2">
|
|
<span className="text-[#FFD700] text-sm font-medium">90%佣金</span>
|
|
<ChevronRight className="w-5 h-5 text-white/30" />
|
|
</div>
|
|
</button>
|
|
<button
|
|
onClick={() => router.push("/about")}
|
|
className="w-full flex items-center justify-between p-4 active:bg-white/5"
|
|
>
|
|
<div className="flex items-center gap-3">
|
|
<div className="w-6 h-6 rounded-full bg-gradient-to-br from-[#00CED1] to-[#20B2AA] flex items-center justify-center">
|
|
<Info className="w-3 h-3 text-white" />
|
|
</div>
|
|
<span className="text-white">关于作者</span>
|
|
</div>
|
|
<ChevronRight className="w-5 h-5 text-white/30" />
|
|
</button>
|
|
<button
|
|
onClick={() => router.push("/my/settings")}
|
|
className="w-full flex items-center justify-between p-4 active:bg-white/5"
|
|
>
|
|
<div className="flex items-center gap-3">
|
|
<div className="w-6 h-6 rounded-full bg-gray-500/20 flex items-center justify-center">
|
|
<Settings className="w-3 h-3 text-gray-400" />
|
|
</div>
|
|
<span className="text-white">设置</span>
|
|
</div>
|
|
<ChevronRight className="w-5 h-5 text-white/30" />
|
|
</button>
|
|
</div>
|
|
</>
|
|
) : (
|
|
<>
|
|
{/* 足迹内容 */}
|
|
<div className="mx-4 mt-4 space-y-4">
|
|
{/* 阅读统计 */}
|
|
<div className="p-4 rounded-2xl bg-[#1c1c1e] border border-white/5">
|
|
<h3 className="text-white font-medium mb-3 flex items-center gap-2">
|
|
<Eye className="w-4 h-4 text-[#00CED1]" />
|
|
阅读统计
|
|
</h3>
|
|
<div className="grid grid-cols-3 gap-3">
|
|
<div className="text-center p-3 rounded-xl bg-white/5">
|
|
<BookOpen className="w-5 h-5 text-[#00CED1] mx-auto mb-1" />
|
|
<p className="text-white font-bold">{purchasedCount}</p>
|
|
<p className="text-white/40 text-xs">已读章节</p>
|
|
</div>
|
|
<div className="text-center p-3 rounded-xl bg-white/5">
|
|
<Clock className="w-5 h-5 text-[#FFD700] mx-auto mb-1" />
|
|
<p className="text-white font-bold">{footprintData.totalReadTime}</p>
|
|
<p className="text-white/40 text-xs">阅读分钟</p>
|
|
</div>
|
|
<div className="text-center p-3 rounded-xl bg-white/5">
|
|
<Users className="w-5 h-5 text-[#E91E63] mx-auto mb-1" />
|
|
<p className="text-white font-bold">{footprintData.matchHistory.length || 0}</p>
|
|
<p className="text-white/40 text-xs">匹配伙伴</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* 最近阅读 */}
|
|
<div className="p-4 rounded-2xl bg-[#1c1c1e] border border-white/5">
|
|
<h3 className="text-white font-medium mb-3 flex items-center gap-2">
|
|
<BookOpen className="w-4 h-4 text-[#00CED1]" />
|
|
最近阅读
|
|
</h3>
|
|
{footprintData.recentChapters.length > 0 ? (
|
|
<div className="space-y-2">
|
|
{footprintData.recentChapters.map((sectionId, index) => (
|
|
<div
|
|
key={sectionId}
|
|
className="flex items-center justify-between p-3 rounded-xl bg-white/5"
|
|
>
|
|
<div className="flex items-center gap-3">
|
|
<span className="text-white/30 text-sm">{index + 1}</span>
|
|
<span className="text-white text-sm">章节 {sectionId}</span>
|
|
</div>
|
|
<button
|
|
onClick={() => router.push(`/read/${sectionId}`)}
|
|
className="text-[#00CED1] text-xs"
|
|
>
|
|
继续阅读
|
|
</button>
|
|
</div>
|
|
))}
|
|
</div>
|
|
) : (
|
|
<div className="text-center py-6 text-white/40">
|
|
<BookOpen className="w-8 h-8 mx-auto mb-2 opacity-50" />
|
|
<p className="text-sm">暂无阅读记录</p>
|
|
<button
|
|
onClick={() => router.push("/chapters")}
|
|
className="mt-2 text-[#00CED1] text-sm"
|
|
>
|
|
去阅读 →
|
|
</button>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
{/* 匹配记录 */}
|
|
<div className="p-4 rounded-2xl bg-[#1c1c1e] border border-white/5">
|
|
<h3 className="text-white font-medium mb-3 flex items-center gap-2">
|
|
<Users className="w-4 h-4 text-[#00CED1]" />
|
|
匹配记录
|
|
</h3>
|
|
<div className="text-center py-6 text-white/40">
|
|
<Users className="w-8 h-8 mx-auto mb-2 opacity-50" />
|
|
<p className="text-sm">暂无匹配记录</p>
|
|
<button
|
|
onClick={() => router.push("/match")}
|
|
className="mt-2 text-[#00CED1] text-sm"
|
|
>
|
|
去匹配 →
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</>
|
|
)}
|
|
|
|
<BottomNavBar />
|
|
|
|
{/* 绑定弹窗 */}
|
|
{showBindModal && (
|
|
<div className="fixed inset-0 z-50 flex items-center justify-center p-4">
|
|
<div className="absolute inset-0 bg-black/60 backdrop-blur-sm" onClick={() => !isBinding && setShowBindModal(false)} />
|
|
<div className="relative w-full max-w-sm bg-[#1c1c1e] rounded-2xl overflow-hidden">
|
|
<div className="flex items-center justify-between p-4 border-b border-white/10">
|
|
<h3 className="text-lg font-semibold text-white">
|
|
绑定{bindType === "phone" ? "手机号" : bindType === "wechat" ? "微信号" : "支付宝"}
|
|
</h3>
|
|
<button
|
|
onClick={() => !isBinding && setShowBindModal(false)}
|
|
className="w-8 h-8 rounded-full bg-white/10 flex items-center justify-center"
|
|
>
|
|
<X className="w-4 h-4 text-white/60" />
|
|
</button>
|
|
</div>
|
|
|
|
<div className="p-5">
|
|
<div className="mb-4">
|
|
<label className="block text-white/40 text-xs mb-2">
|
|
{bindType === "phone" ? "手机号" : bindType === "wechat" ? "微信号" : "支付宝账号"}
|
|
</label>
|
|
<input
|
|
type={bindType === "phone" ? "tel" : "text"}
|
|
value={bindValue}
|
|
onChange={(e) => setBindValue(e.target.value)}
|
|
placeholder={
|
|
bindType === "phone" ? "请输入11位手机号" :
|
|
bindType === "wechat" ? "请输入微信号" :
|
|
"请输入支付宝账号"
|
|
}
|
|
className="w-full px-4 py-3 rounded-xl bg-black/30 border border-white/10 text-white placeholder-white/30 focus:outline-none focus:border-[#00CED1]/50"
|
|
disabled={isBinding}
|
|
/>
|
|
</div>
|
|
|
|
{bindError && (
|
|
<p className="text-red-400 text-sm mb-4">{bindError}</p>
|
|
)}
|
|
|
|
<p className="text-white/40 text-xs mb-4">
|
|
{bindType === "phone" && "绑定手机号后可用于找伙伴匹配"}
|
|
{bindType === "wechat" && "绑定微信号后可用于找伙伴匹配和好友添加"}
|
|
{bindType === "alipay" && "绑定支付宝后可用于提现收益"}
|
|
</p>
|
|
|
|
<button
|
|
onClick={handleBind}
|
|
disabled={isBinding || !bindValue}
|
|
className="w-full py-3 rounded-xl bg-[#00CED1] text-black font-medium flex items-center justify-center gap-2 disabled:opacity-50"
|
|
>
|
|
{isBinding ? (
|
|
<>
|
|
<Loader2 className="w-4 h-4 animate-spin" />
|
|
绑定中...
|
|
</>
|
|
) : (
|
|
"确认绑定"
|
|
)}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</main>
|
|
)
|
|
}
|