Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions client/src/components/appointmentCard/AppointmentJoinButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@ export const AppointmentJoinButton = ({
isPast,
onDelete,
}: AppointmentJoinButtonProps) => {
const openCallTab = () => {
if (!videoCall) return;

const opened = window.open(videoCall, "_blank");
if (!opened) {
window.location.href = videoCall;
}
};

if (isPast && onDelete) {
return (
<div className="flex items-center justify-center min-[480px]:ml-auto">
Expand All @@ -32,10 +41,8 @@ export const AppointmentJoinButton = ({
<div className="flex items-center justify-center min-[480px]:ml-auto">
{canJoin ? (
<Button
as="a"
href={videoCall}
target="_blank"
rel="noopener noreferrer"
as="button"
onClick={openCallTab}
variant="link"
className="text-white underline text-[14px] md:text-[16px] hover:text-gray-300"
>
Expand Down
58 changes: 50 additions & 8 deletions client/src/components/clientsDashboard/MyLessonsSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,70 @@ import { PageTitle } from "../pageTitle/PageTitle";
import { FindTeachersCard } from "./FindTeachersCard";
import { useStudentAppointmentsQuery } from "../../features/appointments/query/useAppointmentsQuery";
import { useAuthSessionStore } from "../../store/authSession.store";
import { useAppointmentTime } from "../../features/appointments/hooks/useAppointmentTime";
import { isInternalVideoCallLink } from "../appointmentCard/appointmentCard.utils";
import { Button } from "../ui/button/Button";
import {
studentBase,
studentPrivatesRoutesVariables,
} from "../../router/routesVariables/pathVariables";
import { joinPath } from "../../util/joinPath.util";

export const MyLessonsSection = () => {
const user = useAuthSessionStore((state) => state.user);
const { data, isLoading, error } = useStudentAppointmentsQuery(
user?.id || "",
);
const { isPastAppointment } = useAppointmentTime();
const studentDashboardPath = joinPath(
studentBase,
studentPrivatesRoutesVariables.dashboard,
);

const appointments = data?.appointments || [];

const today = new Date().toISOString().split("T")[0];
const todayAppointments = appointments.filter(
(appointment) => appointment.date === today,
);
const openCallTab = (url: string) => {
const opened = window.open(url, "_blank");
if (!opened) {
window.location.href = url;
}
};

const tableRows = todayAppointments.map((appointment) => {
const isPast = isPastAppointment(appointment.date, appointment.time);
const callLink = appointment.videoCall ?? "";
const canJoin = !isPast && isInternalVideoCallLink(callLink) && callLink;
const videoCallHref = canJoin
? `${callLink}${callLink.includes("?") ? "&" : "?"}returnTo=${encodeURIComponent(studentDashboardPath)}`
: "";

const tableRows = todayAppointments.map((appointment) => ({
id: appointment.id,
checked: appointment.status === "approved",
lesson: appointment.lesson,
teacher: appointment.teacherName || appointment.teacherId || "N/A",
price: appointment.price,
videoCall: appointment.videoCall || "Join",
}));
return {
id: appointment.id,
checked: appointment.status === "approved",
lesson: appointment.lesson,
teacher: appointment.teacherName || appointment.teacherId || "N/A",
price: appointment.price,
isPast,
videoCall: canJoin ? (
<Button
as="button"
onClick={() => openCallTab(videoCallHref)}
variant="link"
className="text-white underline text-[14px] md:text-[16px] hover:text-gray-300"
>
Join
</Button>
) : isPast ? (
"Past"
) : (
"N/A"
),
};
});

return (
<div>
Expand Down
37 changes: 37 additions & 0 deletions client/src/components/icons/EraserIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import {
type Ref,
type SVGProps,
forwardRef,
memo,
type MemoExoticComponent,
type ForwardRefExoticComponent,
} from "react";

const EraserIconComponent = (
props: SVGProps<SVGSVGElement>,
ref: Ref<SVGSVGElement>,
) => (
<svg
width={24}
height={24}
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
ref={ref}
{...props}
>
<path
d="M19 19.9998H8.5L4.29 15.6998C4.10375 15.5125 3.99921 15.259 3.99921 14.9948C3.99921 14.7306 4.10375 14.4772 4.29 14.2898L14.29 4.28982C14.4774 4.10357 14.7308 3.99902 14.995 3.99902C15.2592 3.99902 15.5126 4.10357 15.7 4.28982L20.7 9.28982C20.8863 9.47718 20.9908 9.73063 20.9908 9.99482C20.9908 10.259 20.8863 10.5125 20.7 10.6998L11.5 19.9998M18 13.2998L11.7 6.99982"
stroke="currentColor"
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);

const EraserIcon = memo(forwardRef(EraserIconComponent)) as MemoExoticComponent<
ForwardRefExoticComponent<SVGProps<SVGSVGElement>>
>;

export default EraserIcon;
37 changes: 37 additions & 0 deletions client/src/components/icons/PenIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import {
type Ref,
type SVGProps,
forwardRef,
memo,
type MemoExoticComponent,
type ForwardRefExoticComponent,
} from "react";

const PenIconComponent = (
props: SVGProps<SVGSVGElement>,
ref: Ref<SVGSVGElement>,
) => (
<svg
width={24}
height={24}
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
ref={ref}
{...props}
>
<path
d="M13.5 6.50006L17.5 10.5001M4 20.0001H8L18.5 9.50006C19.0304 8.96963 19.3284 8.2502 19.3284 7.50006C19.3284 6.74991 19.0304 6.03049 18.5 5.50006C17.9696 4.96963 17.2501 4.67163 16.5 4.67163C15.7499 4.67163 15.0304 4.96963 14.5 5.50006L4 16.0001V20.0001Z"
stroke="currentColor"
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);

const PenIcon = memo(forwardRef(PenIconComponent)) as MemoExoticComponent<
ForwardRefExoticComponent<SVGProps<SVGSVGElement>>
>;

export default PenIcon;
37 changes: 37 additions & 0 deletions client/src/components/icons/WhiteboardClosedIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import {
type Ref,
type SVGProps,
forwardRef,
memo,
type MemoExoticComponent,
type ForwardRefExoticComponent,
} from "react";

const WhiteboardClosedIconComponent = (
props: SVGProps<SVGSVGElement>,
ref: Ref<SVGSVGElement>,
) => (
<svg
width={24}
height={24}
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
ref={ref}
{...props}
>
<path
d="M8 19H5C4.46957 19 3.96086 18.7893 3.58579 18.4142C3.21071 18.0391 3 17.5304 3 17V7C3 6.46957 3.21071 5.96086 3.58579 5.58579C3.96086 5.21071 4.46957 5 5 5M9 5H19C19.5304 5 20.0391 5.21071 20.4142 5.58579C20.7893 5.96086 21 6.46957 21 7V17M17 17V18C17 18.2652 16.8946 18.5196 16.7071 18.7071C16.5196 18.8946 16.2652 19 16 19H12C11.7348 19 11.4804 18.8946 11.2929 18.7071C11.1054 18.5196 11 18.2652 11 18V17C11 16.7348 11.1054 16.4804 11.2929 16.2929C11.4804 16.1054 11.7348 16 12 16H16M3 3L21 21"
stroke="currentColor"
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);

const WhiteboardClosedIcon = memo(
forwardRef(WhiteboardClosedIconComponent),
) as MemoExoticComponent<ForwardRefExoticComponent<SVGProps<SVGSVGElement>>>;

export default WhiteboardClosedIcon;
37 changes: 37 additions & 0 deletions client/src/components/icons/WhiteboardOpenIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import {
type Ref,
type SVGProps,
forwardRef,
memo,
type MemoExoticComponent,
type ForwardRefExoticComponent,
} from "react";

const WhiteboardOpenIconComponent = (
props: SVGProps<SVGSVGElement>,
ref: Ref<SVGSVGElement>,
) => (
<svg
width={24}
height={24}
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
ref={ref}
{...props}
>
<path
d="M8 19H5C4.46957 19 3.96086 18.7893 3.58579 18.4142C3.21071 18.0391 3 17.5304 3 17V7C3 6.46957 3.21071 5.96086 3.58579 5.58579C3.96086 5.21071 4.46957 5 5 5H19C19.5304 5 20.0391 5.21071 20.4142 5.58579C20.7893 5.96086 21 6.46957 21 7V18C21 18.2652 20.8946 18.5196 20.7071 18.7071C20.5196 18.8946 20.2652 19 20 19M11 17C11 16.7348 11.1054 16.4804 11.2929 16.2929C11.4804 16.1054 11.7348 16 12 16H16C16.2652 16 16.5196 16.1054 16.7071 16.2929C16.8946 16.4804 17 16.7348 17 17V18C17 18.2652 16.8946 18.5196 16.7071 18.7071C16.5196 18.8946 16.2652 19 16 19H12C11.7348 19 11.4804 18.8946 11.2929 18.7071C11.1054 18.5196 11 18.2652 11 18V17Z"
stroke="currentColor"
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);

const WhiteboardOpenIcon = memo(
forwardRef(WhiteboardOpenIconComponent),
) as MemoExoticComponent<ForwardRefExoticComponent<SVGProps<SVGSVGElement>>>;

export default WhiteboardOpenIcon;
3 changes: 2 additions & 1 deletion client/src/components/table/LessonRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ const LessonRow = ({
rel="noopener noreferrer"
className={`underline ${isPastLesson ? "text-gray-500" : "text-[#B9B9B9]"} hover:text-[#7186FF]`}
>
{(data.linkText as string) || "Join"}
{(data.linkText as string) ||
(data.student ? "Start call" : "Join")}
</a>
) : column.key === "videoCall" ? (
<span
Expand Down
Loading
Loading