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,53 @@
import * as PropertySymbol from '../PropertySymbol.js';
/**
* Storage.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/Storage
*/
export default class Storage {
[PropertySymbol.data]: {
[key: string]: string;
};
/**
* Constructor.
*/
constructor();
/**
* Returns length.
*
* @returns Length.
*/
get length(): number;
/**
* Returns name of the nth key.
*
* @param index Index.
* @returns Name.
*/
key(index: number): string | null;
/**
* Sets item.
*
* @param name Name.
* @param item Item.
*/
setItem(name: string, item: string): void;
/**
* Returns item.
*
* @param name Name.
* @returns Item.
*/
getItem(name: string): string | null;
/**
* Removes item.
*
* @param name Name.
*/
removeItem(name: string): void;
/**
* Clears storage.
*/
clear(): void;
}
//# sourceMappingURL=Storage.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"Storage.d.ts","sourceRoot":"","sources":["../../src/storage/Storage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,cAAc,MAAM,sBAAsB,CAAC;AAEvD;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,OAAO;IACpB,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAM;IAE7D;;OAEG;;IA6EH;;;;OAIG;IACH,IAAW,MAAM,IAAI,MAAM,CAE1B;IAED;;;;;OAKG;IACI,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKxC;;;;;OAKG;IACI,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAIhD;;;;;OAKG;IACI,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAI3C;;;;OAIG;IACI,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIrC;;OAEG;IACI,KAAK,IAAI,IAAI;CAMpB"}

132
frontend/node_modules/happy-dom/lib/storage/Storage.js generated vendored Normal file
View File

@@ -0,0 +1,132 @@
import ClassMethodBinder from '../utilities/ClassMethodBinder.js';
import * as PropertySymbol from '../PropertySymbol.js';
/**
* Storage.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/Storage
*/
export default class Storage {
[PropertySymbol.data] = {};
/**
* Constructor.
*/
constructor() {
const data = this[PropertySymbol.data];
const methodBinder = new ClassMethodBinder(this, [Storage]);
return new Proxy(this, {
get: (target, property) => {
if (property in target || typeof property === 'symbol') {
methodBinder.bind(property);
return target[property];
}
if (property in data) {
return data[property];
}
},
set(target, property, newValue) {
methodBinder.bind(property);
if (property in target || typeof property === 'symbol') {
return true;
}
data[String(property)] = String(newValue);
return true;
},
deleteProperty(_target, property) {
if (property in data) {
delete data[String(property)];
return true;
}
return false;
},
ownKeys() {
return Object.keys(data);
},
has(target, property) {
if (property in target || property in data) {
return true;
}
return false;
},
defineProperty(target, property, descriptor) {
methodBinder.preventBinding(property);
if (property in target) {
Object.defineProperty(target, property, descriptor);
return true;
}
if (descriptor.value !== undefined) {
data[String(property)] = String(descriptor.value);
return true;
}
return false;
},
getOwnPropertyDescriptor(target, property) {
if (property in target) {
return;
}
const value = data[String(property)];
if (value !== undefined) {
return {
value: value,
writable: true,
enumerable: true,
configurable: true
};
}
}
});
}
/**
* Returns length.
*
* @returns Length.
*/
get length() {
return Object.keys(this[PropertySymbol.data]).length;
}
/**
* Returns name of the nth key.
*
* @param index Index.
* @returns Name.
*/
key(index) {
const name = Object.keys(this[PropertySymbol.data])[index];
return name !== undefined ? name : null;
}
/**
* Sets item.
*
* @param name Name.
* @param item Item.
*/
setItem(name, item) {
this[PropertySymbol.data][name] = String(item);
}
/**
* Returns item.
*
* @param name Name.
* @returns Item.
*/
getItem(name) {
return this[PropertySymbol.data][name] !== undefined ? this[PropertySymbol.data][name] : null;
}
/**
* Removes item.
*
* @param name Name.
*/
removeItem(name) {
delete this[PropertySymbol.data][name];
}
/**
* Clears storage.
*/
clear() {
const data = this[PropertySymbol.data];
for (const key of Object.keys(data)) {
delete data[key];
}
}
}
//# sourceMappingURL=Storage.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"Storage.js","sourceRoot":"","sources":["../../src/storage/Storage.ts"],"names":[],"mappings":"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"}