Skip to content
Merged
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
6 changes: 6 additions & 0 deletions .github/workflows/quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,9 @@ jobs:

- name: Build
run: bun run build

- name: Install browser
run: bunx playwright install --with-deps chromium

- name: Browser tests
run: bun run test:e2e
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,8 @@ yarn-error.log*
next-env.d.ts

!.env.example

/test-results/
/playwright-report/

/public/pingpong/vision.worker.js
4 changes: 4 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@
.claude
node_modules
public/*.pdf

public/pingpong/vision.worker.js
test-results
playwright-report
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,7 @@ Professional links and contact details are available at [jorgesandoval.dev](http
## License

Copyright © Jorge Sandoval. All rights reserved.

## PingPong

The mobile scorer lives at [/pingpong](https://jorgesandoval.dev/pingpong). It includes local camera tracking, assisted points, limited experimental automatic double-bounce scoring, manual correction and local history. See [setup, architecture and limitations](docs/pingpong/README.md) and [validation](docs/pingpong/validation-report.md). The camera mode is a beta; real-game accuracy has not been measured.
87 changes: 50 additions & 37 deletions app/components/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use client";
import { useState } from "react";
import { usePathname } from "next/navigation";
import Link from "next/link";

const links = [
Expand All @@ -10,45 +11,57 @@ const links = [
];
export default function Navbar() {
const [open, setOpen] = useState(false);
const pathname = usePathname();
if (pathname === "/pingpong" || pathname.startsWith("/pingpong/"))
return null;
return (
<header className="site-header">
<nav
className="wrap navigation"
aria-label="Main navigation"
onKeyDown={(event) => {
if (event.key === "Escape") setOpen(false);
}}
>
<Link className="wordmark" href="/#main" onClick={() => setOpen(false)}>
Jorge Sandoval<span aria-hidden="true">.</span>
</Link>
<button
className="menu-toggle"
aria-expanded={open}
aria-controls="navigation-links"
onClick={() => setOpen((current) => !current)}
<>
<a className="skip-link" href="#main">
Skip to content
</a>
<header className="site-header">
<nav
className="wrap navigation"
aria-label="Main navigation"
onKeyDown={(event) => {
if (event.key === "Escape") setOpen(false);
}}
>
{open ? "Close −" : "Menu +"}
</button>
<div
id="navigation-links"
className={`nav-links ${open ? "is-open" : ""}`}
>
{links.map(([label, id]) => (
<Link key={id} href={`/#${id}`} onClick={() => setOpen(false)}>
{label}
</Link>
))}
<a
className="nav-social"
href="https://www.linkedin.com/in/jorgesandev/"
target="_blank"
rel="noopener noreferrer"
<Link
className="wordmark"
href="/#main"
onClick={() => setOpen(false)}
>
Jorge Sandoval<span aria-hidden="true">.</span>
</Link>
<button
className="menu-toggle"
aria-expanded={open}
aria-controls="navigation-links"
onClick={() => setOpen((current) => !current)}
>
{open ? "Close −" : "Menu +"}
</button>
<div
id="navigation-links"
className={`nav-links ${open ? "is-open" : ""}`}
>
LinkedIn
</a>
</div>
</nav>
</header>
{links.map(([label, id]) => (
<Link key={id} href={`/#${id}`} onClick={() => setOpen(false)}>
{label}
</Link>
))}
<a
className="nav-social"
href="https://www.linkedin.com/in/jorgesandev/"
target="_blank"
rel="noopener noreferrer"
>
LinkedIn
</a>
</div>
</nav>
</header>
</>
);
}
3 changes: 0 additions & 3 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,6 @@ export default function RootLayout({
return (
<html lang="en">
<body className={`${sans.variable} ${mono.variable}`}>
<a className="skip-link" href="#main">
Skip to content
</a>
<Navbar />
{children}
</body>
Expand Down
Loading
Loading