Files
gitlab-instance-0a899031_no…/app/components/CommunityButton.tsx
2026-03-10 01:35:37 -05:00

135 lines
5.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import { useState, useEffect } from "react";
import Link from "next/link";
import { COMMUNITY_CONFIG } from "@/config/course";
import { isPaid } from "@/app/lib/payment";
export function CommunityButton() {
const [open, setOpen] = useState(false);
const [paid, setPaid] = useState(false);
useEffect(() => {
setPaid(isPaid());
const onPay = () => setPaid(isPaid());
window.addEventListener("pay:updated", onPay);
return () => window.removeEventListener("pay:updated", onPay);
}, []);
useEffect(() => {
const onKeyDown = (e: KeyboardEvent) => {
if (e.key === "Escape") setOpen(false);
};
if (open) {
window.addEventListener("keydown", onKeyDown);
document.body.style.overflow = "hidden";
}
return () => {
window.removeEventListener("keydown", onKeyDown);
document.body.style.overflow = "";
};
}, [open]);
if (!COMMUNITY_CONFIG.enabled || !COMMUNITY_CONFIG.wechat) return null;
return (
<>
<button
type="button"
onClick={() => setOpen(true)}
className="text-sm text-[var(--muted-foreground)] transition hover:text-[var(--foreground)]"
>
{COMMUNITY_CONFIG.wechat}
</button>
{open && (
<div
className="fixed inset-0 z-50 flex items-center justify-center bg-black/70 backdrop-blur-sm p-4"
onClick={() => setOpen(false)}
>
<div
className="relative w-full max-w-[420px] overflow-hidden rounded-2xl border border-[var(--border)] bg-[var(--background)] shadow-2xl"
onClick={(e) => e.stopPropagation()}
>
<div className="absolute inset-x-0 top-0 h-1 bg-gradient-to-r from-[var(--accent)] via-cyan-400 to-[var(--accent)]" />
<button
type="button"
onClick={() => setOpen(false)}
className="absolute right-3 top-3 rounded-full p-2 text-[var(--muted-foreground)] transition hover:bg-[var(--muted)] hover:text-[var(--foreground)]"
aria-label="关闭"
>
<svg className="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
{paid ? (
<div className="p-8 pt-10">
<div className="mb-6 text-center">
<div className="mb-3 inline-flex h-14 w-14 items-center justify-center rounded-2xl bg-gradient-to-br from-[var(--accent)]/30 to-cyan-500/20 text-3xl shadow-lg">
💬
</div>
<h3 className="text-xl font-semibold">加入数字游民社群</h3>
<p className="mt-2 text-sm text-[var(--muted-foreground)]">
与导师、同学一起交流,获取持续支持与灵感
</p>
</div>
<div className="flex justify-center">
<div className="relative flex h-56 w-56 items-center justify-center rounded-2xl bg-gradient-to-br from-[var(--card)] to-[var(--muted)]/30 p-5 shadow-inner ring-2 ring-[var(--accent)]/20">
<img
src={COMMUNITY_CONFIG.qrCodeUrl}
alt="社群二维码"
className="h-full w-full object-contain"
onError={(e) => {
const target = e.target as HTMLImageElement;
target.style.display = "none";
const fallback = target.parentElement?.querySelector(".qr-fallback");
if (fallback) (fallback as HTMLElement).classList.remove("hidden");
}}
/>
<div className="qr-fallback hidden absolute inset-0 flex flex-col items-center justify-center gap-2 rounded-2xl bg-[var(--muted)]/40 p-4 text-center text-sm text-[var(--muted-foreground)]">
<span className="text-4xl">📱</span>
<span>请配置社群二维码</span>
<span className="text-xs">config/course.ts → qrCodeUrl</span>
</div>
</div>
</div>
<p className="mt-5 text-center text-sm text-[var(--muted-foreground)]">
长按识别二维码加入
</p>
</div>
) : (
<div className="p-8 pt-10">
<div className="mb-6 text-center">
<div className="mb-3 inline-flex h-16 w-16 items-center justify-center rounded-2xl bg-gradient-to-br from-amber-500/20 to-orange-500/10 text-4xl shadow-lg">
🔒
</div>
<h3 className="text-xl font-semibold">报名后解锁社群</h3>
<p className="mt-2 text-sm leading-relaxed text-[var(--muted-foreground)]">
完成课程报名后,即可加入专属社群,与导师、同学交流答疑
</p>
</div>
<div className="flex flex-col gap-3">
<Link
href="/pay"
className="rounded-xl bg-[var(--accent)] px-6 py-4 text-center font-medium text-[var(--accent-foreground)] transition hover:opacity-90"
onClick={() => setOpen(false)}
>
立即报名
</Link>
<button
type="button"
onClick={() => setOpen(false)}
className="rounded-xl border border-[var(--border)] px-6 py-3 text-sm transition hover:bg-[var(--muted)]"
>
稍后再说
</button>
</div>
</div>
)}
</div>
</div>
)}
</>
);
}