Skip to content

Commit

Permalink
fix(luna): fixed issue with loading spinner
Browse files Browse the repository at this point in the history
  • Loading branch information
mostafakamar2308 committed Dec 24, 2024
1 parent ea6aefb commit 8d9a3f7
Show file tree
Hide file tree
Showing 12 changed files with 66 additions and 55 deletions.
Binary file added apps/nova/src/assets/new-tutor.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion apps/nova/src/components/TutorProfile/ProfileInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const ProfileInfo: React.FC<{
}> = ({ about, topics, video }) => {
const intl = useFormatMessage();
return (
<div className="grid grid-cols-2 py-8 gap-[88px]">
<div className="grid grid-cols-2 py-8 gap-[88px] p-8 px-10">
<div>
{about ? (
<div>
Expand Down
46 changes: 26 additions & 20 deletions apps/nova/src/components/TutorProfile/Ratings.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useFindTutorRatings } from "@litespace/headless/rating";
import React, { useCallback, useMemo } from "react";
import React, { useMemo } from "react";
import { organizeRatings } from "@/lib/ratings";
import { useUser } from "@litespace/headless/context/user";
import {
Expand All @@ -9,26 +9,31 @@ import {
import { Typography } from "@litespace/luna/Typography";
import { useFormatMessage } from "@litespace/luna/hooks/intl";
import Star from "@litespace/assets/Star";
import NewTutor from "@litespace/assets/NewTutor";
import { Button, ButtonSize } from "@litespace/luna/Button";
import { isEmpty } from "lodash";
import { Loader, LoadingError } from "@litespace/luna/Loading";
import cn from "classnames";
import { asFullAssetUrl } from "@litespace/luna/backend";
import NewTutor from "@/assets/new-tutor.png";

const NoTutorRatings: React.FC<{ tutorName: string | null }> = ({
tutorName,
}) => {
const intl = useFormatMessage();
return (
<div className="flex gap-[88px] tw-relative items-center justify-center h-[294px] w-full">
<div className="flex tw-relative items-center justify-center h-[294px] w-full gap-[88px]">
<Typography
element="subtitle-1"
weight="bold"
className="text-natural-950 text-center -translate-y-7 max-w-[476px]"
>
{intl("tutor.profile.first-rating", { tutor: tutorName })}
</Typography>
<NewTutor width={292} className="basis-full mt-16 max-w-[292px]" />
<img
src={NewTutor}
width={292}
className="basis-full mt-16 max-w-[292px]"
/>
</div>
);
};
Expand All @@ -41,13 +46,8 @@ const Ratings: React.FC<{ id: number; tutorName: string | null }> = ({
const intl = useFormatMessage();
const ratingsQuery = useFindTutorRatings(id, { page: 1, size: 30 });

const refetchRatings = useCallback(() => {
ratingsQuery.refetch();
}, [ratingsQuery]);

const ratings = useMemo(
() => organizeRatings(ratingsQuery.data?.list, user?.id),
// () => organizeRatings([], user?.id),
[ratingsQuery.data, user]
);

Expand All @@ -63,26 +63,32 @@ const Ratings: React.FC<{ id: number; tutorName: string | null }> = ({
<div className="h-96 flex items-center justify-center">
<LoadingError
error={intl("tutor.profile.error")}
retry={refetchRatings}
retry={ratingsQuery.refetch}
/>
</div>
);

return (
<div className="flex flex-col y-8 py-8 mx-10 gap-10 justify-center">
<div
className={cn(
"flex flex-col justify-center p-8",
isEmpty(ratings) ? "gap-8" : "gap-10"
)}
>
{isEmpty(ratings) ? (
<NoTutorRatings tutorName={tutorName} />
) : (
<div className="grid gap-4 flex-wrap justify-center grid-cols-[repeat(auto-fill,minmax(256px,1fr))]">
{ratings.map((rating) => {
{ratings.map((rating, index) => {
if (
"userId" in rating &&
(rating.feedback || rating.userId === user.id)
)
return (
<TutorRatingCard
key={index}
feedback={rating.feedback}
imageUrl={rating.image}
imageUrl={asFullAssetUrl(rating.image || "")}
rating={rating.value}
studentId={rating.userId}
studentName={rating.name}
Expand All @@ -94,7 +100,12 @@ const Ratings: React.FC<{ id: number; tutorName: string | null }> = ({
if ("ratings" in rating)
return (
<TutorRatingCardGroup
ratings={rating.ratings}
key={index}
ratings={rating.ratings.map((rating) => ({
userId: rating.userId,
name: rating.name,
imageUrl: asFullAssetUrl(rating.image || ""),
}))}
tutorName={tutorName}
value={rating.value}
/>
Expand All @@ -103,12 +114,7 @@ const Ratings: React.FC<{ id: number; tutorName: string | null }> = ({
</div>
)}

<div
className={cn(
"flex gap-10 flex-col items-center justify-center",
isEmpty(ratings) && "-mt-12"
)}
>
<div className={cn("flex gap-10 flex-col items-center justify-center")}>
<Typography
element="subtitle-1"
weight="medium"
Expand Down
2 changes: 1 addition & 1 deletion apps/nova/src/components/TutorProfile/TutorTabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export const TutorTabs: React.FC<{
value={tab}
onValueChange={(value: string) => setTab(value as Tab)}
>
<Tabs.List className="border-b border-natural-300 flex gap-[56px] ">
<Tabs.List className="border-b border-natural-300 flex gap-[56px] px-10 ">
{tabs.map(({ value, label }) => (
<Tabs.Trigger
key={value}
Expand Down
29 changes: 14 additions & 15 deletions apps/nova/src/lib/ratings.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
import { IRating } from "@litespace/types";
import { concat } from "lodash";

const MAX_RATING_COUNT = 8;

export const organizeRatings = (
ratings: IRating.FindTutorRatingsApiResponse["list"] | undefined,
currentUserId: number | undefined
ratings?: IRating.FindTutorRatingsApiResponse["list"],
currentUserId?: number
) => {
if (!ratings) return [];

let currentUserRating: IRating.RateeRating | undefined;
let currentUserRating: IRating.RateeRating | null = null;
const ratingsWithFeedback: IRating.RateeRating[] = [];
const ratingsWithoutFeedback: {
ratings: IRating.RateeRating[];
value: number;
}[] = [];

ratings.forEach((rating) => {
if (rating.userId === currentUserId) {
currentUserRating = rating;
return;
}
if (rating.userId === currentUserId) return (currentUserRating = rating);

if (rating.feedback) ratingsWithFeedback.push(rating);
if (!rating.feedback) {
const ratingGroup = ratingsWithoutFeedback.find(
(r) => r.value === rating.value
(rating) => rating.value === rating.value
);
if (ratingGroup) return ratingGroup.ratings.push(rating);

Expand All @@ -32,11 +33,9 @@ export const organizeRatings = (
}
});

if (currentUserRating)
return [
currentUserRating,
...ratingsWithFeedback,
...ratingsWithoutFeedback,
].slice(0, 8);
return [...ratingsWithFeedback, ...ratingsWithoutFeedback].slice(0, 8);
const otherUsersRatings = [...ratingsWithFeedback, ...ratingsWithoutFeedback];
return concat(currentUserRating || [], otherUsersRatings).slice(
0,
MAX_RATING_COUNT
);
};
2 changes: 1 addition & 1 deletion apps/nova/src/pages/TutorProfile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const TutorProfile: React.FC = () => {
<span className="underline text-brand-700">{tutor.data.name}</span>
</Typography>
</div>
<div className="bg-natural-50 border border-natural-100 shadow-tutor-profile rounded-2xl p-10 mt-6 flex flex-col gap-12">
<div className="bg-natural-50 border border-natural-100 shadow-tutor-profile rounded-2xl mt-6 flex flex-col gap-12">
<TutorProfileCard {...tutor.data} onBook={openDialog} />
<TutorTabs tutor={tutor.data} />
<BookLesson tutorId={tutor.data.id} close={closeDialog} open={open} />
Expand Down
26 changes: 16 additions & 10 deletions packages/luna/src/components/Loading/Loader.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,37 @@
import React from "react";
import { Typography } from "@litespace/luna/Typography";
import cn from "classnames";
import { motion } from "framer-motion";

export const Loader: React.FC<{
text?: string;
variant?: "small" | "large";
}> = ({ text, variant = "large" }) => {
return (
<div className="tw-h-full tw-flex tw-flex-col tw-justify-center tw-items-center tw-gap-4">
<div
<motion.div
animate={{
rotate: [360, 0],
}}
transition={{
repeat: Infinity,
duration: 1,
ease: "linear",
}}
style={{
animationDirection: "reverse",
maskImage:
variant === "large"
? "radial-gradient(circle, transparent 30px, white 16px)"
: "radial-gradient(circle, transparent 25px, white 0px)",
}}
className={cn(
"tw-animate-spin tw-flex tw-items-center tw-relative tw-rounded-full tw-justify-center tw-bg-loader",
"tw-flex tw-items-center tw-relative tw-rounded-full tw-justify-center tw-bg-loader",
{
"tw-w-[64px] tw-h-[64px]": variant === "small",
"tw-w-[80px] tw-h-[80px]": variant === "large",
}
)}
>
<div
className={cn("tw-bg-white tw-rounded-full", {
"tw-w-[48px] tw-h-[48px]": variant === "small",
"tw-w-[60px] tw-h-[60px]": variant === "large",
})}
/>
<div
className={cn(
"tw-bg-background-loader-spinner tw-rounded-full tw-absolute tw-bottom-0 tw-left-1/2 -tw-translate-x-1/2",
Expand All @@ -35,7 +41,7 @@ export const Loader: React.FC<{
}
)}
/>
</div>
</motion.div>

{text ? (
<Typography
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const meta: Meta<TutorRatingCardGroupProps> = {
function makeRating() {
return {
name: faker.person.fullName(),
imageUrl: faker.image.urlPicsumPhotos({ width: 400, height: 400 }),
image: faker.image.urlPicsumPhotos({ width: 400, height: 400 }),
userId: faker.number.int(),
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export const TutorRatingCardGroup: React.FC<TutorRatingCardGroupProps> = ({
<Avatar
alt={orUndefined(rating.name)}
seed={rating.userId.toString()}
src={idx <= 4 ? orUndefined(rating.image) : undefined}
src={idx <= 4 ? orUndefined(rating.imageUrl) : undefined}
/>
) : (
<Typography
Expand Down
2 changes: 1 addition & 1 deletion packages/luna/src/components/TutorFeedback/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export type TutorRatingCardGroupProps = {
/**
* rater profile image url.
*/
image: string | null;
imageUrl: string | null;
}>;
/**
* the rating value that is shared between all users.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export const TutorProfileCard: React.FC<{
);

return (
<div className="tw-flex tw-gap-10 tw-items-center">
<div className="tw-flex tw-gap-10 tw-items-center tw-p-10">
<div className="tw-w-[242px] tw-aspect-square tw-rounded-full tw-overflow-hidden">
<Avatar
src={orUndefined(image)}
Expand Down
6 changes: 3 additions & 3 deletions packages/luna/src/components/VideoPlayer/V2/VideoPlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { CONTAINER_ID, useVideo } from "@/components/VideoPlayer/V2/video";
import Play from "@litespace/assets/Play";
import Pause from "@litespace/assets/Pause";
import SettingsScrew from "@litespace/assets/SettingsScrew";
import Spinner from "@litespace/assets/Spinner";
import ExclaimationMarkCircle from "@litespace/assets/ExclaimationMarkCircle";
import cn from "classnames";
import SettingsMenu from "@/components/VideoPlayer/V2/SettingsMenu";
Expand All @@ -12,6 +11,7 @@ import { useFormatMessage } from "@/hooks";
import { AudioController } from "@/components/VideoPlayer/V2/AudioController";
import { VideoProgressbar } from "@/components/VideoPlayer/V2/VideoProgressbar";
import { PlayButton } from "@/components/VideoPlayer/V2/PlayButton";
import { Loader } from "@/components/Loading";

export const VideoPlayer: React.FC<{ src?: string }> = ({ src }) => {
const intl = useFormatMessage();
Expand Down Expand Up @@ -58,7 +58,7 @@ export const VideoPlayer: React.FC<{ src?: string }> = ({ src }) => {
src={src}
className="tw-w-full tw-h-full data-[ready=true]:tw-cursor-pointer"
/>
{paused && currentTime === 0 ? (
{readyState > 1 && paused && currentTime === 0 ? (
<div className="tw-absolute tw-top-1/2 tw-left-1/2 -tw-translate-x-1/2 -tw-translate-y-1/2">
<PlayButton togglePlay={togglePlay} />
</div>
Expand Down Expand Up @@ -97,7 +97,7 @@ export const VideoPlayer: React.FC<{ src?: string }> = ({ src }) => {
"tw-absolute tw-z-[8] tw-transition-opacity tw-duration-300 tw-top-1/2 tw-left-1/2 -tw-translate-x-1/2 -tw-translate-y-1/2"
)}
>
<Spinner className="tw-animate-spin" />
<Loader variant="large" />
</span>
) : null}
{status === "error" ? (
Expand Down

0 comments on commit 8d9a3f7

Please sign in to comment.