diff --git a/app/[locale]/(protected)/admin/media-tracking/detail/component/column.tsx b/app/[locale]/(protected)/admin/media-tracking/detail/component/column.tsx index 703bc9ce..62e32d12 100644 --- a/app/[locale]/(protected)/admin/media-tracking/detail/component/column.tsx +++ b/app/[locale]/(protected)/admin/media-tracking/detail/component/column.tsx @@ -31,6 +31,7 @@ import { DialogTrigger, } from "@/components/ui/dialog"; import { Collapsible, CollapsibleContent } from "@/components/ui/collapsible"; +import { validateMediaLink } from "@/service/media-tracking/media-tracking"; const columns: ColumnDef[] = [ { @@ -52,12 +53,85 @@ const columns: ColumnDef[] = [ {row.getValue("title")} ), }, + // { + // accessorKey: "link", + // header: "Link Berita", + // cell: ({ row }) => ( + // {row.getValue("link")} + // ), + // }, { accessorKey: "link", header: "Link Berita", - cell: ({ row }) => ( - {row.getValue("link")} - ), + cell: ({ row }) => { + const link = row.getValue("link"); + + if (!link) { + return -; + } + + return ( + + {link} + + ); + }, + }, + { + id: "validation", + header: "Validasi", + cell: ({ row, table }) => { + const original = row.original; + + const isValid = original.isValid; + const link = original.link; + + const updateRow = (data: Partial) => { + table.options.meta?.updateData(row.index, data); + }; + + const handleValid = async () => { + await validateMediaLink(original.id, true); + updateRow({ isValid: true }); + }; + + const handleInvalid = async () => { + await validateMediaLink(original.id, false); + updateRow({ isValid: false, link: undefined }); + }; + + if (!link) { + return -; + } + + if (isValid === true) { + return ( + + ); + } + + return ( +
+ + +
+ ); + }, }, ]; diff --git a/app/[locale]/(protected)/admin/media-tracking/detail/component/table.tsx b/app/[locale]/(protected)/admin/media-tracking/detail/component/table.tsx index 1992be8f..f6230e7f 100644 --- a/app/[locale]/(protected)/admin/media-tracking/detail/component/table.tsx +++ b/app/[locale]/(protected)/admin/media-tracking/detail/component/table.tsx @@ -253,7 +253,7 @@ const NewsDetailTable = () => { totalData={totalData} totalPage={totalPage} /> - + ); }; diff --git a/app/[locale]/(protected)/admin/media-tracking/results/component/column.tsx b/app/[locale]/(protected)/admin/media-tracking/results/component/column.tsx index 97fb2ec1..d06179ad 100644 --- a/app/[locale]/(protected)/admin/media-tracking/results/component/column.tsx +++ b/app/[locale]/(protected)/admin/media-tracking/results/component/column.tsx @@ -1,7 +1,7 @@ import * as React from "react"; import { ColumnDef } from "@tanstack/react-table"; -import { Eye, MoreVertical, SquarePen, Trash2 } from "lucide-react"; +import { DownloadIcon, Eye, MoreVertical, SquarePen, Trash2 } from "lucide-react"; import { cn } from "@/lib/utils"; import { DropdownMenu, @@ -141,13 +141,17 @@ const columns: ColumnDef[] = [ - + View  {row.original.mediaUpload.fileType.secondaryName && row.original.mediaUpload.fileType.secondaryName.toLowerCase()} + + +

Download

+
); diff --git a/components/landing-page/advertisement-placements.tsx b/components/landing-page/advertisement-placements.tsx index 41e60e61..9f8cd6dc 100644 --- a/components/landing-page/advertisement-placements.tsx +++ b/components/landing-page/advertisement-placements.tsx @@ -80,7 +80,8 @@ // }; // export default AdvertisementPlacements; -import { listDataAdvertisements } from "@/service/broadcast/broadcast"; +"use client"; + import { useEffect, useState } from "react"; import * as React from "react"; import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog"; @@ -93,35 +94,40 @@ interface Advertisement { [key: string]: any; } -const AdvertisementPlacements = (props: { +interface AdvertisementPlacementsProps { placement: string; - data: Advertisement[]; + data?: Advertisement[]; // ⬅️ PENTING: optional loading: boolean; -}) => { - const [ads, setAds] = useState([]); +} + +const AdvertisementPlacements = ({ + placement, + data = [], // ⬅️ DEFAULT VALUE (KUNCI UTAMA) + loading, +}: AdvertisementPlacementsProps) => { + const [ads, setAds] = useState<(Advertisement | undefined)[]>([]); useEffect(() => { - if (!props.loading && props.data.length > 0) { - const filtered = props.data.filter((a) => - a.placements.includes(props.placement) - ); + if (loading || data.length === 0) return; - let temps: Advertisement[] | undefined[] = []; - temps[0] = filtered.find((b) => b.placements.includes("top")); - temps[1] = filtered.find((b) => b.placements.includes("bottom")); - setAds(temps); - } - }, [props.data, props.loading, props.placement]); + const filtered = data.filter((a) => a.placements?.includes(placement)); + + const temps: (Advertisement | undefined)[] = []; + temps[0] = filtered.find((b) => b.placements?.includes("top")); + temps[1] = filtered.find((b) => b.placements?.includes("bottom")); + + setAds(temps); + }, [data, loading, placement]); return (
- {props.loading &&

Loading...

} + {loading &&

Loading...

} - {ads?.map( + {ads.map( (ad) => ad && ( @@ -132,6 +138,7 @@ const AdvertisementPlacements = (props: { className="w-full cursor-pointer rounded-lg shadow-md hover:opacity-90 transition" /> + { + console.log("API DUMMY:", { id, isValid }); + + return new Promise((resolve) => { + setTimeout(() => { + resolve({ + success: true, + isValid, + }); + }, 600); + }); +}; diff --git a/src/types/react-table.d.ts b/src/types/react-table.d.ts new file mode 100644 index 00000000..682a93a0 --- /dev/null +++ b/src/types/react-table.d.ts @@ -0,0 +1,8 @@ +// src/types/react-table.d.ts +import "@tanstack/react-table"; + +declare module "@tanstack/react-table" { + interface TableMeta { + updateData: (rowIndex: number, value: Partial) => void; + } +}