little update
This commit is contained in:
parent
eda6921ae2
commit
91f34586cf
|
|
@ -1,12 +1,13 @@
|
||||||
"use client";
|
"use client";
|
||||||
import { AddIcon } from "@/components/icons";
|
import { AddIcon } from "@/components/icons";
|
||||||
import ArticleTable from "@/components/table/article-table";
|
import ArticleTable from "@/components/table/article-table";
|
||||||
|
import MagazineTable from "@/components/table/magazine/magazine-table";
|
||||||
import generatedArticleIds from "@/store/generated-article-store";
|
import generatedArticleIds from "@/store/generated-article-store";
|
||||||
import { Button, Card } from "@nextui-org/react";
|
import { Button, Card } from "@nextui-org/react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
|
|
||||||
export default function MagazineTable() {
|
export default function MagazineTablePage() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const setGeneratedArticleIdStore = generatedArticleIds(
|
const setGeneratedArticleIdStore = generatedArticleIds(
|
||||||
(state) => state.setArticleIds
|
(state) => state.setArticleIds
|
||||||
|
|
@ -33,7 +34,7 @@ export default function MagazineTable() {
|
||||||
</Button> */}
|
</Button> */}
|
||||||
</div>
|
</div>
|
||||||
<div className="bg-white shadow-lg dark:bg-[#18181b] rounded-xl p-2">
|
<div className="bg-white shadow-lg dark:bg-[#18181b] rounded-xl p-2">
|
||||||
<ArticleTable />
|
<MagazineTable />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -132,29 +132,6 @@ export default function NewCreateMagazineForm() {
|
||||||
clearErrors,
|
clearErrors,
|
||||||
} = useForm<UserSettingSchema>(formOptions);
|
} = useForm<UserSettingSchema>(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<typeof createArticleSchema>) => {
|
const onSubmit = async (values: z.infer<typeof createArticleSchema>) => {
|
||||||
MySwal.fire({
|
MySwal.fire({
|
||||||
title: "Simpan Data",
|
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<typeof createArticleSchema>) => {
|
const save = async (values: z.infer<typeof createArticleSchema>) => {
|
||||||
loading();
|
loading();
|
||||||
const formData = {
|
const formData = {
|
||||||
|
|
@ -189,15 +157,15 @@ export default function NewCreateMagazineForm() {
|
||||||
statusId: 1,
|
statusId: 1,
|
||||||
// description: htmlToString(removeImgTags(values.description)),
|
// description: htmlToString(removeImgTags(values.description)),
|
||||||
description: values.description,
|
description: values.description,
|
||||||
rows: values.rows,
|
// rows: values.rows,
|
||||||
};
|
};
|
||||||
console.log("formd", formData);
|
console.log("formd", formData);
|
||||||
// const response = await createMagazine(formData);
|
const response = await createMagazine(formData);
|
||||||
|
|
||||||
// if (response?.error) {
|
if (response?.error) {
|
||||||
// error(response.message);
|
error(response.message);
|
||||||
// return false;
|
return false;
|
||||||
// }
|
}
|
||||||
// const magazineId = response?.data?.data?.id;
|
// const magazineId = response?.data?.data?.id;
|
||||||
// if (files?.length > 0) {
|
// if (files?.length > 0) {
|
||||||
// const formFiles = new FormData();
|
// const formFiles = new FormData();
|
||||||
|
|
|
||||||
|
|
@ -1,222 +1,355 @@
|
||||||
"use client";
|
"use client";
|
||||||
import {
|
import {
|
||||||
TableCell,
|
CreateIconIon,
|
||||||
TableRow,
|
DeleteIcon,
|
||||||
Table,
|
DotsYIcon,
|
||||||
TableHeader,
|
EyeIconMdi,
|
||||||
TableColumn,
|
SearchIcon,
|
||||||
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,
|
|
||||||
} from "@/components/icons";
|
} 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 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 = {
|
const columns = [
|
||||||
id: number;
|
{ name: "No", uid: "no" },
|
||||||
title: string;
|
{ name: "Judul", uid: "title" },
|
||||||
status: string;
|
{ name: "Kategori", uid: "categoryName" },
|
||||||
description: string;
|
{ name: "Tanggal Unggah", uid: "createdAt" },
|
||||||
avatar: string;
|
{ 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() {
|
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<ArticleData[]>([]);
|
||||||
|
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 columns = [
|
useEffect(() => {
|
||||||
|
initState();
|
||||||
|
}, [page, showData, startDateValue]);
|
||||||
|
|
||||||
{ name: "Title", uid: "title" },
|
useEffect(() => {
|
||||||
{ name: "Description", uid: "description" },
|
getCategories();
|
||||||
{ name: "Action", uid: "actions" },
|
}, []);
|
||||||
];
|
|
||||||
|
|
||||||
const magazineTable = [
|
async function getCategories() {
|
||||||
{
|
const res = await getArticleByCategory();
|
||||||
id: 1,
|
const data = res?.data?.data;
|
||||||
title: "Proses pembuatan website humas ",
|
console.log("datass", res?.data?.data);
|
||||||
status: "active",
|
setCategoies(data);
|
||||||
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",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const renderCell = useCallback((magazine: TableRow, columnKey: Key) => {
|
async function initState() {
|
||||||
const cellValue = magazine[columnKey as keyof UserObject];
|
const req = {
|
||||||
const statusColorMap: Record<string, ChipProps["color"]> = {
|
limit: showData,
|
||||||
active: "primary",
|
page: page,
|
||||||
cancel: "danger",
|
search: search,
|
||||||
pending: "success",
|
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) {
|
const getTableNumber = (limit: number, data: Article[]) => {
|
||||||
case "no":
|
if (data) {
|
||||||
return (
|
const startIndex = limit * (page - 1);
|
||||||
<div>{magazine.id}</div>
|
let iterate = 0;
|
||||||
)
|
const newData = data.map((value: any) => {
|
||||||
|
iterate++;
|
||||||
|
value.no = startIndex + iterate;
|
||||||
|
return value;
|
||||||
|
});
|
||||||
|
console.log("daata", data);
|
||||||
|
setArticle(newData);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
case "title":
|
async function doDelete(id: any) {
|
||||||
return (
|
// loading();
|
||||||
<div className="w-[350px]">{magazine.title}</div>
|
const resDelete = await deleteArticle(id);
|
||||||
)
|
|
||||||
|
|
||||||
case "description":
|
if (resDelete?.error) {
|
||||||
return (
|
error(resDelete.message);
|
||||||
<div className="">{magazine.description}</div>
|
return false;
|
||||||
)
|
}
|
||||||
|
close();
|
||||||
|
success("Berhasil Hapus");
|
||||||
|
initState();
|
||||||
|
}
|
||||||
|
|
||||||
case "status":
|
const handleDelete = (id: any) => {
|
||||||
return (
|
MySwal.fire({
|
||||||
<Chip
|
title: "Hapus Data",
|
||||||
className="capitalize "
|
icon: "warning",
|
||||||
color={statusColorMap[magazine.status]}
|
showCancelButton: true,
|
||||||
size="lg"
|
cancelButtonColor: "#3085d6",
|
||||||
variant="flat"
|
confirmButtonColor: "#d33",
|
||||||
>
|
confirmButtonText: "Hapus",
|
||||||
<div className="flex flex-row items-center gap-2 justify-center">
|
}).then((result) => {
|
||||||
{cellValue}
|
if (result.isConfirmed) {
|
||||||
</div>
|
doDelete(id);
|
||||||
</Chip>
|
}
|
||||||
);
|
});
|
||||||
|
};
|
||||||
|
|
||||||
case "actions":
|
const renderCell = useCallback((article: ArticleData, columnKey: Key) => {
|
||||||
return (
|
const cellValue = article[columnKey as keyof ArticleData];
|
||||||
<div className="relative flex justify-star items-center gap-2">
|
const statusColorMap: Record<string, ChipProps["color"]> = {
|
||||||
<Dropdown className="lg:min-w-[150px] bg-black text-white shadow border ">
|
active: "primary",
|
||||||
<DropdownTrigger>
|
cancel: "danger",
|
||||||
<Button isIconOnly size="lg" variant="light">
|
pending: "success",
|
||||||
<DotsYIcon className="text-default-300" />
|
};
|
||||||
</Button>
|
|
||||||
</DropdownTrigger>
|
|
||||||
<DropdownMenu>
|
|
||||||
<DropdownItem
|
|
||||||
>
|
|
||||||
<Link
|
|
||||||
href={`/admin/magazine/detail`}
|
|
||||||
>
|
|
||||||
<EyeIconMdi className="inline mr-2 mb-1" />
|
|
||||||
Detail
|
|
||||||
</Link>
|
|
||||||
</DropdownItem>
|
|
||||||
<DropdownItem
|
|
||||||
>
|
|
||||||
<Link
|
|
||||||
href={`#`}
|
|
||||||
>
|
|
||||||
<CreateIconIon className="inline mr-2 mb-1" />
|
|
||||||
Edit
|
|
||||||
</Link>
|
|
||||||
</DropdownItem>
|
|
||||||
<DropdownItem
|
|
||||||
>
|
|
||||||
<Link
|
|
||||||
href={`#`}
|
|
||||||
>
|
|
||||||
<DeleteIcon
|
|
||||||
width={20}
|
|
||||||
height={16}
|
|
||||||
className="inline mr-2 mb-1"
|
|
||||||
/>
|
|
||||||
Delete
|
|
||||||
</Link>
|
|
||||||
</DropdownItem>
|
|
||||||
</DropdownMenu>
|
|
||||||
</Dropdown>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
default:
|
switch (columnKey) {
|
||||||
return cellValue;
|
case "status":
|
||||||
}
|
return (
|
||||||
}, []);
|
<Chip
|
||||||
|
className="capitalize "
|
||||||
return (
|
color={statusColorMap[article.status]}
|
||||||
<>
|
size="lg"
|
||||||
<div className="mx-3 my-5">
|
variant="flat"
|
||||||
<Link href="/admin/magazine/create" >
|
>
|
||||||
<Button className="my-3 bg-blue-600 text-white" ><CreateIconIon />Create New Magazine</Button>
|
<div className="flex flex-row items-center gap-2 justify-center">
|
||||||
</Link>
|
{cellValue}
|
||||||
<div className="flex flex-col items-center rounded-2xl">
|
|
||||||
<Table
|
|
||||||
// selectionMode="multiple"
|
|
||||||
aria-label="micro issue table"
|
|
||||||
className="rounded-xl"
|
|
||||||
classNames={{
|
|
||||||
th: "bg-white dark:bg-black text-black dark:text-white border-b-1 text-md",
|
|
||||||
base: "bg-white dark:bg-black border",
|
|
||||||
wrapper: "min-h-[50px] bg-transpararent text-black dark:text-white ",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<TableHeader columns={columns}>
|
|
||||||
{(column) => (
|
|
||||||
<TableColumn key={column.uid}>{column.name}</TableColumn>
|
|
||||||
)}
|
|
||||||
</TableHeader>
|
|
||||||
<TableBody items={magazineTable} emptyContent={"No data to display."}>
|
|
||||||
{(item) => (
|
|
||||||
<TableRow key={item.id}>
|
|
||||||
{(columnKey) => (
|
|
||||||
<TableCell>{renderCell(item, columnKey)}</TableCell>
|
|
||||||
)}
|
|
||||||
</TableRow>
|
|
||||||
)}
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</Chip>
|
||||||
|
);
|
||||||
|
case "createdAt":
|
||||||
|
return <p>{convertDateFormat(article.createdAt)}</p>;
|
||||||
|
|
||||||
</>
|
case "actions":
|
||||||
);
|
return (
|
||||||
|
<div className="relative flex justify-star items-center gap-2">
|
||||||
|
<Dropdown className="lg:min-w-[150px] bg-black text-white shadow border ">
|
||||||
|
<DropdownTrigger>
|
||||||
|
<Button isIconOnly size="lg" variant="light">
|
||||||
|
<DotsYIcon className="text-default-300" />
|
||||||
|
</Button>
|
||||||
|
</DropdownTrigger>
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownItem>
|
||||||
|
<Link href={`/admin/article/detail/${article.id}`}>
|
||||||
|
<EyeIconMdi className="inline mr-2 mb-1" />
|
||||||
|
Detail
|
||||||
|
</Link>
|
||||||
|
</DropdownItem>
|
||||||
|
<DropdownItem>
|
||||||
|
<Link href={`/admin/article/edit/${article.id}`}>
|
||||||
|
<CreateIconIon className="inline mr-2 mb-1" />
|
||||||
|
Edit
|
||||||
|
</Link>
|
||||||
|
</DropdownItem>
|
||||||
|
<DropdownItem onClick={() => handleDelete(article.id)}>
|
||||||
|
<DeleteIcon
|
||||||
|
color="red"
|
||||||
|
width={20}
|
||||||
|
height={16}
|
||||||
|
className="inline mr-2 mb-1"
|
||||||
|
/>
|
||||||
|
Delete
|
||||||
|
</DropdownItem>
|
||||||
|
</DropdownMenu>
|
||||||
|
</Dropdown>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
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 (
|
||||||
|
<>
|
||||||
|
<div className="p-3">
|
||||||
|
<div className="flex flex-col items-start rounded-2xl gap-3">
|
||||||
|
<div className="flex flex-col md:flex-row gap-3 w-full">
|
||||||
|
<div className="flex flex-col gap-1 w-1/3">
|
||||||
|
<p className="font-semibold text-sm">Pencarian</p>
|
||||||
|
<Input
|
||||||
|
aria-label="Search"
|
||||||
|
classNames={{
|
||||||
|
inputWrapper: "bg-default-100",
|
||||||
|
input: "text-sm",
|
||||||
|
}}
|
||||||
|
labelPlacement="outside"
|
||||||
|
startContent={
|
||||||
|
<SearchIcon className="text-base text-default-400 pointer-events-none flex-shrink-0" />
|
||||||
|
}
|
||||||
|
type="text"
|
||||||
|
onChange={(e) => setSearch(e.target.value)}
|
||||||
|
onKeyUp={handleKeyUp}
|
||||||
|
onKeyDown={handleKeyDown}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col gap-1 w-[72px]">
|
||||||
|
<p className="font-semibold text-sm">Data</p>
|
||||||
|
<Select
|
||||||
|
label=""
|
||||||
|
variant="bordered"
|
||||||
|
labelPlacement="outside"
|
||||||
|
placeholder="Select"
|
||||||
|
selectedKeys={[showData]}
|
||||||
|
className="w-full"
|
||||||
|
classNames={{ trigger: "border-1" }}
|
||||||
|
onChange={(e) =>
|
||||||
|
e.target.value === "" ? "" : setShowData(e.target.value)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<SelectItem key="5" value="5">
|
||||||
|
5
|
||||||
|
</SelectItem>
|
||||||
|
<SelectItem key="10" value="10">
|
||||||
|
10
|
||||||
|
</SelectItem>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col gap-1 w-[230px]">
|
||||||
|
<p className="font-semibold text-sm">Kategori</p>
|
||||||
|
<Select
|
||||||
|
label=""
|
||||||
|
variant="bordered"
|
||||||
|
labelPlacement="outside"
|
||||||
|
placeholder="Select"
|
||||||
|
selectionMode="multiple"
|
||||||
|
selectedKeys={[selectedCategories]}
|
||||||
|
className="w-full"
|
||||||
|
classNames={{ trigger: "border-1" }}
|
||||||
|
onChange={(e) => {
|
||||||
|
e.target.value === ""
|
||||||
|
? ""
|
||||||
|
: setSelectedCategories(e.target.value);
|
||||||
|
console.log("eeess", e.target.value);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{categories?.map((category: any) => (
|
||||||
|
<SelectItem key={category?.id} value={category?.id}>
|
||||||
|
{category?.title}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col gap-1 w-full md:w-[240px]">
|
||||||
|
<p className="font-semibold text-sm">Tanggal</p>
|
||||||
|
<Datepicker
|
||||||
|
value={startDateValue}
|
||||||
|
displayFormat="DD/MM/YYYY"
|
||||||
|
onChange={(e: any) => 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"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Table
|
||||||
|
aria-label="micro issue table"
|
||||||
|
className="rounded-3xl"
|
||||||
|
classNames={{
|
||||||
|
th: "bg-white dark:bg-black text-black dark:text-white border-b-1 text-md",
|
||||||
|
base: "bg-white dark:bg-black border",
|
||||||
|
wrapper:
|
||||||
|
"min-h-[50px] bg-transpararent text-black dark:text-white ",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TableHeader columns={columns}>
|
||||||
|
{(column) => (
|
||||||
|
<TableColumn key={column.uid}>{column.name}</TableColumn>
|
||||||
|
)}
|
||||||
|
</TableHeader>
|
||||||
|
<TableBody
|
||||||
|
items={article}
|
||||||
|
emptyContent={"No data to display."}
|
||||||
|
loadingContent={<Spinner label="Loading..." />}
|
||||||
|
>
|
||||||
|
{(item) => (
|
||||||
|
<TableRow key={item.id}>
|
||||||
|
{(columnKey) => (
|
||||||
|
<TableCell>{renderCell(item, columnKey)}</TableCell>
|
||||||
|
)}
|
||||||
|
</TableRow>
|
||||||
|
)}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
<div className="my-2 w-full flex justify-center">
|
||||||
|
<Pagination
|
||||||
|
isCompact
|
||||||
|
showControls
|
||||||
|
showShadow
|
||||||
|
color="primary"
|
||||||
|
classNames={{
|
||||||
|
base: "bg-transparent",
|
||||||
|
wrapper: "bg-transparent",
|
||||||
|
}}
|
||||||
|
page={page}
|
||||||
|
total={totalPage}
|
||||||
|
onChange={(page) => setPage(page)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { PaginationRequest } from "@/types/globals";
|
||||||
import {
|
import {
|
||||||
httpDeleteInterceptor,
|
httpDeleteInterceptor,
|
||||||
httpGet,
|
httpGet,
|
||||||
|
|
@ -16,3 +17,16 @@ export async function createMagazine(data: any) {
|
||||||
const pathUrl = `/magazines`;
|
const pathUrl = `/magazines`;
|
||||||
return await httpPost(pathUrl, headers, data);
|
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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue