Update server and frontend files, add new uploads

This commit is contained in:
sanikapendurkar
2025-02-17 14:40:11 +05:30
parent 0f4e1a3183
commit 56bbb4596f
20 changed files with 82109 additions and 13 deletions

View File

@@ -46,11 +46,32 @@ const meetingSchema = new mongoose.Schema({
}); });
const Meeting = mongoose.model("Meeting", meetingSchema); const Meeting = mongoose.model("Meeting", meetingSchema);
app.get("/api/meetings", async (req, res) => {
try {
const meetings = await Meeting.find(); // Fetching all meetings
// Format agenda in HTML for each meeting
const formattedMeetings = meetings.map((meeting) => {
const formattedAgenda = meeting.agenda
? meeting.agenda.map((item, index) => `<li>${index + 1}. ${item}</li>`).join("")
: "<li>No agenda provided</li>";
return { ...meeting.toObject(), formattedAgenda }; // Add formatted agenda to each meeting
});
res.json(formattedMeetings); // Send formatted meetings
} catch (error) {
console.error("Error fetching meetings:", error);
res.status(500).json({ error: "Error fetching meetings" });
}
});
// API to send email // API to send email
app.post("/api/send-email", upload.array("attachments"), async (req, res) => { app.post("/api/send-email", upload.array("attachments"), async (req, res) => {
try { try {
const { program, department, subject, body, agenda, date, startTime, endTime, recipients } = req.body; const { program, department, subject, body, agenda, date, startTime, endTime, recipients } = req.body;
const files = req.files; const files = req.files;
console.log({ program, department, subject, body, agenda, date, startTime, endTime, recipients, files });
if (!program || !department || !subject || !body || !date || !startTime || !endTime || !recipients) { if (!program || !department || !subject || !body || !date || !startTime || !endTime || !recipients) {
return res.status(400).json({ error: "All fields are required!" }); return res.status(400).json({ error: "All fields are required!" });

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -4,6 +4,7 @@ import Page1 from './Page1';
import Page2 from './Page2'; import Page2 from './Page2';
import Page3 from './Page3'; import Page3 from './Page3';
import Page4 from './Page4'; import Page4 from './Page4';
import Page5 from './Page5';
import { GoogleOAuthProvider } from '@react-oauth/google'; import { GoogleOAuthProvider } from '@react-oauth/google';
const App = () => { const App = () => {
@@ -15,6 +16,7 @@ const App = () => {
<Route path="/page2" element={<Page2 />} /> <Route path="/page2" element={<Page2 />} />
<Route path="/page3" element={<Page3 />} /> <Route path="/page3" element={<Page3 />} />
<Route path="/page4" element={<Page4 />} /> <Route path="/page4" element={<Page4 />} />
<Route path="/page5" element={<Page5 />} />
</Routes> </Routes>
</Router> </Router>
</GoogleOAuthProvider> </GoogleOAuthProvider>

View File

@@ -23,9 +23,9 @@
color: rgb(166, 2, 2); color: rgb(166, 2, 2);
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
border: 2px solid red; /* Add border to see if it's visible */ border: 2px solid red; /* Add border to see if it's visible */
margin-top: 80px;
} }
h2 { h2 {
font-size: 24px; font-size: 24px;
margin-bottom: 30px; margin-bottom: 30px;

View File

@@ -3,6 +3,7 @@ import { useNavigate } from 'react-router-dom';
import { GoogleLogin } from '@react-oauth/google'; // Import GoogleLogin component import { GoogleLogin } from '@react-oauth/google'; // Import GoogleLogin component
import { getAuth, signInWithEmailAndPassword, signInWithPopup, GoogleAuthProvider } from 'firebase/auth'; // Firebase authentication methods import { getAuth, signInWithEmailAndPassword, signInWithPopup, GoogleAuthProvider } from 'firebase/auth'; // Firebase authentication methods
import './Page1.css'; import './Page1.css';
import image from './components/image.png';
// Firebase configuration // Firebase configuration
import { initializeApp } from 'firebase/app'; import { initializeApp } from 'firebase/app';
@@ -118,7 +119,7 @@ const Page1 = () => {
return ( return (
<div className="wrapper"> <div className="wrapper">
<form id="login-form" onSubmit={handleLogin}> <form id="login-form" onSubmit={handleLogin}>
<img src="../src/image.png" alt="Responsive" className="responsive-image" /> <img src={image} alt="Responsive" className="responsive-image" />
<h2>Board Of Studies</h2> <h2>Board Of Studies</h2>
<div className="input-box"> <div className="input-box">

View File

@@ -117,11 +117,19 @@ body {
transition: background-color 0.3s; transition: background-color 0.3s;
} }
.stream-bar ul li a {
color: black; /* Change the link text to white on hover */
}
.stream-bar ul li:hover { .stream-bar ul li:hover {
background-color: black; background-color: #B7202E;
color: white; color: white;
} }
.stream-bar ul li:hover a {
color: white; /* Change the link text to white on hover */
}
/* Content Area (Left Side) */ /* Content Area (Left Side) */
.content-area { .content-area {
flex: 1; flex: 1;

View File

@@ -28,10 +28,10 @@ const Page2 = () => {
<nav className="navbar"> <nav className="navbar">
<ul> <ul>
<li><Link to="/page2">Home</Link></li> <li><Link to="/page2">Home</Link></li>
<li><Link to="/page3">Schedule</Link></li> <li><a href="#">Schedule</a></li>
<li><a href="#">About</a></li> <li><Link to="/page5">Meeting DataBase</Link></li>
<li><a href="#">Contact</a></li> <li><a href="#">Contact</a></li>
<li><Link to="/">Login/Signup</Link></li> <li><Link to="/">Log Out</Link></li>
</ul> </ul>
</nav> </nav>

View File

@@ -14,7 +14,7 @@
.content-area h1 { .content-area h1 {
font-size: 30px; font-size: 30px;
font-weight: 600; font-weight: 600;
color: #333; color: #B7202E;
margin-bottom: 20px; margin-bottom: 20px;
text-align: center; text-align: center;
} }
@@ -51,7 +51,7 @@
.content-area input:focus, .content-area input:focus,
.content-area select:focus, .content-area select:focus,
.content-area textarea:focus { .content-area textarea:focus {
border-color: #4CAF50; border-color: #B7202E;
} }
/* Textarea Specific Styling */ /* Textarea Specific Styling */
@@ -77,7 +77,7 @@
.content-area button { .content-area button {
width: 100%; width: 100%;
padding: 12px; padding: 12px;
background-color: #4CAF50; background-color: #B7202E;
color: white; color: white;
font-size: 16px; font-size: 16px;
border: none; border: none;
@@ -88,7 +88,7 @@
} }
.content-area button:hover { .content-area button:hover {
background-color: #45a049; background-color: #B7202E;
} }
/* Remove Button Styling for Agenda & Recipients */ /* Remove Button Styling for Agenda & Recipients */

View File

@@ -113,9 +113,9 @@ const Page4 = () => {
<ul> <ul>
<li><Link to="/page2">Home</Link></li> <li><Link to="/page2">Home</Link></li>
<li><Link to="/page3">Schedule</Link></li> <li><Link to="/page3">Schedule</Link></li>
<li><a href="#">About</a></li> <li><Link to="/page5">Meeting DataBase</Link></li>
<li><a href="#">Contact</a></li> <li><a href="#">Contact</a></li>
<li><Link to="/">Login/Signup</Link></li> <li><Link to="/">Log Out</Link></li>
</ul> </ul>
</nav> </nav>
@@ -125,7 +125,7 @@ const Page4 = () => {
<div className="stream-bar"> <div className="stream-bar">
<h3>Streams</h3> <h3>Streams</h3>
<ul> <ul>
{["Engineering & Technology", "Management", "Education", "Dharama", "Commerce", "Science", "Humanities", "Music", "Language"].map((stream) => ( {["Engineering & Technology", "Management Studies", "Education", "Dharama Studies", "Commerce & Business Studies", "Science", "Humanities & Social Science", "Music Performance & Art", "Language & Literature"].map((stream) => (
<li key={stream} onClick={() => alert(`Selected: ${stream}`)}>{stream}</li> <li key={stream} onClick={() => alert(`Selected: ${stream}`)}>{stream}</li>
))} ))}
</ul> </ul>

141
frontend/src/Page5.css Normal file
View File

@@ -0,0 +1,141 @@
/* Ensure body has margin 0 and full height for scrolling */
body {
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
background-color: #f4f4f4;
min-height: 100vh;
overflow-y: auto; /* Ensure scrolling */
}
/* Main container for the meetings */
.meetings-container {
background-color: #ffffff;
border-radius: 10px; /* Rounded corners */
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
border: 1px solid #e0e0e0; /* Light border for the box */
box-sizing: border-box;
max-width: 1200px;
margin: 20px auto; /* Added margin to ensure some space from top */
padding: 20px;
}
/* Heading for the page */
h1 {
text-align: center;
font-size: 2rem;
margin-bottom: 20px;
}
/* List of meetings */
.meetings-list {
display: flex;
flex-direction: column;
gap: 20px;
}
/* Styling for each meeting box */
.meeting-box {
background-color: #ffffff;
padding: 20px;
border-radius: 10px; /* Rounded corners */
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
border-left: 5px solid #B7202E; /* Changed to the new color */
overflow: hidden; /* Prevents overflow */
box-sizing: border-box;
}
/* Styling for meeting titles */
.meeting-box h2 {
font-size: 1.5rem;
color: #333;
margin-bottom: 10px;
}
/* Styling for meeting details like Program, Date, etc. */
.meeting-box p {
font-size: 1rem;
color: #555;
}
/* Styling for links like Google Calendar and attachments */
.meeting-box a {
text-decoration: none;
color: #B7202E; /* Changed to the new color */
font-weight: bold;
display: inline-block;
margin-top: 10px;
}
.meeting-box a:hover {
text-decoration: underline;
}
/* Button for Google Calendar link */
.google-calendar-link {
margin-top: 10px;
display: inline-block;
padding: 10px 20px;
background-color: #B7202E; /* Changed to the new color */
color: white;
border-radius: 5px;
text-align: center;
}
.google-calendar-link:hover {
background-color: #9e1c25; /* Darkened shade of the same color */
}
/* Ensure that meetings overflow properly on the page */
body {
display: flex;
flex-direction: column;
justify-content: flex-start;
overflow-y: auto;
}
.meeting-box ul {
list-style-type: none;
padding-left: 0;
}
.meeting-box ul li {
font-size: 1rem;
color: #444;
margin-bottom: 5px;
}
/* Responsive Design for smaller screens */
@media (max-width: 768px) {
.meeting-box {
padding: 15px;
}
.meeting-box h2 {
font-size: 1.2rem;
}
.meeting-box p,
.meeting-box ul li {
font-size: 0.9rem;
}
.google-calendar-link {
font-size: 0.9rem;
}
}
/* Button for Google Calendar link */
.google-calendar-link {
margin-top: 10px;
display: inline-block;
padding: 10px 20px;
background-color: #B7202E; /* Red color */
color: white !important; /* Text color set to white */
border-radius: 5px;
text-align: center;
}
.google-calendar-link:hover {
background-color: #9e1c25; /* Darkened shade of red on hover */
}

83
frontend/src/Page5.js Normal file
View File

@@ -0,0 +1,83 @@
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import './Page5.css';
const Page5 = () => {
const [meetings, setMeetings] = useState([]);
// Fetch meetings data from the server
useEffect(() => {
axios.get('http://localhost:5000/api/meetings') // Updated to backend URL
.then((response) => {
setMeetings(response.data);
})
.catch((error) => {
console.error('Error fetching meetings:', error);
});
}, []);
return (
<div className="meetings-container">
<h1>Meeting Details</h1>
<div className="meetings-list">
{meetings.length === 0 ? (
<p>No meetings available</p>
) : (
meetings.map((meeting, index) => (
<div key={index} className="meeting-box">
<h2>{meeting.subject}</h2>
<p><strong>Program:</strong> {meeting.program}</p>
<p><strong>Department:</strong> {meeting.department}</p>
<p><strong>Date:</strong> {meeting.date}</p>
<p><strong>Time:</strong> {meeting.startTime} - {meeting.endTime}</p>
<p><strong>Agenda:</strong></p>
{meeting.agenda && meeting.agenda.length > 0 ? (
<ul>
{meeting.agenda.map((item, idx) => (
<li key={idx}>{item}</li>
))}
</ul>
) : (
<p>No agenda provided</p>
)}
<p><strong>Body:</strong> {meeting.body}</p>
<p><strong>Recipients:</strong> {meeting.recipients}</p>
{/* Display Attachments if available */}
<p><strong>Attachments:</strong></p>
{meeting.attachments && meeting.attachments.length > 0 ? (
<ul>
{meeting.attachments.map((file, idx) => (
<li key={idx}>
<a href={`/uploads/${file.filename}`} target="_blank" rel="noopener noreferrer">
{file.filename}
</a>
</li>
))}
</ul>
) : (
<p>No attachments available</p>
)}
<a
href={`https://calendar.google.com/calendar/render?action=TEMPLATE&text=${encodeURIComponent(
meeting.subject
)}&details=${encodeURIComponent(meeting.body)}&dates=${meeting.date}T${meeting.startTime}/${meeting.date}T${meeting.endTime}`}
target="_blank"
rel="noopener noreferrer"
className="google-calendar-link"
>
Add to Google Calendar
</a>
</div>
))
)}
</div>
</div>
);
};
export default Page5;