diff --git a/apps/web/src/components/UpcomingLessons/Content.tsx b/apps/web/src/components/UpcomingLessons/Content.tsx index 5344bdc6e..3e63a183d 100644 --- a/apps/web/src/components/UpcomingLessons/Content.tsx +++ b/apps/web/src/components/UpcomingLessons/Content.tsx @@ -21,6 +21,8 @@ import { capture } from "@/lib/sentry"; import { Web } from "@litespace/utils/routes"; import { router } from "@/lib/routes"; import { isStudent } from "@litespace/utils/user"; +import { range } from "lodash"; +import { faker } from "@faker-js/faker/locale/ar"; type Lessons = ILesson.FindUserLessonsApiResponse["list"]; @@ -113,7 +115,7 @@ export const Content: React.FC<{ return (
-
+
{list.map((item) => { const tutor = item.members.find( (member) => @@ -172,6 +174,8 @@ export const Content: React.FC<{ otherMember.role === IUser.Role.Student ? "student" : "tutor", + topics: range(7).map(() => faker.lorem.words(1)), + level: "C1", }} sendingMessage={sendingMessageLessonId === item.lesson.id} disabled={!!sendingMessageLessonId} diff --git a/packages/ui/src/components/Lessons/LessonCard.stories.tsx b/packages/ui/src/components/Lessons/LessonCard.stories.tsx index b0774e2b3..06f723233 100644 --- a/packages/ui/src/components/Lessons/LessonCard.stories.tsx +++ b/packages/ui/src/components/Lessons/LessonCard.stories.tsx @@ -2,6 +2,7 @@ import { Meta, StoryObj } from "@storybook/react"; import LessonCard, { Props } from "@/components/Lessons/LessonCard"; import dayjs from "@/lib/dayjs"; import { faker } from "@faker-js/faker/locale/ar"; +import { range } from "lodash"; const meta: Meta = { title: "Lessons/LessonCard", @@ -30,6 +31,8 @@ export const BeforeJoinForStudent: Story = { name: faker.person.fullName(), image: url, role: "tutor", + topics: range(7).map(() => faker.lorem.words(1)), + level: "C1", }, ...actions, }, @@ -45,6 +48,8 @@ export const BeforeJoinForTutor: Story = { name: faker.person.fullName(), image: url, role: "student", + topics: range(7).map(() => faker.lorem.words(1)), + level: "C1", }, ...actions, }, @@ -60,6 +65,8 @@ export const CanJoinLesson: Story = { name: faker.person.fullName(), image: url, role: "tutor", + topics: range(7).map(() => faker.lorem.words(1)), + level: "C1", }, ...actions, }, @@ -75,6 +82,8 @@ export const CanJoinLessonNow: Story = { name: faker.person.fullName(), image: url, role: "tutor", + topics: range(7).map(() => faker.lorem.words(1)), + level: "C1", }, ...actions, }, @@ -90,6 +99,8 @@ export const AfterLessonStarted: Story = { name: faker.person.fullName(), image: url, role: "tutor", + topics: range(7).map(() => faker.lorem.words(1)), + level: "C1", }, ...actions, }, @@ -105,6 +116,8 @@ export const LessonAboutToEnd: Story = { name: faker.person.fullName(), image: url, role: "tutor", + topics: range(7).map(() => faker.lorem.words(1)), + level: "C1", }, ...actions, }, @@ -120,6 +133,8 @@ export const AfterLessonFinishForStudent: Story = { name: faker.person.fullName(), image: url, role: "tutor", + topics: range(7).map(() => faker.lorem.words(1)), + level: "C1", }, ...actions, }, @@ -135,6 +150,8 @@ export const AfterLessonFinishForTutor: Story = { name: faker.person.fullName(), image: url, role: "student", + topics: range(7).map(() => faker.lorem.words(1)), + level: "C1", }, ...actions, }, @@ -150,6 +167,8 @@ export const CanceledByTutor: Story = { name: faker.person.fullName(), image: url, role: "tutor", + topics: range(7).map(() => faker.lorem.words(1)), + level: "C1", }, ...actions, }, @@ -165,6 +184,8 @@ export const CanceledByStudent: Story = { name: faker.person.fullName(), image: url, role: "student", + topics: range(7).map(() => faker.lorem.words(1)), + level: "C1", }, ...actions, }, @@ -180,6 +201,8 @@ export const CanceledByCurrentTutor: Story = { name: faker.person.fullName(), image: url, role: "student", + topics: range(7).map(() => faker.lorem.words(1)), + level: "C1", }, ...actions, }, @@ -195,6 +218,8 @@ export const CanceledByCurrentStudent: Story = { name: faker.person.fullName(), image: url, role: "tutor", + topics: range(7).map(() => faker.lorem.words(1)), + level: "C1", }, ...actions, }, diff --git a/packages/ui/src/components/Lessons/LessonCard.tsx b/packages/ui/src/components/Lessons/LessonCard.tsx index 83ace1840..835d8787c 100644 --- a/packages/ui/src/components/Lessons/LessonCard.tsx +++ b/packages/ui/src/components/Lessons/LessonCard.tsx @@ -11,6 +11,9 @@ import { Menu, type MenuAction } from "@/components/Menu"; import CalendarEdit from "@litespace/assets/CalendarEdit"; import CalendarRemove from "@litespace/assets/CalendarRemove"; import CheckCircle from "@litespace/assets/CheckCircle"; +import Calendar from "@litespace/assets/Calendar"; +import AllMessages from "@litespace/assets/AllMessages"; +import Clock from "@litespace/assets/Clock"; export type Props = { start: string; @@ -24,7 +27,10 @@ export type Props = { * @note role shall be `student` when the current user is tutor and vice versa */ role: "tutor" | "student"; + topics: Array; + level: string; }; + sendingMessage: boolean; disabled: boolean; onRebook: Void; @@ -126,6 +132,16 @@ export const LessonCard: React.FC = ({ return () => clearInterval(interval); }, [getTitle]); + const isEnded = useMemo(() => end.isBefore(dayjs()), [end]); + const isOngoing = useMemo( + () => !canceled && dayjs().isBetween(dayjs(start), end), + [canceled, start, end] + ); + const isFuture = useMemo( + () => !canceled && dayjs().isBefore(dayjs(start)), + [canceled, start] + ); + const actions: MenuAction[] = useMemo( () => currentUserRole === "student" @@ -154,25 +170,41 @@ export const LessonCard: React.FC = ({ ); const action = useMemo(() => { - const ended = end.isBefore(dayjs()); - if (currentUserRole === "student" && (ended || canceled)) - return { - label: intl("lessons.button.rebook"), - onClick: onRebook, - }; - if (currentUserRole === "tutor" && (ended || canceled)) - return { - label: intl("lessons.button.send-message"), - onClick: onSendMsg, - }; + if (currentUserRole === "student") { + if (isEnded || canceled) { + return { + label: intl("lessons.button.rebook"), + onClick: onRebook, + }; + } + } else if (currentUserRole === "tutor") { + if (isEnded) { + return { + label: intl("lessons.button.send-message"), + onClick: onSendMsg, + }; + } + if (canceled) { + return { + label: intl("lessons.button.contact-student"), + onClick: onSendMsg, + }; + } + } return { label: intl("lessons.button.join"), onClick: onJoin, }; - }, [canceled, currentUserRole, end, intl, onJoin, onRebook, onSendMsg]); + }, [canceled, currentUserRole, isEnded, intl, onJoin, onRebook, onSendMsg]); + + const buttonType = useMemo( + () => (currentUserRole === "tutor" && isOngoing ? "main" : "natural"), + [currentUserRole, isOngoing] + ); const button = (
-
- +
+
+ + {member.level} + +
+
+ +
-
+
{member.name} - - {dayjs(start).format("dddd، D MMMM")} - - - {dayjs(start).format("h:mm a")} - {" - "} - {dayjs(start).add(duration, "minutes").format("h:mm a")} - + +
+
+ + + {dayjs(start).format("h:mm a")} + {" - "} + {dayjs(start).add(duration, "minutes").format("h:mm a")} + +
+ +
+ + + {dayjs(start).format("dddd، D MMMM")} + +
+
+ +
+ {member.topics.slice(0, 4).map((topic) => ( + + {topic} + + ))} + {member.topics.length > 4 && ( + + {member.topics.length - 4}+ + + )} +
- {button} +
+ {button} + {currentUserRole === "tutor" && isFuture && ( +
); diff --git a/packages/ui/src/locales/ar-eg.json b/packages/ui/src/locales/ar-eg.json index 3232fadc6..7c702eef4 100644 --- a/packages/ui/src/locales/ar-eg.json +++ b/packages/ui/src/locales/ar-eg.json @@ -732,6 +732,7 @@ "lessons.button.rebook": "إعادة الحجز", "lessons.button.join": "دخول الحصة", "lessons.button.send-message": "إرسال رسالة", + "lessons.button.contact-student": "تواصل مع الطالب", "lessons.button.find-tutors": "تصفح المعلمين", "lessons.canceled-by-tutor": "لقد تم إلغاء الحصة من قبل المعلم", "lessons.canceled-by-student": "لقد قام الطالب بإلغاء الحصة", @@ -779,7 +780,7 @@ "student-dashboard.past-lessons.loading": "برجاء الانتظار... جاري تحميل الدروس السابقة!", "student-dashboard.past-lessons.error": "عذرًا، حدث خطأ أثناء تحميل الدروس السابقة، برجاء المحاولة مرة أخرى", "tour.sdashboard/1.title": "👋 مرحبًا بك في رحلتك لتعلّم اللغة!", - "tour.sdashboard/1.description": "من خلال صفحة المدرّسين، تستطيع ان تستعرض كل المعلمين وتقوم بـ حجز جلسة مباشرة مع أيّ معلم منهم.
كل ما عليك هو ان تضغط على المدرّس المناسب لك، وتستعرض ملفه الشخصي، مواعيده المتاحة، وتبدأ الحجز في الحال!", + "tour.sdashboard/1.description": "من خلال صفحة المدرّسين، تستطيع ان تستعرض كل المعلمين وتقوم بـ حجز جلسة مباشرة مع أيّ معلم منهم.كل ما عليك هو ان تضغط على المدرّس المناسب لك، وتستعرض ملفه الشخصي، مواعيده المتاحة، وتبدأ الحجز في الحال!", "tour.sdashboard/2.title": "هل وجدت المعلم المناسب لك؟", "tour.sdashboard/2.description": "اضغط على 'احجز الآن' لكي تبدأ أول جلسة مع المعلم.", "tour.sdashboard/3.title": "الفيديو التعريفي للمعلم",