tinfo-web-server / controllers /admissionController.js
Faridaqurr
initial backend
e8c33fa
Raw
History Blame Contribute Delete
11.1 kB
const Admission = require('../models/Admission');
const { asyncController } = require('../utils/asyncController');
const stripHtml = (value) => String(value || '').replace(/<[^>]*>/g, '');
const isValidHttpUrl = (url) => /^https?:\/\//i.test(String(url || ''));
const sanitizeAdmissionType = (obj) => ({
description: stripHtml(String((obj && obj.description) || '').trim()),
learnMoreUrl: String((obj && obj.learnMoreUrl) || '').trim(),
});
const DEFAULT_DATA = {
undergraduate: { description: '', learnMoreUrl: '' },
snbt: { description: '', learnMoreUrl: '' },
snbp: { description: '', learnMoreUrl: '' },
overview: {
paragraphs: [
'Welcome to the Department of Information Technology admissions portal. We are excited that you are considering joining our vibrant academic community.',
'Our admissions process is designed to identify students who demonstrate academic excellence, passion for technology, creative problem-solving abilities, and the potential to contribute to our diverse learning environment.',
'We offer comprehensive programs at both undergraduate and graduate levels, providing students with cutting-edge knowledge and hands-on experience in various areas of information technology.',
],
whyChooseItems: [
'Industry-aligned curriculum with latest technologies',
'Experienced faculty with real-world expertise',
'State-of-the-art laboratories and facilities',
'Strong industry partnerships and internship opportunities',
'95% graduation rate and 92% employment rate',
],
officialPageUrl: '',
},
requirements: {
items: [
'High school diploma or equivalent with strong grades in mathematics and science',
'Minimum GPA of 3.0 on a 4.0 scale',
'Standardized test scores (SAT/ACT) or equivalent',
'Two letters of recommendation from teachers or academic advisors',
'Personal statement or essay (500-750 words)',
'Transcripts from all previously attended institutions',
'English language proficiency test (for international students)',
],
},
procedure: {
steps: [
{ title: 'Complete Online Application', description: 'Fill out the online application form with accurate personal and academic information' },
{ title: 'Submit Required Documents', description: 'Upload transcripts, test scores, letters of recommendation, and personal statement' },
{ title: 'Pay Application Fee', description: 'Submit the non-refundable application fee of $75 (fee waivers available for eligible students)' },
{ title: 'Application Review', description: 'Our admissions committee will review your application materials (2-4 weeks)' },
{ title: 'Interview (if required)', description: 'Selected candidates may be invited for an interview with faculty members' },
{ title: 'Admission Decision', description: 'Receive your admission decision via email and through the application portal' },
{ title: 'Accept Offer & Enroll', description: 'Accept your offer of admission and complete enrollment procedures' },
],
},
deadlines: {
note: 'All deadlines are at 11:59 PM in your local time zone. We encourage you to submit your application well before the deadline to avoid any technical issues.',
semesters: [
{
name: 'Fall Semester',
dates: [
{ label: 'Early Action', value: 'November 1, 2025' },
{ label: 'Regular Decision', value: 'January 15, 2026' },
{ label: 'Notification Date', value: 'March 31, 2026' },
],
},
{
name: 'Spring Semester',
dates: [
{ label: 'Regular Decision', value: 'October 1, 2025' },
{ label: 'Notification Date', value: 'November 15, 2025' },
],
},
],
},
otherInfo: {
items: [
{ title: 'PROGRAM STUDI', icon: 'trophy', iconBg: 'bg-orange-100', iconColor: 'text-orange-600', photoUrl: '', fullPhotoUrl: '', content: 'Secara umum computing adalah suatu bidang ilmu yang mempelajari bagaimana menciptakan dan memanfaatkan komputer. Dengan demikian, computing ini bisa diartikan sebagai bidang ilmu yang mempelajari bagaimana merancang dan membangun perangkat keras dan perangkat lunak sistem untuk berbagai tujuan, antara lain pengolahan data, pengelolaan informasi; membuat sistem komputer berperilaku cerdas; mengirimkan data melalui saluran komunikasi data, berbagi pakai media hiburan, mencari dan menemukan informasi yang relevan dan lain-lain.\nMenurut ACM dan IEEE-CS tahun 2005, ilmu komputing dibedakan menjadi 5 bidang, yakni: Teknik Komputer (CE - Computer Engineering), Informatika (cs \u2013 Computer Science), Sistem Informasi (IS - Information System), Teknologi Informasi (IT - Information Technology) dan Rekayasa Perangkat Lunak (SE - Software Engineering).\nTeknologi Informasi diharapkan lebih mampu melakukan perencanaan dan pengelolaan teknologi informasi yang aman, meliputi instalasi, integrasi, kastamisasi, dan pemeliharaan. Serta fokus pada metodologi pemanfaatan teknologi infrastruktur terkini.' },
{ title: 'PERATURAN AKADEMIK', icon: 'badge', iconBg: 'bg-blue-100', iconColor: 'text-blue-600', photoUrl: '', fullPhotoUrl: '', content: '' },
{ title: 'KALENDER AKADEMIK', icon: 'ribbon', iconBg: 'bg-green-100', iconColor: 'text-green-600', photoUrl: '', fullPhotoUrl: '', content: '' },
{ title: 'PENDAFTARAN', icon: 'star', iconBg: 'bg-purple-100', iconColor: 'text-purple-600', photoUrl: '', fullPhotoUrl: '', content: '' },
{ title: 'ORGANISASI', icon: 'star', iconBg: 'bg-blue-100', iconColor: 'text-blue-600', photoUrl: '', fullPhotoUrl: '', content: '' },
{ title: 'AKREDETISA', icon: 'star', iconBg: 'bg-purple-100', iconColor: 'text-purple-600', photoUrl: '', fullPhotoUrl: '', content: '' },
{ title: 'PROSPEK KARIR', icon: 'star', iconBg: 'bg-blue-100', iconColor: 'text-blue-600', photoUrl: '', fullPhotoUrl: '', content: '' },
{ title: 'PERKULIAHAN', icon: 'trophy', iconBg: 'bg-orange-100', iconColor: 'text-orange-600', photoUrl: '', fullPhotoUrl: '', content: '' },
],
},
};
const toAdmType = (val) => ({
description: String((val && val.description) || ''),
learnMoreUrl: String((val && val.learnMoreUrl) || ''),
});
const getAdmission = asyncController(async (req, res) => {
const admission = await Admission.findOne().lean();
if (!admission) { res.json(DEFAULT_DATA); return; }
res.json({
...admission,
undergraduate: toAdmType(admission.undergraduate),
snbt: toAdmType(admission.snbt),
snbp: toAdmType(admission.snbp),
});
});
const sanitizeOverview = (overview) => {
if (!overview || typeof overview !== 'object') return overview;
const result = { ...overview };
if (Array.isArray(result.paragraphs)) {
result.paragraphs = result.paragraphs.map((p) => stripHtml(String(p || '').trim()));
}
if (Array.isArray(result.whyChooseItems)) {
result.whyChooseItems = result.whyChooseItems.map((item) => stripHtml(String(item || '').trim()));
}
return result;
};
const sanitizeOtherInfo = (otherInfo) => {
if (!otherInfo || typeof otherInfo !== 'object') return otherInfo;
const result = { ...otherInfo };
if (Array.isArray(result.items)) {
result.items = result.items.map((item) => {
if (!item || typeof item !== 'object') return item;
return {
...item,
title: item.title !== undefined ? stripHtml(String(item.title || '').trim()) : item.title,
content: item.content !== undefined ? stripHtml(String(item.content || '').trim()) : item.content,
};
});
}
return result;
};
const sanitizeRequirements = (requirements) => {
if (!requirements || typeof requirements !== 'object') return requirements;
const result = { ...requirements };
if (Array.isArray(result.items)) {
result.items = result.items.map((item) => stripHtml(String(item || '').trim()));
}
return result;
};
const sanitizeProcedure = (procedure) => {
if (!procedure || typeof procedure !== 'object') return procedure;
const result = { ...procedure };
if (Array.isArray(result.steps)) {
result.steps = result.steps.map((step) => {
if (!step || typeof step !== 'object') return step;
return {
...step,
title: step.title !== undefined ? stripHtml(String(step.title || '').trim()) : step.title,
description: step.description !== undefined ? stripHtml(String(step.description || '').trim()) : step.description,
};
});
}
return result;
};
const sanitizeDeadlines = (deadlines) => {
if (!deadlines || typeof deadlines !== 'object') return deadlines;
const result = { ...deadlines };
if (result.note !== undefined) result.note = stripHtml(String(result.note || '').trim());
if (Array.isArray(result.semesters)) {
result.semesters = result.semesters.map((sem) => {
if (!sem || typeof sem !== 'object') return sem;
const s = { ...sem };
if (s.name !== undefined) s.name = stripHtml(String(s.name || '').trim());
if (Array.isArray(s.dates)) {
s.dates = s.dates.map((d) => {
if (!d || typeof d !== 'object') return d;
return {
...d,
label: d.label !== undefined ? stripHtml(String(d.label || '').trim()) : d.label,
value: d.value !== undefined ? stripHtml(String(d.value || '').trim()) : d.value,
};
});
}
return s;
});
}
return result;
};
const updateAdmission = asyncController(async (req, res) => {
const { overview, requirements, procedure, deadlines, otherInfo, undergraduate, snbt, snbp } = req.body;
const updateFields = {};
for (const [key, label] of [['undergraduate', 'Undergraduate'], ['snbt', 'SNBT'], ['snbp', 'SNBP']]) {
const value = req.body[key];
if (value !== undefined) {
const url = String((value && value.learnMoreUrl) || '').trim();
if (url && !isValidHttpUrl(url)) {
res.status(400).json({
success: false,
message: `${label} Learn More URL must start with http:// or https://`,
fields: { learnMoreUrl: 'Enter a valid URL (http:// or https://)' },
});
return;
}
updateFields[key] = sanitizeAdmissionType(value);
}
}
if (overview !== undefined) updateFields.overview = sanitizeOverview(overview);
if (requirements !== undefined) updateFields.requirements = sanitizeRequirements(requirements);
if (procedure !== undefined) updateFields.procedure = sanitizeProcedure(procedure);
if (deadlines !== undefined) updateFields.deadlines = sanitizeDeadlines(deadlines);
if (otherInfo !== undefined) updateFields.otherInfo = sanitizeOtherInfo(otherInfo);
const admission = await Admission.findOneAndUpdate(
{},
{ $set: updateFields },
{ upsert: true, new: true, setDefaultsOnInsert: true }
);
res.json(admission);
}, { defaultStatus: 400 });
module.exports = { getAdmission, updateAdmission };