upd: profile

Deskripsi
- tampilan edit profile
- integrasi api edit profile
- tampilan edit password
- integrasi api update password

No Issues
This commit is contained in:
2025-11-13 16:34:01 +08:00
parent 6e1d3ecb56
commit cc293d3bad
3 changed files with 247 additions and 35 deletions

View File

@@ -0,0 +1,190 @@
import apiFetch from "@/lib/apiFetch";
import { Button, Divider, Flex, Group, Input, Modal, Stack, Title } from "@mantine/core";
import { useEffect, useState } from "react";
import notification from "./notificationGlobal";
export default function ProfileUser() {
const [opened, setOpened] = useState(false);
const [openedPassword, setOpenedPassword] = useState(false);
const [pwdBaru, setPwdBaru] = useState("");
const [host, setHost] = useState({
id: "",
name: "",
phone: "",
roleId: "",
email: "",
});
const [error, setError] = useState({
name: false,
email: false,
phone: false,
});
useEffect(() => {
async function fetchHost() {
const { data } = await apiFetch.api.user.find.get();
setHost({
id: data?.user?.id ?? "",
name: data?.user?.name ?? "",
phone: data?.user?.phone ?? "",
roleId: data?.user?.roleId ?? "",
email: data?.user?.email ?? "",
});
}
fetchHost();
}, []);
function onValidation({ kat, value }: { kat: 'name' | 'email' | 'phone', value: string, }) {
if (value.length < 1) {
setError({ ...error, [kat]: true });
} else {
setError({ ...error, [kat]: false });
}
setHost({ ...host, [kat]: value });
}
async function handleUpdate() {
try {
const res = await apiFetch.api.user.update.post(host);
if (res.status === 200) {
setOpened(false);
notification({
title: "Success",
message: "Your profile have been saved",
type: "success",
})
} else {
notification({
title: "Error",
message: "Failed to update profile",
type: "error",
})
}
} catch (error) {
console.log(error);
notification({
title: "Error",
message: "Failed to update profile",
type: "error",
})
}
}
async function handleUpdatePassword() {
try {
const res = await apiFetch.api.user["update-password"].post({ password: pwdBaru, id: host.id });
if (res.status === 200) {
setPwdBaru("");
setOpenedPassword(false);
notification({
title: "Success",
message: "Your password have been saved",
type: "success",
})
} else {
notification({
title: "Error",
message: "Failed to update password",
type: "error",
})
}
} catch (error) {
console.log(error);
notification({
title: "Error",
message: "Failed to update password",
type: "error",
})
}
}
return (
<>
<Stack gap={"md"}>
<Flex align="center" justify="space-between">
<Title order={4} c="gray.2">
Profile Pengguna
</Title>
<Group gap="md">
<Button variant="light" onClick={() => setOpened(true)}>Edit</Button>
<Button variant="light" onClick={() => setOpenedPassword(true)}>Ubah Password</Button>
</Group>
</Flex>
<Divider my={0} />
<Stack gap={"md"}>
<Group gap="xl" grow>
<Input.Wrapper label="Nama" description="" error="">
<Input value={host?.name ?? ""} readOnly />
</Input.Wrapper>
<Input.Wrapper label="Phone" description="" error="">
<Input value={host?.phone ?? ""} readOnly />
</Input.Wrapper>
</Group>
<Group gap="xl" grow>
<Input.Wrapper label="Email" description="" error="">
<Input value={host?.email ?? ""} readOnly />
</Input.Wrapper>
<Input.Wrapper label="Role" description="" error="">
<Input value={host?.roleId ?? ""} readOnly />
</Input.Wrapper>
</Group>
</Stack>
</Stack>
<Modal
opened={opened}
onClose={() => setOpened(false)}
title={"Edit Profile"}
size={"lg"}
overlayProps={{ backgroundOpacity: 0.55, blur: 3 }}
>
<Stack gap={"md"}>
<Input.Wrapper label="Nama" description="" error={error.name ? "Field is required" : ""}>
<Input value={host?.name ?? ""} onChange={(e) => onValidation({ kat: 'name', value: e.target.value })} />
</Input.Wrapper>
<Input.Wrapper label="Phone" description="" error={error.phone ? "Field is required" : ""}>
<Input value={host?.phone ?? ""} onChange={(e) => onValidation({ kat: 'phone', value: e.target.value })} />
</Input.Wrapper>
<Input.Wrapper label="Email" description="" error={error.email ? "Field is required" : ""}>
<Input value={host?.email ?? ""} onChange={(e) => onValidation({ kat: 'email', value: e.target.value })} />
</Input.Wrapper>
<Group grow>
<Button variant="light" onClick={() => setOpened(false)}>
Batal
</Button>
<Button variant="filled" onClick={() => handleUpdate()} disabled={error.name || error.phone || error.email}>
Simpan
</Button>
</Group>
</Stack>
</Modal>
<Modal
opened={openedPassword}
onClose={() => setOpenedPassword(false)}
title={"Ubah Password"}
overlayProps={{ backgroundOpacity: 0.55, blur: 3 }}
>
<Stack gap={"md"}>
<Input.Wrapper label="Password Baru" description="">
<Input value={pwdBaru} onChange={(e) => setPwdBaru(e.target.value)} />
</Input.Wrapper>
<Group grow>
<Button variant="light" onClick={() => setOpenedPassword(false)}>
Batal
</Button>
<Button variant="filled" onClick={() => handleUpdatePassword()} disabled={pwdBaru.length < 1}>
Simpan
</Button>
</Group>
</Stack>
</Modal>
</>
)
}