mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-10-31 08:13:50 +00:00
The demo user becomes Nora Lindqvist, engineering lead at Meridian Labs, in the week of a product launch. The fixtures tell one story across mail, contacts, calendar, tasks and files, and exercise the features the screenshots and the public demo should show: - a second, mail-only login (her personal domain) and the shared Support mailbox delegated to the work account, so the account switcher, the shared section and the merged inbox have real content - raw headers the way Stalwart writes them: the sender check fails on the phishing mail, newsletters carry a one-click unsubscribe, one mail asks for a read receipt, and spam scores show in the details - an iMIP invitation with a served .ics, an event waiting for the answer on the calendar, and RSVP patches applied in the demo client - @mentions as mailto links in a received mail, a verification code twelve minutes old, nested folders, named tags on the mail, contact groups, a scheduled message and tasks switched on - every attachment and file backed by real bytes under public/demo, generated by `scripts/demo-assets/generate.mjs`; contact photos are bundled portraits instead of requests to randomuser.me - folder counts computed from the mail instead of hand-kept numbers Demo login seeds the tags, templates and merged-inbox settings once per device and switches the cross-account gate on for the session; "Reset" restores them. `bulwark-demo-simulate=off` in localStorage stops the simulated incoming mail for screenshot runs.
48 lines
1.7 KiB
TypeScript
48 lines
1.7 KiB
TypeScript
let demoIdCounter = 0;
|
|
|
|
/** Generate a unique demo ID with the given prefix. */
|
|
export function generateDemoId(prefix: string = 'demo'): string {
|
|
return `${prefix}-${Date.now()}-${++demoIdCounter}`;
|
|
}
|
|
|
|
/**
|
|
* Generate an ISO date string relative to "now".
|
|
* @param daysOffset - whole days from today
|
|
* @param hoursOffset - additional hours offset (default 0)
|
|
* @param minutesOffset - additional minutes offset (default 0)
|
|
*/
|
|
export function demoDate(daysOffset: number, hoursOffset: number = 0, minutesOffset: number = 0): string {
|
|
const d = new Date();
|
|
d.setDate(d.getDate() + daysOffset);
|
|
d.setHours(d.getHours() + hoursOffset, d.getMinutes() + minutesOffset, 0, 0);
|
|
return d.toISOString();
|
|
}
|
|
|
|
/**
|
|
* Generate a local date-time string (YYYY-MM-DDTHH:mm:ss) for JSCalendar "start" fields.
|
|
*/
|
|
export function demoISODate(daysOffset: number, hours: number = 0, minutes: number = 0): string {
|
|
const d = new Date();
|
|
d.setDate(d.getDate() + daysOffset);
|
|
d.setHours(hours, minutes, 0, 0);
|
|
const pad = (n: number) => String(n).padStart(2, '0');
|
|
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}:00`;
|
|
}
|
|
|
|
/**
|
|
* The UTC instant of a local wall-clock time on a day relative to today
|
|
* (`demoAt(1, 14)` is tomorrow 14:00 local, as an ISO string). Pairs with
|
|
* demoISODate for JSCalendar utcStart/utcEnd.
|
|
*/
|
|
export function demoAt(daysOffset: number, hours: number = 0, minutes: number = 0): string {
|
|
const d = new Date();
|
|
d.setDate(d.getDate() + daysOffset);
|
|
d.setHours(hours, minutes, 0, 0);
|
|
return d.toISOString();
|
|
}
|
|
|
|
/** Deep clone fixture data so in-memory mutations don't corrupt originals. */
|
|
export function cloneFixtures<T>(data: T): T {
|
|
return JSON.parse(JSON.stringify(data));
|
|
}
|