README / components /shared /TopStatsBar.tsx
kaigiii's picture
Deploy Learn8 Demo Space
5c920e9
"use client";
import React, { useState } from "react";
import Link from "next/link";
import ProfileModal from "./ProfileModal";
import useUserStore from "@/stores/useUserStore";
interface TopStatsBarProps {
backHref?: string;
pageTitle?: string;
}
export default function TopStatsBar({ backHref, pageTitle }: TopStatsBarProps = {}) {
const [profileOpen, setProfileOpen] = useState(false);
const { streak, gems, level } = useUserStore();
/* Compute rank label from level */
const rankLabel =
level >= 15 ? "Diamond Rank" :
level >= 10 ? "Platinum Rank" :
level >= 7 ? "Gold Rank" :
level >= 4 ? "Silver Rank" :
"Bronze Rank";
return (
<>
<nav className="sticky top-0 z-50 flex items-center justify-between px-4 md:px-8 py-3 bg-white/70 backdrop-blur-lg border-b border-white/40 shadow-sm">
{/* Left: back arrow or avatar + logo */}
<div className="flex items-center gap-3 relative">
{backHref ? (
/* Back arrow mode (e.g. store, map) */
<>
<Link
href={backHref}
className="h-10 w-10 rounded-full flex items-center justify-center hover:bg-brand-gray-50 transition text-brand-gray-600"
>
<svg viewBox="0 0 24 24" className="h-6 w-6" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
<path d="M15 18l-6-6 6-6" />
</svg>
</Link>
<OwlLogoSmall />
<span className="font-heading text-xl font-extrabold text-brand-gray-700">
{pageTitle}
</span>
</>
) : (
/* Default avatar + logo mode */
<>
<button
onClick={() => setProfileOpen(true)}
className="relative h-11 w-11 rounded-full overflow-hidden border-2 border-brand-teal shadow-md hover:shadow-lg transition"
>
<MascotAvatar />
</button>
<Link href="/home" className="flex items-center gap-2">
<span className="font-heading text-xl font-extrabold text-brand-teal hidden sm:inline">
Learn8
</span>
</Link>
</>
)}
</div>
{/* Right: stats */}
<div className="flex items-center gap-4 md:gap-6">
{/* Streak */}
<div className="flex items-center gap-1.5">
<span className="text-lg">πŸ”₯</span>
<span className="font-heading font-bold text-brand-gray-700 text-sm md:text-base">
{streak} Days
</span>
</div>
{/* Gems */}
<Link
href="/store"
className="flex items-center gap-1.5 hover:opacity-80 transition"
>
<span className="text-lg">πŸ’Ž</span>
<span className="font-heading font-bold text-brand-gray-700 text-sm md:text-base">
{gems.toLocaleString()}
</span>
</Link>
{/* Rank badge */}
<div className="flex items-center gap-1.5">
<div className="h-8 w-8 rounded-full bg-gradient-to-br from-yellow-300 to-yellow-500 flex items-center justify-center shadow-md">
<span className="font-heading font-extrabold text-white text-xs">
{level}
</span>
</div>
<span className="font-heading font-bold text-brand-gray-700 text-sm md:text-base hidden md:inline">
{rankLabel}
</span>
</div>
</div>
</nav>
{/* Profile modal */}
{profileOpen && (
<ProfileModal onClose={() => setProfileOpen(false)} />
)}
</>
);
}
/* ── Small mascot avatar ── */
function MascotAvatar() {
return (
<svg viewBox="0 0 64 64" className="h-full w-full" fill="none">
<rect width="64" height="64" rx="32" fill="#E8F5F4" />
<ellipse cx="32" cy="36" rx="16" ry="18" fill="#C4A882" />
<ellipse cx="32" cy="34" rx="12" ry="14" fill="#E8D5B7" />
<circle cx="26" cy="29" r="5" fill="white" />
<circle cx="38" cy="29" r="5" fill="white" />
<circle cx="26" cy="29" r="5.5" fill="none" stroke="#6B6B6B" strokeWidth="1.2" />
<circle cx="38" cy="29" r="5.5" fill="none" stroke="#6B6B6B" strokeWidth="1.2" />
<line x1="31" y1="29" x2="33" y2="29" stroke="#6B6B6B" strokeWidth="1.2" />
<circle cx="27" cy="29" r="2.5" fill="#333" />
<circle cx="37" cy="29" r="2.5" fill="#333" />
<circle cx="28" cy="28" r="0.8" fill="white" />
<circle cx="38" cy="28" r="0.8" fill="white" />
<polygon points="32,33 30,36 34,36" fill="#E8734A" />
<polygon points="25,22 28,17 30,24" fill="#C4A882" />
<polygon points="39,22 36,17 34,24" fill="#C4A882" />
</svg>
);
}
/* ── Small owl logo icon ── */
function OwlLogoSmall() {
return (
<svg viewBox="0 0 32 32" className="h-8 w-8" fill="none">
<circle cx="16" cy="16" r="15" fill="#7AC7C4" opacity="0.2" />
<ellipse cx="16" cy="18" rx="9" ry="10" fill="#C4A882" />
<ellipse cx="16" cy="17" rx="7" ry="8" fill="#E8D5B7" />
<circle cx="13" cy="14" r="3" fill="white" />
<circle cx="19" cy="14" r="3" fill="white" />
<circle cx="13.5" cy="14" r="1.5" fill="#333" />
<circle cx="18.5" cy="14" r="1.5" fill="#333" />
<polygon points="16,16 14.5,18 17.5,18" fill="#E8734A" />
</svg>
);
}