diff --git a/app/(admin)/admin/magazine/page.tsx b/app/(admin)/admin/magazine/page.tsx index f2c6555..b95c09a 100644 --- a/app/(admin)/admin/magazine/page.tsx +++ b/app/(admin)/admin/magazine/page.tsx @@ -1,12 +1,13 @@ "use client"; import { AddIcon } from "@/components/icons"; import ArticleTable from "@/components/table/article-table"; +import MagazineTable from "@/components/table/magazine/magazine-table"; import generatedArticleIds from "@/store/generated-article-store"; import { Button, Card } from "@nextui-org/react"; import Link from "next/link"; import { useRouter } from "next/navigation"; -export default function MagazineTable() { +export default function MagazineTablePage() { const router = useRouter(); const setGeneratedArticleIdStore = generatedArticleIds( (state) => state.setArticleIds @@ -33,7 +34,7 @@ export default function MagazineTable() { */}
- +
diff --git a/components/form/magazine/create-magazine-form.tsx b/components/form/magazine/create-magazine-form.tsx index c385234..263e8dc 100644 --- a/components/form/magazine/create-magazine-form.tsx +++ b/components/form/magazine/create-magazine-form.tsx @@ -132,29 +132,6 @@ export default function NewCreateMagazineForm() { clearErrors, } = useForm(formOptions); - useEffect(() => { - fetchCategory(); - }, []); - - const fetchCategory = async () => { - const res = await getArticleByCategory(); - if (res?.data?.data) { - setupCategory(res?.data?.data); - } - }; - - const setupCategory = (data: any) => { - const temp = []; - for (const element of data) { - temp.push({ - id: element.id, - label: element.title, - value: element.id, - }); - } - setListCategory(temp); - }; - const onSubmit = async (values: z.infer) => { MySwal.fire({ title: "Simpan Data", @@ -171,15 +148,6 @@ export default function NewCreateMagazineForm() { }); }; - function removeImgTags(htmlString: string) { - const parser = new DOMParser(); - const doc = parser.parseFromString(String(htmlString), "text/html"); - - const images = doc.querySelectorAll("img"); - images.forEach((img) => img.remove()); - return doc.body.innerHTML; - } - const save = async (values: z.infer) => { loading(); const formData = { @@ -189,15 +157,15 @@ export default function NewCreateMagazineForm() { statusId: 1, // description: htmlToString(removeImgTags(values.description)), description: values.description, - rows: values.rows, + // rows: values.rows, }; console.log("formd", formData); - // const response = await createMagazine(formData); + const response = await createMagazine(formData); - // if (response?.error) { - // error(response.message); - // return false; - // } + if (response?.error) { + error(response.message); + return false; + } // const magazineId = response?.data?.data?.id; // if (files?.length > 0) { // const formFiles = new FormData(); diff --git a/components/table/magazine/magazine-table.tsx b/components/table/magazine/magazine-table.tsx index a4948eb..abeb469 100644 --- a/components/table/magazine/magazine-table.tsx +++ b/components/table/magazine/magazine-table.tsx @@ -1,222 +1,355 @@ "use client"; import { - TableCell, - TableRow, - Table, - TableHeader, - TableColumn, - TableBody, - Pagination, - Dropdown, - DropdownTrigger, - DropdownMenu, - DropdownItem, - Input, - User, - Card, - Divider, - Chip, - ChipProps, -} from "@nextui-org/react"; -import { Button } from "@nextui-org/button"; -import React, { Key, useCallback, useMemo, useState } from "react"; -import { - AddIcon, - CreateIconIon, - DeleteIcon, - DotsYIcon, - EyeFilledIcon, - EyeIconMdi, + CreateIconIon, + DeleteIcon, + DotsYIcon, + EyeIconMdi, + SearchIcon, } from "@/components/icons"; +import { error, success } from "@/config/swal"; +import { + deleteArticle, + getArticleByCategory, + getListArticle, +} from "@/service/article"; +import { getListMagazine } from "@/service/magazine"; +import { Article } from "@/types/globals"; +import { convertDateFormat } from "@/utils/global"; +import { Button } from "@nextui-org/button"; +import { + Chip, + ChipProps, + Dropdown, + DropdownItem, + DropdownMenu, + DropdownTrigger, + Input, + Pagination, + Select, + SelectItem, + Spinner, + Table, + TableBody, + TableCell, + TableColumn, + TableHeader, + TableRow, +} from "@nextui-org/react"; import Link from "next/link"; +import { Key, useCallback, useEffect, useState } from "react"; +import Datepicker from "react-tailwindcss-datepicker"; +import Swal from "sweetalert2"; +import withReactContent from "sweetalert2-react-content"; -type UserObject = { - id: number; - title: string; - status: string; - description: string; - avatar: string; +const columns = [ + { name: "No", uid: "no" }, + { name: "Judul", uid: "title" }, + { name: "Kategori", uid: "categoryName" }, + { name: "Tanggal Unggah", uid: "createdAt" }, + { name: "Kreator", uid: "createdByName" }, + + { name: "Aksi", uid: "actions" }, +]; + +type ArticleData = Article & { + no: number; + createdAt: string; }; -const statusColorMap = { - active: "success", - paused: "danger", - vacation: "warning", -}; - - export default function MagazineTable() { - type TableRow = (typeof magazineTable)[0]; + const MySwal = withReactContent(Swal); + const [page, setPage] = useState(1); + const [totalPage, setTotalPage] = useState(1); + const [article, setArticle] = useState([]); + const [showData, setShowData] = useState("10"); + const [search, setSearch] = useState(""); + const [categories, setCategoies] = useState([]); + const [selectedCategories, setSelectedCategories] = useState([]); + const [startDateValue, setStartDateValue] = useState({ + startDate: null, + endDate: null, + }); - const columns = [ + useEffect(() => { + initState(); + }, [page, showData, startDateValue]); - { name: "Title", uid: "title" }, - { name: "Description", uid: "description" }, - { name: "Action", uid: "actions" }, - ]; + useEffect(() => { + getCategories(); + }, []); - const magazineTable = [ - { - id: 1, - title: "Proses pembuatan website humas ", - status: "active", - description: "Pembuatan website Humas adalah sebuah proses yang strategis untuk membangun identitas digital sebuah organisasi atau entitas, yang bertujuan untuk menyebarkan informasi kepada publik, memperkuat citra merek, serta menjaga keterbukaan dan transparansi. Proses ini melibatkan beberapa tahapan yang terstruktur dan terkoordinasi dengan baik", - avatar: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSa8Luglga9J2R3Bxt_PsWZISUHQWODD6_ZTAJ5mIQgxYCAE-YbkY81faTqp-hSA_jVPTs&usqp=CAU", - }, - { - id: 2, - title: "Proses pembuatan website humas ", - status: "active", - description: "Pembuatan website Humas adalah sebuah proses yang strategis untuk membangun identitas digital sebuah organisasi atau entitas, yang bertujuan untuk menyebarkan informasi kepada publik, memperkuat citra merek, serta menjaga keterbukaan dan transparansi. Proses ini melibatkan beberapa tahapan yang terstruktur dan terkoordinasi dengan baik", - avatar: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSa8Luglga9J2R3Bxt_PsWZISUHQWODD6_ZTAJ5mIQgxYCAE-YbkY81faTqp-hSA_jVPTs&usqp=CAU", - }, - { - id: 3, - title: "Proses pembuatan website humas ", - status: "active", - description: "Pembuatan website Humas adalah sebuah proses yang strategis untuk membangun identitas digital sebuah organisasi atau entitas, yang bertujuan untuk menyebarkan informasi kepada publik, memperkuat citra merek, serta menjaga keterbukaan dan transparansi. Proses ini melibatkan beberapa tahapan yang terstruktur dan terkoordinasi dengan baik", - avatar: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSa8Luglga9J2R3Bxt_PsWZISUHQWODD6_ZTAJ5mIQgxYCAE-YbkY81faTqp-hSA_jVPTs&usqp=CAU", - }, - { - id: 4, - title: "Proses pembuatan website humas ", - status: "active", - description: "Pembuatan website Humas adalah sebuah proses yang strategis untuk membangun identitas digital sebuah organisasi atau entitas, yang bertujuan untuk menyebarkan informasi kepada publik, memperkuat citra merek, serta menjaga keterbukaan dan transparansi. Proses ini melibatkan beberapa tahapan yang terstruktur dan terkoordinasi dengan baik", - avatar: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSa8Luglga9J2R3Bxt_PsWZISUHQWODD6_ZTAJ5mIQgxYCAE-YbkY81faTqp-hSA_jVPTs&usqp=CAU", - }, - { - id: 5, - title: "Proses pembuatan website humas ", - status: "active", - description: "Pembuatan website Humas adalah sebuah proses yang strategis untuk membangun identitas digital sebuah organisasi atau entitas, yang bertujuan untuk menyebarkan informasi kepada publik, memperkuat citra merek, serta menjaga keterbukaan dan transparansi. Proses ini melibatkan beberapa tahapan yang terstruktur dan terkoordinasi dengan baik", - avatar: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSa8Luglga9J2R3Bxt_PsWZISUHQWODD6_ZTAJ5mIQgxYCAE-YbkY81faTqp-hSA_jVPTs&usqp=CAU", - }, - ]; + async function getCategories() { + const res = await getArticleByCategory(); + const data = res?.data?.data; + console.log("datass", res?.data?.data); + setCategoies(data); + } - const renderCell = useCallback((magazine: TableRow, columnKey: Key) => { - const cellValue = magazine[columnKey as keyof UserObject]; - const statusColorMap: Record = { - active: "primary", - cancel: "danger", - pending: "success", - }; + async function initState() { + const req = { + limit: showData, + page: page, + search: search, + startDate: + startDateValue.startDate === null ? "" : startDateValue.startDate, + endDate: startDateValue.endDate === null ? "" : startDateValue.endDate, + }; + const res = await getListMagazine(req); + getTableNumber(parseInt(showData), res.data?.data); + console.log("res.data?.data magz", res.data); + setTotalPage(res?.data?.meta?.totalPage); + } - switch (columnKey) { - case "no": - return ( -
{magazine.id}
- ) + const getTableNumber = (limit: number, data: Article[]) => { + if (data) { + const startIndex = limit * (page - 1); + let iterate = 0; + const newData = data.map((value: any) => { + iterate++; + value.no = startIndex + iterate; + return value; + }); + console.log("daata", data); + setArticle(newData); + } + }; - case "title": - return ( -
{magazine.title}
- ) + async function doDelete(id: any) { + // loading(); + const resDelete = await deleteArticle(id); - case "description": - return ( -
{magazine.description}
- ) + if (resDelete?.error) { + error(resDelete.message); + return false; + } + close(); + success("Berhasil Hapus"); + initState(); + } - case "status": - return ( - -
- {cellValue} -
-
- ); + const handleDelete = (id: any) => { + MySwal.fire({ + title: "Hapus Data", + icon: "warning", + showCancelButton: true, + cancelButtonColor: "#3085d6", + confirmButtonColor: "#d33", + confirmButtonText: "Hapus", + }).then((result) => { + if (result.isConfirmed) { + doDelete(id); + } + }); + }; - case "actions": - return ( -
- - - - - - - - - Detail - - - - - - Edit - - - - - - Delete - - - - -
- ); + const renderCell = useCallback((article: ArticleData, columnKey: Key) => { + const cellValue = article[columnKey as keyof ArticleData]; + const statusColorMap: Record = { + active: "primary", + cancel: "danger", + pending: "success", + }; - default: - return cellValue; - } - }, []); - - return ( - <> -
- - - -
- - - {(column) => ( - {column.name} - )} - - - {(item) => ( - - {(columnKey) => ( - {renderCell(item, columnKey)} - )} - - )} - -
-
+ switch (columnKey) { + case "status": + return ( + +
+ {cellValue}
+
+ ); + case "createdAt": + return

{convertDateFormat(article.createdAt)}

; - - ); + case "actions": + return ( +
+ + + + + + + + + Detail + + + + + + Edit + + + handleDelete(article.id)}> + + Delete + + + +
+ ); + + default: + return cellValue; + } + }, []); + + let typingTimer: NodeJS.Timeout; + const doneTypingInterval = 1500; + + const handleKeyUp = () => { + clearTimeout(typingTimer); + typingTimer = setTimeout(doneTyping, doneTypingInterval); + }; + + const handleKeyDown = () => { + clearTimeout(typingTimer); + }; + + async function doneTyping() { + initState(); + } + + return ( + <> +
+
+
+
+

Pencarian

+ + } + type="text" + onChange={(e) => setSearch(e.target.value)} + onKeyUp={handleKeyUp} + onKeyDown={handleKeyDown} + /> +
+
+

Data

+ +
+
+

Kategori

+ +
+
+

Tanggal

+ setStartDateValue(e)} + inputClassName="z-50 w-full text-sm bg-transparent border-1 border-gray-200 px-2 py-[6px] rounded-xl h-[40px] text-gray-600 dark:text-gray-300" + /> +
+
+ + + {(column) => ( + {column.name} + )} + + } + > + {(item) => ( + + {(columnKey) => ( + {renderCell(item, columnKey)} + )} + + )} + +
+
+ setPage(page)} + /> +
+
+
+ + ); } diff --git a/service/magazine.tsx b/service/magazine.tsx index efda83a..e242546 100644 --- a/service/magazine.tsx +++ b/service/magazine.tsx @@ -1,3 +1,4 @@ +import { PaginationRequest } from "@/types/globals"; import { httpDeleteInterceptor, httpGet, @@ -16,3 +17,16 @@ export async function createMagazine(data: any) { const pathUrl = `/magazines`; return await httpPost(pathUrl, headers, data); } + +export async function getListMagazine(props: PaginationRequest) { + const { page, limit, search, startDate, endDate } = props; + const headers = { + "content-type": "application/json", + }; + return await httpGet( + `/magazines?limit=${limit}&page=${page}&title=${search}&startDate=${ + startDate || "" + }&endDate=${endDate || ""}`, + headers + ); +}