diff --git a/backend/database.sqlite b/backend/database.sqlite index 6c2b539..95f3b3f 100644 Binary files a/backend/database.sqlite and b/backend/database.sqlite differ diff --git a/backend/server.js b/backend/server.js index 388bb05..b3a142b 100644 --- a/backend/server.js +++ b/backend/server.js @@ -5,7 +5,7 @@ const passport = require("./authentication/auth/passport"); const routes = require("./authentication/routes"); const path = require("path"); -const { Event, sequelize, User } = require("./database.js"); +const { Event, sequelize, User, Review } = require("./database.js"); const express = require("express"); const cors = require("cors"); @@ -209,17 +209,29 @@ app.delete("/events/:id", async (req, res) => { }); app.post("/api/reviews", async (req, res) => { + console.log("in /api/reviews"); // Handle review submission const { review_text, event_name } = req.body; - console.log("Server has received a review: ", review_text); - // Save the review or do other logic here res.status(200).json({ review_text }); - console.log("THIS THE TEXTTT: ", req.body.review_text); - console.log(req.body.event_name); + console.log("Server has received a review: ", review_text); + const newReview = await Review.create({ review_text: req.body.review_text, event_name: req.body.event_name, }); + +}); + +app.get("/api/reviews", async (req, res) => { + const eventName = req.query.event_name; + + try { + const reviews = await Review.findAll({ where: { event_name: eventName } }); + res.json(reviews); + } catch (error) { + console.error("Error fetching reviews:", error); + res.status(500).json({ error: "Failed to fetch reviews" }); + } }); //start server diff --git a/frontend/source/components/eventPage/compare.js b/frontend/source/components/eventPage/compare.js new file mode 100644 index 0000000..de8e0b4 --- /dev/null +++ b/frontend/source/components/eventPage/compare.js @@ -0,0 +1,208 @@ +import { openEventForm } from "../eventCreationForm/eventCreationForm.js"; + +export function showEventDetails(event) { + const eventDetailView = + document.getElementById("event-detail-view") || + document.createElement("div"); + eventDetailView.id = "event-detail-view"; + eventDetailView.classList.add("event-detail-view"); + document.body.appendChild(eventDetailView); + + eventDetailView.innerHTML = ` +
Genre: ${event.genre || "N/A"}
+Location: ${ + event.location || "N/A" + }
+ + + + ${ + event.host === getCurrentUserName() + ? `` + : "" + } +${newReview.review_text}
`; // Append review + document.getElementById("review-text").value = ""; // Clear text area + alert("Review Submitted!"); + } else { + alert("Failed to submit review"); + } + } else { + alert("Please write a review"); + } +} + +function rsvpEvent(event) { + const modal = document.getElementById("rsvp-modal"); + if (!modal) { + const modalElement = document.createElement("div"); + modalElement.id = "rsvp-modal"; + modalElement.classList.add("modal"); + modalElement.innerHTML = ` + + `; + + document.body.appendChild(modalElement); + + document + .querySelector(".close") + .addEventListener("click", () => (modalElement.style.display = "none")); + + document.getElementById("rsvp-form").addEventListener("submit", (e) => { + e.preventDefault(); + const attendance = document.getElementById("attendance").value; + const attendeesCount = document.getElementById("attendees").value; + const comments = document.getElementById("comments").value; + + console.log(`RSVP for event: ${event.title}`); + console.log(`Attendance: ${attendance}`); + console.log(`Number of people: ${attendeesCount}`); + console.log(`Comments: ${comments}`); + + modalElement.style.display = "none"; + }); + } + modal.style.display = "block"; +} diff --git a/frontend/source/components/eventPage/eventPage.css b/frontend/source/components/eventPage/eventPage.css index 0983f9c..42d4ddf 100644 --- a/frontend/source/components/eventPage/eventPage.css +++ b/frontend/source/components/eventPage/eventPage.css @@ -125,6 +125,44 @@ footer { font-size: 32px; } +.review-box { + width: 100%; + min-height: 100px; + max-height: 200px; + overflow-y: auto; + background-color: #2a2a3f; + padding: 10px; + border-radius: 2px; + color: #e0c084; + display: flex; + flex-direction: column; + gap: 10px; + box-sizing: border-box; +} + +.review { + background-color: #1a002b; + border-radius: 5px; + padding: 10px; + color: #fafafa;; + font-size: 0.9em; + text-align: left; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); + flex-shrink: 0; +} + +/* #review-text { + width: 100%; + height: 60px; + padding: 10px; + border-radius: 8px; + border: none; + margin-bottom: 10px; + resize: none; + background-color: #2a2a3f; + color: #e0c084; +} */ + /* Prevent Modal Style Inheritance */ .modal { display: none; diff --git a/frontend/source/components/eventPage/eventPage.js b/frontend/source/components/eventPage/eventPage.js index a6c7df3..0e174e8 100644 --- a/frontend/source/components/eventPage/eventPage.js +++ b/frontend/source/components/eventPage/eventPage.js @@ -1,18 +1,26 @@ export function showEventDetails(event) { - const eventDetailView = document.getElementById('event-detail-view') || document.createElement('div'); - eventDetailView.id = 'event-detail-view'; - eventDetailView.classList.add('event-detail-view'); - document.body.appendChild(eventDetailView); - - eventDetailView.innerHTML = ` + const eventDetailView = + document.getElementById("event-detail-view") || + document.createElement("div"); + eventDetailView.id = "event-detail-view"; + eventDetailView.classList.add("event-detail-view"); + document.body.appendChild(eventDetailView); + + eventDetailView.innerHTML = `Genre: ${event.genre || 'N/A'}
-Location: ${event.location || 'N/A'}
- +Genre: ${event.genre || "N/A"}
+Location: ${ + event.location || "N/A" + }
+${newReview.review_text}
`; // Append review - document.getElementById("review-text").value = ""; // Clear text area - alert("Review Submitted!"); + alert("Review has been submitted!"); } else { alert("Failed to submit review"); } @@ -128,13 +134,57 @@ async function submitReview(event) { } } +async function fetchAndDisplayReviews(eventName) { + // Check if eventName is provided + console.log(eventName); + if (!eventName) { + console.error("Event name is undefined or empty"); + alert("Event name is missing. Unable to fetch reviews."); + return; + } + + try { + // Fetch reviews from the server + const response = await fetch( + `http://127.0.0.1:4000/api/reviews?event_name=${eventName}` + ); + console.log(response); + // Check if the response is successful + if (!response.ok) { + console.error("Error fetching reviews: " + response.statusText); + alert("Failed to fetch reviews. Please try again later."); + return; + } + + // Parse the response JSON + const reviews = await response.json(); + + // Get the review box element + const reviewBox = document.getElementById("review-box"); + reviewBox.innerHTML = ""; // Clear existing reviews + + // Display the reviews + reviews.forEach((review) => { + const reviewElement = document.createElement("div"); + reviewElement.className = "review"; + reviewElement.textContent = review.review_text; + reviewBox.appendChild(reviewElement); + }); + } catch (error) { + // Handle errors (network issues, JSON parsing, etc.) + console.error("Error fetching reviews:", error); + alert("Failed to fetch reviews. Please try again later."); + } +} + + function rsvpEvent(event) { - const modal = document.getElementById("rsvp-modal"); - if (!modal) { - const modalElement = document.createElement("div"); - modalElement.id = "rsvp-modal"; - modalElement.classList.add("modal"); - modalElement.innerHTML = ` + const modal = document.getElementById("rsvp-modal"); + if (!modal) { + const modalElement = document.createElement("div"); + modalElement.id = "rsvp-modal"; + modalElement.classList.add("modal"); + modalElement.innerHTML = ` `; - document.body.appendChild(modalElement); + document.body.appendChild(modalElement); - document.querySelector(".close").addEventListener("click", () => modalElement.style.display = "none"); + document + .querySelector(".close") + .addEventListener("click", () => (modalElement.style.display = "none")); - document.getElementById("rsvp-form").addEventListener("submit", (e) => { - e.preventDefault(); - const attendance = document.getElementById("attendance").value; - const attendeesCount = document.getElementById("attendees").value; - const comments = document.getElementById("comments").value; + document.getElementById("rsvp-form").addEventListener("submit", (e) => { + e.preventDefault(); + const attendance = document.getElementById("attendance").value; + const attendeesCount = document.getElementById("attendees").value; + const comments = document.getElementById("comments").value; - console.log(`RSVP for event: ${event.title}`); - console.log(`Attendance: ${attendance}`); - console.log(`Number of people: ${attendeesCount}`); - console.log(`Comments: ${comments}`); + console.log(`RSVP for event: ${event.title}`); + console.log(`Attendance: ${attendance}`); + console.log(`Number of people: ${attendeesCount}`); + console.log(`Comments: ${comments}`); - modalElement.style.display = "none"; - }); - } - modal.style.display = "block"; + modalElement.style.display = "none"; + }); + } + modal.style.display = "block"; } diff --git a/node_modules/sqlite3/build/Makefile b/node_modules/sqlite3/build/Makefile index c887ca0..8731d03 100644 --- a/node_modules/sqlite3/build/Makefile +++ b/node_modules/sqlite3/build/Makefile @@ -347,7 +347,7 @@ endif quiet_cmd_regen_makefile = ACTION Regenerating $@ cmd_regen_makefile = cd $(srcdir); /usr/local/lib/node_modules/npm/node_modules/node-gyp/gyp/gyp_main.py -fmake --ignore-environment "-Dlibrary=shared_library" "-Dvisibility=default" "-Dnode_root_dir=/Users/ipsita/Library/Caches/node-gyp/23.1.0" "-Dnode_gyp_dir=/usr/local/lib/node_modules/npm/node_modules/node-gyp" "-Dnode_lib_file=/Users/ipsita/Library/Caches/node-gyp/23.1.0/<(target_arch)/node.lib" "-Dmodule_root_dir=/Users/ipsita/Downloads/UMass_Junior_Year/CS326/LocalVibes/node_modules/sqlite3" "-Dnode_engine=v8" "--depth=." "-Goutput_dir=." "--generator-output=build" -I/Users/ipsita/Downloads/UMass_Junior_Year/CS326/LocalVibes/node_modules/sqlite3/build/config.gypi -I/usr/local/lib/node_modules/npm/node_modules/node-gyp/addon.gypi -I/Users/ipsita/Library/Caches/node-gyp/23.1.0/include/node/common.gypi "--toplevel-dir=." binding.gyp -Makefile: $(srcdir)/build/config.gypi $(srcdir)/../../../../../../../../usr/local/lib/node_modules/npm/node_modules/node-gyp/addon.gypi $(srcdir)/../node-addon-api/node_api.gyp $(srcdir)/binding.gyp $(srcdir)/../../../../../../Library/Caches/node-gyp/23.1.0/include/node/common.gypi $(srcdir)/deps/common-sqlite.gypi $(srcdir)/deps/sqlite3.gyp +Makefile: $(srcdir)/../node-addon-api/node_api.gyp $(srcdir)/build/config.gypi $(srcdir)/deps/sqlite3.gyp $(srcdir)/binding.gyp $(srcdir)/../../../../../../Library/Caches/node-gyp/23.1.0/include/node/common.gypi $(srcdir)/../../../../../../../../usr/local/lib/node_modules/npm/node_modules/node-gyp/addon.gypi $(srcdir)/deps/common-sqlite.gypi $(call do_cmd,regen_makefile) # "all" is a concatenation of the "all" targets from all the included