added tier badge loading fallback

This commit is contained in:
rgrgogu
2026-07-31 00:35:45 +08:00
parent 975b16b8c6
commit d97946463d
+15 -2
View File
@@ -152,12 +152,20 @@ function ClientNav() {
// Caches the resolved stream URL per asset_id — avoids re-hitting /media/token
// for the same asset on re-renders. Token TTL is 4h so safe within a session.
const badgeTokenCache = useRef({})
// Starts false on every mount (incl. full page reloads) so the tier badge
// shows a gray skeleton instead of flashing "Free" before /tiers/me resolves —
// myTier stays null for genuinely-free users too, so it can't be used as the signal.
const [tierReady, setTierReady] = useState(false)
useEffect(() => {
if (!user) return;
if (achievements.length === 0) getAchievements();
if (!myTier) getMyTier();
if (tierCategories.length === 0) getTierCategories();
if (!myTier) {
getMyTier().finally(() => setTierReady(true));
} else {
setTierReady(true);
}
}, [user]);
// ── Derive directly from auth user — same pattern as admin UserMenu ──────
@@ -247,7 +255,12 @@ function ClientNav() {
</svg>
</div>
<div id="name" className="lg:-ml-1 font-medium text-sm flex items-center gap-2">
{tierBadge && (
{!tierReady ? (
<div className="xs:hidden md:inline-flex items-center gap-1 px-2.5 py-0.5 rounded-full text-xs font-semibold bg-muted animate-pulse">
<div className="size-3 rounded-full bg-muted-foreground/30" />
<span className="text-transparent select-none">Free</span>
</div>
) : tierBadge && (
<div className={`xs:hidden md:inline-flex items-center gap-1 px-2.5 py-0.5 rounded-full text-xs font-semibold ${tierBadge.cls}`}>
{badgeImgUrl
? <img src={badgeImgUrl} className="size-3.5 rounded-full object-cover" />