forked from UKSOURCE/cms.lams
feat(admin): implement unified submission and newsletter management
Introduce a centralized system to manage all website form submissions and newsletter subscriptions. - Add `Submission` and `NewsletterSubscription` models with MongoDB schema validation - Implement `submissionController` and `newsletterSubscriptionController` for CRUD operations and filtering - Create a unified admin UI for reviewing submissions across different sources (home, request, contact, partnership, newsletter) - Add database migration scripts for creating collections and indexes - Refactor partnership inquiry forms to use a fixed field structure - Update admin navigation and server CORS settings to support PATCH requests
This commit is contained in:
@@ -97,12 +97,6 @@
|
||||
renderPartners();
|
||||
});
|
||||
|
||||
document.getElementById("addInquiryFieldBtn")?.addEventListener("click", function () {
|
||||
state.inquiryForm.fields.push(getDefaultInquiryField());
|
||||
ensurePartnershipIds();
|
||||
renderInquiryFields();
|
||||
});
|
||||
|
||||
document.getElementById("resetPartnershipsForm")?.addEventListener("click", function () {
|
||||
window.location.reload();
|
||||
});
|
||||
@@ -378,7 +372,7 @@
|
||||
input.value = field[key] || "";
|
||||
input.addEventListener("input", function () {
|
||||
field[key] = input.value;
|
||||
if (key === "label") {
|
||||
if (key === "label") {
|
||||
title.textContent = input.value || `${inquiryFieldFields.label?.label || "Field"} ${index + 1}`;
|
||||
}
|
||||
if (key === "type") {
|
||||
@@ -401,11 +395,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
node.querySelector("[data-remove-item]").addEventListener("click", function () {
|
||||
state.inquiryForm.fields.splice(index, 1);
|
||||
renderInquiryFields();
|
||||
});
|
||||
|
||||
node.querySelector("[data-add-option]").addEventListener("click", function () {
|
||||
field.options = Array.isArray(field.options) ? field.options : [];
|
||||
field.options.push("");
|
||||
@@ -444,7 +433,6 @@
|
||||
inquiryFieldsList.appendChild(node);
|
||||
});
|
||||
|
||||
initSortable(inquiryFieldsList, state.inquiryForm.fields, renderInquiryFields, '[data-item="inquiry-field"]');
|
||||
}
|
||||
|
||||
function initSortable(container, list, rerender, draggableSelector) {
|
||||
|
||||
@@ -16,17 +16,13 @@
|
||||
<div class="mb-3">
|
||||
<div>
|
||||
<label class="form-label fw-semibold mb-1"><%= inquiryUi.fields?.label || "Form fields" %></label>
|
||||
<div class="form-text mt-0"><%= inquiryUi.fieldsHelpText || inquiryUi.fields?.helpText || "" %></div>
|
||||
<div class="form-text mt-0">
|
||||
Field structure is fixed to match the inquiry form: First Name, Last Name, Organization Name, Partnership Type, and Message. You can edit field text, required state, width, and Partnership Type select options.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="inquiryFieldsList"></div>
|
||||
<button type="button" class="cms-add-button mt-3" id="addInquiryFieldBtn">
|
||||
<i class="fas fa-plus me-2"></i><%= inquiryUi.fields?.addLabel || "Add Field" %>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -100,9 +100,6 @@
|
||||
<div class="card cms-item-card mb-3" data-item="inquiry-field">
|
||||
<div class="card-header d-flex justify-content-between align-items-center gap-2 flex-wrap">
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<button type="button" class="drag-handle" title="Drag to reorder">
|
||||
<i class="fas fa-grip-vertical"></i>
|
||||
</button>
|
||||
<div>
|
||||
<div class="fw-semibold" data-title>Field</div>
|
||||
<div class="small text-muted" data-subtitle></div>
|
||||
@@ -112,9 +109,6 @@
|
||||
<button type="button" class="cms-collapse-toggle" data-toggle-item title="Collapse item">
|
||||
<i class="fas fa-chevron-down"></i>
|
||||
</button>
|
||||
<button type="button" class="cms-remove-button" data-remove-item title="Remove item">
|
||||
<i class="fas fa-trash-alt"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@@ -129,7 +123,7 @@
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label fw-semibold"><%= inquiryFieldFields.type?.label || "Field type" %></label>
|
||||
<select class="form-select" data-field="type">
|
||||
<select class="form-select" data-field="type" disabled>
|
||||
<% (inquiryFieldFields.type?.options || []).forEach((option) => { %>
|
||||
<option value="<%= option.value %>"><%= option.label %></option>
|
||||
<% }) %>
|
||||
@@ -144,10 +138,10 @@
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4 d-flex align-items-end">
|
||||
<div class="form-check mb-2">
|
||||
<input class="form-check-input" type="checkbox" data-field="required">
|
||||
<label class="form-check-label fw-semibold"><%= inquiryFieldFields.required?.label || "Required field" %></label>
|
||||
</div>
|
||||
<div class="form-check mb-2">
|
||||
<input class="form-check-input" type="checkbox" data-field="required">
|
||||
<label class="form-check-label fw-semibold"><%= inquiryFieldFields.required?.label || "Required field" %></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12" data-options-wrap>
|
||||
<div class="cms-editor-group">
|
||||
|
||||
Reference in New Issue
Block a user