fix(ux): Batch F part 3 — bounty ranks, Lab tab grid, contacts search

- Bounty leaderboards no longer slice to top 50 before computing the current
  user's rank (anyone outside the top 50 never saw their position), and each row
  no longer prints the count twice
- Lab craft tabs: 4-up grid (11 tabs were laid out 5-across, leaving a lone
  'Judges' orphan row); stale comment corrected
- Contacts search placeholder now says it filters by npub (it never matched the
  displayed names)
This commit is contained in:
SkateSpots 2026-09-26 18:54:55 +07:00
parent a464913d6f
commit 760bc9b82c
3 changed files with 10 additions and 14 deletions

View file

@ -100,8 +100,8 @@ function LeaderboardEntry({
<Badge className="bg-[#ff0040] text-white text-[10px] px-1.5 py-0">You</Badge>
)}
</div>
<p className="text-xs text-gray-500">
{count} {getTypeLabel()}
<p className="text-xs text-gray-500 capitalize">
{getTypeLabel()}
</p>
</div>
@ -153,8 +153,7 @@ export default function BountyLeaderboardPage() {
return Object.entries(countByPubkey)
.map(([pubkey, count]) => ({ pubkey, count }))
.sort((a, b) => b.count - a.count)
.slice(0, 50);
.sort((a, b) => b.count - a.count);
}, [shops]);
// Calculate spot leaderboard
@ -168,8 +167,7 @@ export default function BountyLeaderboardPage() {
return Object.entries(countByPubkey)
.map(([pubkey, count]) => ({ pubkey, count }))
.sort((a, b) => b.count - a.count)
.slice(0, 50);
.sort((a, b) => b.count - a.count);
}, [spots]);
// Combined leaderboard (total contributions)
@ -190,8 +188,7 @@ export default function BountyLeaderboardPage() {
return Object.entries(combined)
.map(([pubkey, data]) => ({ pubkey, ...data }))
.sort((a, b) => b.total - a.total)
.slice(0, 50);
.sort((a, b) => b.total - a.total);
}, [shops, spots]);
// Find user's rank

View file

@ -240,7 +240,7 @@ export default function ContactsPage() {
type="text"
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Paste an npub to filter…"
placeholder="Filter by npub…"
className="h-10 w-full rounded-xl border border-white/10 bg-white/5 pl-9 pr-9 text-sm text-white placeholder:text-gray-600 focus:border-teal-500/50 focus:outline-none"
/>
{query && (

View file

@ -448,11 +448,10 @@ function LabToolbar({
return (
<div className="sticky top-14 md:top-16 z-30 bg-black/95 backdrop-blur border-b border-white/5 -mx-4 px-4 py-3 space-y-2.5">
{/* Tab row — a wrapping grid so every craft is visible at a glance with
no horizontal scrolling. 10 crafts lay out as two tidy rows of five on
phones, and flex to a single line on wide screens. Icon-over-label
stack keeps each tab compact but tappable; a count badge floats in
the corner. */}
<div className="grid grid-cols-5 gap-1.5 sm:gap-2 md:flex md:flex-wrap -mx-1 px-1">
no horizontal scrolling. 11 crafts lay out 4-4-3 on phones, and flex
to a single line on wide screens. Icon-over-label stack keeps each tab
compact but tappable; a count badge floats in the corner. */}
<div className="grid grid-cols-4 gap-1.5 sm:gap-2 md:flex md:flex-wrap -mx-1 px-1">
{tabs.map(({ key, label, icon: Icon }) => {
const isActive = serviceType === key;
const a = ACCENT[key];