forked from UKSOURCE/cms.lams
feat(cms): refactor page content management and implement detailed editors
Refactor the CMS page content system to use a more modular configuration-driven approach. This replaces the monolithic `pageContentConfig.js` with individual configuration files for each page and introduces a shared field utility to standardize editor components. Key changes: - Implement a generic `_renderSingletonPageView` helper to reduce duplication across controllers. - Enhance `_createPageContentController` with `normalizeForEditor`, `normalizeForApi`, and `preparePayload` hooks for custom data transformation. - Create dedicated configuration and view structures for Partnerships, History, Accreditation, Admissions, and Policies pages. - Add a specialized section editor for Policies to manage complex nested content. - Improve the frontend `page-content-editor.js` with support for visibility logic, auto-sequencing for arrays, and URL synchronization for active tabs. - Update data JSON files to align with the new schema.
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
const {
|
||||
text,
|
||||
textarea,
|
||||
image,
|
||||
icon,
|
||||
checkbox,
|
||||
url,
|
||||
combobox,
|
||||
object,
|
||||
stringList,
|
||||
objectList,
|
||||
} = require("./sharedFields");
|
||||
|
||||
module.exports = {
|
||||
key: "history",
|
||||
title: "History Management",
|
||||
subtitle: "Edit content displayed on the history page",
|
||||
routeBase: "/admin/history",
|
||||
apiPath: "/api/history",
|
||||
previewPath: "/about/history",
|
||||
dataFile: "history",
|
||||
imageType: "history",
|
||||
tabs: [
|
||||
{
|
||||
key: "highlight",
|
||||
label: "Highlight Bar",
|
||||
icon: "fas fa-star",
|
||||
schema: object("highlight", "Highlight bar", [
|
||||
icon("icon", "Highlight icon"),
|
||||
text("text", "Message", { maxLength: 110 }),
|
||||
text("linkLabel", "Link label", { maxLength: 30 }),
|
||||
url("href", "Link URL", { maxLength: 255 }),
|
||||
]),
|
||||
},
|
||||
{
|
||||
key: "hero",
|
||||
label: "Hero",
|
||||
icon: "fas fa-image",
|
||||
schema: object("hero", "Hero", [
|
||||
text("badge", "Eyebrow label", { maxLength: 40 }),
|
||||
text("title", "Headline", { maxLength: 90 }),
|
||||
textarea("description", "Supporting text", { maxLength: 220, rows: 4 }),
|
||||
]),
|
||||
},
|
||||
{
|
||||
key: "filters",
|
||||
label: "Filter Controls",
|
||||
icon: "fas fa-filter",
|
||||
schema: object("filters", "Filter controls", [
|
||||
text("yearLabel", "Year filter label", { maxLength: 30 }),
|
||||
text("categoryLabel", "Category filter label", { maxLength: 30 }),
|
||||
text("buttonLabel", "Apply button label", { maxLength: 30 }),
|
||||
stringList("yearOptions", "Year options", {
|
||||
itemLabel: "Year option",
|
||||
maxLength: 30,
|
||||
sortable: true,
|
||||
helpText: "Reorder to control the dropdown order shown to users.",
|
||||
}),
|
||||
stringList("categoryOptions", "Category options", {
|
||||
itemLabel: "Category option",
|
||||
maxLength: 40,
|
||||
sortable: true,
|
||||
}),
|
||||
]),
|
||||
},
|
||||
{
|
||||
key: "timeline",
|
||||
label: "Timeline",
|
||||
icon: "fas fa-clock-rotate-left",
|
||||
schema: object("timeline", "Timeline", [
|
||||
text("loadMoreLabel", "Load more button label", { maxLength: 40 }),
|
||||
objectList(
|
||||
"items",
|
||||
"Milestones",
|
||||
[
|
||||
text("id", "Milestone key", { maxLength: 60 }),
|
||||
text("year", "Year", { maxLength: 10 }),
|
||||
combobox("yearRange", "Year range", {
|
||||
maxLength: 30,
|
||||
optionsPath: "filters.yearOptions",
|
||||
}),
|
||||
combobox("category", "Category", {
|
||||
maxLength: 40,
|
||||
optionsPath: "filters.categoryOptions",
|
||||
}),
|
||||
text("categoryLabel", "Category badge label", { maxLength: 30 }),
|
||||
text("title", "Milestone title", { maxLength: 90 }),
|
||||
textarea("description", "Description", {
|
||||
maxLength: 260,
|
||||
rows: 4,
|
||||
}),
|
||||
image("image", "Milestone image", {
|
||||
imageHint: "Recommended 436x190 px",
|
||||
helpText: "Wide image used inside the milestone card.",
|
||||
}),
|
||||
text("imageAlt", "Image alt text", { maxLength: 120 }),
|
||||
objectList(
|
||||
"stats",
|
||||
"Stats",
|
||||
[
|
||||
text("value", "Value", { maxLength: 24 }),
|
||||
text("label", "Label", { maxLength: 50 }),
|
||||
],
|
||||
{
|
||||
itemLabel: "Stat",
|
||||
sortable: true,
|
||||
emptyText: "No stats yet.",
|
||||
},
|
||||
),
|
||||
checkbox("featured", "Featured milestone"),
|
||||
],
|
||||
{
|
||||
itemLabel: "Milestone",
|
||||
sortable: true,
|
||||
itemTitleKey: "title",
|
||||
itemSubtitleKey: "year",
|
||||
emptyText: "No milestones yet.",
|
||||
},
|
||||
),
|
||||
]),
|
||||
},
|
||||
],
|
||||
};
|
||||
Reference in New Issue
Block a user