diff --git a/frontend/app/[locale]/leaderboard/page.tsx b/frontend/app/[locale]/leaderboard/page.tsx index af5fff5e..ffedf790 100644 --- a/frontend/app/[locale]/leaderboard/page.tsx +++ b/frontend/app/[locale]/leaderboard/page.tsx @@ -1,5 +1,11 @@ import { getLeaderboardData } from '@/db/queries/leaderboard'; import LeaderboardClient from '@/components/leaderboard/LeaderboardClient'; +import { Metadata } from 'next'; + +export const metadata: Metadata = { + title: 'Leaderboard | DevLovers', + description: 'Top performers of the community', +}; export const revalidate = 3600; diff --git a/frontend/components/header/AppMobileMenu.tsx b/frontend/components/header/AppMobileMenu.tsx index 46afcb3b..74fa8aea 100644 --- a/frontend/components/header/AppMobileMenu.tsx +++ b/frontend/components/header/AppMobileMenu.tsx @@ -54,7 +54,7 @@ export function AppMobileMenu({ className="flex h-9 w-9 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-secondary hover:text-foreground" aria-label="Toggle menu" aria-expanded={open ? 'true' : 'false'} - aria-controls="app-mobile-nav" + aria-controls={open ? 'app-mobile-nav' : undefined} > {open ? : } diff --git a/frontend/components/leaderboard/LeaderboardClient.tsx b/frontend/components/leaderboard/LeaderboardClient.tsx index a3a90b96..042f5ee2 100644 --- a/frontend/components/leaderboard/LeaderboardClient.tsx +++ b/frontend/components/leaderboard/LeaderboardClient.tsx @@ -1,11 +1,9 @@ 'use client'; -import { useState } from 'react'; -import { LeaderboardTabs } from './LeaderboardTabs'; +import { useTranslations } from 'next-intl'; import { LeaderboardPodium } from './LeaderboardPodium'; import { LeaderboardTable } from './LeaderboardTable'; import { User } from './types'; -import { Trophy } from 'lucide-react'; interface LeaderboardClientProps { initialUsers: User[]; @@ -14,7 +12,7 @@ interface LeaderboardClientProps { export default function LeaderboardClient({ initialUsers, }: LeaderboardClientProps) { - const [activeTab, setActiveTab] = useState('Overall'); + const t = useTranslations('leaderboard'); const usersWithPoints = initialUsers.filter(user => user.points > 0); const hasResults = usersWithPoints.length > 0; @@ -32,60 +30,60 @@ export default function LeaderboardClient({ className="pointer-events-none absolute inset-0 opacity-70 -z-10" aria-hidden="true" > -
-
-
+
+
+
-
-
-

-

+
+
); } diff --git a/frontend/components/leaderboard/LeaderboardPodium.tsx b/frontend/components/leaderboard/LeaderboardPodium.tsx index 41f51ae6..a149290d 100644 --- a/frontend/components/leaderboard/LeaderboardPodium.tsx +++ b/frontend/components/leaderboard/LeaderboardPodium.tsx @@ -2,14 +2,17 @@ import Image from 'next/image'; import { Crown } from 'lucide-react'; +import { useTranslations } from 'next-intl'; import { cn } from '@/lib/utils'; import { User } from './types'; export function LeaderboardPodium({ topThree }: { topThree: User[] }) { + const t = useTranslations('leaderboard'); + return (
    {topThree.map(user => { if (!user) return null; @@ -21,95 +24,81 @@ export function LeaderboardPodium({ topThree }: { topThree: User[] }) {
  1. -
    -
    +
    +
    {isFirst && (
    -
    -

    +
    +
    {user.username} -

    -
    - {user.points}{' '} - - pts - +
    +
    +
    + {user.points}{' '} + {t('pts')} +
    +
); })} diff --git a/frontend/components/leaderboard/LeaderboardTable.tsx b/frontend/components/leaderboard/LeaderboardTable.tsx index 99e84e56..d052c01e 100644 --- a/frontend/components/leaderboard/LeaderboardTable.tsx +++ b/frontend/components/leaderboard/LeaderboardTable.tsx @@ -1,71 +1,77 @@ 'use client'; import { TrendingUp } from 'lucide-react'; +import { useTranslations } from 'next-intl'; import { User } from './types'; export function LeaderboardTable({ users }: { users: User[] }) { + const t = useTranslations('leaderboard'); + return ( -
+
- + - + {users.map(user => ( - - ))} diff --git a/frontend/components/leaderboard/LeaderboardTabs.tsx b/frontend/components/leaderboard/LeaderboardTabs.tsx deleted file mode 100644 index 40b8086b..00000000 --- a/frontend/components/leaderboard/LeaderboardTabs.tsx +++ /dev/null @@ -1,44 +0,0 @@ -'use client'; - -import { cn } from '@/lib/utils'; - -interface LeaderboardTabsProps { - activeTab: string; - onTabChange: (t: string) => void; -} - -export function LeaderboardTabs({ - activeTab, - onTabChange, -}: LeaderboardTabsProps) { - const tabs = ['Overall', 'Day 1', 'Day 2', 'Day 3', 'Day 4']; - - return ( - - ); -} diff --git a/frontend/components/shared/CookieBanner.tsx b/frontend/components/shared/CookieBanner.tsx index 8f6acdd3..a777ff33 100644 --- a/frontend/components/shared/CookieBanner.tsx +++ b/frontend/components/shared/CookieBanner.tsx @@ -44,9 +44,9 @@ export function CookieBanner() {
-

+
{t('title')} -

+

{t('description')}{' '}

- Leaderboard ranking for other participants - {t('tableCaption')}
- Rank + {t('rank')} - UserName + {t('user')} - Points + {t('score')}
+ {user.rank}
+
- + {user.username} - - + {user.change > 0 && ( + + + )}
- {user.points.toLocaleString()} + + + {user.points.toLocaleString()} +