Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions IMPROVEMENTS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# PingDiff Improvement Log

## 2026-03-19 — Accessibility: Site-wide accessibility improvements

Accessibility pass across all pages. Every page now has consistent skip-to-content
navigation, active nav state announced to screen readers, major sections labelled as
landmarks, chart regions wrapped with accessible roles, table headers scoped, decorative
icons hidden from assistive tech, and a sr-only utility added to globals.css.

**Files changed:** `web/src/app/globals.css`, `web/src/components/Navbar.tsx`,
`web/src/app/page.tsx`, `web/src/app/community/page.tsx`,
`web/src/app/dashboard/page.tsx`, `web/src/app/download/page.tsx`
**Lines:** +57 / -27

## 2026-03-19 — New Feature: Date range filter and CSV export for dashboard

Added two practical dashboard improvements with no new dependencies and no API changes.
Expand Down
13 changes: 9 additions & 4 deletions web/src/app/community/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@ import { Footer } from "@/components/Footer";
export default function CommunityPage() {
return (
<div className="min-h-screen">
<a href="#main-content" className="skip-to-content focus-ring">
Skip to main content
</a>

<Navbar />

<main className="max-w-6xl mx-auto px-4 py-16">
<main id="main-content" className="max-w-6xl mx-auto px-4 py-16">
{/* Coming Soon Banner */}
<div className="text-center mb-16">
<div className="inline-flex items-center justify-center w-20 h-20 bg-yellow-500/20 rounded-2xl mb-6">
<Construction className="w-10 h-10 text-yellow-500" />
<Construction className="w-10 h-10 text-yellow-500" aria-hidden="true" />
</div>
<h1 className="text-4xl font-bold mb-4">Community Hub</h1>
<p className="text-zinc-400 text-lg max-w-xl mx-auto">
Expand All @@ -25,7 +29,8 @@ export default function CommunityPage() {
</div>

{/* Preview Features */}
<div className="grid md:grid-cols-3 gap-6 mb-16">
<section aria-labelledby="preview-features-heading" className="grid md:grid-cols-3 gap-6 mb-16">
<h2 id="preview-features-heading" className="sr-only">Upcoming community features</h2>
<div className="bg-zinc-900/50 border border-zinc-800 rounded-xl p-6 opacity-60">
<div className="w-12 h-12 bg-blue-500/20 rounded-xl flex items-center justify-center mb-4">
<MessageSquare className="w-6 h-6 text-blue-500" />
Expand Down Expand Up @@ -55,7 +60,7 @@ export default function CommunityPage() {
See the best ping results by region, ISP, and server location.
</p>
</div>
</div>
</section>

{/* CTA */}
<div className="text-center bg-zinc-900/50 border border-zinc-800 rounded-2xl p-8">
Expand Down
30 changes: 17 additions & 13 deletions web/src/app/dashboard/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -226,10 +226,14 @@ export default function DashboardPage() {

return (
<div className="min-h-screen">
<a href="#main-content" className="skip-to-content focus-ring">
Skip to main content
</a>

<Navbar />

{/* Main Content */}
<main className="max-w-6xl mx-auto px-4 py-8">
<main id="main-content" className="max-w-6xl mx-auto px-4 py-8">
<div className="flex flex-col sm:flex-row sm:justify-between sm:items-center gap-4 mb-8">
<div>
<h1 className="text-3xl font-bold">Dashboard</h1>
Expand Down Expand Up @@ -398,11 +402,11 @@ export default function DashboardPage() {
</div>

{/* Charts */}
<div className="grid md:grid-cols-2 gap-6 mb-8">
<div className="grid md:grid-cols-2 gap-6 mb-8" role="region" aria-label="Performance charts">
{/* Ping History Chart */}
<div className="bg-zinc-900 border border-zinc-800 rounded-xl p-6">
<h3 className="text-lg font-semibold mb-4">Ping History</h3>
<div className="h-64">
<h3 className="text-lg font-semibold mb-4" id="ping-history-heading">Ping History</h3>
<div className="h-64" role="img" aria-labelledby="ping-history-heading">
<ResponsiveContainer width="100%" height="100%">
<LineChart data={chartData}>
<CartesianGrid strokeDasharray="3 3" stroke="#333" />
Expand All @@ -429,8 +433,8 @@ export default function DashboardPage() {

{/* Server Comparison Chart */}
<div className="bg-zinc-900 border border-zinc-800 rounded-xl p-6">
<h3 className="text-lg font-semibold mb-4">Server Comparison</h3>
<div className="h-64">
<h3 className="text-lg font-semibold mb-4" id="server-comparison-heading">Server Comparison</h3>
<div className="h-64" role="img" aria-labelledby="server-comparison-heading">
<ResponsiveContainer width="100%" height="100%">
<BarChart data={serverChartData}>
<CartesianGrid strokeDasharray="3 3" stroke="#333" />
Expand Down Expand Up @@ -459,15 +463,15 @@ export default function DashboardPage() {
</span>
</div>
<div className="overflow-x-auto">
<table className="w-full">
<table className="w-full" aria-label="Recent ping test results">
<thead>
<tr className="text-left text-zinc-400 text-sm">
<th className="pb-4">Server</th>
<th className="pb-4">Ping</th>
<th className="pb-4">Jitter</th>
<th className="pb-4">Loss</th>
<th className="pb-4">ISP</th>
<th className="pb-4">Time</th>
<th scope="col" className="pb-4">Server</th>
<th scope="col" className="pb-4">Ping</th>
<th scope="col" className="pb-4">Jitter</th>
<th scope="col" className="pb-4">Loss</th>
<th scope="col" className="pb-4">ISP</th>
<th scope="col" className="pb-4">Time</th>
</tr>
</thead>
<tbody>
Expand Down
10 changes: 8 additions & 2 deletions web/src/app/download/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,14 @@ export default function DownloadPage() {

return (
<div className="min-h-screen">
<a href="#main-content" className="skip-to-content focus-ring">
Skip to main content
</a>

<Navbar />

{/* Main Content */}
<main className="max-w-4xl mx-auto px-4 py-16">
<main id="main-content" className="max-w-4xl mx-auto px-4 py-16">
<div className="text-center mb-12">
<h1 className="text-4xl font-bold mb-4">Download PingDiff</h1>
<p className="text-zinc-400 text-lg">
Expand Down Expand Up @@ -111,8 +115,10 @@ export default function DownloadPage() {
<a
href={release?.downloadUrl || "#"}
className={`inline-flex items-center gap-2 btn-primary px-8 py-4 rounded-xl font-semibold text-lg focus-ring ${loading ? 'opacity-50 pointer-events-none' : ''}`}
aria-label={loading ? "Loading download link" : `Download ${getFileName()} for Windows`}
aria-disabled={loading}
>
<Download className="w-5 h-5" />
<Download className="w-5 h-5" aria-hidden="true" />
{loading ? "Loading..." : `Download ${getFileName()}`}
</a>
</div>
Expand Down
13 changes: 13 additions & 0 deletions web/src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,19 @@ body {
top: 0;
}

/* Screen-reader only utility — visually hidden but accessible to assistive tech */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
}

/* Custom scrollbar */
::-webkit-scrollbar {
width: 8px;
Expand Down
16 changes: 8 additions & 8 deletions web/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export default function Home() {
href="/download"
className="inline-flex items-center justify-center gap-2 btn-primary px-8 py-4 rounded-xl font-semibold text-lg focus-ring"
>
<Download className="w-5 h-5" />
<Download className="w-5 h-5" aria-hidden="true" />
Download for Windows
</Link>
<Link
Expand Down Expand Up @@ -94,9 +94,9 @@ export default function Home() {
</section>

{/* Features Section */}
<section className="bg-zinc-900/50 py-16 md:py-24">
<section className="bg-zinc-900/50 py-16 md:py-24" aria-labelledby="features-heading">
<div className="max-w-6xl mx-auto px-4">
<h2 className="text-2xl md:text-3xl font-bold text-center mb-4">Why PingDiff?</h2>
<h2 id="features-heading" className="text-2xl md:text-3xl font-bold text-center mb-4">Why PingDiff?</h2>
<p className="text-zinc-400 text-center mb-12 max-w-2xl mx-auto">
Stop guessing. Start knowing. Get real data about your connection before every game.
</p>
Expand Down Expand Up @@ -198,9 +198,9 @@ export default function Home() {
</section>

{/* How It Works */}
<section className="py-16 md:py-24">
<section className="py-16 md:py-24" aria-labelledby="how-it-works-heading">
<div className="max-w-6xl mx-auto px-4">
<h2 className="text-2xl md:text-3xl font-bold text-center mb-4">How It Works</h2>
<h2 id="how-it-works-heading" className="text-2xl md:text-3xl font-bold text-center mb-4">How It Works</h2>
<p className="text-zinc-400 text-center mb-12">
Three simple steps to better gaming
</p>
Expand Down Expand Up @@ -240,16 +240,16 @@ export default function Home() {
</section>

{/* Supported Games */}
<section className="bg-zinc-900/50 py-16 md:py-24">
<section className="bg-zinc-900/50 py-16 md:py-24" aria-labelledby="supported-games-heading">
<div className="max-w-6xl mx-auto px-4 text-center">
<div className="inline-flex items-center gap-2 bg-blue-500/10 border border-blue-500/20 rounded-full px-4 py-2 mb-4">
<div className="inline-flex items-center gap-2 bg-blue-500/10 border border-blue-500/20 rounded-full px-4 py-2 mb-4" aria-hidden="true">
<span className="relative flex h-2 w-2">
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75"></span>
<span className="relative inline-flex rounded-full h-2 w-2 bg-green-500"></span>
</span>
<span className="text-sm text-blue-400">9 games • 141 servers worldwide</span>
</div>
<h2 className="text-2xl md:text-3xl font-bold mb-4">Supported Games</h2>
<h2 id="supported-games-heading" className="text-2xl md:text-3xl font-bold mb-4">Supported Games</h2>
<p className="text-zinc-400 mb-12">
Test your connection to your favorite games. More coming soon.
</p>
Expand Down
2 changes: 2 additions & 0 deletions web/src/components/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export function Navbar() {
className={`transition focus-ring rounded-lg px-2 py-1 ${
isActive(href) ? "text-white font-medium" : "text-zinc-400 hover:text-white"
}`}
aria-current={isActive(href) ? "page" : undefined}
>
{label}
</Link>
Expand Down Expand Up @@ -93,6 +94,7 @@ export function Navbar() {
isActive(href) ? "text-white font-medium" : "text-zinc-400 hover:text-white"
}`}
onClick={() => setMobileMenuOpen(false)}
aria-current={isActive(href) ? "page" : undefined}
>
{label}
</Link>
Expand Down
Loading