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