Skip to content

Commit c6e49ee

Browse files
authored
Merge branch 'leaderboard-temp' into order-top
2 parents 09c13fc + 287869c commit c6e49ee

6 files changed

Lines changed: 33 additions & 12 deletions

File tree

.env.example

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
GITHUB_TOKEN=your_github_token_here
2+
# Public GitHub repository URL shown by the app.
3+
# If omitted, the app falls back to https://github.com/O2sa/DevImpact
4+
NEXT_PUBLIC_GITHUB_REPO_URL=your_github_repo_url_here
25

36
# Redis caching (optional — strongly recommended for leaderboard performance)
47
# Use either redis://localhost:6379 or include password if enabled: redis://:password@localhost:6379

components/app-header.tsx

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import Link from "next/link";
22
import { BrandLogo } from "@/components/brand-logo";
33
import { LanguageSwitcher } from "@/components/language-switcher";
44
import { ThemeToggle } from "@/components/theme-toggle";
5+
import { GithubLink } from "@/components/github-link";
56

67
export function AppHeader() {
78
return (
@@ -11,16 +12,11 @@ export function AppHeader() {
1112
<BrandLogo priority size="md" />
1213
</Link>
1314

14-
<nav className="flex items-center gap-4">
15-
<Link
16-
href="/leaderboard"
17-
className="hidden rounded-full border border-border px-3 py-1 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground sm:inline-flex"
18-
>
19-
Leaderboard
20-
</Link>
15+
<div className="flex gap-4 [&>*:last-child]:-ml-4">
2116
<LanguageSwitcher />
2217
<ThemeToggle />
23-
</nav>
18+
<GithubLink variant="compact" />
19+
</div>
2420
</div>
2521
</header>
2622
);

components/github-link.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ type GithubLinkProps = {
1111
export function GithubLink({ variant = "compact" }: GithubLinkProps) {
1212
const isProminent = variant === "prominent";
1313

14+
const githubRepoUrl= process.env.NEXT_PUBLIC_GITHUB_REPO_URL || "https://github.com/O2sa/DevImpact";
1415
return (
1516
<a
16-
href="https://github.com/O2sa/DevImpact"
17+
href={githubRepoUrl}
1718
target="_blank"
1819
rel="noopener noreferrer"
1920
aria-label="GitHub repository"

components/theme-toggle.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { useTheme } from "next-themes";
55
import { useSyncExternalStore } from "react";
66
import { useTranslation } from "./language-provider";
77
import { Button } from "./ui/button";
8-
import { GithubLink } from "./github-link";
98

109
const emptySubscribe = () => () => { };
1110

@@ -81,7 +80,6 @@ export function ThemeToggle() {
8180
>
8281
{mounted && current === "dark" ? <Sun size={16} /> : <Moon size={16} />}
8382
</Button>
84-
<GithubLink variant="compact" />
8583
</div>
8684
);
8785
}

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
"test": "vitest",
1111
"test:watch": "vitest --watch",
1212
"redis:up": "docker compose up -d redis",
13-
"redis:down": "docker compose stop redis"
13+
"redis:down": "docker compose stop redis",
14+
"validate-locales": "node scripts/validate-locales.js"
1415
},
1516
"dependencies": {
1617
"@octokit/graphql": "^9.0.3",

scripts/validate-locales.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/* eslint-disable @typescript-eslint/no-require-imports */
2+
const fs = require('fs');
3+
const path = require('path');
4+
5+
const localesDir = path.join(__dirname, '..', 'locales');
6+
const enKeys = Object.keys(JSON.parse(fs.readFileSync(path.join(localesDir, 'en.json'), 'utf8'))).sort();
7+
8+
let hasError = false;
9+
10+
fs.readdirSync(localesDir).forEach(file => {
11+
if (file === 'en.json') return;
12+
13+
const fileKeys = Object.keys(JSON.parse(fs.readFileSync(path.join(localesDir, file), 'utf8'))).sort();
14+
const missing = enKeys.filter(k => !fileKeys.includes(k));
15+
const extra = fileKeys.filter(k => !enKeys.includes(k));
16+
if (missing.length || extra.length) {
17+
hasError = true;
18+
console.error(`${file}: ${missing.length ? `Missing keys: ${missing.join(', ')}` : ''}${extra.length ? ` Extra keys: ${extra.join(', ')}` : ''}`);
19+
}
20+
});
21+
22+
process.exit(hasError ? 1 : 0);

0 commit comments

Comments
 (0)