Refactor Login and Signup components to utilize Suspense for improved loading states. Update error handling in LoginDialog to reference issues instead of errors for better validation feedback. Enhance appointment error handling by casting response data to unknown before extracting error messages.

This commit is contained in:
iamkiddy 2025-11-24 16:38:09 +00:00
parent eec3976f94
commit 7db02adbd7
4 changed files with 41 additions and 17 deletions

View File

@ -1,6 +1,6 @@
"use client"; "use client";
import { useState, useEffect } from "react"; import { useState, useEffect, Suspense } from "react";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { import {
@ -26,7 +26,7 @@ import { toast } from "sonner";
type Step = "login" | "signup" | "verify"; type Step = "login" | "signup" | "verify";
export default function Login() { function LoginContent() {
const { theme } = useAppTheme(); const { theme } = useAppTheme();
const isDark = theme === "dark"; const isDark = theme === "dark";
const [step, setStep] = useState<Step>("login"); const [step, setStep] = useState<Step>("login");
@ -794,3 +794,15 @@ export default function Login() {
</div> </div>
); );
} }
export default function Login() {
return (
<Suspense fallback={
<div className="min-h-screen flex items-center justify-center">
<Loader2 className="w-8 h-8 animate-spin text-rose-600" />
</div>
}>
<LoginContent />
</Suspense>
);
}

View File

@ -1,6 +1,6 @@
"use client"; "use client";
import { useState, useEffect } from "react"; import { useState, useEffect, Suspense } from "react";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { import {
@ -17,7 +17,7 @@ import { useAuth } from "@/hooks/useAuth";
import { registerSchema, verifyOtpSchema, type RegisterInput, type VerifyOtpInput } from "@/lib/schema/auth"; import { registerSchema, verifyOtpSchema, type RegisterInput, type VerifyOtpInput } from "@/lib/schema/auth";
import { toast } from "sonner"; import { toast } from "sonner";
export default function Signup() { function SignupContent() {
const { theme } = useAppTheme(); const { theme } = useAppTheme();
const isDark = theme === "dark"; const isDark = theme === "dark";
const [showPassword, setShowPassword] = useState(false); const [showPassword, setShowPassword] = useState(false);
@ -456,3 +456,15 @@ export default function Signup() {
); );
} }
export default function Signup() {
return (
<Suspense fallback={
<div className="min-h-screen flex items-center justify-center">
<Loader2 className="w-8 h-8 animate-spin text-rose-600" />
</div>
}>
<SignupContent />
</Suspense>
);
}

View File

@ -54,7 +54,7 @@ export function LoginDialog({ open, onOpenChange, onLoginSuccess }: LoginDialogP
// Validate form // Validate form
const validation = loginSchema.safeParse(loginData); const validation = loginSchema.safeParse(loginData);
if (!validation.success) { if (!validation.success) {
const firstError = validation.error.errors[0]; const firstError = validation.error.issues[0];
setError(firstError.message); setError(firstError.message);
return; return;
} }
@ -82,7 +82,7 @@ export function LoginDialog({ open, onOpenChange, onLoginSuccess }: LoginDialogP
// Validate form // Validate form
const validation = registerSchema.safeParse(signupData); const validation = registerSchema.safeParse(signupData);
if (!validation.success) { if (!validation.success) {
const firstError = validation.error.errors[0]; const firstError = validation.error.issues[0];
setError(firstError.message); setError(firstError.message);
return; return;
} }

View File

@ -62,7 +62,7 @@ export async function createAppointment(
const data: AppointmentResponse = await response.json(); const data: AppointmentResponse = await response.json();
if (!response.ok) { if (!response.ok) {
const errorMessage = extractErrorMessage(data as ApiError); const errorMessage = extractErrorMessage(data as unknown as ApiError);
throw new Error(errorMessage); throw new Error(errorMessage);
} }
@ -90,7 +90,7 @@ export async function getAvailableDates(): Promise<string[]> {
const data: AvailableDatesResponse | string[] = await response.json(); const data: AvailableDatesResponse | string[] = await response.json();
if (!response.ok) { if (!response.ok) {
const errorMessage = extractErrorMessage(data as ApiError); const errorMessage = extractErrorMessage(data as unknown as ApiError);
throw new Error(errorMessage); throw new Error(errorMessage);
} }
@ -124,7 +124,7 @@ export async function listAppointments(email?: string): Promise<Appointment[]> {
const data = await response.json(); const data = await response.json();
if (!response.ok) { if (!response.ok) {
const errorMessage = extractErrorMessage(data as ApiError); const errorMessage = extractErrorMessage(data as unknown as ApiError);
throw new Error(errorMessage); throw new Error(errorMessage);
} }
@ -162,7 +162,7 @@ export async function getUserAppointments(): Promise<Appointment[]> {
const data = await response.json(); const data = await response.json();
if (!response.ok) { if (!response.ok) {
const errorMessage = extractErrorMessage(data as ApiError); const errorMessage = extractErrorMessage(data as unknown as ApiError);
throw new Error(errorMessage); throw new Error(errorMessage);
} }
@ -200,7 +200,7 @@ export async function getAppointmentDetail(id: string): Promise<Appointment> {
const data: AppointmentResponse = await response.json(); const data: AppointmentResponse = await response.json();
if (!response.ok) { if (!response.ok) {
const errorMessage = extractErrorMessage(data as ApiError); const errorMessage = extractErrorMessage(data as unknown as ApiError);
throw new Error(errorMessage); throw new Error(errorMessage);
} }
@ -234,7 +234,7 @@ export async function scheduleAppointment(
const data: AppointmentResponse = await response.json(); const data: AppointmentResponse = await response.json();
if (!response.ok) { if (!response.ok) {
const errorMessage = extractErrorMessage(data as ApiError); const errorMessage = extractErrorMessage(data as unknown as ApiError);
throw new Error(errorMessage); throw new Error(errorMessage);
} }
@ -268,7 +268,7 @@ export async function rejectAppointment(
const data: AppointmentResponse = await response.json(); const data: AppointmentResponse = await response.json();
if (!response.ok) { if (!response.ok) {
const errorMessage = extractErrorMessage(data as ApiError); const errorMessage = extractErrorMessage(data as unknown as ApiError);
throw new Error(errorMessage); throw new Error(errorMessage);
} }
@ -298,7 +298,7 @@ export async function getAdminAvailability(): Promise<AdminAvailability> {
const data: AdminAvailability = await response.json(); const data: AdminAvailability = await response.json();
if (!response.ok) { if (!response.ok) {
const errorMessage = extractErrorMessage(data as ApiError); const errorMessage = extractErrorMessage(data as unknown as ApiError);
throw new Error(errorMessage); throw new Error(errorMessage);
} }
@ -327,7 +327,7 @@ export async function updateAdminAvailability(
const data: AdminAvailability = await response.json(); const data: AdminAvailability = await response.json();
if (!response.ok) { if (!response.ok) {
const errorMessage = extractErrorMessage(data as ApiError); const errorMessage = extractErrorMessage(data as unknown as ApiError);
throw new Error(errorMessage); throw new Error(errorMessage);
} }
@ -353,7 +353,7 @@ export async function getAppointmentStats(): Promise<AppointmentStats> {
const data: AppointmentStats = await response.json(); const data: AppointmentStats = await response.json();
if (!response.ok) { if (!response.ok) {
const errorMessage = extractErrorMessage(data as ApiError); const errorMessage = extractErrorMessage(data as unknown as ApiError);
throw new Error(errorMessage); throw new Error(errorMessage);
} }
@ -379,7 +379,7 @@ export async function getJitsiMeetingInfo(id: string): Promise<JitsiMeetingInfo>
const data: JitsiMeetingInfo = await response.json(); const data: JitsiMeetingInfo = await response.json();
if (!response.ok) { if (!response.ok) {
const errorMessage = extractErrorMessage(data as ApiError); const errorMessage = extractErrorMessage(data as unknown as ApiError);
throw new Error(errorMessage); throw new Error(errorMessage);
} }