From 049f0cf8fc3edd62d9b9a37f0a796f7760d5314c Mon Sep 17 00:00:00 2001 From: Rama Priyanto Date: Fri, 31 Jan 2025 19:42:40 +0700 Subject: [PATCH] feat:comment article, fix:polda filter --- components/icons.tsx | 4 +- components/landing/HeaderNews.tsx | 2 +- components/landing/NewsTicker.tsx | 2 +- components/landing/RegionalNews.tsx | 19 +- components/landing/SidebarNav.tsx | 4 +- .../main/dashboard/chart/column-chart.tsx | 1 - components/main/detail/comment.tsx | 553 +++++++++++++----- components/main/detail/list-news.tsx | 11 +- components/main/detail/new-detail.tsx | 4 +- components/ui/social-media/gpr-kominfo.tsx | 34 +- messages/en.json | 3 +- messages/id.json | 3 +- package-lock.json | 10 + package.json | 1 + service/master-user.ts | 31 +- styles/globals.css | 4 + 16 files changed, 509 insertions(+), 177 deletions(-) diff --git a/components/icons.tsx b/components/icons.tsx index ab6d419..fa90a7e 100644 --- a/components/icons.tsx +++ b/components/icons.tsx @@ -107,7 +107,7 @@ export const SendIcon: React.FC = ({ fill="none" xmlns="http://www.w3.org/2000/svg" > - + diff --git a/components/landing/HeaderNews.tsx b/components/landing/HeaderNews.tsx index 330d447..5d0b817 100644 --- a/components/landing/HeaderNews.tsx +++ b/components/landing/HeaderNews.tsx @@ -135,7 +135,7 @@ export default function HeaderNews() { key={data?.id} className="hidden lg:block" > - {data.title}{" "} + {textEllipsis(data.title, 66)}

diff --git a/components/landing/NewsTicker.tsx b/components/landing/NewsTicker.tsx index 4771286..353ba7f 100644 --- a/components/landing/NewsTicker.tsx +++ b/components/landing/NewsTicker.tsx @@ -49,7 +49,7 @@ export default function NewsTicker() {

BREAKING NEWS -
+
{ + const cleaned = name.replace("Polda ", "").trim(); + const slug = cleaned.includes(" ") + ? cleaned.toLowerCase().replace(/\s+/g, "-") + : cleaned; + return slug; + }; + return (
@@ -312,7 +320,10 @@ export default function RegionalNews() {
*/}
{listPolda.map((item: any, index: any) => ( - +
- +
setSelectedTab("media")} className={ selectedTab === "media" - ? "text-black dark:text-white border-b-3 border-red-400 cursor-pointer py-2" + ? "text-black border-b-3 border-red-400 cursor-pointer py-2" : "text-slate-300 cursor-pointer py-2" } > @@ -40,7 +40,7 @@ export default function SidebarNav() { onClick={() => setSelectedTab("video")} className={ selectedTab === "video" - ? "text-black dark:text-white border-b-3 border-red-400 cursor-pointer py-2" + ? "text-black border-b-3 border-red-400 cursor-pointer py-2" : "text-slate-300 cursor-pointer py-2" } > diff --git a/components/main/dashboard/chart/column-chart.tsx b/components/main/dashboard/chart/column-chart.tsx index 4a300c4..9cfb30d 100644 --- a/components/main/dashboard/chart/column-chart.tsx +++ b/components/main/dashboard/chart/column-chart.tsx @@ -86,7 +86,6 @@ const ApexChartColumn = (props: { }) ); } else { - console.log("sadadad", getDatas.visit, getDatas.view, getDatas.share); setSeriesVisit(getDatas.visit); setSeriesView(getDatas.view); setSeriesShare(getDatas.share); diff --git a/components/main/detail/comment.tsx b/components/main/detail/comment.tsx index a406521..46b39b8 100644 --- a/components/main/detail/comment.tsx +++ b/components/main/detail/comment.tsx @@ -1,14 +1,25 @@ import { Button } from "@nextui-org/button"; import { Input, Textarea } from "@nextui-org/input"; -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; import { Controller, useForm } from "react-hook-form"; import * as z from "zod"; import { zodResolver } from "@hookform/resolvers/zod"; -import { otpRequest, otpValidation } from "@/service/master-user"; +import { + deleteArticleComment, + editArticleComment, + getArticleComment, + otpRequest, + otpValidation, + postArticleComment, +} from "@/service/master-user"; import { error } from "@/config/swal"; import { UserProfileIcon } from "@/components/icons/globals"; import { convertDateFormat } from "@/utils/global"; import Cookies from "js-cookie"; +import OTPInput from "react-otp-input"; +import Swal from "sweetalert2"; +import withReactContent from "sweetalert2-react-content"; +import { SendIcon, TimesIcon } from "@/components/icons"; const userId = Cookies.get("uie"); @@ -29,26 +40,17 @@ const commentSchema = z.object({ }), }); -const dummyData = [ - { - id: 1, - createdByName: "User 2", - comment: "test comment", - createdAt: "2025-01-30T00:09:39.352384Z", - createdById: 32, - }, - { - id: 2, - createdByName: "User 2", - comment: "test comment 22", - createdAt: "2025-01-31T00:10:50.352384Z", - createdById: 23, - }, -]; +export default function Comment(props: { id: string | null }) { + const { id } = props; + const MySwal = withReactContent(Swal); -export default function Comment() { const [needOtp, setNeedOtp] = useState(false); const [otpValue, setOtpValue] = useState(""); + const [commentList, setCommentList] = useState([]); + const [openCommentId, setOpenCommentId] = useState(0); + const [editCommentId, setEditCommentId] = useState(0); + const [replyValue, setReplyValue] = useState(""); + const [editValue, setEditValue] = useState(""); const formOptions = { resolver: zodResolver(commentSchema), }; @@ -60,9 +62,18 @@ export default function Comment() { setValue, } = useForm(formOptions); + useEffect(() => { + fetchData(); + }, [id]); + + const fetchData = async () => { + const res = await getArticleComment(String(id)); + setCommentList(res?.data?.data); + }; + const onSubmit = async (values: z.infer) => { if (!needOtp) { - const res = await otpRequest(values.email); + const res = await otpRequest(values.email, values?.name); if (res?.error) { error(res.message); return false; @@ -74,168 +85,400 @@ export default function Comment() { error("OTP Tidak Sesuai"); return false; } - const req = { - email: values.email, - name: values.name, - comment: values.comment, + + const data = { + articleId: Number(id), + isPublic: true, + message: values.comment, + parentId: 0, }; - console.log("req", req); + const res = await postArticleComment(data); + if (res?.error) { + error(res?.message); + return false; + } + fetchData(); } }; - return ( -
-
- {dummyData.map((list) => ( -
-
- -
-

{list.createdByName}

-

{list.comment}

+ + const handleDelete = async (id: number) => { + MySwal.fire({ + title: "Delete Comment", + text: "", + icon: "warning", + showCancelButton: true, + cancelButtonColor: "#d33", + confirmButtonColor: "#3085d6", + confirmButtonText: "Simpan", + }).then((result) => { + if (result.isConfirmed) { + doDelete(id); + } + }); + }; + + const doDelete = async (id: number) => { + const res = await deleteArticleComment(id); + if (res?.error) { + error(res?.message); + return false; + } + MySwal.fire({ + title: "Sukses", + icon: "success", + confirmButtonColor: "#3085d6", + confirmButtonText: "OK", + }).then((result) => { + if (result.isConfirmed) { + } + }); + fetchData(); + }; + + const sendComment = async (idComment: number) => { + const data = { + articleId: Number(id), + isPublic: true, + message: replyValue, + parentId: idComment, + }; + + const res = await postArticleComment(data); + if (res?.error) { + error(res?.message); + return false; + } + fetchData(); + }; + const editComment = async (idComment: number, parentId: number) => { + const data = { + articleId: Number(id), + isPublic: true, + id: idComment, + message: editValue, + parentId: parentId, + }; + + const res = await editArticleComment(data, idComment); + if (res?.error) { + error(res?.message); + return false; + } + setEditCommentId(0); + fetchData(); + }; + + const childComment = (parentId: number) => { + const filteredComment = commentList.filter( + (a: any) => a.parentId === parentId + ); + + return filteredComment.length > 0 ? ( +
+ {filteredComment.map((list: any) => ( +
+ +
+
+

{list?.commentFromName}

+

{convertDateFormat(list?.updatedAt)}

-
-
-

{convertDateFormat(list.createdAt)}

- {(userId === String(list.createdById) || userId === "16") && ( - Hapus + {editCommentId === list?.id ? ( + + } + labelPlacement="outside" + className="w-full " + classNames={{ + inputWrapper: [ + "border-1 rounded-lg", + "dark:group-data-[focused=false]:bg-transparent !border-1 dark:!border-gray-400", + ], + }} + variant="bordered" + /> + setEditCommentId(0)} + > + + +
+ ) : ( +
+

{list?.message}

+ +
+ {userId === "16" && ( + { + setEditValue(list?.message); + setEditCommentId(list?.id); + }} + > + Edit + + )} + {(userId === String(list?.commentFromId) || + userId === "16") && ( + handleDelete(list?.id)} + > + Hapus + + )} +
+
)}
))}
+ ) : ( + "" + ); + }; + + return ( +
- Tinggalkan balasan -

- Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai{" "} - * -

-
-

Komentar

- ( -