amalia/14-jan-26 #110

Merged
amaliadwiy merged 2 commits from amalia/14-jan-26 into main 2026-01-14 17:43:12 +08:00
3 changed files with 90 additions and 61 deletions

View File

@@ -1,5 +1,5 @@
import apiFetch from "@/lib/apiFetch";
import { Flex, Loader, Modal, Text } from "@mantine/core";
import { Flex, Modal, Progress, Stack, Text } from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks";
import html2canvas from "html2canvas";
import jsPDF from "jspdf";
@@ -35,7 +35,7 @@ export default function ModalSurat({
fontSize: "14px",
fontFamily: "Times New Roman",
};
const [uploading, setUploading] = useState<"Menyiapkan" | "Mengupload" | "Selesai">("Menyiapkan")
const [uploading, setUploading] = useState<{ text: "Menyiapkan" | "Mengupload" | "Selesai", value: number }>({ text: "Menyiapkan", value: 10 })
const hiddenRef = useRef<any>(null);
const { data, mutate, isLoading } = useSWR("surat", () =>
apiFetch.api.surat.detail.get({
@@ -52,7 +52,7 @@ export default function ModalSurat({
const uploadPdf = async () => {
try {
if (data && data.data && data.data.surat && (data.data.surat.file == "" || data.data.surat.file == null)) {
setUploading("Mengupload");
setUploading({ text: "Mengupload", value: 75 });
const element = hiddenRef.current;
const canvas = await html2canvas(element, {
scale: 2,
@@ -95,7 +95,7 @@ export default function ModalSurat({
filename: resImg.data?.filename!,
});
setUploading("Selesai");
setUploading({ text: "Selesai", value: 100 });
setTimeout(() => {
onClose(resUpdate.data?.link);
}, 1000)
@@ -136,14 +136,24 @@ export default function ModalSurat({
},
}}
title={
<Flex justify="space-between" align="center" w="100%">
<div style={{ fontSize: 18, fontWeight: 600 }}>Preview Surat</div>
<>
<Flex justify="space-between" align="center" w="100%">
<div style={{ fontSize: 18, fontWeight: 600 }}>Preview Surat</div>
<Flex gap={8} align="center">
{/* <Flex gap={8} align="center">
<Loader color="blue" size="xs" />
<Text size="sm">{uploading}</Text>
<Text size="sm">{uploading.text}</Text>
</Flex> */}
</Flex>
</Flex>
<Stack
align="stretch"
justify="center"
gap="xs"
>
<Text size="sm" ta="center">{uploading.text} - Harap menunggu sampai selesai</Text>
<Progress radius="md" value={uploading.value} animated size="lg" />
</Stack>
</>
}
>
<div ref={hiddenRef} style={A4Style}>

View File

@@ -317,57 +317,60 @@ function SearchData() {
}
return (
<FormSection
title="Cari Pengajuan Surat"
info="Masukkan nomor pengajuan dan nomor telepon yang digunakan saat pengajuan surat."
>
<Grid>
<Grid.Col span={6}>
<TextInput
label={
<FieldLabel
label="Nomor Pengajuan"
hint="Nomor pengajuan surat"
/>
}
placeholder="PS-2025-000123"
onChange={(e) => {
setSearchPengajuan(e.target.value);
}}
/>
</Grid.Col>
<>
<FullScreenLoading visible={submitLoading} text="Mencari Data" />
<FormSection
title="Cari Pengajuan Surat"
info="Masukkan nomor pengajuan dan nomor telepon yang digunakan saat pengajuan surat."
>
<Grid>
<Grid.Col span={6}>
<TextInput
label={
<FieldLabel
label="Nomor Pengajuan"
hint="Nomor pengajuan surat"
/>
}
placeholder="PS-2025-000123"
onChange={(e) => {
setSearchPengajuan(e.target.value);
}}
/>
</Grid.Col>
<Grid.Col span={6}>
<TextInput
label={
<FieldLabel
label="Nomor Telephone"
hint="Nomor telephone yang dapat dihubungi / terhubung dengan whatsapp"
/>
}
placeholder="08123456789"
type="number"
onChange={(e) => {
setSearchPengajuanPhone(e.target.value);
}}
/>
</Grid.Col>
<Grid.Col span={6}>
<TextInput
label={
<FieldLabel
label="Nomor Telephone"
hint="Nomor telephone yang dapat dihubungi / terhubung dengan whatsapp"
/>
}
placeholder="08123456789"
type="number"
onChange={(e) => {
setSearchPengajuanPhone(e.target.value);
}}
/>
</Grid.Col>
<Grid.Col span={12}>
<Button
fullWidth
variant="light"
color="blue"
onClick={() => {
handleSearch();
}}
loading={submitLoading}
>
Cari Pengajuan
</Button>
</Grid.Col>
</Grid>
</FormSection>
<Grid.Col span={12}>
<Button
fullWidth
variant="light"
color="blue"
onClick={() => {
handleSearch();
}}
loading={submitLoading}
>
Cari Pengajuan
</Button>
</Grid.Col>
</Grid>
</FormSection>
</>
);
}
@@ -387,6 +390,7 @@ function DataUpdate({
const [dataSyaratDokumen, setDataSyaratDokumen] = useState<DataItem[]>([]);
const [dataPengajuan, setDataPengajuan] = useState<DataPengajuan | {}>({});
const [status, setStatus] = useState("");
const [loadingFetchData, setLoadingFetchData] = useState(false);
const [formSurat, setFormSurat] = useState<FormUpdateSurat>({
dataPelengkap: [],
syaratDokumen: [],
@@ -394,6 +398,7 @@ function DataUpdate({
async function fetchData() {
try {
setLoadingFetchData(true);
const res = await apiFetch.api.pelayanan["detail-data"].post({
nomerPengajuan: noPengajuan,
});
@@ -421,6 +426,8 @@ function DataUpdate({
}
} catch (error) {
console.error("Error fetching data:", error);
} finally {
setLoadingFetchData(false);
}
}
@@ -600,7 +607,7 @@ function DataUpdate({
return (
<>
<FullScreenLoading visible={submitLoading} />
<FullScreenLoading visible={submitLoading || loadingFetchData} />
<Modal
opened={opened}
onClose={close}
@@ -667,6 +674,7 @@ function DataUpdate({
<Grid.Col span={6} key={index}>
{item.type == "enum" ? (
<Select
disabled={status != "ditolak" && status != "antrian"}
allowDeselect={false}
label={<FieldLabel label={item.name} hint={item.desc} />}
data={item.options ?? []}
@@ -686,6 +694,7 @@ function DataUpdate({
/>
) : item.type == "date" ? (
<DateInput
disabled={status != "ditolak" && status != "antrian"}
locale="id"
valueFormat="DD MMMM YYYY"
label={<FieldLabel label={item.name} hint={item.desc} />}
@@ -712,7 +721,7 @@ function DataUpdate({
(n: any) => n.key === item.key,
)?.value,
)
: parseTanggalID(item.value)
: parseTanggalID(item.value)
}
/>
) : (

View File

@@ -1,4 +1,5 @@
import BreadCrumbs from "@/components/BreadCrumbs";
import FullScreenLoading from "@/components/FullScreenLoading";
import ModalFile from "@/components/ModalFile";
import ModalSurat from "@/components/ModalSurat";
import notification from "@/components/notificationGlobal";
@@ -125,6 +126,7 @@ function DetailDataPengajuan({
const [editValue, setEditValue] = useState({ id: "", jenis: "", val: "", option: null as any, type: "", key: "" })
const [openEdit, setOpenEdit] = useState(false)
const [loadingUpdate, setLoadingUpdate] = useState(false)
const [loadingFS, setLoadingFS] = useState({ value: false, text: "" })
useEffect(() => {
async function fetchHost() {
@@ -143,6 +145,7 @@ function DetailDataPengajuan({
async function sendWA({ status, linkSurat, linkUpdate }: { status: string, linkSurat: string, linkUpdate: string }) {
try {
setLoadingFS({ value: true, text: "Sending message to warga" })
const resWA = await apiFetch.api["send-wa"]["pengajuan-surat"].post({
noPengajuan: data?.noPengajuan ?? "",
jenisSurat: data?.category ?? "",
@@ -181,10 +184,14 @@ function DetailDataPengajuan({
type: "error",
});
}
finally {
setLoadingFS({ value: false, text: "" })
}
}
const handleKonfirmasi = async (cat: "terima" | "tolak") => {
try {
setLoadingFS({ value: true, text: "Updating status" })
const statusFix = cat == "tolak"
? "ditolak"
: data.status == "antrian"
@@ -234,6 +241,8 @@ function DetailDataPengajuan({
message: "Failed to update pengajuan surat",
type: "error",
});
} finally {
setLoadingFS({ value: false, text: "" })
}
};
@@ -275,7 +284,6 @@ function DetailDataPengajuan({
}
useShallowEffect(() => {
console.log('jalan', viewImg)
if (viewImg) {
setOpenedPreviewFile(true);
}
@@ -308,6 +316,8 @@ function DetailDataPengajuan({
return (
<>
<FullScreenLoading visible={loadingFS.value} text={loadingFS.text} />
{/* MODAL EDIT DATA PELENGKAP */}
<Modal
opened={openEdit}