chore: 恢复上传 components 目录到 GitHub

This commit is contained in:
卡若
2025-12-29 19:06:29 +08:00
parent 5dfc9b2898
commit 0bee46d58d
35 changed files with 3255 additions and 1 deletions

107
components/user-menu.tsx Normal file
View File

@@ -0,0 +1,107 @@
"use client"
import { useState } from "react"
import Link from "next/link"
import { User, LogOut, BookOpen, Gift, Settings } from "lucide-react"
import { useStore } from "@/lib/store"
import { AuthModal } from "./modules/auth/auth-modal"
export function UserMenu() {
const [isAuthOpen, setIsAuthOpen] = useState(false)
const [isMenuOpen, setIsMenuOpen] = useState(false)
const { user, isLoggedIn, logout } = useStore()
if (!isLoggedIn || !user) {
return (
<>
<button
onClick={() => setIsAuthOpen(true)}
className="flex items-center gap-2 px-4 py-2 rounded-lg bg-[#38bdac]/10 text-[#38bdac] hover:bg-[#38bdac]/20 transition-colors"
>
<User className="w-4 h-4" />
<span></span>
</button>
<AuthModal isOpen={isAuthOpen} onClose={() => setIsAuthOpen(false)} />
</>
)
}
return (
<div className="relative">
<button
onClick={() => setIsMenuOpen(!isMenuOpen)}
className="flex items-center gap-2 px-4 py-2 rounded-lg bg-[#0f2137] border border-gray-700 hover:border-[#38bdac]/50 transition-colors"
>
<div className="w-8 h-8 rounded-full bg-[#38bdac]/20 flex items-center justify-center">
<User className="w-4 h-4 text-[#38bdac]" />
</div>
<span className="text-white text-sm max-w-[100px] truncate">{user.nickname}</span>
</button>
{isMenuOpen && (
<>
<div className="fixed inset-0 z-40" onClick={() => setIsMenuOpen(false)} />
<div className="absolute right-0 top-full mt-2 w-56 bg-[#0f2137] border border-gray-700 rounded-xl shadow-xl z-50 overflow-hidden">
{/* User info */}
<div className="p-4 border-b border-gray-700/50">
<p className="text-white font-medium">{user.nickname}</p>
<p className="text-gray-500 text-sm">{user.phone}</p>
{user.hasFullBook && (
<span className="inline-block mt-2 px-2 py-1 bg-[#38bdac]/20 text-[#38bdac] text-xs rounded">
</span>
)}
</div>
{/* Menu items */}
<div className="py-2">
<Link
href="/my/purchases"
className="flex items-center gap-3 px-4 py-3 text-gray-300 hover:bg-gray-800/50 transition-colors"
onClick={() => setIsMenuOpen(false)}
>
<BookOpen className="w-4 h-4" />
<span></span>
</Link>
<Link
href="/my/referral"
className="flex items-center gap-3 px-4 py-3 text-gray-300 hover:bg-gray-800/50 transition-colors"
onClick={() => setIsMenuOpen(false)}
>
<Gift className="w-4 h-4" />
<span></span>
{user.earnings > 0 && (
<span className="ml-auto text-[#38bdac] text-sm">¥{user.earnings.toFixed(2)}</span>
)}
</Link>
{user.isAdmin && (
<Link
href="/admin"
className="flex items-center gap-3 px-4 py-3 text-gray-300 hover:bg-gray-800/50 transition-colors"
onClick={() => setIsMenuOpen(false)}
>
<Settings className="w-4 h-4" />
<span></span>
</Link>
)}
</div>
{/* Logout */}
<div className="border-t border-gray-700/50 py-2">
<button
onClick={() => {
logout()
setIsMenuOpen(false)
}}
className="w-full flex items-center gap-3 px-4 py-3 text-red-400 hover:bg-gray-800/50 transition-colors"
>
<LogOut className="w-4 h-4" />
<span>退</span>
</button>
</div>
</div>
</>
)}
</div>
)
}