Skip to content

Commit

Permalink
Merge pull request #176 from makeopensource/111-Implement-enrolled-no…
Browse files Browse the repository at this point in the history
…t-enrolled-feature

completed enrolled/not-enrolled feature
  • Loading branch information
jessehartloff authored Nov 5, 2024
2 parents 94b82f5 + c2d9cfe commit 97a2f95
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 58 deletions.
18 changes: 17 additions & 1 deletion devU-client/src/components/listItems/courseListItem.scss
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,29 @@

color: $text-color;


&.enrolled {
background-color: #dff0d8; // Light green background for enrolled courses
border-color: #3c763d; // Darker green border for enrolled courses
color: #3c763d; // Change text color to darker green
}
&:hover,
&:focus {
background: $list-item-background-hover;
}
}

.enrollmentStatus {
margin-left: 10px;
font-weight: bold; // Make it bold for emphasis
}

.enrolled {
color: green; // Change color for enrolled courses
}

.notEnrolled {
color: red; // Change color for not enrolled courses
}

@media (max-width: $medium) {
.subText {
Expand Down
2 changes: 1 addition & 1 deletion devU-client/src/components/misc/globalToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const GlobalToolbar = () => {
<DarkModeToggle />
{
<Link to={`/courses`} className={styles.link} >
My Courses
Join a Course
</Link>
}
{/*<Link to={`/myCourses`} className={styles.link}>*/}
Expand Down
120 changes: 64 additions & 56 deletions devU-client/src/components/pages/listPages/courses/coursesListPage.tsx
Original file line number Diff line number Diff line change
@@ -1,70 +1,81 @@
import React, {useEffect, useState} from 'react'
import {Course, UserCourse} from 'devu-shared-modules'
import LoadingOverlay from 'components/shared/loaders/loadingOverlay'
import PageWrapper from 'components/shared/layouts/pageWrapper'
import Dropdown, {Option} from 'components/shared/inputs/dropdown'
import ErrorPage from '../../errorPage/errorPage'
import RequestService from 'services/request.service'
import styles from './coursesListPage.scss'
import React, { useEffect, useState } from 'react';
import { Course } from 'devu-shared-modules';
import LoadingOverlay from 'components/shared/loaders/loadingOverlay';
import PageWrapper from 'components/shared/layouts/pageWrapper';
import Dropdown, { Option } from 'components/shared/inputs/dropdown';
import ErrorPage from '../../errorPage/errorPage';
import RequestService from 'services/request.service';
import styles from './coursesListPage.scss';
import CourseListItem from "../../../listItems/courseListItem";
// import {useAppSelector} from "../../../../redux/hooks";
import Button from "@mui/material/Button";
import {useHistory} from "react-router-dom";
import { useHistory } from "react-router-dom";
import { useAppSelector } from "../../../../redux/hooks";

type Filter = true | false
type Filter = true | false;

const filterOptions: Option<Filter>[] = [
{label: 'Expand All', value: true},
{label: 'Collapse All', value: false},
]
{ label: 'Expand All', value: true },
{ label: 'Collapse All', value: false },
];

const UserCoursesListPage = () => {
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);

const [allCourses, setAllCourses] = useState<Course[]>([]);
const [filter, setFilter] = useState<Filter>(false);
const history = useHistory();

const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
const [userCourses, setUserCourses] = useState(new Array<UserCourse>())
const [filter, setFilter] = useState<Filter>(false )
const history = useHistory()

//Temporary place to store state for all courses
const [allCourses, setAllCourses] = useState(new Array<Course>())
// Get userId from Redux store
const userId = useAppSelector((store) => store.user.id);

useEffect(() => {
fetchData()
}, [])
fetchData();
}, []);

const fetchData = async () => {
try {
// const userCourses = await RequestService.get<UserCourse[]>(`/api/user-courses?filterBy=${filter}`)
const courseRequests = userCourses.map((u) => RequestService.get<Course>(`/api/courses/${u.courseId}`))
const courses = await Promise.all(courseRequests)

// Mapify course ids so we can look them up more easilly via their id
const courseMap: Record<string, Course> = {}
for (const course of courses) courseMap[course.id || ''] = course

// Temporary place to grab and display all courses
const allCourses = await RequestService.get('/api/courses')
setAllCourses(allCourses)

setUserCourses(userCourses)
// Fetch user-specific courses
const userCourseData = await RequestService.get<{
instructorCourses: Course[];
activeCourses: Course[];
pastCourses: Course[];
upcomingCourses: Course[];
}>(`/api/courses/user/${userId}`);

// Flatten and combine user course data into a single array
const userCoursesList = [
...userCourseData.instructorCourses,
...userCourseData.activeCourses,
...userCourseData.pastCourses,
...userCourseData.upcomingCourses,
];

// Fetch all courses
const allCourseData = await RequestService.get<Course[]>(`/api/courses`);

// Filter to get courses the user is not enrolled in
const unenrolledCourses = allCourseData.filter(
(course) => !userCoursesList.some((userCourse) => userCourse.id === course.id)
);


setAllCourses(unenrolledCourses);
} catch (error: any) {
setError(error)
setError(error);
} finally {
setLoading(false)
setLoading(false);
}
}
};

const handleFilterChange = (updatedFilter: Filter) => {
setFilter(updatedFilter)
}
setFilter(updatedFilter);
};

if (loading) return <LoadingOverlay delay={250}/>
if (error) return <ErrorPage error={error}/>

const defaultOption = filterOptions.find((o) => o.value === filter)
if (loading) return <LoadingOverlay delay={250} />;
if (error) return <ErrorPage error={error} />;

const defaultOption = filterOptions.find((o) => o.value === filter);

return (
<PageWrapper>
Expand All @@ -73,9 +84,8 @@ const UserCoursesListPage = () => {
<h1>All Courses</h1>
<div className={styles.largeLine}></div>

<Button variant="contained" onClick={() => {
history.push(`/addCoursesForm`)
}}>Add Course
<Button variant="contained" onClick={() => history.push(`/addCoursesForm`)}>
Add Course
</Button>
<div className={styles.filters}>
<Dropdown
Expand All @@ -87,13 +97,11 @@ const UserCoursesListPage = () => {
/>
</div>
</div>
{allCourses.map(course => (
<CourseListItem course={course} key={course.id} isOpen={filter}/>
{allCourses.map((course) => (
<CourseListItem course={course} key={course.id} isOpen={filter} />
))}
</PageWrapper>
)


}
);
};

export default UserCoursesListPage
export default UserCoursesListPage;
34 changes: 34 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"devDependencies": {
"@types/react": "^18.3.12"
}
}

0 comments on commit 97a2f95

Please sign in to comment.