diff --git a/app/(admin)/admin/booking/[id]/page.tsx b/app/(admin)/admin/booking/[id]/page.tsx
index fe60ede..e781e5b 100644
--- a/app/(admin)/admin/booking/[id]/page.tsx
+++ b/app/(admin)/admin/booking/[id]/page.tsx
@@ -389,13 +389,13 @@ export default function AppointmentDetailPage() {
className={`p-4 rounded-xl border ${isDark ? "bg-gray-700/50 border-gray-600" : "bg-gray-50 border-gray-200"}`}
>
-
+
{match.day_name || "Unknown Day"}
{formatShortDate(match.date || match.date_obj || "")}
-
+
{match.available_slots && Array.isArray(match.available_slots) && match.available_slots.length > 0 && (
@@ -408,19 +408,19 @@ export default function AppointmentDetailPage() {
};
const normalizedSlot = String(slot).toLowerCase().trim();
return (
-
+ >
{timeSlotLabels[normalizedSlot] || slot}
-
+
);
})}
-
- )}
+
+ )}
))}
-
+
)}
diff --git a/components/ContactSection.tsx b/components/ContactSection.tsx
index 77381d3..0e08023 100644
--- a/components/ContactSection.tsx
+++ b/components/ContactSection.tsx
@@ -2,7 +2,7 @@
import { motion, useInView } from "framer-motion";
import { useRef, useState } from "react";
-import { Send, Loader2 } from "lucide-react";
+import { Send } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
@@ -29,20 +29,15 @@ export function ContactSection() {
setIsSubmitting(true);
try {
- await submitContactForm({
- name: formData.name,
- email: formData.email,
- phone: formData.phone,
- message: formData.message,
- });
-
+ await submitContactForm(formData);
toast.success("Message Sent Successfully", {
description: "Thank you for reaching out. We'll get back to you soon!",
});
setFormData({ name: "", email: "", phone: "", message: "" });
} catch (error) {
- toast.error("Failed to Send Message", {
- description: error instanceof Error ? error.message : "Please try again later.",
+ const errorMessage = error instanceof Error ? error.message : "Failed to send message. Please try again.";
+ toast.error("Error Sending Message", {
+ description: errorMessage,
});
} finally {
setIsSubmitting(false);
@@ -227,17 +222,8 @@ export function ContactSection() {
className="w-full cursor-pointer bg-gradient-to-r from-rose-500 to-pink-600 text-white transition-all hover:from-rose-600 hover:to-pink-700 hover:scale-[1.02] disabled:opacity-50 disabled:cursor-not-allowed"
size="lg"
>
- {isSubmitting ? (
- <>
-
- Sending...
- >
- ) : (
- <>
-
- Send Message
- >
- )}
+
+ {isSubmitting ? "Sending..." : "Send Message"}
diff --git a/lib/actions/auth.ts b/lib/actions/auth.ts
index 06c2d54..f1de991 100644
--- a/lib/actions/auth.ts
+++ b/lib/actions/auth.ts
@@ -9,6 +9,7 @@ import type {
ResetPasswordInput,
TokenRefreshInput,
UpdateProfileInput,
+ ContactInput,
} from "@/lib/schema/auth";
import type { AuthResponse, ApiError, AuthTokens, User } from "@/lib/models/auth";
@@ -439,67 +440,18 @@ export async function updateProfile(input: UpdateProfileInput): Promise {
throw new Error("Invalid profile response format");
}
-export interface ContactFormInput {
- name: string;
- email: string;
- phone: string;
- message: string;
-}
-
-export interface ContactFormResponse {
- message?: string;
- success?: boolean;
-}
-
/**
- * Submit contact form (public endpoint - no authentication required)
+ * Submit contact form
*/
-export async function submitContactForm(
- data: ContactFormInput
-): Promise {
- try {
- const response = await fetch(API_ENDPOINTS.auth.contact, {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- "Accept": "application/json",
- },
- body: JSON.stringify({
- name: data.name.trim(),
- email: data.email.trim().toLowerCase(),
- phone: data.phone.trim(),
- message: data.message.trim(),
- }),
- });
+export async function submitContactForm(input: ContactInput): Promise<{ message: string }> {
+ const response = await fetch(API_ENDPOINTS.auth.contact, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify(input),
+ });
- // Handle empty responses
- const contentType = response.headers.get("content-type");
- let responseData: any;
-
- if (contentType && contentType.includes("application/json")) {
- const text = await response.text();
- responseData = text ? JSON.parse(text) : {};
- } else {
- const text = await response.text();
- responseData = text ? { message: text } : {};
- }
-
- if (!response.ok) {
- // Check for authentication error specifically
- if (response.status === 401 || response.status === 403) {
- throw new Error("Contact form submission requires authentication. Please contact support if this is a public form.");
- }
-
- const error: ApiError = responseData;
- throw new Error(extractErrorMessage(error));
- }
-
- return responseData;
- } catch (error) {
- if (error instanceof Error) {
- throw error;
- }
- throw new Error("Failed to submit contact form. Please try again later.");
- }
+ return handleResponse<{ message: string }>(response);
}
diff --git a/lib/schema/auth.ts b/lib/schema/auth.ts
index f77813f..b7b7f44 100644
--- a/lib/schema/auth.ts
+++ b/lib/schema/auth.ts
@@ -87,3 +87,13 @@ export const updateProfileSchema = z.object({
export type UpdateProfileInput = z.infer;
+// Contact Form Schema
+export const contactSchema = z.object({
+ name: z.string().min(1, "Name is required"),
+ email: z.string().email("Invalid email address"),
+ phone: z.string().min(1, "Phone number is required"),
+ message: z.string().min(1, "Message is required"),
+});
+
+export type ContactInput = z.infer;
+