113 lines
4.4 KiB
JavaScript
113 lines
4.4 KiB
JavaScript
import React, { useState } from "react";
|
|
import AdminLayout from "./Layout/AdminLayout";
|
|
import { FaPlus, FaTrash } from "react-icons/fa6";
|
|
import Pagination from "../../Components/Pagination";
|
|
import { FaEdit } from "react-icons/fa";
|
|
import { IoBookOutline } from "react-icons/io5";
|
|
import { Link } from "@inertiajs/react";
|
|
import GenerateUrl from "../../Utils/GenerateUrl";
|
|
import useSWR from "swr";
|
|
import { fetcher } from "../../Utils/Fetcher";
|
|
import { debounce } from "../../Utils/Debounce";
|
|
import NoDataTable from "../../Components/NoDataTable";
|
|
|
|
const Materi = (props) => {
|
|
const [page, setPage] = useState(1);
|
|
const [search, setSearch] = useState("");
|
|
const URL = GenerateUrl(
|
|
"/api/v1/kategori",
|
|
`page=${page}`,
|
|
`search=${encodeURIComponent(search)}`
|
|
);
|
|
const { data, error, isLoading } = useSWR(URL, fetcher);
|
|
|
|
const handleSearch = debounce((term) => {
|
|
setSearch(term);
|
|
}, 500);
|
|
|
|
const handleChangeSearch = (e) => {
|
|
const { value } = e.target;
|
|
setPage(1);
|
|
handleSearch(value);
|
|
};
|
|
|
|
return (
|
|
<AdminLayout title="Materi">
|
|
<div className="w-full h-full flex flex-col px-3 py-1">
|
|
<div className="flex items-center w-full gap-4 mb-3">
|
|
<label className="input input-bordered flex w-full items-center gap-2 max-w-[400px]">
|
|
<input
|
|
type="text"
|
|
className="grow"
|
|
onChange={handleChangeSearch}
|
|
placeholder="Search"
|
|
/>
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
viewBox="0 0 16 16"
|
|
fill="currentColor"
|
|
className="w-4 h-4 opacity-70"
|
|
>
|
|
<path
|
|
fillRule="evenodd"
|
|
d="M9.965 11.026a5 5 0 1 1 1.06-1.06l2.755 2.754a.75.75 0 1 1-1.06 1.06l-2.755-2.754ZM10.5 7a3.5 3.5 0 1 1-7 0 3.5 3.5 0 0 1 7 0Z"
|
|
clipRule="evenodd"
|
|
/>
|
|
</svg>
|
|
</label>
|
|
</div>
|
|
<NoDataTable
|
|
isLoading={isLoading}
|
|
isError={error}
|
|
message={error ? "Failed get data" : "No data"}
|
|
isEmpty={
|
|
data && data.result.data.length == 0 ? true : false
|
|
}
|
|
>
|
|
{data && (
|
|
<>
|
|
<div className="grid grid-cols-2 md:grid-cols-3 gap-3">
|
|
{data.result.data.map((item, index) => {
|
|
return (
|
|
<CardMateri
|
|
key={index}
|
|
title={item.nama}
|
|
deskripsi={`Total: ${item.module.length} Materi`}
|
|
link={`/admin/module/${item.id}`}
|
|
/>
|
|
);
|
|
})}
|
|
</div>
|
|
<Pagination
|
|
total={data.result.total}
|
|
showItem={data.result.data.length}
|
|
page={page}
|
|
setPage={setPage}
|
|
limit={data.result.per_page}
|
|
/>
|
|
</>
|
|
)}
|
|
</NoDataTable>
|
|
</div>
|
|
</AdminLayout>
|
|
);
|
|
};
|
|
|
|
const CardMateri = ({ title, deskripsi, link = "/admin/materi/detail" }) => {
|
|
return (
|
|
<Link href={link}>
|
|
<div className="bg-white shadow-md rounded-md p-4 flex items-center gap-4">
|
|
<div>
|
|
<h1 className="font-semibold">{title}</h1>
|
|
<p className="text-xs text-gray-500">{deskripsi}</p>
|
|
<button className="btn btn-sm btn-primary mt-3">
|
|
Detail
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</Link>
|
|
);
|
|
};
|
|
|
|
export default Materi;
|