Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { AuthProvider, ProtectedRoute } from "./context/auth";
import { ModalProvider } from "./context/modal";
import { ProfileProvider } from "./context/profile";
import Welcome from "./pages/welcome";
import CohortViewStudent from "./pages/cohortViewStudent";

const App = () => {
return (
Expand Down Expand Up @@ -48,7 +49,6 @@ const App = () => {
</ProtectedRoute>
}
/>

<Route
path="/profile/:id/edit"
element={
Expand All @@ -57,6 +57,14 @@ const App = () => {
</ProtectedRoute>
}
/>
<Route
path="/cohort/:id"
element={
<ProtectedRoute>
<CohortViewStudent />
</ProtectedRoute>
}
/>
</Routes>
</ModalProvider>
</AuthProvider>
Expand Down
70 changes: 35 additions & 35 deletions src/components/navigation/index.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,41 @@
import { NavLink } from "react-router-dom"
import CohortIcon from "../../assets/icons/cohortIcon"
import HomeIcon from "../../assets/icons/homeIcon"
import ProfileIcon from "../../assets/icons/profileIcon"
import useAuth from "../../hooks/useAuth"
import './style.css'
import { NavLink } from "react-router-dom";
import CohortIcon from "../../assets/icons/cohortIcon";
import HomeIcon from "../../assets/icons/homeIcon";
import ProfileIcon from "../../assets/icons/profileIcon";
import useAuth from "../../hooks/useAuth";
import "./style.css";

const Navigation = () => {
const { token, user } = useAuth();
const { token, user } = useAuth();

if (!token) {
return null;
}
if (!token) {
return null;
}

return (
<nav>
<ul>
<li>
<NavLink to="/">
<HomeIcon colour="#000046" />
<p>Home</p>
</NavLink>
</li>
<li>
<NavLink to={user ? `/profile/${user.id}` : "/"}>
<ProfileIcon />
<p>Profile</p>
</NavLink>
</li>
<li>
<NavLink to="/">
<CohortIcon />
<p>Cohort</p>
</NavLink>
</li>
</ul>
</nav>
);
}
return (
<nav>
<ul>
<li>
<NavLink to="/">
<HomeIcon colour="#000046" />
<p>Home</p>
</NavLink>
</li>
<li>
<NavLink to={user ? `/profile/${user.id}` : "/"}>
<ProfileIcon />
<p>Profile</p>
</NavLink>
</li>
<li>
<NavLink to={user ? `/cohort/${user.id}` : "/"}>
<CohortIcon />
<p>Cohort</p>
</NavLink>
</li>
</ul>
</nav>
);
};

export default Navigation;
44 changes: 22 additions & 22 deletions src/components/posts/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,28 @@ import { useEffect, useState } from "react";
import Post from "../post";
import { getPosts } from "../../service/apiClient";

const Posts = ({ postCreated }) => {
const [posts, setPosts] = useState([])
const Posts = () => {
const [posts, setPosts] = useState([]);

useEffect(() => {
getPosts().then((r) => {
setPosts(r.sort((a, b) => b.id - a.id))
})
}, [postCreated])
useEffect(() => {
getPosts().then(setPosts);
}, []);

return (
<>
{posts ? posts.map(post => {
return <Post
key={post.id}
name={`${post.user.profile.firstName} ${post.user.profile.lastName}`}
date={post.createdAt}
content={post.content}
comments={post.comments}
/>
}) : <p>No posts to show.</p>}
</>
)
}
return (
<>
{posts.map((post) => {
return (
<Post
key={post.id}
name={`${post.author.firstName} ${post.author.lastName}`}
date={post.createdAt}
content={post.content}
comments={post.comments}
/>
);
})}
</>
);
};

export default Posts
export default Posts;
217 changes: 217 additions & 0 deletions src/pages/cohortViewStudent/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
import { useState, useEffect, useContext } from "react";
import useAuth from "../../hooks/useAuth";
import "./style.css";
import Card from "../../components/card";

const CohortViewStudent = () => {
const { token, user } = useAuth();
const apiUrl = process.env.REACT_APP_API_URL;

const [cohort, setCohort] = useState(null);
const [teachers, setTeachers] = useState([]);
const [loading, setLoading] = useState(true);
const [grades, setGrades] = useState(null);
const [completion, setCompletion] = useState(null);

//function to calculate completion for user's grades
function calculateCompletion(data) {
let result = {
modules: { total: 0, completed: 0 },
units: { total: 0, completed: 0 },
exercises: { total: 0, completed: 0 },
};

data.grades.forEach((module) => {
result.modules.total += 1;
let moduleCompleted = true;

module.units.forEach((unit) => {
result.units.total += 1;
let unitCompleted = true;

unit.exercises.forEach((exercise) => {
result.exercises.total += 1;

if (exercise.grade >= 70) {
result.exercises.completed += 1;
} else {
unitCompleted = false;
moduleCompleted = false;
}
});

if (unitCompleted) {
result.units.completed += 1;
}
});

if (moduleCompleted) {
result.modules.completed += 1;
}
});

return result;
}

// useEffect to load required page data
useEffect(() => {
const fetchData = async () => {
try {
setLoading(true);

// Fetch cohort information
const cohortResponse = await fetch(`${apiUrl}/cohorts/1`, {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
});
const cohortData = await cohortResponse.json();
setCohort(cohortData.data);

// Fetch list of teachers
const usersResponse = await fetch(`${apiUrl}/users`, {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
});
const usersData = await usersResponse.json();

const teacherList = usersData.data.users
.filter((userObj) => userObj.user.role === "TEACHER")
.map((userObj) => userObj.user);
setTeachers(teacherList);

// Fetch grades and calculate completion
const gradesResponse = await fetch(
`${apiUrl}/users/${user.id}/completion`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
}
);
const gradesData = await gradesResponse.json();
setGrades(gradesData);
setCompletion(calculateCompletion(gradesData));
} catch (error) {
console.error("Error fetching data:", error);
} finally {
setLoading(false);
}
};

fetchData();
}, [apiUrl, token, user]);

return (
<div id="cohort-page-container">
<div className="cohort-section">
<Card>
<h3>My Cohort</h3>
<div className="cohort-section-header">
<div className="profile-icon">
<p className="icon-text">&lt; &gt;</p>
</div>
<div className="cohort-header-container">
<h4 className="cohort-name">Cohort Name</h4>
<p className="cohort-dates">Cohort Dates</p>
</div>
</div>
<ul className="cohort-details">
{loading ? (
<li>
<p>Loading...</p>
</li>
) : (
cohort?.users.map((user) => (
<li key={user.id} className="user-card">
<div className="profile-icon">
<p>JB</p>
</div>
<p className="bold-text">User Name</p>
</li>
))
)}
<li className="user-card">
<div className="profile-icon">
<p>AB</p>
</div>
<p className="bold-text">User Name</p>
</li>
<li className="user-card">
<div className="profile-icon">
<p>AB</p>
</div>
<p className="bold-text">User Name</p>
</li>
<li className="user-card">
<div className="profile-icon">
<p>AB</p>
</div>
<p className="bold-text">User Name</p>
</li>
</ul>
</Card>
</div>
<div className="right-side-container">
<div className="teachers-section">
<Card>
<h3>Teachers</h3>
<ul className="teachers-details">
{loading ? (
<li>
<p>Loading...</p>
</li>
) : (
teachers.map((teacher) => (
<li key={teacher.id} className="user-card">
<div className="profile-icon">
<p>{`${teacher.firstName[0]}${teacher.lastName[0]}`}</p>
</div>
<div className="teacher-name-and-specialism">
<p className="bold-text">{`${teacher.firstName} ${teacher.lastName}`}</p>
<p className="light-text">
{teacher.specialism ? teacher.specialism : "General"}
</p>
</div>
</li>
))
)}
</ul>
</Card>
</div>
<div className="exercises-section">
<Card>
<h3>My Exercises</h3>
{completion ? (
<div className="exercise-details-container light-text">
<p className="aligned-left">Modules:</p>
<p className="aligned-right">
{`${completion.modules.completed}/${completion.modules.total} completed`}
</p>
<p className="aligned-left">Units:</p>
<p className="aligned-right">
{`${completion.units.completed}/${completion.units.total} completed`}
</p>
<p className="aligned-left">Exercises:</p>
<p className="aligned-right">
{`${completion.exercises.completed}/${completion.exercises.total} completed`}
</p>
</div>
) : (
<p>Loading exercise data...</p>
)}
</Card>
</div>
</div>
</div>
);
};

export default CohortViewStudent;
Loading