forked from UKSOURCE/cms.lams
Improve the CMS administration interface across multiple pages (Accreditation, Admissions, History, Partnerships, and Policies) with a focus on usability and data integrity. Key changes include: - Implement `ensureUniqueIds` utility to automatically generate and maintain unique slugs for content items, removing the need for manual ID entry in the UI. - Refactor the Admissions calculator to support detailed per-option editing via a new dedicated view and routes. - Replace basic datalists with a custom, searchable icon combobox component for better visual selection. - Update `_renderSingletonPageView` to handle active tab persistence via query parameters. - Streamline editor configurations by removing redundant fields and improving help text. - Enhance the Admissions "Key Dates" editor with a dynamic table interface for managing columns and rows. - Normalize data payloads in controllers to ensure consistent API responses and internal linking.
117 lines
3.5 KiB
JavaScript
117 lines
3.5 KiB
JavaScript
const PartnershipsPage = require("../models/partnerships");
|
|
const AUDIT_ACTIONS = require("../constants/auditAction");
|
|
const partnershipsConfig = require("../utils/contentEditors/partnershipsConfig");
|
|
const createPageContentController = require("./_createPageContentController");
|
|
const createRenderSingletonPageView = require("./_renderSingletonPageView");
|
|
const { ensureUniqueIds } = require("../utils/contentEditorIds");
|
|
|
|
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
|
|
: [];
|
|
const partners = Array.isArray(normalized?.directory?.partners)
|
|
? normalized.directory.partners
|
|
: [];
|
|
|
|
return {
|
|
...normalized,
|
|
directory: {
|
|
...normalized.directory,
|
|
partners: ensureUniqueIds(
|
|
partners,
|
|
(partner) => partner.id,
|
|
(partner, index) => partner.name || partner.category || `partner-${index + 1}`,
|
|
"partner",
|
|
),
|
|
},
|
|
inquiryForm: {
|
|
...normalized.inquiryForm,
|
|
fields: ensureUniqueIds(
|
|
fields,
|
|
(field) => field.id,
|
|
(field, index) => field.label || field.placeholder || `field-${index + 1}`,
|
|
"field",
|
|
).map((field) => ({
|
|
id: field.id,
|
|
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: 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;
|