Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
piotr-pajak committed Dec 10, 2024
1 parent aa82717 commit 3b6aee4
Show file tree
Hide file tree
Showing 31 changed files with 634 additions and 81 deletions.
27 changes: 24 additions & 3 deletions apps/api/src/courses/courses.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -547,9 +547,32 @@ export class CoursesService {
};
}

// TODO: Needs to be refactored
async getTeacherCourses(authorId: UUIDType): Promise<AllCoursesForTeacherResponse> {
return this.db
.select(this.getSelectField())
.select({
id: courses.id,
description: sql<string>`${courses.description}`,
title: courses.title,
imageUrl: courses.imageUrl,
authorId: sql<string>`${courses.authorId}`,
author: sql<string>`CONCAT(${users.firstName} || ' ' || ${users.lastName})`,
authorEmail: sql<string>`${users.email}`,
category: sql<string>`${categories.title}`,
enrolled: sql<boolean>`CASE WHEN ${studentCourses.studentId} IS NOT NULL THEN true ELSE false END`,
enrolledParticipantCount: sql<number>`0`,
courseLessonCount: courses.lessonsCount,
completedLessonCount: sql<number>`0`,
priceInCents: courses.priceInCents,
currency: courses.currency,
hasFreeLessons: sql<boolean>`
EXISTS (
SELECT 1
FROM ${courseLessons}
WHERE ${courseLessons.courseId} = ${courses.id}
AND ${courseLessons.isFree} = true
)`,
})
.from(courses)
.leftJoin(studentCourses, eq(studentCourses.courseId, courses.id))
.leftJoin(categories, eq(courses.categoryId, categories.id))
Expand All @@ -573,8 +596,6 @@ export class CoursesService {
users.email,
studentCourses.studentId,
categories.title,
coursesSummaryStats.freePurchasedCount,
coursesSummaryStats.paidPurchasedCount,
)
.orderBy(
sql<boolean>`CASE WHEN ${studentCourses.studentId} IS NULL THEN true ELSE false END`,
Expand Down
22 changes: 22 additions & 0 deletions apps/api/src/swagger/api-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -3191,6 +3191,26 @@
"data": {
"type": "object",
"properties": {
"firstName": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"lastName": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"id": {
"format": "uuid",
"type": "string"
Expand Down Expand Up @@ -3237,6 +3257,8 @@
}
},
"required": [
"firstName",
"lastName",
"id",
"description",
"contactEmail",
Expand Down
4 changes: 3 additions & 1 deletion apps/api/src/users/schemas/user.schema.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { Type, type Static } from "@sinclair/typebox";
import { type Static, Type } from "@sinclair/typebox";

import { commonUserSchema } from "src/common/schemas/common-user.schema";

export const allUsersSchema = Type.Array(commonUserSchema);
export const userDetailsSchema = Type.Object({
firstName: Type.Union([Type.String(), Type.Null()]),
lastName: Type.Union([Type.String(), Type.Null()]),
id: Type.String({ format: "uuid" }),
description: Type.Union([Type.String(), Type.Null()]),
contactEmail: Type.Union([Type.String(), Type.Null()]),
Expand Down
3 changes: 3 additions & 0 deletions apps/api/src/users/users.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,16 @@ export class UsersService {
public async getUserDetails(userId: string): Promise<UserDetails> {
const [userBio]: UserDetails[] = await this.db
.select({
firstName: users.firstName,
lastName: users.lastName,
id: userDetails.id,
description: userDetails.description,
contactEmail: userDetails.contactEmail,
contactPhone: userDetails.contactPhoneNumber,
jobTitle: userDetails.jobTitle,
})
.from(userDetails)
.leftJoin(users, eq(userDetails.userId, users.id))
.where(eq(userDetails.userId, userId));

if (!userBio) {
Expand Down
8 changes: 2 additions & 6 deletions apps/web/app/api/generated-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2088,16 +2088,14 @@ export class API<SecurityDataType extends unknown> extends HttpClient<SecurityDa
*/
coursesControllerGetStudentCourses: (
query?: {
perPage?: number;
title?: string;
category?: string;
author?: string;
"creationDateRange[0]"?: string;
"creationDateRange[1]"?: string;
state?: string;
archived?: string;
/** @min 1 */
page?: number;
perPage?: number;
sort?:
| "title"
| "category"
Expand Down Expand Up @@ -2130,16 +2128,14 @@ export class API<SecurityDataType extends unknown> extends HttpClient<SecurityDa
*/
coursesControllerGetAvailableCourses: (
query?: {
perPage?: number;
title?: string;
category?: string;
author?: string;
"creationDateRange[0]"?: string;
"creationDateRange[1]"?: string;
state?: string;
archived?: string;
/** @min 1 */
page?: number;
perPage?: number;
sort?:
| "title"
| "category"
Expand Down
4 changes: 2 additions & 2 deletions apps/web/app/api/queries/useTeacherCourses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ApiClient } from "../api-client";

import type { GetTeacherCoursesResponse } from "../generated-api";

export const teacherCourses = (authorId: string) => {
export const teacherCoursesOptions = (authorId: string) => {
return {
queryKey: ["teacher-courses", authorId],
queryFn: async () => {
Expand All @@ -17,5 +17,5 @@ export const teacherCourses = (authorId: string) => {
};

export function useTeacherCourses(authorId: string) {
return useQuery(teacherCourses(authorId));
return useQuery(teacherCoursesOptions(authorId));
}
6 changes: 2 additions & 4 deletions apps/web/app/assets/svgs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,7 @@ export { default as ArrowUp } from "./arrow-up.svg?react";
export { default as ArrowDown } from "./arrow-down.svg?react";
export { default as DragAndDropIcon } from "./drag-and-drop.svg?react";
export { default as Info } from "./info.svg?react";
export { default as Text } from "./text.svg?react";
export { default as Presentation } from "./presentation.svg?react";
export { default as Video } from "./video.svg?react";
export { default as Quiz } from "./quiz.svg?react";
export { default as Warning } from "./warning.svg?react";
export { default as Admin } from "./admin.svg?react";

export * from "./lesson-types";
4 changes: 4 additions & 0 deletions apps/web/app/assets/svgs/lesson-types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export { default as Text } from "./text.svg?react";
export { default as Presentation } from "./presentation.svg?react";
export { default as Video } from "./video.svg?react";
export { default as Quiz } from "./quiz.svg?react";
3 changes: 3 additions & 0 deletions apps/web/app/assets/svgs/lesson-types/presentation.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions apps/web/app/assets/svgs/lesson-types/quiz.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions apps/web/app/assets/svgs/lesson-types/text.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions apps/web/app/assets/svgs/lesson-types/video.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 0 additions & 3 deletions apps/web/app/assets/svgs/presentation.svg

This file was deleted.

3 changes: 0 additions & 3 deletions apps/web/app/assets/svgs/quiz.svg

This file was deleted.

3 changes: 0 additions & 3 deletions apps/web/app/assets/svgs/text.svg

This file was deleted.

3 changes: 0 additions & 3 deletions apps/web/app/assets/svgs/video.svg

This file was deleted.

44 changes: 44 additions & 0 deletions apps/web/app/components/Badges/ProgressBadge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Badge } from "~/components/ui/badge";

import type { IconName } from "~/types/shared";

type ProgressBadgeProps = {
progress: "completed" | "inProgress" | "notStarted";
className?: string;
};

type ProgressConfig = {
[key in "completed" | "inProgress" | "notStarted"]: {
variant: "successFilled" | "inProgressFilled" | "notStartedFilled";
icon: IconName;
label: string;
};
};

export const ProgressBadge = ({ progress, className }: ProgressBadgeProps) => {
const progressConfig: ProgressConfig = {
completed: {
variant: "successFilled",
icon: "InputRoundedMarkerSuccess",
label: "Completed",
},
inProgress: {
variant: "inProgressFilled",
icon: "InProgress",
label: "In Progress",
},
notStarted: {
variant: "notStartedFilled",
icon: "NotStartedRounded",
label: "Not Started",
},
};

const { variant, icon, label } = progressConfig[progress];

return (
<Badge variant={variant} icon={icon} {...(Boolean(className) && { className })}>
{label}
</Badge>
);
};
1 change: 1 addition & 0 deletions apps/web/app/components/CardBadge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const badgeVariants = cva(
default: "text-neutral-900",
primary: "text-primary-950",
secondary: "text-secondary-700",
secondaryFilled: "text-secondary-700 bg-secondary-50",
successOutlined: "text-success-800",
successFilled: "text-white bg-success-600",
},
Expand Down
46 changes: 42 additions & 4 deletions apps/web/app/components/PageWrapper/PageWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,53 @@
import {
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbSeparator,
} from "~/components/ui/breadcrumb";
import { cn } from "~/lib/utils";

import type { HTMLAttributes } from "react";
import type { HTMLAttributes, ReactNode } from "react";

type PageWrapperProps = HTMLAttributes<HTMLDivElement> & {
breadcrumbs?: { title: string; href: string }[];
children: ReactNode;
className?: string;
};

export const PageWrapper = ({ className, ...props }: PageWrapperProps) => {
type Breadcrumb = { title: string; href: string };

type BreadcrumbsProps = {
breadcrumbs?: Breadcrumb[];
};

export const Breadcrumbs = ({ breadcrumbs = [] }: BreadcrumbsProps) => {
if (!breadcrumbs.length) return null;

return (
<BreadcrumbList>
{breadcrumbs.map(({ href, title }, index) => (
<BreadcrumbItem key={index}>
<BreadcrumbLink href={href}>{title}</BreadcrumbLink>
{index < breadcrumbs.length - 1 && <BreadcrumbSeparator />}
</BreadcrumbItem>
))}
</BreadcrumbList>
);
};

export const PageWrapper = ({ className, breadcrumbs, children, ...props }: PageWrapperProps) => {
const hasBreadcrumbs = Boolean(breadcrumbs);

const classes = cn(
"h-auto w-full pt-6 px-4 pb-4 md:px-6 md:pb-6 2xl:pt-12 2xl:px-8 2xl:pb-8",
"w-full pt-6 px-4 pb-4 md:px-6 md:pb-6 3xl:pt-12 3xl:px-8 3xl:pb-8",
{ "pt-8 md:pt-6 3xl:pb-2": hasBreadcrumbs },
className,
);
return <div className={classes} {...props} />;

return (
<div className={classes} {...props}>
{breadcrumbs && <Breadcrumbs breadcrumbs={breadcrumbs} />}
{children}
</div>
);
};
Loading

0 comments on commit 3b6aee4

Please sign in to comment.