diff --git a/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/course.tsx b/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/course.tsx
new file mode 100644
index 00000000..aa1678d4
--- /dev/null
+++ b/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/course.tsx
@@ -0,0 +1,232 @@
+"use client";
+import { EyeOpenIcon, Pencil2Icon } from "@radix-ui/react-icons";
+import { removeCourse, startCourse } from "@services/courses/activity";
+import Link from "next/link";
+import React from "react";
+import styled from "styled-components";
+import { getAPIUrl, getBackendUrl, getUriWithOrg } from "@services/config/config";
+import useSWR, { mutate } from "swr";
+import ToolTip from "@components/UI/Tooltip/Tooltip";
+import PageLoading from "@components/Pages/PageLoading";
+import { revalidateTags } from "@services/utils/ts/requests";
+
+const CourseClient = (props: any) => {
+ const courseid = props.courseid;
+ const orgslug = props.orgslug;
+ const course = props.course;
+
+ async function startCourseUI() {
+ // Create activity
+ await startCourse("course_" + courseid, orgslug);
+
+ revalidateTags(['courses']);
+ }
+
+ async function quitCourse() {
+
+ // Close activity
+ let activity = await removeCourse("course_" + courseid, orgslug);
+ console.log(activity);
+
+ // Mutate course
+ revalidateTags(['courses']);
+ }
+
+ console.log(course);
+ return (
+ <>
+ {!course ? (
+
+ ) : (
+
+ Course
+
+ {course.course.name}{" "}
+
+
+ {" "}
+
+
+
+
+
+
+
+
+ Description
+
+
+ {course.course.description}
+
+
+ What you will learn
+
+ {course.learnings == ![] ? "no data" : course.learnings}
+
+
+ Course Lessons
+
+
+ {course.chapters.map((chapter: any) => {
+ return (
+
+
{chapter.name}
+
{chapter.activities.map((activity: any) => {
+ return (
+ <>
+
+ {activity.name}
+
+
+ {" "}
+
+ >
+ );
+ })}
+
+ );
+ })}
+
+
+
+ {course.trail.status == "ongoing" ? (
+
+ ) : (
+
+ )}
+
+
+
+ )}
+ >
+ );
+};
+
+const CourseThumbnailWrapper = styled.div`
+ display: flex;
+ padding-bottom: 20px;
+ img {
+ width: 100%;
+ height: 300px;
+ object-fit: cover;
+ object-position: center;
+ background: url(), #d9d9d9;
+ border: 1px solid rgba(255, 255, 255, 0.19);
+ box-shadow: 0px 13px 33px -13px rgba(0, 0, 0, 0.42);
+ border-radius: 7px;
+ }
+`;
+const CoursePageLayout = styled.div`
+ width: 1300px;
+ margin: 0 auto;
+ p {
+ margin-bottom: 0px;
+ letter-spacing: -0.05em;
+
+ color: #727272;
+ font-weight: 700;
+ }
+ h1 {
+ margin-top: 5px;
+ letter-spacing: -0.05em;
+ margin-bottom: 10px;
+ }
+`;
+
+const ChaptersWrapper = styled.div`
+ display: flex;
+ width: 100%;
+`;
+const CourseIndicator = styled.div< { active?: boolean, done?: boolean } >`
+ border-radius: 20px;
+ height: 5px;
+ background: #151515;
+ border-radius: 3px;
+
+ background-color: ${props => props.done ? "green" : "black"};
+
+ width: 40px;
+ margin: 10px;
+ margin-bottom: 20px;
+ margin-left: 0px;
+
+ &:hover {
+ cursor: pointer;
+ background-color: #9d9d9d;
+ }
+`;
+
+const ChapterSeparator = styled.div`
+ display: flex;
+ flex-direction: row;
+ padding-right: 7px;
+`;
+
+const BoxWrapper = styled.div`
+ background: #ffffff;
+ box-shadow: 0px 4px 16px rgba(0, 0, 0, 0.03);
+ border-radius: 7px;
+ padding: 20px;
+ padding-top: 7px;
+ padding-left: 30px;
+
+ p {
+ font-family: "DM Sans";
+ font-style: normal;
+ font-weight: 500;
+ line-height: 16px;
+ letter-spacing: -0.02em;
+
+ color: #9d9d9d;
+ }
+`;
+
+const CourseMetaWrapper = styled.div`
+ display: flex;
+ justify-content: space-between;
+`;
+
+const CourseMetaLeft = styled.div`
+ width: 80%;
+`;
+
+const CourseMetaRight = styled.div`
+ background: #ffffff;
+ box-shadow: 0px 4px 16px rgba(0, 0, 0, 0.03);
+ border-radius: 7px;
+ padding: 20px;
+ width: 30%;
+ display: flex;
+ height: 100%;
+ justify-content: center;
+ margin-left: 50px;
+ margin-top: 20px;
+ button {
+ width: 100%;
+ height: 50px;
+ background: #151515;
+ border-radius: 15px;
+ border: none;
+ color: white;
+ font-weight: 700;
+ font-family: "DM Sans";
+ font-size: 16px;
+ letter-spacing: -0.05em;
+ transition: all 0.2s ease;
+ box-shadow: 0px 13px 33px -13px rgba(0, 0, 0, 0.42);
+
+ &:hover {
+ cursor: pointer;
+ background: #000000;
+ }
+ }
+`;
+
+export default CourseClient;
diff --git a/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/loading.tsx b/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/loading.tsx
new file mode 100644
index 00000000..b3fd3bc3
--- /dev/null
+++ b/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/loading.tsx
@@ -0,0 +1,9 @@
+import PageLoading from "@components/Pages/PageLoading";
+
+export default function Loading() {
+ // Or a custom loading skeleton component
+ return (
+
+ )
+
+}
\ No newline at end of file
diff --git a/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/page.tsx b/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/page.tsx
index 8a6214c4..3617db18 100644
--- a/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/page.tsx
+++ b/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/page.tsx
@@ -1,261 +1,44 @@
-"use client";
-import { EyeOpenIcon, Pencil2Icon } from "@radix-ui/react-icons";
-import { removeCourse, startCourse } from "@services/courses/activity";
-import Link from "next/link";
-import React from "react";
-import styled from "styled-components";
-import { getAPIUrl, getBackendUrl, getUriWithOrg } from "@services/config/config";
-import useSWR, { mutate } from "swr";
-import { swrFetcher } from "@services/utils/ts/requests";
-import { useRouter } from "next/navigation";
-import ToolTip from "@components/UI/Tooltip/Tooltip";
-import PageLoading from "@components/Pages/PageLoading";
+import React from 'react'
+import CourseClient from './course'
+import { cookies } from 'next/headers';
+import { getCourseMetadataWithAuthHeader } from '@services/courses/courses';
+import { getOrganizationContextInfo } from '@services/organizations/orgs';
+import { Metadata } from 'next';
-const CourseIdPage = (params: any) => {
- const courseid = params.params.courseid;
- const orgslug = params.params.orgslug;
- const router = useRouter();
-
- const { data: course, error: error } = useSWR(`${getAPIUrl()}courses/meta/course_${courseid}`,
- (url: string, body: any) => swrFetcher(url, body, router)
- );
-
- async function startCourseUI() {
- // Create activity
- await startCourse("course_" + courseid, orgslug);
-
- // Mutate course
- mutate(`${getAPIUrl()}courses/meta/course_${courseid}`);
- }
-
- async function quitCourse() {
-
- // Close activity
- let activity = await removeCourse("course_" + courseid, orgslug);
- console.log(activity);
-
- // Mutate course
- mutate(`${getAPIUrl()}courses/meta/course_${courseid}`);
- }
-
- return (
- <>
- {error &&
Failed to load
}
- {!course ? (
-
- ) : (
-
-
- Course
-
- {course.course.name}{" "}
-
-
- {" "}
-
-
- {course.chapters.map((chapter: any) => {
- return (
-
- {chapter.activities.map((activity: any) => {
- return (
- <>
-
-
-
-
-
-
- >
- );
- })}
-
- );
- })}
-
-
-
-
-
-
-
-
- Description
-
-
- {course.course.description}
-
-
- What you will learn
-
- {course.course.learnings == ![] ? "no data" : course.course.learnings}
-
-
- Course Lessons
-
-
- {course.chapters.map((chapter: any) => {
- return (
-
-
{chapter.name}
-
{chapter.activities.map((activity: any) => {
- return (
- <>
-
- {activity.name}
-
-
- {" "}
-
- >
- );
- })}
-
- );
- })}
-
-
-
- {course.trail.status == "ongoing" ? (
-
- ) : (
-
- )}
-
-
-
- )}
- >
- );
+type MetadataProps = {
+ params: { orgslug: string, courseid: string };
+ searchParams: { [key: string]: string | string[] | undefined };
};
-const CourseThumbnailWrapper = styled.div`
- display: flex;
- padding-bottom: 20px;
- img {
- width: 100%;
- height: 300px;
- object-fit: cover;
- object-position: center;
- background: url(), #d9d9d9;
- border: 1px solid rgba(255, 255, 255, 0.19);
- box-shadow: 0px 13px 33px -13px rgba(0, 0, 0, 0.42);
- border-radius: 7px;
- }
-`;
-const CoursePageLayout = styled.div`
- width: 1300px;
- margin: 0 auto;
- p {
- margin-bottom: 0px;
- letter-spacing: -0.05em;
+export async function generateMetadata(
+ { params }: MetadataProps,
+): Promise {
+ const cookieStore = cookies();
+ const access_token_cookie: any = cookieStore.get('access_token_cookie');
- color: #727272;
- font-weight: 700;
- }
- h1 {
- margin-top: 5px;
- letter-spacing: -0.05em;
- margin-bottom: 10px;
- }
-`;
+ // Get Org context information
+ const org = await getOrganizationContextInfo(params.orgslug, { revalidate: 1800, tags: ['organizations'] });
+ const course_meta = await getCourseMetadataWithAuthHeader(params.courseid, { revalidate: 360, tags: ['courses'] }, access_token_cookie.value)
-const ChaptersWrapper = styled.div`
- display: flex;
- width: 100%;
-`;
-const CourseIndicator = styled.div< { active?: boolean, done?: boolean } >`
- border-radius: 20px;
- height: 5px;
- background: #151515;
- border-radius: 3px;
+ return {
+ title: course_meta.course.name + ` — ${org.name}`,
+ description: course_meta.course.mini_description,
+ };
+}
- background-color: ${props => props.done ? "green" : "black"};
- width: 40px;
- margin: 10px;
- margin-bottom: 20px;
- margin-left: 0px;
- &:hover {
- cursor: pointer;
- background-color: #9d9d9d;
- }
-`;
+const CoursePage = async (params: any) => {
+ const cookieStore = cookies();
+ const access_token_cookie: any = cookieStore.get('access_token_cookie');
+ const courseid = params.params.courseid
+ const orgslug = params.params.orgslug;
+ const course_meta = await getCourseMetadataWithAuthHeader(courseid, { revalidate: 360, tags: ['courses'] }, access_token_cookie.value)
+ return (
+
+
+
+ )
+}
-const ChapterSeparator = styled.div`
- display: flex;
- flex-direction: row;
- padding-right: 7px;
-`;
-
-const BoxWrapper = styled.div`
- background: #ffffff;
- box-shadow: 0px 4px 16px rgba(0, 0, 0, 0.03);
- border-radius: 7px;
- padding: 20px;
- padding-top: 7px;
- padding-left: 30px;
-
- p {
- font-family: "DM Sans";
- font-style: normal;
- font-weight: 500;
- line-height: 16px;
- letter-spacing: -0.02em;
-
- color: #9d9d9d;
- }
-`;
-
-const CourseMetaWrapper = styled.div`
- display: flex;
- justify-content: space-between;
-`;
-
-const CourseMetaLeft = styled.div`
- width: 80%;
-`;
-
-const CourseMetaRight = styled.div`
- background: #ffffff;
- box-shadow: 0px 4px 16px rgba(0, 0, 0, 0.03);
- border-radius: 7px;
- padding: 20px;
- width: 30%;
- display: flex;
- height: 100%;
- justify-content: center;
- margin-left: 50px;
- margin-top: 20px;
- button {
- width: 100%;
- height: 50px;
- background: #151515;
- border-radius: 15px;
- border: none;
- color: white;
- font-weight: 700;
- font-family: "DM Sans";
- font-size: 16px;
- letter-spacing: -0.05em;
- transition: all 0.2s ease;
- box-shadow: 0px 13px 33px -13px rgba(0, 0, 0, 0.42);
-
- &:hover {
- cursor: pointer;
- background: #000000;
- }
- }
-`;
-
-export default CourseIdPage;
+export default CoursePage
\ No newline at end of file
diff --git a/front/app/orgs/[orgslug]/(withmenu)/courses/page.tsx b/front/app/orgs/[orgslug]/(withmenu)/courses/page.tsx
index 17dd3580..ef2615db 100644
--- a/front/app/orgs/[orgslug]/(withmenu)/courses/page.tsx
+++ b/front/app/orgs/[orgslug]/(withmenu)/courses/page.tsx
@@ -17,7 +17,7 @@ export async function generateMetadata(
// Get Org context information
const org = await getOrganizationContextInfo(params.orgslug, { revalidate: 1800, tags: ['organizations'] });
return {
- title: org.name + " — Courses",
+ title: "Courses — " + org.name,
description: org.description,
};
}
diff --git a/front/services/courses/chapters.ts b/front/services/courses/chapters.ts
index eecaca41..35a8887c 100644
--- a/front/services/courses/chapters.ts
+++ b/front/services/courses/chapters.ts
@@ -1,5 +1,5 @@
import { getAPIUrl } from "@services/config/config";
-import { RequestBody, errorHandling } from "@services/utils/ts/requests";
+import { RequestBody, RequestBodyWithAuthHeader, errorHandling } from "@services/utils/ts/requests";
/*
This file includes only POST, PUT, DELETE requests
@@ -8,11 +8,13 @@ import { RequestBody, errorHandling } from "@services/utils/ts/requests";
//TODO : depreciate this function
export async function getCourseChaptersMetadata(course_id: any, next: any) {
- const result = await fetch(`${getAPIUrl()}chapters/meta/course_${course_id}`, RequestBody("GET", null,next));
+ const result = await fetch(`${getAPIUrl()}chapters/meta/course_${course_id}`, RequestBody("GET", null, next));
const res = await errorHandling(result);
return res;
}
+
+
export async function updateChaptersMetadata(course_id: any, data: any) {
const result: any = await fetch(`${getAPIUrl()}chapters/meta/course_${course_id}`, RequestBody("PUT", data, null));
const res = await errorHandling(result);
diff --git a/front/services/courses/courses.ts b/front/services/courses/courses.ts
index 1d6b75a6..62e29b3f 100644
--- a/front/services/courses/courses.ts
+++ b/front/services/courses/courses.ts
@@ -19,6 +19,11 @@ export async function getOrgCoursesWithAuthHeader(org_id: number, next: any, acc
return res;
}
+export async function getCourseMetadataWithAuthHeader(course_id: any, next: any, access_token: string) {
+ const result = await fetch(`${getAPIUrl()}courses/meta/course_${course_id}`, RequestBodyWithAuthHeader("GET", null, next, access_token));
+ const res = await errorHandling(result);
+ return res;
+}
export async function getCourse(course_id: string, next: any) {
const result: any = await fetch(`${getAPIUrl()}courses/${course_id}`, RequestBody("GET", null, next));