Skip to content

Commit e4235c5

Browse files
committed
refactor: improve code readability and formatting in Library component
1 parent 6358774 commit e4235c5

1 file changed

Lines changed: 43 additions & 12 deletions

File tree

src/pages/Library.tsx

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import { ProgressStateEnum } from "@/api/models/Progress";
2727
import MultiSelectFilterDialog, {
2828
FilterItem,
2929
} from "@/components/MultiSelectFilterDialog";
30+
import { Strong, TextLink } from "@/components/tailwind/text";
3031

3132
const SORT_BY: { label: string; value: string }[] = [
3233
{ label: "Title", value: "sort_title" },
@@ -79,8 +80,7 @@ export default function Library() {
7980
const { serverUrl, user } = useAuth();
8081

8182
const CONTROL_HEIGHT_CLASS = "min-h-11 sm:min-h-9";
82-
const INPUT_CONTROL_HEIGHT_CLASS =
83-
"[&_input]:min-h-11 sm:[&_input]:min-h-9";
83+
const INPUT_CONTROL_HEIGHT_CLASS = "[&_input]:min-h-11 sm:[&_input]:min-h-9";
8484

8585
const urlInitializedRef = useRef(false);
8686
const [search, setSearch] = useState("");
@@ -183,12 +183,14 @@ export default function Library() {
183183
// Defer search to avoid spamming requests while user types quickly
184184
const deferredSearch = useDeferredValue(search);
185185

186-
// Convert selected game type FilterItems to GamevaultGameTypeEnum values for API
186+
// Convert selected type FilterItems to GamevaultGameTypeEnum values for API
187187
const gameTypeValues = useMemo(() => {
188188
return selectedGameTypes
189189
.map((item) => String(item.id))
190190
.filter((v): v is GamevaultGameTypeEnum =>
191-
Object.values(GamevaultGameTypeEnum).includes(v as GamevaultGameTypeEnum),
191+
Object.values(GamevaultGameTypeEnum).includes(
192+
v as GamevaultGameTypeEnum,
193+
),
192194
);
193195
}, [selectedGameTypes]);
194196

@@ -265,7 +267,9 @@ export default function Library() {
265267

266268
const isGameType = useCallback(
267269
(value: string): value is GamevaultGameTypeEnum =>
268-
Object.values(GamevaultGameTypeEnum).includes(value as GamevaultGameTypeEnum),
270+
Object.values(GamevaultGameTypeEnum).includes(
271+
value as GamevaultGameTypeEnum,
272+
),
269273
[],
270274
);
271275

@@ -277,7 +281,10 @@ export default function Library() {
277281

278282
const isBookmark = useCallback(
279283
(value: string): value is BookmarkFilter | "1" =>
280-
value === "all" || value === "mine" || value === "others" || value === "1",
284+
value === "all" ||
285+
value === "mine" ||
286+
value === "others" ||
287+
value === "1",
281288
[],
282289
);
283290

@@ -370,8 +377,16 @@ export default function Library() {
370377
.map((i) => String(i.id))
371378
.filter((v): v is GamevaultGameTypeEnum => isGameType(v)),
372379
);
373-
setParamValues(params, "tags", selectedTags.map((t) => t.name));
374-
setParamValues(params, "genres", selectedGenres.map((g) => g.name));
380+
setParamValues(
381+
params,
382+
"tags",
383+
selectedTags.map((t) => t.name),
384+
);
385+
setParamValues(
386+
params,
387+
"genres",
388+
selectedGenres.map((g) => g.name),
389+
);
375390
setParamValues(
376391
params,
377392
"developers",
@@ -531,7 +546,7 @@ export default function Library() {
531546

532547
{/* Section 1: Multi-Select Filter Buttons */}
533548
<div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-5 gap-3">
534-
{/* Game Types */}
549+
{/* Types */}
535550
<div className="col-span-1">
536551
<label className="block text-xs font-medium text-fg-muted mb-1">
537552
Type
@@ -836,7 +851,7 @@ export default function Library() {
836851
</div>
837852
</div>
838853
)}
839-
<div className="flex-1 overflow-y-scroll overflow-x-hidden">
854+
<div className="flex-1 overflow-y-scroll overflow-x-hidden text-center">
840855
{!serverUrl && (
841856
<div className="p-8 text-sm text-fg-muted">
842857
Connect to a server to load games.
@@ -851,7 +866,23 @@ export default function Library() {
851866
<div className="p-8 text-sm text-fg-muted">Loading games…</div>
852867
)}
853868
{serverUrl && !loading && games.length === 0 && !error && (
854-
<div className="p-8 text-sm text-fg-muted">No games found.</div>
869+
<div className="p-8 text-sm text-fg-muted">
870+
No games found.
871+
{(search.trim() || hasActiveFilters) && (
872+
<div className="mt-2">
873+
<TextLink
874+
href="#"
875+
onClick={() => {
876+
clearAllFilters();
877+
setShowFilters(false);
878+
setSearch("");
879+
}}
880+
>
881+
<Strong>Try clearing all filters and search</Strong>
882+
</TextLink>
883+
</div>
884+
)}
885+
</div>
855886
)}
856887
<div className="grid gap-4 grid-cols-[repeat(auto-fill,minmax(140px,1fr))] pb-8">
857888
{games.map((g) => (
@@ -870,7 +901,7 @@ export default function Library() {
870901
<MultiSelectFilterDialog
871902
open={gameTypesDialogOpen}
872903
onClose={() => setGameTypesDialogOpen(false)}
873-
title="Game Types"
904+
title="Types"
874905
staticItems={GAME_TYPE_FILTER_ITEMS}
875906
selectedItems={selectedGameTypes}
876907
onSelectionChange={setSelectedGameTypes}

0 commit comments

Comments
 (0)