diff --git a/admin/css/adminPanel.css b/admin/css/adminPanel.css index 811d7d9..09581d7 100644 --- a/admin/css/adminPanel.css +++ b/admin/css/adminPanel.css @@ -73,7 +73,7 @@ main { } /* bg color for input */ -#name, #date, #description, #time { +#name, #date, #description, #timeInput { background-color: #595959; color: white; } diff --git a/admin/html/admin.html b/admin/html/admin.html index 25ed595..db97e52 100644 --- a/admin/html/admin.html +++ b/admin/html/admin.html @@ -16,14 +16,14 @@

Admin Panel

-
+ diff --git a/admin/js/editScript.js b/admin/js/editScript.js index 9a328f9..08ca79d 100644 --- a/admin/js/editScript.js +++ b/admin/js/editScript.js @@ -5,25 +5,64 @@ let deleteModal = document.getElementById('deleteModal'); // Set up span elements for edit and delete modals let editSpan = document.getElementById("editClose"); let deleteSpan = document.getElementById("deleteClose"); +let currentEventId = null; +let currentEventName = null; +let currentEventDelId = null; - // Function to open the modals -function openModal(modalType) { +function openModal(modalType, elementName, elementDelId) { if(modalType === 'edit') { console.log("Edit Button clicked!"); + editModal.style.display = "block"; - } else if(modalType === 'delete') { + } else if (modalType === 'delete') { console.log("Delete button clicked!"); + console.log(elementName); + currentEventName = elementName; + currentEventDelId = elementDelId; deleteModal.style.display = "block"; } } + +function delEvent() { + if (!currentEventName) { + console.error('No event ID to delete.'); + return; + } + + console.log(currentEventName); + fetch(`http://localhost:3000/admin/delete?eventName=${currentEventName}`, { + method: 'DELETE', + }) + .then((res) => { + if (res.ok) { + // Remove the event card from UI + const eventCard = document.getElementById(currentEventDelId); + if (eventCard) { + eventCard.remove(); + } + closeModal('delete'); + } else { + throw 'Failed to delete event'; + } + }) + .catch((error) => { + console.error('Error deleting event:', error); + alert('Failed to delete event. Please try again.'); + }) + .finally(() => { + currentEventId = null; // Reset the currentEventId after deletion + }); +} + // Function to close the modals function closeModal(modalType) { if(modalType === 'edit') { editModal.style.display = "none"; } else if (modalType === 'delete') { deleteModal.style.display = "none"; + currentEventId = null; } } @@ -67,6 +106,10 @@ function toggleDiv() { } } -window.onload = () => { +document.addEventListener('DOMContentLoaded', function() { + toggleDiv(); +}); + +window.onload = function() { toggleDiv(); } diff --git a/admin/js/eventParse.js b/admin/js/eventParse.js index 9d1196d..f17ad0c 100644 --- a/admin/js/eventParse.js +++ b/admin/js/eventParse.js @@ -2,6 +2,7 @@ window.onload = displayEvents(); let editContainer = document.getElementById('itemContainer'); function displayEvents() { + fetch('api/fetch/events').then((res) => { return res.json() }).then((data) => { data.message.forEach(element => { addElement(element); @@ -20,21 +21,35 @@ function searchElement() { }); } +function randNum(max) { + return Math.floor(Math.random() * max) + 1; +} + function addElement(element) { + let time = convertTime(element.time); + let id = randNum(100000); let container = ` -
- acm +
+ acm

${element.name}

${element.description}

-

${element.date}

- - +

${element.date} at ${time}

+ +
`; editContainer.innerHTML += container; } +function convertTime(time24) { + const [hours, minutes] = time24.split(':').map(Number); + const period = hours < 12 ? 'AM' : 'PM'; + const hours12 = hours % 12 || 12; + + return `${hours12}:${minutes.toString().padStart(2, '0')} ${period}`; +} + const search = document.getElementById('search'); search.addEventListener('input', searchElement); diff --git a/admin/js/script.js b/admin/js/script.js index a332c5f..f75c520 100644 --- a/admin/js/script.js +++ b/admin/js/script.js @@ -8,11 +8,12 @@ function submitEvent(e) { let name = document.getElementById("name").value.trim(); let date = document.getElementById("date").value; let description = document.getElementById("description").value.trim(); + let time = document.getElementById("timeInput").value; let imageInput = document.getElementById("image"); let imageFile = imageInput.files[0]; // Get the selected image file // Check for empty fields - if (!name || !date || !description) { + if (!name || !date || !description || !time) { alert("Please fill out all fields before submitting!"); return; } @@ -21,6 +22,7 @@ function submitEvent(e) { formData.append("name", name); formData.append("date", date); formData.append("description", description); + formData.append("time", time); formData.append("image", imageFile); alert("Event Added!"); diff --git a/controllers/adminController.js b/controllers/adminController.js index 1254049..99375c0 100644 --- a/controllers/adminController.js +++ b/controllers/adminController.js @@ -1,6 +1,7 @@ const mongo_utils = require('../utils/mongo_utils'); const path = require('path'); + // Stuff for gridfsbucket, also set up multer as to use req.file.originalname const multer = require("multer"); const { GridFSBucket, ObjectID } = require('mongodb'); @@ -35,7 +36,7 @@ exports.login = async (req,res)=>{ // Encrypt cookie const auth = cookieCrypt.encrypt((new Date()).toString()); // Set cookie - res.cookie('auth',auth,{httpOnly:true}); + res.cookie('auth', auth, { httpOnly: true }); return res.redirect('/admin'); } @@ -47,9 +48,10 @@ exports.create = async (req, res)=>{ const name = req.body.name.trim(); const date = req.body.date; const desc = req.body.description.trim(); + const time = req.body.time; const imageName = req.file.originalname; - if (!req.body.name || !req.body.date || !req.body.description) { + if (!req.body.name || !req.body.date || !req.body.description || !req.body.time) { res.status(400).redirect("/admin"); return; } @@ -58,6 +60,7 @@ exports.create = async (req, res)=>{ name:name, date:date, description:desc, + time:time, imageName: imageName }; @@ -86,27 +89,39 @@ exports.create = async (req, res)=>{ // Delete event by name exports.deleteEvent = async (req,res)=>{ - const eventName = req.query.name; // Specify the name of the event to delete - console.log(`Deleting event with name: ${eventName}`); + const eventName = req.query.eventName; // Specify the name of the event to delete + const currentEventImgName = req.query.imgName; + // console.log(req.query.eventName); + // console.log(req.query.imgName); + // console.log(`Deleting event with name: ${eventName}`); try { const db = mongo_utils.get_client().db(); + + const imgCollection = db.collection('images.files') + const imgId = await imgCollection.findOne({filename : currentEventImgName}); + const imgResult = await imgCollection.deleteOne({ filename : currentEventImgName }); + + const chunksCollection = db.collection('images.chunks') + const chunksResult = await chunksCollection.deleteMany({ files_id : imgId._id }); + const collection = db.collection('events'); + const result = await collection.deleteOne({ name : eventName }); - // Delete the event by name - const result = await collection.deleteOne({ name: eventName }); console.log(result); + console.log(imgResult); + console.log(chunksResult); - if (result.deletedCount === 1) { - // Event successfully deleted + if (result.deletedCount >= 1 && imgResult.deletedCount >= 1 && chunksResult.deletedCount >= 1){ res.status(200).json({ message: 'Event deleted successfully' }); + return; } else { - // Event not found - res.status(404).json({ message: 'Event not found' }); + res.status(404).json({ message: ':(' }); + return; } } catch (err) { - // Error handling res.status(500).json({ message: err.message }); + return; } } \ No newline at end of file diff --git a/controllers/apiController.js b/controllers/apiController.js index 695d1f9..ebf768e 100644 --- a/controllers/apiController.js +++ b/controllers/apiController.js @@ -8,6 +8,7 @@ exports.fetchEvent = async(req, res)=>{ const getName = req.query.name; const getType = req.query.type; const getDate = req.query.date; + const query = {}; if(getName) { @@ -25,7 +26,7 @@ exports.fetchEvent = async(req, res)=>{ const db = mongo_utils.get_client().db(); const collection = db.collection('events'); - const result = await collection.find(query, { projection: { _id : 0 } }).toArray(); + const result = await collection.find(query).toArray(); res.send({ message: result, diff --git a/package-lock.json b/package-lock.json index 8aa7dda..31e56ee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "mongodb": "^6.5.0", "mongoose": "^7.6.2", "multer": "^1.4.5-lts.1", + "nodeman": "^1.1.2", "nodemon": "^3.1.0" }, "devDependencies": { @@ -274,6 +275,14 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/colorx": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/colorx/-/colorx-0.0.7.tgz", @@ -1223,6 +1232,21 @@ "node": ">= 0.6" } }, + "node_modules/nodeman": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/nodeman/-/nodeman-1.1.2.tgz", + "integrity": "sha512-RpRpDnMI4TN/EPX6+my7f02585I14AQO8YrHTkO1aTiC65+sMa5G3NwQplN6kwue1njxWiaSz2UwCnDbwkLgeQ==", + "dependencies": { + "colors": "*" + }, + "bin": { + "_nodeman": "bin/_nodeman", + "nodeman": "bin/nodeman" + }, + "engines": { + "node": "*" + } + }, "node_modules/nodemon": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.0.tgz", diff --git a/package.json b/package.json index a0e6287..a480af5 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "mongodb": "^6.5.0", "mongoose": "^7.6.2", "multer": "^1.4.5-lts.1", + "nodeman": "^1.1.2", "nodemon": "^3.1.0" }, "devDependencies": { diff --git a/routes/adminRouter.js b/routes/adminRouter.js index e7736f9..e77ced6 100644 --- a/routes/adminRouter.js +++ b/routes/adminRouter.js @@ -1,7 +1,7 @@ const express = require("express"); const router = express.Router(); const { cookieAuthCheck } = require("../utils/secureCookie.js"); -const { render, create, deleteEvent,login,loginRender } = require('../controllers/adminController.js'); +const { render, create, deleteEvent, login, loginRender } = require('../controllers/adminController.js'); const bodyParser = require("body-parser"); const file_utils = require("../utils/file_utils.js"); @@ -10,9 +10,9 @@ console.log(__dirname); router.use('/submit', file_utils.upload.single('image')); -router.get('/', cookieAuthCheck,render); -router.get('/login',loginRender) -router.post('/login',login) +router.get('/', cookieAuthCheck, render); +router.get('/login', loginRender) +router.post('/login', login) router.post('/submit', cookieAuthCheck, create); router.post('/delete', /*cookieAuthCheck,*/ deleteEvent); diff --git a/routes/rootRouter.js b/routes/rootRouter.js index acaad4e..ac0ee18 100644 --- a/routes/rootRouter.js +++ b/routes/rootRouter.js @@ -5,13 +5,13 @@ const router = express.Router(); const routes = require('../controllers/rootController'); -router.get('/',routes.homePage); -router.get('/workshops',routes.workshopPage); +router.get('/', routes.homePage); +router.get('/workshops', routes.workshopPage); router.get('/events', routes.eventPage); -router.get('/calendar',routes.calenderPage); -router.get('/important-links',routes.importantLinkPage); -router.get('/leadership',routes.leadershipPage); -router.get('/merchandise',routes.merchandisePage); -router.get('/projects',routes.projectPage); +router.get('/calendar', routes.calenderPage); +router.get('/important-links', routes.importantLinkPage); +router.get('/leadership', routes.leadershipPage); +router.get('/merchandise', routes.merchandisePage); +router.get('/projects', routes.projectPage); module.exports = router; \ No newline at end of file