123 lines
4.4 KiB
TypeScript
123 lines
4.4 KiB
TypeScript
"use client"
|
|
|
|
import { X, MessageCircle, Users, Music } from "lucide-react"
|
|
import { useStore } from "@/lib/store"
|
|
import { Button } from "@/components/ui/button"
|
|
import Image from "next/image"
|
|
import { useState, useEffect } from "react"
|
|
|
|
interface QRCodeModalProps {
|
|
isOpen: boolean
|
|
onClose: () => void
|
|
}
|
|
|
|
export function QRCodeModal({ isOpen, onClose }: QRCodeModalProps) {
|
|
const { settings, getLiveQRCodeUrl } = useStore()
|
|
const [isJoining, setIsJoining] = useState(false)
|
|
const [qrCodeUrl, setQrCodeUrl] = useState("/images/party-group-qr.png") // Default fallback
|
|
|
|
// Fetch config on mount
|
|
useEffect(() => {
|
|
const fetchConfig = async () => {
|
|
try {
|
|
const res = await fetch('/api/config')
|
|
const data = await res.json()
|
|
if (data.marketing?.partyGroup?.qrCode) {
|
|
setQrCodeUrl(data.marketing.partyGroup.qrCode)
|
|
}
|
|
} catch (e) {
|
|
console.error("Failed to load QR config", e)
|
|
}
|
|
}
|
|
fetchConfig()
|
|
}, [])
|
|
|
|
if (!isOpen) return null
|
|
|
|
const handleJoin = () => {
|
|
setIsJoining(true)
|
|
// 获取活码随机URL
|
|
const url = getLiveQRCodeUrl("party-group")
|
|
if (url) {
|
|
window.open(url, "_blank")
|
|
}
|
|
setTimeout(() => setIsJoining(false), 1000)
|
|
}
|
|
|
|
return (
|
|
<div className="fixed inset-0 z-50 flex items-center justify-center p-4">
|
|
<div className="absolute inset-0 bg-black/80 backdrop-blur-md" onClick={onClose} />
|
|
|
|
{/* iOS Style Modal */}
|
|
<div className="relative w-full max-w-[320px] bg-[#1a1a1a] rounded-3xl border border-white/10 overflow-hidden shadow-2xl animate-in fade-in zoom-in-95 duration-200">
|
|
|
|
{/* Header Background Effect */}
|
|
<div className="absolute top-0 left-0 right-0 h-32 bg-gradient-to-b from-[#7000ff]/20 to-transparent pointer-events-none" />
|
|
|
|
<button
|
|
onClick={onClose}
|
|
className="absolute top-4 right-4 p-2 text-white/50 hover:text-white transition-colors z-10 bg-black/20 rounded-full backdrop-blur-sm"
|
|
>
|
|
<X className="w-5 h-5" />
|
|
</button>
|
|
|
|
<div className="p-8 flex flex-col items-center text-center relative">
|
|
|
|
{/* Icon Badge */}
|
|
<div className="w-16 h-16 mb-6 rounded-full bg-gradient-to-tr from-[#7000ff] to-[#bd00ff] p-[2px] shadow-lg shadow-purple-500/20">
|
|
<div className="w-full h-full rounded-full bg-[#1a1a1a] flex items-center justify-center">
|
|
<Music className="w-8 h-8 text-[#bd00ff]" />
|
|
</div>
|
|
</div>
|
|
|
|
<h3 className="text-xl font-bold text-white mb-2 tracking-tight">
|
|
Soul 创业派对
|
|
</h3>
|
|
|
|
<div className="flex items-center gap-2 mb-6">
|
|
<span className="px-2 py-0.5 rounded-full bg-white/10 text-[10px] text-white/70 border border-white/5">
|
|
Live
|
|
</span>
|
|
<p className="text-white/60 text-xs">
|
|
{settings.authorInfo?.liveTime || "06:00-09:00"} · {settings.authorInfo?.name || "卡若"}
|
|
</p>
|
|
</div>
|
|
|
|
{/* QR Code Container - Enhanced Visibility */}
|
|
<div className="bg-white p-3 rounded-2xl shadow-xl mb-6 transform transition-transform hover:scale-105 duration-300">
|
|
<div className="relative w-48 h-48">
|
|
<Image
|
|
src={qrCodeUrl}
|
|
alt="派对群二维码"
|
|
fill
|
|
className="object-contain"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<p className="text-white/40 text-xs mb-6 px-4">
|
|
扫码加入私域流量实战群<br/>获取《私域运营100问》
|
|
</p>
|
|
|
|
<Button
|
|
onClick={handleJoin}
|
|
disabled={isJoining}
|
|
className="w-full bg-gradient-to-r from-[#7000ff] to-[#bd00ff] hover:opacity-90 text-white font-medium rounded-xl h-12 shadow-lg shadow-purple-900/20 border-0 transition-all active:scale-95"
|
|
>
|
|
{isJoining ? (
|
|
<span className="flex items-center gap-2">
|
|
<Users className="w-4 h-4 animate-pulse" />
|
|
跳转中...
|
|
</span>
|
|
) : (
|
|
<span className="flex items-center gap-2">
|
|
<MessageCircle className="w-4 h-4" />
|
|
立即加入
|
|
</span>
|
|
)}
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
} |