Skip to content

Commit 002d60d

Browse files
Merge pull request #2255 from OneCommunityGlobal/veda-job-application-form-page
Veda job application form page
2 parents 2ce9133 + 2442b70 commit 002d60d

3 files changed

Lines changed: 102 additions & 0 deletions

File tree

src/controllers/collaborationController.js

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
const mongoose = require('mongoose');
12
const Form = require('../models/JobFormsModel');
23
const Response = require('../models/jobApplicationsModel');
4+
const upload = require('../middleware/multerMiddleware');
35
const QuestionSet = require('../models/questionSet');
46
const {
57
canManageJobForms,
@@ -161,6 +163,94 @@ exports.updateFormFormat = async (req, res) => {
161163
}
162164
};
163165

166+
// Submit a job application for a form (public — applicants)
167+
exports.submitJobApplication = async (req, res) => {
168+
try {
169+
const { formId } = req.params;
170+
let payload = {};
171+
try {
172+
payload = JSON.parse(req.body.payload || '{}');
173+
} catch (parseError) {
174+
return res.status(400).json({ message: 'Invalid application payload.' });
175+
}
176+
177+
const form = await Form.findById(formId);
178+
if (!form) {
179+
return res.status(404).json({ message: 'Form not found.' });
180+
}
181+
182+
const { applicantName, applicantEmail, answers: answersPayload = [], profile = {} } = payload;
183+
if (!applicantEmail || !String(applicantEmail).trim()) {
184+
return res.status(400).json({ message: 'Email is required.' });
185+
}
186+
187+
const fileByField = {};
188+
(req.files || []).forEach((file) => {
189+
fileByField[file.fieldname] = file;
190+
});
191+
192+
const builtAnswers = answersPayload.map(({ questionId, answer }) => {
193+
const qIdStr = questionId ? String(questionId) : '';
194+
const uploaded = qIdStr ? fileByField[`questionFile_${qIdStr}`] : null;
195+
if (uploaded) {
196+
return {
197+
questionId: questionId || new mongoose.Types.ObjectId(),
198+
answer: {
199+
fileName: uploaded.originalname,
200+
mimeType: uploaded.mimetype,
201+
size: uploaded.size,
202+
},
203+
};
204+
}
205+
return {
206+
questionId: questionId || new mongoose.Types.ObjectId(),
207+
answer,
208+
};
209+
});
210+
211+
const { resume } = fileByField;
212+
if (resume) {
213+
builtAnswers.push({
214+
questionId: new mongoose.Types.ObjectId(),
215+
answer: {
216+
type: 'resume',
217+
fileName: resume.originalname,
218+
mimeType: resume.mimetype,
219+
size: resume.size,
220+
},
221+
});
222+
}
223+
224+
builtAnswers.push({
225+
questionId: new mongoose.Types.ObjectId(),
226+
answer: {
227+
type: 'applicantProfile',
228+
applicantName,
229+
applicantEmail,
230+
...profile,
231+
},
232+
});
233+
234+
const submission = new Response({
235+
formId,
236+
respondent: String(applicantEmail).trim(),
237+
answers: builtAnswers,
238+
});
239+
240+
await submission.save();
241+
242+
res.status(201).json({
243+
message: 'Application submitted successfully.',
244+
responseId: submission._id,
245+
});
246+
} catch (error) {
247+
console.error('Error submitting job application:', error);
248+
res.status(500).json({ message: 'Error submitting application.', error: error.message });
249+
}
250+
};
251+
252+
exports.submitJobApplicationMiddleware = upload.any();
253+
164254
// Get all responses of a form
165255
exports.getFormResponses = async (req, res) => {
166256
try {

src/routes/collaborationRouter.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ router.get('/jobforms/:formId', formController.getFormFormat);
1717
// Get all responses of a form
1818
router.get('/jobforms/:formId/responses', formController.getFormResponses);
1919

20+
// Submit a job application (public)
21+
router.post(
22+
'/jobforms/:formId/responses',
23+
formController.submitJobApplicationMiddleware,
24+
formController.submitJobApplication,
25+
);
26+
2027
// Question management routes
2128
router.post('/jobforms/:formId/questions', formController.addQuestion);
2229
router.patch('/jobforms/:formId/questions/:questionIndex', formController.updateQuestion);

src/startup/middleware.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ module.exports = function (app) {
7979
return;
8080
}
8181

82+
if (/^\/api\/jobforms\/[^/]+\/responses$/.test(req.originalUrl) && req.method === 'POST') {
83+
next();
84+
return;
85+
}
86+
8287
if (req.originalUrl.startsWith('/api/bluesky')) {
8388
next();
8489
return;

0 commit comments

Comments
 (0)