diff --git a/components/details/details-content.tsx b/components/details/details-content.tsx index 69e64c0..53d35ca 100644 --- a/components/details/details-content.tsx +++ b/components/details/details-content.tsx @@ -7,6 +7,7 @@ import { close, loading } from "@/config/swal"; import { useParams } from "next/navigation"; import Author from "../landing-page/author"; import { Link2, MailIcon } from "lucide-react"; +import { getAdvertise } from "@/service/advertisement"; type TabKey = "trending" | "comments" | "latest"; @@ -27,6 +28,15 @@ type Article = { }[]; }; +type Advertise = { + id: number; + title: string; + description: string; + placement: string; + contentFileUrl: string; + redirectLink: string; +}; + interface CategoryType { id: number; label: string; @@ -69,6 +79,36 @@ export default function DetailContent() { { id: "latest", label: "Latest" }, ]; + const [bannerAd, setBannerAd] = useState(null); + + useEffect(() => { + initStateAdver(); + }, []); + + async function initStateAdver() { + const req = { + limit: 100, + page: 1, + sort: "desc", + sortBy: "created_at", + isPublish: true, + }; + + try { + const res = await getAdvertise(req); + const data: Advertise[] = res?.data?.data || [1]; + + // filter iklan dengan placement = "banner" + const banner = data.find((ad) => ad.placement === "jumbotron"); + + if (banner) { + setBannerAd(banner); + } + } catch (err) { + console.error("Error fetching advertisement:", err); + } + } + useEffect(() => { fetchTabArticles(); }, [activeTab]); @@ -520,13 +560,32 @@ export default function DetailContent() {
- Iklan + {bannerAd ? ( + +
+ {bannerAd.title +
+
+ ) : ( + Berita Utama + )} diff --git a/components/form/article/create-article-form.tsx b/components/form/article/create-article-form.tsx index 4ef5c90..a8fbe78 100644 --- a/components/form/article/create-article-form.tsx +++ b/components/form/article/create-article-form.tsx @@ -9,7 +9,7 @@ import { CloudUploadIcon, TimesIcon } from "@/components/icons"; import Image from "next/image"; import ReactSelect from "react-select"; import makeAnimated from "react-select/animated"; -import { htmlToString } from "@/utils/global"; +import { convertDateFormatNoTime, htmlToString } from "@/utils/global"; import { close, error, loading, successToast } from "@/config/swal"; import { useRouter } from "next/navigation"; import Link from "next/link"; @@ -44,6 +44,13 @@ import GenerateSingleArticleForm from "./generate-ai-single-form"; import GenerateContentRewriteForm from "./generate-ai-content-rewrite-form"; import { Textarea } from "@/components/ui/textarea"; import { Badge } from "@/components/ui/badge"; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover"; +import { Calendar } from "@/components/ui/calendar"; +import DatePicker from "react-datepicker"; const CustomEditor = dynamic( () => { @@ -121,8 +128,8 @@ export default function CreateArticleForm() { "publish" ); const [isScheduled, setIsScheduled] = useState(false); - - const [startDateValue, setStartDateValue] = useState(null); + const [startDateValue, setStartDateValue] = useState(); + const [startTimeValue, setStartTimeValue] = useState(""); const { getRootProps, getInputProps } = useDropzone({ onDrop: (acceptedFiles) => { @@ -332,12 +339,34 @@ export default function CreateArticleForm() { } } - if (status === "scheduled") { + if (status === "scheduled" && startDateValue) { + // ambil waktu, default 00:00 jika belum diisi + const [hours, minutes] = startTimeValue + ? startTimeValue.split(":").map(Number) + : [0, 0]; + + // gabungkan tanggal + waktu + const combinedDate = new Date(startDateValue); + combinedDate.setHours(hours, minutes, 0, 0); + + // format: 2025-10-08 14:30:00 + const formattedDateTime = `${combinedDate.getFullYear()}-${String( + combinedDate.getMonth() + 1 + ).padStart(2, "0")}-${String(combinedDate.getDate()).padStart( + 2, + "0" + )} ${String(combinedDate.getHours()).padStart(2, "0")}:${String( + combinedDate.getMinutes() + ).padStart(2, "0")}:00`; + const request = { id: articleId, - date: `${startDateValue?.year}-${startDateValue?.month}-${startDateValue?.day}`, + date: formattedDateTime, }; + + console.log("📤 Sending schedule request:", request); const res = await createArticleSchedule(request); + console.log("✅ Schedule response:", res); } close(); @@ -812,32 +841,49 @@ export default function CreateArticleForm() {
- {/* {isScheduled && ( -
-
+ {isScheduled && ( +
+ {/* Pilih tanggal */} +

Tanggal

- + setStartDateValue(date ?? undefined) + } + dateFormat="yyyy-MM-dd" + className="w-full border rounded-lg px-2 py-1 text-black cursor-pointer h-[150px]" + placeholderText="Pilih tanggal" />
+ + {/* Pilih waktu */} +
+

Waktu

+ setStartTimeValue(e.target.value)} + className="w-full border rounded-lg px-2 py-[6px] text-black" + /> +
- )} */} + )}
diff --git a/components/landing-page/breaking-news.tsx b/components/landing-page/breaking-news.tsx index ebf041e..dc7ebc2 100644 --- a/components/landing-page/breaking-news.tsx +++ b/components/landing-page/breaking-news.tsx @@ -6,6 +6,7 @@ import Image from "next/image"; import { Calendar } from "lucide-react"; import { getListArticle } from "@/service/article"; import Link from "next/link"; +import { getAdvertise } from "@/service/advertisement"; type Article = { id: number; @@ -19,6 +20,15 @@ type Article = { files: { fileUrl: string; file_alt: string }[]; }; +type Advertise = { + id: number; + title: string; + description: string; + placement: string; + contentFileUrl: string; + redirectLink: string; +}; + export default function BreakingNews() { const [articles, setArticles] = useState([]); const [editorArticles, setEditorArticles] = useState([]); @@ -26,6 +36,35 @@ export default function BreakingNews() { const [activeTab, setActiveTab] = useState< "trending" | "comments" | "latest" >("trending"); + const [bannerAd, setBannerAd] = useState(null); + + useEffect(() => { + initStateAdver(); + }, []); + + async function initStateAdver() { + const req = { + limit: 100, + page: 1, + sort: "desc", + sortBy: "created_at", + isPublish: true, + }; + + try { + const res = await getAdvertise(req); + const data: Advertise[] = res?.data?.data || []; + + // filter iklan dengan placement = "banner" + const banner = data.find((ad) => ad.placement === "banner"); + + if (banner) { + setBannerAd(banner); + } + } catch (err) { + console.error("Error fetching advertisement:", err); + } + } useEffect(() => { fetchArticles(); @@ -141,12 +180,32 @@ export default function BreakingNews() {
)}
- Kolom PPS + {bannerAd ? ( + +
+ {bannerAd.title +
+
+ ) : ( + Berita Utama + )}
@@ -206,12 +265,32 @@ export default function BreakingNews() {
- Kolom PPS + {bannerAd ? ( + +
+ {bannerAd.title +
+
+ ) : ( + Berita Utama + )}
{/* News Index Section */}
@@ -335,21 +414,34 @@ export default function BreakingNews() { ))}
- Berita Utama -
-
- Berita Utama + {bannerAd ? ( + +
+ {bannerAd.title +
+
+ ) : ( + Berita Utama + )}
+ {/* Follow Us Section */}

@@ -437,8 +529,33 @@ export default function BreakingNews() {

{/* Banner Slot */} -
- KOLOM PPS +
+ {bannerAd ? ( + +
+ {bannerAd.title +
+
+ ) : ( + Berita Utama + )}
); diff --git a/components/landing-page/news.tsx b/components/landing-page/news.tsx index 45bf0c3..3db1689 100644 --- a/components/landing-page/news.tsx +++ b/components/landing-page/news.tsx @@ -5,6 +5,7 @@ import Image from "next/image"; import { getListArticle } from "@/service/article"; import Link from "next/link"; import { usePathname } from "next/navigation"; +import { getAdvertise } from "@/service/advertisement"; type Article = { id: number; @@ -23,10 +24,48 @@ type Article = { }[]; }; +type Advertise = { + id: number; + title: string; + description: string; + placement: string; + contentFileUrl: string; + redirectLink: string; +}; + export default function BumnNews() { const [articles, setArticles] = useState([]); const [popular, setPopular] = useState([]); - const pathname = usePathname(); // ⬅️ "/bumn-news" misalnya + const pathname = usePathname(); + const [bannerAd, setBannerAd] = useState(null); + + useEffect(() => { + initStateAdver(); + }, []); + + async function initStateAdver() { + const req = { + limit: 100, + page: 1, + sort: "desc", + sortBy: "created_at", + isPublish: true, + }; + + try { + const res = await getAdvertise(req); + const data: Advertise[] = res?.data?.data || [1]; + + // filter iklan dengan placement = "banner" + const banner = data.find((ad) => ad.placement === "jumbotron"); + + if (banner) { + setBannerAd(banner); + } + } catch (err) { + console.error("Error fetching advertisement:", err); + } + } // ⬅️ "/bumn-news" misalnya const categoryName = pathname .split("/") @@ -215,13 +254,32 @@ export default function BumnNews() { {/* Advert */}
- Advertisement + {bannerAd ? ( + +
+ {bannerAd.title +
+
+ ) : ( + Berita Utama + )}