feat: Reinitialize frontend with SvelteKit and TypeScript

- Delete old Vite+Svelte frontend
- Initialize new SvelteKit project with TypeScript
- Configure Tailwind CSS v4 + DaisyUI
- Implement JWT authentication with auto-refresh
- Create login page with form validation (Zod)
- Add protected route guards
- Update Docker configuration for single-stage build
- Add E2E tests with Playwright (6/11 passing)
- Fix Svelte 5 reactivity with $state() runes

Known issues:
- 5 E2E tests failing (timing/async issues)
- Token refresh implementation needs debugging
- Validation error display timing
This commit is contained in:
2026-02-17 16:19:59 -05:00
parent 54df6018f5
commit de2d83092e
28274 changed files with 3816354 additions and 90 deletions

View File

@@ -0,0 +1,15 @@
/**
* Register later cleanup task
*
* @param {() => void} onCleanup
*/
export function addCleanupTask(onCleanup: () => void): () => void;
/** Clean up all components and elements added to the document. */
export function cleanup(): void;
/**
* Remove a cleanup task without running it.
*
* @param {() => void} onCleanup
*/
export function removeCleanupTask(onCleanup: () => void): void;
//# sourceMappingURL=cleanup.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"cleanup.d.ts","sourceRoot":"","sources":["../src/cleanup.js"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,0CAFW,MAAM,IAAI,SAAJ,IAAI,CAKpB;AAWD,kEAAkE;AAClE,gCAMC;AAhBD;;;;GAIG;AACH,6CAFW,MAAM,IAAI,QAIpB"}

View File

@@ -0,0 +1,5 @@
export * from "./cleanup.js";
export * from "./mount.js";
export * from "./render.js";
export * from "./setup.js";
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":""}

View File

@@ -0,0 +1,10 @@
/**
* Render a Svelte component into the document.
*
* @template {import('../types.js').Component} C
* @param {import('../types.js').ComponentImport<C>} Component
* @param {import('../types.js').MountOptions<C>} options
* @returns {import('../types.js').MountResult<C>}
*/
export function mount<C extends import("../types.js").Component>(Component: import("../types.js").ComponentImport<C>, options: import("../types.js").MountOptions<C>): import("../types.js").MountResult<C>;
//# sourceMappingURL=mount.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../src/mount.js"],"names":[],"mappings":"AA2EA;;;;;;;GAOG;AACH,sBAL+C,CAAC,SAAnC,OAAQ,aAAa,EAAE,SAAU,aACnC,OAAO,aAAa,EAAE,eAAe,CAAC,CAAC,CAAC,WACxC,OAAO,aAAa,EAAE,YAAY,CAAC,CAAC,CAAC,GACnC,OAAO,aAAa,EAAE,WAAW,CAAC,CAAC,CAAC,CAwBhD"}

View File

@@ -0,0 +1,12 @@
/**
* Create a shallowly reactive props object.
*
* This allows us to update props on `rerender`
* without turing `props` into a deep set of Proxy objects
*
* @template {Record<string, unknown>} Props
* @param {Props} initialProps
* @returns {[Props, (nextProps: Partial<Props>) => void]}
*/
export function createProps<Props extends Record<string, unknown>>(initialProps?: Props): [Props, (nextProps: Partial<Props>) => void];
//# sourceMappingURL=props.svelte.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"props.svelte.d.ts","sourceRoot":"","sources":["../src/props.svelte.js"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,4BAJuC,KAAK,SAA9B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAE,iBAC3B,KAAK,GACH,CAAC,KAAK,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CA0BxD"}

View File

@@ -0,0 +1,12 @@
/**
* Render a component into the document.
*
* @template {import('../types.js').Component} C
*
* @param {import('../types.js').ComponentImport<C>} Component - The component to render.
* @param {import('../types.js').ComponentOptions<C>} componentOptions - Customize how Svelte renders the component.
* @param {import('../types.js').SetupOptions} setupOptions - Customize how the document is set up.
* @returns {import('../types.js').RenderResult<C>} The rendered component.
*/
export function render<C extends import("../types.js").Component>(Component: import("../types.js").ComponentImport<C>, componentOptions: import("../types.js").ComponentOptions<C>, setupOptions?: import("../types.js").SetupOptions): import("../types.js").RenderResult<C>;
//# sourceMappingURL=render.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.js"],"names":[],"mappings":"AAGA;;;;;;;;;GASG;AACH,uBAP+C,CAAC,SAAnC,OAAQ,aAAa,EAAE,SAAU,aAEnC,OAAO,aAAa,EAAE,eAAe,CAAC,CAAC,CAAC,oBACxC,OAAO,aAAa,EAAE,gBAAgB,CAAC,CAAC,CAAC,iBACzC,OAAO,aAAa,EAAE,YAAY,GAChC,OAAO,aAAa,EAAE,YAAY,CAAC,CAAC,CAAC,CAOjD"}

View File

@@ -0,0 +1,13 @@
/**
* Set up the document to render a component.
*
* @template {import('../types.js').Component} C
* @param {import('../types.js').ComponentOptions<C>} componentOptions - props or mount options
* @param {import('../types.js').SetupOptions} setupOptions - base element of the document to bind any queries
* @returns {import('../types.js').SetupResult<C>}
*/
export function setup<C extends import("../types.js").Component>(componentOptions: import("../types.js").ComponentOptions<C>, setupOptions?: import("../types.js").SetupOptions): import("../types.js").SetupResult<C>;
export class UnknownSvelteOptionsError extends TypeError {
constructor(unknownOptions: any);
}
//# sourceMappingURL=setup.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../src/setup.js"],"names":[],"mappings":"AAsDA;;;;;;;GAOG;AACH,sBAL+C,CAAC,SAAnC,OAAQ,aAAa,EAAE,SAAU,oBACnC,OAAO,aAAa,EAAE,gBAAgB,CAAC,CAAC,CAAC,iBACzC,OAAO,aAAa,EAAE,YAAY,GAChC,OAAO,aAAa,EAAE,WAAW,CAAC,CAAC,CAAC,CAuBhD;AA1ED;IACE,iCAaC;CACF"}

View File

@@ -0,0 +1,3 @@
/** Whether we're using Svelte >= 5. */
export const IS_MODERN_SVELTE: boolean;
//# sourceMappingURL=svelte-version.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"svelte-version.d.ts","sourceRoot":"","sources":["../src/svelte-version.js"],"names":[],"mappings":"AAGA,uCAAuC;AACvC,uCAA2D"}