fix: fixing placement in spit polda

This commit is contained in:
Sabda Yagra 2025-09-29 13:39:08 +07:00
parent c65afe8ced
commit 92e300a0cf
1 changed files with 48 additions and 39 deletions

View File

@ -7,8 +7,6 @@ import { useParams, useRouter } from "next/navigation";
import { useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
import dynamic from "next/dynamic"; import dynamic from "next/dynamic";
import Cookies from "js-cookie"; import Cookies from "js-cookie";
// UI Components
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label"; import { Label } from "@/components/ui/label";
@ -26,8 +24,6 @@ import {
} from "@/components/ui/select"; } from "@/components/ui/select";
import { Checkbox } from "@/components/ui/checkbox"; import { Checkbox } from "@/components/ui/checkbox";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
// Icons
import { import {
AlertCircle, AlertCircle,
FileText, FileText,
@ -44,8 +40,6 @@ import {
CheckCircle, CheckCircle,
XCircle, XCircle,
} from "lucide-react"; } from "lucide-react";
// Swiper
import { Swiper, SwiperSlide } from "swiper/react"; import { Swiper, SwiperSlide } from "swiper/react";
import { Swiper as SwiperType } from "swiper"; import { Swiper as SwiperType } from "swiper";
import "swiper/css"; import "swiper/css";
@ -54,8 +48,6 @@ import "swiper/css/navigation";
import "swiper/css/pagination"; import "swiper/css/pagination";
import "swiper/css/thumbs"; import "swiper/css/thumbs";
import { FreeMode, Navigation, Pagination, Thumbs } from "swiper/modules"; import { FreeMode, Navigation, Pagination, Thumbs } from "swiper/modules";
// Services
import { import {
convertSPIT, convertSPIT,
deleteSPIT, deleteSPIT,
@ -64,15 +56,12 @@ import {
listEnableCategory, listEnableCategory,
} from "@/service/content/content"; } from "@/service/content/content";
import { generateDataRewrite, getDetailArticle } from "@/service/content/ai"; import { generateDataRewrite, getDetailArticle } from "@/service/content/ai";
// Utils
import { getCookiesDecrypt } from "@/lib/utils"; import { getCookiesDecrypt } from "@/lib/utils";
import { error } from "@/lib/swal"; import { error } from "@/lib/swal";
import Swal from "sweetalert2"; import Swal from "sweetalert2";
import withReactContent from "sweetalert2-react-content"; import withReactContent from "sweetalert2-react-content";
import { close, loading } from "@/config/swal"; import { close, loading } from "@/config/swal";
// Types
interface Category { interface Category {
id: number; id: number;
name: string; name: string;
@ -289,9 +278,7 @@ export default function FormConvertSPIT() {
try { try {
const response = await getTagsBySubCategoryId(categoryId); const response = await getTagsBySubCategoryId(categoryId);
if (response?.data?.data?.length > 0) { if (response?.data?.data?.length > 0) {
// Extract tag names from the response objects
const apiTags = response?.data?.data?.map((tag: any) => tag.tagName); const apiTags = response?.data?.data?.map((tag: any) => tag.tagName);
// Merge with existing tags, ensuring uniqueness
const tagsMerge = Array.from(new Set([...tags, ...apiTags])); const tagsMerge = Array.from(new Set([...tags, ...apiTags]));
setTags(tagsMerge); setTags(tagsMerge);
} }
@ -313,7 +300,6 @@ export default function FormConvertSPIT() {
setDetail(details); setDetail(details);
// <-- use API contentList objects directly -->
const contentList: FileType[] = (details.contentList || []).map( const contentList: FileType[] = (details.contentList || []).map(
(it: any) => ({ (it: any) => ({
contentId: it.contentId, contentId: it.contentId,
@ -329,11 +315,9 @@ export default function FormConvertSPIT() {
setFiles(contentList); setFiles(contentList);
setDetailThumb(contentList); setDetailThumb(contentList);
// Initialize file placements
const fileCount = contentList.length || 0; const fileCount = contentList.length || 0;
setFilePlacements(Array(fileCount).fill([])); setFilePlacements(Array(fileCount).fill([]));
// Set form values
setValue("contentTitle", details.contentTitle || ""); setValue("contentTitle", details.contentTitle || "");
setValue("contentDescription", details.contentDescription || ""); setValue("contentDescription", details.contentDescription || "");
setValue("contentCreator", details.contentCreator || ""); setValue("contentCreator", details.contentCreator || "");
@ -342,16 +326,16 @@ export default function FormConvertSPIT() {
(details as any).contentRewriteDescription || "" (details as any).contentRewriteDescription || ""
); );
// Set category and load category tags
if (details.categoryId) { if (details.categoryId) {
setSelectedCategoryId(details.categoryId); setSelectedCategoryId(details.categoryId);
await loadTags(details.categoryId); await loadTags(details.categoryId);
} }
// Set content tags and merge with category tags
if (details.contentTag) { if (details.contentTag) {
const contentTags = details.contentTag.split(",").map((tag: string) => tag.trim()); const contentTags = details.contentTag
setTags(prev => Array.from(new Set([...prev, ...contentTags]))); .split(",")
.map((tag: string) => tag.trim());
setTags((prev) => Array.from(new Set([...prev, ...contentTags])));
} }
} catch (error) { } catch (error) {
console.error("Failed to load detail:", error); console.error("Failed to load detail:", error);
@ -552,14 +536,24 @@ export default function FormConvertSPIT() {
); );
}; };
const getPlacementData = () => { const getPlacementData = (type: string) => {
const placementData: PlacementData[] = []; const placementData: PlacementData[] = [];
for (let i = 0; i < filePlacements.length; i++) { if (type == "mabes") {
if (filePlacements[i].length > 0) { for (let i = 0; i < filePlacements.length; i++) {
const placements = filePlacements[i]; if (filePlacements[i].length > 0) {
const placements = filePlacements[i];
placementData.push({
mediaFileId: files[i].contentId,
placements: placements.join(","),
});
}
}
} else {
for (let i = 0; i < files.length; i++) {
placementData.push({ placementData.push({
mediaFileId: files[i].contentId, mediaFileId: files[i].contentId,
placements: placements.join(","), placements: "polda",
}); });
} }
} }
@ -578,7 +572,6 @@ export default function FormConvertSPIT() {
return temp; return temp;
}; };
// Form submission
const onSubmit = async (data: FormData) => { const onSubmit = async (data: FormData) => {
const pnmhTags = tags.filter((tag) => tag.toLowerCase().includes("pnmh")); const pnmhTags = tags.filter((tag) => tag.toLowerCase().includes("pnmh"));
@ -624,7 +617,9 @@ export default function FormConvertSPIT() {
categoryId: selectedCategoryId, categoryId: selectedCategoryId,
publishedFor: publishedFor.join(","), publishedFor: publishedFor.join(","),
creator: data.contentCreator, creator: data.contentCreator,
files: isUserMabesApprover ? getPlacementData() : [], files: isUserMabesApprover
? getPlacementData("mabes")
: getPlacementData("polda"),
}; };
await convertSPIT(requestData); await convertSPIT(requestData);
@ -978,7 +973,10 @@ export default function FormConvertSPIT() {
centeredSlides={true} centeredSlides={true}
> >
{detailThumb.map((item) => ( {detailThumb.map((item) => (
<SwiperSlide key={item.contentId} className="!w-full"> <SwiperSlide
key={item.contentId}
className="!w-full"
>
{item.contentType === "VIDEO" ? ( {item.contentType === "VIDEO" ? (
<div className="relative w-full h-96 overflow-hidden rounded-lg"> <div className="relative w-full h-96 overflow-hidden rounded-lg">
<video <video
@ -989,8 +987,8 @@ export default function FormConvertSPIT() {
poster={item.thumbnailFileUrl || undefined} poster={item.thumbnailFileUrl || undefined}
title={`Video ${item.contentId}`} title={`Video ${item.contentId}`}
onError={(e) => { onError={(e) => {
console.error('Video load error:', e); console.error("Video load error:", e);
e.currentTarget.style.display = 'none'; e.currentTarget.style.display = "none";
}} }}
/> />
</div> </div>
@ -1000,10 +998,13 @@ export default function FormConvertSPIT() {
src={item.contentFile} src={item.contentFile}
alt={`Media ${item.contentId}`} alt={`Media ${item.contentId}`}
className="max-w-full max-h-full object-contain rounded-lg" className="max-w-full max-h-full object-contain rounded-lg"
style={{ maxWidth: '100%', maxHeight: '100%' }} style={{
maxWidth: "100%",
maxHeight: "100%",
}}
onError={(e) => { onError={(e) => {
console.error('Image load error:', e); console.error("Image load error:", e);
e.currentTarget.style.display = 'none'; e.currentTarget.style.display = "none";
}} }}
/> />
</div> </div>
@ -1047,7 +1048,10 @@ export default function FormConvertSPIT() {
preventClicksPropagation={false} preventClicksPropagation={false}
> >
{detailThumb.map((item) => ( {detailThumb.map((item) => (
<SwiperSlide key={`thumb-${item.contentId}`} className="!w-auto flex-shrink-0"> <SwiperSlide
key={`thumb-${item.contentId}`}
className="!w-auto flex-shrink-0"
>
{item.contentType === "VIDEO" ? ( {item.contentType === "VIDEO" ? (
<div className="relative w-20 h-16 rounded cursor-pointer overflow-hidden flex-shrink-0"> <div className="relative w-20 h-16 rounded cursor-pointer overflow-hidden flex-shrink-0">
{/* use preload metadata so browser doesn't download full video */} {/* use preload metadata so browser doesn't download full video */}
@ -1059,8 +1063,11 @@ export default function FormConvertSPIT() {
playsInline playsInline
tabIndex={-1} tabIndex={-1}
onError={(e) => { onError={(e) => {
console.error('Thumbnail video load error:', e); console.error(
e.currentTarget.style.display = 'none'; "Thumbnail video load error:",
e
);
e.currentTarget.style.display = "none";
}} }}
/> />
<div className="absolute inset-0 flex items-center justify-center bg-black/30 pointer-events-none"> <div className="absolute inset-0 flex items-center justify-center bg-black/30 pointer-events-none">
@ -1081,8 +1088,11 @@ export default function FormConvertSPIT() {
alt={`Thumbnail ${item.contentId}`} alt={`Thumbnail ${item.contentId}`}
className="w-full h-full object-cover" className="w-full h-full object-cover"
onError={(e) => { onError={(e) => {
console.error('Thumbnail image load error:', e); console.error(
e.currentTarget.style.display = 'none'; "Thumbnail image load error:",
e
);
e.currentTarget.style.display = "none";
}} }}
/> />
</div> </div>
@ -1138,7 +1148,6 @@ export default function FormConvertSPIT() {
key={file.contentId} key={file.contentId}
className="flex gap-4 p-4 border rounded-lg" className="flex gap-4 p-4 border rounded-lg"
> >
{/* show thumbnail or video preview */}
{file.contentType === "VIDEO" ? ( {file.contentType === "VIDEO" ? (
<video <video
src={file.contentFile} src={file.contentFile}