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:
@@ -0,0 +1,85 @@
|
||||
const mongoose = require("mongoose");
|
||||
|
||||
const SOURCES = ["home", "request", "contact", "partnership"];
|
||||
const STATUSES = ["new", "contacted", "info_provided", "closed"];
|
||||
|
||||
const emailPattern = /^\S+@\S+\.\S+$/;
|
||||
const phonePattern = /^[+()\d\s.-]{7,20}$/;
|
||||
|
||||
const submissionSchema = new mongoose.Schema(
|
||||
{
|
||||
source: {
|
||||
type: String,
|
||||
enum: SOURCES,
|
||||
required: [true, "Source is required"],
|
||||
},
|
||||
pageUrl: {
|
||||
type: String,
|
||||
trim: true,
|
||||
default: "",
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
required: [true, "Name is required"],
|
||||
trim: true,
|
||||
maxlength: [160, "Name cannot exceed 160 characters"],
|
||||
},
|
||||
email: {
|
||||
type: String,
|
||||
default: "",
|
||||
trim: true,
|
||||
lowercase: true,
|
||||
validate: {
|
||||
validator(value) {
|
||||
return !value || emailPattern.test(value);
|
||||
},
|
||||
message: "Please enter a valid email",
|
||||
},
|
||||
},
|
||||
phone: {
|
||||
type: String,
|
||||
trim: true,
|
||||
default: "",
|
||||
validate: {
|
||||
validator(value) {
|
||||
return !value || phonePattern.test(value);
|
||||
},
|
||||
message: "Please enter a valid phone number",
|
||||
},
|
||||
},
|
||||
payload: {
|
||||
type: mongoose.Schema.Types.Mixed,
|
||||
default: {},
|
||||
},
|
||||
status: {
|
||||
type: String,
|
||||
enum: STATUSES,
|
||||
default: "new",
|
||||
},
|
||||
internalNote: {
|
||||
type: String,
|
||||
trim: true,
|
||||
default: "",
|
||||
maxlength: [2000, "Internal note cannot exceed 2000 characters"],
|
||||
},
|
||||
ipAddress: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
userAgent: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
},
|
||||
{
|
||||
collection: "submissions",
|
||||
timestamps: true,
|
||||
autoCreate: false,
|
||||
autoIndex: false,
|
||||
},
|
||||
);
|
||||
|
||||
submissionSchema.statics.SOURCES = SOURCES;
|
||||
submissionSchema.statics.STATUSES = STATUSES;
|
||||
|
||||
module.exports = mongoose.model("Submission", submissionSchema);
|
||||
Reference in New Issue
Block a user