fix(frontend): enforce lint locally and in CI, fix all pre-existing violations
## Pre-commit hook
- Add .husky/pre-commit at repo root: runs `cd frontend && npm run lint`
- Update prepare script in package.json to auto-configure git hooks path
on npm install (git -C .. config core.hooksPath .husky)
- Add lint step to CI unit-tests job so it catches issues before tests run
- Add generated dirs to .prettierignore (paraglide_bak*, test-results, .auth)
- Add src/lib/paraglide_bak* to .gitignore so ESLint can ignore them
## ESLint fixes (all pre-existing)
- Disable svelte/no-navigation-without-resolve: false positive in SvelteKit
(rule targets Svelte 5 standalone routing, not SvelteKit <a href>)
- Fix svelte/require-each-key: add (item.id)/(item) keys to all {#each} blocks
across 10 files — improves Svelte reconciliation performance
- Fix svelte/prefer-writable-derived in PersonTypeahead: $state+$effect → $derived
- Fix svelte/prefer-svelte-reactivity: URLSearchParams → SvelteURLSearchParams,
Map → SvelteMap (enables Svelte reactive tracking)
- Fix @typescript-eslint/no-unused-vars: remove dead imports/variables
## Prettier
- Run npm run format to bring all source files in line with .prettierrc
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3,8 +3,17 @@ import { env } from '$env/dynamic/private';
|
||||
import { createApiClient } from '$lib/api.server';
|
||||
import { parseBackendError, getErrorMessage } from '$lib/errors';
|
||||
|
||||
export async function load({ fetch, locals }: { fetch: typeof globalThis.fetch; locals: App.Locals }) {
|
||||
const canWrite = locals.user?.groups?.some((g: { permissions: string[] }) => g.permissions.includes('WRITE_ALL')) ?? false;
|
||||
export async function load({
|
||||
fetch,
|
||||
locals
|
||||
}: {
|
||||
fetch: typeof globalThis.fetch;
|
||||
locals: App.Locals;
|
||||
}) {
|
||||
const canWrite =
|
||||
locals.user?.groups?.some((g: { permissions: string[] }) =>
|
||||
g.permissions.includes('WRITE_ALL')
|
||||
) ?? false;
|
||||
if (!canWrite) throw error(403, 'Forbidden');
|
||||
|
||||
const api = createApiClient(fetch);
|
||||
|
||||
@@ -74,7 +74,9 @@ function handleDateInput(e: Event) {
|
||||
<form method="POST" enctype="multipart/form-data" use:enhance class="space-y-6 pb-20">
|
||||
<!-- ── Section 1: Wer & Wann ── -->
|
||||
<div class="rounded-sm border border-brand-sand bg-white p-6 shadow-sm">
|
||||
<h2 class="mb-5 text-xs font-bold tracking-widest text-gray-400 uppercase">{m.doc_section_who_when()}</h2>
|
||||
<h2 class="mb-5 text-xs font-bold tracking-widest text-gray-400 uppercase">
|
||||
{m.doc_section_who_when()}
|
||||
</h2>
|
||||
|
||||
<div class="grid grid-cols-1 gap-5 md:grid-cols-2">
|
||||
<!-- Datum -->
|
||||
@@ -104,7 +106,9 @@ function handleDateInput(e: Event) {
|
||||
|
||||
<!-- Ort -->
|
||||
<div>
|
||||
<label for="location" class="mb-1 block text-sm font-medium text-gray-700">{m.form_label_location()}</label>
|
||||
<label for="location" class="mb-1 block text-sm font-medium text-gray-700"
|
||||
>{m.form_label_location()}</label
|
||||
>
|
||||
<input
|
||||
id="location"
|
||||
type="text"
|
||||
@@ -129,12 +133,16 @@ function handleDateInput(e: Event) {
|
||||
|
||||
<!-- ── Section 2: Beschreibung ── -->
|
||||
<div class="rounded-sm border border-brand-sand bg-white p-6 shadow-sm">
|
||||
<h2 class="mb-5 text-xs font-bold tracking-widest text-gray-400 uppercase">{m.doc_section_description()}</h2>
|
||||
<h2 class="mb-5 text-xs font-bold tracking-widest text-gray-400 uppercase">
|
||||
{m.doc_section_description()}
|
||||
</h2>
|
||||
|
||||
<div class="space-y-5">
|
||||
<!-- Titel -->
|
||||
<div>
|
||||
<label for="title" class="mb-1 block text-sm font-medium text-gray-700">{m.form_label_title()} *</label>
|
||||
<label for="title" class="mb-1 block text-sm font-medium text-gray-700"
|
||||
>{m.form_label_title()} *</label
|
||||
>
|
||||
<input
|
||||
id="title"
|
||||
type="text"
|
||||
@@ -168,7 +176,9 @@ function handleDateInput(e: Event) {
|
||||
|
||||
<!-- Inhalt -->
|
||||
<div>
|
||||
<label for="summary" class="mb-1 block text-sm font-medium text-gray-700">{m.form_label_content()}</label>
|
||||
<label for="summary" class="mb-1 block text-sm font-medium text-gray-700"
|
||||
>{m.form_label_content()}</label
|
||||
>
|
||||
<textarea
|
||||
id="summary"
|
||||
name="summary"
|
||||
@@ -182,7 +192,9 @@ function handleDateInput(e: Event) {
|
||||
|
||||
<!-- ── Section 3: Transkription ── -->
|
||||
<div class="rounded-sm border border-brand-sand bg-white p-6 shadow-sm">
|
||||
<h2 class="mb-5 text-xs font-bold tracking-widest text-gray-400 uppercase">{m.form_label_transcription()}</h2>
|
||||
<h2 class="mb-5 text-xs font-bold tracking-widest text-gray-400 uppercase">
|
||||
{m.form_label_transcription()}
|
||||
</h2>
|
||||
<textarea
|
||||
id="transcription"
|
||||
name="transcription"
|
||||
@@ -194,10 +206,13 @@ function handleDateInput(e: Event) {
|
||||
|
||||
<!-- ── Section 4: Datei ── -->
|
||||
<div class="rounded-sm border border-brand-sand bg-white p-6 shadow-sm">
|
||||
<h2 class="mb-5 text-xs font-bold tracking-widest text-gray-400 uppercase">{m.doc_section_file()}</h2>
|
||||
<h2 class="mb-5 text-xs font-bold tracking-widest text-gray-400 uppercase">
|
||||
{m.doc_section_file()}
|
||||
</h2>
|
||||
|
||||
<label for="file-upload" class="mb-1 block text-sm font-medium text-gray-700">
|
||||
{m.doc_file_upload_label()} <span class="font-normal text-gray-400">({m.doc_file_upload_note()})</span>
|
||||
{m.doc_file_upload_label()}
|
||||
<span class="font-normal text-gray-400">({m.doc_file_upload_note()})</span>
|
||||
</label>
|
||||
<input
|
||||
id="file-upload"
|
||||
|
||||
Reference in New Issue
Block a user