Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Broken links #613

Merged
merged 13 commits into from
Jul 24, 2024
4 changes: 2 additions & 2 deletions src/components/widgets/course-info/item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ type TProps = {
value: string | number;
};

const CourseInfoItem = ({ icon, label, value }: TProps) => {
const CourseInfo = ({ icon, label, value }: TProps) => {
return (
<div className="tw-flex tw-items-center tw-justify-between tw-py-3.8 tw-border-t tw-border-t-gray-500 first:tw-border-0">
<h6 className="tw-mb-0">
Expand All @@ -23,4 +23,4 @@ const CourseInfoItem = ({ icon, label, value }: TProps) => {
);
};

export default CourseInfoItem;
export default CourseInfo;
105 changes: 105 additions & 0 deletions src/containers/course-details/curriculam-panel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import clsx from "clsx";
import Badge from "@ui/badge";
import Anchor from "@ui/anchor";
import { useUser } from "@contexts/user-context";
import { ICurriculum } from "@utils/types";

type TProps = {
curriculum: ICurriculum[];
courseSlug: string;
};

interface UserContextType {
courseProgress?: Array<{ course: string }>;
}

const CurriculumPanel = ({ curriculum, courseSlug }: TProps) => {
const user = useUser() as UserContextType;
const courseProgress = user?.courseProgress ?? [];
const enrolledCourse = courseProgress.find(
(cs) => cs.course === courseSlug
);

return (
<div className="curriculum-sections">
{curriculum.map(({ id, title, description, lessons }) => (
<div
key={id}
className="tw-border tw-border-alto tw-rounded tw-mt-[50px] first:tw-mt-0"
>
<div className="tw-py-5 tw-px-3.8 md:tw-py-[22px] md:tw-px-12">
<h5 className="tw-text-xl tw-mb-0">{title}</h5>
{description && (
<p className="tw-text-md tw-mb-0 tw-mt-[5px] tw-italic">
{description}
</p>
)}
</div>
{lessons.length > 0 && (
<ul className="section-content">
{lessons.map((item) => {
const hasAccess =
enrolledCourse || item.access === "free";
return (
<li
key={item.slug}
className="tw-text-md even:tw-bg-light-100 odd:tw-bg-white even:last:tw-rounded-b"
>
<Anchor
path={item.path}
className={clsx(
"tw-px-3.8 md:tw-pl-12 md:tw-pr-7.5 tw-min-h-[56px] tw-flex tw-flex-wrap tw-items-center",
!hasAccess &&
"tw-pointer-events-none"
)}
>
<span className="tw-grow tw-py-2.5">
<i
className={clsx(
"far tw-w-5 tw-text-md",
item.type ===
"lesson" &&
"fa-file-alt",
item.type === "quiz" &&
"fa-clock"
)}
/>
{item.title}
</span>
<div className="tw-text-right tw-flex tw-items-center tw-py-2.5">
<Badge className="tw-ml-2.5">
{item.duration}
</Badge>
{item.type === "lesson" &&
item.access === "free" && (
<Badge
className="tw-ml-2.5"
color="primary"
>
Preview
</Badge>
)}
{item?.video && (
<span className="tw-ml-2.5 tw-font-medium tw-px-3.8">
<i className="far fa-video" />
</span>
)}
{item.access === "paid" && (
<span className="tw-ml-2.5 tw-font-medium tw-px-3.8">
<i className="fas fa-lock-alt" />
</span>
)}
</div>
</Anchor>
</li>
);
})}
</ul>
)}
</div>
))}
</div>
);
};

export default CurriculumPanel;
59 changes: 59 additions & 0 deletions src/containers/course-details/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { TabContainer, TabNav, TabPane, TabList, TabContent } from "@ui/tab";
import { ICourse } from "@utils/types";
import OverviewPanel from "./overview-panel";
// import InstructorPanel from "./instructor-panel";
// import ReviewPanel from "./review-panel";

type TProps = {
data: {
course: ICourse;
};
};

const CourseDetails = ({ data: { course } }: TProps) => {
return (
<section className="course-details">
<div className="tw-container tw-grid lg:tw-grid-cols-3 tw-gap-12">
<div className="lg:tw-col-[1/3]">
<TabContainer variant="underline">
<TabList>
<TabNav>Overview</TabNav>
{/* Remove unused tabs */}
{/* <TabNav>Curriculum</TabNav>
<TabNav>Instructor</TabNav>
<TabNav>Reviews</TabNav> */}
</TabList>
<TabContent className="tw-mt-10 lg:tw-mt-[50px]">
<TabPane>
{course?.description && (
<OverviewPanel
description={course?.description}
/>
)}
</TabPane>
{/* Remove unused TabPane components */}
{/* <TabPane>
{curriculum && (
<CurriculamPanel
curriculum={curriculum}
courseSlug={course.slug}
/>
)}
</TabPane>
<TabPane>
<InstructorPanel {...instructor} />
</TabPane>
<TabPane>
{course?.reviews && (
<ReviewPanel {...course.reviews} />
)}
</TabPane> */}
</TabContent>
</TabContainer>
</div>
</div>
</section>
);
};

export default CourseDetails;
52 changes: 52 additions & 0 deletions src/containers/course-details/instructor-panel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import Anchor from "@ui/anchor";
import Social, { SocialLink } from "@components/ui/social";
import { IInstructor } from "@utils/types";

type TProps = IInstructor;

const OverviewPanel = ({ name, image, designation, bio, socials }: TProps) => {
return (
<div className="instructor tw-grid tw-gap-7.5 md:tw-grid-cols-3 lg:tw-gap-[50px]">
<figure className="md:tw-col-[1/1]">
{image.src && (
<img
src={image.src}
alt={image?.alt || name}
width={238}
height={238}
loading="lazy"
/>
)}
</figure>
<div className="md:tw-col-[2/-1]">
<h3>
<Anchor path="/profile">{name}</Anchor>
</h3>
<h6 className="tw-font-normal tw-text-body tw-leading-relaxed tw-mb-0">
/{designation}
</h6>
<p className="tw-mt-3.8 tw-mb-0">{bio}</p>

<Social
shape="circle"
variant="outlined"
color="light"
className="tw-mt-7.5"
>
{socials.map((social) => (
<SocialLink
key={social.label}
href={social.url}
label={social.label}
className="tw-mr-3"
>
<i className={social.icon} />
</SocialLink>
))}
</Social>
</div>
</div>
);
};

export default OverviewPanel;
18 changes: 18 additions & 0 deletions src/containers/course-details/overview-panel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { IContent } from "@utils/types";

import HTMLContent from "@components/html-content";

type TProps = {
description: IContent[];
};

const OverviewPanel = ({ description }: TProps) => {
return (
<div className="course-overview tw-prose prose-h2:tw-text-xl sm:prose-h2:tw-text-3xl tw-max-w-none">
<h2 className="title tw-mb-5">Course Description</h2>
<HTMLContent body={description} />
</div>
);
};

export default OverviewPanel;
64 changes: 64 additions & 0 deletions src/containers/course-details/review-panel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import ProgressBar from "@ui/progress-bar";
import StarRating from "@ui/star-rating";
import Review from "@components/review";
import { ReviewType } from "@utils/types";

const ReviewPanel = ({ average, count, rating_details, items }: ReviewType) => {
return (
<>
<h3 className="tw-mt-[13px] tw-mb-[26px]">Reviews</h3>
<div className="tw-flex tw-flex-wrap">
<div className="tw-shrink-0 tw-w-full tw-mb-7.5 sm:tw-mb-0 sm:tw-w-[200px] sm:tw-mr-7.5 md:tw-mr-[70px]">
<p className="tw-text-secondary tw-font-medium tw-mb-3.8">
Average Rating
</p>
<div className="tw-bg-white tw-text-center tw-pt-[34px] tw-pb-[38px] tw-px-7.5 tw-shadow-2sm tw-shadow-heading/10">
<div className="tw-text-[56px] tw-font-semibold tw-leading-none tw-mb-2 tw-text-primary">
{average}
</div>
<StarRating rating={average} />
<div className="tw-mt-0.5">({count} ratings)</div>
</div>
</div>
<div className="tw-grow">
<p className="tw-text-secondary tw-font-medium sm:tw-mb-[42px]">
Detailed Rating
</p>
{Object.entries(rating_details).map(([key, value]) => (
<div className="tw-flex tw-items-center" key={key}>
<StarRating
rating={+key}
size="sm"
align="left"
className="tw-shrink-0 tw-mr-5"
/>
<ProgressBar
color="primary"
now={value ? 50 : 0}
disableAnimation
className="tw-grow"
/>
<span className="tw-shrink-0 tw-text-gray-400 tw-font-medium tw-min-w-[25px] tw-text-right tw-ml-1">
{value}
</span>
</div>
))}
</div>
</div>
{items.length > 0 && (
<ul className="course-reviews-list tw-mt-[50px]">
{items.map((item) => (
<li
key={item.id}
className="tw-mb-7.5 tw-pl-[5px] tw-pr-5 tw-pt-5 tw-pb-7 tw-border-b tw-border-b-gray-500 tw-mt-2.5 first:tw-mt-0 last:tw-mb-0"
>
<Review {...item} />
</li>
))}
</ul>
)}
</>
);
};

export default ReviewPanel;
5 changes: 1 addition & 4 deletions src/containers/course/layout-05/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,7 @@ const CourseArea = ({
viewport={{ once: true, amount: 0.4 }}
variants={scrollUpVariants}
>
<Button
path="/curriculum/subjects"
className="tw-mt-[50px]"
>
<Button path="/courses/all" className="tw-mt-[50px]">
View All Modules{" "}
<i className="far fa-long-arrow-right tw-ml-3" />
</Button>
Expand Down
2 changes: 1 addition & 1 deletion src/data/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ export default [
{
id: 22,
label: "Modules",
path: "/curriculum/subjects",
path: "/courses/all",
},
{
id: 23,
Expand Down
2 changes: 1 addition & 1 deletion src/lib/course.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export function getCourseBySlug(
return {
...course,
published_at: fileContents.published_at,
path: `/curriculum/${realSlug}`,
path: `/courses/${realSlug}`,
};
}

Expand Down
Loading
Loading