Merge pull request #120 from learnhouse/swve/eng-116-redesign-parts-of-course-page

Redesign parts of course page
This commit is contained in:
Badr B 2023-10-13 18:41:10 +02:00 committed by GitHub
commit f556e41dda
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 124 additions and 31 deletions

View file

@ -1,25 +1,34 @@
"use client";
import { EyeOpenIcon, Pencil2Icon } from "@radix-ui/react-icons";
import { removeCourse, startCourse } from "@services/courses/activity";
import Link from "next/link";
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/StyledElements/Tooltip/Tooltip";
import React, { use, useEffect, useState } from "react";
import { getUriWithOrg } from "@services/config/config";
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";
import { getCourseThumbnailMediaDirectory } from "@services/media/media";
import { ArrowRight, Check, File, Sparkles, Star, Video } from "lucide-react";
import Avvvatars from "avvvatars-react";
import { getUser } from "@services/users/users";
const CourseClient = (props: any) => {
const [user, setUser] = useState<any>({});
const courseid = props.courseid;
const orgslug = props.orgslug;
const course = props.course;
const router = useRouter();
async function getUserUI() {
let user_id = course.course.authors[0];
const user = await getUser(user_id);
setUser(user);
console.log(user);
}
async function startCourseUI() {
// Create activity
await startCourse("course_" + courseid, orgslug);
@ -36,11 +45,12 @@ const CourseClient = (props: any) => {
// Mutate course
await revalidateTags(['courses'], orgslug);
router.refresh();
// refresh page (FIX for Next.js BUG)
//window.location.reload();
}
useEffect(() => {
getUserUI();
}
, []);
return (
<>
@ -57,7 +67,6 @@ const CourseClient = (props: any) => {
<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(${getCourseThumbnailMediaDirectory(course.course.org_id, course.course.course_id, course.course.thumbnail)})` }}>
</div>
<ActivityIndicators course_id={props.course.course.course_id} orgslug={orgslug} course={course} />
@ -65,52 +74,128 @@ const CourseClient = (props: any) => {
<div className="flex flex-row pt-10">
<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>
</StyledBox>
<div className="bg-white shadow-md shadow-gray-300/25 outline outline-1 outline-neutral-200/40 rounded-lg overflow-hidden">
<p className="py-5 px-5">{course.course.description}</p>
</div>
<h2 className="py-3 text-2xl font-bold">What you will learn</h2>
<StyledBox>
<p className="py-3">{course.learnings == ![] ? "no data" : course.learnings}</p>
</StyledBox>
<div className="bg-white shadow-md shadow-gray-300/25 outline outline-1 outline-neutral-200/40 rounded-lg overflow-hidden px-5 py-5 space-y-2">
{course.course.learnings.map((learning: any) => {
return (
<div key={learning}
className="flex space-x-2 items-center font-semibold text-gray-500 capitalize">
<div className="px-2 py-2 rounded-full">
<Check className="text-gray-400" size={15} />
</div>
<p>{learning}</p>
</div>
);
}
)}
</div>
<h2 className="py-3 text-2xl font-bold">Course Lessons</h2>
<StyledBox>
<div className="bg-white shadow-md shadow-gray-300/25 outline outline-1 outline-neutral-200/40 rounded-lg overflow-hidden">
{course.chapters.map((chapter: any) => {
return (
<div
key={chapter}
className="py-3"
className=""
>
<h3 className="text-lg">{chapter.name}</h3>
<div className="flex text-lg py-4 px-4 outline outline-1 outline-neutral-200/40 font-bold bg-neutral-50 text-neutral-600 items-center">
<h3 className="grow">{chapter.name}</h3>
<p className="text-sm font-normal text-neutral-400 px-3 py-[2px] outline-1 outline outline-neutral-200 rounded-full ">
{chapter.activities.length} Activities
</p>
</div>
<div
className="py-3"
>{chapter.activities.map((activity: any) => {
return (
<>
<p className="flex text-md">
{activity.name}
<Link className="pl-3" href={getUriWithOrg(orgslug, "") + `/course/${courseid}/activity/${activity.id.replace("activity_", "")}`} rel="noopener noreferrer">
<EyeOpenIcon />
</Link>{" "}
</p>
<div className="flex space-x-1 py-2 px-4 items-center">
<div className="courseicon items-center flex space-x-2 text-neutral-400">
{activity.type === "dynamic" &&
<div className="bg-gray-100 px-2 py-2 rounded-full">
<Sparkles className="text-gray-400" size={13} />
</div>
}
{activity.type === "video" &&
<div className="bg-gray-100 px-2 py-2 rounded-full">
<Video className="text-gray-400" size={13} />
</div>
}
{activity.type === "documentpdf" &&
<div className="bg-gray-100 px-2 py-2 rounded-full">
<File className="text-gray-400" size={13} />
</div>
}
</div>
<Link className="flex font-semibold grow pl-2 text-neutral-500" href={getUriWithOrg(orgslug, "") + `/course/${courseid}/activity/${activity.id.replace("activity_", "")}`} rel="noopener noreferrer">
<p>{activity.name}</p>
</Link>
<div className="flex ">
{activity.type === "dynamic" &&
<>
<Link className="flex grow pl-2 text-gray-500" href={getUriWithOrg(orgslug, "") + `/course/${courseid}/activity/${activity.id.replace("activity_", "")}`} rel="noopener noreferrer">
<div className="text-xs bg-gray-100 text-gray-400 font-bold px-2 py-1 rounded-full flex space-x-1 items-center">
<p>Page</p>
<ArrowRight size={13} /></div>
</Link>
</>
}
{activity.type === "video" &&
<>
<Link className="flex grow pl-2 text-gray-500" href={getUriWithOrg(orgslug, "") + `/course/${courseid}/activity/${activity.id.replace("activity_", "")}`} rel="noopener noreferrer">
<div className="text-xs bg-gray-100 text-gray-400 font-bold px-2 py-1 rounded-full flex space-x-1 items-center">
<p>Video</p>
<ArrowRight size={13} /></div>
</Link>
</>
}
{activity.type === "documentpdf" &&
<>
<Link className="flex grow pl-2 text-gray-500" href={getUriWithOrg(orgslug, "") + `/course/${courseid}/activity/${activity.id.replace("activity_", "")}`} rel="noopener noreferrer">
<div className="text-xs bg-gray-100 text-gray-400 font-bold px-2 py-1 rounded-full flex space-x-1 items-center">
<p>Document</p>
<ArrowRight size={13} /></div>
</Link>
</>
}
</div>
</div>
</>
);
})}</div>
</div>
);
})}
</StyledBox>
</div>
</div>
<div className="course_metadata_right w-64 flex items-center ml-10 h-28 p-3 bg-white shadow-sm justify-center ring-1 ring-inset ring-gray-400/10 rounded-lg transition-all">
<div className="course_metadata_right space-y-3 w-64 antialiased flex flex-col ml-10 h-fit p-3 py-5 bg-white shadow-md shadow-gray-300/25 outline outline-1 outline-neutral-200/40 rounded-lg overflow-hidden">
{ user &&
<div className="flex mx-auto space-x-3 px-2 py-2 items-center">
<div className="">
<Avvvatars border borderSize={5} borderColor="white" size={50} shadow value={course.course.authors[0]} style='shape' />
</div>
<div className="-space-y-2 ">
<div className="text-[12px] text-neutral-400 font-semibold">Author</div>
<div className="text-xl font-bold text-neutral-800">{user.full_name}</div>
</div>
</div>
}
{course.trail.status == "ongoing" ? (
<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}>
<button className="py-2 px-5 mx-auto 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 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>
<button className="py-2 px-5 mx-auto 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>
)}
</div>
</div>

View file

@ -28,13 +28,13 @@ export const HeaderProfileBox = () => {
</UnidentifiedArea>
)}
{auth.isAuthenticated && (
<AccountArea className="space-x-3">
<div className="text-sm text-gray-600 p-1.5 px-2 rounded-lg">{auth.userInfo.user_object.full_name}</div>
<AccountArea className="-space-x-2">
<div className="text-xs px-4 text-gray-600 p-1.5 rounded-full bg-gray-50">{auth.userInfo.user_object.full_name}</div>
<div className="flex -space-x-2 items-center">
<div className="py-4">
<Avvvatars size={26} value={auth.userInfo.user_object.user_id} style="shape" />
</div>
<Link className="bg-slate-50 p-1.5 rounded-full" href={"/settings"}><GearIcon fontSize={26} /></Link>
<Link className="bg-gray-50 p-1.5 rounded-full" href={"/settings"}><GearIcon fontSize={26} /></Link>
</div>
</AccountArea>
)}

View file

@ -0,0 +1,8 @@
import { getAPIUrl } from "@services/config/config";
import { RequestBody, errorHandling } from "@services/utils/ts/requests";
export async function getUser(user_id: string) {
const result = await fetch(`${getAPIUrl()}users/user_id/${user_id}`, RequestBody("GET", null, null));
const res = await errorHandling(result);
return res;
}