feature plus ux rearrangements

This commit is contained in:
JCEEE
2026-08-22 19:49:46 +01:00
parent f14f4e2ac1
commit 42b9a27ce6
44 changed files with 2020 additions and 538 deletions
+54
View File
@@ -0,0 +1,54 @@
// App-wide notices — Svelte 5 rune store (.svelte.ts). Rendered globally by
// <NoticeDialog /> in the root layout.
export type NoticeType = 'info' | 'success' | 'warning' | 'error';
export interface Notice {
id: string;
type: NoticeType;
title: string;
message?: string;
action?: { label: string; href: string };
dismissible: boolean;
}
let idCounter = 0;
class NoticeStore {
list = $state<Notice[]>([]);
add(notice: Omit<Notice, 'id'>): string {
const id = `notice-${Date.now()}-${idCounter++}`;
this.list.push({ ...notice, id });
return id;
}
remove(id: string) {
this.list = this.list.filter((n) => n.id !== id);
}
clear() {
this.list = [];
}
success(title: string, message?: string, action?: Notice['action']) {
return this.add({ type: 'success', title, message, action, dismissible: true });
}
info(title: string, message?: string, action?: Notice['action']) {
return this.add({ type: 'info', title, message, action, dismissible: true });
}
warning(title: string, message?: string, action?: Notice['action']) {
return this.add({ type: 'warning', title, message, action, dismissible: true });
}
error(title: string, message?: string, action?: Notice['action']) {
return this.add({ type: 'error', title, message, action, dismissible: true });
}
}
export const notices = new NoticeStore();
// Fire-and-forget helper — auto-dismisses after `duration` ms.
export function addAutoDismissNotice(notice: Omit<Notice, 'id'>, duration = 5000): string {
const id = notices.add({ ...notice, dismissible: true });
setTimeout(() => notices.remove(id), duration);
return id;
}