"use client" import * as React from "react" import { zodResolver } from "@hookform/resolvers/zod" import { useForm } from "react-hook-form" import { z } from "zod" import { toast } from "@/hooks/use-toast" import { Button } from "@/components/ui/button" import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from "@/components/ui/form" import { Input } from "@/components/ui/input" import { findUserById } from "@/lib/admin-users/service" import { useSession } from "next-auth/react"; import { updateUserProfileImage } from "@/lib/users/service" const accountFormSchema = z.object({ name: z .string() .min(2, { message: "Name must be at least 2 characters.", }) .max(30, { message: "Name must not be longer than 30 characters.", }), email: z.string().email(), company: z .string() .min(2, { message: "Name must be at least 2 characters.", }) .max(30, { message: "Name must not be longer than 30 characters.", }), imageFile: z.any().optional(), }) type AccountFormValues = z.infer export function AccountForm() { const { data: session } = useSession(); const userId = session?.user.id || "" const [previewUrl, setPreviewUrl] = React.useState(null) const form = useForm({ resolver: zodResolver(accountFormSchema), defaultValues: { name: "", company: "", email: "", imageFile: null, }, }) // Fetch data in useEffect React.useEffect(() => { console.log("Form state changed: ", form.getValues()); async function fetchUser() { try { const data = await findUserById(Number(userId)) if (data) { // Also reset the form's default values form.reset({ name: data.user_name || "", company: data.company_name || "", email: data.user_email || "", imageFile: data.user_image, // no file to begin with }) } } catch (error) { console.error("Failed to fetch user data:", error) } } if (userId) { fetchUser() } }, [userId, form]) async function onSubmit(data: AccountFormValues) { // RHF가 추적한 dirtyFields를 가져옵니다. const { dirtyFields } = form.formState // 변경된 필드가 전혀 없다면 => 업데이트 스킵 if (Object.keys(dirtyFields).length === 0) { toast({ title: "No changes", description: "Nothing to update", }) return } // 바뀐 파일만 업로드 let imageFile: File | null = null if (dirtyFields.imageFile && data.imageFile && data.imageFile.length > 0) { // 새로 업로드한 파일 imageFile = data.imageFile[0] } // FormData 생성 const formData = new FormData() formData.append("userId", userId) formData.append("name", data.name) formData.append("company", data.company) formData.append("email", data.email) if (imageFile) { formData.append("file", imageFile) } try { // 서버 액션(또는 API) 호출 await updateUserProfileImage(formData) toast({ title: "Account updated", description: "User updated successfully!", }) } catch (error: any) { toast({ title: "Error", description: `Error: ${error.message ?? error}`, variant: "destructive", }) } } return (
( Name This is the name that will be displayed on your profile and in emails. )} /> ( Email This is the email that will be used on login. If you want change it, please be careful. )} /> ( Company This is the name that will be displayed on your profile and in emails. )} /> {/* 이미지 업로드 */} ( Profile Image
{ field.onChange(e.target.files) if (e.target.files && e.target.files.length > 0) { // 로컬 미리보기 URL const file = e.target.files[0] const url = URL.createObjectURL(file) setPreviewUrl(url) } }} /> {previewUrl ? ( Local Preview ) : ( typeof field.value === "string" && field.value && ( Server Image ) )}
Upload your profile image.
)} /> ) }