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,78 @@
import CSSStyleSheet from '../../css/CSSStyleSheet.js';
import * as PropertySymbol from '../../PropertySymbol.js';
import SVGElement from '../svg-element/SVGElement.js';
/**
* SVG Style Element.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/SVGStyleElement
*/
export default class SVGStyleElement extends SVGElement {
[PropertySymbol.sheet]: CSSStyleSheet | null;
[PropertySymbol.styleNode]: this;
[PropertySymbol.disabled]: boolean;
/**
* Returns media.
*
* @returns Media.
*/
get media(): string;
/**
* Sets media.
*
* @param media Media.
*/
set media(media: string);
/**
* Returns type.
*
* @deprecated
* @returns Type.
*/
get type(): string;
/**
* Sets type.
*
* @deprecated
* @param type Type.
*/
set type(type: string);
/**
* Returns title.
*
* @returns Title.
*/
get title(): string;
/**
* Sets title.
*
* @param title Title.
*/
set title(title: string);
/**
* Returns disabled.
*
* @returns Disabled.
*/
get disabled(): boolean;
/**
* Sets disabled.
*
* @param disabled Disabled.
*/
set disabled(disabled: boolean);
/**
* Returns style.
*
* @returns Style.
*/
get sheet(): CSSStyleSheet;
/**
* @override
*/
[PropertySymbol.disconnectedFromDocument](): void;
/**
* Updates the CSSStyleSheet with the text content.
*/
[PropertySymbol.updateSheet](): void;
}
//# sourceMappingURL=SVGStyleElement.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"SVGStyleElement.d.ts","sourceRoot":"","sources":["../../../src/nodes/svg-style-element/SVGStyleElement.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,4BAA4B,CAAC;AACvD,OAAO,KAAK,cAAc,MAAM,yBAAyB,CAAC;AAC1D,OAAO,UAAU,MAAM,8BAA8B,CAAC;AAEtD;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,UAAU;IAE/C,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,aAAa,GAAG,IAAI,CAAQ;IACpD,CAAC,cAAc,CAAC,SAAS,CAAC,OAAQ;IAClC,CAAC,cAAc,CAAC,QAAQ,CAAC,UAAS;IAEzC;;;;OAIG;IACH,IAAW,KAAK,IAAI,MAAM,CAEzB;IAED;;;;OAIG;IACH,IAAW,KAAK,CAAC,KAAK,EAAE,MAAM,EAE7B;IAED;;;;;OAKG;IACH,IAAW,IAAI,IAAI,MAAM,CAExB;IAED;;;;;OAKG;IACH,IAAW,IAAI,CAAC,IAAI,EAAE,MAAM,EAE3B;IAED;;;;OAIG;IACH,IAAW,KAAK,IAAI,MAAM,CAEzB;IAED;;;;OAIG;IACH,IAAW,KAAK,CAAC,KAAK,EAAE,MAAM,EAE7B;IAED;;;;OAIG;IACH,IAAW,QAAQ,IAAI,OAAO,CAE7B;IAED;;;;OAIG;IACH,IAAW,QAAQ,CAAC,QAAQ,EAAE,OAAO,EAEpC;IAED;;;;OAIG;IACH,IAAW,KAAK,IAAI,aAAa,CAWhC;IAED;;OAEG;IACa,CAAC,cAAc,CAAC,wBAAwB,CAAC,IAAI,IAAI;IAKjE;;OAEG;IACI,CAAC,cAAc,CAAC,WAAW,CAAC,IAAI,IAAI;CAK3C"}

View File

@@ -0,0 +1,110 @@
import * as PropertySymbol from '../../PropertySymbol.js';
import SVGElement from '../svg-element/SVGElement.js';
/**
* SVG Style Element.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/SVGStyleElement
*/
export default class SVGStyleElement extends SVGElement {
// Internal properties
[PropertySymbol.sheet] = null;
[PropertySymbol.styleNode] = this;
[PropertySymbol.disabled] = false;
/**
* Returns media.
*
* @returns Media.
*/
get media() {
return this.getAttribute('media') || 'all';
}
/**
* Sets media.
*
* @param media Media.
*/
set media(media) {
this.setAttribute('media', media);
}
/**
* Returns type.
*
* @deprecated
* @returns Type.
*/
get type() {
return this.getAttribute('type') || 'text/css';
}
/**
* Sets type.
*
* @deprecated
* @param type Type.
*/
set type(type) {
this.setAttribute('type', type);
}
/**
* Returns title.
*
* @returns Title.
*/
get title() {
return this.getAttribute('title') || '';
}
/**
* Sets title.
*
* @param title Title.
*/
set title(title) {
this.setAttribute('title', title);
}
/**
* Returns disabled.
*
* @returns Disabled.
*/
get disabled() {
return this[PropertySymbol.disabled];
}
/**
* Sets disabled.
*
* @param disabled Disabled.
*/
set disabled(disabled) {
this[PropertySymbol.disabled] = Boolean(disabled);
}
/**
* Returns style.
*
* @returns Style.
*/
get sheet() {
if (!this[PropertySymbol.isConnected]) {
return null;
}
if (!this[PropertySymbol.sheet]) {
this[PropertySymbol.sheet] = new this[PropertySymbol.ownerDocument][PropertySymbol.window].CSSStyleSheet();
this[PropertySymbol.sheet].replaceSync(this.textContent);
}
return this[PropertySymbol.sheet];
}
/**
* @override
*/
[PropertySymbol.disconnectedFromDocument]() {
super[PropertySymbol.disconnectedFromDocument]();
this[PropertySymbol.sheet] = null;
}
/**
* Updates the CSSStyleSheet with the text content.
*/
[PropertySymbol.updateSheet]() {
if (this[PropertySymbol.sheet]) {
this[PropertySymbol.sheet].replaceSync(this.textContent);
}
}
}
//# sourceMappingURL=SVGStyleElement.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"SVGStyleElement.js","sourceRoot":"","sources":["../../../src/nodes/svg-style-element/SVGStyleElement.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,cAAc,MAAM,yBAAyB,CAAC;AAC1D,OAAO,UAAU,MAAM,8BAA8B,CAAC;AAEtD;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,UAAU;IACtD,sBAAsB;IACf,CAAC,cAAc,CAAC,KAAK,CAAC,GAAyB,IAAI,CAAC;IACpD,CAAC,cAAc,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;IAClC,CAAC,cAAc,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC;IAEzC;;;;OAIG;IACH,IAAW,KAAK;QACf,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC;IAC5C,CAAC;IAED;;;;OAIG;IACH,IAAW,KAAK,CAAC,KAAa;QAC7B,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACnC,CAAC;IAED;;;;;OAKG;IACH,IAAW,IAAI;QACd,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC;IAChD,CAAC;IAED;;;;;OAKG;IACH,IAAW,IAAI,CAAC,IAAY;QAC3B,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACH,IAAW,KAAK;QACf,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IACzC,CAAC;IAED;;;;OAIG;IACH,IAAW,KAAK,CAAC,KAAa;QAC7B,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACnC,CAAC;IAED;;;;OAIG;IACH,IAAW,QAAQ;QAClB,OAAO,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IACtC,CAAC;IAED;;;;OAIG;IACH,IAAW,QAAQ,CAAC,QAAiB;QACpC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnD,CAAC;IAED;;;;OAIG;IACH,IAAW,KAAK;QACf,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,CAAC;YACvC,OAAO,IAAI,CAAC;QACb,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;YACjC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,CAClE,cAAc,CAAC,MAAM,CACrB,CAAC,aAAa,EAAE,CAAC;YAClB,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC1D,CAAC;QACD,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;IAED;;OAEG;IACa,CAAC,cAAc,CAAC,wBAAwB,CAAC;QACxD,KAAK,CAAC,cAAc,CAAC,wBAAwB,CAAC,EAAE,CAAC;QACjD,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;IACnC,CAAC;IAED;;OAEG;IACI,CAAC,cAAc,CAAC,WAAW,CAAC;QAClC,IAAI,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;YAChC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC1D,CAAC;IACF,CAAC;CACD"}