feat:comment approval
This commit is contained in:
parent
3817131f52
commit
094ac206b6
|
|
@ -1,82 +1,11 @@
|
|||
"use client";
|
||||
import { AddIcon, CloudUploadIcon, TimesIcon } from "@/components/icons";
|
||||
import AdvertiseTable from "@/components/table/advertise/advertise-table";
|
||||
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
Chip,
|
||||
Input,
|
||||
Modal,
|
||||
ModalBody,
|
||||
ModalContent,
|
||||
ModalFooter,
|
||||
ModalHeader,
|
||||
Switch,
|
||||
Textarea,
|
||||
useDisclosure,
|
||||
} from "@heroui/react";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/navigation";
|
||||
import * as z from "zod";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { Fragment, useEffect, useState } from "react";
|
||||
import Swal from "sweetalert2";
|
||||
import withReactContent from "sweetalert2-react-content";
|
||||
|
||||
import { useDropzone } from "react-dropzone";
|
||||
import { close, error, loading } from "@/config/swal";
|
||||
import Image from "next/image";
|
||||
import CommentTable from "@/components/table/comment/comment-table";
|
||||
|
||||
const createArticleSchema = z.object({
|
||||
title: z.string().min(2, {
|
||||
message: "Judul harus diisi",
|
||||
}),
|
||||
url: z.string().min(2, {
|
||||
message: "Link harus diisi",
|
||||
}),
|
||||
description: z.string().min(2, {
|
||||
message: "Deskripsi harus diisi",
|
||||
}),
|
||||
});
|
||||
|
||||
export default function AdvertisePage() {
|
||||
const { isOpen, onOpen, onOpenChange, onClose } = useDisclosure();
|
||||
const MySwal = withReactContent(Swal);
|
||||
|
||||
const [refresh, setRefresh] = useState(false);
|
||||
const [isHeader, setIsHeader] = useState(false);
|
||||
|
||||
const [files, setFiles] = useState<File[]>([]);
|
||||
|
||||
const formOptions = {
|
||||
resolver: zodResolver(createArticleSchema),
|
||||
defaultValues: { title: "", description: "", url: "" },
|
||||
};
|
||||
|
||||
const { getRootProps, getInputProps } = useDropzone({
|
||||
onDrop: (acceptedFiles) => {
|
||||
setFiles(acceptedFiles.map((file) => Object.assign(file)));
|
||||
},
|
||||
maxFiles: 1,
|
||||
accept: {
|
||||
"image/*": [],
|
||||
},
|
||||
});
|
||||
type UserSettingSchema = z.infer<typeof createArticleSchema>;
|
||||
const {
|
||||
control,
|
||||
handleSubmit,
|
||||
formState: { errors },
|
||||
} = useForm<UserSettingSchema>(formOptions);
|
||||
|
||||
return (
|
||||
<div className="overflow-x-hidden overflow-y-scroll">
|
||||
<div className="px-2 md:px-4 md:py-4 w-full">
|
||||
<div className="bg-white shadow-lg dark:bg-[#18181b] rounded-xl p-3">
|
||||
<CommentTable triggerRefresh={refresh} />
|
||||
<CommentTable />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,245 @@
|
|||
"use client";
|
||||
import { close, error, loading } from "@/config/swal";
|
||||
import { FormEvent, Fragment, useEffect, useRef, useState } from "react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import * as z from "zod";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import Swal from "sweetalert2";
|
||||
import withReactContent from "sweetalert2-react-content";
|
||||
import { Input, Textarea } from "@heroui/input";
|
||||
import { Button } from "@heroui/button";
|
||||
import { useParams, useRouter } from "next/navigation";
|
||||
import { getCommentById, saveCommentStatus } from "@/service/comment";
|
||||
import {
|
||||
Modal,
|
||||
ModalBody,
|
||||
ModalContent,
|
||||
ModalFooter,
|
||||
ModalHeader,
|
||||
useDisclosure,
|
||||
} from "@heroui/react";
|
||||
import { getArticleById } from "@/service/article";
|
||||
import Link from "next/link";
|
||||
import { postArticleComment } from "@/service/master-user";
|
||||
|
||||
interface DetailComments {
|
||||
id: number;
|
||||
message: string;
|
||||
articleId: number;
|
||||
commentFromName: string;
|
||||
}
|
||||
|
||||
export default function ReviewComment() {
|
||||
const MySwal = withReactContent(Swal);
|
||||
const { isOpen, onOpen, onOpenChange } = useDisclosure();
|
||||
|
||||
const params = useParams();
|
||||
const id = Number(params?.id);
|
||||
const router = useRouter();
|
||||
const [replyValue, setReplyValue] = useState("");
|
||||
|
||||
const [detailData, setDetailData] = useState<DetailComments>();
|
||||
const [detailArticle, setDetailArticle] = useState<{
|
||||
id: number;
|
||||
slug: string;
|
||||
title: string;
|
||||
}>();
|
||||
useEffect(() => {
|
||||
initFetch();
|
||||
}, []);
|
||||
|
||||
const initFetch = async () => {
|
||||
loading();
|
||||
const res = await getCommentById(id);
|
||||
setDetailData(res?.data?.data);
|
||||
const resArticle = await getArticleById(res?.data?.data?.articleId);
|
||||
setDetailArticle(resArticle?.data?.data);
|
||||
console.log("iddd", res?.data?.data);
|
||||
close();
|
||||
};
|
||||
|
||||
const handleCommentStatus = async (statusId: number) => {
|
||||
MySwal.fire({
|
||||
title: "Submit Data",
|
||||
text: "",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
cancelButtonColor: "#d33",
|
||||
confirmButtonColor: "#3085d6",
|
||||
confirmButtonText: "Simpan",
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
saveStatus(statusId);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const saveStatus = async (statusId: number) => {
|
||||
const req = { id: id, statusId: statusId };
|
||||
const res = await saveCommentStatus(req);
|
||||
if (res?.error) {
|
||||
error(res.message);
|
||||
return false;
|
||||
}
|
||||
successSubmit("/admin/comment");
|
||||
};
|
||||
|
||||
function successSubmit(redirect: string) {
|
||||
MySwal.fire({
|
||||
title: "Sukses",
|
||||
icon: "success",
|
||||
confirmButtonColor: "#3085d6",
|
||||
confirmButtonText: "OK",
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
router.push(redirect);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const sendComment = async () => {
|
||||
const data = {
|
||||
articleId: detailData?.articleId,
|
||||
isPublic: true,
|
||||
message: replyValue,
|
||||
parentId: id,
|
||||
};
|
||||
|
||||
const res = await postArticleComment(data);
|
||||
if (res?.error) {
|
||||
error(res?.message);
|
||||
return false;
|
||||
}
|
||||
saveStatus(2);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="p-8">
|
||||
<div className="bg-white shadow-lg p-4 rounded-lg flex flex-col gap-3 text-sm w-full lg:w-1/2">
|
||||
<div className="flex flex-col gap-1">
|
||||
<p>Artikel</p>
|
||||
<Link
|
||||
target="_black"
|
||||
className="text-primary hover:underline w-fit"
|
||||
href={`/news/detail/${detailArticle?.id}-${detailArticle?.slug}`}
|
||||
>
|
||||
{detailArticle?.title}
|
||||
</Link>
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
<p>Nama</p>
|
||||
<Input
|
||||
type="text"
|
||||
id="username"
|
||||
placeholder=""
|
||||
label=""
|
||||
isReadOnly
|
||||
value={detailData?.commentFromName}
|
||||
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"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
<p>Komentar</p>
|
||||
<Textarea
|
||||
type="text"
|
||||
id="address"
|
||||
placeholder=""
|
||||
label=""
|
||||
value={detailData?.message}
|
||||
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"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
<p>Status</p>
|
||||
<div className="flex flex-row gap-3">
|
||||
<Button
|
||||
onPress={() => handleCommentStatus(1)}
|
||||
color="success"
|
||||
className="w-fit text-white"
|
||||
>
|
||||
Setujui
|
||||
</Button>
|
||||
<Button onPress={onOpen} color="primary" className="w-fit">
|
||||
Balas
|
||||
</Button>
|
||||
<Button
|
||||
onPress={() => handleCommentStatus(3)}
|
||||
color="danger"
|
||||
className="w-fit"
|
||||
>
|
||||
Tolak
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full justify-end flex">
|
||||
<Button
|
||||
onPress={router.back}
|
||||
color="danger"
|
||||
variant="bordered"
|
||||
className="w-fit"
|
||||
>
|
||||
Kembali
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<Modal isOpen={isOpen} onOpenChange={onOpenChange}>
|
||||
<ModalContent>
|
||||
{(onClose) => (
|
||||
<>
|
||||
<ModalHeader className="flex flex-col gap-1">
|
||||
Komentar Balasan
|
||||
</ModalHeader>
|
||||
<ModalBody>
|
||||
<Textarea
|
||||
type="text"
|
||||
id="address"
|
||||
placeholder=""
|
||||
label=""
|
||||
value={replyValue}
|
||||
onValueChange={setReplyValue}
|
||||
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"
|
||||
/>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button color="danger" variant="light" onPress={onClose}>
|
||||
Close
|
||||
</Button>
|
||||
<Button
|
||||
isDisabled={replyValue.length < 2}
|
||||
color="primary"
|
||||
onPress={() => sendComment()}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</>
|
||||
)}
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -295,7 +295,7 @@ export default function CreateArticleForm() {
|
|||
tags: values.tags.join(","),
|
||||
description: htmlToString(removeImgTags(values.description)),
|
||||
htmlDescription: removeImgTags(values.description),
|
||||
// aiArticleId: await saveArticleToDise(values),
|
||||
aiArticleId: await saveArticleToDise(values),
|
||||
isDraft: status === "draft",
|
||||
isPublish: status === "publish",
|
||||
};
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ export default function Comment(props: { id: string | null }) {
|
|||
|
||||
const data = {
|
||||
articleId: Number(id),
|
||||
isPublic: true,
|
||||
isPublic: false,
|
||||
message: values.comment,
|
||||
parentId: 0,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -121,6 +121,8 @@ export default function ArticleTable() {
|
|||
return value;
|
||||
});
|
||||
setArticle(newData);
|
||||
} else {
|
||||
setArticle([]);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import { close, error, loading, success } from "@/config/swal";
|
|||
import {
|
||||
deleteArticle,
|
||||
getArticleByCategory,
|
||||
getArticleById,
|
||||
getListArticle,
|
||||
} from "@/service/article";
|
||||
import { Article } from "@/types/globals";
|
||||
|
|
@ -56,12 +57,15 @@ import withReactContent from "sweetalert2-react-content";
|
|||
import { useDropzone } from "react-dropzone";
|
||||
import Image from "next/image";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { getComments } from "@/service/comment";
|
||||
|
||||
const columns = [
|
||||
{ name: "No", uid: "no" },
|
||||
{ name: "Nama", uid: "name" },
|
||||
{ name: "Email", uid: "email" },
|
||||
{ name: "Komentar", uid: "comment" },
|
||||
{ name: "Nama", uid: "commentFromName" },
|
||||
{ name: "Komentar", uid: "message" },
|
||||
{ name: "Article", uid: "articleId" },
|
||||
{ name: "Status", uid: "status" },
|
||||
|
||||
{ name: "Aksi", uid: "actions" },
|
||||
];
|
||||
|
||||
|
|
@ -70,101 +74,26 @@ interface Category {
|
|||
title: string;
|
||||
}
|
||||
|
||||
const createArticleSchema = z.object({
|
||||
id: z.string().optional(),
|
||||
title: z.string().min(2, {
|
||||
message: "Judul harus diisi",
|
||||
}),
|
||||
url: z.string().min(2, {
|
||||
message: "Link harus diisi",
|
||||
}),
|
||||
description: z.string().min(2, {
|
||||
message: "Deskripsi harus diisi",
|
||||
}),
|
||||
file: z.string().optional(),
|
||||
});
|
||||
|
||||
export default function CommentTable(props: { triggerRefresh: boolean }) {
|
||||
export default function CommentTable() {
|
||||
const MySwal = withReactContent(Swal);
|
||||
const { isOpen, onOpen, onOpenChange, onClose } = useDisclosure();
|
||||
const router = useRouter();
|
||||
const [page, setPage] = useState(1);
|
||||
const [totalPage, setTotalPage] = useState(1);
|
||||
const [article, setArticle] = useState<any[]>([]);
|
||||
const [comments, setComments] = useState<any[]>([]);
|
||||
const [showData, setShowData] = useState("10");
|
||||
const [search, setSearch] = useState("");
|
||||
const [categories, setCategoies] = useState<any>([]);
|
||||
const [selectedCategories, setSelectedCategories] = useState<any>([]);
|
||||
const [startDateValue, setStartDateValue] = useState({
|
||||
startDate: null,
|
||||
endDate: null,
|
||||
});
|
||||
|
||||
const [isHeader, setIsHeader] = useState(false);
|
||||
|
||||
const [files, setFiles] = useState<File[]>([]);
|
||||
|
||||
const formOptions = {
|
||||
resolver: zodResolver(createArticleSchema),
|
||||
defaultValues: { title: "", description: "", url: "", file: "" },
|
||||
};
|
||||
|
||||
const { getRootProps, getInputProps } = useDropzone({
|
||||
onDrop: (acceptedFiles) => {
|
||||
setFiles(acceptedFiles.map((file) => Object.assign(file)));
|
||||
},
|
||||
maxFiles: 1,
|
||||
accept: {
|
||||
"image/*": [],
|
||||
},
|
||||
});
|
||||
type UserSettingSchema = z.infer<typeof createArticleSchema>;
|
||||
const {
|
||||
control,
|
||||
handleSubmit,
|
||||
setValue,
|
||||
formState: { errors },
|
||||
} = useForm<UserSettingSchema>(formOptions);
|
||||
|
||||
useEffect(() => {
|
||||
initState();
|
||||
}, [
|
||||
page,
|
||||
showData,
|
||||
startDateValue,
|
||||
selectedCategories,
|
||||
props.triggerRefresh,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
getCategories();
|
||||
}, []);
|
||||
|
||||
async function getCategories() {
|
||||
const res = await getArticleByCategory();
|
||||
const data = res?.data?.data;
|
||||
setCategoies(data);
|
||||
}
|
||||
|
||||
const handleRemoveFile = (file: File) => {
|
||||
const uploadedFiles = files;
|
||||
const filtered = uploadedFiles.filter((i) => i.name !== file.name);
|
||||
setFiles([...filtered]);
|
||||
};
|
||||
}, [page, showData]);
|
||||
|
||||
async function initState() {
|
||||
const req = {
|
||||
limit: showData,
|
||||
page: page,
|
||||
search: search,
|
||||
startDate:
|
||||
startDateValue.startDate === null ? "" : startDateValue.startDate,
|
||||
endDate: startDateValue.endDate === null ? "" : startDateValue.endDate,
|
||||
category: Array.from(selectedCategories).join(","),
|
||||
sort: "desc",
|
||||
sortBy: "created_at",
|
||||
};
|
||||
const res = await getListArticle(req);
|
||||
const res = await getComments(req);
|
||||
getTableNumber(parseInt(showData), res.data?.data);
|
||||
setTotalPage(res?.data?.meta?.totalPage);
|
||||
}
|
||||
|
|
@ -178,12 +107,14 @@ export default function CommentTable(props: { triggerRefresh: boolean }) {
|
|||
value.no = startIndex + iterate;
|
||||
return value;
|
||||
});
|
||||
setArticle(newData);
|
||||
setComments(newData);
|
||||
} else {
|
||||
setComments([]);
|
||||
}
|
||||
};
|
||||
|
||||
async function doDelete(id: any) {
|
||||
// loading();
|
||||
loading();
|
||||
const resDelete = await deleteArticle(id);
|
||||
|
||||
if (resDelete?.error) {
|
||||
|
|
@ -210,38 +141,23 @@ export default function CommentTable(props: { triggerRefresh: boolean }) {
|
|||
});
|
||||
};
|
||||
|
||||
const onSubmit = async (values: z.infer<typeof createArticleSchema>) => {
|
||||
loading();
|
||||
const formData = {
|
||||
title: values.title,
|
||||
description: values.description,
|
||||
isHeader: isHeader,
|
||||
url: values.url,
|
||||
};
|
||||
console.log("dataas", formData);
|
||||
close();
|
||||
// setRefresh(!refresh);
|
||||
// MySwal.fire({
|
||||
// title: "Sukses",
|
||||
// icon: "success",
|
||||
// confirmButtonColor: "#3085d6",
|
||||
// confirmButtonText: "OK",
|
||||
// }).then((result) => {
|
||||
// if (result.isConfirmed) {
|
||||
// }
|
||||
// });
|
||||
};
|
||||
|
||||
const openModal = async (id: number) => {
|
||||
// const res = await getCategoryById(Number(id));
|
||||
// const data = res?.data?.data;
|
||||
// setValue("id", String(data?.id));
|
||||
// setValue("title", data?.title);
|
||||
// setValue("description", data?.description);
|
||||
// setValue("url", data?.url);
|
||||
// setValue("file", data?.thumbnailUrl);
|
||||
|
||||
onOpen();
|
||||
const openArticle = async (id: number) => {
|
||||
const res = await getArticleById(id);
|
||||
if (res?.error) {
|
||||
MySwal.fire({
|
||||
title: "Artikel tidak ditemukan atau telah dihapus",
|
||||
icon: "warning",
|
||||
showCancelButton: false,
|
||||
cancelButtonColor: "#3085d6",
|
||||
confirmButtonColor: "#d33",
|
||||
confirmButtonText: "Oke",
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
router.push(`/news/detail/${id}-${res?.data?.data?.slug}`);
|
||||
};
|
||||
|
||||
const renderCell = useCallback(
|
||||
|
|
@ -249,17 +165,37 @@ export default function CommentTable(props: { triggerRefresh: boolean }) {
|
|||
const cellValue = comment[columnKey as keyof any];
|
||||
|
||||
switch (columnKey) {
|
||||
case "url":
|
||||
case "articleId":
|
||||
return (
|
||||
<Link
|
||||
href={`https://www.google.com/`}
|
||||
target="_blank"
|
||||
className="text-primary hover:underline"
|
||||
<a
|
||||
onClick={() => openArticle(cellValue)}
|
||||
className="text-primary underline cursor-pointer"
|
||||
>
|
||||
https://www.google.com/
|
||||
</Link>
|
||||
Buka Article
|
||||
</a>
|
||||
);
|
||||
case "status":
|
||||
return (
|
||||
<p
|
||||
className={`${
|
||||
comment?.statusId == 1
|
||||
? "bg-success"
|
||||
: comment?.statusId == 1
|
||||
? "bg-primary"
|
||||
: comment?.statusId == 1
|
||||
? "bg-danger"
|
||||
: "bg-warning"
|
||||
} text-white w-[180px] rounded-lg py-1 text-center`}
|
||||
>
|
||||
{comment?.statusId == 1
|
||||
? "Disetujui"
|
||||
: comment?.statusId == 2
|
||||
? "Dibalas"
|
||||
: comment?.statusId == 3
|
||||
? "Ditolak"
|
||||
: "Menunggu Review"}
|
||||
</p>
|
||||
);
|
||||
|
||||
case "actions":
|
||||
return (
|
||||
<div className="relative flex justify-star items-center gap-2">
|
||||
|
|
@ -270,25 +206,24 @@ export default function CommentTable(props: { triggerRefresh: boolean }) {
|
|||
</Button>
|
||||
</DropdownTrigger>
|
||||
<DropdownMenu>
|
||||
{/* <DropdownItem key="detail">
|
||||
<Link href={`/admin/comment/detail/${article.id}`}>
|
||||
<EyeIconMdi className="inline mr-2 mb-1" />
|
||||
Detail
|
||||
</Link>
|
||||
</DropdownItem> */}
|
||||
<DropdownItem
|
||||
key="edit"
|
||||
onPress={() =>
|
||||
router.push(`/admin/comment/review${comment.id}`)
|
||||
router.push(`/admin/comment/review/${comment.id}`)
|
||||
}
|
||||
className={comment.isPublic ? "hidden" : ""}
|
||||
>
|
||||
<CreateIconIon className="inline mr-2 mb-1" />
|
||||
Review
|
||||
{comment.isPublic == false && (
|
||||
<>
|
||||
<CreateIconIon size={22} className="inline mr-2 mb-1" />
|
||||
Review
|
||||
</>
|
||||
)}
|
||||
</DropdownItem>
|
||||
|
||||
<DropdownItem
|
||||
key="delete"
|
||||
// onPress={() => handleDelete(article.id)}
|
||||
onPress={() => handleDelete(comment.id)}
|
||||
>
|
||||
<DeleteIcon
|
||||
color="red"
|
||||
|
|
@ -306,7 +241,7 @@ export default function CommentTable(props: { triggerRefresh: boolean }) {
|
|||
return cellValue;
|
||||
}
|
||||
},
|
||||
[article]
|
||||
[comments]
|
||||
);
|
||||
|
||||
let typingTimer: NodeJS.Timeout;
|
||||
|
|
@ -387,7 +322,7 @@ export default function CommentTable(props: { triggerRefresh: boolean }) {
|
|||
)}
|
||||
</TableHeader>
|
||||
<TableBody
|
||||
items={article}
|
||||
items={comments}
|
||||
emptyContent={"No data to display."}
|
||||
loadingContent={<Spinner label="Loading..." />}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -111,6 +111,8 @@ export default function MagazineTable() {
|
|||
});
|
||||
console.log("daata", data);
|
||||
setArticle(newData);
|
||||
} else {
|
||||
setArticle([]);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -172,6 +172,8 @@ export default function CategoriesTable(props: { triggerRefresh: boolean }) {
|
|||
return value;
|
||||
});
|
||||
setCategories(newData);
|
||||
} else {
|
||||
setCategories([]);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -61,13 +61,17 @@ import { useDropzone } from "react-dropzone";
|
|||
import Image from "next/image";
|
||||
import SuggestionsChart from "@/components/main/dashboard/chart/suggestions-line-chart";
|
||||
import { parseDate } from "@internationalized/date";
|
||||
import { getFeedbacks, getFeedbacksById } from "@/service/feedbacks";
|
||||
import {
|
||||
deleteFeedback,
|
||||
getFeedbacks,
|
||||
getFeedbacksById,
|
||||
} from "@/service/feedbacks";
|
||||
|
||||
const columns = [
|
||||
{ name: "No", uid: "no" },
|
||||
{ name: "Nama", uid: "name" },
|
||||
{ name: "Email", uid: "email" },
|
||||
{ name: "Kritik & Saran", uid: "suggestions" },
|
||||
{ name: "Nama", uid: "commentFromName" },
|
||||
{ name: "Email", uid: "commentFromEmail" },
|
||||
{ name: "Kritik & Saran", uid: "message" },
|
||||
{ name: "Aksi", uid: "actions" },
|
||||
];
|
||||
|
||||
|
|
@ -135,12 +139,14 @@ export default function SuggestionsTable() {
|
|||
return value;
|
||||
});
|
||||
setArticle(newData);
|
||||
} else {
|
||||
setArticle([]);
|
||||
}
|
||||
};
|
||||
|
||||
async function doDelete(id: any) {
|
||||
// loading();
|
||||
const resDelete = await deleteArticle(id);
|
||||
async function doDelete(id: number) {
|
||||
loading();
|
||||
const resDelete = await deleteFeedback(id);
|
||||
|
||||
if (resDelete?.error) {
|
||||
error(resDelete.message);
|
||||
|
|
@ -151,7 +157,7 @@ export default function SuggestionsTable() {
|
|||
initState();
|
||||
}
|
||||
|
||||
const handleDelete = (id: any) => {
|
||||
const handleDelete = (id: number) => {
|
||||
MySwal.fire({
|
||||
title: "Hapus Data",
|
||||
icon: "warning",
|
||||
|
|
@ -226,17 +232,6 @@ export default function SuggestionsTable() {
|
|||
const cellValue = suggestion[columnKey as keyof any];
|
||||
|
||||
switch (columnKey) {
|
||||
case "commentFromEmail":
|
||||
return (
|
||||
<Link
|
||||
href={`https://www.google.com/`}
|
||||
target="_blank"
|
||||
className="text-primary hover:underline"
|
||||
>
|
||||
https://www.google.com/
|
||||
</Link>
|
||||
);
|
||||
|
||||
case "actions":
|
||||
return (
|
||||
<div className="relative flex justify-star items-center gap-2">
|
||||
|
|
@ -258,12 +253,12 @@ export default function SuggestionsTable() {
|
|||
onPress={() => openModal(suggestion.id)}
|
||||
>
|
||||
<CreateIconIon className="inline mr-2 mb-1" />
|
||||
Edit
|
||||
Detail
|
||||
</DropdownItem>
|
||||
|
||||
<DropdownItem
|
||||
key="delete"
|
||||
// onPress={() => handleDelete(article.id)}
|
||||
onPress={() => handleDelete(suggestion.id)}
|
||||
>
|
||||
<DeleteIcon
|
||||
color="red"
|
||||
|
|
@ -399,7 +394,6 @@ export default function SuggestionsTable() {
|
|||
</SelectItem>
|
||||
</Select>
|
||||
</div>
|
||||
<Button onPress={() => openModal(4)}>test</Button>
|
||||
</div>
|
||||
<Table
|
||||
aria-label="micro issue table"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
import {
|
||||
httpDeleteInterceptor,
|
||||
httpGet,
|
||||
httpPost,
|
||||
httpPut,
|
||||
} from "./http-config/axios-base-service";
|
||||
import Cookies from "js-cookie";
|
||||
|
||||
const token = Cookies.get("access_token");
|
||||
|
||||
export async function getComments(data: any) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
const pathUrl = `/article-comments?page=${data?.page || 1}&limit=${
|
||||
data?.limit || ""
|
||||
}&message=${data?.search || ""}&parentId=0`;
|
||||
return await httpGet(pathUrl, headers);
|
||||
}
|
||||
|
||||
export async function deleteComment(id: number) {
|
||||
return await httpDeleteInterceptor(`/article-comments/${id}`);
|
||||
}
|
||||
|
||||
export async function getCommentById(id: number) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
const pathUrl = `/article-comments/${id}`;
|
||||
return await httpGet(pathUrl, headers);
|
||||
}
|
||||
|
||||
export async function saveCommentStatus(data: {
|
||||
id: number;
|
||||
statusId: number;
|
||||
}) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
const pathUrl = `/article-comments/approval`;
|
||||
return await httpPost(pathUrl, headers, data);
|
||||
}
|
||||
|
|
@ -20,9 +20,9 @@ export async function getFeedbacks(data: any) {
|
|||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
const pathUrl = `/feedbacks?limit=${data?.limit || ""}&message=${
|
||||
data?.search || ""
|
||||
}`;
|
||||
const pathUrl = `/feedbacks?page=${data?.page || 1}limit=${
|
||||
data?.limit || ""
|
||||
}&message=${data?.search || ""}`;
|
||||
return await httpGet(pathUrl, headers);
|
||||
}
|
||||
|
||||
|
|
@ -33,3 +33,6 @@ export async function getFeedbacksById(id: number) {
|
|||
const pathUrl = `/feedbacks/${id}`;
|
||||
return await httpGet(pathUrl, headers);
|
||||
}
|
||||
export async function deleteFeedback(id: number) {
|
||||
return await httpDeleteInterceptor(`/feedbacks/${id}`);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -125,7 +125,10 @@ export async function getArticleComment(id: string) {
|
|||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpGet(`/article-comments?articleId=${id}`, headers);
|
||||
return await httpGet(
|
||||
`/article-comments?isPublic=true&articleId=${id}`,
|
||||
headers
|
||||
);
|
||||
}
|
||||
|
||||
export async function deleteArticleComment(id: number) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue