Skip to content
Closed
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
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react";
import { useNavigate } from "react-router-dom";
import { useLocation, useNavigate } from "react-router-dom";
import { authRoutesVariables } from "../../../router/routesVariables/pathVariables";
import SignInIcon from "../../icons/SignInIcon";
import Cross from "../../icons/Cross";
Expand All @@ -11,10 +11,14 @@ interface Props {

export const SignInConfirmation: React.FC<Props> = ({ isOpen, onClose }) => {
const navigate = useNavigate();
const location = useLocation();

const handleSignIn = () => {
const redirectTo = `${location.pathname}${location.search}${location.hash}`;
onClose();
navigate(authRoutesVariables.loginStudent);
navigate(authRoutesVariables.loginStudent, {
state: { redirectTo },
});
};

if (!isOpen) return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useState, useMemo } from "react";
import { useParams } from "react-router-dom";
import { Calendar } from "./Calendar/Calendar";
import { Time } from "./Time/Time";
import { TeacherType } from "../../../api/teacher/teacher.type";
Expand All @@ -13,15 +14,81 @@ interface TeacherScheduleProps {
teacher?: TeacherType;
}

type PendingBookingIntent = {
teacherId: string;
selectedDate: string;
selectedTime: string;
selectedSubject: string;
selectedLevel: string;
description: string;
};

const PENDING_BOOKING_INTENT_KEY = "pending-booking-intent";

export default function TeacherSchedule({ teacher }: TeacherScheduleProps) {
const [selectedDate, setSelectedDate] = useState<Date | null>(null);
const [showTimeAndBook, setShowTimeAndBook] = useState<boolean>(false);
const [selectedSubject, setSelectedSubject] = useState<string>("");
const [selectedLevel, setSelectedLevel] = useState<string>("");
const [selectedTime, setSelectedTime] = useState<string | null>(null);
const [description, setDescription] = useState<string>("");
const params = useParams<{ id: string }>();

const [initialPendingBooking] = useState<{
selectedDate: Date;
selectedTime: string;
selectedSubject: string;
selectedLevel: string;
description: string;
} | null>(() => {
const routeTeacherId = params.id;
const raw = sessionStorage.getItem(PENDING_BOOKING_INTENT_KEY);

if (!routeTeacherId || !raw) {
return null;
}

try {
const pending: PendingBookingIntent = JSON.parse(raw);
if (pending.teacherId !== routeTeacherId) {
return null;
}

const restoredDate = new Date(pending.selectedDate);
if (Number.isNaN(restoredDate.getTime())) {
sessionStorage.removeItem(PENDING_BOOKING_INTENT_KEY);
return null;
}

sessionStorage.removeItem(PENDING_BOOKING_INTENT_KEY);

return {
selectedDate: restoredDate,
selectedTime: pending.selectedTime,
selectedSubject: pending.selectedSubject,
selectedLevel: pending.selectedLevel,
description: pending.description,
};
} catch {
sessionStorage.removeItem(PENDING_BOOKING_INTENT_KEY);
return null;
}
});

const [selectedDate, setSelectedDate] = useState<Date | null>(
initialPendingBooking?.selectedDate ?? null,
);
const [showTimeAndBook, setShowTimeAndBook] = useState<boolean>(
Boolean(initialPendingBooking),
);
const [selectedSubject, setSelectedSubject] = useState<string>(
initialPendingBooking?.selectedSubject ?? "",
);
const [selectedLevel, setSelectedLevel] = useState<string>(
initialPendingBooking?.selectedLevel ?? "",
);
const [selectedTime, setSelectedTime] = useState<string | null>(
initialPendingBooking?.selectedTime ?? null,
);
const [description, setDescription] = useState<string>(
initialPendingBooking?.description ?? "",
);
const [showSubjectLevelSelection, setShowSubjectLevelSelection] =
useState<boolean>(false);
useState<boolean>(Boolean(initialPendingBooking?.selectedTime));

const { open: openModal } = useModalStore();
const user = useAuthSessionStore((state) => state.user);
Expand Down Expand Up @@ -102,6 +169,20 @@ export default function TeacherSchedule({ teacher }: TeacherScheduleProps) {

const handleTimeSelection = (time: string): void => {
if (!isAuthenticated) {
if (teacher?.id && selectedDate) {
const pending: PendingBookingIntent = {
teacherId: teacher.id,
selectedDate: selectedDate.toISOString(),
selectedTime: time,
selectedSubject,
selectedLevel,
description,
};
sessionStorage.setItem(
PENDING_BOOKING_INTENT_KEY,
JSON.stringify(pending),
);
}
openModal("signIn");
return;
}
Expand Down
9 changes: 7 additions & 2 deletions client/src/features/auth/mutations/useLoginMutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,30 @@ import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useAuthSessionStore } from "../../../store/authSession.store";
import { loginApi } from "../../../api/auth/auth.api";
import { queryKeys } from "../../queryKeys";
import { useNavigate } from "react-router-dom";
import { useLocation, useNavigate } from "react-router-dom";
import { getErrorMessage } from "../../../util/ErrorUtil";
import { LoginFinalType } from "../../../api/auth/types";
import { useNotificationStore } from "../../../store/notification.store";

export function useLoginMutation() {
const qc = useQueryClient();
const navigate = useNavigate();
const location = useLocation();
const setAccessToken = useAuthSessionStore((s) => s.setAccessToken);
const success = useNotificationStore((s) => s.success);
const notifyError = useNotificationStore((s) => s.error);

return useMutation({
mutationFn: (data: LoginFinalType) => loginApi(data),
onSuccess: async ({ accessToken }) => {
const redirectTo =
((location.state as { redirectTo?: string } | null)?.redirectTo ??
"/") ||
"/";
setAccessToken(accessToken);
success("Successfully logged in");
localStorage.setItem("hadSession", "1");
navigate("/", { replace: true });
navigate(redirectTo, { replace: true });
await qc.invalidateQueries({ queryKey: queryKeys.me });
},
onError: (error) => {
Expand Down
Loading