import { zodResolver } from "@hookform/resolvers/zod"; import type { LoaderFunctionArgs } from "@remix-run/node"; import { useLoaderData } from "@remix-run/react"; import { jwtDecode } from "jwt-decode"; import { Paperclip } from "lucide-react"; import { useForm } from "react-hook-form"; import { ClientOnly } from "remix-utils/client-only"; import { toast } from "sonner"; import DocumentUploader from "~/components/document-uploader"; import PageContainer from "~/components/page-container"; import { Button } from "~/components/ui/button"; import { Combobox, type ComboboxItem } from "~/components/ui/combobox"; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, } from "~/components/ui/form"; import { Input } from "~/components/ui/input"; import RequiredIcon from "~/components/ui/required-icon"; import Spinner from "~/components/ui/spinner"; import { Textarea } from "~/components/ui/textarea"; import { httpClient } from "~/lib/http"; import { useGetCities, useGetDistricts, useGetProvinces } from "~/services/indonesia-region"; import { useUpdateUser } from "~/services/user/update"; import { authenticator } from "~/sessions/auth.server"; import { type Anggota, type AnggotaResponse, anggotaSchema } from "~/types/api/anggota"; import type { BaseResponse } from "~/types/constants/base-response"; import type { AuthJwtPayload } from "~/types/constants/jwt-payload"; import { formatInputDate } from "~/utils/format-input-date"; import { formatImagePath } from "~/utils/prefix-file-path"; export async function loader({ request }: LoaderFunctionArgs) { const token = await authenticator.isAuthenticated(request); const payload = jwtDecode(token || ""); const response = await httpClient.get>(`/user/${payload.id}`); if (response.data.data === undefined) return {} as AnggotaResponse; return response.data.data; } export default function ProfilePage() { const data = useLoaderData(); const { mutateAsync: updateUser } = useUpdateUser(data.id?.toString() || ""); const form = useForm({ resolver: zodResolver(anggotaSchema), defaultValues: { role: data.role || "", nik: data.nik || "", nama: data?.nama || "", no_hp: data?.no_hp || "", tempat_lahir: data?.tempat_lahir || "", tanggal_lahir: data?.tanggal_lahir ? formatInputDate(data.tanggal_lahir) : "", provinsi: data?.provinsi || "", kota: data?.kota || "", kecamatan: data?.kecamatan || "", alamat: data?.alamat || "", foto_profile: data.foto_profile as unknown as File | null, foto_diri: data.foto_diri ? [data.foto_diri] : [], foto_ktp: data.foto_ktp as unknown as File | null, status: data?.status || "", }, }); const { data: provinces } = useGetProvinces(); const provincesItems = (provinces?.data ?? []).map((province) => ({ value: province.code, label: province.name, })) as ComboboxItem[]; const selectedProvince = form.watch("provinsi"); const selectedCity = form.watch("kota"); const { data: cities } = useGetCities(selectedProvince || ""); const { data: districts } = useGetDistricts(selectedCity || ""); const citiesItems = (cities ?? []).map((city) => ({ value: city.code, label: city.name, })) as ComboboxItem[]; const districtsItems = (districts ?? []).map((district) => ({ value: district.code, label: district.name, })) as ComboboxItem[]; const handleProvinceChange = (value: string) => { form.setValue("provinsi", value); form.setValue("kota", ""); form.setValue("kecamatan", ""); }; const handleCityChange = (value: string) => { form.setValue("kota", value); form.setValue("kecamatan", ""); }; async function onSubmit(data: Anggota) { try { await updateUser(data); toast.success("Data anggota berhasil diubah"); } catch (error) { console.error(error); toast.error("Gagal mengubah data anggota"); } } return (

Profil Anggota

}> {() => (
( NIK )} /> ( Nama Lengkap )} />
( No. Handphone )} />
( Tempat Lahir )} /> ( Tanggal Lahir )} />
( Provinsi handleProvinceChange(value)} /> )} /> ( Kota/Kabupaten handleCityChange(value)} /> )} /> ( Kecamatan )} />
( Detail Alamat