From 30e1071fcb39128c5f959b5b04135dc48bd04fb1 Mon Sep 17 00:00:00 2001
From: Dorian Koch <doriank@fsmpi.rwth-aachen.de>
Date: Thu, 5 Sep 2024 17:52:29 +0200
Subject: [PATCH] Add option to only show public courses, Closes #2

---
 lang/de.slf           |  1 +
 lang/en.slf           |  1 +
 src/pages/courses.tsx | 56 +++++++++++++++++++++++++++++++++++++------
 3 files changed, 51 insertions(+), 7 deletions(-)

diff --git a/lang/de.slf b/lang/de.slf
index de4c479..97792e6 100644
--- a/lang/de.slf
+++ b/lang/de.slf
@@ -162,6 +162,7 @@ ui.search.no_results = "Keine Ergebnisse gefunden."
 ui.search.no_query = "Gebe einen Suchbegriff in das Suchfeld ein."
 
 ui.course_list.group_by = "Gruppierung"
+ui.course_list.show_only_public_courses = "Nur öffentliche Veranstaltungen anzeigen"
 
 ui.course.back_to_list = "Zur Kursliste"
 ui.course.download_all_videos = "Download aller Videos"
diff --git a/lang/en.slf b/lang/en.slf
index bf932c4..8b09fb8 100644
--- a/lang/en.slf
+++ b/lang/en.slf
@@ -166,6 +166,7 @@ ui.search.no_results = "No results found."
 ui.search.no_query = "Please enter a search query."
 
 ui.course_list.group_by = "Group by"
+ui.course_list.show_only_public_courses = "Show only public courses"
 
 ui.course.back_to_list = "Back to course list"
 ui.course.download_all_videos = "Download all videos"
diff --git a/src/pages/courses.tsx b/src/pages/courses.tsx
index c9bc534..e22b3f6 100644
--- a/src/pages/courses.tsx
+++ b/src/pages/courses.tsx
@@ -88,9 +88,11 @@ export function CourseItem({
 function CourseGroupCard({
     g,
     groupedby,
+    onlyShowPublicCourses,
 }: {
     g: { groupTitle: string; list: Array<course> };
     groupedby: string;
+    onlyShowPublicCourses: boolean;
 }) {
     return (
         <div className="card mb-3">
@@ -98,14 +100,22 @@ function CourseGroupCard({
                 <h4 className="card-title">{g.groupTitle}</h4>
                 <div className="card-text">
                     <ul className="courses-list m-0 p-0">
-                        {g.list.map((c) => {
-                            return (
+                        {g.list.flatMap((c) => {
+                            if (
+                                onlyShowPublicCourses &&
+                                !c.default_authentication_methods?.includes("public")
+                            ) {
+                                // I chose not to check c.is_visible or c.is_listed here because
+                                // it may be useful for videoag admins to check which courses are falsely set to public
+                                return [];
+                            }
+                            return [
                                 <CourseItem
                                     key={c.id}
                                     course={c}
                                     showSemester={groupedby !== "semester"}
-                                />
-                            );
+                                />,
+                            ];
                         })}
                     </ul>
                 </div>
@@ -117,9 +127,11 @@ function CourseGroupCard({
 function CourseList({
     courseData,
     groupBy,
+    onlyShowPublicCourses,
 }: {
     courseData: ResourceType<GetCoursesResponse>;
     groupBy: GroupByTypes;
+    onlyShowPublicCourses: boolean;
 }) {
     const data = courseData.read()!;
 
@@ -151,7 +163,14 @@ function CourseList({
             return groupBy === "semester" ? -cmp : cmp;
         })
         .map(([key, groupObject]) => {
-            return <CourseGroupCard key={key} g={groupObject} groupedby={groupBy} />;
+            return (
+                <CourseGroupCard
+                    key={key}
+                    g={groupObject}
+                    groupedby={groupBy}
+                    onlyShowPublicCourses={onlyShowPublicCourses}
+                />
+            );
         });
 }
 
@@ -162,6 +181,7 @@ export default function Courses() {
     const { editMode } = useEditMode();
     const [courseData, setCourseData] = useState<ResourceType<GetCoursesResponse>>();
     const { language } = useLanguage();
+    const [onlyShowPublic, setOnlyShowPublic] = useState(false);
 
     const reloadData = () => {
         setCourseData(fetchDataWrapper(api.getCourses()));
@@ -188,7 +208,7 @@ export default function Courses() {
                 )}
             >
                 <div className="col-12 p-0">
-                    <ul className="list-inline d-flex">
+                    <ul className="list-inline d-flex align-items-center">
                         <DropdownButton
                             variant="primary"
                             title={language.get("ui.course_list.group_by")}
@@ -206,6 +226,24 @@ export default function Courses() {
                             ))}
                         </DropdownButton>
 
+                        <div className="ms-2 border border-light-subtle rounded">
+                            <div className="form-check form-switch m-2">
+                                <input
+                                    className="form-check-input"
+                                    type="checkbox"
+                                    role="switch"
+                                    id="only_public_switch"
+                                    onChange={() => {
+                                        setOnlyShowPublic((old) => !old);
+                                    }}
+                                    checked={onlyShowPublic}
+                                />
+                                <label className="form-check-label " htmlFor="only_public_switch">
+                                    {language.get("ui.course_list.show_only_public_courses")}
+                                </label>
+                            </div>
+                        </div>
+
                         <li className="flex-fill" />
 
                         {editMode && (
@@ -222,7 +260,11 @@ export default function Courses() {
                 </div>
 
                 <Suspense fallback={<div className="spinner-border" />}>
-                    <CourseList courseData={courseData} groupBy={groupedBy} />
+                    <CourseList
+                        courseData={courseData}
+                        groupBy={groupedBy}
+                        onlyShowPublicCourses={onlyShowPublic}
+                    />
                 </Suspense>
             </FallbackErrorBoundary>
         </ReloadBoundary>
-- 
GitLab