fix: comprehensive CMS QA fixes — i18n, UI labels, breadcrumbs
- 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:
@@ -126,7 +126,7 @@ export default async function BookingsPage({
|
|||||||
icon={<CalendarCheck className="h-5 w-5" />}
|
icon={<CalendarCheck className="h-5 w-5" />}
|
||||||
/>
|
/>
|
||||||
<StatsCard
|
<StatsCard
|
||||||
title={t('common.of')}
|
title={t('list.total')}
|
||||||
value={total}
|
value={total}
|
||||||
icon={<Euro className="h-5 w-5" />}
|
icon={<Euro className="h-5 w-5" />}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ export default async function EventsPage({ params, searchParams }: PageProps) {
|
|||||||
{t('capacity')}
|
{t('capacity')}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" className="p-3 text-left font-medium">
|
<th scope="col" className="p-3 text-left font-medium">
|
||||||
{t('status')}
|
{t('statusLabel')}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" className="p-3 text-right font-medium">
|
<th scope="col" className="p-3 text-right font-medium">
|
||||||
{t('registrations')}
|
{t('registrations')}
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ export default async function EventRegistrationsPage({ params }: PageProps) {
|
|||||||
{t('eventDate')}
|
{t('eventDate')}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" className="p-3 text-left font-medium">
|
<th scope="col" className="p-3 text-left font-medium">
|
||||||
{t('status')}
|
{t('statusLabel')}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" className="p-3 text-right font-medium">
|
<th scope="col" className="p-3 text-right font-medium">
|
||||||
{t('capacity')}
|
{t('capacity')}
|
||||||
|
|||||||
@@ -144,13 +144,13 @@ export default async function FinancePage({ params, searchParams }: PageProps) {
|
|||||||
|
|
||||||
{/* Toolbar */}
|
{/* Toolbar */}
|
||||||
<ListToolbar
|
<ListToolbar
|
||||||
searchPlaceholder={t('common.showAll')}
|
searchPlaceholder={t('common.searchPlaceholder')}
|
||||||
filters={[
|
filters={[
|
||||||
{
|
{
|
||||||
param: 'status',
|
param: 'status',
|
||||||
label: t('common.status'),
|
label: t('common.status'),
|
||||||
options: [
|
options: [
|
||||||
{ value: '', label: t('common.noData') },
|
{ value: '', label: t('common.all') },
|
||||||
{ value: 'draft', label: t('status.draft') },
|
{ value: 'draft', label: t('status.draft') },
|
||||||
{ value: 'ready', label: t('sepa.newBatch') },
|
{ value: 'ready', label: t('sepa.newBatch') },
|
||||||
{ value: 'sent', label: t('status.sent') },
|
{ value: 'sent', label: t('status.sent') },
|
||||||
|
|||||||
@@ -30,10 +30,13 @@ export default async function MemberDetailPage({ params }: Props) {
|
|||||||
api.listMandates(memberId),
|
api.listMandates(memberId),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const memberName = `${String(member.first_name)} ${String(member.last_name)}`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CmsPageShell
|
<CmsPageShell
|
||||||
account={account}
|
account={account}
|
||||||
title={`${String(member.first_name)} ${String(member.last_name)}`}
|
title={memberName}
|
||||||
|
breadcrumbValues={{ [memberId]: memberName }}
|
||||||
>
|
>
|
||||||
<MemberDetailView
|
<MemberDetailView
|
||||||
member={member}
|
member={member}
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ interface CmsPageShellProps {
|
|||||||
account: string;
|
account: string;
|
||||||
title: string;
|
title: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
|
/** Override breadcrumb labels for URL path segments (e.g. UUID → name) */
|
||||||
|
breadcrumbValues?: Record<string, string>;
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,6 +22,7 @@ export function CmsPageShell({
|
|||||||
account,
|
account,
|
||||||
title,
|
title,
|
||||||
description,
|
description,
|
||||||
|
breadcrumbValues,
|
||||||
children,
|
children,
|
||||||
}: CmsPageShellProps) {
|
}: CmsPageShellProps) {
|
||||||
return (
|
return (
|
||||||
@@ -28,7 +31,11 @@ export function CmsPageShell({
|
|||||||
account={account}
|
account={account}
|
||||||
title={title}
|
title={title}
|
||||||
description={
|
description={
|
||||||
description !== undefined ? description : <AppBreadcrumbs />
|
description !== undefined ? (
|
||||||
|
description
|
||||||
|
) : (
|
||||||
|
<AppBreadcrumbs values={breadcrumbValues} />
|
||||||
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
@@ -304,34 +304,54 @@
|
|||||||
"paginationNext": "Weiter →"
|
"paginationNext": "Weiter →"
|
||||||
},
|
},
|
||||||
"permissions": {
|
"permissions": {
|
||||||
"modules.read": "Module lesen",
|
"modules": {
|
||||||
"modules.write": "Module bearbeiten",
|
"read": "Module lesen",
|
||||||
"modules.delete": "Module löschen",
|
"write": "Module bearbeiten",
|
||||||
"modules.insert": "Datensätze erstellen",
|
"delete": "Module löschen",
|
||||||
"modules.lock": "Datensätze sperren",
|
"insert": "Datensätze erstellen",
|
||||||
"modules.import": "Daten importieren",
|
"lock": "Datensätze sperren",
|
||||||
"modules.export": "Daten exportieren",
|
"import": "Daten importieren",
|
||||||
"modules.print": "Drucken",
|
"export": "Daten exportieren",
|
||||||
"modules.manage": "Module verwalten",
|
"print": "Drucken",
|
||||||
"members.read": "Mitglieder lesen",
|
"manage": "Module verwalten"
|
||||||
"members.write": "Mitglieder bearbeiten",
|
},
|
||||||
"courses.read": "Kurse lesen",
|
"members": {
|
||||||
"courses.write": "Kurse bearbeiten",
|
"read": "Mitglieder lesen",
|
||||||
"bookings.read": "Buchungen lesen",
|
"write": "Mitglieder bearbeiten"
|
||||||
"bookings.write": "Buchungen bearbeiten",
|
},
|
||||||
"finance.read": "Finanzen lesen",
|
"courses": {
|
||||||
"finance.write": "Finanzen bearbeiten",
|
"read": "Kurse lesen",
|
||||||
"finance.sepa": "SEPA-Einzüge ausführen",
|
"write": "Kurse bearbeiten"
|
||||||
"documents.generate": "Dokumente generieren",
|
},
|
||||||
"newsletter.send": "Newsletter versenden",
|
"bookings": {
|
||||||
"fischerei.read": "Fischerei lesen",
|
"read": "Buchungen lesen",
|
||||||
"fischerei.write": "Fischerei bearbeiten",
|
"write": "Buchungen bearbeiten"
|
||||||
"meetings.read": "Sitzungsprotokolle lesen",
|
},
|
||||||
"meetings.write": "Sitzungsprotokolle bearbeiten",
|
"finance": {
|
||||||
"meetings.delete": "Sitzungsprotokolle löschen",
|
"read": "Finanzen lesen",
|
||||||
"verband.read": "Verbandsverwaltung lesen",
|
"write": "Finanzen bearbeiten",
|
||||||
"verband.write": "Verbandsverwaltung bearbeiten",
|
"sepa": "SEPA-Einzüge ausführen"
|
||||||
"verband.delete": "Verbandsverwaltung löschen"
|
},
|
||||||
|
"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": {
|
"status": {
|
||||||
"active": "Aktiv",
|
"active": "Aktiv",
|
||||||
@@ -812,4 +832,4 @@
|
|||||||
"formatExcel": "Excel"
|
"formatExcel": "Excel"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -146,7 +146,9 @@
|
|||||||
"next": "Weiter",
|
"next": "Weiter",
|
||||||
"type": "Typ",
|
"type": "Typ",
|
||||||
"date": "Datum",
|
"date": "Datum",
|
||||||
"description": "Beschreibung"
|
"description": "Beschreibung",
|
||||||
|
"searchPlaceholder": "Rechnung suchen...",
|
||||||
|
"all": "Alle"
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
"draft": "Entwurf",
|
"draft": "Entwurf",
|
||||||
@@ -160,4 +162,4 @@
|
|||||||
"completed": "Abgeschlossen",
|
"completed": "Abgeschlossen",
|
||||||
"failed": "Fehlgeschlagen"
|
"failed": "Fehlgeschlagen"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -295,26 +295,40 @@
|
|||||||
"paginationNext": "Next →"
|
"paginationNext": "Next →"
|
||||||
},
|
},
|
||||||
"permissions": {
|
"permissions": {
|
||||||
"modules.read": "Read Modules",
|
"modules": {
|
||||||
"modules.write": "Edit Modules",
|
"read": "Read Modules",
|
||||||
"modules.delete": "Delete Modules",
|
"write": "Edit Modules",
|
||||||
"modules.insert": "Create Records",
|
"delete": "Delete Modules",
|
||||||
"modules.lock": "Lock Records",
|
"insert": "Create Records",
|
||||||
"modules.import": "Import Data",
|
"lock": "Lock Records",
|
||||||
"modules.export": "Export Data",
|
"import": "Import Data",
|
||||||
"modules.print": "Print",
|
"export": "Export Data",
|
||||||
"modules.manage": "Manage Modules",
|
"print": "Print",
|
||||||
"members.read": "Read Members",
|
"manage": "Manage Modules"
|
||||||
"members.write": "Edit Members",
|
},
|
||||||
"courses.read": "Read Courses",
|
"members": {
|
||||||
"courses.write": "Edit Courses",
|
"read": "Read Members",
|
||||||
"bookings.read": "Read Bookings",
|
"write": "Edit Members"
|
||||||
"bookings.write": "Edit Bookings",
|
},
|
||||||
"finance.read": "Read Finance",
|
"courses": {
|
||||||
"finance.write": "Edit Finance",
|
"read": "Read Courses",
|
||||||
"finance.sepa": "Execute SEPA Collections",
|
"write": "Edit Courses"
|
||||||
"documents.generate": "Generate Documents",
|
},
|
||||||
"newsletter.send": "Send Newsletter",
|
"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": {
|
"verband": {
|
||||||
"delete": "Delete Association Data"
|
"delete": "Delete Association Data"
|
||||||
}
|
}
|
||||||
@@ -338,4 +352,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -146,7 +146,9 @@
|
|||||||
"next": "Next",
|
"next": "Next",
|
||||||
"type": "Type",
|
"type": "Type",
|
||||||
"date": "Date",
|
"date": "Date",
|
||||||
"description": "Description"
|
"description": "Description",
|
||||||
|
"searchPlaceholder": "Search invoices...",
|
||||||
|
"all": "All"
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
"draft": "Draft",
|
"draft": "Draft",
|
||||||
@@ -160,4 +162,4 @@
|
|||||||
"completed": "Completed",
|
"completed": "Completed",
|
||||||
"failed": "Failed"
|
"failed": "Failed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -95,7 +95,8 @@ export function ApplicationWorkflow({
|
|||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<h2 className="text-lg font-semibold">Aufnahmeanträge</h2>
|
<h2 className="text-lg font-semibold">Aufnahmeanträge</h2>
|
||||||
<p className="text-muted-foreground text-sm">
|
<p className="text-muted-foreground text-sm">
|
||||||
{applications.length} Antrag{applications.length !== 1 ? 'e' : ''}
|
{applications.length}{' '}
|
||||||
|
{applications.length === 1 ? 'Antrag' : 'Anträge'}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user