Skip to content

Commit

Permalink
refactor(ui): refactor book lesson logic
Browse files Browse the repository at this point in the history
  • Loading branch information
neuodev committed Dec 15, 2024
1 parent 6eb2392 commit ff52d7e
Show file tree
Hide file tree
Showing 17 changed files with 269 additions and 219 deletions.
14 changes: 12 additions & 2 deletions apps/nova/src/components/Lessons/BookLesson.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import dayjs from "dayjs";
import { useCallback } from "react";
import { useToast } from "@litespace/luna/Toast";
import { useFormatMessage } from "@litespace/luna/hooks/intl";
import { useQueryClient } from "@tanstack/react-query";
import { QueryKey } from "@litespace/headless/constants";

const BookLesson = ({
open,
Expand All @@ -25,16 +27,24 @@ const BookLesson = ({
const toast = useToast();
const before = dayjs().toISOString();
const after = dayjs(before).add(user.notice, "minutes").toISOString();
const queryClient = useQueryClient();
const rulesQuery = useFindUserRulesWithSlots({
id: user.tutorId,
before,
after,
});

const onSuccess = useCallback(() => {
toast.success({ title: intl("book-lesson.success", { tutor: user.name }) });
close();
}, [toast, close, intl, user.name]);
toast.success({ title: intl("book-lesson.success", { tutor: user.name }) });
queryClient.invalidateQueries({
queryKey: [
QueryKey.FindRulesWithSlots,
QueryKey.FindLesson,
QueryKey.FindTutors,
],
});
}, [toast, intl, user.name, close, queryClient]);

const onError = useCallback(() => {
toast.error({ title: intl("book-lesson.error") });
Expand Down
34 changes: 16 additions & 18 deletions apps/nova/src/components/Tutors/Content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { TutorCard } from "@litespace/luna/TutorCard";
import { asFullAssetUrl } from "@litespace/luna/backend";
import { Route } from "@/types/routes";
import { useNavigate } from "react-router-dom";
import { AnimatePresence, motion } from "framer-motion";
import { motion } from "framer-motion";
import { InView } from "react-intersection-observer";
import BookLesson from "@/components/Lessons/BookLesson";

Expand Down Expand Up @@ -49,9 +49,9 @@ const Content: React.FC<{
bio={tutor.bio}
about={tutor.about}
name={tutor.name}
lessonCount={20}
studentCount={20}
rating={4.5}
lessonCount={tutor.lessonCount}
studentCount={tutor.studentCount}
rating={tutor.avgRating}
onBook={() => openBookingDialog(tutor)}
onOpenProfile={() => navigate(profileUrl)}
profileUrl={profileUrl}
Expand All @@ -62,20 +62,18 @@ const Content: React.FC<{
})}
</div>

<AnimatePresence>
{tutor ? (
<BookLesson
close={closeBookingDialog}
open={!!tutor}
user={{
tutorId: tutor?.id,
imageUrl: tutor.image,
notice: tutor.notice,
name: tutor.name,
}}
/>
) : null}
</AnimatePresence>
{tutor ? (
<BookLesson
close={closeBookingDialog}
open={!!tutor}
user={{
tutorId: tutor?.id,
imageUrl: tutor.image,
notice: tutor.notice,
name: tutor.name,
}}
/>
) : null}

{fetching ? <Loading className="mt-6 text-natural-950" /> : null}

Expand Down
10 changes: 7 additions & 3 deletions apps/nova/src/pages/TutorProfile.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { Loading } from "@litespace/luna/Loading";
import React, { useCallback, useMemo, useState } from "react";
import { useParams } from "react-router-dom";
import { Link, useParams } from "react-router-dom";
import { useFindTutorInfo } from "@litespace/headless/tutor";
import RightArrow from "@litespace/assets/ArrowRight";
import { Typography } from "@litespace/luna/Typography";
import { useFormatMessage } from "@litespace/luna/hooks/intl";
import { TutorProfileCard } from "@litespace/luna/TutorProfile";
import { TutorTabs } from "@/components/TutorProfile/TutorTabs";
import BookLesson from "@/components/Lessons/BookLesson";
import { Route } from "@/types/routes";

const TutorProfile: React.FC = () => {
const params = useParams<{ id: string }>();
Expand All @@ -30,9 +31,12 @@ const TutorProfile: React.FC = () => {
return (
<div className="w-full max-w-screen-3xl p-6 mx-auto mb-12 lg:max-w-screen-3xl">
<div className="flex items-center gap-6">
<button className="w-6 h-6 flex items-center justify-center">
<Link
to={Route.Tutors}
className="w-6 h-6 flex items-center justify-center"
>
<RightArrow className="[&>*]:stroke-brand-700" />
</button>
</Link>
<Typography element="subtitle-2" className="font-bold text-natural-950">
{intl("tutors.title")} /{" "}
<span className="underline text-brand-700">{tutor.data.name}</span>
Expand Down
14 changes: 7 additions & 7 deletions packages/atlas/src/rule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@ export class Rule extends Base {
return await this.get(`/api/v1/rule/list/${id}`);
}

/**
* @param id user id (manger or tutor)
* @param after utc after datetime (get rules after this date)
* @param before utc before datetime (get rules before this date)
*/
async findUserRulesWithSlots({
id,
after,
before,
}: IRule.FindRulesWithSlotsApiQuery): Promise<IRule.FindUserRulesWithSlotsApiResponse> {
after,
}: {
/**
* user id (manger or tutor)
*/
id: number;
} & IRule.FindRulesWithSlotsApiQuery): Promise<IRule.FindUserRulesWithSlotsApiResponse> {
return await this.get(`/api/v1/rule/slots/${id}`, {}, { after, before });
}

Expand Down
13 changes: 5 additions & 8 deletions packages/headless/src/lessons.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { Element, IFilter, ILesson, Void } from "@litespace/types";
import { Element, IFilter, ILesson } from "@litespace/types";
import { useCallback } from "react";
import { useAtlas } from "@/atlas/index";
import { MutationKey, QueryKey } from "@/constants";
import { useMutation } from "@tanstack/react-query";
import { UsePaginateResult, usePaginate } from "@/pagination";
import { InfiniteQueryHandler, useInfinitePaginationQuery } from "./query";

type OnSuccess = Void;
type OnError = (error: Error) => void;
import { OnError, OnSuccess } from "@/types/query";

export function useFindLessons(
query: ILesson.FindLessonsApiQuery & { userOnly?: boolean }
Expand Down Expand Up @@ -77,7 +75,7 @@ export function useCreateLesson({
onError,
}: {
tutorId: number;
onSuccess: OnSuccess;
onSuccess: OnSuccess<ILesson.Self>;
onError: OnError;
}) {
const atlas = useAtlas();
Expand All @@ -88,11 +86,10 @@ export function useCreateLesson({
start,
duration,
}: {
ruleId: number | null;
start: string | null;
ruleId: number;
start: string;
duration: ILesson.Duration;
}) => {
if (!ruleId || !start) return;
return await atlas.lesson.create({
tutorId,
duration,
Expand Down
4 changes: 2 additions & 2 deletions packages/headless/src/rule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export function useDeleteRule({
}

export function useFindUserRulesWithSlots(
payload: IRule.FindRulesWithSlotsApiQuery
payload: { id: number } & IRule.FindRulesWithSlotsApiQuery
) {
const atlas = useAtlas();

Expand All @@ -111,6 +111,6 @@ export function useFindUserRulesWithSlots(

return useQuery({
queryFn: findRules,
queryKey: [QueryKey.FindRulesWithSlots],
queryKey: [QueryKey.FindRulesWithSlots, payload],
});
}
3 changes: 2 additions & 1 deletion packages/luna/src/components/Dialog/V2/Dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
import cn from "classnames";
import React from "react";
import X from "@litespace/assets/X";
import { Void } from "@litespace/types";

export const Dialog: React.FC<{
trigger?: React.ReactNode;
Expand All @@ -18,7 +19,7 @@ export const Dialog: React.FC<{
className?: string;
open?: boolean;
setOpen?: (open: boolean) => void;
close: () => void;
close: Void;
description?: string;
}> = ({
trigger,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,33 @@ export const LoadingRules: Story = {
},
};

export const ConfirmationLoading: Story = {
args: {
open: true,
close: identity,
tutorId: faker.number.int(),
name: faker.person.fullName(),
imageUrl: faker.image.urlPicsumPhotos({ width: 400, height: 400 }),
rules: [makeRule(1)],
slots: range(5).map((idx) => ({
ruleId: 1,
start: dayjs
.utc()
.add(1, "day")
.set("hour", 10)
.set("minutes", 0)
.add(idx * 30, "minutes")
.toISOString(),
duration: 30,
})),
notice: 0,
confirmationLoading: true,
onBook() {
alert("Lesson booked!!");
},
},
};

export const LoadingThenShowingRules: Story = {
args: {
open: true,
Expand Down Expand Up @@ -139,9 +166,10 @@ export const LoadingThenShowingRules: Story = {
render: (props) => {
const [loading, setIsLoading] = useState(true);
useEffect(() => {
setTimeout(() => {
const id = setTimeout(() => {
setIsLoading(false);
}, 2_000);
return () => clearTimeout(id);
}, []);
return <BookLessonDialog {...props} loading={loading} />;
},
Expand Down
Loading

0 comments on commit ff52d7e

Please sign in to comment.