From 847d92f1543038aa15844aa6620cb2044992e4d0 Mon Sep 17 00:00:00 2001 From: AliceeLe Date: Sat, 22 Feb 2025 15:37:34 -0500 Subject: [PATCH] Set up backend --- backend/api/app.py | 73 ++++++++++++++++++++++ backend/app.py | 24 +++++++ frontend/src/pages/SupportFeatureIdeas.tsx | 63 +++++++++++++++++-- frontend/src/pages/SupportTips.tsx | 34 +++++----- frontend/src/pages/Welcome.tsx | 20 +++++- frontend/vite.config.js | 2 +- 6 files changed, 190 insertions(+), 26 deletions(-) create mode 100644 backend/app.py diff --git a/backend/api/app.py b/backend/api/app.py index 4a6cb3d..5da2548 100644 --- a/backend/api/app.py +++ b/backend/api/app.py @@ -67,5 +67,78 @@ def search_events(): return jsonify(results) +from flask import Flask, request, jsonify +from pymongo import MongoClient +import requests + +app = Flask(__name__) +client = MongoClient("mongodb://localhost:27017/") # Update with your DB URI +db = client["cmucal"] +users_collection = db["users"] +events_collection = db["events"] + +CALSERVER_URL = "https://calserver.example.com" +GCAL_API_URL = "https://www.googleapis.com/calendar/v3/calendars" + +@app.route("/new_user", methods=["POST"]) +def create_user(): + data = request.json + if not data.get("email"): + return jsonify({"error": "Email is required"}), 400 + + users_collection.insert_one(data) + + # Call calserver to create a user-specific CMUCal calendar + calserver_response = requests.post(f"{CALSERVER_URL}/create_calendar", json={"email": data["email"]}) + + # Sync to Google Calendar (stub, requires auth) + gcal_response = requests.post(f"{GCAL_API_URL}/primary/events", json={"summary": "CMUCal Events"}) + + return jsonify({"message": "User created", "calserver": calserver_response.json(), "gcal": gcal_response.json()}) + +@app.route("/user", methods=["GET"]) +def get_user(): + user_id = request.args.get("id") + email = request.args.get("email") + query = {"_id": user_id} if user_id else {"email": email} + user = users_collection.find_one(query) + if not user: + return jsonify({"error": "User not found"}), 404 + return jsonify(user) + +@app.route("/user", methods=["PUT"]) +def update_user(): + data = request.json + email = data.get("email") + if not email: + return jsonify({"error": "Email is required"}), 400 + users_collection.update_one({"email": email}, {"$set": data}) + return jsonify({"message": "User updated"}) + +@app.route("/events", methods=["GET"]) +def get_events(): + filters = request.args.to_dict() + events = list(events_collection.find(filters)) + return jsonify(events) + +@app.route("/update_user_calendar", methods=["POST"]) +def update_user_calendar(): + data = request.json + if not data.get("email") or not data.get("staged_events"): + return jsonify({"error": "Email and staged events are required"}), 400 + response = requests.post(f"{CALSERVER_URL}/update_calendar", json=data) + return jsonify(response.json()) + +@app.route("/get_user_calendar", methods=["GET"]) +def get_user_calendar(): + email = request.args.get("email") + if not email: + return jsonify({"error": "Email is required"}), 400 + response = requests.get(f"{CALSERVER_URL}/get_calendar", params={"email": email}) + return jsonify(response.json()) + +if __name__ == "__main__": + app.run(debug=True) + if __name__ == "__main__": app.run() \ No newline at end of file diff --git a/backend/app.py b/backend/app.py new file mode 100644 index 0000000..41b9514 --- /dev/null +++ b/backend/app.py @@ -0,0 +1,24 @@ +from flask import Flask, jsonify, request +from flask_cors import CORS + +app = Flask(__name__) +CORS(app) + +@app.route('/', methods=['GET']) +def main(): + data = {'message': 'Welcome to CMUCal!'} + return jsonify(data) + +@app.route('/welcome', methods=['GET']) +def welcome(): + data = {'message': 'Welcome to CMUCal!'} + return jsonify(data) + +@app.route('/data', methods=['GET']) +def get_data(): + data = {'message': 'Hello from Flask!'} + return jsonify(data) + +if __name__ == '__main__': + app.run(debug=True) + diff --git a/frontend/src/pages/SupportFeatureIdeas.tsx b/frontend/src/pages/SupportFeatureIdeas.tsx index 4effdb8..689a535 100644 --- a/frontend/src/pages/SupportFeatureIdeas.tsx +++ b/frontend/src/pages/SupportFeatureIdeas.tsx @@ -1,12 +1,65 @@ -import React from 'react' +import React, { useState } from 'react' +import { FaHeart } from "react-icons/fa"; +import { HiOutlineUserCircle } from "react-icons/hi"; +import { IoAdd } from "react-icons/io5"; + +interface TipsContent { + title: string; + description: string; + date: string; + votes: BigInt; + note: React.ReactNode; +} + +const FeatureCard = ({ title, description, date, votes, icon }: any) => ( +
+

{title}

+

{description}

+
+
+ {icon} + {date} +
+
+ + {votes} +
+
+
+); const SupportFeatureIdeas: React.FC = () => { return ( -
-

Support Feature Ideas

+
+

Feature Ideas Hub

+

Welcome to the Feature Ideas Hub! Below, you'll find posts from our community sharing their ideas for new features and improvements. Browse through the suggestions, vote on your favorites, and contribute your own ideas to help us make CMUCal even better.

+ + + +
+ + + + + + +
) } - -export {SupportFeatureIdeas}; +export { SupportFeatureIdeas }; diff --git a/frontend/src/pages/SupportTips.tsx b/frontend/src/pages/SupportTips.tsx index 85e4553..ecfa5a4 100644 --- a/frontend/src/pages/SupportTips.tsx +++ b/frontend/src/pages/SupportTips.tsx @@ -42,7 +42,7 @@ const addEvent: TipsContent = {
  • Apply any necessary filters to narrow down the search results.
  • , - , + ,
  • Click Add all.
      @@ -60,22 +60,22 @@ const addEvent: TipsContent = { const deleteEvent: TipsContent = { title: 'Delete events easily', logo: , - text: -
      -

      - Instead of using{" "} - {" "} - on event card on the left panel to remove events in the calendar view, you - can easily delete events directly from the calendar view. Follow these - steps: -

      -
      , + text: +
      +

      + Instead of using{" "} + {" "} + on event card on the left panel to remove events in the calendar view, you + can easily delete events directly from the calendar view. Follow these + steps: +

      +
      , bulletPoints: [
    • On the right calendar view, find the event you want to delete.
    • ,
    • diff --git a/frontend/src/pages/Welcome.tsx b/frontend/src/pages/Welcome.tsx index f2e6efc..703070e 100644 --- a/frontend/src/pages/Welcome.tsx +++ b/frontend/src/pages/Welcome.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useEffect, useState } from "react"; import { GoogleLogin } from "@react-oauth/google"; import { useNavigate } from "react-router-dom"; import axios from "axios"; @@ -62,11 +62,26 @@ const Video: React.FC = () => { }; const Welcome: React.FC = () => { + const [welcomeMessage, setWelcomeMessage] = useState(""); + + useEffect(() => { + const fetchWelcomeMessage = async () => { + try { + const response = await axios.get("/welcome"); + setWelcomeMessage(response.data.message); + } catch (error) { + console.error("Error fetching welcome message:", error); + } + }; + + fetchWelcomeMessage(); + }, []); + return ( <>

      - Welcome to CMUCal + {welcomeMessage || "Loading..."}

      the all-in-one CMU resources platform @@ -83,5 +98,4 @@ const Welcome: React.FC = () => { ); }; - export { Welcome }; diff --git a/frontend/vite.config.js b/frontend/vite.config.js index a881686..88a8273 100644 --- a/frontend/vite.config.js +++ b/frontend/vite.config.js @@ -44,7 +44,7 @@ export default defineConfig({ server: { proxy: { '/api': { - target: 'http://localhost:5000', + target: 'http://127.0.0.1:5000/', changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, ''), },