Verbessere Fehlerbehandlung beim Laden von PDF-Vorlagen und füge Ursacheninformationen hinzu
Some checks failed
Code Analysis and Production Deploy / deploy-production (push) Has been cancelled
Code Analysis and Production Deploy / deploy-test (push) Has been cancelled
Code Analysis and Production Deploy / analyze (push) Has been cancelled

This commit is contained in:
Torsten Schulz (local)
2026-07-17 08:50:47 +02:00
parent bd45beadd5
commit f0ac4b7e56
6 changed files with 96 additions and 67 deletions

View File

@@ -211,7 +211,9 @@
placeholder="myTischtennis-Team-ID" placeholder="myTischtennis-Team-ID"
:disabled="isSaving" :disabled="isSaving"
> >
<p class="mt-1 text-xs text-gray-500">Verknüpft diese Mannschaft eindeutig mit dem importierten Spielplan.</p> <p class="mt-1 text-xs text-gray-500">
Verknüpft diese Mannschaft eindeutig mit dem importierten Spielplan.
</p>
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-gray-700 mb-2">Liga *</label> <label class="block text-sm font-medium text-gray-700 mb-2">Liga *</label>

83
package-lock.json generated
View File

@@ -26,11 +26,13 @@
"vue": "^3.5.22" "vue": "^3.5.22"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^10.0.1",
"@nuxtjs/tailwindcss": "^6.11.0", "@nuxtjs/tailwindcss": "^6.11.0",
"@types/dompurify": "^3.0.5", "@types/dompurify": "^3.0.5",
"autoprefixer": "^10.4.0", "autoprefixer": "^10.4.0",
"commander": "^13.1.0", "commander": "^13.1.0",
"dotenv": "^17.2.3", "dotenv": "^17.2.3",
"eslint": "^10.7.0",
"eslint-plugin-vue": "^10.6.2", "eslint-plugin-vue": "^10.6.2",
"globals": "^16.5.0", "globals": "^16.5.0",
"lucide-vue-next": "^0.344.0", "lucide-vue-next": "^0.344.0",
@@ -593,7 +595,6 @@
"version": "4.12.2", "version": "4.12.2",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": "^12.0.0 || ^14.0.0 || >=16.0.0" "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
} }
@@ -602,7 +603,6 @@
"version": "0.23.5", "version": "0.23.5",
"devOptional": true, "devOptional": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true,
"dependencies": { "dependencies": {
"@eslint/object-schema": "^3.0.5", "@eslint/object-schema": "^3.0.5",
"debug": "^4.3.1", "debug": "^4.3.1",
@@ -616,7 +616,6 @@
"version": "0.6.0", "version": "0.6.0",
"devOptional": true, "devOptional": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true,
"dependencies": { "dependencies": {
"@eslint/core": "^1.2.1" "@eslint/core": "^1.2.1"
}, },
@@ -628,7 +627,6 @@
"version": "1.2.1", "version": "1.2.1",
"devOptional": true, "devOptional": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true,
"dependencies": { "dependencies": {
"@types/json-schema": "^7.0.15" "@types/json-schema": "^7.0.15"
}, },
@@ -636,11 +634,31 @@
"node": "^20.19.0 || ^22.13.0 || >=24" "node": "^20.19.0 || ^22.13.0 || >=24"
} }
}, },
"node_modules/@eslint/js": {
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz",
"integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^20.19.0 || ^22.13.0 || >=24"
},
"funding": {
"url": "https://eslint.org/donate"
},
"peerDependencies": {
"eslint": "^10.0.0"
},
"peerDependenciesMeta": {
"eslint": {
"optional": true
}
}
},
"node_modules/@eslint/object-schema": { "node_modules/@eslint/object-schema": {
"version": "3.0.5", "version": "3.0.5",
"devOptional": true, "devOptional": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true,
"engines": { "engines": {
"node": "^20.19.0 || ^22.13.0 || >=24" "node": "^20.19.0 || ^22.13.0 || >=24"
} }
@@ -649,7 +667,6 @@
"version": "0.7.2", "version": "0.7.2",
"devOptional": true, "devOptional": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true,
"dependencies": { "dependencies": {
"@eslint/core": "^1.2.1", "@eslint/core": "^1.2.1",
"levn": "^0.4.1" "levn": "^0.4.1"
@@ -666,7 +683,6 @@
"version": "0.19.2", "version": "0.19.2",
"devOptional": true, "devOptional": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true,
"dependencies": { "dependencies": {
"@humanfs/types": "^0.15.0" "@humanfs/types": "^0.15.0"
}, },
@@ -678,7 +694,6 @@
"version": "0.16.8", "version": "0.16.8",
"devOptional": true, "devOptional": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true,
"dependencies": { "dependencies": {
"@humanfs/core": "^0.19.2", "@humanfs/core": "^0.19.2",
"@humanfs/types": "^0.15.0", "@humanfs/types": "^0.15.0",
@@ -692,7 +707,6 @@
"version": "0.15.0", "version": "0.15.0",
"devOptional": true, "devOptional": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true,
"engines": { "engines": {
"node": ">=18.18.0" "node": ">=18.18.0"
} }
@@ -701,7 +715,6 @@
"version": "1.0.1", "version": "1.0.1",
"devOptional": true, "devOptional": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true,
"engines": { "engines": {
"node": ">=12.22" "node": ">=12.22"
}, },
@@ -714,7 +727,6 @@
"version": "0.4.3", "version": "0.4.3",
"devOptional": true, "devOptional": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true,
"engines": { "engines": {
"node": ">=18.18" "node": ">=18.18"
}, },
@@ -2226,8 +2238,7 @@
"node_modules/@types/json-schema": { "node_modules/@types/json-schema": {
"version": "7.0.15", "version": "7.0.15",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT"
"peer": true
}, },
"node_modules/@types/resolve": { "node_modules/@types/resolve": {
"version": "1.20.2", "version": "1.20.2",
@@ -2726,7 +2737,6 @@
"version": "6.15.0", "version": "6.15.0",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"fast-deep-equal": "^3.1.1", "fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0", "fast-json-stable-stringify": "^2.0.0",
@@ -3958,8 +3968,7 @@
"node_modules/deep-is": { "node_modules/deep-is": {
"version": "0.1.4", "version": "0.1.4",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT"
"peer": true
}, },
"node_modules/deepmerge": { "node_modules/deepmerge": {
"version": "4.3.1", "version": "4.3.1",
@@ -4336,7 +4345,6 @@
"version": "4.0.0", "version": "4.0.0",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">=10" "node": ">=10"
}, },
@@ -4348,7 +4356,6 @@
"version": "10.7.0", "version": "10.7.0",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"peer": true,
"workspaces": [ "workspaces": [
"packages/*" "packages/*"
], ],
@@ -4464,7 +4471,6 @@
"version": "5.3.2", "version": "5.3.2",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">= 4" "node": ">= 4"
} }
@@ -4523,7 +4529,6 @@
"version": "2.0.3", "version": "2.0.3",
"devOptional": true, "devOptional": true,
"license": "BSD-2-Clause", "license": "BSD-2-Clause",
"peer": true,
"engines": { "engines": {
"node": ">=0.10.0" "node": ">=0.10.0"
} }
@@ -4596,8 +4601,7 @@
"node_modules/fast-deep-equal": { "node_modules/fast-deep-equal": {
"version": "3.1.3", "version": "3.1.3",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT"
"peer": true
}, },
"node_modules/fast-diff": { "node_modules/fast-diff": {
"version": "1.3.0", "version": "1.3.0",
@@ -4634,14 +4638,12 @@
"node_modules/fast-json-stable-stringify": { "node_modules/fast-json-stable-stringify": {
"version": "2.1.0", "version": "2.1.0",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT"
"peer": true
}, },
"node_modules/fast-levenshtein": { "node_modules/fast-levenshtein": {
"version": "2.0.6", "version": "2.0.6",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT"
"peer": true
}, },
"node_modules/fast-npm-meta": { "node_modules/fast-npm-meta": {
"version": "1.5.1", "version": "1.5.1",
@@ -4702,7 +4704,6 @@
"version": "8.0.0", "version": "8.0.0",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"flat-cache": "^4.0.0" "flat-cache": "^4.0.0"
}, },
@@ -4728,7 +4729,6 @@
"version": "5.0.0", "version": "5.0.0",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"locate-path": "^6.0.0", "locate-path": "^6.0.0",
"path-exists": "^4.0.0" "path-exists": "^4.0.0"
@@ -4744,7 +4744,6 @@
"version": "4.0.1", "version": "4.0.1",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"flatted": "^3.2.9", "flatted": "^3.2.9",
"keyv": "^4.5.4" "keyv": "^4.5.4"
@@ -4756,8 +4755,7 @@
"node_modules/flatted": { "node_modules/flatted": {
"version": "3.4.2", "version": "3.4.2",
"devOptional": true, "devOptional": true,
"license": "ISC", "license": "ISC"
"peer": true
}, },
"node_modules/foreground-child": { "node_modules/foreground-child": {
"version": "3.3.1", "version": "3.3.1",
@@ -5263,7 +5261,6 @@
"version": "0.1.4", "version": "0.1.4",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">=0.8.19" "node": ">=0.8.19"
} }
@@ -5557,20 +5554,17 @@
"node_modules/json-buffer": { "node_modules/json-buffer": {
"version": "3.0.1", "version": "3.0.1",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT"
"peer": true
}, },
"node_modules/json-schema-traverse": { "node_modules/json-schema-traverse": {
"version": "0.4.1", "version": "0.4.1",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT"
"peer": true
}, },
"node_modules/json-stable-stringify-without-jsonify": { "node_modules/json-stable-stringify-without-jsonify": {
"version": "1.0.1", "version": "1.0.1",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT"
"peer": true
}, },
"node_modules/json5": { "node_modules/json5": {
"version": "2.2.3", "version": "2.2.3",
@@ -5645,7 +5639,6 @@
"version": "4.5.4", "version": "4.5.4",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"json-buffer": "3.0.1" "json-buffer": "3.0.1"
} }
@@ -5875,7 +5868,6 @@
"version": "0.4.1", "version": "0.4.1",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"prelude-ls": "^1.2.1", "prelude-ls": "^1.2.1",
"type-check": "~0.4.0" "type-check": "~0.4.0"
@@ -5991,7 +5983,6 @@
"version": "6.0.0", "version": "6.0.0",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"p-locate": "^5.0.0" "p-locate": "^5.0.0"
}, },
@@ -6822,7 +6813,6 @@
"version": "0.9.4", "version": "0.9.4",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"deep-is": "^0.1.3", "deep-is": "^0.1.3",
"fast-levenshtein": "^2.0.6", "fast-levenshtein": "^2.0.6",
@@ -6957,7 +6947,6 @@
"version": "3.1.0", "version": "3.1.0",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"yocto-queue": "^0.1.0" "yocto-queue": "^0.1.0"
}, },
@@ -6972,7 +6961,6 @@
"version": "5.0.0", "version": "5.0.0",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"p-limit": "^3.0.2" "p-limit": "^3.0.2"
}, },
@@ -7006,7 +6994,6 @@
"version": "4.0.0", "version": "4.0.0",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
@@ -7733,7 +7720,6 @@
"version": "1.2.1", "version": "1.2.1",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">= 0.8.0" "node": ">= 0.8.0"
} }
@@ -7776,7 +7762,6 @@
"version": "2.3.1", "version": "2.3.1",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">=6" "node": ">=6"
} }
@@ -9427,7 +9412,6 @@
"version": "0.4.0", "version": "0.4.0",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"prelude-ls": "^1.2.1" "prelude-ls": "^1.2.1"
}, },
@@ -9890,7 +9874,6 @@
"version": "4.4.1", "version": "4.4.1",
"devOptional": true, "devOptional": true,
"license": "BSD-2-Clause", "license": "BSD-2-Clause",
"peer": true,
"dependencies": { "dependencies": {
"punycode": "^2.1.0" "punycode": "^2.1.0"
} }
@@ -10535,7 +10518,6 @@
"version": "1.2.5", "version": "1.2.5",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">=0.10.0" "node": ">=0.10.0"
} }
@@ -10718,7 +10700,6 @@
"version": "0.1.0", "version": "0.1.0",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">=10" "node": ">=10"
}, },

View File

@@ -49,11 +49,13 @@
"vue": "^3.5.22" "vue": "^3.5.22"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^10.0.1",
"@nuxtjs/tailwindcss": "^6.11.0", "@nuxtjs/tailwindcss": "^6.11.0",
"@types/dompurify": "^3.0.5", "@types/dompurify": "^3.0.5",
"autoprefixer": "^10.4.0", "autoprefixer": "^10.4.0",
"commander": "^13.1.0", "commander": "^13.1.0",
"dotenv": "^17.2.3", "dotenv": "^17.2.3",
"eslint": "^10.7.0",
"eslint-plugin-vue": "^10.6.2", "eslint-plugin-vue": "^10.6.2",
"globals": "^16.5.0", "globals": "^16.5.0",
"lucide-vue-next": "^0.344.0", "lucide-vue-next": "^0.344.0",

View File

@@ -33,13 +33,22 @@
</div> </div>
</div> </div>
<div v-if="pending" class="py-12 text-center text-gray-500"> <div
v-if="pending"
class="py-12 text-center text-gray-500"
>
Lade QTTR-Werte... Lade QTTR-Werte...
</div> </div>
<div v-else-if="error" class="rounded-lg border border-red-200 bg-red-50 p-4 text-red-800"> <div
v-else-if="error"
class="rounded-lg border border-red-200 bg-red-50 p-4 text-red-800"
>
{{ error.statusMessage || error.message || 'QTTR-Werte konnten nicht geladen werden.' }} {{ error.statusMessage || error.message || 'QTTR-Werte konnten nicht geladen werden.' }}
</div> </div>
<div v-else class="overflow-x-auto"> <div
v-else
class="overflow-x-auto"
>
<table class="min-w-full divide-y divide-gray-200"> <table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50"> <thead class="bg-gray-50">
<tr> <tr>

View File

@@ -11,13 +11,24 @@
</div> </div>
<div class="bg-white rounded-xl shadow-lg p-8"> <div class="bg-white rounded-xl shadow-lg p-8">
<form class="space-y-6" @submit.prevent="handleSubmit"> <form
<div v-if="!token" class="bg-red-50 border border-red-200 rounded-lg p-4"> class="space-y-6"
<p class="text-sm text-red-800">Der Reset-Link ist unvollständig. Fordern Sie bitte einen neuen Link an.</p> @submit.prevent="handleSubmit"
>
<div
v-if="!token"
class="bg-red-50 border border-red-200 rounded-lg p-4"
>
<p class="text-sm text-red-800">
Der Reset-Link ist unvollständig. Fordern Sie bitte einen neuen Link an.
</p>
</div> </div>
<div> <div>
<label for="password" class="block text-sm font-medium text-gray-700 mb-2"> <label
for="password"
class="block text-sm font-medium text-gray-700 mb-2"
>
Neues Passwort Neues Passwort
</label> </label>
<input <input
@@ -32,7 +43,10 @@
</div> </div>
<div> <div>
<label for="passwordRepeat" class="block text-sm font-medium text-gray-700 mb-2"> <label
for="passwordRepeat"
class="block text-sm font-medium text-gray-700 mb-2"
>
Neues Passwort wiederholen Neues Passwort wiederholen
</label> </label>
<input <input
@@ -46,13 +60,24 @@
> >
</div> </div>
<div v-if="errorMessage" class="bg-red-50 border border-red-200 rounded-lg p-4"> <div
<p class="text-sm text-red-800">{{ errorMessage }}</p> v-if="errorMessage"
class="bg-red-50 border border-red-200 rounded-lg p-4"
>
<p class="text-sm text-red-800">
{{ errorMessage }}
</p>
</div> </div>
<div v-if="successMessage" class="bg-green-50 border border-green-200 rounded-lg p-4"> <div
v-if="successMessage"
class="bg-green-50 border border-green-200 rounded-lg p-4"
>
<p class="text-sm text-green-800 flex items-center"> <p class="text-sm text-green-800 flex items-center">
<Check :size="18" class="mr-2" /> <Check
:size="18"
class="mr-2"
/>
{{ successMessage }} {{ successMessage }}
</p> </p>
</div> </div>
@@ -62,12 +87,19 @@
:disabled="isLoading || !token || Boolean(successMessage)" :disabled="isLoading || !token || Boolean(successMessage)"
class="w-full px-6 py-3 bg-primary-600 hover:bg-primary-700 disabled:bg-gray-400 text-white font-semibold rounded-lg transition-colors flex items-center justify-center" class="w-full px-6 py-3 bg-primary-600 hover:bg-primary-700 disabled:bg-gray-400 text-white font-semibold rounded-lg transition-colors flex items-center justify-center"
> >
<Loader2 v-if="isLoading" :size="20" class="mr-2 animate-spin" /> <Loader2
v-if="isLoading"
:size="20"
class="mr-2 animate-spin"
/>
<span>{{ isLoading ? 'Wird gespeichert...' : 'Passwort speichern' }}</span> <span>{{ isLoading ? 'Wird gespeichert...' : 'Passwort speichern' }}</span>
</button> </button>
<div class="text-center"> <div class="text-center">
<NuxtLink to="/login" class="text-sm text-primary-600 hover:text-primary-700 font-medium"> <NuxtLink
to="/login"
class="text-sm text-primary-600 hover:text-primary-700 font-medium"
>
Zurück zum Login Zurück zum Login
</NuxtLink> </NuxtLink>
</div> </div>

View File

@@ -371,7 +371,10 @@ export default defineEventHandler(async (event) => {
arrayBuffer = await res.arrayBuffer() arrayBuffer = await res.arrayBuffer()
} }
} catch (templateLoadError) { } catch (templateLoadError) {
throw new Error('Template-Laden fehlgeschlagen: ' + templateLoadError.message) throw new Error(
'Template-Laden fehlgeschlagen: ' + (templateLoadError?.message || String(templateLoadError)),
{ cause: templateLoadError }
)
} }
const pdfDoc = await PDFDocument.load(arrayBuffer) const pdfDoc = await PDFDocument.load(arrayBuffer)