import React, { useEffect } from "react"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; import { useMutation } from "@tanstack/react-query"; import { apiRequest, queryClient } from "@/lib/queryClient"; import { useAuth } from "@/hooks/use-auth"; import { useToast } from "@/hooks/use-toast"; import { updateUserProfileSchema } from "@shared/schema"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogFooter, } from "@/components/ui/dialog"; import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from "@/components/ui/form"; import { Input } from "@/components/ui/input"; import { Textarea } from "@/components/ui/textarea"; import { Button } from "@/components/ui/button"; import { Loader2 } from "lucide-react"; // Create a form schema const profileFormSchema = z.object({ fullName: z.string().optional(), location: z.string().optional(), interests: z.array(z.string()).optional(), interestsInput: z.string().optional(), // For input field value only, not submitted profession: z.string().optional(), pets: z.string().optional(), systemContext: z.string().optional(), }); type ProfileFormValues = z.infer; interface UserSettingsModalProps { isOpen: boolean; onClose: () => void; } export default function UserSettingsModal({ isOpen, onClose, }: UserSettingsModalProps) { const { user } = useAuth(); const { toast } = useToast(); // Create form with default values const form = useForm({ resolver: zodResolver(profileFormSchema), defaultValues: { fullName: "", location: "", interests: [], interestsInput: "", profession: "", pets: "", systemContext: "", }, }); // Update form when user data changes useEffect(() => { if (user) { // Convert interests array to comma-separated string for display const interestsString = user.interests?.join(", ") || ""; form.reset({ fullName: user.fullName || "", location: user.location || "", interests: user.interests || [], interestsInput: interestsString, profession: user.profession || "", pets: user.pets || "", systemContext: user.systemContext || "", }); } }, [user, form]); const updateProfileMutation = useMutation({ mutationFn: async (data: ProfileFormValues) => { const res = await apiRequest("PATCH", "/api/user/profile", data); if (!res.ok) { const errorData = await res.json(); throw new Error(errorData.message || "Failed to update profile"); } return await res.json(); }, onSuccess: (updatedUser) => { queryClient.setQueryData(["/api/user"], updatedUser); toast({ title: "Profile updated", description: "Your profile has been updated successfully.", }); onClose(); }, onError: (error: Error) => { toast({ title: "Update failed", description: error.message, variant: "destructive", }); }, }); const onSubmit = async (data: ProfileFormValues) => { // Create a copy of the data object without interestsInput const { interestsInput, ...submitData } = data; // Submit data without the temporary interestsInput field await updateProfileMutation.mutateAsync(submitData); }; // Convert string to array for interests field if needed const handleInterestsChange = (e: React.ChangeEvent) => { const value = e.target.value; // Just store the input value as is, don't process it yet form.setValue("interestsInput", value); // Process for the actual interests field that gets submitted const interestsArray = value .split(",") .map((item) => item.trim()) .filter((item) => item !== ""); form.setValue("interests", interestsArray); }; return ( !open && onClose()}> User Settings Update your profile information and AI assistant preferences
{/* Profile Information Section */}

Profile Information

( Full Name )} /> ( Location )} /> ( Profession )} /> ( Interests Enter your interests separated by commas )} /> ( Pets )} /> {/* AI Assistant Preferences Section */}

AI Assistant Preferences

( Additional Information