From e94492eab6cccff3e68db51b6aea755a6f6ad0d8 Mon Sep 17 00:00:00 2001 From: "D. Rimron-Soutter" Date: Sat, 10 Jan 2026 22:05:28 +0000 Subject: [PATCH] Unify ZXDB list layouts Apply sidebar filter layout to label/genre/language/machine lists and restructure release detail into a two-column view. Signed-off-by: codex@lucy.xalior.com --- src/app/zxdb/genres/GenresSearch.tsx | 77 ++- src/app/zxdb/labels/LabelsSearch.tsx | 85 ++- src/app/zxdb/languages/LanguagesSearch.tsx | 77 ++- .../zxdb/machinetypes/MachineTypesSearch.tsx | 77 ++- .../[entryId]/[releaseSeq]/ReleaseDetail.tsx | 629 +++++++++--------- 5 files changed, 503 insertions(+), 442 deletions(-) diff --git a/src/app/zxdb/genres/GenresSearch.tsx b/src/app/zxdb/genres/GenresSearch.tsx index d996344..6f16bf9 100644 --- a/src/app/zxdb/genres/GenresSearch.tsx +++ b/src/app/zxdb/genres/GenresSearch.tsx @@ -39,40 +39,55 @@ export default function GenresSearch({ initial, initialQ }: { initial?: Paged -

Genres

-
-
- setQ(e.target.value)} /> +
+
+

Genres

+
{data?.total.toLocaleString() ?? "0"} results
-
- -
- +
-
- {data && data.items.length === 0 &&
No genres found.
} - {data && data.items.length > 0 && ( -
- - - - - - - - - {data.items.map((g) => ( - - - - - ))} - -
IDName
#{g.id} - {g.name} -
+
+
+
+
+
+
+ + setQ(e.target.value)} /> +
+
+ +
+
+
- )} +
+ +
+ {data && data.items.length === 0 &&
No genres found.
} + {data && data.items.length > 0 && ( +
+ + + + + + + + + {data.items.map((g) => ( + + + + + ))} + +
IDName
#{g.id} + {g.name} +
+
+ )} +
diff --git a/src/app/zxdb/labels/LabelsSearch.tsx b/src/app/zxdb/labels/LabelsSearch.tsx index 1a081ba..bb3cce4 100644 --- a/src/app/zxdb/labels/LabelsSearch.tsx +++ b/src/app/zxdb/labels/LabelsSearch.tsx @@ -41,44 +41,59 @@ export default function LabelsSearch({ initial, initialQ }: { initial?: Paged -

Labels

-
-
- setQ(e.target.value)} /> +
+
+

Labels

+
{data?.total.toLocaleString() ?? "0"} results
-
- -
- +
-
- {data && data.items.length === 0 &&
No labels found.
} - {data && data.items.length > 0 && ( -
- - - - - - - - - - {data.items.map((l) => ( - - - - - - ))} - -
IDNameType
#{l.id} - {l.name} - - {l.labeltypeId ?? "?"} -
+
+
+
+
+
+
+ + setQ(e.target.value)} /> +
+
+ +
+
+
- )} +
+ +
+ {data && data.items.length === 0 &&
No labels found.
} + {data && data.items.length > 0 && ( +
+ + + + + + + + + + {data.items.map((l) => ( + + + + + + ))} + +
IDNameType
#{l.id} + {l.name} + + {l.labeltypeId ?? "?"} +
+
+ )} +
diff --git a/src/app/zxdb/languages/LanguagesSearch.tsx b/src/app/zxdb/languages/LanguagesSearch.tsx index 8ff5cc8..9395dd8 100644 --- a/src/app/zxdb/languages/LanguagesSearch.tsx +++ b/src/app/zxdb/languages/LanguagesSearch.tsx @@ -39,40 +39,55 @@ export default function LanguagesSearch({ initial, initialQ }: { initial?: Paged ]} /> -

Languages

-
-
- setQ(e.target.value)} /> +
+
+

Languages

+
{data?.total.toLocaleString() ?? "0"} results
-
- -
- +
-
- {data && data.items.length === 0 &&
No languages found.
} - {data && data.items.length > 0 && ( -
- - - - - - - - - {data.items.map((l) => ( - - - - - ))} - -
CodeName
{l.id} - {l.name} -
+
+
+
+
+
+
+ + setQ(e.target.value)} /> +
+
+ +
+
+
- )} +
+ +
+ {data && data.items.length === 0 &&
No languages found.
} + {data && data.items.length > 0 && ( +
+ + + + + + + + + {data.items.map((l) => ( + + + + + ))} + +
CodeName
{l.id} + {l.name} +
+
+ )} +
diff --git a/src/app/zxdb/machinetypes/MachineTypesSearch.tsx b/src/app/zxdb/machinetypes/MachineTypesSearch.tsx index a1a7b7d..7f5982f 100644 --- a/src/app/zxdb/machinetypes/MachineTypesSearch.tsx +++ b/src/app/zxdb/machinetypes/MachineTypesSearch.tsx @@ -41,40 +41,55 @@ export default function MachineTypesSearch({ initial, initialQ }: { initial?: Pa ]} /> -

Machine Types

-
-
- setQ(e.target.value)} /> +
+
+

Machine Types

+
{data?.total.toLocaleString() ?? "0"} results
-
- -
- +
-
- {data && data.items.length === 0 &&
No machine types found.
} - {data && data.items.length > 0 && ( -
- - - - - - - - - {data.items.map((m) => ( - - - - - ))} - -
IDName
#{m.id} - {m.name} -
+
+
+
+
+
+
+ + setQ(e.target.value)} /> +
+
+ +
+
+
- )} +
+ +
+ {data && data.items.length === 0 &&
No machine types found.
} + {data && data.items.length > 0 && ( +
+ + + + + + + + + {data.items.map((m) => ( + + + + + ))} + +
IDName
#{m.id} + {m.name} +
+
+ )} +
diff --git a/src/app/zxdb/releases/[entryId]/[releaseSeq]/ReleaseDetail.tsx b/src/app/zxdb/releases/[entryId]/[releaseSeq]/ReleaseDetail.tsx index 0c18153..86d6e22 100644 --- a/src/app/zxdb/releases/[entryId]/[releaseSeq]/ReleaseDetail.tsx +++ b/src/app/zxdb/releases/[entryId]/[releaseSeq]/ReleaseDetail.tsx @@ -191,336 +191,337 @@ export default function ReleaseDetailClient({ data }: { data: ReleaseDetailData
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldValue
Entry - #{data.entry.id} -
Release Sequence#{data.release.releaseSeq}
Release Date - {data.release.year != null ? ( - - {data.release.year} - {data.release.month != null ? `/${String(data.release.month).padStart(2, "0")}` : ""} - {data.release.day != null ? `/${String(data.release.day).padStart(2, "0")}` : ""} - - ) : ( - - - )} -
Currency - {data.release.currency.id ? ( - {data.release.currency.id} {data.release.currency.name ? `(${data.release.currency.name})` : ""} - ) : ( - - - )} -
Price{formatCurrency(data.release.prices.release, data.release.currency)}
Budget Price{formatCurrency(data.release.prices.budget, data.release.currency)}
Microdrive Price{formatCurrency(data.release.prices.microdrive, data.release.currency)}
Disk Price{formatCurrency(data.release.prices.disk, data.release.currency)}
Cartridge Price{formatCurrency(data.release.prices.cartridge, data.release.currency)}
Book ISBN{data.release.book.isbn ?? -}
Book Pages{data.release.book.pages ?? -}
-
- -
- -
-
Other Releases
- {otherReleases.length === 0 &&
No other releases
} - {otherReleases.length > 0 && ( -
- {otherReleases.map((r) => ( - - #{r.releaseSeq}{r.year != null ? ` · ${r.year}` : ""} - - ))} -
- )} -
- -
- -
-
Places (Magazines)
- {magazineGroups.length === 0 &&
No magazine references
} - {magazineGroups.length > 0 && ( -
- {magazineGroups.map((group) => ( -
-
-
- {group.magazineId != null ? ( - - {group.magazineName ?? `Magazine #${group.magazineId}`} - - ) : ( - Unknown magazine - )} -
-
{group.items.length} reference{group.items.length === 1 ? "" : "s"}
-
- {groupIssueRefs(group.items).map((issueGroup) => ( -
-
-
- Issue #{issueGroup.issueId} -
{formatIssue(issueGroup.issue) || "-"}
-
-
- {issueGroup.items.length} reference{issueGroup.items.length === 1 ? "" : "s"} -
-
-
- - - - - - - - - - - {issueGroup.items.map((m) => ( - - - - - - - ))} - -
PageTypeOriginalNotes
{m.page}{m.referencetypeName ?? `#${m.referencetypeId}`}{m.isOriginal ? "Yes" : "No"}{m.scoreGroup || "-"}
-
-
- ))} -
- ))} -
- )} -
- -
- -
-
Downloads
- {data.downloads.length === 0 &&
No downloads
} - {data.downloads.length > 0 && ( -
- - - - - - - - - - - - - - {data.downloads.map((d) => { - const isHttp = d.link.startsWith("http://") || d.link.startsWith("https://"); - return ( - - +
+
+
+
+
Release Summary
+
+
TypeLinkSizeMD5FlagsDetailsComments
{d.type.name}
+ + + - - - - - - ); - })} - -
Entry - {isHttp ? ( - {d.link} - ) : ( - {d.link} - )} + #{data.entry.id} {typeof d.size === "number" ? d.size.toLocaleString() : "-"}{d.md5 ?? "-"} -
- {d.isDemo ? Demo : null} - {d.scheme.name ? {d.scheme.name} : null} - {d.source.name ? {d.source.name} : null} - {d.case.name ? {d.case.name} : null} -
-
-
- {d.language.name ? ( - {d.language.name} - ) : null} - {d.machinetype.name ? ( - {d.machinetype.name} - ) : null} - {typeof d.year === "number" ? {d.year} : null} -
-
{d.comments ?? ""}
-
- )} -
- -
- -
-
Scraps / Media
- {data.scraps.length === 0 &&
No scraps
} - {data.scraps.length > 0 && ( -
- - - - - - - - - - - - - {data.scraps.map((s) => { - const isHttp = s.link?.startsWith("http://") || s.link?.startsWith("https://"); - return ( - - + + + + + + - - - - - ); - })} - -
TypeLinkSizeFlagsDetailsRationale
{s.type.name}
Release Sequence#{data.release.releaseSeq}
Release Date - {s.link ? ( - isHttp ? ( - {s.link} - ) : ( - {s.link} - ) + {data.release.year != null ? ( + + {data.release.year} + {data.release.month != null ? `/${String(data.release.month).padStart(2, "0")}` : ""} + {data.release.day != null ? `/${String(data.release.day).padStart(2, "0")}` : ""} + ) : ( - )} {typeof s.size === "number" ? s.size.toLocaleString() : "-"} -
- {s.isDemo ? Demo : null} - {s.scheme.name ? {s.scheme.name} : null} - {s.source.name ? {s.source.name} : null} - {s.case.name ? {s.case.name} : null} -
-
-
- {s.language.name ? ( - {s.language.name} - ) : null} - {s.machinetype.name ? ( - {s.machinetype.name} - ) : null} - {typeof s.year === "number" ? {s.year} : null} -
-
{s.rationale}
-
- )} -
- -
- -
-
Issue Files
- {data.files.length === 0 &&
No files linked
} - {data.files.length > 0 && ( -
- - - - - - - - - - - - {data.files.map((f) => { - const isHttp = f.link.startsWith("http://") || f.link.startsWith("https://"); - return ( - - + + - - - - ); - })} - -
TypeLinkSizeMD5Comments
{f.type.name}
Currency - {isHttp ? ( - {f.link} + {data.release.currency.id ? ( + {data.release.currency.id} {data.release.currency.name ? `(${data.release.currency.name})` : ""} ) : ( - {f.link} + - )} {f.size != null ? new Intl.NumberFormat().format(f.size) : "-"}{f.md5 ?? "-"}{f.comments ?? ""}
+ + Price + {formatCurrency(data.release.prices.release, data.release.currency)} + + + Budget Price + {formatCurrency(data.release.prices.budget, data.release.currency)} + + + Microdrive Price + {formatCurrency(data.release.prices.microdrive, data.release.currency)} + + + Disk Price + {formatCurrency(data.release.prices.disk, data.release.currency)} + + + Cartridge Price + {formatCurrency(data.release.prices.cartridge, data.release.currency)} + + + Book ISBN + {data.release.book.isbn ?? -} + + + Book Pages + {data.release.book.pages ?? -} + + + +
+
- )} -
-
+
+
+
Other Releases
+ {otherReleases.length === 0 &&
No other releases
} + {otherReleases.length > 0 && ( +
+ {otherReleases.map((r) => ( + + #{r.releaseSeq}{r.year != null ? ` · ${r.year}` : ""} + + ))} +
+ )} +
+
+
+ +
+
+
+
Places (Magazines)
+ {magazineGroups.length === 0 &&
No magazine references
} + {magazineGroups.length > 0 && ( +
+ {magazineGroups.map((group) => ( +
+
+
+ {group.magazineId != null ? ( + + {group.magazineName ?? `Magazine #${group.magazineId}`} + + ) : ( + Unknown magazine + )} +
+
{group.items.length} reference{group.items.length === 1 ? "" : "s"}
+
+ {groupIssueRefs(group.items).map((issueGroup) => ( +
+
+
+ Issue #{issueGroup.issueId} +
{formatIssue(issueGroup.issue) || "-"}
+
+
+ {issueGroup.items.length} reference{issueGroup.items.length === 1 ? "" : "s"} +
+
+
+ + + + + + + + + + + {issueGroup.items.map((m) => ( + + + + + + + ))} + +
PageTypeOriginalNotes
{m.page}{m.referencetypeName ?? `#${m.referencetypeId}`}{m.isOriginal ? "Yes" : "No"}{m.scoreGroup || "-"}
+
+
+ ))} +
+ ))} +
+ )} +
+
+ +
+
+
Downloads
+ {data.downloads.length === 0 &&
No downloads
} + {data.downloads.length > 0 && ( +
+ + + + + + + + + + + + + + {data.downloads.map((d) => { + const isHttp = d.link.startsWith("http://") || d.link.startsWith("https://"); + return ( + + + + + + + + + + ); + })} + +
TypeLinkSizeMD5FlagsDetailsComments
{d.type.name} + {isHttp ? ( + {d.link} + ) : ( + {d.link} + )} + {typeof d.size === "number" ? d.size.toLocaleString() : "-"}{d.md5 ?? "-"} +
+ {d.isDemo ? Demo : null} + {d.scheme.name ? {d.scheme.name} : null} + {d.source.name ? {d.source.name} : null} + {d.case.name ? {d.case.name} : null} +
+
+
+ {d.language.name ? ( + {d.language.name} + ) : null} + {d.machinetype.name ? ( + {d.machinetype.name} + ) : null} + {typeof d.year === "number" ? {d.year} : null} +
+
{d.comments ?? ""}
+
+ )} +
+
+ +
+
+
Scraps / Media
+ {data.scraps.length === 0 &&
No scraps
} + {data.scraps.length > 0 && ( +
+ + + + + + + + + + + + + {data.scraps.map((s) => { + const isHttp = s.link?.startsWith("http://") || s.link?.startsWith("https://"); + return ( + + + + + + + + + ); + })} + +
TypeLinkSizeFlagsDetailsRationale
{s.type.name} + {s.link ? ( + isHttp ? ( + {s.link} + ) : ( + {s.link} + ) + ) : ( + - + )} + {typeof s.size === "number" ? s.size.toLocaleString() : "-"} +
+ {s.isDemo ? Demo : null} + {s.scheme.name ? {s.scheme.name} : null} + {s.source.name ? {s.source.name} : null} + {s.case.name ? {s.case.name} : null} +
+
+
+ {s.language.name ? ( + {s.language.name} + ) : null} + {s.machinetype.name ? ( + {s.machinetype.name} + ) : null} + {typeof s.year === "number" ? {s.year} : null} +
+
{s.rationale}
+
+ )} +
+
+ +
+
+
Issue Files
+ {data.files.length === 0 &&
No files linked
} + {data.files.length > 0 && ( +
+ + + + + + + + + + + + {data.files.map((f) => { + const isHttp = f.link.startsWith("http://") || f.link.startsWith("https://"); + return ( + + + + + + + + ); + })} + +
TypeLinkSizeMD5Comments
{f.type.name} + {isHttp ? ( + {f.link} + ) : ( + {f.link} + )} + {f.size != null ? new Intl.NumberFormat().format(f.size) : "-"}{f.md5 ?? "-"}{f.comments ?? ""}
+
+ )} +
+
+
+
Permalink