Improve about page guidance and onboarding visuals

This commit is contained in:
Shinuwa 2026-08-13 23:56:30 +02:00
parent 48dcc8182c
commit 9248b5d075
15 changed files with 610 additions and 173 deletions

View file

@ -99,12 +99,18 @@ export function validateSiteContent(site) {
"about.eyebrow",
"about.title",
"about.description",
"about.sectionsEyebrow",
"about.sectionsTitle",
"about.toolsTitle",
"about.toolsIntro",
"about.toolsLibraryLink",
"about.limitsTitle",
"about.contribute.eyebrow",
"about.contribute.title",
"about.contribute.image",
"about.contribute.imageAlt",
"about.contribute.description",
"about.contribute.exampleIntro",
"about.contribute.example",
"about.contribute.promptTitle",
"about.contribute.promptIntro",
@ -521,17 +527,62 @@ export function validateSiteContent(site) {
assert.ok(Array.isArray(aboutSections), "about.sections must be an array");
assert.ok(aboutSections.length >= 2, "about.sections must contain at least 2 items");
aboutSections.forEach((section) => {
assertNonEmptyString({ section }, "section.icon");
assertNonEmptyString({ section }, "section.image");
assertNonEmptyString({ section }, "section.title");
assertNonEmptyString({ section }, "section.text");
if (section.afterText) {
assertNonEmptyString({ section }, "section.afterText");
}
if (section.warning) {
assertNonEmptyString({ section }, "section.warning");
}
if (section.bullets) {
assert.ok(Array.isArray(section.bullets), "section.bullets must be an array");
assert.ok(section.bullets.length >= 1, "section.bullets must not be empty");
if (section.bulletsColumns) {
assert.ok([1, 2].includes(section.bulletsColumns), "section.bulletsColumns must be 1 or 2");
}
section.bullets.forEach((bullet, bulletIndex) => {
assert.equal(typeof bullet, "string", `section.bullets[${bulletIndex}] must be a string`);
assert.ok(bullet.trim(), `section.bullets[${bulletIndex}] must not be empty`);
});
}
});
const aboutTools = valueAt(site, "about.tools");
assert.ok(Array.isArray(aboutTools), "about.tools must be an array");
assert.ok(aboutTools.length >= 1, "about.tools must contain at least 1 item");
aboutTools.forEach((tool) => {
assertNonEmptyString({ tool }, "tool.icon");
assertNonEmptyString({ tool }, "tool.name");
assertNonEmptyString({ tool }, "tool.description");
const aboutToolGroups = valueAt(site, "about.toolGroups");
assert.ok(Array.isArray(aboutToolGroups), "about.toolGroups must be an array");
assert.ok(aboutToolGroups.length >= 3, "about.toolGroups must contain at least 3 items");
aboutToolGroups.forEach((group, index) => {
assertNonEmptyString({ group }, "group.icon");
assertNonEmptyString({ group }, "group.title");
assertNonEmptyString({ group }, "group.text");
assert.ok(Array.isArray(group.examples), `about.toolGroups[${index}].examples must be an array`);
assert.ok(group.examples.length >= 1, `about.toolGroups[${index}].examples must not be empty`);
group.examples.forEach((example, exampleIndex) => {
assert.equal(typeof example, "string", `about.toolGroups[${index}].examples[${exampleIndex}] must be a string`);
assert.ok(example.trim(), `about.toolGroups[${index}].examples[${exampleIndex}] must not be empty`);
});
});
const contributeBlocks = valueAt(site, "about.contribute.blocks");
assert.ok(Array.isArray(contributeBlocks), "about.contribute.blocks must be an array");
assert.equal(contributeBlocks.length, 3, "about.contribute.blocks must contain 3 items");
contributeBlocks.forEach((block, index) => {
assertNonEmptyString({ block }, "block.icon");
assertNonEmptyString({ block }, "block.title");
assertNonEmptyString({ block }, "block.text");
if (block.note) {
assertNonEmptyString({ block }, "block.note");
}
if (block.bullets) {
assert.ok(Array.isArray(block.bullets), `about.contribute.blocks[${index}].bullets must be an array`);
assert.ok(block.bullets.length >= 1, `about.contribute.blocks[${index}].bullets must not be empty`);
block.bullets.forEach((bullet, bulletIndex) => {
assert.equal(typeof bullet, "string", `about.contribute.blocks[${index}].bullets[${bulletIndex}] must be a string`);
assert.ok(bullet.trim(), `about.contribute.blocks[${index}].bullets[${bulletIndex}] must not be empty`);
});
}
});
const onboardingCards = valueAt(site, "home.onboarding.cards");

View file

@ -72,7 +72,8 @@ test("vite entrypoint and app shell are wired", async () => {
assert.match(aboutPage, /export function AboutPage/);
assert.match(aboutPage, /HomeOnboardingSection/);
assert.match(aboutPage, /siteContent\.home\.onboarding/);
assert.match(aboutPage, /module-icon-\$\{tool\.icon \|\| "notepad"\}/);
assert.match(aboutPage, /module-icon-\$\{group\.icon \|\| "notepad"\}/);
assert.match(aboutPage, /about-tool-examples/);
assert.match(libraryPage, /export function LibraryPage/);
assert.match(libraryPage, /LIBRARY_TOOLBOX_ID/);
assert.match(libraryPage, /TaskPlannerModule/);
@ -133,9 +134,15 @@ test("legacy icons and primary images are available", async () => {
await readFile("website/public/static/icons/rubber.svg", "utf8");
await readFile("website/public/static/icons/trashcan.svg", "utf8");
await readFile("website/public/static/icons/zoom.svg", "utf8");
await readFile("website/public/static/icons/warning.svg", "utf8");
await readFile("website/public/favicon.ico");
await readFile("website/public/static/img/dragon-home.png");
await readFile("website/public/static/img/dragon-sidebar.png");
await readFile("website/public/static/img/dragon-dual-monitor.png");
await readFile("website/public/static/img/dragon-session-tools.png");
await readFile("website/public/static/img/dragon-game-guides.png");
await readFile("website/public/static/img/dragon-local-data.png");
await readFile("website/public/static/img/dragon-contribution-data.png");
await readFile("website/public/static/img/dragon-gameguide.png");
await readFile("website/public/static/img/dragon-toolbox.png");
await readFile("website/public/static/img/onboarding/toolbox-overview.png");