diff --git a/src/pages/Login.tsx b/src/pages/Login.tsx index da726da..986f569 100644 --- a/src/pages/Login.tsx +++ b/src/pages/Login.tsx @@ -1,12 +1,12 @@ import clientRoutes from "@/clientRoutes"; import { Button, - Container, - Group, + Center, + Paper, PasswordInput, Stack, Text, - TextInput, + TextInput } from "@mantine/core"; import { useState } from "react"; import apiFetch from "../lib/apiFetch"; @@ -73,25 +73,73 @@ export default function Login() { }; return ( - - - Login - setEmail(e.target.value)} - /> - setPassword(e.target.value)} - /> - - - - - + + + ); } diff --git a/src/pages/scr/dashboard/pengaduan/detail_page.tsx b/src/pages/scr/dashboard/pengaduan/detail_page.tsx index 2bfa9d8..cfa6994 100644 --- a/src/pages/scr/dashboard/pengaduan/detail_page.tsx +++ b/src/pages/scr/dashboard/pengaduan/detail_page.tsx @@ -93,6 +93,7 @@ function DetailDataPengaduan({ const [keterangan, setKeterangan] = useState(""); const [host, setHost] = useState(null); const [permissions, setPermissions] = useState([]); + const [isLoading, setIsLoading] = useState(false); useEffect(() => { async function fetchHost() { @@ -111,6 +112,7 @@ function DetailDataPengaduan({ const handleKonfirmasi = async (cat: "terima" | "tolak") => { try { + setIsLoading(true); const res = await apiFetch.api.pengaduan["update-status"].post({ id: data?.id, status: @@ -184,6 +186,8 @@ function DetailDataPengaduan({ message: "Failed to update pengaduan", type: "error", }); + } finally { + setIsLoading(false); } }; @@ -218,6 +222,7 @@ function DetailDataPengaduan({ color="red" disabled={keterangan.length < 1} onClick={() => handleKonfirmasi("tolak")} + loading={isLoading} > Tolak @@ -242,6 +247,7 @@ function DetailDataPengaduan({ variant="filled" color="green" onClick={() => handleKonfirmasi("terima")} + loading={isLoading} > Ya diff --git a/src/pages/scr/dashboard/warga/detail_warga_page.tsx b/src/pages/scr/dashboard/warga/detail_warga_page.tsx index eab34f9..e5c65aa 100644 --- a/src/pages/scr/dashboard/warga/detail_warga_page.tsx +++ b/src/pages/scr/dashboard/warga/detail_warga_page.tsx @@ -1,62 +1,66 @@ +import notification from "@/components/notificationGlobal"; import apiFetch from "@/lib/apiFetch"; import { Avatar, Box, Button, Card, + CloseButton, Container, Divider, Flex, Grid, Group, + Input, LoadingOverlay, + Pagination, Stack, Table, Text, Title, } from "@mantine/core"; import { useShallowEffect } from "@mantine/hooks"; -import { IconPhone } from "@tabler/icons-react"; +import { IconPhone, IconSearch } from "@tabler/icons-react"; import _ from "lodash"; +import { useState } from "react"; import { useLocation, useNavigate } from "react-router-dom"; -import useSwr from "swr"; export default function DetailWargaPage() { const { search } = useLocation(); const query = new URLSearchParams(search); const id = query.get("id"); - const { data, mutate, isLoading } = useSwr("/", () => - apiFetch.api.warga.detail.get({ - query: { - id: id!, - }, - }), - ); + // const { data, mutate, isLoading } = useSwr("/", () => + // apiFetch.api.warga.detail.get({ + // query: { + // id: id!, + // }, + // }), + // ); - useShallowEffect(() => { - mutate(); - }, []); + // useShallowEffect(() => { + // mutate(); + // }, []); return ( <> - + @@ -68,13 +72,66 @@ export default function DetailWargaPage() { } function DetailDataHistori({ - data, + id, kategori, }: { - data: any; + id: string; kategori: "pengaduan" | "pelayanan"; }) { const navigate = useNavigate(); + const [data, setData] = useState([]); + const [totalPages, setTotalPages] = useState(1); + const [totalRows, setTotalRows] = useState(0); + const [page, setPage] = useState(1); + const [search, setSearch] = useState(""); + + async function getData() { + try { + const res = await apiFetch.api.warga.detail.get({ + query: { + id, + category: kategori, + page: String(page), + search + } + }) as { data: { success: boolean; data: any[]; totalPages: number, totalRows: number } }; + + if (res?.data?.success) { + setData(res.data.data) + setTotalPages(res?.data?.totalPages) + setTotalRows(res?.data?.totalRows) + } else { + setData([]) + setTotalPages(1) + setTotalRows(0) + notification({ + title: "Failed", + message: "Failed to get data", + type: "error", + }); + } + + } catch (error) { + console.error(error); + notification({ + title: "Failed", + message: "Failed to get data", + type: "error", + }); + } + } + + useShallowEffect(() => { + getData() + }, [page]) + + + useShallowEffect(() => { + setPage(1) + if (page == 1) { + getData() + } + }, [search]); return ( Histori {_.upperFirst(kategori)} + + setSearch(event.currentTarget.value)} + leftSection={} + rightSectionPointerEvents="all" + rightSection={ + setSearch("")} + style={{ display: search ? undefined : "none" }} + /> + } + /> + + {`${5 * (page - 1) + 1} – ${Math.min(totalRows, 5 * page)} of ${totalRows}`} + + + @@ -110,7 +197,7 @@ function DetailDataHistori({ {data?.length > 0 ? ( data?.map((item: any, index: number) => ( - {item.noPengaduan} + {item.noPengaduan} {kategori == "pengaduan" ? item.title : item.category} @@ -121,11 +208,11 @@ function DetailDataHistori({ onClick={() => { kategori == "pengaduan" ? navigate( - `/scr/dashboard/pengaduan/detail?id=${item.id}`, - ) + `/scr/dashboard/pengaduan/detail?id=${item.id}`, + ) : navigate( - `/scr/dashboard/pelayanan-surat/detail-pelayanan?id=${item.id}`, - ); + `/scr/dashboard/pelayanan-surat/detail-pelayanan?id=${item.id}`, + ); }} > Detail @@ -147,7 +234,33 @@ function DetailDataHistori({ ); } -function DetailWarga({ data }: { data: any }) { +function DetailWarga({ id }: { id: string }) { + const [data, setData] = useState(null); + + async function getWarga() { + try { + const res = await apiFetch.api.warga.detail.get({ + query: { + id: id, + category: "warga", + page: "1", + search: "", + }, + }); + setData(res.data); + } catch (error) { + console.error(error); + notification({ + title: "Failed", + message: "Failed to get data warga", + type: "error", + }); + } + } + + useShallowEffect(() => { + getWarga(); + }, []); return ( { - const { id } = query + const { id, category, search, page } = query + const skip = !page ? 0 : (Number(page) - 1) * 5 + const dataWarga = await prisma.warga.findUnique({ where: { id } }) - const dataPengaduan = await prisma.pengaduan.findMany({ - orderBy: { - createdAt: "desc" - }, - where: { + if (!dataWarga) + return { success: false, message: "data warga tidak ditemukan", data: null, totalPages: 1, totalRows: 0 } + + if (category == "warga") { + return dataWarga + } else if (category == "pengaduan") { + const where: any = { isActive: true, - idWarga: id - }, - select: { - id: true, - status: true, - noPengaduan: true, - title: true + idWarga: id, + OR: [ + { + title: { + contains: search ?? "", + mode: "insensitive" + }, + }, + { + noPengaduan: { + contains: search ?? "", + mode: "insensitive" + }, + } + ] } - }) + const totalData = await prisma.pengaduan.count({ + where + }); + const dataPengaduan = await prisma.pengaduan.findMany({ + skip, + take: 5, + orderBy: { + createdAt: "desc" + }, + where, + select: { + id: true, + status: true, + noPengaduan: true, + title: true + } + }) + const dataReturn = { + success: true, + message: "data pengaduan berhasil diambil", + data: dataPengaduan, + totalRows: totalData, + totalPages: Math.ceil(totalData / 5) + } - const dataPelayanan = await prisma.pelayananAjuan.findMany({ - orderBy: { - createdAt: "desc" - }, - where: { + return dataReturn + } else if (category == "pelayanan") { + const where: any = { isActive: true, - idWarga: id - }, - select: { - id: true, - noPengajuan: true, - status: true, - CategoryPelayanan: { - select: { - name: true + idWarga: id, + OR: [ + { + CategoryPelayanan: { + name: { + contains: search ?? "", + mode: "insensitive" + }, + }, + }, + { + noPengajuan: { + contains: search ?? "", + mode: "insensitive" + }, + }, + ] + } + + const totalData = await prisma.pelayananAjuan.count({ + where + }); + + const dataPelayanan = await prisma.pelayananAjuan.findMany({ + skip, + take: 5, + orderBy: { + createdAt: "desc" + }, + where, + select: { + id: true, + noPengajuan: true, + status: true, + CategoryPelayanan: { + select: { + name: true + } } } + }) + + const dataPelayanFix = dataPelayanan.map((v: any) => ({ + ..._.omit(v, ["CategoryPelayanan"]), + id: v.id, + noPengaduan: v.noPengajuan, + status: v.status, + category: v.CategoryPelayanan.name + })) + + const dataReturn = { + success: true, + message: "data pelayanan berhasil diambil", + data: dataPelayanFix, + totalRows: totalData, + totalPages: Math.ceil(totalData / 5) } - }) - const dataPelayanFix = dataPelayanan.map((v: any) => ({ - ..._.omit(v, ["CategoryPelayanan"]), - id: v.id, - noPengaduan: v.noPengajuan, - status: v.status, - category: v.CategoryPelayanan.name - })) - - return { - warga: dataWarga, - pengaduan: dataPengaduan, - pelayanan: dataPelayanFix + return dataReturn } }, { query: t.Object({ - id: t.String({ minLength: 1, error: "id harus diisi" }) + id: t.String({ minLength: 1, error: "id harus diisi" }), + category: t.String({ minLength: 1, error: "kategori harus diisi" }), + page: t.String({ optional: true }), + search: t.String({ optional: true }), }), detail: { summary: "Detail Warga",