feat:approval

This commit is contained in:
Rama Priyanto 2025-01-02 13:24:16 +07:00
parent 5b9f3b27cc
commit 2f745162a2
1 changed files with 138 additions and 26 deletions

View File

@ -43,7 +43,8 @@ import {
DialogTitle, DialogTitle,
} from "@/components/ui/dialog"; } from "@/components/ui/dialog";
import { Textarea } from "@/components/ui/textarea"; import { Textarea } from "@/components/ui/textarea";
import { error, loading } from "@/config/swal"; import { close, error, loading } from "@/config/swal";
import { te } from "date-fns/locale";
const imageSchema = z.object({ const imageSchema = z.object({
title: z.string().min(1, { message: "Judul diperlukan" }), title: z.string().min(1, { message: "Judul diperlukan" }),
@ -112,6 +113,7 @@ export default function FormImageDetail() {
const [selectedPublishers, setSelectedPublishers] = useState<number[]>([]); const [selectedPublishers, setSelectedPublishers] = useState<number[]>([]);
const [description, setDescription] = useState(""); const [description, setDescription] = useState("");
const [main, setMain] = useState<any>([]); const [main, setMain] = useState<any>([]);
const [filePlacements, setFilePlacements] = useState<string[][]>([]);
const [selectedTarget, setSelectedTarget] = useState(""); const [selectedTarget, setSelectedTarget] = useState("");
const [files, setFiles] = useState<FileType[]>([]); const [files, setFiles] = useState<FileType[]>([]);
@ -190,6 +192,14 @@ export default function FormImageDetail() {
} }
}; };
const setupPlacementCheck = (length: number) => {
const temp = [];
for (let i = 0; i < length; i++) {
temp.push([]);
}
setFilePlacements(temp);
};
useEffect(() => { useEffect(() => {
async function initState() { async function initState() {
if (id) { if (id) {
@ -204,6 +214,7 @@ export default function FormImageDetail() {
names: details?.files[0]?.fileName, names: details?.files[0]?.fileName,
format: details?.files[0]?.format, format: details?.files[0]?.format,
}); });
setupPlacementCheck(details?.files?.length);
if (details.publishedForObject) { if (details.publishedForObject) {
const publisherIds = details.publishedForObject.map( const publisherIds = details.publishedForObject.map(
@ -227,9 +238,16 @@ export default function FormImageDetail() {
}, [refresh, setValue]); }, [refresh, setValue]);
const actionApproval = (e: string) => { const actionApproval = (e: string) => {
const temp = [];
for (const element of detail.files) {
temp.push([]);
}
setFilePlacements(temp);
setStatus(e); setStatus(e);
setModalOpen(true); setFiles(detail.files);
setDescription(""); setDescription("");
setModalOpen(true);
}; };
const submit = async () => { const submit = async () => {
@ -238,31 +256,44 @@ export default function FormImageDetail() {
Number(status) == 2 || Number(status) == 2 ||
Number(status) == 4 Number(status) == 4
) { ) {
MySwal.fire({ save();
title: "Simpan Approval",
text: "", // MySwal.fire({
icon: "warning", // title: "Simpan Approval",
showCancelButton: true, // text: "",
cancelButtonColor: "#d33", // icon: "warning",
confirmButtonColor: "#3085d6", // showCancelButton: true,
confirmButtonText: "Simpan", // cancelButtonColor: "#d33",
}).then((result) => { // confirmButtonColor: "#3085d6",
if (result.isConfirmed) { // confirmButtonText: "Simpan",
save(); // }).then((result) => {
} // if (result.isConfirmed) {
}); // save();
// }
// });
} }
}; };
const getPlacement = () => {
console.log("getPlaa", filePlacements);
const temp = [];
for (let i = 0; i < filePlacements?.length; i++) {
if (filePlacements[i].length !== 0) {
const now = filePlacements[i].filter((a) => a !== "all");
const data = { mediaFileId: files[i].id, placement: now.join(",") };
temp.push(data);
}
}
return temp;
};
async function save() { async function save() {
const data = { const data = {
mediaUploadId: id, mediaUploadId: id,
statusId: status, statusId: status,
message: description, message: description,
files: [], files: isMabesApprover ? getPlacement() : [],
// files: isMabesApprover ? getPlacement() : [],
}; };
loading(); loading();
const response = await submitApproval(data); const response = await submitApproval(data);
@ -275,6 +306,8 @@ export default function FormImageDetail() {
listFiles: rejectedFiles, listFiles: rejectedFiles,
}; };
console.log("reject", dataReject);
const resReject = await rejectFiles(dataReject); const resReject = await rejectFiles(dataReject);
if (resReject?.error) { if (resReject?.error) {
@ -286,6 +319,38 @@ export default function FormImageDetail() {
return false; return false;
} }
const setupPlacement = (
index: number,
placement: string,
checked: boolean
) => {
let temp = [...filePlacements];
if (checked) {
if (placement === "all") {
temp[index] = ["all", "mabes", "polda", "international"];
} else {
const now = temp[index];
now.push(placement);
if (now.length === 3 && !now.includes("all")) {
now.push("all");
}
temp[index] = now;
}
} else {
if (placement === "all") {
temp[index] = [];
} else {
const now = temp[index].filter((a) => a !== placement);
console.log("now", now);
temp[index] = now;
if (now.length === 3 && now.includes("all")) {
const newData = now.filter((b) => b !== "all");
temp[index] = newData;
}
}
}
setFilePlacements(temp);
};
function handleDeleteFileApproval(id: number) { function handleDeleteFileApproval(id: number) {
const selectedFiles = files.filter((file) => file.id != id); const selectedFiles = files.filter((file) => file.id != id);
@ -606,7 +671,7 @@ export default function FormImageDetail() {
<DialogTitle>Berikan Komentar</DialogTitle> <DialogTitle>Berikan Komentar</DialogTitle>
</DialogHeader> </DialogHeader>
{status == "2" {status == "2"
? files?.map((file) => ( ? files?.map((file, index) => (
<div <div
key={file.id} key={file.id}
className="flex flex-row gap-2 items-center" className="flex flex-row gap-2 items-center"
@ -615,13 +680,26 @@ export default function FormImageDetail() {
<div className="flex flex-col gap-2 w-full"> <div className="flex flex-col gap-2 w-full">
<div className="flex justify-between text-sm"> <div className="flex justify-between text-sm">
{file.fileName} {file.fileName}
<a> <a
onClick={() =>
handleDeleteFileApproval(file.id)
}
>
<Icon icon="humbleicons:times" color="red" /> <Icon icon="humbleicons:times" color="red" />
</a> </a>
</div> </div>
<div className="flex flex-row gap-2"> <div className="flex flex-row gap-2">
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">
<Checkbox id="terms" /> <Checkbox
id="terms"
value="all"
checked={filePlacements[index]?.includes(
"all"
)}
onCheckedChange={(e) =>
setupPlacement(index, "all", Boolean(e))
}
/>
<label <label
htmlFor="terms" htmlFor="terms"
className="text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" className="text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
@ -630,7 +708,15 @@ export default function FormImageDetail() {
</label> </label>
</div> </div>
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">
<Checkbox id="terms" /> <Checkbox
id="terms"
checked={filePlacements[index]?.includes(
"mabes"
)}
onCheckedChange={(e) =>
setupPlacement(index, "mabes", Boolean(e))
}
/>
<label <label
htmlFor="terms" htmlFor="terms"
className="text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" className="text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
@ -639,7 +725,15 @@ export default function FormImageDetail() {
</label> </label>
</div> </div>
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">
<Checkbox id="terms" /> <Checkbox
id="terms"
checked={filePlacements[index]?.includes(
"polda"
)}
onCheckedChange={(e) =>
setupPlacement(index, "polda", Boolean(e))
}
/>
<label <label
htmlFor="terms" htmlFor="terms"
className="text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" className="text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
@ -649,7 +743,19 @@ export default function FormImageDetail() {
</div> </div>
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">
<Checkbox id="terms" /> <Checkbox
id="terms"
checked={filePlacements[index]?.includes(
"international"
)}
onCheckedChange={(e) =>
setupPlacement(
index,
"international",
Boolean(e)
)
}
/>
<label <label
htmlFor="terms" htmlFor="terms"
className="text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" className="text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
@ -737,13 +843,19 @@ export default function FormImageDetail() {
</div> </div>
)} )}
<DialogFooter> <DialogFooter>
<Button type="button" color="primary"> <Button
type="button"
color="primary"
onClick={() => submit()}
>
Submit Submit
</Button> </Button>
<Button <Button
type="button" type="button"
color="destructive" color="destructive"
onClick={() => setModalOpen(false)} onClick={() => {
setModalOpen(false);
}}
> >
Cancel Cancel
</Button> </Button>