Spaces:
Runtime error
Runtime error
| "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> | |
| ); | |
| } | |