diff --git a/components/details/details-content.tsx b/components/details/details-content.tsx index a70e778..832dfeb 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 { CommentIcon } from "../icons/sidebar-icon"; import { Link2, MailIcon } from "lucide-react"; +import { getAdvertise } from "@/service/advertisement"; type TabKey = "trending" | "comments" | "latest"; @@ -33,6 +34,15 @@ interface CategoryType { value: number; } +type Advertise = { + id: number; + title: string; + description: string; + placement: string; + contentFileUrl: string; + redirectLink: string; +}; + export default function DetailContent() { const params = useParams(); const id = params?.id; @@ -68,6 +78,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 === "banner"); + + if (banner) { + setBannerAd(banner); + } + } catch (err) { + console.error("Error fetching advertisement:", err); + } + } + useEffect(() => { initState(); }, [page, showData, startDateValue, selectedCategories]); @@ -184,7 +224,8 @@ export default function DetailContent() { - {articleDetail?.createdByName} + {articleDetail?.customCreatorName || + articleDetail?.createdByName} - @@ -382,7 +423,8 @@ export default function DetailContent() { {/* Info Author */}

- {articleDetail?.createdByName} + {articleDetail?.customCreatorName || + articleDetail?.createdByName}

@@ -424,12 +466,32 @@ export default function DetailContent() {
- Berita Utama + {bannerAd ? ( + +
+ {bannerAd.title +
+
+ ) : ( + Berita Utama + )}

Tinggalkan Balasan

diff --git a/components/form/article/create-article-form.tsx b/components/form/article/create-article-form.tsx index 1f6b448..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( () => { @@ -82,6 +89,9 @@ const createArticleSchema = z.object({ title: z.string().min(2, { message: "Judul harus diisi", }), + customCreatorName: z.string().min(2, { + message: "Judul harus diisi", + }), slug: z.string().min(2, { message: "Slug harus diisi", }), @@ -94,6 +104,7 @@ const createArticleSchema = z.object({ tags: z.array(z.string()).nonempty({ message: "Minimal 1 tag", }), + source: z.enum(["internal", "external"]).optional(), }); export default function CreateArticleForm() { @@ -117,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) => { @@ -225,6 +236,8 @@ export default function CreateArticleForm() { const request = { id: diseData?.id, title: values.title, + customCreatorName: values.customCreatorName, + source: values.source, articleBody: removeImgTags(values.description), metaDescription: diseData?.metaDescription, metaTitle: diseData?.metaTitle, @@ -280,6 +293,8 @@ export default function CreateArticleForm() { title: values.title, typeId: 1, slug: values.slug, + customCreatorName: values.customCreatorName, + source: values.source, categoryIds: values.category.map((a) => a.id).join(","), tags: values.tags.join(","), description: htmlToString(removeImgTags(values.description)), @@ -324,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(); @@ -524,13 +561,21 @@ export default function CreateArticleForm() { Single Article - Content Rewrite + {/* Content Rewrite */} {selectedWritingType === "single" ? ( { setDiseData(data); + // setValue("title", data?.title ?? "", { + // shouldValidate: true, + // shouldDirty: true, + // }); + // setValue("slug", generateSlug(data?.title ?? ""), { + // shouldValidate: true, + // shouldDirty: true, + // }); setValue( "description", data?.articleBody ? data?.articleBody : "" @@ -651,7 +696,38 @@ export default function CreateArticleForm() { )} )} - +

Kreator

+ ( + + )} + /> +
+

Tipe Kreator

+ ( + + )} + /> +

Kategori

{ + onChange(selected); + }} closeMenuOnSelect={false} components={animatedComponents} isClearable={true} @@ -683,60 +762,7 @@ export default function CreateArticleForm() { )}

Tags

- {/* ( -