Skip to content

Commit db521c2

Browse files
authored
Merge pull request #11 from bokiko/auto/improve-2026-03-20-bugfix
fix: add per-page metadata to dashboard, download, and community pages
2 parents e8ec5a5 + 4824f68 commit db521c2

7 files changed

Lines changed: 962 additions & 910 deletions

File tree

IMPROVEMENTS.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,33 @@
11
# PingDiff Improvement Log
22

3+
## 2026-03-20 — Bug Fix: Per-page metadata for dashboard, download, and community
4+
5+
All three main pages used `"use client"` at the top level, which blocks Next.js from reading the
6+
`metadata` export. Every page fell back to the generic homepage title and description — so sharing
7+
any page on Discord, Twitter, or iMessage showed "PingDiff - Test Your Game Server Connection"
8+
regardless of which page it was. The `template: "%s | PingDiff"` in `layout.tsx` was dead code.
9+
10+
Fixed by splitting each page into a thin server wrapper (`page.tsx`, exports metadata) and a
11+
client component (`*Client.tsx`, holds all interactive state). No logic changed — pure structural
12+
refactor following the standard App Router pattern. Each page now has a distinct title,
13+
description, and og:title/og:description for accurate social previews.
14+
15+
**Files changed:** `web/src/app/dashboard/page.tsx`, `web/src/app/dashboard/DashboardClient.tsx` (new), `web/src/app/download/page.tsx`, `web/src/app/download/DownloadClient.tsx` (new), `web/src/app/community/page.tsx`, `web/src/app/community/CommunityClient.tsx` (new)
16+
**Lines:** +934 / -890
17+
18+
## 2026-03-20 — Accessibility: ARIA labels, table semantics, and skip navigation
19+
20+
Comprehensive a11y pass across the dashboard, navbar, and secondary pages. The site had no named navigation landmark, no skip links on 3 of 4 pages, tables without column scope attributes, charts completely invisible to assistive technology, and stat cards that conveyed quality purely through color (WCAG 1.4.1 violation). All fixed without new dependencies.
21+
22+
Dashboard: skip link + main-content anchor, role="region" on stats grid, aria-label on each stat card with text description, aria-hidden on decorative icons, role="img" + aria-label on both charts, aria-label on table element, scope="col" on all th elements, time element for timestamps, aria-label on ping/loss cells so quality is communicated in text not just color.
23+
24+
Navbar: aria-label="Main navigation" on nav element, aria-haspopup on mobile toggle, role="menu" on mobile menu container.
25+
26+
Community and Download pages: both were missing skip-to-content links and main-content anchor targets entirely.
27+
28+
**Files changed:** `web/src/app/dashboard/page.tsx`, `web/src/components/Navbar.tsx`, `web/src/app/community/page.tsx`, `web/src/app/download/page.tsx`
29+
**Lines:** +64 / -30
30+
331
## 2026-03-19 — Performance: Memoize dashboard derived state
432

533
All derived values on the dashboard (filteredResults, avgPing, avgPacketLoss, avgJitter, regions, chartData, serverChartData) were being recomputed inline on every React render — including renders triggered by unrelated state changes like the loading flag toggling off. Wrapped each value in useMemo with the tightest possible dependency array, eliminating 5 O(n) reduce passes and 2 groupBy passes on every extraneous render. At current scale the savings are modest; at the 500-1000 result range the dashboard would hit without this change the difference is measurable. The memoized structure also makes data dependencies explicit and auditable at a glance.
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
"use client";
2+
3+
import { MessageSquare, ThumbsUp, Users, Construction } from "lucide-react";
4+
import { Navbar } from "@/components/Navbar";
5+
import { Footer } from "@/components/Footer";
6+
7+
export default function CommunityClient() {
8+
return (
9+
<div className="min-h-screen">
10+
<a href="#main-content" className="skip-to-content focus-ring">
11+
Skip to main content
12+
</a>
13+
<Navbar />
14+
15+
<main id="main-content" className="max-w-6xl mx-auto px-4 py-16">
16+
{/* Coming Soon Banner */}
17+
<div className="text-center mb-16">
18+
<div className="inline-flex items-center justify-center w-20 h-20 bg-yellow-500/20 rounded-2xl mb-6">
19+
<Construction className="w-10 h-10 text-yellow-500" />
20+
</div>
21+
<h1 className="text-4xl font-bold mb-4">Community Hub</h1>
22+
<p className="text-zinc-400 text-lg max-w-xl mx-auto">
23+
Share tips, compare results, and help other players find the best servers.
24+
</p>
25+
<div className="mt-6 inline-flex items-center gap-2 bg-yellow-500/10 border border-yellow-500/20 rounded-full px-4 py-2">
26+
<span className="text-yellow-400 text-sm font-medium">Coming Soon</span>
27+
</div>
28+
</div>
29+
30+
{/* Preview Features */}
31+
<div className="grid md:grid-cols-3 gap-6 mb-16">
32+
<div className="bg-zinc-900/50 border border-zinc-800 rounded-xl p-6 opacity-60">
33+
<div className="w-12 h-12 bg-blue-500/20 rounded-xl flex items-center justify-center mb-4">
34+
<MessageSquare className="w-6 h-6 text-blue-500" />
35+
</div>
36+
<h3 className="text-xl font-semibold mb-2">ISP Tips</h3>
37+
<p className="text-zinc-400">
38+
Share and discover tips for optimizing your connection based on your ISP and region.
39+
</p>
40+
</div>
41+
42+
<div className="bg-zinc-900/50 border border-zinc-800 rounded-xl p-6 opacity-60">
43+
<div className="w-12 h-12 bg-green-500/20 rounded-xl flex items-center justify-center mb-4">
44+
<ThumbsUp className="w-6 h-6 text-green-500" />
45+
</div>
46+
<h3 className="text-xl font-semibold mb-2">Upvote System</h3>
47+
<p className="text-zinc-400">
48+
Vote on the most helpful tips to surface the best advice for each region.
49+
</p>
50+
</div>
51+
52+
<div className="bg-zinc-900/50 border border-zinc-800 rounded-xl p-6 opacity-60">
53+
<div className="w-12 h-12 bg-purple-500/20 rounded-xl flex items-center justify-center mb-4">
54+
<Users className="w-6 h-6 text-purple-500" />
55+
</div>
56+
<h3 className="text-xl font-semibold mb-2">Leaderboards</h3>
57+
<p className="text-zinc-400">
58+
See the best ping results by region, ISP, and server location.
59+
</p>
60+
</div>
61+
</div>
62+
63+
{/* CTA */}
64+
<div className="text-center bg-zinc-900/50 border border-zinc-800 rounded-2xl p-8">
65+
<h2 className="text-2xl font-bold mb-4">Want to be notified when Community launches?</h2>
66+
<p className="text-zinc-400 mb-6">
67+
Star our GitHub repo to get updates on new features.
68+
</p>
69+
<a
70+
href="https://github.com/bokiko/pingdiff"
71+
target="_blank"
72+
rel="noopener noreferrer"
73+
className="inline-flex items-center gap-2 btn-primary px-6 py-3 rounded-xl font-medium"
74+
>
75+
Star on GitHub
76+
</a>
77+
</div>
78+
</main>
79+
80+
<Footer />
81+
</div>
82+
);
83+
}

web/src/app/community/page.tsx

Lines changed: 12 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,15 @@
1-
"use client";
2-
3-
import { MessageSquare, ThumbsUp, Users, Construction } from "lucide-react";
4-
import { Navbar } from "@/components/Navbar";
5-
import { Footer } from "@/components/Footer";
1+
import type { Metadata } from "next";
2+
import CommunityClient from "./CommunityClient";
3+
4+
export const metadata: Metadata = {
5+
title: "Community",
6+
description: "Share connection tips, compare ping results with other players, and find the best game servers for your region.",
7+
openGraph: {
8+
title: "PingDiff Community Hub",
9+
description: "Share connection tips, compare ping results with other players, and find the best game servers for your region.",
10+
},
11+
};
612

713
export default function CommunityPage() {
8-
return (
9-
<div className="min-h-screen">
10-
<a href="#main-content" className="skip-to-content focus-ring">
11-
Skip to main content
12-
</a>
13-
<Navbar />
14-
15-
<main id="main-content" className="max-w-6xl mx-auto px-4 py-16">
16-
{/* Coming Soon Banner */}
17-
<div className="text-center mb-16">
18-
<div className="inline-flex items-center justify-center w-20 h-20 bg-yellow-500/20 rounded-2xl mb-6">
19-
<Construction className="w-10 h-10 text-yellow-500" />
20-
</div>
21-
<h1 className="text-4xl font-bold mb-4">Community Hub</h1>
22-
<p className="text-zinc-400 text-lg max-w-xl mx-auto">
23-
Share tips, compare results, and help other players find the best servers.
24-
</p>
25-
<div className="mt-6 inline-flex items-center gap-2 bg-yellow-500/10 border border-yellow-500/20 rounded-full px-4 py-2">
26-
<span className="text-yellow-400 text-sm font-medium">Coming Soon</span>
27-
</div>
28-
</div>
29-
30-
{/* Preview Features */}
31-
<div className="grid md:grid-cols-3 gap-6 mb-16">
32-
<div className="bg-zinc-900/50 border border-zinc-800 rounded-xl p-6 opacity-60">
33-
<div className="w-12 h-12 bg-blue-500/20 rounded-xl flex items-center justify-center mb-4">
34-
<MessageSquare className="w-6 h-6 text-blue-500" />
35-
</div>
36-
<h3 className="text-xl font-semibold mb-2">ISP Tips</h3>
37-
<p className="text-zinc-400">
38-
Share and discover tips for optimizing your connection based on your ISP and region.
39-
</p>
40-
</div>
41-
42-
<div className="bg-zinc-900/50 border border-zinc-800 rounded-xl p-6 opacity-60">
43-
<div className="w-12 h-12 bg-green-500/20 rounded-xl flex items-center justify-center mb-4">
44-
<ThumbsUp className="w-6 h-6 text-green-500" />
45-
</div>
46-
<h3 className="text-xl font-semibold mb-2">Upvote System</h3>
47-
<p className="text-zinc-400">
48-
Vote on the most helpful tips to surface the best advice for each region.
49-
</p>
50-
</div>
51-
52-
<div className="bg-zinc-900/50 border border-zinc-800 rounded-xl p-6 opacity-60">
53-
<div className="w-12 h-12 bg-purple-500/20 rounded-xl flex items-center justify-center mb-4">
54-
<Users className="w-6 h-6 text-purple-500" />
55-
</div>
56-
<h3 className="text-xl font-semibold mb-2">Leaderboards</h3>
57-
<p className="text-zinc-400">
58-
See the best ping results by region, ISP, and server location.
59-
</p>
60-
</div>
61-
</div>
62-
63-
{/* CTA */}
64-
<div className="text-center bg-zinc-900/50 border border-zinc-800 rounded-2xl p-8">
65-
<h2 className="text-2xl font-bold mb-4">Want to be notified when Community launches?</h2>
66-
<p className="text-zinc-400 mb-6">
67-
Star our GitHub repo to get updates on new features.
68-
</p>
69-
<a
70-
href="https://github.com/bokiko/pingdiff"
71-
target="_blank"
72-
rel="noopener noreferrer"
73-
className="inline-flex items-center gap-2 btn-primary px-6 py-3 rounded-xl font-medium"
74-
>
75-
Star on GitHub
76-
</a>
77-
</div>
78-
</main>
79-
80-
<Footer />
81-
</div>
82-
);
14+
return <CommunityClient />;
8315
}

0 commit comments

Comments
 (0)