From 3d57c7251a7e92c476a2f602035cf4f7861dc03d Mon Sep 17 00:00:00 2001 From: Harini312821 Date: Fri, 12 Jul 2024 01:45:02 +0800 Subject: [PATCH] events client and server side --- client/src/App.tsx | 3 + client/src/components/NavigationBar.tsx | 8 +- client/src/pages/EventsPage.tsx | 49 ++++++++ server/index.js | 3 + server/models/Events.js | 41 +++++++ server/routes/events.js | 145 ++++++++++++++++++++++++ 6 files changed, 248 insertions(+), 1 deletion(-) create mode 100644 client/src/pages/EventsPage.tsx create mode 100644 server/models/Events.js create mode 100644 server/routes/events.js diff --git a/client/src/App.tsx b/client/src/App.tsx index d326fba..219b961 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -9,6 +9,7 @@ import CommunityPage from "./pages/CommunityPage"; import CreatePostPage from "./pages/CreatePostPage"; import EditPostPage from "./pages/EditPostPage"; import SchedulePage from "./pages/SchedulePage"; +import EventsPage from "./pages/EventsPage"; function App() { return ( @@ -23,6 +24,8 @@ function App() { } path="/createPost" /> } path="/editPost/:id" /> } path="/schedule" /> + } path="/events" /> + ); } diff --git a/client/src/components/NavigationBar.tsx b/client/src/components/NavigationBar.tsx index 8be17f0..600d24b 100644 --- a/client/src/components/NavigationBar.tsx +++ b/client/src/components/NavigationBar.tsx @@ -76,7 +76,13 @@ export default function NavigationBar() { />
- +
+ + ))} + + + + ); +}; + +export default EventsPage; diff --git a/server/index.js b/server/index.js index d41b95d..42cf0d5 100644 --- a/server/index.js +++ b/server/index.js @@ -25,6 +25,9 @@ app.get("/", (req, res) => { app.use("/users", usersRoute); +const eventsRoute = require('./routes/events'); +app.use("/events", eventsRoute); + const postRoute = require('./routes/post'); app.use("/post", postRoute); diff --git a/server/models/Events.js b/server/models/Events.js new file mode 100644 index 0000000..c604912 --- /dev/null +++ b/server/models/Events.js @@ -0,0 +1,41 @@ +module.exports = (sequelize, DataTypes) => { + const Events = sequelize.define("Events", { + title: { + type: DataTypes.STRING, + allowNull: false, + }, + description: { + type: DataTypes.STRING, + allowNull: false, + }, + date: { + type: DataTypes.DATE, + allowNull: false, + }, + time: { + type: DataTypes.STRING, + allowNull: false, + }, + location: { + type: DataTypes.STRING, + allowNull: false, + }, + category: { + type: DataTypes.STRING, + allowNull: false, + }, + Events: { + type: DataTypes.BLOB("long"), + allowNull: true, + }, + slotsAvailable: { + type: DataTypes.INTEGER, + allowNull: false, + } + }, { + tableName: "events", + timestamps: true, + }); + + return Events; +}; \ No newline at end of file diff --git a/server/routes/events.js b/server/routes/events.js new file mode 100644 index 0000000..58ba6a0 --- /dev/null +++ b/server/routes/events.js @@ -0,0 +1,145 @@ +const express = require('express'); +const router = express.Router(); +const { Events } = require('../models'); +const multer = require('multer'); +const path = require('path'); +const yup = require('yup'); + +router.post("/", async (req, res) => { + let data = req.body; + console.log("Incoming data:", data); // Log incoming data + const validationSchema = yup.object({ + title: yup.string().trim().min(3).max(100).required(), + description: yup.string().trim().min(3).max(500).required(), + date: yup.date().required(), + time: yup.string().required(), + location: yup.string().required(), + category: yup.string().required(), + imageUrl: yup.string().matches(/(\/uploads\/.+)/, 'Image URL must be a valid path').required(), + slotsAvailable: yup.number().integer().required() + }); + + try { + data = await validationSchema.validate(data, { abortEarly: false }); + console.log("Validated data:", data); // Log validated data + const result = await Events.create(data); + console.log("Event created:", result); // Log successful creation + res.json(result); + } catch (err) { + console.error("Validation error:", err); // Log the validation error + res.status(400).json({ errors: err.errors }); + } +}); + +const upload = multer({ storage: multer.memoryStorage() }); + +router.put( + "/:id", + upload.single("image"), + async (req, res) => { + const id = req.params.id; + + // Check if file is uploaded + if (!req.file) { + return res.status(400).json({ message: "No file uploaded" }); + } + + try { + const { buffer, mimetype, size } = req.file; + + // Validate file type and size (example: max 5MB, only images) + const allowedTypes = ["image/jpeg", "image/png", "image/gif"]; + const maxSize = 5 * 1024 * 1024; // 5MB + + if (!allowedTypes.includes(mimetype)) { + return res.status(400).json({ + message: + "Invalid file type\nSupported: jpeg, png, gif\nUploaded: " + + mimetype.substring(6), + }); + } + + if (size > maxSize) { + return res.status(400).json({ + message: + "File too large!\nMaximum: 5MB, Uploaded: " + + (size / 1000000).toFixed(2) + + "MB", + }); + } + + // Crop the image to a square + const croppedBuffer = await sharp(buffer) + .resize({ width: 512, height: 512, fit: sharp.fit.cover }) // Adjust size as necessary + .toBuffer(); + + await User.update( + { Events: croppedBuffer }, + { where: { id: id } } + ); + + res.json({ message: "Event image successfully uploaded." }); + } catch (err) { + res + .status(500) + .json({ message: "Internal server error", errors: err.errors }); + } + } + ); + + +router.get("/", async (req, res) => { + const list = await Events.findAll({ + order: [['createdAt', 'DESC']], + }); + res.json(list); +}); + +router.get("/:id", async (req, res) => { + const id = req.params.id; + const event = await Events.findByPk(id); + if (!event) { + res.sendStatus(404); + return; + } + res.json(event); +}); + +router.put("/:id", async (req, res) => { + const id = req.params.id; + let data = req.body; + const validationSchema = yup.object({ + title: yup.string().trim().min(3).max(100), + description: yup.string().trim().min(3).max(500), + date: yup.date(), + time: yup.string(), + location: yup.string(), + category: yup.string(), + imageUrl: yup.string().matches(/(\/uploads\/.+)/, 'Image URL must be a valid path'), + slotsAvailable: yup.number().integer() + }); + + try { + data = await validationSchema.validate(data, { abortEarly: false }); + const event = await Events.findByPk(id); + if (!event) { + return res.status(404).json({ message: "Event not found" }); + } + await Events.update(data, { where: { id: id } }); + res.json({ message: "Event updated successfully" }); + } catch (err) { + res.status(400).json({ errors: err.errors }); + } +}); + +router.delete("/:id", async (req, res) => { + const id = req.params.id; + const event = await Events.findByPk(id); + if (!event) { + return res.status(404).json({ message: "Event not found" }); + } + await Events.destroy({ where: { id: id } }); + res.json({ message: "Event deleted successfully" }); +}); + +module.exports = router;