mediahub-fe/app/[locale]/(protected)/admin/survey/component/table.tsx

332 lines
9.7 KiB
TypeScript

"use client";
import * as React from "react";
import {
ColumnDef,
ColumnFiltersState,
PaginationState,
SortingState,
VisibilityState,
flexRender,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
useReactTable,
} from "@tanstack/react-table";
import { Button } from "@/components/ui/button";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import {
ChevronLeft,
ChevronRight,
Eye,
MoreVertical,
Search,
SquarePen,
Trash2,
TrendingDown,
TrendingUp,
UserIcon,
} from "lucide-react";
import { cn } from "@/lib/utils";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuRadioGroup,
DropdownMenuRadioItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Input } from "@/components/ui/input";
import { InputGroup, InputGroupText } from "@/components/ui/input-group";
import { paginationBlog } from "@/service/blog/blog";
import { ticketingPagination } from "@/service/ticketing/ticketing";
import { Badge } from "@/components/ui/badge";
import { useRouter, useSearchParams } from "next/navigation";
import TablePagination from "@/components/table/table-pagination";
import columns from "./column";
import { close, loading } from "@/config/swal";
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectLabel,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import {
Bar,
BarChart,
CartesianGrid,
Label,
ResponsiveContainer,
Tooltip,
XAxis,
YAxis,
} from "recharts";
import { getSurveyData } from "@/service/survey/survey";
const data = [
{
question: "Seberapa Sering User Mengakses\nMediaHub Polri",
total: 100,
},
{
question: "Tampilan dan Desain pada Website\nMediaHub Polri",
total: 90,
},
{
question: "Kemudahan Navigasi pada Website\nMediaHub Polri",
total: 80,
},
{
question: "Kecepatan Akses pada Website\nMediaHub Polri",
total: 70,
},
{
question:
"Seberapa Akurat dan Terpercaya\nInformasi pada Website MediaHub Polri",
total: 60,
},
{
question:
"Seberapa Lengkap Informasi dan Berita\npada Website MediaHub Polri",
total: 55,
},
{
question: "Seberapa membantu dalam\nmendapatkan Informasi terkait Polri",
total: 52,
},
];
const SurveyListTable = () => {
const router = useRouter();
const searchParams = useSearchParams();
const [dataTable, setDataTable] = React.useState<any[]>([]);
const [totalData, setTotalData] = React.useState<number>(1);
const [search, setSearch] = React.useState<string>("");
const [showData, setShowData] = React.useState("polri");
const [startDate, setStartDate] = React.useState("");
const [sorting, setSorting] = React.useState<SortingState>([]);
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
[]
);
const [columnVisibility, setColumnVisibility] =
React.useState<VisibilityState>({});
const [rowSelection, setRowSelection] = React.useState({});
const [pagination, setPagination] = React.useState<PaginationState>({
pageIndex: 0,
pageSize: 10,
});
const [page, setPage] = React.useState(1);
const [totalPage, setTotalPage] = React.useState(1);
const table = useReactTable({
data: dataTable,
columns,
onSortingChange: setSorting,
onColumnFiltersChange: setColumnFilters,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
getFilteredRowModel: getFilteredRowModel(),
onColumnVisibilityChange: setColumnVisibility,
onRowSelectionChange: setRowSelection,
onPaginationChange: setPagination,
state: {
sorting,
columnFilters,
columnVisibility,
rowSelection,
pagination,
},
});
React.useEffect(() => {
const pageFromUrl = searchParams?.get("page");
if (pageFromUrl) {
setPage(Number(pageFromUrl));
}
}, [searchParams]);
React.useEffect(() => {
fetchData();
}, [page]);
async function fetchData() {
try {
loading();
const res = await getSurveyData();
const data = res?.data?.data;
const contentData = data?.content;
contentData.forEach((item: any, index: number) => {
item.no = (page - 1) * 10 + index + 1;
});
console.log("contentData : ", data);
setDataTable(contentData);
setTotalData(data?.totalElements);
setTotalPage(data?.totalPages);
close();
} catch (error) {
console.error("Error fetching tasks:", error);
}
}
const handleSearch = (e: React.ChangeEvent<HTMLInputElement>) => {
setSearch(e.target.value); // Perbarui state search
table.getColumn("judul")?.setFilterValue(e.target.value); // Set filter tabel
};
return (
<div className="w-full overflow-x-auto bg-white dark:bg-black p-4 rounded-sm space-y-3">
<div className="flex-1 text-xl font-medium text-default-900">Survey</div>
<div className="flex flex-row gap-2 items-center justify-between">
<div className="w-full md:w-[200px] lg:w-[300px] px-2">
<InputGroup merged>
<InputGroupText className="bg-transparent dark:border-secondary dark:group-focus-within:border-secondary">
<Search className=" h-4 w-4 dark:text-white" />
</InputGroupText>
<Input
type="text"
placeholder="Search Judul..."
className="bg-transparent dark:border-secondary dark:placeholder-white/80 dark:focus:border-secondary dark:text-white"
value={search}
onChange={handleSearch}
/>
</InputGroup>
</div>
<div className="flex flex-row gap-2 items-center">
<div className="mx-2 my-1">
<Input
type="date"
value={startDate}
onChange={(e) => setStartDate(e.target.value)}
className="max-w-sm"
/>
</div>
<div className="mx-3">
<Select>
<SelectTrigger className="w-[150px]">
<SelectValue placeholder="Select a filter" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>Filter</SelectLabel>
<SelectItem value="polri">Polri</SelectItem>
<SelectItem value="umum">Umum</SelectItem>
<SelectItem value="jurnalist">Journalist</SelectItem>
<SelectItem value="ksp">Ksp</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</div>
</div>
</div>
<div className="p-3">
<h2 className="text-center font-semibold mb-4">
Survei Kepuasan Pengguna MediaHub Polri
</h2>
<ResponsiveContainer width="100%" height={500}>
<BarChart
layout="vertical"
data={data}
margin={{ top: 20, right: 30, left: 30, bottom: 80 }}
>
<CartesianGrid strokeDasharray="5 5" />
<XAxis type="number">
<Label
value="Total Survei"
offset={-30}
position="insideBottom"
style={{ textAnchor: "middle", fontStyle: "italic" }}
/>
</XAxis>
<YAxis
type="category"
dataKey="question"
width={240} // Lebarkan agar teks muat
tick={{
fontSize: 12,
}}
tickFormatter={(value: string) =>
value.length > 40 ? value.slice(0, 37) + "..." : value
} // Atur potong teks panjang, atau hapus kalau mau tampil semua
>
<Label
value="Pertanyaan"
angle={-90}
position="insideLeft"
style={{ textAnchor: "middle", fontStyle: "italic" }}
dx={-20}
/>
</YAxis>
<Tooltip />
<Bar dataKey="total" fill="#3163d4" />
</BarChart>
</ResponsiveContainer>
</div>
<Table className="overflow-hidden">
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id} className="bg-default-200">
{headerGroup.headers.map((header) => (
<TableHead key={header.id}>
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext()
)}
</TableHead>
))}
</TableRow>
))}
</TableHeader>
<TableBody>
{table.getRowModel().rows?.length ? (
table.getRowModel().rows.map((row) => (
<TableRow
key={row.id}
data-state={row.getIsSelected() && "selected"}
className="h-[75px]"
>
{row.getVisibleCells().map((cell) => (
<TableCell key={cell.id}>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</TableCell>
))}
</TableRow>
))
) : (
<TableRow>
<TableCell colSpan={columns.length} className="h-24 text-center">
No results.
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
<TablePagination
table={table}
totalData={totalData}
totalPage={totalPage}
/>
</div>
);
};
export default SurveyListTable;