From 7ced42966b6ad29c8ac4a3733079e249b3569850 Mon Sep 17 00:00:00 2001 From: Anang Yusman Date: Sun, 12 Oct 2025 23:09:52 +0800 Subject: [PATCH] update --- app/page.tsx | 2 +- components/details/details-content.tsx | 349 +++++++++++++----- .../form/article/create-article-form.tsx | 113 +++++- components/form/article/edit-article-form.tsx | 74 +++- .../form/article/generate-ai-single-form.tsx | 13 +- .../citizen-news/citizen-news.tsx | 79 +++- .../citizen-news/header-citizen.tsx | 9 +- .../development/development-news.tsx | 79 +++- .../development/header-development.tsx | 11 +- components/landing-page/header.tsx | 79 +++- .../landing-page/health/header-health.tsx | 9 +- .../landing-page/health/health-news.tsx | 80 +++- .../landing-page/latest-and-popular.tsx | 3 +- components/landing-page/news.tsx | 113 +++++- .../main/dashboard/dashboard-container.tsx | 77 ++-- components/table/article-table.tsx | 41 +- service/article.ts | 3 +- service/master-user.ts | 25 +- utils/global.tsx | 8 + 19 files changed, 922 insertions(+), 245 deletions(-) diff --git a/app/page.tsx b/app/page.tsx index 1f7cd7d..c821a1a 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -23,7 +23,7 @@ export default function Home() { /> -
+
diff --git a/components/details/details-content.tsx b/components/details/details-content.tsx index 662517c..01efbe9 100644 --- a/components/details/details-content.tsx +++ b/components/details/details-content.tsx @@ -4,9 +4,18 @@ import Author from "../landing-page/author"; import { useEffect, useState } from "react"; import Link from "next/link"; import { getArticleById, getListArticle } from "@/service/article"; -import { close, loading } from "@/config/swal"; -import { useParams } from "next/navigation"; +import { close, error, loading } from "@/config/swal"; +import { useParams, usePathname } from "next/navigation"; import { Link2, MailIcon } from "lucide-react"; +import { getAdvertise } from "@/service/advertisement"; +import { saveActivity } from "@/service/activity-log"; +import { + getArticleComment, + otpRequest, + otpValidation, + postArticleComment, +} from "@/service/master-user"; +import { useForm } from "react-hook-form"; type TabKey = "trending" | "comments" | "latest"; @@ -18,6 +27,7 @@ type Article = { categoryName: string; createdAt: string; createdByName: string; + customCreatorName: string; thumbnailUrl: string; categories: { title: string; @@ -34,9 +44,19 @@ 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; + const pathname = usePathname(); const [page, setPage] = useState(1); const [totalPage, setTotalPage] = useState(1); const [articles, setArticles] = useState([]); @@ -62,6 +82,67 @@ export default function DetailContent() { const [tabArticles, setTabArticles] = useState([]); const [activeTab, setActiveTab] = useState("trending"); + const [needOtp, setNeedOtp] = useState(false); + const [otpValue, setOtpValue] = useState(""); + const { register, handleSubmit, reset, watch } = useForm(); + const [commentList, setCommentList] = useState([]); + + useEffect(() => { + fetchData(); + }, [id]); + + const fetchData = async () => { + try { + const res = await getArticleComment(String(id)); + const data = res?.data?.data; + setCommentList(data); + console.log("komen", data); + } catch (err) { + console.error("❌ Gagal memuat komentar:", err); + setCommentList([]); + } + }; + + const onSubmit = async (values: any) => { + if (!needOtp) { + const res = await otpRequest(values.email, values?.name); + if (res?.error) { + error(res.message); + return false; + } + setNeedOtp(true); + } else { + const validation = await otpValidation(values.email, otpValue); + if (validation?.error) { + error("OTP Tidak Sesuai"); + return false; + } + + const data = { + commentFromName: values.name, + commentFromEmail: values.email, + articleId: Number(id), + isPublic: false, + message: values.comment, + parentId: 0, + }; + const res = await postArticleComment(data); + if (res?.error) { + error(res?.message); + return false; + } + const req: any = { + activityTypeId: 5, + url: "https://dev.mikulnews/" + pathname, + articleId: Number(id), + }; + + const resActivity = await saveActivity(req); + reset(); + fetchData(); + setNeedOtp(false); + } + }; const tabs: { id: TabKey; label: string }[] = [ { id: "trending", label: "Trending" }, @@ -69,6 +150,35 @@ 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]; + + const banner = data.find((ad) => ad.placement === "jumbotron"); + + if (banner) { + setBannerAd(banner); + } + } catch (err) { + console.error("Error fetching advertisement:", err); + } + } + useEffect(() => { fetchTabArticles(); }, [activeTab]); @@ -83,7 +193,6 @@ export default function DetailContent() { sortBy: "created_at", }; - // Sesuaikan sortBy berdasarkan tab if (activeTab === "trending") { req.sortBy = "view_count"; } else if (activeTab === "comments") { @@ -92,7 +201,6 @@ export default function DetailContent() { req.sortBy = "created_at"; } - // Hanya kirimkan search jika valid if (search && search !== "-" && search !== "") { req.search = search; } @@ -243,7 +351,7 @@ export default function DetailContent() {
- {articleDetail?.createdByName} + {articleDetail?.customCreatorName || articleDetail?.createdByName} @@ -394,7 +502,8 @@ export default function DetailContent() { {/* Info Author */}

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

@@ -435,14 +544,14 @@ export default function DetailContent() {
-
+ {/*
Berita Utama -
+
*/}
{/*
*

- -
-
- -