63 lines
2.5 KiB
TypeScript
63 lines
2.5 KiB
TypeScript
"use client";
|
||
|
||
import { PropsWithChildren, useState } from "react";
|
||
import { motion, AnimatePresence } from "framer-motion";
|
||
import { useDeveloperFlags } from "@/components/developer-flags-provider";
|
||
|
||
export function HiddenEasterEggTrigger({ children }: PropsWithChildren) {
|
||
const [clickCount, setClickCount] = useState(0);
|
||
const [show, setShow] = useState(false);
|
||
const { flags, setFlag } = useDeveloperFlags();
|
||
|
||
return (
|
||
<>
|
||
<button
|
||
onClick={() => {
|
||
const next = clickCount + 1;
|
||
setClickCount(next);
|
||
if (next >= 10) {
|
||
setShow(true);
|
||
setClickCount(0);
|
||
}
|
||
}}
|
||
>
|
||
{children}
|
||
</button>
|
||
<AnimatePresence>
|
||
{show && (
|
||
<motion.div
|
||
initial={{ opacity: 0 }}
|
||
animate={{ opacity: 1 }}
|
||
exit={{ opacity: 0 }}
|
||
className="fixed inset-0 z-50 grid place-items-center bg-slate-950/60 px-4"
|
||
onClick={() => setShow(false)}
|
||
>
|
||
<motion.div
|
||
initial={{ y: 12, opacity: 0 }}
|
||
animate={{ y: 0, opacity: 1 }}
|
||
className="w-full max-w-sm rounded-2xl border border-cyan-300/30 bg-slate-900/90 p-6 backdrop-blur-lg"
|
||
>
|
||
<p className="text-lg font-semibold text-cyan-300">开发者控制台</p>
|
||
<p className="mt-2 text-sm text-slate-300">仅开发者可见的开关,不对普通用户展示。</p>
|
||
<div className="mt-4 space-y-2 text-sm">
|
||
<label className="flex items-center justify-between rounded-lg border border-white/10 px-3 py-2">
|
||
运营弹层
|
||
<input type="checkbox" checked={flags.opsPopup} onChange={(e) => setFlag("opsPopup", e.target.checked)} />
|
||
</label>
|
||
<label className="flex items-center justify-between rounded-lg border border-white/10 px-3 py-2">
|
||
A/B Banner
|
||
<input type="checkbox" checked={flags.abBanner} onChange={(e) => setFlag("abBanner", e.target.checked)} />
|
||
</label>
|
||
<label className="flex items-center justify-between rounded-lg border border-white/10 px-3 py-2">
|
||
事件调试面板
|
||
<input type="checkbox" checked={flags.eventDebug} onChange={(e) => setFlag("eventDebug", e.target.checked)} />
|
||
</label>
|
||
</div>
|
||
</motion.div>
|
||
</motion.div>
|
||
)}
|
||
</AnimatePresence>
|
||
</>
|
||
);
|
||
}
|