89 lines
3.0 KiB
TypeScript
89 lines
3.0 KiB
TypeScript
"use client";
|
||
|
||
import Link from "next/link";
|
||
import { useMemo } from "react";
|
||
import { useTrack } from "@/hooks/use-track";
|
||
import { TRACKING_EVENTS } from "@/lib/tracking-events";
|
||
import { useAuth } from "@/components/auth-provider";
|
||
|
||
export function AccessGate({ slug, children }: { slug: string; children: React.ReactNode }) {
|
||
const { session, loginAs, setAccessLevel } = useAuth();
|
||
const { track } = useTrack();
|
||
const state = session.accessLevel;
|
||
|
||
const hint = useMemo(() => {
|
||
if (state === "vip") return "当前状态:VIP。可访问全部下载渠道与历史版本包。";
|
||
if (state === "unlocked") return "当前状态:已解锁。可访问部分高级下载源。";
|
||
return "当前状态:游客。请先解锁或开通 VIP。";
|
||
}, [state]);
|
||
|
||
return (
|
||
<section className="card-glass space-y-4">
|
||
<div className="flex flex-wrap items-center justify-between gap-3">
|
||
<div>
|
||
<h3 className="text-lg font-semibold">下载权限门禁</h3>
|
||
<p className="text-sm text-slate-300">{hint}</p>
|
||
</div>
|
||
<div className="flex gap-2">
|
||
<button
|
||
className={`pill ${state === "guest" ? "pill-active" : ""}`}
|
||
onClick={() => setAccessLevel("guest")}
|
||
>
|
||
游客
|
||
</button>
|
||
<button
|
||
className={`pill ${state === "unlocked" ? "pill-active" : ""}`}
|
||
onClick={() => setAccessLevel("unlocked")}
|
||
>
|
||
已解锁
|
||
</button>
|
||
<button
|
||
className={`pill ${state === "vip" ? "pill-active" : ""}`}
|
||
onClick={() => setAccessLevel("vip")}
|
||
>
|
||
VIP
|
||
</button>
|
||
</div>
|
||
</div>
|
||
{!session.isLoggedIn && (
|
||
<div className="rounded-2xl border border-cyan-300/20 bg-cyan-400/10 p-3 text-sm text-slate-100">
|
||
<p>当前未登录,建议先登录后再解锁下载权限。</p>
|
||
<button
|
||
className="cta-sub mt-2"
|
||
onClick={() => {
|
||
loginAs();
|
||
track(TRACKING_EVENTS.ctaClick, { slug, target: "login_quick" });
|
||
}}
|
||
>
|
||
一键模拟登录
|
||
</button>
|
||
</div>
|
||
)}
|
||
|
||
{state === "guest" && (
|
||
<div className="rounded-2xl border border-amber-300/30 bg-amber-400/10 p-4 text-sm text-amber-100">
|
||
<p>你还未解锁当前资源。</p>
|
||
<div className="mt-3 flex flex-wrap gap-2">
|
||
<Link
|
||
href="/unlock"
|
||
onClick={() => track(TRACKING_EVENTS.ctaClick, { slug, target: "unlock_center", gate: "guest" })}
|
||
className="cta-sub"
|
||
>
|
||
去解锁中心
|
||
</Link>
|
||
<Link
|
||
href={`/checkout?plan=pro&slug=${slug}`}
|
||
onClick={() => track(TRACKING_EVENTS.ctaClick, { slug, target: "checkout", gate: "guest" })}
|
||
className="cta-main"
|
||
>
|
||
开通 VIP
|
||
</Link>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{state !== "guest" && children}
|
||
</section>
|
||
);
|
||
}
|