Skip to content

Commit e41d2a8

Browse files
committed
Update CHANGELOG for version 16.2.1 and refactor GameCard and Community components to use Link for navigation
1 parent 80a4c12 commit e41d2a8

3 files changed

Lines changed: 62 additions & 59 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# GameVault Frontend Changelog
22

3+
## 16.2.1
4+
5+
### Changes
6+
7+
- [#6](https://github.com/Phalcode/gamevault-frontend/issues/6) - Use proper href links on game cards and community progress list for better accessibility (middle-click/right-click to open in new tab)
8+
39
## 16.2.0
410

511
### Changes

src/components/GameCard.tsx

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {
1717
} from "@tw/dropdown";
1818
import clsx from "clsx";
1919
import { useCallback, useMemo, useState, useEffect } from "react";
20-
import { useNavigate } from "react-router";
20+
import { Link } from "react-router";
2121

2222
export function GameCard({ game }: { game: GamevaultGame }) {
2323
const { serverUrl, user, authFetch } = useAuth();
@@ -107,16 +107,7 @@ export function GameCard({ game }: { game: GamevaultGame }) {
107107
[game.id],
108108
);
109109

110-
const navigate = useNavigate();
111-
112-
const handleOpenGameView = useCallback(
113-
(e: React.MouseEvent) => {
114-
e.preventDefault();
115-
e.stopPropagation();
116-
navigate(`/library/${game.id}`);
117-
},
118-
[navigate, game.id],
119-
);
110+
const gameViewUrl = `/library/${game.id}`;
120111

121112
const handleOpenSettings = useCallback(
122113
(e: React.MouseEvent) => {
@@ -129,12 +120,12 @@ export function GameCard({ game }: { game: GamevaultGame }) {
129120

130121
return (
131122
<>
132-
<div
123+
<Link
124+
to={gameViewUrl}
133125
className={clsx(
134126
"group flex flex-col rounded-xl bg-zinc-100 dark:bg-zinc-800 shadow-sm ring-1 ring-zinc-950/10 dark:ring-white/5 overflow-hidden focus:outline-none focus:ring-2 focus:ring-indigo-500",
135127
"transition-colors hover:bg-zinc-200/60 dark:hover:bg-zinc-700/70 cursor-pointer",
136128
)}
137-
tabIndex={0}
138129
>
139130
<div className="relative aspect-[3/4] w-full bg-bg-muted flex items-center justify-center overflow-hidden">
140131
{coverId ? (
@@ -148,10 +139,9 @@ export function GameCard({ game }: { game: GamevaultGame }) {
148139
className="h-full w-full object-contain rounded-none"
149140
square
150141
alt={localGame.title}
151-
onClick={handleOpenGameView}
152142
/>
153143
) : (
154-
<div onClick={handleOpenGameView} className="text-xs text-fg-muted">
144+
<div className="text-xs text-fg-muted">
155145
No Cover
156146
</div>
157147
)}
@@ -226,7 +216,7 @@ export function GameCard({ game }: { game: GamevaultGame }) {
226216
</p>
227217
)}
228218
</div>
229-
</div>
219+
</Link>
230220
{settingsOpen && (
231221
<GameSettings
232222
game={game}

src/pages/Community.tsx

Lines changed: 50 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,12 @@ import { Divider } from "@tw/divider";
55
import { Heading } from "@tw/heading";
66
import { Listbox, ListboxLabel, ListboxOption } from "@tw/listbox";
77
import { useEffect, useMemo, useState } from "react";
8-
import { useNavigate } from "react-router";
8+
import { Link } from "react-router";
99
import { GamevaultUser } from "../api";
1010
import { ROLE_LABELS } from "@/utils/roles";
1111

1212
export default function Community() {
1313
const { serverUrl, authFetch, user: loggedIn } = useAuth();
14-
const navigate = useNavigate();
1514
const [users, setUsers] = useState<GamevaultUser[]>([]);
1615
const [currentUsername, setCurrentUsername] = useState<string>("");
1716
const [loading, setLoading] = useState<boolean>(false);
@@ -282,52 +281,60 @@ export default function Community() {
282281
const coverId = game ? getGameCoverMediaId(game) : null;
283282
const key = p.id ?? `${(game && game.id) || "g"}-${idx}`;
284283
const hours = minutes / 60;
285-
const openGame = () => {
286-
if (!game?.id) return;
287-
const base = (serverUrl || "").replace(/\/+$/, "");
288-
if (base) {
289-
window.location.href = `${base}/library/${game.id}`;
290-
} else {
291-
navigate(`/library/${game.id}`);
292-
}
293-
};
294-
const onKey: React.KeyboardEventHandler<HTMLDivElement> = (e) => {
295-
if (e.key === 'Enter' || e.key === ' ') {
296-
e.preventDefault();
297-
openGame();
298-
}
299-
};
284+
const gameUrl = game?.id ? `/library/${game.id}` : undefined;
300285
return (
301286
<div
302287
key={String(key)}
303288
className="flex items-center gap-4 p-3"
304289
>
305-
<div
306-
className="shrink-0 cursor-pointer focus:outline-none focus:ring-2 focus:ring-indigo-500 rounded-lg"
307-
role="button"
308-
tabIndex={0}
309-
onClick={openGame}
310-
onKeyDown={onKey}
311-
title={title}
312-
>
313-
{coverId ? (
314-
<Media
315-
media={{ id: coverId } as any}
316-
width={48}
317-
height={64}
318-
className="rounded-lg"
319-
square
320-
alt={title}
321-
/>
322-
) : (
323-
<div
324-
className="rounded-lg bg-zinc-200 dark:bg-zinc-800 flex items-center justify-center text-[10px] text-zinc-600 dark:text-zinc-400"
325-
style={{ width: 48, height: 64 }}
326-
>
327-
No Cover
328-
</div>
329-
)}
330-
</div>
290+
{gameUrl ? (
291+
<Link
292+
to={gameUrl}
293+
className="shrink-0 focus:outline-none focus:ring-2 focus:ring-indigo-500 rounded-lg"
294+
title={title}
295+
>
296+
{coverId ? (
297+
<Media
298+
media={{ id: coverId } as any}
299+
width={48}
300+
height={64}
301+
className="rounded-lg"
302+
square
303+
alt={title}
304+
/>
305+
) : (
306+
<div
307+
className="rounded-lg bg-zinc-200 dark:bg-zinc-800 flex items-center justify-center text-[10px] text-zinc-600 dark:text-zinc-400"
308+
style={{ width: 48, height: 64 }}
309+
>
310+
No Cover
311+
</div>
312+
)}
313+
</Link>
314+
) : (
315+
<div
316+
className="shrink-0 rounded-lg"
317+
title={title}
318+
>
319+
{coverId ? (
320+
<Media
321+
media={{ id: coverId } as any}
322+
width={48}
323+
height={64}
324+
className="rounded-lg"
325+
square
326+
alt={title}
327+
/>
328+
) : (
329+
<div
330+
className="rounded-lg bg-zinc-200 dark:bg-zinc-800 flex items-center justify-center text-[10px] text-zinc-600 dark:text-zinc-400"
331+
style={{ width: 48, height: 64 }}
332+
>
333+
No Cover
334+
</div>
335+
)}
336+
</div>
337+
)}
331338
<div className="min-w-0 flex-1">
332339
<div className="text-sm font-medium truncate">
333340
{title}

0 commit comments

Comments
 (0)