forked from CSI-KJSCE/BOS-React-
Update server and frontend files, add new uploads
This commit is contained in:
@@ -46,12 +46,33 @@ const meetingSchema = new mongoose.Schema({
|
||||
});
|
||||
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
|
||||
app.post("/api/send-email", upload.array("attachments"), async (req, res) => {
|
||||
try {
|
||||
const { program, department, subject, body, agenda, date, startTime, endTime, recipients } = req.body;
|
||||
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) {
|
||||
return res.status(400).json({ error: "All fields are required!" });
|
||||
}
|
||||
|
||||
13640
backend/uploads/1739209912476.pdf
Normal file
13640
backend/uploads/1739209912476.pdf
Normal file
File diff suppressed because one or more lines are too long
BIN
backend/uploads/1739247757264.docx
Normal file
BIN
backend/uploads/1739247757264.docx
Normal file
Binary file not shown.
BIN
backend/uploads/1739247983721.docx
Normal file
BIN
backend/uploads/1739247983721.docx
Normal file
Binary file not shown.
BIN
backend/uploads/1739248179757.docx
Normal file
BIN
backend/uploads/1739248179757.docx
Normal file
Binary file not shown.
BIN
backend/uploads/1739248221016.docx
Normal file
BIN
backend/uploads/1739248221016.docx
Normal file
Binary file not shown.
13640
backend/uploads/1739248583503.pdf
Normal file
13640
backend/uploads/1739248583503.pdf
Normal file
File diff suppressed because one or more lines are too long
13640
backend/uploads/1739248594797.pdf
Normal file
13640
backend/uploads/1739248594797.pdf
Normal file
File diff suppressed because one or more lines are too long
13640
backend/uploads/1739248653057.pdf
Normal file
13640
backend/uploads/1739248653057.pdf
Normal file
File diff suppressed because one or more lines are too long
13640
backend/uploads/1739248664516.pdf
Normal file
13640
backend/uploads/1739248664516.pdf
Normal file
File diff suppressed because one or more lines are too long
13640
backend/uploads/1739248714664.pdf
Normal file
13640
backend/uploads/1739248714664.pdf
Normal file
File diff suppressed because one or more lines are too long
@@ -4,6 +4,7 @@ import Page1 from './Page1';
|
||||
import Page2 from './Page2';
|
||||
import Page3 from './Page3';
|
||||
import Page4 from './Page4';
|
||||
import Page5 from './Page5';
|
||||
import { GoogleOAuthProvider } from '@react-oauth/google';
|
||||
|
||||
const App = () => {
|
||||
@@ -15,6 +16,7 @@ const App = () => {
|
||||
<Route path="/page2" element={<Page2 />} />
|
||||
<Route path="/page3" element={<Page3 />} />
|
||||
<Route path="/page4" element={<Page4 />} />
|
||||
<Route path="/page5" element={<Page5 />} />
|
||||
</Routes>
|
||||
</Router>
|
||||
</GoogleOAuthProvider>
|
||||
|
||||
@@ -23,9 +23,9 @@
|
||||
color: rgb(166, 2, 2);
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||
border: 2px solid red; /* Add border to see if it's visible */
|
||||
margin-top: 80px;
|
||||
}
|
||||
|
||||
|
||||
h2 {
|
||||
font-size: 24px;
|
||||
margin-bottom: 30px;
|
||||
|
||||
@@ -3,6 +3,7 @@ import { useNavigate } from 'react-router-dom';
|
||||
import { GoogleLogin } from '@react-oauth/google'; // Import GoogleLogin component
|
||||
import { getAuth, signInWithEmailAndPassword, signInWithPopup, GoogleAuthProvider } from 'firebase/auth'; // Firebase authentication methods
|
||||
import './Page1.css';
|
||||
import image from './components/image.png';
|
||||
|
||||
// Firebase configuration
|
||||
import { initializeApp } from 'firebase/app';
|
||||
@@ -118,7 +119,7 @@ const Page1 = () => {
|
||||
return (
|
||||
<div className="wrapper">
|
||||
<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>
|
||||
|
||||
<div className="input-box">
|
||||
|
||||
@@ -117,11 +117,19 @@ body {
|
||||
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 {
|
||||
background-color: black;
|
||||
background-color: #B7202E;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.stream-bar ul li:hover a {
|
||||
color: white; /* Change the link text to white on hover */
|
||||
}
|
||||
|
||||
/* Content Area (Left Side) */
|
||||
.content-area {
|
||||
flex: 1;
|
||||
|
||||
@@ -28,10 +28,10 @@ const Page2 = () => {
|
||||
<nav className="navbar">
|
||||
<ul>
|
||||
<li><Link to="/page2">Home</Link></li>
|
||||
<li><Link to="/page3">Schedule</Link></li>
|
||||
<li><a href="#">About</a></li>
|
||||
<li><a href="#">Schedule</a></li>
|
||||
<li><Link to="/page5">Meeting DataBase</Link></li>
|
||||
<li><a href="#">Contact</a></li>
|
||||
<li><Link to="/">Login/Signup</Link></li>
|
||||
<li><Link to="/">Log Out</Link></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
.content-area h1 {
|
||||
font-size: 30px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
color: #B7202E;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
@@ -51,7 +51,7 @@
|
||||
.content-area input:focus,
|
||||
.content-area select:focus,
|
||||
.content-area textarea:focus {
|
||||
border-color: #4CAF50;
|
||||
border-color: #B7202E;
|
||||
}
|
||||
|
||||
/* Textarea Specific Styling */
|
||||
@@ -77,7 +77,7 @@
|
||||
.content-area button {
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
background-color: #4CAF50;
|
||||
background-color: #B7202E;
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
border: none;
|
||||
@@ -88,7 +88,7 @@
|
||||
}
|
||||
|
||||
.content-area button:hover {
|
||||
background-color: #45a049;
|
||||
background-color: #B7202E;
|
||||
}
|
||||
|
||||
/* Remove Button Styling for Agenda & Recipients */
|
||||
|
||||
@@ -113,9 +113,9 @@ const Page4 = () => {
|
||||
<ul>
|
||||
<li><Link to="/page2">Home</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><Link to="/">Login/Signup</Link></li>
|
||||
<li><Link to="/">Log Out</Link></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
@@ -125,7 +125,7 @@ const Page4 = () => {
|
||||
<div className="stream-bar">
|
||||
<h3>Streams</h3>
|
||||
<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>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
141
frontend/src/Page5.css
Normal file
141
frontend/src/Page5.css
Normal 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
83
frontend/src/Page5.js
Normal 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;
|
||||
Reference in New Issue
Block a user