jaecoo-kelapagading/components/form/agent/update-agent-form.tsx

272 lines
7.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { Checkbox } from "@/components/ui/checkbox";
import { Button } from "@/components/ui/button";
import { getAgentById, updateAgent } from "@/service/agent";
import { useRouter } from "next/navigation";
import Swal from "sweetalert2";
import withReactContent from "sweetalert2-react-content";
import { X } from "lucide-react";
type AgentFormValues = {
fullName: string;
job_title: string;
position: string;
phone: string;
roles: string[];
};
const AGENT_TYPES = ["After Sales", "Sales", "Spv", "Branch Manager"];
export default function UpdateAgentForm({ id }: { id: number }) {
const router = useRouter();
const MySwal = withReactContent(Swal);
const [loading, setLoading] = useState(true);
const [file, setFile] = useState<File | null>(null);
const [preview, setPreview] = useState<string | null>(null);
const [agentData, setAgentData] = useState<any>(null);
const form = useForm<AgentFormValues>({
defaultValues: {
fullName: "",
position: "",
phone: "",
roles: [],
},
});
/* ================= FETCH DATA ================= */
useEffect(() => {
async function fetchData() {
try {
const res = await getAgentById(id);
const agent = res?.data?.data;
if (!agent) return;
setAgentData(agent);
form.reset({
fullName: agent.name,
job_title: agent.job_title,
phone: agent.phone,
roles: Array.isArray(agent.agent_type) ? agent.agent_type : [],
});
// ✅ FOTO DARI API
setPreview(agent.profile_picture_url ?? null);
} catch (error) {
console.error("FETCH AGENT ERROR:", error);
} finally {
setLoading(false);
}
}
fetchData();
}, [id, form]);
/* ================= FILE HANDLER ================= */
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const selected = e.target.files?.[0];
if (!selected) return;
setFile(selected);
setPreview(URL.createObjectURL(selected));
};
const handleRemoveFile = () => {
setFile(null);
setPreview(agentData?.profile_picture_url ?? null);
};
/* ================= SUBMIT ================= */
const onSubmit = async (data: AgentFormValues) => {
try {
const formData = new FormData();
formData.append("name", data.fullName);
formData.append("job_title", data.job_title);
formData.append("phone", data.phone);
// ✅ MULTI agent_type
formData.append("agent_type", JSON.stringify(data.roles));
if (file) {
formData.append("file", file);
}
// DEBUG
for (const pair of formData.entries()) {
console.log(pair[0], pair[1]);
}
await updateAgent(id, formData);
MySwal.fire({
title: "Berhasil",
text: "Data agen berhasil diperbarui",
icon: "success",
}).then(() => router.push("/admin/agent"));
} catch (error) {
console.error("UPDATE AGENT ERROR:", error);
}
};
if (loading) return <p className="p-6">Loading...</p>;
return (
<div className="bg-white p-6 rounded-lg shadow-sm">
<h2 className="text-2xl font-bold text-teal-800 mb-6">Edit Agen</h2>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
{/* BASIC INFO */}
<div className="grid md:grid-cols-3 gap-4">
<FormField
control={form.control}
name="fullName"
render={({ field }) => (
<FormItem>
<FormLabel>Nama Lengkap</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="job_title"
render={({ field }) => (
<FormItem>
<FormLabel>Jabatan</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="phone"
render={({ field }) => (
<FormItem>
<FormLabel>No Telp</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
</FormItem>
)}
/>
</div>
{/* JENIS AGEN */}
<div>
<FormLabel>Jenis Agen</FormLabel>
<div className="flex gap-6 mt-3">
{AGENT_TYPES.map((role) => (
<FormField
key={role}
control={form.control}
name="roles"
render={({ field }) => {
const selected = field.value || [];
return (
<FormItem className="flex items-center gap-2">
<FormControl>
<Checkbox
checked={selected.includes(role)}
onCheckedChange={(checked) => {
const updated = checked
? [...selected, role] // tambah
: selected.filter((r) => r !== role); // hapus
field.onChange(updated);
}}
/>
</FormControl>
<span>{role}</span>
</FormItem>
);
}}
/>
))}
</div>
</div>
{/* FOTO */}
<div>
<FormLabel>Foto Agen</FormLabel>
<div className="flex items-center gap-5 mt-3">
{preview && (
<div className="relative w-28 h-28 rounded-md overflow-hidden border">
<img
src={preview}
alt="Foto Agen"
className="w-full h-full object-cover"
/>
<button
type="button"
onClick={handleRemoveFile}
className="absolute top-1 right-1 bg-red-600 text-white p-1 rounded-full"
>
<X className="w-4 h-4" />
</button>
</div>
)}
<Button
type="button"
onClick={() => document.getElementById("upload-photo")?.click()}
className="bg-teal-700 text-white"
>
Upload Baru
</Button>
<input
id="upload-photo"
type="file"
accept="image/*"
className="hidden"
onChange={handleFileChange}
/>
</div>
</div>
{/* BUTTON */}
<div className="grid md:grid-cols-3 gap-4 pt-6">
<Button
type="button"
variant="secondary"
onClick={() => router.back()}
>
Batal
</Button>
<Button
type="submit"
className="md:col-span-2 bg-teal-700 text-white"
>
Simpan Perubahan
</Button>
</div>
</form>
</Form>
</div>
);
}