Spaces:
Runtime error
Runtime error
File size: 5,549 Bytes
5c920e9 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | "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>
);
}
|