feat: enhance accessibility and testing with data-test attributes and improve error handling
Some checks failed
Workflow / ⚫️ Test (push) Has been cancelled
Workflow / ʦ TypeScript (push) Has been cancelled

This commit is contained in:
T. Zehetbauer
2026-04-01 10:46:44 +02:00
parent 3bcc5c70a3
commit abac22feb1
55 changed files with 1622 additions and 128 deletions

View File

@@ -68,6 +68,7 @@ export function GenerateDocumentForm({ accountSlug, initialType }: Props) {
<select
id="documentType"
name="documentType"
data-test="document-type-select"
value={selectedType}
onChange={(e) => {
setSelectedType(e.target.value);
@@ -190,7 +191,11 @@ export function GenerateDocumentForm({ accountSlug, initialType }: Props) {
{/* Submit button */}
<div className="flex justify-end">
<Button type="submit" disabled={isPending || isComingSoon}>
<Button
type="submit"
data-test="document-generate-btn"
disabled={isPending || isComingSoon}
>
{isPending ? (
<>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />

View File

@@ -259,10 +259,10 @@ async function generateMemberCards(
orientation: input.orientation,
style: s.page,
},
...batch.map((m) =>
...batch.map((memberItem) =>
React.createElement(
View,
{ key: m.id, style: s.card },
{ key: memberItem.id, style: s.card },
// Accent bar
React.createElement(View, { style: s.accentBar }),
@@ -298,7 +298,7 @@ async function generateMemberCards(
React.createElement(
Text,
{ style: s.memberNumber },
`Nr. ${m.member_number ?? ''}`,
`Nr. ${memberItem.member_number ?? ''}`,
),
),
@@ -309,7 +309,7 @@ async function generateMemberCards(
React.createElement(
Text,
{ style: s.memberName },
`${m.first_name} ${m.last_name}`,
`${memberItem.first_name} ${memberItem.last_name}`,
),
React.createElement(
View,
@@ -326,7 +326,7 @@ async function generateMemberCards(
React.createElement(
Text,
{ style: s.fieldValue },
fmtDate(m.entry_date),
fmtDate(memberItem.entry_date),
),
),
// Date of birth
@@ -341,7 +341,7 @@ async function generateMemberCards(
React.createElement(
Text,
{ style: s.fieldValue },
fmtDate(m.date_of_birth),
fmtDate(memberItem.date_of_birth),
),
),
// Address
@@ -356,13 +356,16 @@ async function generateMemberCards(
React.createElement(
Text,
{ style: s.fieldValue },
[m.street, m.house_number].filter(Boolean).join(' ') ||
'',
[memberItem.street, memberItem.house_number]
.filter(Boolean)
.join(' ') || '',
),
React.createElement(
Text,
{ style: { ...s.fieldValue, marginTop: 1 } },
[m.postal_code, m.city].filter(Boolean).join(' ') || '',
[memberItem.postal_code, memberItem.city]
.filter(Boolean)
.join(' ') || '',
),
),
),
@@ -428,12 +431,20 @@ async function generateLabels(
return { success: false, error: 'Keine aktiven Mitglieder.' };
const api = createDocumentGeneratorApi();
const records = members.map((m) => ({
line1: [m.salutation, m.title, m.first_name, m.last_name]
const records = members.map((record) => ({
line1: [
record.salutation,
record.title,
record.first_name,
record.last_name,
]
.filter(Boolean)
.join(' '),
line2: [m.street, m.house_number].filter(Boolean).join(' ') || undefined,
line3: [m.postal_code, m.city].filter(Boolean).join(' ') || undefined,
line2:
[record.street, record.house_number].filter(Boolean).join(' ') ||
undefined,
line3:
[record.postal_code, record.city].filter(Boolean).join(' ') || undefined,
}));
const html = api.generateLabelsHtml({ labelFormat: 'avery-l7163', records });
@@ -500,16 +511,16 @@ async function generateMemberReport(
excluded: 'Ausgeschlossen',
};
for (const m of members) {
for (const member of members) {
ws.addRow({
nr: m.member_number ?? '',
name: m.last_name,
vorname: m.first_name,
email: m.email ?? '',
plz: m.postal_code ?? '',
ort: m.city ?? '',
status: SL[m.status] ?? m.status,
eintritt: m.entry_date ? formatDate(m.entry_date) : '',
nr: member.member_number ?? '',
name: member.last_name,
vorname: member.first_name,
email: member.email ?? '',
plz: member.postal_code ?? '',
ort: member.city ?? '',
status: SL[member.status] ?? member.status,
eintritt: member.entry_date ? formatDate(member.entry_date) : '',
});
}

View File

@@ -46,7 +46,7 @@ export default async function DocumentTemplatesPage({ params }: PageProps) {
</p>
</div>
<Button>
<Button data-test="document-templates-new-btn">
<Plus className="mr-2 h-4 w-4" />
Neue Vorlage
</Button>