diff --git a/front/app/api/revalidate/route.ts b/front/app/api/revalidate/route.ts index c3d0aa71..3ca5eec1 100644 --- a/front/app/api/revalidate/route.ts +++ b/front/app/api/revalidate/route.ts @@ -6,7 +6,7 @@ export async function GET(request: NextRequest) { revalidateTag(tag); return NextResponse.json( - { revalidated: true, now: Date.now() }, + { revalidated: true, now: Date.now(), tag }, { status: 200, headers: { diff --git a/front/app/editor/course/[courseid]/activity/[activityid]/edit/loading.tsx b/front/app/editor/course/[courseid]/activity/[activityid]/edit/loading.tsx index b3fd3bc3..3f902486 100644 --- a/front/app/editor/course/[courseid]/activity/[activityid]/edit/loading.tsx +++ b/front/app/editor/course/[courseid]/activity/[activityid]/edit/loading.tsx @@ -1,4 +1,4 @@ -import PageLoading from "@components/Pages/PageLoading"; +import PageLoading from "@components/Objects/Loaders/PageLoading"; export default function Loading() { // Or a custom loading skeleton component diff --git a/front/app/editor/course/[courseid]/activity/[activityid]/edit/page.tsx b/front/app/editor/course/[courseid]/activity/[activityid]/edit/page.tsx index 2be18fae..37c19000 100644 --- a/front/app/editor/course/[courseid]/activity/[activityid]/edit/page.tsx +++ b/front/app/editor/course/[courseid]/activity/[activityid]/edit/page.tsx @@ -1,7 +1,7 @@ import { default as React, } from "react"; import { useRouter } from "next/navigation"; import AuthProvider from "@components/Security/AuthProvider"; -import EditorWrapper from "@components/Editor/EditorWrapper"; +import EditorWrapper from "@components/Objects/Editor/EditorWrapper"; import { getAPIUrl } from "@services/config/config"; import { swrFetcher } from "@services/utils/ts/requests"; import { getOrganizationContextInfo } from "@services/organizations/orgs"; diff --git a/front/app/layout.tsx b/front/app/layout.tsx index dfad1471..84c73f3a 100644 --- a/front/app/layout.tsx +++ b/front/app/layout.tsx @@ -1,6 +1,6 @@ "use client"; import "../styles/globals.css"; -import StyledComponentsRegistry from "../components/UI/libs/styled-registry"; +import StyledComponentsRegistry from "../components/Utils/libs/styled-registry"; import { motion } from "framer-motion"; export default function RootLayout({ children }: { children: React.ReactNode }) { diff --git a/front/app/organizations/new/page.tsx b/front/app/organizations/new/page.tsx index d80467e0..df43c47b 100644 --- a/front/app/organizations/new/page.tsx +++ b/front/app/organizations/new/page.tsx @@ -1,6 +1,5 @@ "use client"; import React from "react"; -import { Title } from "../../../components/UI/Elements/Styles/Title"; import { createNewOrganization } from "../../../services/organizations/orgs"; const Organizations = () => { @@ -35,7 +34,7 @@ const Organizations = () => { return (
- New Organization +
New Organization
Name:
Description: diff --git a/front/app/organizations/page.tsx b/front/app/organizations/page.tsx index 84b3fb64..e2654448 100644 --- a/front/app/organizations/page.tsx +++ b/front/app/organizations/page.tsx @@ -1,7 +1,6 @@ "use client"; //todo: use server components import Link from "next/link"; import React from "react"; -import { Title } from "../../components/UI/Elements/Styles/Title"; import { deleteOrganizationFromBackend } from "@services/organizations/orgs"; import useSWR, { mutate } from "swr"; import { swrFetcher } from "@services/utils/ts/requests"; @@ -19,14 +18,14 @@ const Organizations = () => { return ( <> - + <div className="font-bold text-lg"> Your Organizations{" "} <Link href="/organizations/new"> <button className="bg-blue-500 text-white px-2 py-1 rounded-md hover:bg-blue-600 focus:outline-none"> + </button> </Link> - +

{error &&

Failed to load

} diff --git a/front/app/orgs/[orgslug]/(withmenu)/collection/[collectionid]/error.tsx b/front/app/orgs/[orgslug]/(withmenu)/collection/[collectionid]/error.tsx index 9e4c3efb..8bac23db 100644 --- a/front/app/orgs/[orgslug]/(withmenu)/collection/[collectionid]/error.tsx +++ b/front/app/orgs/[orgslug]/(withmenu)/collection/[collectionid]/error.tsx @@ -1,6 +1,6 @@ 'use client'; // Error components must be Client Components -import ErrorUI from '@components/UI/Error/Error'; +import ErrorUI from '@components/StyledElements/Error/Error'; import { useEffect } from 'react'; export default function Error({ diff --git a/front/app/orgs/[orgslug]/(withmenu)/collection/[collectionid]/loading.tsx b/front/app/orgs/[orgslug]/(withmenu)/collection/[collectionid]/loading.tsx index 9a7cafe9..ec352ab7 100644 --- a/front/app/orgs/[orgslug]/(withmenu)/collection/[collectionid]/loading.tsx +++ b/front/app/orgs/[orgslug]/(withmenu)/collection/[collectionid]/loading.tsx @@ -1,4 +1,4 @@ -import PageLoading from "@components/Pages/PageLoading"; +import PageLoading from "@components/Objects/Loaders/PageLoading"; export default function Loading() { return ( diff --git a/front/app/orgs/[orgslug]/(withmenu)/collection/[collectionid]/page.tsx b/front/app/orgs/[orgslug]/(withmenu)/collection/[collectionid]/page.tsx index 7a79fa23..f96b7734 100644 --- a/front/app/orgs/[orgslug]/(withmenu)/collection/[collectionid]/page.tsx +++ b/front/app/orgs/[orgslug]/(withmenu)/collection/[collectionid]/page.tsx @@ -1,3 +1,4 @@ +import GeneralWrapperStyled from "@components/StyledElements/Wrappers/GeneralWrapper"; import { getBackendUrl, getUriWithOrg } from "@services/config/config"; import { getCollectionByIdWithAuthHeader } from "@services/courses/collections"; import { getOrganizationContextInfo } from "@services/organizations/orgs"; @@ -38,7 +39,7 @@ const CollectionPage = async (params : any) => { } - return
+ return

Collection

{col.name}


@@ -56,7 +57,7 @@ const CollectionPage = async (params : any) => { -
; + ; }; export default CollectionPage; \ No newline at end of file diff --git a/front/app/orgs/[orgslug]/(withmenu)/collections/admin.tsx b/front/app/orgs/[orgslug]/(withmenu)/collections/admin.tsx index 0acef9ba..04a9307d 100644 --- a/front/app/orgs/[orgslug]/(withmenu)/collections/admin.tsx +++ b/front/app/orgs/[orgslug]/(withmenu)/collections/admin.tsx @@ -1,70 +1,34 @@ 'use client'; +import AuthenticatedClientElement from '@components/Security/AuthenticatedClientElement'; import { AuthContext } from '@components/Security/AuthProvider'; +import { getUriWithOrg } from '@services/config/config'; import { deleteCollection } from '@services/courses/collections'; import { revalidateTags } from '@services/utils/ts/requests'; import { Link, Trash } from 'lucide-react'; +import { useRouter } from 'next/navigation'; import React from 'react' const CollectionAdminEditsArea = (props: any) => { - const org_roles_values = ["admin", "owner"]; - const user_roles_values = ["role_admin"]; - const auth: any = React.useContext(AuthContext); - - - // this is amazingly terrible code, but gotta release that MVP - // TODO: fix this - - function isAuthorized() { - const org_id = props.collection.org_id; - const org_roles = auth.userInfo.user_object.orgs; - const user_roles = auth.userInfo.user_object.roles; - const org_role = org_roles.find((org: any) => org.org_id == org_id); - const user_role = user_roles.find((role: any) => role.org_id == org_id); - - if (org_role && user_role) { - if (org_roles_values.includes(org_role.org_role) && user_roles_values.includes(user_role.role_id)) { - return true; - } - else { - return false; - } - } else { - return false; - } - } + const router = useRouter(); const deleteCollectionUI = async (collectionId: number) => { await deleteCollection(collectionId); revalidateTags(["collections"]); // reload the page - window.location.reload(); + router.refresh(); + router.push(getUriWithOrg(props.orgslug, "/collections")); } - // this is amazingly terrible code, but gotta release that MVP - // TODO: fix this - - if (auth.isAuthenticated) { - if (isAuthorized()) { - return ( -
- - -
- ) - } else { - return ( -
- ) - } - } - else { - return ( -
- ) - } + return ( + +
+ +
+
+ ) } export default CollectionAdminEditsArea; \ No newline at end of file diff --git a/front/app/orgs/[orgslug]/(withmenu)/collections/loading.tsx b/front/app/orgs/[orgslug]/(withmenu)/collections/loading.tsx index b3fd3bc3..3f902486 100644 --- a/front/app/orgs/[orgslug]/(withmenu)/collections/loading.tsx +++ b/front/app/orgs/[orgslug]/(withmenu)/collections/loading.tsx @@ -1,4 +1,4 @@ -import PageLoading from "@components/Pages/PageLoading"; +import PageLoading from "@components/Objects/Loaders/PageLoading"; export default function Loading() { // Or a custom loading skeleton component diff --git a/front/app/orgs/[orgslug]/(withmenu)/collections/new/page.tsx b/front/app/orgs/[orgslug]/(withmenu)/collections/new/page.tsx index cf94e666..62b20dfe 100644 --- a/front/app/orgs/[orgslug]/(withmenu)/collections/new/page.tsx +++ b/front/app/orgs/[orgslug]/(withmenu)/collections/new/page.tsx @@ -1,7 +1,6 @@ "use client"; import { useRouter } from "next/navigation"; import React from "react"; -import { Title } from "@components/UI/Elements/Styles/Title"; import { createCollection } from "@services/courses/collections"; import useSWR from "swr"; import { getAPIUrl, getUriWithOrg } from "@services/config/config"; @@ -45,14 +44,16 @@ function NewCollection(params: any) { }; await createCollection(collection); revalidateTags(["collections"]); + router.prefetch(getUriWithOrg(orgslug, "/collections")); router.push(getUriWithOrg(orgslug, "/collections")); + router.refresh(); }; return ( <>
- Add new +
Add new
{ const collections = await getOrgCollectionsWithAuthHeader(org_id, access_token_cookie ? access_token_cookie.value : null); return ( -
+
- + <TypeOfContentTitle title="Collections" type="col" /> + <AuthenticatedClientElement checkMethod='authentication'> <Link className="flex justify-center" href={getUriWithOrg(orgslug, "/collections/new")}> <button className="rounded-md bg-black antialiased ring-offset-purple-800 p-2 px-5 my-auto font text-sm font-bold text-white drop-shadow-lg">Add Collection + </button> </Link> + </AuthenticatedClientElement> </div> <div className="home_collections flex flex-wrap"> {collections.map((collection: any) => ( - <div className="pr-8 flex flex-col" key={collection.collection_id}> - <CollectionAdminEditsArea collection_id={collection.collection_id} collection={collection} /> + <div className="flex flex-col py-3 px-3" key={collection.collection_id}> + <CollectionAdminEditsArea org_id={org_id} collection_id={collection.collection_id} collection={collection} /> <Link href={getUriWithOrg(orgslug, "/collection/" + removeCollectionPrefix(collection.collection_id))}> <div className="inset-0 ring-1 ring-inset ring-black/10 rounded-lg shadow-xl relative w-[249px] h-[180px] bg-cover flex flex-col items-center justify-center bg-indigo-600 font-bold text-zinc-50" > <h1 className="font-bold text-lg py-2 justify-center mb-2">{collection.name}</h1> @@ -68,7 +69,7 @@ const CollectionsPage = async (params: any) => { </div> ))} </div> - </div> + </GeneralWrapperStyled> ); } diff --git a/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/activity/[activityid]/activity.tsx b/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/activity/[activityid]/activity.tsx index bf498799..de2fb637 100644 --- a/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/activity/[activityid]/activity.tsx +++ b/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/activity/[activityid]/activity.tsx @@ -1,15 +1,15 @@ "use client"; import Link from "next/link"; -import React, { useMemo } from "react"; +import React from "react"; import { getAPIUrl, getBackendUrl, getUriWithOrg } from "@services/config/config"; import Canva from "@components/Pages/Activities/DynamicCanva/DynamicCanva"; -import styled from "styled-components"; import VideoActivity from "@components/Pages/Activities/Video/Video"; -import useSWR, { mutate } from "swr"; import { Check } from "lucide-react"; import { markActivityAsComplete } from "@services/courses/activity"; -import ToolTip from "@components/UI/Tooltip/Tooltip"; import DocumentPdfActivity from "@components/Pages/Activities/DocumentPdf/DocumentPdf"; +import ActivityIndicators from "@components/Pages/Courses/ActivityIndicators"; +import GeneralWrapperStyled from "@components/StyledElements/Wrappers/GeneralWrapper"; +import { useRouter } from "next/navigation"; interface ActivityClientProps { activityid: string; @@ -19,6 +19,7 @@ interface ActivityClientProps { course: any; } + function ActivityClient(props: ActivityClientProps) { const activityid = props.activityid; const courseid = props.courseid; @@ -26,195 +27,104 @@ function ActivityClient(props: ActivityClientProps) { const activity = props.activity; const course = props.course; - - async function markActivityAsCompleteFront() { - const trail = await markActivityAsComplete(orgslug, courseid, activityid); - mutate(`${getAPIUrl()}activities/activity_${activityid}`); - mutate(`${getAPIUrl()}courses/meta/course_${courseid}`); + function getChapterName(chapterId: string) { + let chapterName = ""; + course.chapters.forEach((chapter: any) => { + if (chapter.chapter_id === chapterId) { + chapterName = chapter.name; + } + }); + return chapterName; } + + + + return ( <> - <ActivityLayout> - <pre style={{ display: "none" }}>{JSON.stringify(activity, null, 2)}</pre> - <ActivityTopWrapper> - <ActivityThumbnail> + <GeneralWrapperStyled> + <div className="space-y-4 pt-4"> + <div className="flex space-x-6"> + <div className="flex"> <Link href={getUriWithOrg(orgslug, "") + `/course/${courseid}`}> - <img src={`${getBackendUrl()}content/uploads/img/${course.course.thumbnail}`} alt="" /> + <img className="w-[100px] h-[57px] rounded-md drop-shadow-md" src={`${getBackendUrl()}content/uploads/img/${course.course.thumbnail}`} alt="" /> </Link> - </ActivityThumbnail> - <ActivityInfo> - <p>Course</p> - <h1>{course.course.name}</h1> - </ActivityInfo> - </ActivityTopWrapper> - <ChaptersWrapper> - {course.chapters.map((chapter: any) => { - return ( - <> - <div style={{ display: "flex", flexDirection: "row" }} key={chapter.chapter_id}> - {chapter.activities.map((activity: any) => { - return ( - <ToolTip sideOffset={-5} slateBlack content={activity.name} key={activity.id}> - <Link href={getUriWithOrg(orgslug, "") + `/course/${courseid}/activity/${activity.id.replace("activity_", "")}`}> - <ChapterIndicator - done={course.trail.activities_marked_complete && course.trail.activities_marked_complete.includes(activity.id) && course.trail.status == "ongoing"} - active={"activity_" + activityid === activity.id ? true : false} key={activity.id} - /> - </Link> - </ToolTip> - ); - })} - </div> -      - </> - ); - })} - </ChaptersWrapper> + </div> + <div className="flex flex-col -space-y-1"> + <p className="font-bold text-gray-700 text-md">Course </p> + <h1 className="font-bold text-gray-950 text-2xl first-letter:uppercase" >{course.course.name}</h1> + </div> + </div> + <ActivityIndicators current_activity={activityid} orgslug={orgslug} course={course} /> + + <div className="flex justify-between items-center"> + <div className="flex flex-col -space-y-1"> + <p className="font-bold text-gray-700 text-md">Chapter : {getChapterName(activity.chapter_id)}</p> + <h1 className="font-bold text-gray-950 text-2xl first-letter:uppercase" >{activity.name}</h1> + </div> + <div className="flex space-x-2"> + <MarkStatus activityid={activityid} course={course} orgslug={orgslug} courseid={courseid} /> + + </div> + </div> {activity ? ( - <CourseContent> - {activity.type == "dynamic" && <Canva content={activity.content} activity={activity} />} - {/* todo : use apis & streams instead of this */} - {activity.type == "video" && <VideoActivity course={course} activity={activity} />} + <div className={`p-7 pt-2 drop-shadow-sm rounded-lg ${activity.type == 'dynamic' ? 'bg-white' : 'bg-zinc-950'}`}> + <div> + {activity.type == "dynamic" && <Canva content={activity.content} activity={activity} />} + {/* todo : use apis & streams instead of this */} + {activity.type == "video" && <VideoActivity course={course} activity={activity} />} - {activity.type == "documentpdf" && <DocumentPdfActivity course={course} activity={activity} />} + {activity.type == "documentpdf" && <DocumentPdfActivity course={course} activity={activity} />} - <ActivityMarkerWrapper className="py-10"> + <div className="py-10"> - {course.trail.activities_marked_complete && - course.trail.activities_marked_complete.includes("activity_" + activityid) && - course.trail.status == "ongoing" ? ( - <button style={{ backgroundColor: "green" }}> - <i> - <Check size={20}></Check> - </i>{" "} - Already completed - </button> - ) : ( - <button onClick={markActivityAsCompleteFront}> - {" "} - <i> - <Check size={20}></Check> - </i>{" "} - Mark as complete - </button> - )} - </ActivityMarkerWrapper> - </CourseContent> + + </div> + </div> + </div> ) : (<div></div>)} {<div style={{ height: "100px" }}></div>} - </ActivityLayout> + </div> + </GeneralWrapperStyled> </> ); } -const ActivityLayout = styled.div``; -const ActivityThumbnail = styled.div` - padding-right: 30px; - justify-self: center; - img { - box-shadow: 0px 13px 33px -13px rgba(0, 0, 0, 0.42); - border-radius: 7px; - width: 100px; - height: 57px; - } -`; -const ActivityInfo = styled.div` - h1 { - margin-top: 0px; + +export function MarkStatus(props: { activityid: string, course: any, orgslug: string, courseid: string }) { + const router = useRouter(); + + + async function markActivityAsCompleteFront() { + const trail = await markActivityAsComplete(props.orgslug, props.courseid, props.activityid); + router.refresh(); } - p { - margin-top: 0; - margin-bottom: 0; - font-weight: 700; - } -`; + return ( + <>{props.course.trail.activities_marked_complete && + props.course.trail.activities_marked_complete.includes("activity_" + props.activityid) && + props.course.trail.status == "ongoing" ? ( + <div className="bg-teal-600 rounded-md drop-shadow-md flex flex-col p-3 text-sm text-white hover:cursor-pointer transition delay-150 duration-300 ease-in-out" > + <i> + <Check size={15}></Check> + </i>{" "} + Already completed + </div> + ) : ( + <div className="bg-zinc-600 rounded-md drop-shadow-md flex flex-col p-3 text-sm text-white hover:cursor-pointer transition delay-150 duration-300 ease-in-out" onClick={markActivityAsCompleteFront}> + {" "} + <i> + <Check size={15}></Check> + </i>{" "} + Mark as complete + </div> + )}</> + ) +} -const ChaptersWrapper = styled.div` - display: flex; - // row - flex-direction: row; - width: 100%; - width: 1300px; - margin: 0 auto; -`; -const ChapterIndicator = styled.div < { active?: boolean, done?: boolean } > ` - border-radius: 20px; - height: 5px; - background: #151515; - border-radius: 3px; - - width: 35px; - background-color: ${props => props.done ? "green" : (props.active ? "#9d9d9d" : "black")}; - margin: 10px; - margin-bottom: 0px; - margin-left: 0px; - - &:hover { - cursor: pointer; - background-color: #9d9d9d; - } -`; - -const ActivityTopWrapper = styled.div` - width: 1300px; - padding-top: 50px; - margin: 0 auto; - display: flex; -`; - -const CourseContent = styled.div` - display: flex; - flex-direction: column; - background-color: white; - min-height: 600px; -`; - -const ActivityMarkerWrapper = styled.div` - display: block; - width: 1300px; - justify-content: flex-end; - margin: 0 auto; - align-items: center; - - button { - background-color: #151515; - border: none; - padding: 18px; - border-radius: 15px; - margin: 15px; - margin-left: 20px; - margin-top: 20px; - cursor: pointer; - transition: all 0.2s ease; - display: flex; - align-items: center; - justify-content: center; - margin: auto; - color: white; - font-weight: 700; - font-family: "DM Sans"; - font-size: 16px; - letter-spacing: -0.05em; - box-shadow: 0px 13px 33px -13px rgba(0, 0, 0, 0.42); - - i { - margin-right: 5px; - - // center the icon - display: flex; - align-items: center; - justify-content: center; - } - - &:hover { - background-color: #000000; - } - } -`; export default ActivityClient; diff --git a/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/activity/[activityid]/error.tsx b/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/activity/[activityid]/error.tsx index 9e4c3efb..8bac23db 100644 --- a/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/activity/[activityid]/error.tsx +++ b/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/activity/[activityid]/error.tsx @@ -1,6 +1,6 @@ 'use client'; // Error components must be Client Components -import ErrorUI from '@components/UI/Error/Error'; +import ErrorUI from '@components/StyledElements/Error/Error'; import { useEffect } from 'react'; export default function Error({ diff --git a/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/activity/[activityid]/loading.tsx b/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/activity/[activityid]/loading.tsx index b3fd3bc3..3f902486 100644 --- a/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/activity/[activityid]/loading.tsx +++ b/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/activity/[activityid]/loading.tsx @@ -1,4 +1,4 @@ -import PageLoading from "@components/Pages/PageLoading"; +import PageLoading from "@components/Objects/Loaders/PageLoading"; export default function Loading() { // Or a custom loading skeleton component diff --git a/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/course.tsx b/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/course.tsx index d88b6ce8..fc323f5c 100644 --- a/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/course.tsx +++ b/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/course.tsx @@ -2,68 +2,75 @@ 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 React, { use } 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 ToolTip from "@components/StyledElements/Tooltip/Tooltip"; +import PageLoading from "@components/Objects/Loaders/PageLoading"; import { revalidateTags } from "@services/utils/ts/requests"; +import ActivityIndicators from "@components/Pages/Courses/ActivityIndicators"; +import { useRouter } from "next/navigation"; +import GeneralWrapperStyled from "@components/StyledElements/Wrappers/GeneralWrapper"; const CourseClient = (props: any) => { const courseid = props.courseid; const orgslug = props.orgslug; const course = props.course; + const router = useRouter(); async function startCourseUI() { // Create activity await startCourse("course_" + courseid, orgslug); revalidateTags(['courses']); + router.refresh(); } async function quitCourse() { - // Close activity let activity = await removeCourse("course_" + courseid, orgslug); // Mutate course revalidateTags(['courses']); + router.refresh(); } console.log(course); + return ( <> {!course ? ( <PageLoading></PageLoading> ) : ( - <CoursePageLayout className="pt-6"> - <p className="text-lg font-bold">Course</p> - <h1 className="text-3xl font-bold flex items-center space-x-5"> - {course.course.name}{" "} - <Link href={getUriWithOrg(orgslug, "") + `/course/${courseid}/edit`} rel="noopener noreferrer"> - <Pencil2Icon /> - </Link>{" "} - </h1> + <GeneralWrapperStyled> + <div className="pb-3"> + <p className="text-md font-bold text-gray-400 pb-2">Course</p> + <h1 className="text-3xl -mt-3 font-bold"> + {course.course.name} + </h1> + </div> - <CourseThumbnailWrapper> - <img src={`${getBackendUrl()}content/uploads/img/${course.course.thumbnail}`} alt="" /> - </CourseThumbnailWrapper> - <CourseMetaWrapper> - <CourseMetaLeft> - <h2 className="py-3 font-bold">Description</h2> + <div className="inset-0 ring-1 ring-inset ring-black/10 rounded-lg shadow-xl relative w-auto h-[300px] bg-cover bg-center mb-4" style={{ backgroundImage: `url(${getBackendUrl()}content/uploads/img/${course.course.thumbnail})` }}> - <BoxWrapper> + </div> + + <ActivityIndicators orgslug={orgslug} course={course} /> + + <div className="flex flex-row pt-10 flex-wrap"> + <div className="course_metadata_left grow space-y-2"> + <h2 className="py-3 text-2xl font-bold">Description</h2> + <StyledBox> <p className="py-3">{course.course.description}</p> - </BoxWrapper> + </StyledBox> + + <h2 className="py-3 text-2xl font-bold">What you will learn</h2> + <StyledBox> - <h2 className="py-3 font-bold">What you will learn</h2> - <BoxWrapper> <p className="py-3">{course.learnings == ![] ? "no data" : course.learnings}</p> - </BoxWrapper> + </StyledBox> - <h2 className="py-3 font-bold">Course Lessons</h2> - - <BoxWrapper> + <h2 className="py-3 text-2xl font-bold">Course Lessons</h2> + <StyledBox> {course.chapters.map((chapter: any) => { return ( <div @@ -88,142 +95,32 @@ const CourseClient = (props: any) => { </div> ); })} - </BoxWrapper> - </CourseMetaLeft> - <CourseMetaRight> + </StyledBox> + + </div> + <div className="course_metadata_right w-64 flex items-center ml-10 h-28 p-3 bg-white rounded-md justify-center drop-shadow-[0_33px_13px_rgba(0,0,0,0.042)] transition-all"> {course.trail.status == "ongoing" ? ( - <button style={{ backgroundColor: "red" }} onClick={quitCourse}> + <button className="py-2 px-5 rounded-xl text-white font-bold h-12 w-[200px] drop-shadow-md bg-red-600 hover:bg-red-700 hover:cursor-pointer" onClick={quitCourse}> Quit Course </button> ) : ( - <button onClick={startCourseUI}>Start Course</button> + <button className="py-2 px-5 rounded-xl text-white font-bold h-12 w-[200px] drop-shadow-md bg-black hover:bg-gray-900 hover:cursor-pointer" onClick={startCourseUI}>Start Course</button> )} - </CourseMetaRight> - </CourseMetaWrapper> - </CoursePageLayout> + </div> + </div> + </GeneralWrapperStyled> )} </> ); }; -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 StyledBox = (props: any) => ( + <div className="p-3 pl-10 bg-white rounded-md w-[100%] h-auto drop-shadow-[0_33px_13px_rgba(0,0,0,0.042)]"> + {props.children} + </div> -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]/edit/page.tsx b/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/edit/page.tsx index 0dda558b..5bbecf64 100644 --- a/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/edit/page.tsx +++ b/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/edit/page.tsx @@ -3,18 +3,19 @@ import React from "react"; import { useState, useEffect } from "react"; import styled from "styled-components"; -import { Title } from "@components/UI/Elements/Styles/Title"; import { DragDropContext, Droppable } from "react-beautiful-dnd"; import { initialData, initialData2 } from "@components/Pages/CourseEdit/Draggables/data"; import Chapter from "@components/Pages/CourseEdit/Draggables/Chapter"; import { createChapter, deleteChapter, getCourseChaptersMetadata, updateChaptersMetadata } from "@services/courses/chapters"; import { useRouter } from "next/navigation"; -import NewChapterModal from "@components/Modals/Chapters/NewChapter"; -import NewActivityModal from "@components/Modals/Activities/Create/NewActivity"; +import NewChapterModal from "@components/Objects/Modals/Chapters/NewChapter"; +import NewActivityModal from "@components/Objects/Modals/Activities/Create/NewActivity"; import { createActivity, createFileActivity, createExternalVideoActivity } from "@services/courses/activities"; import { getOrganizationContextInfo } from "@services/organizations/orgs"; -import Modal from "@components/UI/Modal/Modal"; +import Modal from "@components/StyledElements/Modal/Modal"; import { denyAccessToUser } from "@services/utils/react/middlewares/views"; +import { Folders, Package2, SaveIcon } from "lucide-react"; +import GeneralWrapperStyled from "@components/StyledElements/Wrappers/GeneralWrapper"; function CourseEdit(params: any) { @@ -240,120 +241,94 @@ function CourseEdit(params: any) { return ( <> - <Page> - <Title> - Edit Course {" "} + <div + className="bg-gradient-radial bg-fixed bg-repeat bg-[0 0],[25px 25px] bg-[50px 50px] bg-[#4744446b 1px]" + > + <GeneralWrapperStyled> + <div className="font-bold text-lg flex space-x-2 items-center"> + <p> Edit Course {" "}</p> + + + <div + className="bg-black hover:bg-gray-950 text-white font-bold p-1 px-2 text-sm rounded flex items-center cursor-pointer space-x-2" + onClick={() => { + updateChapters(); + }} + > + <SaveIcon className="w-4 h-4" /> + <p>Save</p> + + </div> + </div> + <Modal - isDialogOpen={newChapterModal} - onOpenChange={setNewChapterModal} - minHeight="sm" - dialogContent={<NewChapterModal - closeModal={closeNewChapterModal} - submitChapter={submitChapter} - ></NewChapterModal>} - dialogTitle="Create chapter" - dialogDescription="Add a new chapter to the course" - dialogTrigger={ - <button> Add chapter + - </button> - } + isDialogOpen={newActivityModal} + onOpenChange={setNewActivityModal} + minHeight="no-min" + addDefCloseButton={false} + dialogContent={<NewActivityModal + closeModal={closeNewActivityModal} + submitFileActivity={submitFileActivity} + submitExternalVideo={submitExternalVideo} + submitActivity={submitActivity} + chapterId={newActivityModalData} + ></NewActivityModal>} + dialogTitle="Create Activity" + dialogDescription="Choose between types of activities to add to the course" + /> - <button - onClick={() => { - updateChapters(); - }} - > - Save - </button> - - - } - dialogTitle="Create Activity" - dialogDescription="Choose between types of activities to add to the course" - - /> - -
- {winReady && ( - - - - {(provided) => ( - <> -
- {getChapters().map((info: any, index: any) => ( - <> - - - ))} - {provided.placeholder} -
- - )} -
-
-
- )} - +
+ {winReady && ( +
+ + + {(provided) => ( + <> +
+ {getChapters().map((info: any, index: any) => ( + <> + + + ))} + {provided.placeholder} +
+ + )} +
+
+ } + dialogTitle="Create chapter" + dialogDescription="Add a new chapter to the course" + dialogTrigger={ +
+ +
Add chapter +
+
+ } + /> +
+ )} + +
); } -const Page = styled.div` - height: 100%; - width: 100%; - min-height: 100vh; - min-width: 100vw; - padding-top: 30px; - // dots background - background-image: radial-gradient(#4744446b 1px, transparent 1px), radial-gradient(#4744446b 1px, transparent 1px); - background-position: 0 0, 25px 25px; - background-size: 50px 50px; - background-attachment: fixed; - background-repeat: repeat; - - button { - margin-left: 10px; - background-color: #000000; - border: none; - border-radius: 5px; - padding: 5px 10px; - color: white; - font-size: 13px; - cursor: pointer; - transition: 0.2s; - font-family: "DM Sans", sans-serif; - &:hover { - background-color: #474444; - - transition: 0.2s; - } - } -`; -const ChapterlistWrapper = styled.div` - display: flex; - padding-left: 30px; - justify-content: center; -`; export default CourseEdit; diff --git a/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/error.tsx b/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/error.tsx index 9e4c3efb..8bac23db 100644 --- a/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/error.tsx +++ b/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/error.tsx @@ -1,6 +1,6 @@ 'use client'; // Error components must be Client Components -import ErrorUI from '@components/UI/Error/Error'; +import ErrorUI from '@components/StyledElements/Error/Error'; import { useEffect } from 'react'; export default function Error({ diff --git a/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/loading.tsx b/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/loading.tsx index b3fd3bc3..3f902486 100644 --- a/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/loading.tsx +++ b/front/app/orgs/[orgslug]/(withmenu)/course/[courseid]/loading.tsx @@ -1,4 +1,4 @@ -import PageLoading from "@components/Pages/PageLoading"; +import PageLoading from "@components/Objects/Loaders/PageLoading"; export default function Loading() { // Or a custom loading skeleton component diff --git a/front/app/orgs/[orgslug]/(withmenu)/courses/courses.tsx b/front/app/orgs/[orgslug]/(withmenu)/courses/courses.tsx index 19f9e17e..1257e34b 100644 --- a/front/app/orgs/[orgslug]/(withmenu)/courses/courses.tsx +++ b/front/app/orgs/[orgslug]/(withmenu)/courses/courses.tsx @@ -1,8 +1,8 @@ 'use client'; -import CreateCourseModal from '@components/Modals/Course/Create/CreateCourse'; -import Modal from '@components/UI/Modal/Modal'; +import CreateCourseModal from '@components/Objects/Modals/Course/Create/CreateCourse'; +import Modal from '@components/StyledElements/Modal/Modal'; import { Edit2, Trash } from "lucide-react"; -import { getAPIUrl, getBackendUrl, getUriWithOrg } from '@services/config/config'; +import { getBackendUrl, getUriWithOrg } from '@services/config/config'; import CoursesLogo from "public/svg/courses.svg"; import CollectionsLogo from "public/svg/collections.svg"; import { deleteCourseFromBackend } from '@services/courses/courses'; @@ -11,6 +11,10 @@ import React from 'react' import Image from 'next/image'; import { AuthContext } from '@components/Security/AuthProvider'; import { revalidateTags } from '@services/utils/ts/requests'; +import { useRouter } from 'next/navigation'; +import GeneralWrapperStyled from '@components/StyledElements/Wrappers/GeneralWrapper'; +import TypeOfContentTitle from '@components/StyledElements/Titles/TypeOfContentTitle'; +import AuthenticatedClientElement from '@components/Security/AuthenticatedClientElement'; interface CourseProps { orgslug: string; @@ -26,48 +30,48 @@ function Courses(props: CourseProps) { const orgslug = props.orgslug; const courses = props.courses; const [newCourseModal, setNewCourseModal] = React.useState(false); + const router = useRouter(); async function deleteCourses(course_id: any) { await deleteCourseFromBackend(course_id); revalidateTags(['courses']); - // terrible, nextjs right now doesn't mutate the page when the data changes - window.location.reload(); + + router.refresh(); } async function closeNewCourseModal() { setNewCourseModal(false); } - - - return (
-
+
- - <Modal - isDialogOpen={newCourseModal} - onOpenChange={setNewCourseModal} - minHeight="md" - dialogContent={<CreateCourseModal - closeModal={closeNewCourseModal} - orgslug={orgslug} - ></CreateCourseModal>} - dialogTitle="Create Course" - dialogDescription="Create a new course" - dialogTrigger={ - <button className="rounded-md bg-black antialiased ring-offset-purple-800 p-2 px-5 my-auto font text-sm font-bold text-white drop-shadow-lg">Add Course + </button> - } - /> + <TypeOfContentTitle title="Courses" type="cou" /> + <AuthenticatedClientElement checkMethod='authentication'> + <Modal + isDialogOpen={newCourseModal} + onOpenChange={setNewCourseModal} + minHeight="md" + dialogContent={<CreateCourseModal + closeModal={closeNewCourseModal} + orgslug={orgslug} + ></CreateCourseModal>} + dialogTitle="Create Course" + dialogDescription="Create a new course" + dialogTrigger={ + <button className="rounded-md bg-black antialiased ring-offset-purple-800 p-2 px-5 my-auto font text-sm font-bold text-white drop-shadow-lg">Add Course + </button> + } + /> + </AuthenticatedClientElement> </div> - <div className="flex space-x-5"> + <div className="flex flex-wrap"> {courses.map((course: any) => ( - <div key={course.course_id}> - <AdminEditsArea course={course} orgslug={orgslug} course_id={course.course_id} deleteCourses={deleteCourses} /> + <div className="px-3" key={course.course_id}> + <AdminEditsArea course={course} orgSlug={orgslug} courseId={course.course_id} deleteCourses={deleteCourses} /> <Link href={getUriWithOrg(orgslug, "/course/" + removeCoursePrefix(course.course_id))}> <div className="inset-0 ring-1 ring-inset ring-black/10 rounded-lg shadow-xl relative w-[249px] h-[131px] bg-cover" style={{ backgroundImage: `url(${getBackendUrl()}content/uploads/img/${course.thumbnail})` }}> @@ -78,83 +82,28 @@ function Courses(props: CourseProps) { ))} </div> - </div> + </GeneralWrapperStyled> </div> ) } -export const Title = (props: any) => { +const AdminEditsArea = (props: { orgSlug: string, courseId: string, course: any, deleteCourses: any }) => { return ( - <div className="home_category_title flex my-5"> - <div className="rounded-full ring-1 ring-slate-900/5 shadow-sm p-2 my-auto mr-4"> - <Image className="" src={props.type == "col" ? CollectionsLogo : CoursesLogo} alt="Courses logo" /> - </div> - <h1 className="font-bold text-lg">{props.title}</h1> + <AuthenticatedClientElement checkMethod='roles' orgId={props.course.org_id}><div className="flex space-x-2 py-2"> + <button className="rounded-md text-sm px-3 font-bold text-red-800 bg-red-200 w-16 flex justify-center items-center" onClick={() => props.deleteCourses(props.courseId)}> + Delete <Trash size={10}></Trash> + </button> + <Link href={getUriWithOrg(props.orgSlug, "/course/" + removeCoursePrefix(props.courseId) + "/edit")}> + <button className="rounded-md text-sm px-3 font-bold text-orange-800 bg-orange-200 w-16 flex justify-center items-center"> + Edit <Edit2 size={10}></Edit2> + </button> + </Link> </div> + </AuthenticatedClientElement> ) } -const AdminEditsArea = (props: any) => { - const org_roles_values = ["admin", "owner"]; - const user_roles_values = ["role_admin"]; - - const auth: any = React.useContext(AuthContext); - console.log("auth: ", auth); - - - // this is amazingly terrible code, but gotta release that MVP - // TODO: fix this - - function isAuthorized() { - const org_id = props.course.org_id; - const org_roles = auth.userInfo.user_object.orgs; - const user_roles = auth.userInfo.user_object.roles; - const org_role = org_roles.find((org: any) => org.org_id == org_id); - const user_role = user_roles.find((role: any) => role.org_id == org_id); - - if (org_role && user_role) { - if (org_roles_values.includes(org_role.org_role) && user_roles_values.includes(user_role.role_id)) { - return true; - } - else { - return false; - } - } else { - return false; - } - } - - // this is amazingly terrible code, but gotta release that MVP - // TODO: fix this - - if (auth.isAuthenticated) { - if (isAuthorized()) { - return ( - <div className="flex space-x-2 py-2"> - <button className="rounded-md text-sm px-3 font-bold text-red-800 bg-red-200 w-16 flex justify-center items-center" onClick={() => props.deleteCourses(props.course_id)}> - Delete <Trash size={10}></Trash> - </button> - <Link href={getUriWithOrg(props.orgslug, "/course/" + removeCoursePrefix(props.course_id) + "/edit")}> - <button className="rounded-md text-sm px-3 font-bold text-orange-800 bg-orange-200 w-16 flex justify-center items-center"> - Edit <Edit2 size={10}></Edit2> - </button> - </Link> - </div> - ) - } else { - return ( - <div></div> - ) - } - } - else { - return ( - <div></div> - ) - } -} - export default Courses \ No newline at end of file diff --git a/front/app/orgs/[orgslug]/(withmenu)/courses/error.tsx b/front/app/orgs/[orgslug]/(withmenu)/courses/error.tsx index 9e4c3efb..8bac23db 100644 --- a/front/app/orgs/[orgslug]/(withmenu)/courses/error.tsx +++ b/front/app/orgs/[orgslug]/(withmenu)/courses/error.tsx @@ -1,6 +1,6 @@ 'use client'; // Error components must be Client Components -import ErrorUI from '@components/UI/Error/Error'; +import ErrorUI from '@components/StyledElements/Error/Error'; import { useEffect } from 'react'; export default function Error({ diff --git a/front/app/orgs/[orgslug]/(withmenu)/courses/loading.tsx b/front/app/orgs/[orgslug]/(withmenu)/courses/loading.tsx index b3fd3bc3..3f902486 100644 --- a/front/app/orgs/[orgslug]/(withmenu)/courses/loading.tsx +++ b/front/app/orgs/[orgslug]/(withmenu)/courses/loading.tsx @@ -1,4 +1,4 @@ -import PageLoading from "@components/Pages/PageLoading"; +import PageLoading from "@components/Objects/Loaders/PageLoading"; export default function Loading() { // Or a custom loading skeleton component diff --git a/front/app/orgs/[orgslug]/(withmenu)/error.tsx b/front/app/orgs/[orgslug]/(withmenu)/error.tsx index 9e4c3efb..8bac23db 100644 --- a/front/app/orgs/[orgslug]/(withmenu)/error.tsx +++ b/front/app/orgs/[orgslug]/(withmenu)/error.tsx @@ -1,6 +1,6 @@ 'use client'; // Error components must be Client Components -import ErrorUI from '@components/UI/Error/Error'; +import ErrorUI from '@components/StyledElements/Error/Error'; import { useEffect } from 'react'; export default function Error({ diff --git a/front/app/orgs/[orgslug]/(withmenu)/layout.tsx b/front/app/orgs/[orgslug]/(withmenu)/layout.tsx index 05df761a..f26f3813 100644 --- a/front/app/orgs/[orgslug]/(withmenu)/layout.tsx +++ b/front/app/orgs/[orgslug]/(withmenu)/layout.tsx @@ -1,5 +1,5 @@ import "@styles/globals.css"; -import { Menu } from "@components/UI/Elements/Menu/Menu"; +import { Menu } from "@components/Objects/Menu/Menu"; import AuthProvider from "@components/Security/AuthProvider"; export default async function RootLayout({ children, params }: { children: React.ReactNode , params:any}) { diff --git a/front/app/orgs/[orgslug]/(withmenu)/loading.tsx b/front/app/orgs/[orgslug]/(withmenu)/loading.tsx index 9a7cafe9..ec352ab7 100644 --- a/front/app/orgs/[orgslug]/(withmenu)/loading.tsx +++ b/front/app/orgs/[orgslug]/(withmenu)/loading.tsx @@ -1,4 +1,4 @@ -import PageLoading from "@components/Pages/PageLoading"; +import PageLoading from "@components/Objects/Loaders/PageLoading"; export default function Loading() { return ( diff --git a/front/app/orgs/[orgslug]/(withmenu)/page.tsx b/front/app/orgs/[orgslug]/(withmenu)/page.tsx index b51d1a7d..046bda78 100644 --- a/front/app/orgs/[orgslug]/(withmenu)/page.tsx +++ b/front/app/orgs/[orgslug]/(withmenu)/page.tsx @@ -2,14 +2,15 @@ export const dynamic = 'force-dynamic'; import { Metadata, ResolvingMetadata } from 'next'; import { getBackendUrl, getUriWithOrg } from "@services/config/config"; import { getCourse, getOrgCourses, getOrgCoursesWithAuthHeader } from "@services/courses/courses"; -import CoursesLogo from "public/svg/courses.svg"; -import CollectionsLogo from "public/svg/collections.svg"; + import Link from "next/link"; import Image from "next/image"; import { getOrgCollections, getOrgCollectionsWithAuthHeader } from "@services/courses/collections"; import { getOrganizationContextInfo } from '@services/organizations/orgs'; import { cookies } from 'next/headers'; +import GeneralWrapperStyled from '@components/StyledElements/Wrappers/GeneralWrapper'; +import TypeOfContentTitle from '@components/StyledElements/Titles/TypeOfContentTitle'; type MetadataProps = { params: { orgslug: string }; @@ -50,12 +51,12 @@ const OrgHomePage = async (params: any) => { return ( <div> - <div className="max-w-7xl mx-auto px-4 py-10"> + <GeneralWrapperStyled> {/* Collections */} - <Title title="Collections" type="col" /> + <TypeOfContentTitle title="Collections" type="col" /> <div className="home_collections flex flex-wrap"> {collections.map((collection: any) => ( - <div className="pr-8 flex flex-col" key={collection.collection_id}> + <div className="flex flex-col py-3 px-3" key={collection.collection_id}> <Link href={getUriWithOrg(orgslug, "/collection/" + removeCollectionPrefix(collection.collection_id))}> <div className="inset-0 ring-1 ring-inset ring-black/10 rounded-lg shadow-xl relative w-[249px] h-[180px] bg-cover flex flex-col items-center justify-center bg-indigo-600 font-bold text-zinc-50" > <h1 className="font-bold text-lg py-2 justify-center mb-2">{collection.name}</h1> @@ -73,35 +74,24 @@ const OrgHomePage = async (params: any) => { </div> {/* Courses */} - <Title title="Courses" type="cou" /> + <div className='h-5'></div> + <TypeOfContentTitle title="Courses" type="cou" /> <div className="home_courses flex flex-wrap"> {courses.map((course: any) => ( - <div className="pr-8" key={course.course_id}> + <div className="py-3 px-3" key={course.course_id}> <Link href={getUriWithOrg(orgslug, "/course/" + removeCoursePrefix(course.course_id))}> - <div className="inset-0 ring-1 ring-inset ring-black/10 rounded-lg shadow-xl relative w-[249px] h-[131px] bg-cover" style={{ backgroundImage: `url(${getBackendUrl()}content/uploads/img/${course.thumbnail})` }}> + <div className="inset-0 ring-1 ring-inset ring-black/10 rounded-lg shadow-xl relative w-[249px] h-[131px] bg-cover transition-all hover:scale-102" style={{ backgroundImage: `url(${getBackendUrl()}content/uploads/img/${course.thumbnail})` }}> </div> </Link> <h2 className="font-bold text-lg w-[250px] py-2">{course.name}</h2> </div> ))} </div> - </div> + </GeneralWrapperStyled> </div> ); }; -const Title = (props: any) => { - return ( - <div className="home_category_title flex my-5"> - <div className="rounded-full ring-1 ring-slate-900/5 shadow-sm p-2 my-auto mr-4"> - <Image className="" src={props.type == "col" ? CollectionsLogo : CoursesLogo} alt="Courses logo" /> - </div> - <h1 className="font-bold text-lg">{props.title}</h1> - </div> - ) -} - - export default OrgHomePage; diff --git a/front/app/orgs/[orgslug]/(withmenu)/trail/page.tsx b/front/app/orgs/[orgslug]/(withmenu)/trail/page.tsx index b44645af..b32c1463 100644 --- a/front/app/orgs/[orgslug]/(withmenu)/trail/page.tsx +++ b/front/app/orgs/[orgslug]/(withmenu)/trail/page.tsx @@ -1,5 +1,7 @@ "use client"; -import PageLoading from "@components/Pages/PageLoading"; +import PageLoading from "@components/Objects/Loaders/PageLoading"; +import TypeOfContentTitle from "@components/StyledElements/Titles/TypeOfContentTitle"; +import GeneralWrapperStyled from "@components/StyledElements/Wrappers/GeneralWrapper"; import { getAPIUrl, getBackendUrl } from "@services/config/config"; import { swrFetcher } from "@services/utils/ts/requests"; import React from "react"; @@ -12,10 +14,8 @@ function Trail(params: any) { return ( - <TrailLayout> - <h1>Trail</h1> - <br /> - {error && <p>Failed to load</p>} + <GeneralWrapperStyled> + <TypeOfContentTitle title="Trail" type="tra" /> {!trail ? ( <PageLoading></PageLoading> ) : ( @@ -36,19 +36,13 @@ function Trail(params: any) { ))} </div> )} - </TrailLayout> + </GeneralWrapperStyled> ); } export default Trail; -const TrailLayout = styled.div` - display: flex; - margin: 0 auto; - width: 1300px; - height: 100%; - flex-direction: column; -`; + const TrailMetadata = styled.div` display: flex; diff --git a/front/app/orgs/[orgslug]/login/page.tsx b/front/app/orgs/[orgslug]/login/page.tsx index f64a72a2..aaad485c 100644 --- a/front/app/orgs/[orgslug]/login/page.tsx +++ b/front/app/orgs/[orgslug]/login/page.tsx @@ -2,12 +2,11 @@ import { useRouter } from 'next/navigation'; import React, { useState } from "react"; import { styled } from '@stitches/react'; -import { Title } from "../../../../components/UI/Elements/Styles/Title"; import { loginAndGetToken } from "../../../../services/auth/auth"; -import FormLayout, { ButtonBlack, Flex, FormField, FormLabel, FormMessage, Input } from '@components/UI/Form/Form'; +import FormLayout, { ButtonBlack, Flex, FormField, FormLabel, FormMessage, Input } from '@components/StyledElements/Form/Form'; import * as Form from '@radix-ui/react-form'; import { BarLoader } from 'react-spinners'; -import Toast from '@components/UI/Toast/Toast'; +import Toast from '@components/StyledElements/Toast/Toast'; import { toast } from 'react-hot-toast'; const Login = () => { diff --git a/front/app/orgs/[orgslug]/settings/organization/general/organization.tsx b/front/app/orgs/[orgslug]/settings/organization/general/organization.tsx index bc26be95..7b1038f9 100644 --- a/front/app/orgs/[orgslug]/settings/organization/general/organization.tsx +++ b/front/app/orgs/[orgslug]/settings/organization/general/organization.tsx @@ -4,6 +4,7 @@ import { Field, Form, Formik } from 'formik'; import { updateOrganization, uploadOrganizationLogo } from '@services/settings/org'; import { UploadCloud } from 'lucide-react'; import { revalidateTags } from '@services/utils/ts/requests'; +import { useRouter } from 'next/navigation'; interface OrganizationValues { @@ -17,7 +18,7 @@ interface OrganizationValues { function OrganizationClient(props: any) { const [selectedFile, setSelectedFile] = useState<File | null>(null); - + const router = useRouter(); // ... const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => { @@ -33,9 +34,8 @@ function OrganizationClient(props: any) { await uploadOrganizationLogo(org_id, selectedFile); setSelectedFile(null); // Reset the selected file revalidateTags(['organizations']); - // reload the page - // terrible hack, it will fixed later - window.location.reload(); + router.refresh(); + } }; diff --git a/front/app/orgs/[orgslug]/signup/page.tsx b/front/app/orgs/[orgslug]/signup/page.tsx index 3f0fc0db..29e13ff8 100644 --- a/front/app/orgs/[orgslug]/signup/page.tsx +++ b/front/app/orgs/[orgslug]/signup/page.tsx @@ -1,6 +1,5 @@ "use client"; import React from "react"; -import { Title } from "../../../../components/UI/Elements/Styles/Title"; import { signup } from "../../../../services/auth/auth"; import { useRouter } from "next/navigation"; @@ -39,9 +38,8 @@ const SignUp = (params: any) => { return ( <div> <div title="Sign up"> - <Title>Sign up +
Sign up
- {/* Create a login ui with tailwindcss */}
diff --git a/front/components/Editor/Editor.tsx b/front/components/Objects/Editor/Editor.tsx similarity index 98% rename from front/components/Editor/Editor.tsx rename to front/components/Objects/Editor/Editor.tsx index 19cfee84..a9b77fb8 100644 --- a/front/components/Editor/Editor.tsx +++ b/front/components/Objects/Editor/Editor.tsx @@ -4,7 +4,7 @@ import { useEditor, EditorContent } from "@tiptap/react"; import StarterKit from "@tiptap/starter-kit"; import Collaboration from "@tiptap/extension-collaboration"; import CollaborationCursor from "@tiptap/extension-collaboration-cursor"; -import { AuthContext } from "../Security/AuthProvider"; +import { AuthContext } from "../../Security/AuthProvider"; import learnhouseIcon from "public/learnhouse_icon.png"; import { ToolbarButtons } from "./Toolbar/ToolbarButtons"; import { motion, AnimatePresence } from "framer-motion"; @@ -23,7 +23,7 @@ import { Eye, Save } from "lucide-react"; import MathEquationBlock from "./Extensions/MathEquation/MathEquationBlock"; import PDFBlock from "./Extensions/PDF/PDFBlock"; import QuizBlock from "./Extensions/Quiz/QuizBlock"; -import ToolTip from "@components/UI/Tooltip/Tooltip"; +import ToolTip from "@components/StyledElements/Tooltip/Tooltip"; import Link from "next/link"; interface Editor { diff --git a/front/components/Editor/EditorWrapper.tsx b/front/components/Objects/Editor/EditorWrapper.tsx similarity index 96% rename from front/components/Editor/EditorWrapper.tsx rename to front/components/Objects/Editor/EditorWrapper.tsx index 3119a71e..ed09a6d9 100644 --- a/front/components/Editor/EditorWrapper.tsx +++ b/front/components/Objects/Editor/EditorWrapper.tsx @@ -5,7 +5,7 @@ import { WebrtcProvider } from "y-webrtc"; import Editor from "./Editor"; import { updateActivity } from "@services/courses/activities"; import { toast } from "react-hot-toast"; -import Toast from "@components/UI/Toast/Toast"; +import Toast from "@components/StyledElements/Toast/Toast"; interface EditorWrapperProps { content: string; diff --git a/front/components/Editor/Extensions/Callout/Info/InfoCallout.ts b/front/components/Objects/Editor/Extensions/Callout/Info/InfoCallout.ts similarity index 100% rename from front/components/Editor/Extensions/Callout/Info/InfoCallout.ts rename to front/components/Objects/Editor/Extensions/Callout/Info/InfoCallout.ts diff --git a/front/components/Editor/Extensions/Callout/Info/InfoCalloutComponent.tsx b/front/components/Objects/Editor/Extensions/Callout/Info/InfoCalloutComponent.tsx similarity index 75% rename from front/components/Editor/Extensions/Callout/Info/InfoCalloutComponent.tsx rename to front/components/Objects/Editor/Extensions/Callout/Info/InfoCalloutComponent.tsx index e52430e0..b04503b9 100644 --- a/front/components/Editor/Extensions/Callout/Info/InfoCalloutComponent.tsx +++ b/front/components/Objects/Editor/Extensions/Callout/Info/InfoCalloutComponent.tsx @@ -7,7 +7,7 @@ function InfoCalloutComponent(props: any) { return ( - + ); @@ -17,7 +17,7 @@ const InfoCalloutWrapper = styled.div` display: flex; flex-direction: row; color: #1f3a8a; - background-color: #dbe9fe; + background-color: #dbe9fe; border: 1px solid #c1d9fb; border-radius: 16px; margin: 1rem 0; @@ -36,14 +36,6 @@ const InfoCalloutWrapper = styled.div` } `; -const DragHandle = styled.div` - position: absolute; - top: 0; - left: 0; - width: 1rem; - height: 100%; - cursor: move; - z-index: 1; -`; + export default InfoCalloutComponent; diff --git a/front/components/Editor/Extensions/Callout/Warning/WarningCallout.ts b/front/components/Objects/Editor/Extensions/Callout/Warning/WarningCallout.ts similarity index 100% rename from front/components/Editor/Extensions/Callout/Warning/WarningCallout.ts rename to front/components/Objects/Editor/Extensions/Callout/Warning/WarningCallout.ts diff --git a/front/components/Editor/Extensions/Callout/Warning/WarningCalloutComponent.tsx b/front/components/Objects/Editor/Extensions/Callout/Warning/WarningCalloutComponent.tsx similarity index 100% rename from front/components/Editor/Extensions/Callout/Warning/WarningCalloutComponent.tsx rename to front/components/Objects/Editor/Extensions/Callout/Warning/WarningCalloutComponent.tsx diff --git a/front/components/Editor/Extensions/Image/ImageBlock.ts b/front/components/Objects/Editor/Extensions/Image/ImageBlock.ts similarity index 100% rename from front/components/Editor/Extensions/Image/ImageBlock.ts rename to front/components/Objects/Editor/Extensions/Image/ImageBlock.ts diff --git a/front/components/Editor/Extensions/Image/ImageBlockComponent.tsx b/front/components/Objects/Editor/Extensions/Image/ImageBlockComponent.tsx similarity index 95% rename from front/components/Editor/Extensions/Image/ImageBlockComponent.tsx rename to front/components/Objects/Editor/Extensions/Image/ImageBlockComponent.tsx index 0751e19c..0825fa13 100644 --- a/front/components/Editor/Extensions/Image/ImageBlockComponent.tsx +++ b/front/components/Objects/Editor/Extensions/Image/ImageBlockComponent.tsx @@ -5,8 +5,8 @@ import { Resizable } from 're-resizable'; import * as AspectRatio from '@radix-ui/react-aspect-ratio'; import { AlertCircle, AlertTriangle, Image, ImagePlus, Info } from "lucide-react"; -import { getImageFile, uploadNewImageFile } from "../../../../services/blocks/Image/images"; -import { getBackendUrl } from "../../../../services/config/config"; +import { getImageFile, uploadNewImageFile } from "../../../../../services/blocks/Image/images"; +import { getBackendUrl } from "../../../../../services/config/config"; function ImageBlockComponent(props: any) { const [image, setImage] = React.useState(null); diff --git a/front/components/Editor/Extensions/MathEquation/MathEquationBlock.ts b/front/components/Objects/Editor/Extensions/MathEquation/MathEquationBlock.ts similarity index 100% rename from front/components/Editor/Extensions/MathEquation/MathEquationBlock.ts rename to front/components/Objects/Editor/Extensions/MathEquation/MathEquationBlock.ts diff --git a/front/components/Editor/Extensions/MathEquation/MathEquationBlockComponent.tsx b/front/components/Objects/Editor/Extensions/MathEquation/MathEquationBlockComponent.tsx similarity index 100% rename from front/components/Editor/Extensions/MathEquation/MathEquationBlockComponent.tsx rename to front/components/Objects/Editor/Extensions/MathEquation/MathEquationBlockComponent.tsx diff --git a/front/components/Editor/Extensions/PDF/PDFBlock.ts b/front/components/Objects/Editor/Extensions/PDF/PDFBlock.ts similarity index 100% rename from front/components/Editor/Extensions/PDF/PDFBlock.ts rename to front/components/Objects/Editor/Extensions/PDF/PDFBlock.ts diff --git a/front/components/Editor/Extensions/PDF/PDFBlockComponent.tsx b/front/components/Objects/Editor/Extensions/PDF/PDFBlockComponent.tsx similarity index 93% rename from front/components/Editor/Extensions/PDF/PDFBlockComponent.tsx rename to front/components/Objects/Editor/Extensions/PDF/PDFBlockComponent.tsx index eaf8bc7f..52c125d0 100644 --- a/front/components/Editor/Extensions/PDF/PDFBlockComponent.tsx +++ b/front/components/Objects/Editor/Extensions/PDF/PDFBlockComponent.tsx @@ -2,8 +2,8 @@ import { NodeViewWrapper } from "@tiptap/react"; import React from "react"; import styled from "styled-components"; import { AlertCircle, AlertTriangle, FileText, Image, ImagePlus, Info } from "lucide-react"; -import { getPDFFile, uploadNewPDFFile } from "../../../../services/blocks/Pdf/pdf"; -import { getBackendUrl } from "../../../../services/config/config"; +import { getPDFFile, uploadNewPDFFile } from "../../../../../services/blocks/Pdf/pdf"; +import { getBackendUrl } from "../../../../../services/config/config"; function PDFBlockComponent(props: any) { const [pdf, setPDF] = React.useState(null); diff --git a/front/components/Editor/Extensions/Quiz/QuizBlock.ts b/front/components/Objects/Editor/Extensions/Quiz/QuizBlock.ts similarity index 100% rename from front/components/Editor/Extensions/Quiz/QuizBlock.ts rename to front/components/Objects/Editor/Extensions/Quiz/QuizBlock.ts diff --git a/front/components/Editor/Extensions/Quiz/QuizBlockComponent.tsx b/front/components/Objects/Editor/Extensions/Quiz/QuizBlockComponent.tsx similarity index 100% rename from front/components/Editor/Extensions/Quiz/QuizBlockComponent.tsx rename to front/components/Objects/Editor/Extensions/Quiz/QuizBlockComponent.tsx diff --git a/front/components/Editor/Extensions/Video/VideoBlock.ts b/front/components/Objects/Editor/Extensions/Video/VideoBlock.ts similarity index 100% rename from front/components/Editor/Extensions/Video/VideoBlock.ts rename to front/components/Objects/Editor/Extensions/Video/VideoBlock.ts diff --git a/front/components/Editor/Extensions/Video/VideoBlockComponent.tsx b/front/components/Objects/Editor/Extensions/Video/VideoBlockComponent.tsx similarity index 94% rename from front/components/Editor/Extensions/Video/VideoBlockComponent.tsx rename to front/components/Objects/Editor/Extensions/Video/VideoBlockComponent.tsx index cb324c52..2911d8ec 100644 --- a/front/components/Editor/Extensions/Video/VideoBlockComponent.tsx +++ b/front/components/Objects/Editor/Extensions/Video/VideoBlockComponent.tsx @@ -2,8 +2,8 @@ import { NodeViewWrapper } from "@tiptap/react"; import { AlertTriangle, Image, Video } from "lucide-react"; import React from "react"; import styled from "styled-components"; -import { getBackendUrl } from "../../../../services/config/config"; -import { uploadNewVideoFile } from "../../../../services/blocks/Video/video"; +import { getBackendUrl } from "../../../../../services/config/config"; +import { uploadNewVideoFile } from "../../../../../services/blocks/Video/video"; function VideoBlockComponents(props: any) { const [video, setVideo] = React.useState(null); diff --git a/front/components/Editor/Toolbar/ToolbarButtons.tsx b/front/components/Objects/Editor/Toolbar/ToolbarButtons.tsx similarity index 98% rename from front/components/Editor/Toolbar/ToolbarButtons.tsx rename to front/components/Objects/Editor/Toolbar/ToolbarButtons.tsx index 3dd9fcac..7f04b6c7 100644 --- a/front/components/Editor/Toolbar/ToolbarButtons.tsx +++ b/front/components/Objects/Editor/Toolbar/ToolbarButtons.tsx @@ -1,7 +1,7 @@ import styled from "styled-components"; import { FontBoldIcon, FontItalicIcon, StrikethroughIcon, ArrowLeftIcon, ArrowRightIcon, OpacityIcon, DividerVerticalIcon } from "@radix-ui/react-icons"; import { AlertCircle, AlertTriangle, FileText, GraduationCap, ImagePlus, Info, Sigma, Video, Youtube } from "lucide-react"; -import ToolTip from "@components/UI/Tooltip/Tooltip"; +import ToolTip from "@components/StyledElements/Tooltip/Tooltip"; export const ToolbarButtons = ({ editor, props }: any) => { if (!editor) { diff --git a/front/components/Pages/PageLoading.tsx b/front/components/Objects/Loaders/PageLoading.tsx similarity index 100% rename from front/components/Pages/PageLoading.tsx rename to front/components/Objects/Loaders/PageLoading.tsx diff --git a/front/components/UI/Elements/Menu/Menu.tsx b/front/components/Objects/Menu/Menu.tsx similarity index 97% rename from front/components/UI/Elements/Menu/Menu.tsx rename to front/components/Objects/Menu/Menu.tsx index 21ad6b8b..4baf3e1d 100644 --- a/front/components/UI/Elements/Menu/Menu.tsx +++ b/front/components/Objects/Menu/Menu.tsx @@ -1,11 +1,9 @@ import React from "react"; -import learnhouseLogo from "public/learnhouse_logo.png"; import Link from "next/link"; -import Image from "next/image"; import { getBackendUrl, getUriWithOrg } from "@services/config/config"; -import { getOrganizationContextInfo, getOrganizationContextInfoNoAsync } from "@services/organizations/orgs"; -import ClientComponentSkeleton from "@components/UI/Utils/ClientComp"; +import { getOrganizationContextInfo } from "@services/organizations/orgs"; +import ClientComponentSkeleton from "@components/Utils/ClientComp"; import { HeaderProfileBox } from "@components/Security/HeaderProfileBox"; export const Menu = async (props: any) => { diff --git a/front/components/UI/Elements/Menu/ProfileArea.tsx b/front/components/Objects/Menu/ProfileArea.tsx similarity index 100% rename from front/components/UI/Elements/Menu/ProfileArea.tsx rename to front/components/Objects/Menu/ProfileArea.tsx diff --git a/front/components/Modals/Activities/Create/NewActivity.tsx b/front/components/Objects/Modals/Activities/Create/NewActivity.tsx similarity index 100% rename from front/components/Modals/Activities/Create/NewActivity.tsx rename to front/components/Objects/Modals/Activities/Create/NewActivity.tsx diff --git a/front/components/Modals/Activities/Create/NewActivityModal/DocumentPdf.tsx b/front/components/Objects/Modals/Activities/Create/NewActivityModal/DocumentPdf.tsx similarity index 96% rename from front/components/Modals/Activities/Create/NewActivityModal/DocumentPdf.tsx rename to front/components/Objects/Modals/Activities/Create/NewActivityModal/DocumentPdf.tsx index 01310a84..c231271d 100644 --- a/front/components/Modals/Activities/Create/NewActivityModal/DocumentPdf.tsx +++ b/front/components/Objects/Modals/Activities/Create/NewActivityModal/DocumentPdf.tsx @@ -1,4 +1,4 @@ -import FormLayout, { ButtonBlack, Flex, FormField, FormLabel, FormMessage, Input, Textarea } from "@components/UI/Form/Form"; +import FormLayout, { ButtonBlack, Flex, FormField, FormLabel, FormMessage, Input, Textarea } from "@components/StyledElements/Form/Form"; import React, { useState } from "react"; import * as Form from '@radix-ui/react-form'; import BarLoader from "react-spinners/BarLoader"; diff --git a/front/components/Modals/Activities/Create/NewActivityModal/DynamicCanva.tsx b/front/components/Objects/Modals/Activities/Create/NewActivityModal/DynamicCanva.tsx similarity index 96% rename from front/components/Modals/Activities/Create/NewActivityModal/DynamicCanva.tsx rename to front/components/Objects/Modals/Activities/Create/NewActivityModal/DynamicCanva.tsx index c4e711e0..72722376 100644 --- a/front/components/Modals/Activities/Create/NewActivityModal/DynamicCanva.tsx +++ b/front/components/Objects/Modals/Activities/Create/NewActivityModal/DynamicCanva.tsx @@ -1,4 +1,4 @@ -import FormLayout, { ButtonBlack, Flex, FormField, FormLabel, FormMessage, Input, Textarea } from "@components/UI/Form/Form"; +import FormLayout, { ButtonBlack, Flex, FormField, FormLabel, FormMessage, Input, Textarea } from "@components/StyledElements/Form/Form"; import React, { useState } from "react"; import * as Form from '@radix-ui/react-form'; import BarLoader from "react-spinners/BarLoader"; diff --git a/front/components/Modals/Activities/Create/NewActivityModal/Video.tsx b/front/components/Objects/Modals/Activities/Create/NewActivityModal/Video.tsx similarity index 98% rename from front/components/Modals/Activities/Create/NewActivityModal/Video.tsx rename to front/components/Objects/Modals/Activities/Create/NewActivityModal/Video.tsx index a510ae11..ef855e4a 100644 --- a/front/components/Modals/Activities/Create/NewActivityModal/Video.tsx +++ b/front/components/Objects/Modals/Activities/Create/NewActivityModal/Video.tsx @@ -1,4 +1,4 @@ -import FormLayout, { ButtonBlack, Flex, FormField, FormLabel, FormMessage, Input, Textarea } from "@components/UI/Form/Form"; +import FormLayout, { ButtonBlack, Flex, FormField, FormLabel, FormMessage, Input, Textarea } from "@components/StyledElements/Form/Form"; import React, { useState } from "react"; import * as Form from '@radix-ui/react-form'; import BarLoader from "react-spinners/BarLoader"; diff --git a/front/components/Modals/Chapters/NewChapter.tsx b/front/components/Objects/Modals/Chapters/NewChapter.tsx similarity index 97% rename from front/components/Modals/Chapters/NewChapter.tsx rename to front/components/Objects/Modals/Chapters/NewChapter.tsx index 6f6c0cfa..3d4b563b 100644 --- a/front/components/Modals/Chapters/NewChapter.tsx +++ b/front/components/Objects/Modals/Chapters/NewChapter.tsx @@ -1,4 +1,4 @@ -import FormLayout, { Flex, FormField, Input, Textarea, FormLabel, ButtonBlack } from "@components/UI/Form/Form"; +import FormLayout, { Flex, FormField, Input, Textarea, FormLabel, ButtonBlack } from "@components/StyledElements/Form/Form"; import { FormMessage } from "@radix-ui/react-form"; import * as Form from '@radix-ui/react-form'; import React, { useState } from "react"; diff --git a/front/components/Modals/Course/Create/CreateCourse.tsx b/front/components/Objects/Modals/Course/Create/CreateCourse.tsx similarity index 95% rename from front/components/Modals/Course/Create/CreateCourse.tsx rename to front/components/Objects/Modals/Course/Create/CreateCourse.tsx index f0d0aa9a..f4a49c82 100644 --- a/front/components/Modals/Course/Create/CreateCourse.tsx +++ b/front/components/Objects/Modals/Course/Create/CreateCourse.tsx @@ -1,4 +1,4 @@ -import FormLayout, { ButtonBlack, Flex, FormField, FormLabel, Input, Textarea } from '@components/UI/Form/Form' +import FormLayout, { ButtonBlack, Flex, FormField, FormLabel, Input, Textarea } from '@components/StyledElements/Form/Form' import * as Form from '@radix-ui/react-form' import { getAPIUrl, getUriWithOrg } from '@services/config/config'; import { FormMessage } from "@radix-ui/react-form"; @@ -8,6 +8,7 @@ import React, { useState } from 'react' import { BarLoader } from 'react-spinners' import { mutate } from 'swr'; import { revalidateTags } from '@services/utils/ts/requests'; +import { useRouter } from 'next/navigation'; function CreateCourseModal({ closeModal, orgslug }: any) { const [isSubmitting, setIsSubmitting] = useState(false); @@ -15,6 +16,7 @@ function CreateCourseModal({ closeModal, orgslug }: any) { const [description, setDescription] = React.useState(""); const [isLoading, setIsLoading] = React.useState(false); const [thumbnail, setThumbnail] = React.useState(null) as any; + const router = useRouter(); const [orgId, setOrgId] = React.useState(null) as any; @@ -46,9 +48,7 @@ function CreateCourseModal({ closeModal, orgslug }: any) { if (status.org_id == orgId) { closeModal(); - // reload the page - // terrible, nextjs right now doesn't mutate the page when the data changes - window.location.reload(); + router.refresh(); } else { alert("Error creating course, please see console logs"); console.log(status); diff --git a/front/components/Pages/Activities/DocumentPdf/DocumentPdf.tsx b/front/components/Pages/Activities/DocumentPdf/DocumentPdf.tsx index 4c907a5e..bdd1c56d 100644 --- a/front/components/Pages/Activities/DocumentPdf/DocumentPdf.tsx +++ b/front/components/Pages/Activities/DocumentPdf/DocumentPdf.tsx @@ -1,75 +1,18 @@ import { getBackendUrl } from "@services/config/config"; import React from "react"; -import styled from "styled-components"; function DocumentPdfActivity({ activity, course }: { activity: any; course: any }) { - function getChapterName() { - let chapterName = ""; - let chapterId = activity.chapter_id; - course.chapters.forEach((chapter: any) => { - if (chapter.chapter_id === chapterId) { - chapterName = chapter.name; - } - }); - return chapterName; - } - + return ( - - -

Chapter : {getChapterName()}

- {activity.name} -
- -