upd: dashboard admin
Deskripsi: - detail pengaduan - menerima pengaduan - mengerjakan pengaduan/ - menyelesaikan pengaduan - menolak pengaduan No Issues
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import notification from "@/components/notificationGlobal";
|
||||
import apiFetch from "@/lib/apiFetch";
|
||||
import {
|
||||
Anchor,
|
||||
@@ -17,7 +18,7 @@ import {
|
||||
Textarea,
|
||||
Title,
|
||||
} from "@mantine/core";
|
||||
import { useDisclosure } from "@mantine/hooks";
|
||||
import { useDisclosure, useShallowEffect } from "@mantine/hooks";
|
||||
import {
|
||||
IconAlignJustified,
|
||||
IconCategory,
|
||||
@@ -25,14 +26,15 @@ import {
|
||||
IconInfoTriangle,
|
||||
IconMapPin,
|
||||
IconMessageReport,
|
||||
IconPhone,
|
||||
IconPhotoScan,
|
||||
IconUser,
|
||||
} from "@tabler/icons-react";
|
||||
import type { User } from "generated/prisma";
|
||||
import _ from "lodash";
|
||||
import { useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import useSwr from "swr";
|
||||
import { useShallowEffect } from "@mantine/hooks";
|
||||
|
||||
export default function DetailPengaduanPage() {
|
||||
const { search } = useLocation();
|
||||
@@ -55,7 +57,7 @@ export default function DetailPengaduanPage() {
|
||||
<Grid>
|
||||
<Grid.Col span={8}>
|
||||
<Stack gap={"xl"}>
|
||||
<DetailDataPengaduan data={data?.data?.pengaduan} />
|
||||
<DetailDataPengaduan data={data?.data?.pengaduan} onAction={() => { mutate(); }} />
|
||||
<DetailDataHistori data={data?.data?.history} />
|
||||
</Stack>
|
||||
</Grid.Col>
|
||||
@@ -67,24 +69,57 @@ export default function DetailPengaduanPage() {
|
||||
);
|
||||
}
|
||||
|
||||
function DetailDataPengaduan({ data }: { data: any }) {
|
||||
function DetailDataPengaduan({ data, onAction }: { data: any, onAction: () => void }) {
|
||||
const [opened, { open, close }] = useDisclosure(false);
|
||||
const [catModal, setCatModal] = useState<"tolak" | "terima">("tolak");
|
||||
const [imageSrc, setImageSrc] = useState<string | null>(null);
|
||||
const [openedModalImage, { open: openModalImage, close: closeModalImage }] =
|
||||
useDisclosure(false);
|
||||
const [keterangan, setKeterangan] = useState("");
|
||||
const [host, setHost] = useState<User | null>(null);
|
||||
|
||||
// async function handleLihatGambar() {
|
||||
// const res = await apiFetch.api.pengaduan.image.get({
|
||||
// query: {
|
||||
// fileName: "57d5ce89-7d18-4244-9f4c-ca21b70adb7e",
|
||||
// },
|
||||
// });
|
||||
// console.error("client", res);
|
||||
// // const blob = await res.data?.blob();
|
||||
// // setImageSrc(URL.createObjectURL(blob!));
|
||||
// // openModalImage();
|
||||
// }
|
||||
useEffect(() => {
|
||||
async function fetchHost() {
|
||||
const { data } = await apiFetch.api.user.find.get();
|
||||
setHost(data?.user ?? null);
|
||||
}
|
||||
fetchHost();
|
||||
}, []);
|
||||
|
||||
const handleKonfirmasi = async (cat: "terima" | "tolak") => {
|
||||
try {
|
||||
const res = await apiFetch.api.pengaduan["update-status"].post({
|
||||
id: data?.id,
|
||||
status: cat == 'tolak' ? 'ditolak' : data.status == 'antrian' ? 'diterima' : data.status == 'diterima' ? 'dikerjakan' : 'selesai',
|
||||
keterangan: keterangan,
|
||||
idUser: host?.id ?? ""
|
||||
});
|
||||
|
||||
if (res?.status === 200) {
|
||||
onAction();
|
||||
close();
|
||||
notification({
|
||||
title: "Success",
|
||||
message: "Success update pengaduan",
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
notification({
|
||||
title: "Error",
|
||||
message: "Failed to update pengaduan",
|
||||
type: "error",
|
||||
});
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
notification({
|
||||
title: "Error",
|
||||
message: "Failed to update pengaduan",
|
||||
type: "error",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -94,7 +129,6 @@ function DetailDataPengaduan({ data }: { data: any }) {
|
||||
opened={opened}
|
||||
onClose={close}
|
||||
title={"Konfirmasi"}
|
||||
centered
|
||||
overlayProps={{ backgroundOpacity: 0.55, blur: 3 }}
|
||||
>
|
||||
<Stack gap="sm">
|
||||
@@ -104,25 +138,25 @@ function DetailDataPengaduan({ data }: { data: any }) {
|
||||
Anda yakin ingin menolak pengaduan ini? Berikan alasan penolakan
|
||||
</Text>
|
||||
|
||||
<Textarea size="md" minRows={5} />
|
||||
<Textarea size="md" minRows={5} value={keterangan} onChange={(e) => setKeterangan(e.target.value)} />
|
||||
<Group justify="center" grow>
|
||||
<Button variant="light" onClick={close}>
|
||||
Batal
|
||||
</Button>
|
||||
<Button variant="filled" color="red" onClick={close}>
|
||||
<Button variant="filled" color="red" disabled={keterangan.length < 1} onClick={() => handleKonfirmasi("tolak")}>
|
||||
Tolak
|
||||
</Button>
|
||||
</Group>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Text>Anda yakin ingin menerima pengaduan ini?</Text>
|
||||
<Text>Anda yakin ingin {data?.status == 'antrian' ? 'menerima' : data.status == 'diterima' ? 'mengerjakan' : 'menyelesaikan'} pengaduan ini?</Text>
|
||||
<Group justify="center" grow>
|
||||
<Button variant="light" onClick={close}>
|
||||
Batal
|
||||
Tidak
|
||||
</Button>
|
||||
<Button variant="filled" color="green" onClick={close}>
|
||||
Terima
|
||||
<Button variant="filled" color="green" onClick={() => handleKonfirmasi("terima")}>
|
||||
Ya
|
||||
</Button>
|
||||
</Group>
|
||||
</>
|
||||
@@ -136,7 +170,6 @@ function DetailDataPengaduan({ data }: { data: any }) {
|
||||
opened={openedModalImage}
|
||||
onClose={closeModalImage}
|
||||
title="Gambar Pengaduan"
|
||||
centered
|
||||
overlayProps={{ backgroundOpacity: 0.55, blur: 3 }}
|
||||
>
|
||||
<Image src={imageSrc!} />
|
||||
@@ -175,7 +208,7 @@ function DetailDataPengaduan({ data }: { data: any }) {
|
||||
: data?.status === "selesai"
|
||||
? "blue"
|
||||
: data?.status === "dikerjakan"
|
||||
? "purple"
|
||||
? "gray"
|
||||
: "yellow"
|
||||
}
|
||||
style={{ textTransform: "none" }}
|
||||
@@ -256,26 +289,54 @@ function DetailDataPengaduan({ data }: { data: any }) {
|
||||
</Stack>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={12}>
|
||||
<Group justify="center" grow>
|
||||
<Button
|
||||
variant="light"
|
||||
onClick={() => {
|
||||
setCatModal("tolak");
|
||||
open();
|
||||
}}
|
||||
>
|
||||
Tolak
|
||||
</Button>
|
||||
<Button
|
||||
variant="filled"
|
||||
onClick={() => {
|
||||
setCatModal("terima");
|
||||
open();
|
||||
}}
|
||||
>
|
||||
Terima
|
||||
</Button>
|
||||
</Group>
|
||||
{
|
||||
data?.status === "antrian" ? (
|
||||
<Group justify="center" grow>
|
||||
<Button
|
||||
variant="light"
|
||||
onClick={() => {
|
||||
setCatModal("tolak");
|
||||
open();
|
||||
}}
|
||||
>
|
||||
Tolak
|
||||
</Button>
|
||||
<Button
|
||||
variant="filled"
|
||||
onClick={() => {
|
||||
setCatModal("terima");
|
||||
open();
|
||||
}}
|
||||
>
|
||||
Terima
|
||||
</Button>
|
||||
</Group>
|
||||
) : data?.status === "diterima" ? (
|
||||
<Group justify="center" grow>
|
||||
<Button
|
||||
variant="filled"
|
||||
onClick={() => {
|
||||
setCatModal("terima");
|
||||
open();
|
||||
}}
|
||||
>
|
||||
Kerjakan
|
||||
</Button>
|
||||
</Group>
|
||||
) : data?.status === "dikerjakan" ? (
|
||||
<Group justify="center" grow>
|
||||
<Button
|
||||
variant="filled"
|
||||
onClick={() => {
|
||||
setCatModal("terima");
|
||||
open();
|
||||
}}
|
||||
>
|
||||
Selesai
|
||||
</Button>
|
||||
</Group>
|
||||
) : <></>
|
||||
}
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</Stack>
|
||||
@@ -317,10 +378,10 @@ function DetailDataHistori({ data }: { data: any }) {
|
||||
{
|
||||
data?.map((item: any) => (
|
||||
<Table.Tr key={item.id}>
|
||||
<Table.Td>{item.createdAt}</Table.Td>
|
||||
<Table.Td style={{ whiteSpace: "nowrap" }}>{item.createdAt}</Table.Td>
|
||||
<Table.Td>{item.deskripsi}</Table.Td>
|
||||
<Table.Td>{item.status}</Table.Td>
|
||||
<Table.Td>{item.user}</Table.Td>
|
||||
<Table.Td style={{ whiteSpace: "nowrap" }}>{item.nameUser ? item.nameUser : "-"}</Table.Td>
|
||||
</Table.Tr>
|
||||
))
|
||||
}
|
||||
@@ -365,7 +426,7 @@ function DetailUserPengaduan({ data }: { data: any }) {
|
||||
</Group>
|
||||
<Group justify="space-between">
|
||||
<Group gap="xs">
|
||||
<IconMapPin size={20} />
|
||||
<IconPhone size={20} />
|
||||
<Text size="md">Telepon</Text>
|
||||
</Group>
|
||||
<Text size="md" c="white">
|
||||
|
||||
@@ -233,7 +233,7 @@ function ListPengaduan({ status }: { status: StatusKey }) {
|
||||
: v.status === "selesai"
|
||||
? "blue"
|
||||
: v.status === "dikerjakan"
|
||||
? "purple"
|
||||
? "gray"
|
||||
: "yellow"
|
||||
}
|
||||
style={{ textTransform: "none" }}
|
||||
|
||||
@@ -383,7 +383,14 @@ Respon:
|
||||
id: item.id,
|
||||
deskripsi: item.deskripsi,
|
||||
status: item.status,
|
||||
createdAt: item.createdAt.toLocaleDateString("id-ID", { day: "numeric", month: "long", year: "numeric" }),
|
||||
createdAt: item.createdAt.toLocaleString("id-ID", {
|
||||
day: "2-digit",
|
||||
month: "short",
|
||||
year: "numeric",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
hour12: false
|
||||
}),
|
||||
idUser: item.idUser,
|
||||
nameUser: item.User?.name,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user