diff --git a/components/details/details-content.tsx b/components/details/details-content.tsx index bfa8d65..3f31e57 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 85855c1..73958cd 100644 --- a/components/landing-page/breaking-news.tsx +++ b/components/landing-page/breaking-news.tsx @@ -4,6 +4,7 @@ import React, { useEffect, useState } from "react"; import Image from "next/image"; import { getListArticle } from "@/service/article"; import Link from "next/link"; +import { getAdvertise } from "@/service/advertisement"; type Article = { id: number; @@ -23,10 +24,47 @@ type Article = { }[]; }; +type Advertise = { + id: number; + title: string; + description: string; + placement: string; + contentFileUrl: string; + redirectLink: string; +}; + export default function BreakingNews() { const [articles, setArticles] = useState([]); const [popular, setPopular] = useState([]); + 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(() => { fetchArticles(); fetchPopular(); @@ -204,13 +242,32 @@ export default function BreakingNews() { {/* Advert */}
- Advertisement + {bannerAd ? ( + +
+ {bannerAd.title +
+
+ ) : ( + Berita Utama + )}
diff --git a/components/landing-page/headers.tsx b/components/landing-page/headers.tsx index 37925e4..bc8ee95 100644 --- a/components/landing-page/headers.tsx +++ b/components/landing-page/headers.tsx @@ -4,6 +4,7 @@ import { useEffect, useState } from "react"; import Image from "next/image"; import { getListArticle } from "@/service/article"; import Link from "next/link"; +import { getAdvertise } from "@/service/advertisement"; type Article = { id: number; @@ -16,9 +17,48 @@ type Article = { categories: { title: string }[]; }; +type Advertise = { + id: number; + title: string; + description: string; + placement: string; + contentFileUrl: string; + redirectLink: string; +}; + export default function HeaderNews() { const [articles, setArticles] = useState([]); + 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(); }, []); @@ -168,13 +208,33 @@ export default function HeaderNews() {
{/* Banner bawah */} -
- Kolom PPS +
+ {bannerAd ? ( + +
+ {bannerAd.title +
+
+ ) : ( + Berita Utama + )}
); diff --git a/components/landing-page/story.tsx b/components/landing-page/story.tsx index ad2718b..c1d35f1 100644 --- a/components/landing-page/story.tsx +++ b/components/landing-page/story.tsx @@ -4,6 +4,7 @@ import { useEffect, useState } from "react"; import Image from "next/image"; import { getListArticle } from "@/service/article"; import Link from "next/link"; +import { getAdvertise } from "@/service/advertisement"; type Article = { id: number; @@ -15,9 +16,46 @@ type Article = { categories: { title: string }[]; }; +type Advertise = { + id: number; + title: string; + description: string; + placement: string; + contentFileUrl: string; + redirectLink: string; +}; + export default function Story() { const [articles, setArticles] = useState([]); + 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(); }, []); @@ -75,13 +113,33 @@ export default function Story() { ))} -
- Kolom PPS +
+ {bannerAd ? ( + +
+ {bannerAd.title +
+
+ ) : ( + Berita Utama + )}