diff --git a/.env b/.env
index 0d0092a..ddf3a43 100644
--- a/.env
+++ b/.env
@@ -1,2 +1,2 @@
-VITE_AUTH_URL="http://localhost:8080/auth/google"
-#VITE_AUTH_URL="https://byte-camp-auth-service.fly.dev/auth/google"
\ No newline at end of file
+#VITE_AUTH_URL="http://localhost:8080"
+VITE_AUTH_URL="https://byte-camp-auth-service.fly.dev"
\ No newline at end of file
diff --git a/.env.development b/.env.development
new file mode 100644
index 0000000..7dc9c2c
--- /dev/null
+++ b/.env.development
@@ -0,0 +1,2 @@
+VITE_AUTH_URL="http://localhost:8080"
+#VITE_AUTH_URL="https://byte-camp-auth-service.fly.dev"
\ No newline at end of file
diff --git a/src/components/Navbar.jsx b/src/components/Navbar.jsx
index 64dca56..f541037 100644
--- a/src/components/Navbar.jsx
+++ b/src/components/Navbar.jsx
@@ -1,7 +1,9 @@
import React, { useState, useEffect, useRef } from "react";
import "../scss/styles.scss";
import "../scss/components/_navbar.scss";
-import { Link, useNavigate } from "react-router-dom";
+import { Link } from "react-router-dom";
+
+const authUrl = import.meta.env.VITE_AUTH_URL;
// Using URL reference for ByteCamp logo
const bytecampLogo = "/images/bytecamp.png";
@@ -12,23 +14,9 @@ const Navbar = () => {
const [user, setUser] = useState(null);
const [menuOpen, setMenuOpen] = useState(false);
const menuRef = useRef(null);
- const navigate = useNavigate();
- const handleLogout = () => {
- // Implement client-side logout without calling the backend
- // This clears the user state in the frontend
- setUser(null);
-
- // Clear any authentication cookies if they exist
- document.cookie.split(";").forEach((cookie) => {
- const [name] = cookie.trim().split("=");
- document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;
- });
-
- // Redirect to home page
- navigate("/");
-
- console.log("Logged out successfully");
+ async function handleLogout() {
+ window.open(`${authUrl}/auth/logout`, "_self");
};
useEffect(() => {
@@ -54,7 +42,7 @@ const Navbar = () => {
document.addEventListener("mousedown", handleClickOutside);
async function fetchUser() {
- const res = await fetch("http://localhost:8080/auth/current_user", {
+ const res = await fetch(`${authUrl}/auth/current_user`, {
credentials: "include", // very important
});
if (res.ok) {
diff --git a/src/pages/AssignmentPage.jsx b/src/pages/AssignmentPage.jsx
index 5bd8855..d8b5941 100644
--- a/src/pages/AssignmentPage.jsx
+++ b/src/pages/AssignmentPage.jsx
@@ -1,4 +1,4 @@
-import React, { useState } from "react";
+import React, { useState, useEffect } from "react";
import "../scss/components/_assignment.scss";
const AssignmentPage = () => {
@@ -13,6 +13,32 @@ const AssignmentPage = () => {
const [showModal, setShowModal] = useState(false);
const [editingIndex, setEditingIndex] = useState(null);
+ useEffect(() => {
+ document.title = "Assignment";
+ fetchAssignments();
+ }, []);
+
+ const fetchAssignments = async () => {
+ try {
+ const res = await fetch("http://localhost:8082/instructor/list/9", {
+ // credentials: "include",
+ });
+ if (!res.ok) throw new Error("Failed to fetch");
+
+ const data = await res.json();
+
+
+ // Optional: Remove duplicate assignment IDs if needed
+ const unique = Array.from(
+ new Map(data.map((item) => [item.assignmentid, item])).values()
+ );
+
+ setProjects(unique);
+ } catch (error) {
+ console.error("Error fetching assignments:", error);
+ }
+ };
+
const resetForm = () => {
setStudentName("");
setCampID("");
@@ -28,21 +54,19 @@ const AssignmentPage = () => {
e.preventDefault();
const newProject = {
- studentName,
- campID,
- programID,
+ studentname: studentName,
+ campid: campID,
+ programid: programID,
title,
description,
fileName: file ? file.name : null,
};
if (editingIndex !== null) {
- // Edit mode: update the project at the index
const updatedProjects = [...projects];
updatedProjects[editingIndex] = newProject;
setProjects(updatedProjects);
} else {
- // New submission
setProjects([...projects, newProject]);
}
@@ -53,12 +77,12 @@ const AssignmentPage = () => {
const handleEdit = (index) => {
const project = projects[index];
- setStudentName(project.studentName);
- setCampID(project.campID);
- setProgramID(project.programID);
- setTitle(project.title);
- setDescription(project.description);
- setFile(null); // File can't be set again for editing, usually. You could add note about this.
+ setStudentName(project.studentname || project.studentName || "");
+ setCampID(project.campid || project.campID || "");
+ setProgramID(project.programid || project.programID || "");
+ setTitle(project.title || "");
+ setDescription(project.description || "");
+ setFile(null);
setEditingIndex(index);
setShowModal(true);
};
@@ -70,8 +94,10 @@ const AssignmentPage = () => {
return (
-
📘 Assignments
-
+
+
Assignments
+
+
{showModal && (
@@ -80,110 +106,83 @@ const AssignmentPage = () => {
)}
-
-
📋 Projects
- {projects.map((project, index) => (
-
-
- Student Name: {project.studentName} | CampID: {project.campID} | ProgramID: {project.programID}
-
-
{project.title}
-
{project.description}
- {project.fileName && (
-
Uploaded File: {project.fileName}
+ {projects.length > 0 && (
+
+ {projects.map((project, index) => (
+
+
+ Student Name: {project.studentname || project.studentName} |{" "}
+ CampID: {project.campid || project.campID} |{" "}
+ ProgramID: {project.programid || project.programID}
+
+
+ {project.title &&
{project.title}
}
+ {project.description &&
{project.description}
}
+ {project.fileName &&
Uploaded File: {project.fileName}
}
+
+ {project.assignmenturl && (
+
+ View Assignment
+
+ )}
+ {project.originalfile && (
+
+ Original File |{" "}
+ Editable File
+
+ )}
+
+
+
+
+
+
+
+ ))}
+
)}
-
-
-
-
-
-
-
- ))}
-
-
);
};
diff --git a/src/pages/SignIn.jsx b/src/pages/SignIn.jsx
index 9976eb5..ff2372e 100644
--- a/src/pages/SignIn.jsx
+++ b/src/pages/SignIn.jsx
@@ -1,9 +1,11 @@
import React from "react";
import "@fortawesome/fontawesome-free/css/all.min.css";
+const authUrl = import.meta.env.VITE_AUTH_URL;
+
function SignInForm() {
const [state, setState] = React.useState({
- email: "",
+ assignmentID: "",
password: "",
});
const handleChange = (evt) => {
@@ -17,15 +19,33 @@ function SignInForm() {
const handleOnSubmit = (evt) => {
evt.preventDefault();
- const { email, password } = state;
- alert(`You are login with email: ${email} and password: ${password}`);
+ const { assignmentId, password } = state;
+ console.log(`You are loggind in with email: ${assignmentId} and password: ${password}`);
- for (const key in state) {
- setState({
- ...state,
- [key]: "",
+ console.log("Submitting login request with state:", state);
+ fetch(`${authUrl}/auth/student/login`, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify(state),
+ credentials: "include",
+ })
+ .then((response) => {
+ console.log("Received response:", response);
+ if (!response.ok) {
+ throw new Error("Network response was not ok");
+ }
+ return response.json();
+ })
+ .then((data) => {
+ console.log("Success:", data);
+ window.location.href = "/";
+ })
+ .catch((error) => {
+ console.error("Error occurred during login:", error);
+ alert("Login failed!");
});
- }
};
return (
@@ -39,10 +59,10 @@ function SignInForm() {
*/}
{
evt.preventDefault();
- const { name, email, password } = state;
+ const { assignmentID, password } = state;
alert(
- `You are signed in with name: ${name} email: ${email} and password: ${password}`
+ `You are signed in with assignmentID: ${assignmentID} and password: ${password}`
);
for (const key in state) {
@@ -32,7 +32,12 @@ function SignUpForm() {
};
const googleAuth = () => {
+<<<<<<< HEAD
window.open(authUrl, "_self");
+=======
+
+ window.open(`${authUrl}/auth/google`, "_self");
+>>>>>>> refs/remotes/origin/homepage-2nd-sprint
};
return (
diff --git a/src/scss/components/_assignment.scss b/src/scss/components/_assignment.scss
index 7d424b8..f83f856 100644
--- a/src/scss/components/_assignment.scss
+++ b/src/scss/components/_assignment.scss
@@ -1,7 +1,11 @@
.assignment-page {
- max-width: 600px;
- margin: auto;
+ max-width: 100%;
padding: 20px;
+ margin-top: 70rem;
+ overflow-x: hidden;
+ overflow-y: auto;
+ min-height: 100vh;
+ box-sizing: border-box;
form {
margin-bottom: 20px;
@@ -44,32 +48,97 @@
}
}
- .project-list {
- margin-top: 2rem;
+ // .project-list {
+ // display: grid;
+ // grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
+ // gap: 1.5rem;
+ // margin-top: 2rem;
+ // padding-bottom: 3rem;
+
+ // .project-item {
+ // background: #ffffff;
+ // border: 1px solid #e0e0e0;
+ // border-radius: 12px;
+ // padding: 1.5rem;
+ // box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
+ // transition: transform 0.2s ease, box-shadow 0.2s ease;
+
+ // .project-meta {
+ // margin-bottom: 0.75rem;
+
+ // strong {
+ // color: #34495e;
+ // }
+ // }
+
+ // h4 {
+ // margin: 0.5rem 0;
+ // font-size: 1.2rem;
+ // color: #2d3436;
+ // }
+
+ // p {
+ // margin: 0.25rem 0;
+ // color: #555;
+ // line-height: 1.4;
+
+ // strong {
+ // color: #2d3436;
+ // }
+ // }
+
+ // .action-buttons {
+ // display: flex;
+ // gap: 0.5rem;
+ // margin-top: 0.75rem;
+
+ // button {
+ // background-color: #f4f4f4;
+ // border: 1px solid #ddd;
+ // border-radius: 6px;
+ // padding: 0.4rem 0.8rem;
+ // cursor: pointer;
+ // font-size: 0.9rem;
+
+ // &:hover {
+ // background-color: #e9ecef;
+ // }
+
+ // &:nth-child(1) {
+ // color: #2c3e50;
+ // }
+
+ // &:nth-child(2) {
+ // color: #c0392b;
+ // }
+
+ // &:nth-child(3) {
+ // color: #16a085;
+ // }
+ // }
+ // }
+ // }
+ // }
- h3 {
- color: #4a90e2;
- }
+ .project-list {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr); // exactly 2 columns
+ gap: 1.5rem;
+ margin-top: 2rem;
+ padding-bottom: 3rem;
.project-item {
background: #ffffff;
border: 1px solid #e0e0e0;
border-radius: 12px;
padding: 1.5rem;
- margin-bottom: 1.5rem;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
transition: transform 0.2s ease, box-shadow 0.2s ease;
-
- // &:hover {
- // transform: translateY(-2px);
- // box-shadow: 0 6px 16px rgba(0, 0, 0, 0.08);
- // }
+ overflow-wrap: break-word;
+ box-shadow: rgb(211, 0, 197) 0px 0px 15px, rgb(255, 42, 109) 0px 0px 25px;
.project-meta {
- justify-content: space-between;
- align-items: center;
margin-bottom: 0.75rem;
- flex-wrap: wrap;
strong {
color: #34495e;
@@ -104,7 +173,6 @@
padding: 0.4rem 0.8rem;
cursor: pointer;
font-size: 0.9rem;
- transition: background-color 0.2s ease;
&:hover {
background-color: #e9ecef;
@@ -126,6 +194,7 @@
}
}
+
.modal-overlay {
position: fixed;
@@ -138,6 +207,7 @@
align-items: center;
justify-content: center;
z-index: 1000;
+ overflow: hidden;
}
.modal {
@@ -148,6 +218,7 @@
width: 100%;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
animation: fadeIn 0.3s ease;
+ overflow: auto;
}
.modal h3 {
@@ -235,4 +306,104 @@
transform: translateY(0);
}
}
-}
\ No newline at end of file
+}
+
+.assignment-header-box {
+ background: #0f0f1a;
+ border: 2px solid #00bfff;
+ border-radius: 12px;
+ padding: 50px;
+ text-align: center;
+ margin-bottom: 2rem;
+ // box-shadow: 0 0 20px #00bfff;
+ box-shadow: rgb(211, 0, 197) 0px 0px 15px, rgb(255, 42, 109) 0px 0px 25px;
+ border: 1px solid rgb(211, 0, 197);
+ animation: pulseNeonBlue 2s infinite alternate;
+
+ h2 {
+ color: #00bfff;
+ margin-bottom: 1rem;
+ font-weight: bold;
+ // text-shadow: rgb(5, 217, 232) 0px 0px 5px;
+ }
+
+ button {
+ background-color: #000;
+ border: 2px solid #00bfff;
+ color: #00bfff;
+ padding: 10px 20px;
+ border-radius: 8px;
+ cursor: pointer;
+ font-size: 1rem;
+ font-weight: bold;
+ transition: all 0.3s ease;
+
+ &:hover {
+ background-color: #00bfff;
+ color: #000;
+ }
+ }
+}
+
+// @keyframes pulseNeonBlue {
+// from {
+// box-shadow: 0 0 10px #00bfff, 0 0 20px #00bfff;
+// }
+// to {
+// box-shadow: 0 0 25px #00bfff, 0 0 40px #00bfff;
+// }
+// }
+
+@keyframes pulseNeonHybrid {
+ from {
+ box-shadow:
+ 0 0 10px rgba(211, 0, 197, 0.7),
+ 0 0 20px rgba(255, 42, 109, 0.7),
+ 0 0 10px rgba(0, 191, 255, 0.7);
+ }
+ to {
+ box-shadow:
+ 0 0 25px rgba(211, 0, 197, 0.9),
+ 0 0 40px rgba(255, 42, 109, 0.9),
+ 0 0 30px rgba(0, 191, 255, 0.9);
+ }
+}
+
+
+.assignment-list-box {
+ margin-top: 40px;
+
+ h3 {
+ font-size: 1.5rem;
+ margin-bottom: 20px;
+ }
+
+ .assignment-cards {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
+ gap: 20px;
+ }
+
+ .assignment-card {
+ background: #f5f5f5;
+ padding: 20px;
+ border-radius: 12px;
+ box-shadow: 0 2px 6px rgba(0,0,0,0.1);
+ transition: all 0.3s ease;
+
+ p {
+ margin: 6px 0;
+ }
+
+ a {
+ color: #2c7be5;
+ text-decoration: underline;
+ word-break: break-word;
+ }
+
+ &:hover {
+ transform: translateY(-4px);
+ box-shadow: 0 4px 12px rgba(0,0,0,0.15);
+ }
+ }
+}