fix: rollback spit convert, and content view in task TA

This commit is contained in:
Sabda Yagra 2025-12-02 09:16:01 +07:00
parent b151325bc0
commit 24ea75de43
3 changed files with 92 additions and 55 deletions

View File

@ -210,57 +210,10 @@ export default function FormConvertSPIT() {
const roleId = getCookiesDecrypt("urie");
const [isUserMabesApprover, setIsUserMabesApprover] = useState(false);
// Gunakan channel untuk sync antar tab
const publishChannel = useRef<BroadcastChannel | null>(null);
useEffect(() => {
initializeComponent();
// Init broadcast channel
publishChannel.current = new BroadcastChannel("spit-publish-channel");
// Listener untuk update dari tab lain
publishChannel.current.onmessage = (event) => {
if (event.data === "SPIT_PUBLISHED") {
setIsAlreadySaved(true);
MySwal.fire({
title: "Konten Sudah Dipublish",
text: "Konten ini sudah dipublish dari tab lain. Halaman akan di-refresh.",
icon: "info",
confirmButtonColor: "#3085d6",
}).then(() => {
loadDetail(); // Refresh data terbaru
});
}
};
return () => {
publishChannel.current?.close();
};
}, []);
useEffect(() => {
const interval = setInterval(async () => {
if (detail?.id) {
const response = await detailSPIT(detail.id);
const latest = response?.data?.data;
if (latest?.isPublish && !isAlreadySaved) {
setIsAlreadySaved(true);
MySwal.fire({
title: "Konten Sudah Dipublish",
text: "Konten ini sudah dipublish dari tab lain. Halaman akan di-refresh.",
icon: "info",
confirmButtonColor: "#3085d6",
}).then(() => loadDetail());
}
}
}, 3000);
return () => clearInterval(interval);
}, [detail, isAlreadySaved]);
useEffect(() => {
checkUserPermissions();
}, [userLevelId, roleId]);
@ -671,9 +624,6 @@ export default function FormConvertSPIT() {
await convertSPIT(requestData);
// Broadcast ke semua tab bahwa konten ini sudah publish
publishChannel.current?.postMessage("SPIT_PUBLISHED");
MySwal.fire({
title: "Success",
text: "Data saved successfully",

View File

@ -173,9 +173,16 @@ interface UploadResult {
creatorGroup: string;
}
// interface FileUploaded {
// id: number;
// url: string;
// }
interface FileUploaded {
id: number;
url: string;
fileName: string;
fileTypeId: number;
}
export default function FormTaskTaDetail() {
@ -401,6 +408,19 @@ export default function FormTaskTaDetail() {
fetchAcceptanceStatus();
}, [id]);
const getViewerUrl = (url: string) => {
const ext = url.split(".").pop()?.toLowerCase();
if (ext === "pdf") {
return url; // langsung tampilkan PDF
}
// doc / docx → pakai Google Viewer, lebih compatible
return `https://docs.google.com/viewer?url=${encodeURIComponent(
url
)}&embedded=true`;
};
useEffect(() => {
const fetchExpertsForCompetencies = async () => {
const allExperts: any[] = [];
@ -502,7 +522,7 @@ export default function FormTaskTaDetail() {
const urls = details.urls.map(
(urlObj: any) => urlObj.attachmentUrl || ""
);
setUrlInputs(urls); // Save the URLs to state
setUrlInputs(urls);
}
if (details?.assignedToLevel) {
@ -967,7 +987,13 @@ export default function FormTaskTaDetail() {
wavesurfer && wavesurfer.playPause();
};
const handleRemoveFile = (id: number) => {};
// const handleRemoveFile = (id: number) => {};
const handleRemoveFile = (file: FileUploaded) => {
console.log(file);
// contoh kalau kamu mau hapus dari state:
setVideoUploadedFiles((prev) => prev.filter((f) => f.id !== file.id));
};
const handleSearch = (e: React.ChangeEvent<HTMLInputElement>) => {
setSearch(e.target.value); // Perbarui state search
@ -1255,6 +1281,38 @@ export default function FormTaskTaDetail() {
</Button>
</div>
))}
{/* {videoUploadedFiles?.map((file, index) => (
<div
key={index}
className="flex justify-between border px-3.5 py-3 my-6 rounded-md"
>
<div
className="flex gap-3 items-center cursor-pointer"
onClick={() =>
setSelectedVideo(
`https://mediahub.polri.go.id/api/v2/assignment-expert/file/viewer?id=${file.id}`
)
}
>
<VideoIcon />
<div>
<div className="text-sm text-card-foreground">
{file.fileName}
</div>
</div>
</div>
<Button
size="icon"
color="destructive"
variant="outline"
className="border-none rounded-full"
onClick={() => handleRemoveFile(file)}
>
<Icon icon="tabler:x" className="h-5 w-5" />
</Button>
</div>
))} */}
</div>
</div>
<div>
@ -1312,12 +1370,16 @@ export default function FormTaskTaDetail() {
<div>
{selectedText && (
<Card className="mt-2">
<iframe
{/* <iframe
className="w-full h-96 rounded-md"
src={`https://view.officeapps.live.com/op/embed.aspx?src=${encodeURIComponent(
selectedText
)}`}
title={"Document"}
/> */}
<iframe
className="w-full h-96"
src={getViewerUrl(selectedText)}
/>
</Card>
)}
@ -1454,6 +1516,27 @@ export default function FormTaskTaDetail() {
)}
{isRecording && <p>Recording... {timer} seconds remaining</p>}{" "}
{/* Display remaining time */}
<div className="mt-4">
<Label>Link Url</Label>
{urlInputs.map((url: any, index: any) => (
<Link
key={url.id}
href={url}
target="_blank"
className="flex items-center gap-2 mt-2"
>
<input
type="url"
className="border rounded p-2 w-full cursor-pointer"
value={url}
// onChange={(e) =>
// handleLinkChange(index, e.target.value)
// }
placeholder={`Masukkan link berita ${index + 1}`}
/>
</Link>
))}
</div>
</div>
</div>
</div>

View File

@ -261,6 +261,10 @@ export default function FormTaskTa() {
};
const save = async (data: TaskSchema) => {
const cleanedLinks = links
.map((link) => link.trim())
.filter((link) => link !== "" && link.startsWith("http"));
const requestData: {
id?: number;
title: string;
@ -269,7 +273,7 @@ export default function FormTaskTa() {
narration: string;
assignmentType: string;
expertCompetencies: string;
// attachmentUrl: string[];
attachmentUrl: string[];
} = {
...data,
assignedToUsers: handleExpertChange(),
@ -278,7 +282,7 @@ export default function FormTaskTa() {
narration: data.narration,
expertCompetencies: Array.from(selectedCompetencies).join(","),
title: data.title,
// attachmentUrl: links,
attachmentUrl: cleanedLinks,
};
const response = await createTaskTa(requestData);