feat: comment section in detail image

This commit is contained in:
sabdayagra 2025-01-20 21:51:01 +07:00
parent 50ebdb2429
commit 9266b1924d
2 changed files with 261 additions and 61 deletions

View File

@ -8,15 +8,19 @@ import NewContent from "@/components/landing-page/new-content";
import { useToast } from "@/components/ui/use-toast";
import { getCookiesDecrypt } from "@/lib/utils";
import { close, error, loading, successCallback, warning } from "@/config/swal";
import { checkWishlistStatus, createPublicSuggestion, deleteWishlist, getDetail, getPublicSuggestionList, saveWishlist } from "@/service/landing/landing";
import { checkWishlistStatus, createPublicSuggestion, deletePublicSuggestion, deleteWishlist, getDetail, getPublicSuggestionList, saveWishlist } from "@/service/landing/landing";
import { Link, useRouter } from "@/i18n/routing";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { sendMediaUploadToEmail } from "@/service/media-tracking/media-tracking";
import { checkMaliciousText } from "@/utils/globals";
import { checkMaliciousText, getPublicLocaleTimestamp } from "@/utils/globals";
import withReactContent from "sweetalert2-react-content";
import Swal from "sweetalert2";
import parse from "html-react-parser";
const DetailInfo = () => {
const MySwal = withReactContent(Swal);
const [selectedSize, setSelectedSize] = useState<string>("L");
const [selectedTab, setSelectedTab] = useState("video");
const router = useRouter();
@ -40,12 +44,10 @@ const DetailInfo = () => {
const [emailShareInput, setEmailShareInput] = useState<any>();
const [emailMessageInput, setEmailMessageInput] = useState();
const searchParams = useSearchParams();
const id = searchParams?.get("id");
const [width, setWidth] = useState<any>();
const userRoleId = getCookiesDecrypt("urie");
const [message, setMessage] = useState("");
const [listSuggestion, setListSuggestion] = useState();
const [listSuggestion, setListSuggestion] = useState<any>();
let typeString = "image";
@ -57,9 +59,12 @@ const DetailInfo = () => {
const initFetch = async () => {
const response = await getDetail(String(slug));
console.log("detailImage", response);
const responseGet = await getPublicSuggestionList(slug?.split("-")?.[0]);
setIsFromSPIT(response?.data?.data?.isFromSPIT);
setWidth(window.innerWidth);
setContent(response?.data.data);
setListSuggestion(responseGet.data?.data);
setMain({
id: response?.data?.data?.files[0]?.id,
type: response?.data?.data?.fileType.name,
@ -259,7 +264,7 @@ const DetailInfo = () => {
router.push("/auth/login");
} else {
const data = {
mediaUploadId: id?.split("-")?.[0],
mediaUploadId: slug?.split("-")?.[0],
email: emailShareList || [emailShareInput],
message: emailMessageInput,
url: window.location.href,
@ -291,6 +296,15 @@ const DetailInfo = () => {
return false;
};
function addDefaultProfile(ev: any) {
ev.target.src = "/assets/avatar-profile.png";
}
const showInput = (e: any) => {
console.log(document.querySelector(`#${e}`)?.classList);
document.querySelector(`#${e}`)?.classList.toggle("comment-hidden");
};
const getInputValue = (e: any) => {
const message = e.target.value;
console.log(message);
@ -301,7 +315,7 @@ const DetailInfo = () => {
if (message?.length > 3) {
loading();
const data = {
mediaUploadId: id?.split("-")?.[0],
mediaUploadId: slug?.split("-")?.[0],
message,
parentId: null,
};
@ -310,44 +324,53 @@ const DetailInfo = () => {
console.log(response);
setMessage("");
const responseGet = await getPublicSuggestionList(id?.split("-")?.[0]);
const responseGet = await getPublicSuggestionList(slug?.split("-")?.[0]);
console.log(responseGet?.data?.data);
setListSuggestion(responseGet?.data?.data);
$(":input").val("");
// Hapus nilai semua input secara manual jika perlu
const inputs = document.querySelectorAll("input");
inputs.forEach((input) => {
input.value = "";
});
close();
}
}
// async function sendSuggestionChild(parentId: any) {
// const inputMsg = document.querySelectorAll(`#input-comment-${parentId}`)[0]
// .value;
async function sendSuggestionChild(parentId: any) {
const inputElement = document.querySelector(`#input-comment-${parentId}`) as HTMLInputElement;
// if (inputMsg?.length > 3) {
// loading();
// const data = {
// mediaUploadId: id?.split("-")?.[0],
// message: inputMsg,
// parentId,
// };
if (inputElement && inputElement.value.length > 3) {
loading();
const data = {
mediaUploadId: slug?.split("-")?.[0],
message: inputElement.value,
parentId,
};
// console.log(data);
// const response = await createPublicSuggestion(data);
// console.log(response);
// const responseGet: any = await getPublicSuggestionList(id?.split("-")?.[0]);
// console.log(responseGet.data?.data);
// setListSuggestion(responseGet.data?.data);
// // $(":input").val("");
// document.querySelectorAll(`#input-comment-${parentId}`)[0].value = "";
// // document.querySelectorAll("#comment-id-" + parentId)[0].style.display = "none";
// close();
// }
// }
console.log(data);
const response = await createPublicSuggestion(data);
console.log(response);
const responseGet: any = await getPublicSuggestionList(slug?.split("-")?.[0]);
console.log(responseGet.data?.data);
setListSuggestion(responseGet.data?.data);
// Reset input field
inputElement.value = "";
// document.querySelector("#comment-id-" + parentId)?.style.display = "none";
close();
}
}
const postData = () => {
const checkMessage = checkMaliciousText(message);
if (checkMessage == "") {
if (Number(userRoleId) < 1 || userRoleId == undefined) {
router.push("/auth/login");
router.push("/auth");
} else {
sendSuggestionParent();
}
@ -356,19 +379,44 @@ const DetailInfo = () => {
}
};
// const postDataChild = (id: any) => {
// const checkMessage = checkMaliciousText(message);
// if (checkMessage == "") {
// if (Number(userRoleId) < 1 || userRoleId == undefined) {
// router.push("/auth/login");
// }
// else {
// sendSuggestionChild(id);
// }
// } else {
// warning(checkMessage);
// }
// };
const postDataChild = (id: any) => {
const checkMessage = checkMaliciousText(message);
if (checkMessage == "") {
if (Number(userRoleId) < 1 || userRoleId == undefined) {
router.push("/auth/login");
} else {
sendSuggestionChild(id);
}
} else {
warning(checkMessage);
}
};
async function deleteDataSuggestion(dataId: any) {
loading();
const response = await deletePublicSuggestion(dataId);
console.log(response);
const responseGet = await getPublicSuggestionList(slug.split("-")?.[0]);
console.log(responseGet.data?.data);
setListSuggestion(responseGet.data?.data);
close();
}
const deleteData = (dataId: any) => {
MySwal.fire({
title: "Delete Comment",
icon: "warning",
showCancelButton: true,
cancelButtonColor: "#3085d6",
confirmButtonColor: "#d33",
confirmButtonText: "Delete",
}).then((result) => {
if (result.isConfirmed) {
deleteDataSuggestion(dataId);
console.log(dataId);
}
});
};
return (
<>
@ -514,16 +562,163 @@ const DetailInfo = () => {
<div className="flex flex-col my-16 p-10 bg-[#f7f7f7]">
<div className="gap-5 flex flex-col px-4 lg:px-14">
<p className="flex items-start text-lg">Berikan Komentar</p>
<Textarea placeholder="Type your comments here." className="flex w-full" onChange={getInputValue} />
<button className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1">Kirim</button>
<Textarea placeholder="Type your comments here." className="flex w-full py-8" onChange={getInputValue} />
<button onClick={() => postData()} className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1">
Kirim
</button>
</div>
<div className="border-b-2 border-black mt-4"></div>
<div className="flex flex-row">
<img src="/assets/avatar-profile.png" alt="avatar" />
<div className="bg-white border border-black ">
<div className="border-b-2 border-slate-300 mt-4 w-auto"></div>
{listSuggestion?.map((data: any) => (
<div className="flex flex-col overflow-y-auto">
<div className="flex flex-row mt-2 px-4 lg:px-14">
<img src={data?.suggestionFrom?.profilePictureUrl} className="h-16 w-16 mr-2" onError={addDefaultProfile} alt="" />
<div className="border border-slate-300 w-full p-4 bg-white gap-1">
<p className="text-slate-500 text-base border-b-2 border-slate-200 mb-2">
{Number(data.suggestionFrom?.roleId) == 2 || Number(data.suggestionFrom?.roleId) == 3 || Number(data.suggestionFrom?.roleId) == 4 ? "HUMAS POLRI" : data.suggestionFrom?.fullname}
{getPublicLocaleTimestamp(new Date(data.createdAt))}
</p>
<p className="text-slate-500 text-sm mb-4">{data?.message}</p>
<div>
<a
style={
Number(data.suggestionFrom?.id) == Number(userId)
? {
display: "none",
}
: {}
}
onClick={() => showInput(`comment-id-${data.id}`)}
className="mr-2"
>
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Balas</small>
</a>
{Number(data.suggestionFrom?.id) == Number(userId) || Number(userRoleId) == 2 ? (
<a onClick={() => deleteData(data.id)}>
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Hapus</small>
</a>
) : (
""
)}
</div>
</div>
</div>
</div>
<div id={`comment-id-${data.id}`} className="px-4 lg:px-28 mt-2">
<Textarea id={`input-comment-${data.id}`} className="p-4 focus:outline-none focus:border-sky-500" placeholder="Masukkan balasan anda" />
<div className="flex flex-row gap-3">
<a onClick={() => postDataChild(data.id)}>
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 mt-2 cursor-pointer">Kirim</small>
</a>
<a onClick={() => showInput(`comment-id-${data.id}`)}>
<small className="flex items-start bg-[#bb3523] rounded-lg mt-2 w-fit text-white px-4 py-1 cursor-pointer">Batal</small>
</a>
</div>
</div>
{data.children.length > 0
? data.children?.map((child1: any) => (
<div className="flex flex-row mt-2">
<img src={child1.suggestionFrom?.profilePictureUrl} onError={addDefaultProfile} alt="" className="h-16 w-16 mr-2" />
<div className="border border-slate-300 w-full p-4 bg-white gap-1">
<p className="text-slate-500 text-base border-b-2 border-slate-200 mb-2">
{" "}
<b>{Number(child1.suggestionFrom?.roleId) == 2 || Number(child1.suggestionFrom?.roleId) == 3 || Number(child1.suggestionFrom?.roleId) == 4 ? "HUMAS POLRI" : child1.suggestionFrom?.fullname}</b>{" "}
{getPublicLocaleTimestamp(new Date(child1.createdAt))}
</p>
<p className="text-slate-500 text-sm mb-4">{parse(String(child1?.message))}</p>
<div>
<a
style={
Number(child1.suggestionFrom?.id) == Number(userId)
? {
display: "none",
}
: {}
}
onClick={() => showInput(`comment-id-${child1.id}`)}
>
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Balas</small>
</a>
<a
style={
Number(child1.suggestionFrom?.id) == Number(userId)
? {}
: {
display: "none",
}
}
onClick={() => deleteData(child1.id)}
>
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Hapus</small>
</a>
</div>
</div>
<div id={`comment-id-${child1.id}`}>
<Textarea name="" id={`input-comment-${child1.id}`} placeholder="Masukkan balasan anda" />
<a onClick={() => postDataChild(child1.id)}>
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Kirim</small>
</a>
<a onClick={() => showInput(`comment-id-${child1.id}`)}>
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Batal</small>
</a>
</div>
{child1.children.length > 0
? child1.children?.map((child2: any) => (
<div className="flex flex-col">
<div className="flex flex-row mt-2">
<img src={child2.suggestionFrom?.profilePictureUrl} className="h-16 w-16 mr-2" onError={addDefaultProfile} alt="" />
<div className="border border-slate-300 w-full p-4 bg-white gap-1">
<p className="text-slate-500 text-base border-b-2 border-slate-200 mb-2">
{" "}
<b>{Number(child2.suggestionFrom?.roleId) == 2 || Number(child2.suggestionFrom?.roleId) == 3 || Number(child2.suggestionFrom?.roleId) == 4 ? "HUMAS POLRI" : child2.suggestionFrom?.fullname}</b>{" "}
{getPublicLocaleTimestamp(new Date(child2.createdAt))}
</p>
<p className="text-slate-500 text-sm mb-4">{parse(String(child2?.message))}</p>
<div>
<a
style={
Number(child2.suggestionFrom?.id) == Number(userId)
? {
display: "none",
}
: {}
}
onClick={() => showInput(`comment-id-${child2.id}`)}
>
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Balas</small>
</a>
<a
style={
Number(child2.suggestionFrom?.id) == Number(userId)
? {}
: {
display: "none",
}
}
onClick={() => deleteData(child2.id)}
>
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Hapus</small>
</a>
</div>
</div>
<div id={`comment-id-${child2.id}`}>
<Textarea name="" id={`input-comment-${child2.id}`} placeholder="Masukkan balasan anda" />
<a onClick={() => postDataChild(child2.id)}>
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Kirim</small>
</a>
<a onClick={() => showInput(`comment-id-${child2.id}`)}>
<small className="flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer">Batal</small>
</a>
</div>
</div>
</div>
))
: ""}
</div>
))
: ""}
</div>
))}
</div>
{/* Konten Serupa */}

View File

@ -139,9 +139,12 @@ export async function saveWishlist(data: { mediaUploadId: string }) {
return httpPostInterceptor(url, data);
}
export async function getPublicSuggestionList(id: any) {
const url = `media/public/suggestion?mediaId=${id}`;
return httpGetInterceptor(url);
export async function getPublicSuggestionList(slug: any) {
const url = `media/public/suggestion?mediaId=${slug}`;
const headers = {
"content-Type": "application/json",
};
return httpGet(url, headers);
}
export async function getUserNotifications(page = 0, typeId: any) {
@ -167,13 +170,15 @@ export async function saveUserReports(data: any) {
export async function listCarousel() {
const url = "/media/public/banner";
return httpGetInterceptor(url)
return httpGetInterceptor(url);
}
export async function createPublicSuggestion(data: any) {
const url = 'media/public/suggestion';
const header = {
"content-Type": "application/json",
};
return httpGet( url, data );
const url = "media/public/suggestion";
return httpPostInterceptor(url, data);
}
export async function deletePublicSuggestion(slug: any) {
const url = `media/public/suggestion?id=${slug}`;
return httpDeleteInterceptor( url );
}