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:
@@ -1,11 +1,102 @@
|
||||
const PartnershipsPage = require("../models/partnerships");
|
||||
const AUDIT_ACTIONS = require("../constants/auditAction");
|
||||
const pageContentConfig = require("../utils/pageContentConfig");
|
||||
const partnershipsConfig = require("../utils/contentEditors/partnershipsConfig");
|
||||
const createPageContentController = require("./_createPageContentController");
|
||||
const createRenderSingletonPageView = require("./_renderSingletonPageView");
|
||||
|
||||
module.exports = createPageContentController({
|
||||
function toInquiryField(id, field, type, width) {
|
||||
return {
|
||||
id,
|
||||
label: field?.label || "",
|
||||
placeholder: field?.placeholder || "",
|
||||
type,
|
||||
width,
|
||||
required: true,
|
||||
options: Array.isArray(field?.options) ? field.options : [],
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeInquiryForm(data) {
|
||||
if (!data?.inquiryForm) {
|
||||
return data;
|
||||
}
|
||||
|
||||
if (Array.isArray(data.inquiryForm.fields)) {
|
||||
return data;
|
||||
}
|
||||
|
||||
const legacyFields = data.inquiryForm.fields || {};
|
||||
|
||||
return {
|
||||
...data,
|
||||
inquiryForm: {
|
||||
...data.inquiryForm,
|
||||
fields: [
|
||||
toInquiryField("firstName", legacyFields.firstName, "text", "half"),
|
||||
toInquiryField("lastName", legacyFields.lastName, "text", "half"),
|
||||
toInquiryField("organization", legacyFields.organization, "text", "full"),
|
||||
toInquiryField(
|
||||
"partnershipType",
|
||||
legacyFields.partnershipType,
|
||||
"select",
|
||||
"full",
|
||||
),
|
||||
toInquiryField("message", legacyFields.message, "textarea", "full"),
|
||||
].filter((field) => field.label || field.placeholder || field.id),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function prepareInquiryPayload(payload) {
|
||||
const normalized = normalizeInquiryForm(payload);
|
||||
const fields = Array.isArray(normalized?.inquiryForm?.fields)
|
||||
? normalized.inquiryForm.fields
|
||||
: [];
|
||||
|
||||
return {
|
||||
...normalized,
|
||||
inquiryForm: {
|
||||
...normalized.inquiryForm,
|
||||
fields: fields.map((field, index) => ({
|
||||
id:
|
||||
String(field.id || `field-${index + 1}`)
|
||||
.trim()
|
||||
.replace(/\s+/g, "")
|
||||
.replace(/[^a-zA-Z0-9_-]/g, "") || `field-${index + 1}`,
|
||||
label: field.label || "",
|
||||
placeholder: field.placeholder || "",
|
||||
type: field.type || "text",
|
||||
width: field.width || "full",
|
||||
required: Boolean(field.required),
|
||||
options: Array.isArray(field.options) ? field.options.filter(Boolean) : [],
|
||||
})),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const controller = createPageContentController({
|
||||
model: PartnershipsPage,
|
||||
modelName: "PartnershipsPage",
|
||||
auditAction: AUDIT_ACTIONS.UPDATE_PARTNERSHIPS,
|
||||
editorConfig: pageContentConfig.partnerships,
|
||||
editorConfig: partnershipsConfig,
|
||||
normalizeForEditor: normalizeInquiryForm,
|
||||
normalizeForApi: normalizeInquiryForm,
|
||||
preparePayload: prepareInquiryPayload,
|
||||
});
|
||||
|
||||
controller.index = async function index(req, res) {
|
||||
try {
|
||||
return await createRenderSingletonPageView({
|
||||
model: PartnershipsPage,
|
||||
editorConfig: partnershipsConfig,
|
||||
view: "admin/partnerships/index",
|
||||
normalizeForEditor: normalizeInquiryForm,
|
||||
})(req, res);
|
||||
} catch (error) {
|
||||
console.error("partnerships index error:", error);
|
||||
req.flash("error_msg", "Error loading Partnerships Management");
|
||||
return req.session.save(() => res.redirect("/admin/dashboard"));
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = controller;
|
||||
|
||||
Reference in New Issue
Block a user