fix: comprehensive CMS QA fixes — i18n, UI labels, breadcrumbs
Some checks failed
Workflow / ʦ TypeScript (push) Failing after 6m6s
Workflow / ⚫️ Test (push) Has been skipped

- Fix i18n dotted permission keys causing INVALID_KEY console spam (en/de cms.json)
- Fix member detail breadcrumb showing UUID instead of member name
- Fix bookings stats card showing 'of' instead of 'Total'
- Fix events/registrations table 'status' column header resolving to object
- Fix finance search placeholder showing 'Show All' instead of search text
- Fix finance status filter default showing 'No data' instead of 'All'
- Fix applications page German pluralization 'Antrage' → 'Anträge'
- Add breadcrumbValues prop to CmsPageShell for UUID→name overrides
This commit is contained in:
Zaid Marzguioui
2026-04-02 22:59:42 +02:00
parent 0932c57fa1
commit f10a34c505
11 changed files with 111 additions and 62 deletions

View File

@@ -126,7 +126,7 @@ export default async function BookingsPage({
icon={<CalendarCheck className="h-5 w-5" />}
/>
<StatsCard
title={t('common.of')}
title={t('list.total')}
value={total}
icon={<Euro className="h-5 w-5" />}
/>

View File

@@ -138,7 +138,7 @@ export default async function EventsPage({ params, searchParams }: PageProps) {
{t('capacity')}
</th>
<th scope="col" className="p-3 text-left font-medium">
{t('status')}
{t('statusLabel')}
</th>
<th scope="col" className="p-3 text-right font-medium">
{t('registrations')}

View File

@@ -116,7 +116,7 @@ export default async function EventRegistrationsPage({ params }: PageProps) {
{t('eventDate')}
</th>
<th scope="col" className="p-3 text-left font-medium">
{t('status')}
{t('statusLabel')}
</th>
<th scope="col" className="p-3 text-right font-medium">
{t('capacity')}

View File

@@ -144,13 +144,13 @@ export default async function FinancePage({ params, searchParams }: PageProps) {
{/* Toolbar */}
<ListToolbar
searchPlaceholder={t('common.showAll')}
searchPlaceholder={t('common.searchPlaceholder')}
filters={[
{
param: 'status',
label: t('common.status'),
options: [
{ value: '', label: t('common.noData') },
{ value: '', label: t('common.all') },
{ value: 'draft', label: t('status.draft') },
{ value: 'ready', label: t('sepa.newBatch') },
{ value: 'sent', label: t('status.sent') },

View File

@@ -30,10 +30,13 @@ export default async function MemberDetailPage({ params }: Props) {
api.listMandates(memberId),
]);
const memberName = `${String(member.first_name)} ${String(member.last_name)}`;
return (
<CmsPageShell
account={account}
title={`${String(member.first_name)} ${String(member.last_name)}`}
title={memberName}
breadcrumbValues={{ [memberId]: memberName }}
>
<MemberDetailView
member={member}

View File

@@ -9,6 +9,8 @@ interface CmsPageShellProps {
account: string;
title: string;
description?: string;
/** Override breadcrumb labels for URL path segments (e.g. UUID → name) */
breadcrumbValues?: Record<string, string>;
children: ReactNode;
}
@@ -20,6 +22,7 @@ export function CmsPageShell({
account,
title,
description,
breadcrumbValues,
children,
}: CmsPageShellProps) {
return (
@@ -28,7 +31,11 @@ export function CmsPageShell({
account={account}
title={title}
description={
description !== undefined ? description : <AppBreadcrumbs />
description !== undefined ? (
description
) : (
<AppBreadcrumbs values={breadcrumbValues} />
)
}
/>

View File

@@ -304,34 +304,54 @@
"paginationNext": "Weiter →"
},
"permissions": {
"modules.read": "Module lesen",
"modules.write": "Module bearbeiten",
"modules.delete": "Module löschen",
"modules.insert": "Datensätze erstellen",
"modules.lock": "Datensätze sperren",
"modules.import": "Daten importieren",
"modules.export": "Daten exportieren",
"modules.print": "Drucken",
"modules.manage": "Module verwalten",
"members.read": "Mitglieder lesen",
"members.write": "Mitglieder bearbeiten",
"courses.read": "Kurse lesen",
"courses.write": "Kurse bearbeiten",
"bookings.read": "Buchungen lesen",
"bookings.write": "Buchungen bearbeiten",
"finance.read": "Finanzen lesen",
"finance.write": "Finanzen bearbeiten",
"finance.sepa": "SEPA-Einzüge ausführen",
"documents.generate": "Dokumente generieren",
"newsletter.send": "Newsletter versenden",
"fischerei.read": "Fischerei lesen",
"fischerei.write": "Fischerei bearbeiten",
"meetings.read": "Sitzungsprotokolle lesen",
"meetings.write": "Sitzungsprotokolle bearbeiten",
"meetings.delete": "Sitzungsprotokolle löschen",
"verband.read": "Verbandsverwaltung lesen",
"verband.write": "Verbandsverwaltung bearbeiten",
"verband.delete": "Verbandsverwaltung löschen"
"modules": {
"read": "Module lesen",
"write": "Module bearbeiten",
"delete": "Module löschen",
"insert": "Datensätze erstellen",
"lock": "Datensätze sperren",
"import": "Daten importieren",
"export": "Daten exportieren",
"print": "Drucken",
"manage": "Module verwalten"
},
"members": {
"read": "Mitglieder lesen",
"write": "Mitglieder bearbeiten"
},
"courses": {
"read": "Kurse lesen",
"write": "Kurse bearbeiten"
},
"bookings": {
"read": "Buchungen lesen",
"write": "Buchungen bearbeiten"
},
"finance": {
"read": "Finanzen lesen",
"write": "Finanzen bearbeiten",
"sepa": "SEPA-Einzüge ausführen"
},
"documents": {
"generate": "Dokumente generieren"
},
"newsletter": {
"send": "Newsletter versenden"
},
"fischerei": {
"read": "Fischerei lesen",
"write": "Fischerei bearbeiten"
},
"meetings": {
"read": "Sitzungsprotokolle lesen",
"write": "Sitzungsprotokolle bearbeiten",
"delete": "Sitzungsprotokolle löschen"
},
"verband": {
"read": "Verbandsverwaltung lesen",
"write": "Verbandsverwaltung bearbeiten",
"delete": "Verbandsverwaltung löschen"
}
},
"status": {
"active": "Aktiv",

View File

@@ -146,7 +146,9 @@
"next": "Weiter",
"type": "Typ",
"date": "Datum",
"description": "Beschreibung"
"description": "Beschreibung",
"searchPlaceholder": "Rechnung suchen...",
"all": "Alle"
},
"status": {
"draft": "Entwurf",

View File

@@ -295,26 +295,40 @@
"paginationNext": "Next →"
},
"permissions": {
"modules.read": "Read Modules",
"modules.write": "Edit Modules",
"modules.delete": "Delete Modules",
"modules.insert": "Create Records",
"modules.lock": "Lock Records",
"modules.import": "Import Data",
"modules.export": "Export Data",
"modules.print": "Print",
"modules.manage": "Manage Modules",
"members.read": "Read Members",
"members.write": "Edit Members",
"courses.read": "Read Courses",
"courses.write": "Edit Courses",
"bookings.read": "Read Bookings",
"bookings.write": "Edit Bookings",
"finance.read": "Read Finance",
"finance.write": "Edit Finance",
"finance.sepa": "Execute SEPA Collections",
"documents.generate": "Generate Documents",
"newsletter.send": "Send Newsletter",
"modules": {
"read": "Read Modules",
"write": "Edit Modules",
"delete": "Delete Modules",
"insert": "Create Records",
"lock": "Lock Records",
"import": "Import Data",
"export": "Export Data",
"print": "Print",
"manage": "Manage Modules"
},
"members": {
"read": "Read Members",
"write": "Edit Members"
},
"courses": {
"read": "Read Courses",
"write": "Edit Courses"
},
"bookings": {
"read": "Read Bookings",
"write": "Edit Bookings"
},
"finance": {
"read": "Read Finance",
"write": "Edit Finance",
"sepa": "Execute SEPA Collections"
},
"documents": {
"generate": "Generate Documents"
},
"newsletter": {
"send": "Send Newsletter"
},
"verband": {
"delete": "Delete Association Data"
}

View File

@@ -146,7 +146,9 @@
"next": "Next",
"type": "Type",
"date": "Date",
"description": "Description"
"description": "Description",
"searchPlaceholder": "Search invoices...",
"all": "All"
},
"status": {
"draft": "Draft",

View File

@@ -95,7 +95,8 @@ export function ApplicationWorkflow({
<div className="flex items-center justify-between">
<h2 className="text-lg font-semibold">Aufnahmeanträge</h2>
<p className="text-muted-foreground text-sm">
{applications.length} Antrag{applications.length !== 1 ? 'e' : ''}
{applications.length}{' '}
{applications.length === 1 ? 'Antrag' : 'Anträge'}
</p>
</div>