fix: edit profile
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Sabda Yagra 2026-04-13 09:56:25 +07:00
parent 7ddd584159
commit 0bf2fd68c5
2 changed files with 203 additions and 40 deletions

View File

@ -10,7 +10,7 @@ import * as z from "zod";
import Swal from "sweetalert2"; import Swal from "sweetalert2";
import { getBlog, postBlog } from "@/service/blog/blog"; import { getBlog, postBlog } from "@/service/blog/blog";
import { id } from "date-fns/locale"; import { id } from "date-fns/locale";
import router from "next/router"; import { useRouter } from "next/navigation";
import { getInfoProfile, saveUser } from "@/service/auth"; import { getInfoProfile, saveUser } from "@/service/auth";
import withReactContent from "sweetalert2-react-content"; import withReactContent from "sweetalert2-react-content";
import { Textarea } from "@/components/ui/textarea"; import { Textarea } from "@/components/ui/textarea";
@ -27,7 +27,6 @@ const profileSchema = z.object({
phoneNumber: z.string().optional(), phoneNumber: z.string().optional(),
}); });
type Detail = { type Detail = {
id: number; id: number;
userId: any; userId: any;
@ -39,6 +38,7 @@ type Detail = {
address: string; address: string;
phoneNumber: any; phoneNumber: any;
message: string; message: string;
userKeycloakId: string;
}; };
const UbahProfile: React.FC = () => { const UbahProfile: React.FC = () => {
@ -46,46 +46,75 @@ const UbahProfile: React.FC = () => {
const [detail, setDetail] = useState<Detail>(); const [detail, setDetail] = useState<Detail>();
const [refresh, setRefresh] = useState(false); const [refresh, setRefresh] = useState(false);
const t = useTranslations("LandingPage"); const t = useTranslations("LandingPage");
const router = useRouter();
type ProfileSchema = z.infer<typeof profileSchema>; type ProfileSchema = z.infer<typeof profileSchema>;
const { const {
control, control,
handleSubmit, handleSubmit,
setValue, setValue,
reset,
formState: { errors }, formState: { errors },
} = useForm<ProfileSchema>({ } = useForm<ProfileSchema>({
resolver: zodResolver(profileSchema), resolver: zodResolver(profileSchema),
}); });
// useEffect(() => {
// async function initState() {
// const response = await getInfoProfile();
// const details = response?.data?.data;
// setDetail(details);
// // console.log("data", details);
// }
// initState();
// }, []);
useEffect(() => { useEffect(() => {
async function initState() { async function initState() {
const response = await getInfoProfile(); const response = await getInfoProfile();
const details = response?.data?.data; const details = response?.data?.data;
setDetail(details); setDetail(details);
// console.log("data", details);
reset({
username: details?.username,
fullname: details?.fullname,
memberIdentity: details?.memberIdentity,
email: details?.email,
address: details?.address,
phoneNumber: details?.phoneNumber,
});
} }
initState(); initState();
}, []); }, []);
const save = async (data: ProfileSchema) => { const save = async (data: ProfileSchema) => {
// const requestData = {
// ...data,
// // userId: detail?.userKeycloakId,
// firstName: detail?.fullname,
// username: detail?.username,
// memberIdentity: detail?.memberIdentity,
// email: detail?.email,
// address: detail?.address,
// phoneNumber: detail?.phoneNumber,
// // message: data.title,
// };
const requestData = { const requestData = {
...data, id: detail?.id,
// userId: detail?.userKeycloakId, userKeycloakId: detail?.userKeycloakId, // 🔥 tambahin ini
firstName: detail?.fullname, username: data.username,
username: detail?.username, fullname: data.fullname,
memberIdentity: detail?.memberIdentity, email: data.email,
email: detail?.email, memberIdentity: data.memberIdentity,
address: detail?.address, address: data.address,
phoneNumber: detail?.phoneNumber, phoneNumber: data.phoneNumber,
// message: data.title,
}; };
console.log("FORM DATA:", data);
console.log("REQUEST DATA:", requestData);
const response = await saveUser(requestData); const response = await saveUser(requestData);
// console.log("Form Data Submitted:", requestData);
// console.log("response", response);
MySwal.fire({ MySwal.fire({
title: "Sukses", title: "Sukses",
text: "Data berhasil disimpan.", text: "Data berhasil disimpan.",
@ -93,7 +122,7 @@ const UbahProfile: React.FC = () => {
confirmButtonColor: "#3085d6", confirmButtonColor: "#3085d6",
confirmButtonText: "OK", confirmButtonText: "OK",
}).then(() => { }).then(() => {
router.push("/en/auth"); router.refresh();
}); });
}; };
@ -118,22 +147,32 @@ const UbahProfile: React.FC = () => {
<div className="w-20 h-20 mx-auto rounded-full bg-red-700 flex items-center justify-center"> <div className="w-20 h-20 mx-auto rounded-full bg-red-700 flex items-center justify-center">
<span className="text-white text-3xl font-bold">👤</span> <span className="text-white text-3xl font-bold">👤</span>
</div> </div>
<h1 className="text-2xl font-bold mt-4">{t("changeProfile", { defaultValue: "Change Profile" })}</h1> <h1 className="text-2xl font-bold mt-4">
{t("changeProfile", { defaultValue: "Change Profile" })}
</h1>
</div> </div>
<div className="flex justify-center gap-4 mb-8"> <div className="flex justify-center gap-4 mb-8">
<Link href={"/profile"}> <Link href={"/profile"}>
<button className="bg-red-700 text-white px-4 py-2 rounded">{t("userProfile", { defaultValue: "User Profile" })}</button> <button className="bg-red-700 text-white px-4 py-2 rounded">
{t("userProfile", { defaultValue: "User Profile" })}
</button>
</Link> </Link>
<Link href={"/profile/change-profile"}> <Link href={"/profile/change-profile"}>
<button className="border border-red-700 text-red-700 px-4 py-2 rounded">{t("changePhoto", { defaultValue: "Change Photo" })}</button> <button className="border border-red-700 text-red-700 px-4 py-2 rounded">
{t("changePhoto", { defaultValue: "Change Photo" })}
</button>
</Link> </Link>
<Link href={"/profile/change-password"}> <Link href={"/profile/change-password"}>
<button className="border border-red-700 text-red-700 px-4 py-2 rounded">{t("changePass", { defaultValue: "Change Pass" })}</button> <button className="border border-red-700 text-red-700 px-4 py-2 rounded">
{t("changePass", { defaultValue: "Change Pass" })}
</button>
</Link> </Link>
</div> </div>
<div className="max-w-3xl mx-auto bg-white shadow-sm p-4 rounded"> <div className="max-w-3xl mx-auto bg-white shadow-sm p-4 rounded">
<p className="mb-6 text-gray-600">{t("pleaseChange", { defaultValue: "Please Change" })}</p> <p className="mb-6 text-gray-600">
{t("pleaseChange", { defaultValue: "Please Change" })}
</p>
<form onSubmit={handleSubmit(onSubmit)}> <form onSubmit={handleSubmit(onSubmit)}>
{detail !== undefined ? ( {detail !== undefined ? (
<div> <div>
@ -141,51 +180,176 @@ const UbahProfile: React.FC = () => {
<Label> <Label>
Username<span className="text-red-500">*</span> Username<span className="text-red-500">*</span>
</Label> </Label>
<Controller control={control} name="username" render={({ field }) => <Input size="md" type="text" defaultValue={detail?.username} onChange={field.onChange} placeholder="Enter Title" />} /> {/* <Controller
{errors.username?.message && <p className="text-red-400 text-sm">{errors.username.message}</p>} control={control}
name="username"
render={({ field }) => (
<Input
size="md"
type="text"
defaultValue={detail?.username}
onChange={field.onChange}
placeholder="Enter Title"
/>
)}
/> */}
<Controller
control={control}
name="username"
render={({ field }) => <Input {...field} type="text" readOnly />}
/>
{errors.username?.message && (
<p className="text-red-400 text-sm">
{errors.username.message}
</p>
)}
</div> </div>
<div className="mb-4"> {/* <div className="mb-4">
<Label> <Label>
{t("fullName", { defaultValue: "Full Name" })} {t("fullName", { defaultValue: "Full Name" })}
<span className="text-red-500">*</span> <span className="text-red-500">*</span>
</Label> </Label> */}
<Controller control={control} name="fullname" render={({ field }) => <Input size="md" type="text" defaultValue={detail?.fullname} onChange={field.onChange} placeholder="Enter Title" />} /> {/* <Controller
{errors.fullname?.message && <p className="text-red-400 text-sm">{errors.fullname.message}</p>} control={control}
</div> name="fullname"
render={({ field }) => (
<Input
size="md"
type="text"
defaultValue={detail?.fullname}
onChange={field.onChange}
placeholder="Enter Title"
/>
)}
/> */}
{/* <Controller
control={control}
name="fullname"
render={({ field }) => <Input {...field} type="text" />}
/>
{errors.fullname?.message && (
<p className="text-red-400 text-sm">
{errors.fullname.message}
</p>
)}
</div> */}
<div className="mb-4"> <div className="mb-4">
<Label> <Label>
{t("identityNumber", { defaultValue: "Identity Number" })} {t("identityNumber", { defaultValue: "Identity Number" })}
<span className="text-red-500">*</span> <span className="text-red-500">*</span>
</Label> </Label>
<Controller control={control} name="memberIdentity" render={({ field }) => <Input size="md" type="text" defaultValue={detail?.memberIdentity} onChange={field.onChange} placeholder="Enter Title" />} /> {/* <Controller
{errors.memberIdentity?.message && <p className="text-red-400 text-sm">{errors.memberIdentity.message}</p>} control={control}
name="memberIdentity"
render={({ field }) => (
<Input
size="md"
type="text"
defaultValue={detail?.memberIdentity}
onChange={field.onChange}
placeholder="Enter Title"
/>
)}
/> */}
<Controller
control={control}
name="memberIdentity"
render={({ field }) => <Input {...field} type="text" />}
/>
{errors.memberIdentity?.message && (
<p className="text-red-400 text-sm">
{errors.memberIdentity.message}
</p>
)}
</div> </div>
<div className="mb-4"> <div className="mb-4">
<Label> <Label>
Email<span className="text-red-500">*</span> Email<span className="text-red-500">*</span>
</Label> </Label>
<Controller control={control} name="email" render={({ field }) => <Input size="md" type="text" defaultValue={detail?.email} onChange={field.onChange} placeholder="Enter Title" />} /> {/* <Controller
{errors.email?.message && <p className="text-red-400 text-sm">{errors.email.message}</p>} control={control}
name="email"
render={({ field }) => (
<Input
size="md"
type="text"
defaultValue={detail?.email}
onChange={field.onChange}
placeholder="Enter Title"
/>
)}
/> */}
<Controller
control={control}
name="email"
render={({ field }) => <Input {...field} type="text" />}
/>
{errors.email?.message && (
<p className="text-red-400 text-sm">{errors.email.message}</p>
)}
</div> </div>
<div className="mb-4"> <div className="mb-4">
<Label> <Label>
{t("number", { defaultValue: "Number" })} {t("number", { defaultValue: "Number" })}
<span className="text-red-500">*</span> <span className="text-red-500">*</span>
</Label> </Label>
<Controller control={control} name="phoneNumber" render={({ field }) => <Input size="md" type="number" defaultValue={detail?.phoneNumber} onChange={field.onChange} placeholder="Enter Title" />} /> {/* <Controller
{errors.phoneNumber?.message && <p className="text-red-400 text-sm">{errors.phoneNumber.message}</p>} control={control}
name="phoneNumber"
render={({ field }) => (
<Input
size="md"
type="number"
defaultValue={detail?.phoneNumber}
onChange={field.onChange}
placeholder="Enter Title"
/>
)}
/> */}
<Controller
control={control}
name="phoneNumber"
render={({ field }) => <Input {...field} type="text" />}
/>
{errors.phoneNumber?.message && (
<p className="text-red-400 text-sm">
{errors.phoneNumber.message}
</p>
)}
</div> </div>
<div className="mb-4"> <div className="mb-4">
<Label> <Label>
{t("address", { defaultValue: "Address" })} {t("address", { defaultValue: "Address" })}
<span className="text-red-500">*</span> <span className="text-red-500">*</span>
</Label> </Label>
<Controller control={control} name="address" render={({ field }) => <Textarea defaultValue={detail?.address} onChange={field.onChange} placeholder="Enter Title" />} /> {/* <Controller
{errors.address?.message && <p className="text-red-400 text-sm">{errors.address.message}</p>} control={control}
name="address"
render={({ field }) => (
<Textarea
defaultValue={detail?.address}
onChange={field.onChange}
placeholder="Enter Title"
/>
)}
/> */}
<Controller
control={control}
name="address"
render={({ field }) => <Textarea {...field} />}
/>
{errors.address?.message && (
<p className="text-red-400 text-sm">
{errors.address.message}
</p>
)}
</div> </div>
<div className="text-right"> <div className="text-right">
<div className="mt-4"> <div className="mt-4">
<button type="submit" className="bg-red-700 text-white px-6 py-2 rounded hover:bg-red-800 focus:outline-none focus:ring focus:ring-red-300"> <button
type="submit"
className="bg-red-700 text-white px-6 py-2 rounded hover:bg-red-800 focus:outline-none focus:ring focus:ring-red-300"
>
{t("save", { defaultValue: "Save" })} {t("save", { defaultValue: "Save" })}
</button> </button>
</div> </div>

View File

@ -104,9 +104,8 @@ export async function saveUser(data: any) {
const headers = { const headers = {
"content-type": "application/json", "content-type": "application/json",
}; };
return httpPost(url, headers); return httpPost(url, data, headers);
} }
export async function saveInstitutes(data: any) { export async function saveInstitutes(data: any) {
const url = "public/users/save-institutes"; const url = "public/users/save-institutes";
const headers = { const headers = {