84 lines
2.7 KiB
TypeScript
84 lines
2.7 KiB
TypeScript
"use client";
|
|
|
|
import { useState, useCallback } from "react";
|
|
import { Users, QrCode, LogOut } from "lucide-react";
|
|
import { motion, AnimatePresence } from "framer-motion";
|
|
import QrInviteModal from "./QrInviteModal";
|
|
|
|
interface TopNavProps {
|
|
roomId: string;
|
|
userCount: number;
|
|
onExit?: () => void;
|
|
}
|
|
|
|
export default function TopNav({ roomId, userCount, onExit }: TopNavProps) {
|
|
const [toast, setToast] = useState("");
|
|
const [showQr, setShowQr] = useState(false);
|
|
|
|
const showToast = useCallback((msg: string) => {
|
|
setToast(msg);
|
|
setTimeout(() => setToast(""), 2200);
|
|
}, []);
|
|
|
|
return (
|
|
<>
|
|
<nav className="relative z-10 flex h-14 items-center justify-between px-4">
|
|
<div className="w-24">
|
|
<button
|
|
onClick={() => setShowQr(true)}
|
|
className="flex items-center gap-1 rounded-full bg-emerald-50 px-2.5 py-1 text-xs font-semibold text-emerald-600 transition-colors active:bg-emerald-100"
|
|
>
|
|
<QrCode size={13} />
|
|
邀请饭搭子
|
|
</button>
|
|
</div>
|
|
|
|
<h1 className="text-center text-base font-bold tracking-tight text-zinc-900">
|
|
<span className="block leading-tight">NoWhatever</span>
|
|
<span className="block text-[10px] font-medium tracking-widest text-zinc-400">
|
|
别说随便
|
|
</span>
|
|
</h1>
|
|
|
|
<div className="flex items-center justify-end gap-1.5 text-xs text-zinc-500">
|
|
<span className="rounded-full bg-zinc-100 px-2 py-0.5 font-medium">
|
|
{roomId}
|
|
</span>
|
|
<div className="flex items-center gap-0.5">
|
|
<Users size={13} />
|
|
<span className="font-semibold text-emerald-500">{userCount}</span>
|
|
</div>
|
|
<button
|
|
onClick={onExit}
|
|
className="ml-1 flex items-center justify-center rounded-full p-1 text-zinc-400 transition-colors active:bg-zinc-100 active:text-zinc-600"
|
|
aria-label="退出房间"
|
|
>
|
|
<LogOut size={15} />
|
|
</button>
|
|
</div>
|
|
</nav>
|
|
|
|
<AnimatePresence>
|
|
{toast && (
|
|
<motion.div
|
|
className="fixed left-1/2 top-16 z-50 -translate-x-1/2 rounded-xl bg-zinc-900 px-4 py-2.5 text-xs font-medium text-white shadow-lg"
|
|
initial={{ opacity: 0, y: -12, x: "-50%" }}
|
|
animate={{ opacity: 1, y: 0, x: "-50%" }}
|
|
exit={{ opacity: 0, y: -12, x: "-50%" }}
|
|
transition={{ type: "spring", stiffness: 400, damping: 25 }}
|
|
>
|
|
{toast}
|
|
</motion.div>
|
|
)}
|
|
</AnimatePresence>
|
|
|
|
<QrInviteModal
|
|
open={showQr}
|
|
onClose={() => setShowQr(false)}
|
|
roomId={roomId}
|
|
onToast={showToast}
|
|
/>
|
|
</>
|
|
);
|
|
}
|