fix:login page, table:image,audio,audio-visual,teks
This commit is contained in:
parent
8edaedc9d5
commit
60edcc288f
|
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import {
|
import {
|
||||||
|
ColumnDef,
|
||||||
ColumnFiltersState,
|
ColumnFiltersState,
|
||||||
|
PaginationState,
|
||||||
SortingState,
|
SortingState,
|
||||||
VisibilityState,
|
VisibilityState,
|
||||||
flexRender,
|
flexRender,
|
||||||
|
|
@ -12,7 +14,6 @@ import {
|
||||||
getSortedRowModel,
|
getSortedRowModel,
|
||||||
useReactTable,
|
useReactTable,
|
||||||
} from "@tanstack/react-table";
|
} from "@tanstack/react-table";
|
||||||
import { columns } from "./columns";
|
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
|
@ -26,8 +27,177 @@ import {
|
||||||
|
|
||||||
import { data } from "./data";
|
import { data } from "./data";
|
||||||
import TablePagination from "./table-pagination";
|
import TablePagination from "./table-pagination";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { format } from "date-fns";
|
||||||
|
import {
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuTrigger,
|
||||||
|
} from "@/components/ui/dropdown-menu";
|
||||||
|
import {
|
||||||
|
ChevronLeft,
|
||||||
|
ChevronRight,
|
||||||
|
Eye,
|
||||||
|
MoreVertical,
|
||||||
|
Trash2,
|
||||||
|
} from "lucide-react";
|
||||||
|
import { title } from "process";
|
||||||
|
|
||||||
|
import { getCookiesDecrypt } from "@/lib/utils";
|
||||||
|
import { listDataImage, listDataVideo } from "@/service/content/content";
|
||||||
|
|
||||||
|
export type CompanyData = {
|
||||||
|
no: number;
|
||||||
|
title: string;
|
||||||
|
categoryName: string;
|
||||||
|
createdAt: string;
|
||||||
|
creatorGroup: string;
|
||||||
|
publishedOn: string;
|
||||||
|
isPublish: any;
|
||||||
|
isPublishOnPolda: any;
|
||||||
|
isDone: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const columns: ColumnDef<CompanyData>[] = [
|
||||||
|
{
|
||||||
|
accessorKey: "no",
|
||||||
|
header: "No",
|
||||||
|
cell: ({ row }) => (
|
||||||
|
<div className="flex items-center gap-5">
|
||||||
|
<div className="flex-1 text-start">
|
||||||
|
<h4 className="text-sm font-medium text-default-600 whitespace-nowrap mb-1">
|
||||||
|
{row.getValue("no")}
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "title",
|
||||||
|
header: "Judul",
|
||||||
|
cell: ({ row }) => (
|
||||||
|
<div className="flex items-center gap-5">
|
||||||
|
<div className="flex-1 text-start">
|
||||||
|
<h4 className="text-sm font-medium text-default-600 whitespace-nowrap mb-1">
|
||||||
|
{row.getValue("title")}
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "categoryName",
|
||||||
|
header: "Kategori",
|
||||||
|
cell: ({ row }) => (
|
||||||
|
<span className="whitespace-nowrap">{row.getValue("categoryName")}</span>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "createdAt",
|
||||||
|
header: "Tanggal Unggah",
|
||||||
|
cell: ({ row }) => {
|
||||||
|
const createdAt = row.getValue("createdAt") as
|
||||||
|
| string
|
||||||
|
| number
|
||||||
|
| undefined;
|
||||||
|
|
||||||
|
const formattedDate =
|
||||||
|
createdAt && !isNaN(new Date(createdAt).getTime())
|
||||||
|
? format(new Date(createdAt), "dd-MM-yyyy HH:mm:ss")
|
||||||
|
: "-";
|
||||||
|
return <span className="whitespace-nowrap">{formattedDate}</span>;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "creatorGroup",
|
||||||
|
header: "Sumber ",
|
||||||
|
cell: ({ row }) => (
|
||||||
|
<span className="whitespace-nowrap">{row.getValue("creatorGroup")}</span>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "publishedOn",
|
||||||
|
header: "Penempatan File",
|
||||||
|
cell: ({ row }) => {
|
||||||
|
const isPublish = row.original.isPublish;
|
||||||
|
const isPublishOnPolda = row.original.isPublishOnPolda;
|
||||||
|
|
||||||
|
let displayText = "-";
|
||||||
|
if (isPublish && !isPublishOnPolda) {
|
||||||
|
displayText = "Mabes";
|
||||||
|
} else if (isPublish && isPublishOnPolda) {
|
||||||
|
displayText = "Mabes & Polda";
|
||||||
|
} else if (!isPublish && isPublishOnPolda) {
|
||||||
|
displayText = "Polda";
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="text-center whitespace-nowrap" title={displayText}>
|
||||||
|
{displayText}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
accessorKey: "isDone",
|
||||||
|
header: "Status",
|
||||||
|
cell: ({ row }) => {
|
||||||
|
const isDone = row.getValue<boolean>("isDone");
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Button
|
||||||
|
size="sm"
|
||||||
|
color="success"
|
||||||
|
variant="outline"
|
||||||
|
className={` btn btn-sm ${
|
||||||
|
isDone ? "btn-outline-success" : "btn-outline-primary"
|
||||||
|
} pill-btn ml-1`}
|
||||||
|
>
|
||||||
|
{isDone ? "Selesai" : "Aktif"}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "actions",
|
||||||
|
accessorKey: "action",
|
||||||
|
header: "Actions",
|
||||||
|
enableHiding: false,
|
||||||
|
cell: ({ row }) => {
|
||||||
|
return (
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger asChild>
|
||||||
|
<Button
|
||||||
|
size="icon"
|
||||||
|
className="bg-transparent ring-offset-transparent hover:bg-transparent hover:ring-0 hover:ring-transparent"
|
||||||
|
>
|
||||||
|
<span className="sr-only">Open menu</span>
|
||||||
|
<MoreVertical className="h-4 w-4 text-default-800" />
|
||||||
|
</Button>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent className="p-0" align="end">
|
||||||
|
<a href="/en/task/detail/[id]">
|
||||||
|
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
|
||||||
|
<Eye className="w-4 h-4 me-1.5" />
|
||||||
|
View
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</a>
|
||||||
|
<DropdownMenuItem className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-destructive-foreground rounded-none">
|
||||||
|
<Trash2 className="w-4 h-4 me-1.5" />
|
||||||
|
Delete
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
const TableVideo = () => {
|
const TableVideo = () => {
|
||||||
|
const [videoTable, setVideoTable] = React.useState<CompanyData[]>([]);
|
||||||
const [sorting, setSorting] = React.useState<SortingState>([]);
|
const [sorting, setSorting] = React.useState<SortingState>([]);
|
||||||
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
|
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
|
||||||
[]
|
[]
|
||||||
|
|
@ -35,9 +205,29 @@ const TableVideo = () => {
|
||||||
const [columnVisibility, setColumnVisibility] =
|
const [columnVisibility, setColumnVisibility] =
|
||||||
React.useState<VisibilityState>({});
|
React.useState<VisibilityState>({});
|
||||||
const [rowSelection, setRowSelection] = React.useState({});
|
const [rowSelection, setRowSelection] = React.useState({});
|
||||||
|
const [pagination, setPagination] = React.useState<PaginationState>({
|
||||||
|
pageIndex: 0, // Halaman pertama
|
||||||
|
pageSize: 10, // Jumlah baris per halaman
|
||||||
|
});
|
||||||
|
const [page, setPage] = React.useState(1); // Halaman aktif
|
||||||
|
const [totalPage, setTotalPage] = React.useState(1); // Total halaman
|
||||||
|
const [limit, setLimit] = React.useState(6); // Jumlah baris per halaman
|
||||||
|
const [search, setSearch] = React.useState(title);
|
||||||
|
const userId = getCookiesDecrypt("uie");
|
||||||
|
const userLevelId = getCookiesDecrypt("ulie");
|
||||||
|
|
||||||
|
const [categories, setCategories] = React.useState();
|
||||||
|
const [categoryFilter, setCategoryFilter] = React.useState([]);
|
||||||
|
const [statusFilter, setStatusFilter] = React.useState([]);
|
||||||
|
const [startDateString, setStartDateString] = React.useState("");
|
||||||
|
const [endDateString, setEndDateString] = React.useState("");
|
||||||
|
const [filterByCreator, setFilterByCreator] = React.useState("");
|
||||||
|
const [filterBySource, setFilterBySource] = React.useState("");
|
||||||
|
|
||||||
|
const roleId = getCookiesDecrypt("urie");
|
||||||
|
|
||||||
const table = useReactTable({
|
const table = useReactTable({
|
||||||
data,
|
data: videoTable,
|
||||||
columns,
|
columns,
|
||||||
onSortingChange: setSorting,
|
onSortingChange: setSorting,
|
||||||
onColumnFiltersChange: setColumnFilters,
|
onColumnFiltersChange: setColumnFilters,
|
||||||
|
|
@ -55,6 +245,48 @@ const TableVideo = () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
initState();
|
||||||
|
}, [page, limit]);
|
||||||
|
|
||||||
|
async function initState() {
|
||||||
|
try {
|
||||||
|
const isForSelf = Number(roleId) == 4;
|
||||||
|
const res = await listDataVideo(
|
||||||
|
limit,
|
||||||
|
page,
|
||||||
|
isForSelf,
|
||||||
|
!isForSelf,
|
||||||
|
categoryFilter?.sort().join(","),
|
||||||
|
statusFilter?.sort().join(",").includes("1")
|
||||||
|
? "1,2"
|
||||||
|
: statusFilter?.sort().join(","),
|
||||||
|
statusFilter?.sort().join(",").includes("1") ? userLevelId : "",
|
||||||
|
filterByCreator,
|
||||||
|
filterBySource,
|
||||||
|
startDateString,
|
||||||
|
endDateString
|
||||||
|
);
|
||||||
|
const data = res.data.data.content.map((item: any, index: number) => ({
|
||||||
|
no: (page - 1) * limit + index + 1,
|
||||||
|
title: item.title,
|
||||||
|
categoryName: item.categoryName,
|
||||||
|
creatorGroup: item.creatorGroup,
|
||||||
|
assignmentType: item.assignmentType?.name || "-",
|
||||||
|
createdAt: item.createdAt,
|
||||||
|
isDone: item.isDone,
|
||||||
|
publishedOn: item.publishedOn,
|
||||||
|
isPublish: item.isPublish,
|
||||||
|
isPublishOnPolda: item.isPublishOnPolda,
|
||||||
|
}));
|
||||||
|
|
||||||
|
setVideoTable(data);
|
||||||
|
setTotalPage(res.data.totalPages);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching tasks:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<div className="flex items-center py-4 px-5">
|
<div className="flex items-center py-4 px-5">
|
||||||
|
|
@ -72,12 +304,11 @@ const TableVideo = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Table>
|
<Table className="overflow-hidden">
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
{table.getHeaderGroups().map((headerGroup) => (
|
{table.getHeaderGroups().map((headerGroup) => (
|
||||||
<TableRow key={headerGroup.id}>
|
<TableRow key={headerGroup.id} className="bg-default-200">
|
||||||
{headerGroup.headers.map((header) => {
|
{headerGroup.headers.map((header) => (
|
||||||
return (
|
|
||||||
<TableHead key={header.id}>
|
<TableHead key={header.id}>
|
||||||
{header.isPlaceholder
|
{header.isPlaceholder
|
||||||
? null
|
? null
|
||||||
|
|
@ -86,8 +317,7 @@ const TableVideo = () => {
|
||||||
header.getContext()
|
header.getContext()
|
||||||
)}
|
)}
|
||||||
</TableHead>
|
</TableHead>
|
||||||
);
|
))}
|
||||||
})}
|
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
|
|
@ -97,6 +327,7 @@ const TableVideo = () => {
|
||||||
<TableRow
|
<TableRow
|
||||||
key={row.id}
|
key={row.id}
|
||||||
data-state={row.getIsSelected() && "selected"}
|
data-state={row.getIsSelected() && "selected"}
|
||||||
|
className="h-[75px]"
|
||||||
>
|
>
|
||||||
{row.getVisibleCells().map((cell) => (
|
{row.getVisibleCells().map((cell) => (
|
||||||
<TableCell key={cell.id}>
|
<TableCell key={cell.id}>
|
||||||
|
|
@ -114,7 +345,41 @@ const TableVideo = () => {
|
||||||
)}
|
)}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
<TablePagination table={table} />
|
<div className="flex items-center justify-center py-4 gap-2 flex-none">
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="icon"
|
||||||
|
onClick={() => table.previousPage()}
|
||||||
|
disabled={!table.getCanPreviousPage()}
|
||||||
|
className="w-8 h-8"
|
||||||
|
>
|
||||||
|
<ChevronLeft className="w-4 h-4" />
|
||||||
|
</Button>
|
||||||
|
{table.getPageOptions().map((page, pageIndex) => (
|
||||||
|
<Button
|
||||||
|
key={`basic-data-table-${pageIndex}`}
|
||||||
|
onClick={() => table.setPageIndex(pageIndex)}
|
||||||
|
size="icon"
|
||||||
|
className="w-8 h-8"
|
||||||
|
variant={
|
||||||
|
table.getState().pagination.pageIndex === pageIndex
|
||||||
|
? "default"
|
||||||
|
: "outline"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{page + 1}
|
||||||
|
</Button>
|
||||||
|
))}
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="icon"
|
||||||
|
onClick={() => table.nextPage()}
|
||||||
|
disabled={!table.getCanNextPage()}
|
||||||
|
className="w-8 h-8"
|
||||||
|
>
|
||||||
|
<ChevronRight className="w-4 h-4" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import {
|
import {
|
||||||
|
ColumnDef,
|
||||||
ColumnFiltersState,
|
ColumnFiltersState,
|
||||||
|
PaginationState,
|
||||||
SortingState,
|
SortingState,
|
||||||
VisibilityState,
|
VisibilityState,
|
||||||
flexRender,
|
flexRender,
|
||||||
|
|
@ -12,7 +14,6 @@ import {
|
||||||
getSortedRowModel,
|
getSortedRowModel,
|
||||||
useReactTable,
|
useReactTable,
|
||||||
} from "@tanstack/react-table";
|
} from "@tanstack/react-table";
|
||||||
import { columns } from "./columns";
|
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
|
@ -26,8 +27,181 @@ import {
|
||||||
|
|
||||||
import { data } from "./data";
|
import { data } from "./data";
|
||||||
import TablePagination from "./table-pagination";
|
import TablePagination from "./table-pagination";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { format } from "date-fns";
|
||||||
|
import {
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuTrigger,
|
||||||
|
} from "@/components/ui/dropdown-menu";
|
||||||
|
import {
|
||||||
|
ChevronLeft,
|
||||||
|
ChevronRight,
|
||||||
|
Eye,
|
||||||
|
MoreVertical,
|
||||||
|
Trash2,
|
||||||
|
} from "lucide-react";
|
||||||
|
import { title } from "process";
|
||||||
|
|
||||||
|
import { getCookiesDecrypt } from "@/lib/utils";
|
||||||
|
import {
|
||||||
|
listDataAudio,
|
||||||
|
listDataImage,
|
||||||
|
listDataVideo,
|
||||||
|
} from "@/service/content/content";
|
||||||
|
|
||||||
|
export type CompanyData = {
|
||||||
|
no: number;
|
||||||
|
title: string;
|
||||||
|
categoryName: string;
|
||||||
|
createdAt: string;
|
||||||
|
creatorGroup: string;
|
||||||
|
publishedOn: string;
|
||||||
|
isPublish: any;
|
||||||
|
isPublishOnPolda: any;
|
||||||
|
isDone: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const columns: ColumnDef<CompanyData>[] = [
|
||||||
|
{
|
||||||
|
accessorKey: "no",
|
||||||
|
header: "No",
|
||||||
|
cell: ({ row }) => (
|
||||||
|
<div className="flex items-center gap-5">
|
||||||
|
<div className="flex-1 text-start">
|
||||||
|
<h4 className="text-sm font-medium text-default-600 whitespace-nowrap mb-1">
|
||||||
|
{row.getValue("no")}
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "title",
|
||||||
|
header: "Judul",
|
||||||
|
cell: ({ row }) => (
|
||||||
|
<div className="flex items-center gap-5">
|
||||||
|
<div className="flex-1 text-start">
|
||||||
|
<h4 className="text-sm font-medium text-default-600 whitespace-nowrap mb-1">
|
||||||
|
{row.getValue("title")}
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "categoryName",
|
||||||
|
header: "Kategori",
|
||||||
|
cell: ({ row }) => (
|
||||||
|
<span className="whitespace-nowrap">{row.getValue("categoryName")}</span>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "createdAt",
|
||||||
|
header: "Tanggal Unggah",
|
||||||
|
cell: ({ row }) => {
|
||||||
|
const createdAt = row.getValue("createdAt") as
|
||||||
|
| string
|
||||||
|
| number
|
||||||
|
| undefined;
|
||||||
|
|
||||||
|
const formattedDate =
|
||||||
|
createdAt && !isNaN(new Date(createdAt).getTime())
|
||||||
|
? format(new Date(createdAt), "dd-MM-yyyy HH:mm:ss")
|
||||||
|
: "-";
|
||||||
|
return <span className="whitespace-nowrap">{formattedDate}</span>;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "creatorGroup",
|
||||||
|
header: "Sumber ",
|
||||||
|
cell: ({ row }) => (
|
||||||
|
<span className="whitespace-nowrap">{row.getValue("creatorGroup")}</span>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "publishedOn",
|
||||||
|
header: "Penempatan File",
|
||||||
|
cell: ({ row }) => {
|
||||||
|
const isPublish = row.original.isPublish;
|
||||||
|
const isPublishOnPolda = row.original.isPublishOnPolda;
|
||||||
|
|
||||||
|
let displayText = "-";
|
||||||
|
if (isPublish && !isPublishOnPolda) {
|
||||||
|
displayText = "Mabes";
|
||||||
|
} else if (isPublish && isPublishOnPolda) {
|
||||||
|
displayText = "Mabes & Polda";
|
||||||
|
} else if (!isPublish && isPublishOnPolda) {
|
||||||
|
displayText = "Polda";
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="text-center whitespace-nowrap" title={displayText}>
|
||||||
|
{displayText}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
accessorKey: "isDone",
|
||||||
|
header: "Status",
|
||||||
|
cell: ({ row }) => {
|
||||||
|
const isDone = row.getValue<boolean>("isDone");
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Button
|
||||||
|
size="sm"
|
||||||
|
color="success"
|
||||||
|
variant="outline"
|
||||||
|
className={` btn btn-sm ${
|
||||||
|
isDone ? "btn-outline-success" : "btn-outline-primary"
|
||||||
|
} pill-btn ml-1`}
|
||||||
|
>
|
||||||
|
{isDone ? "Selesai" : "Aktif"}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "actions",
|
||||||
|
accessorKey: "action",
|
||||||
|
header: "Actions",
|
||||||
|
enableHiding: false,
|
||||||
|
cell: ({ row }) => {
|
||||||
|
return (
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger asChild>
|
||||||
|
<Button
|
||||||
|
size="icon"
|
||||||
|
className="bg-transparent ring-offset-transparent hover:bg-transparent hover:ring-0 hover:ring-transparent"
|
||||||
|
>
|
||||||
|
<span className="sr-only">Open menu</span>
|
||||||
|
<MoreVertical className="h-4 w-4 text-default-800" />
|
||||||
|
</Button>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent className="p-0" align="end">
|
||||||
|
<a href="/en/task/detail/[id]">
|
||||||
|
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
|
||||||
|
<Eye className="w-4 h-4 me-1.5" />
|
||||||
|
View
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</a>
|
||||||
|
<DropdownMenuItem className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-destructive-foreground rounded-none">
|
||||||
|
<Trash2 className="w-4 h-4 me-1.5" />
|
||||||
|
Delete
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
const TableAudio = () => {
|
const TableAudio = () => {
|
||||||
|
const [videoTable, setVideoTable] = React.useState<CompanyData[]>([]);
|
||||||
const [sorting, setSorting] = React.useState<SortingState>([]);
|
const [sorting, setSorting] = React.useState<SortingState>([]);
|
||||||
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
|
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
|
||||||
[]
|
[]
|
||||||
|
|
@ -35,9 +209,29 @@ const TableAudio = () => {
|
||||||
const [columnVisibility, setColumnVisibility] =
|
const [columnVisibility, setColumnVisibility] =
|
||||||
React.useState<VisibilityState>({});
|
React.useState<VisibilityState>({});
|
||||||
const [rowSelection, setRowSelection] = React.useState({});
|
const [rowSelection, setRowSelection] = React.useState({});
|
||||||
|
const [pagination, setPagination] = React.useState<PaginationState>({
|
||||||
|
pageIndex: 0, // Halaman pertama
|
||||||
|
pageSize: 10, // Jumlah baris per halaman
|
||||||
|
});
|
||||||
|
const [page, setPage] = React.useState(1); // Halaman aktif
|
||||||
|
const [totalPage, setTotalPage] = React.useState(1); // Total halaman
|
||||||
|
const [limit, setLimit] = React.useState(6); // Jumlah baris per halaman
|
||||||
|
const [search, setSearch] = React.useState(title);
|
||||||
|
const userId = getCookiesDecrypt("uie");
|
||||||
|
const userLevelId = getCookiesDecrypt("ulie");
|
||||||
|
|
||||||
|
const [categories, setCategories] = React.useState();
|
||||||
|
const [categoryFilter, setCategoryFilter] = React.useState([]);
|
||||||
|
const [statusFilter, setStatusFilter] = React.useState([]);
|
||||||
|
const [startDateString, setStartDateString] = React.useState("");
|
||||||
|
const [endDateString, setEndDateString] = React.useState("");
|
||||||
|
const [filterByCreator, setFilterByCreator] = React.useState("");
|
||||||
|
const [filterBySource, setFilterBySource] = React.useState("");
|
||||||
|
|
||||||
|
const roleId = getCookiesDecrypt("urie");
|
||||||
|
|
||||||
const table = useReactTable({
|
const table = useReactTable({
|
||||||
data,
|
data: videoTable,
|
||||||
columns,
|
columns,
|
||||||
onSortingChange: setSorting,
|
onSortingChange: setSorting,
|
||||||
onColumnFiltersChange: setColumnFilters,
|
onColumnFiltersChange: setColumnFilters,
|
||||||
|
|
@ -55,6 +249,48 @@ const TableAudio = () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
initState();
|
||||||
|
}, [page, limit]);
|
||||||
|
|
||||||
|
async function initState() {
|
||||||
|
try {
|
||||||
|
const isForSelf = Number(roleId) == 4;
|
||||||
|
const res = await listDataAudio(
|
||||||
|
limit,
|
||||||
|
page,
|
||||||
|
isForSelf,
|
||||||
|
!isForSelf,
|
||||||
|
categoryFilter?.sort().join(","),
|
||||||
|
statusFilter?.sort().join(",").includes("1")
|
||||||
|
? "1,2"
|
||||||
|
: statusFilter?.sort().join(","),
|
||||||
|
statusFilter?.sort().join(",").includes("1") ? userLevelId : "",
|
||||||
|
filterByCreator,
|
||||||
|
filterBySource,
|
||||||
|
startDateString,
|
||||||
|
endDateString
|
||||||
|
);
|
||||||
|
const data = res.data.data.content.map((item: any, index: number) => ({
|
||||||
|
no: (page - 1) * limit + index + 1,
|
||||||
|
title: item.title,
|
||||||
|
categoryName: item.categoryName,
|
||||||
|
creatorGroup: item.creatorGroup,
|
||||||
|
assignmentType: item.assignmentType?.name || "-",
|
||||||
|
createdAt: item.createdAt,
|
||||||
|
isDone: item.isDone,
|
||||||
|
publishedOn: item.publishedOn,
|
||||||
|
isPublish: item.isPublish,
|
||||||
|
isPublishOnPolda: item.isPublishOnPolda,
|
||||||
|
}));
|
||||||
|
|
||||||
|
setVideoTable(data);
|
||||||
|
setTotalPage(res.data.totalPages);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching tasks:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<div className="flex items-center py-4 px-5">
|
<div className="flex items-center py-4 px-5">
|
||||||
|
|
@ -72,12 +308,11 @@ const TableAudio = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Table>
|
<Table className="overflow-hidden">
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
{table.getHeaderGroups().map((headerGroup) => (
|
{table.getHeaderGroups().map((headerGroup) => (
|
||||||
<TableRow key={headerGroup.id}>
|
<TableRow key={headerGroup.id} className="bg-default-200">
|
||||||
{headerGroup.headers.map((header) => {
|
{headerGroup.headers.map((header) => (
|
||||||
return (
|
|
||||||
<TableHead key={header.id}>
|
<TableHead key={header.id}>
|
||||||
{header.isPlaceholder
|
{header.isPlaceholder
|
||||||
? null
|
? null
|
||||||
|
|
@ -86,8 +321,7 @@ const TableAudio = () => {
|
||||||
header.getContext()
|
header.getContext()
|
||||||
)}
|
)}
|
||||||
</TableHead>
|
</TableHead>
|
||||||
);
|
))}
|
||||||
})}
|
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
|
|
@ -97,6 +331,7 @@ const TableAudio = () => {
|
||||||
<TableRow
|
<TableRow
|
||||||
key={row.id}
|
key={row.id}
|
||||||
data-state={row.getIsSelected() && "selected"}
|
data-state={row.getIsSelected() && "selected"}
|
||||||
|
className="h-[75px]"
|
||||||
>
|
>
|
||||||
{row.getVisibleCells().map((cell) => (
|
{row.getVisibleCells().map((cell) => (
|
||||||
<TableCell key={cell.id}>
|
<TableCell key={cell.id}>
|
||||||
|
|
@ -114,7 +349,41 @@ const TableAudio = () => {
|
||||||
)}
|
)}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
<TablePagination table={table} />
|
<div className="flex items-center justify-center py-4 gap-2 flex-none">
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="icon"
|
||||||
|
onClick={() => table.previousPage()}
|
||||||
|
disabled={!table.getCanPreviousPage()}
|
||||||
|
className="w-8 h-8"
|
||||||
|
>
|
||||||
|
<ChevronLeft className="w-4 h-4" />
|
||||||
|
</Button>
|
||||||
|
{table.getPageOptions().map((page, pageIndex) => (
|
||||||
|
<Button
|
||||||
|
key={`basic-data-table-${pageIndex}`}
|
||||||
|
onClick={() => table.setPageIndex(pageIndex)}
|
||||||
|
size="icon"
|
||||||
|
className="w-8 h-8"
|
||||||
|
variant={
|
||||||
|
table.getState().pagination.pageIndex === pageIndex
|
||||||
|
? "default"
|
||||||
|
: "outline"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{page + 1}
|
||||||
|
</Button>
|
||||||
|
))}
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="icon"
|
||||||
|
onClick={() => table.nextPage()}
|
||||||
|
disabled={!table.getCanNextPage()}
|
||||||
|
className="w-8 h-8"
|
||||||
|
>
|
||||||
|
<ChevronRight className="w-4 h-4" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,8 @@ import {
|
||||||
import { title } from "process";
|
import { title } from "process";
|
||||||
|
|
||||||
import { getCookiesDecrypt } from "@/lib/utils";
|
import { getCookiesDecrypt } from "@/lib/utils";
|
||||||
import { listDataImage } from "@/service/content/content-image";
|
import { listDataImage } from "@/service/content/content";
|
||||||
|
import page from "../page";
|
||||||
|
|
||||||
export type CompanyData = {
|
export type CompanyData = {
|
||||||
no: number;
|
no: number;
|
||||||
|
|
@ -197,7 +198,6 @@ export const columns: ColumnDef<CompanyData>[] = [
|
||||||
];
|
];
|
||||||
|
|
||||||
const TableImage = () => {
|
const TableImage = () => {
|
||||||
const [imageTable, setImageTable] = React.useState<CompanyData[]>([]);
|
|
||||||
const [sorting, setSorting] = React.useState<SortingState>([]);
|
const [sorting, setSorting] = React.useState<SortingState>([]);
|
||||||
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
|
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
|
||||||
[]
|
[]
|
||||||
|
|
@ -205,14 +205,14 @@ const TableImage = () => {
|
||||||
const [columnVisibility, setColumnVisibility] =
|
const [columnVisibility, setColumnVisibility] =
|
||||||
React.useState<VisibilityState>({});
|
React.useState<VisibilityState>({});
|
||||||
const [rowSelection, setRowSelection] = React.useState({});
|
const [rowSelection, setRowSelection] = React.useState({});
|
||||||
|
const [imageTable, setImageTable] = React.useState<CompanyData[]>([]);
|
||||||
const [pagination, setPagination] = React.useState<PaginationState>({
|
const [pagination, setPagination] = React.useState<PaginationState>({
|
||||||
pageIndex: 0, // Halaman pertama
|
pageIndex: 0, // Halaman pertama
|
||||||
pageSize: 10, // Jumlah baris per halaman
|
pageSize: 10, // Jumlah baris per halaman
|
||||||
});
|
});
|
||||||
const [page, setPage] = React.useState(1); // Halaman aktif
|
const [totalPage, setTotalPage] = React.useState<number>(1);
|
||||||
const [totalPage, setTotalPage] = React.useState(1); // Total halaman
|
const [limit, setLimit] = React.useState<number>(10); // Jumlah baris per halaman
|
||||||
const [limit, setLimit] = React.useState(10); // Jumlah baris per halaman
|
const [search, setSearch] = React.useState<string>("");
|
||||||
const [search, setSearch] = React.useState(title);
|
|
||||||
const userId = getCookiesDecrypt("uie");
|
const userId = getCookiesDecrypt("uie");
|
||||||
const userLevelId = getCookiesDecrypt("ulie");
|
const userLevelId = getCookiesDecrypt("ulie");
|
||||||
|
|
||||||
|
|
@ -247,14 +247,14 @@ const TableImage = () => {
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
initState();
|
initState();
|
||||||
}, [page, limit]);
|
}, [limit]);
|
||||||
|
|
||||||
async function initState() {
|
async function initState() {
|
||||||
try {
|
try {
|
||||||
const isForSelf = Number(roleId) == 4;
|
const isForSelf = Number(roleId) === 4;
|
||||||
const res = await listDataImage(
|
const res = await listDataImage(
|
||||||
limit,
|
pagination.pageSize, // Ambil nilai dari pagination.pageSize
|
||||||
page,
|
pagination.pageIndex + 1, // API sering menggunakan page 1-based
|
||||||
isForSelf,
|
isForSelf,
|
||||||
!isForSelf,
|
!isForSelf,
|
||||||
categoryFilter?.sort().join(","),
|
categoryFilter?.sort().join(","),
|
||||||
|
|
@ -267,12 +267,24 @@ const TableImage = () => {
|
||||||
startDateString,
|
startDateString,
|
||||||
endDateString
|
endDateString
|
||||||
);
|
);
|
||||||
const data = res.data.data.content.map((item: any, index: number) => ({
|
|
||||||
no: (page - 1) * limit + index + 1,
|
setupData(res.data?.data);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching tasks:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupData(rawData: {
|
||||||
|
content: any[];
|
||||||
|
totalPages: number;
|
||||||
|
totalElements: number;
|
||||||
|
}) {
|
||||||
|
if (rawData?.content) {
|
||||||
|
const data: CompanyData[] = rawData.content.map((item, index) => ({
|
||||||
|
no: pagination.pageIndex * pagination.pageSize + index + 1,
|
||||||
title: item.title,
|
title: item.title,
|
||||||
categoryName: item.categoryName,
|
categoryName: item.categoryName,
|
||||||
creatorGroup: item.creatorGroup,
|
creatorGroup: item.creatorGroup,
|
||||||
assignmentType: item.assignmentType?.name || "-",
|
|
||||||
createdAt: item.createdAt,
|
createdAt: item.createdAt,
|
||||||
isDone: item.isDone,
|
isDone: item.isDone,
|
||||||
publishedOn: item.publishedOn,
|
publishedOn: item.publishedOn,
|
||||||
|
|
@ -281,9 +293,8 @@ const TableImage = () => {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
setImageTable(data);
|
setImageTable(data);
|
||||||
setTotalPage(res.data.totalPages);
|
setTotalPage(rawData.totalPages);
|
||||||
} catch (error) {
|
console.log(data, "dataImage");
|
||||||
console.error("Error fetching tasks:", error);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import {
|
import {
|
||||||
|
ColumnDef,
|
||||||
ColumnFiltersState,
|
ColumnFiltersState,
|
||||||
|
PaginationState,
|
||||||
SortingState,
|
SortingState,
|
||||||
VisibilityState,
|
VisibilityState,
|
||||||
flexRender,
|
flexRender,
|
||||||
|
|
@ -12,7 +14,6 @@ import {
|
||||||
getSortedRowModel,
|
getSortedRowModel,
|
||||||
useReactTable,
|
useReactTable,
|
||||||
} from "@tanstack/react-table";
|
} from "@tanstack/react-table";
|
||||||
import { columns } from "./columns";
|
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
|
@ -26,8 +27,183 @@ import {
|
||||||
|
|
||||||
import { data } from "./data";
|
import { data } from "./data";
|
||||||
import TablePagination from "./table-pagination";
|
import TablePagination from "./table-pagination";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { format } from "date-fns";
|
||||||
|
import {
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuTrigger,
|
||||||
|
} from "@/components/ui/dropdown-menu";
|
||||||
|
import {
|
||||||
|
ChevronLeft,
|
||||||
|
ChevronRight,
|
||||||
|
Eye,
|
||||||
|
MoreVertical,
|
||||||
|
Trash2,
|
||||||
|
} from "lucide-react";
|
||||||
|
import { title } from "process";
|
||||||
|
|
||||||
|
import { getCookiesDecrypt } from "@/lib/utils";
|
||||||
|
import {
|
||||||
|
listDataAudio,
|
||||||
|
listDataImage,
|
||||||
|
listDataVideo,
|
||||||
|
listSPIT,
|
||||||
|
} from "@/service/content/content";
|
||||||
|
import { pages } from "next/dist/build/templates/app-page";
|
||||||
|
|
||||||
|
export type CompanyData = {
|
||||||
|
no: number;
|
||||||
|
title: string;
|
||||||
|
categoryName: string;
|
||||||
|
createdAt: string;
|
||||||
|
creatorGroup: string;
|
||||||
|
publishedOn: string;
|
||||||
|
isPublish: any;
|
||||||
|
isPublishOnPolda: any;
|
||||||
|
isDone: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const columns: ColumnDef<CompanyData>[] = [
|
||||||
|
{
|
||||||
|
accessorKey: "no",
|
||||||
|
header: "No",
|
||||||
|
cell: ({ row }) => (
|
||||||
|
<div className="flex items-center gap-5">
|
||||||
|
<div className="flex-1 text-start">
|
||||||
|
<h4 className="text-sm font-medium text-default-600 whitespace-nowrap mb-1">
|
||||||
|
{row.getValue("no")}
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "title",
|
||||||
|
header: "Judul",
|
||||||
|
cell: ({ row }) => (
|
||||||
|
<div className="flex items-center gap-5">
|
||||||
|
<div className="flex-1 text-start">
|
||||||
|
<h4 className="text-sm font-medium text-default-600 whitespace-nowrap mb-1">
|
||||||
|
{row.getValue("title")}
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "categoryName",
|
||||||
|
header: "Kategori",
|
||||||
|
cell: ({ row }) => (
|
||||||
|
<span className="whitespace-nowrap">{row.getValue("categoryName")}</span>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "createdAt",
|
||||||
|
header: "Tanggal Unggah",
|
||||||
|
cell: ({ row }) => {
|
||||||
|
const createdAt = row.getValue("createdAt") as
|
||||||
|
| string
|
||||||
|
| number
|
||||||
|
| undefined;
|
||||||
|
|
||||||
|
const formattedDate =
|
||||||
|
createdAt && !isNaN(new Date(createdAt).getTime())
|
||||||
|
? format(new Date(createdAt), "dd-MM-yyyy HH:mm:ss")
|
||||||
|
: "-";
|
||||||
|
return <span className="whitespace-nowrap">{formattedDate}</span>;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "creatorGroup",
|
||||||
|
header: "Sumber ",
|
||||||
|
cell: ({ row }) => (
|
||||||
|
<span className="whitespace-nowrap">{row.getValue("creatorGroup")}</span>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "publishedOn",
|
||||||
|
header: "Penempatan File",
|
||||||
|
cell: ({ row }) => {
|
||||||
|
const isPublish = row.original.isPublish;
|
||||||
|
const isPublishOnPolda = row.original.isPublishOnPolda;
|
||||||
|
|
||||||
|
let displayText = "-";
|
||||||
|
if (isPublish && !isPublishOnPolda) {
|
||||||
|
displayText = "Mabes";
|
||||||
|
} else if (isPublish && isPublishOnPolda) {
|
||||||
|
displayText = "Mabes & Polda";
|
||||||
|
} else if (!isPublish && isPublishOnPolda) {
|
||||||
|
displayText = "Polda";
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="text-center whitespace-nowrap" title={displayText}>
|
||||||
|
{displayText}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
accessorKey: "isDone",
|
||||||
|
header: "Status",
|
||||||
|
cell: ({ row }) => {
|
||||||
|
const isDone = row.getValue<boolean>("isDone");
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Button
|
||||||
|
size="sm"
|
||||||
|
color="success"
|
||||||
|
variant="outline"
|
||||||
|
className={` btn btn-sm ${
|
||||||
|
isDone ? "btn-outline-success" : "btn-outline-primary"
|
||||||
|
} pill-btn ml-1`}
|
||||||
|
>
|
||||||
|
{isDone ? "Selesai" : "Aktif"}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "actions",
|
||||||
|
accessorKey: "action",
|
||||||
|
header: "Actions",
|
||||||
|
enableHiding: false,
|
||||||
|
cell: ({ row }) => {
|
||||||
|
return (
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger asChild>
|
||||||
|
<Button
|
||||||
|
size="icon"
|
||||||
|
className="bg-transparent ring-offset-transparent hover:bg-transparent hover:ring-0 hover:ring-transparent"
|
||||||
|
>
|
||||||
|
<span className="sr-only">Open menu</span>
|
||||||
|
<MoreVertical className="h-4 w-4 text-default-800" />
|
||||||
|
</Button>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent className="p-0" align="end">
|
||||||
|
<a href="/en/task/detail/[id]">
|
||||||
|
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
|
||||||
|
<Eye className="w-4 h-4 me-1.5" />
|
||||||
|
View
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</a>
|
||||||
|
<DropdownMenuItem className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-destructive-foreground rounded-none">
|
||||||
|
<Trash2 className="w-4 h-4 me-1.5" />
|
||||||
|
Delete
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
const TableSPIT = () => {
|
const TableSPIT = () => {
|
||||||
|
const [spitTable, setSpitTable] = React.useState<CompanyData[]>([]);
|
||||||
const [sorting, setSorting] = React.useState<SortingState>([]);
|
const [sorting, setSorting] = React.useState<SortingState>([]);
|
||||||
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
|
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
|
||||||
[]
|
[]
|
||||||
|
|
@ -35,9 +211,29 @@ const TableSPIT = () => {
|
||||||
const [columnVisibility, setColumnVisibility] =
|
const [columnVisibility, setColumnVisibility] =
|
||||||
React.useState<VisibilityState>({});
|
React.useState<VisibilityState>({});
|
||||||
const [rowSelection, setRowSelection] = React.useState({});
|
const [rowSelection, setRowSelection] = React.useState({});
|
||||||
|
const [pagination, setPagination] = React.useState<PaginationState>({
|
||||||
|
pageIndex: 0, // Halaman pertama
|
||||||
|
pageSize: 10, // Jumlah baris per halaman
|
||||||
|
});
|
||||||
|
const [page, setPage] = React.useState(1); // Halaman aktif
|
||||||
|
const [totalPage, setTotalPage] = React.useState(1); // Total halaman
|
||||||
|
const [limit, setLimit] = React.useState(6); // Jumlah baris per halaman
|
||||||
|
const [search, setSearch] = React.useState(title);
|
||||||
|
const userId = getCookiesDecrypt("uie");
|
||||||
|
const userLevelId = getCookiesDecrypt("ulie");
|
||||||
|
|
||||||
|
const [categories, setCategories] = React.useState();
|
||||||
|
const [categoryFilter, setCategoryFilter] = React.useState([]);
|
||||||
|
const [statusFilter, setStatusFilter] = React.useState([1, 2]);
|
||||||
|
const [startDateString, setStartDateString] = React.useState("");
|
||||||
|
const [endDateString, setEndDateString] = React.useState("");
|
||||||
|
const [filterByCreator, setFilterByCreator] = React.useState("");
|
||||||
|
const [filterBySource, setFilterBySource] = React.useState("");
|
||||||
|
|
||||||
|
const roleId = getCookiesDecrypt("urie");
|
||||||
|
|
||||||
const table = useReactTable({
|
const table = useReactTable({
|
||||||
data,
|
data: spitTable,
|
||||||
columns,
|
columns,
|
||||||
onSortingChange: setSorting,
|
onSortingChange: setSorting,
|
||||||
onColumnFiltersChange: setColumnFilters,
|
onColumnFiltersChange: setColumnFilters,
|
||||||
|
|
@ -55,6 +251,47 @@ const TableSPIT = () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
initState();
|
||||||
|
}, [page, limit]);
|
||||||
|
|
||||||
|
async function initState() {
|
||||||
|
try {
|
||||||
|
const isForSelf = Number(roleId) == 4;
|
||||||
|
|
||||||
|
let isPublish;
|
||||||
|
if (statusFilter.length > 1) {
|
||||||
|
isPublish = "";
|
||||||
|
} else if (statusFilter.length === 1) {
|
||||||
|
if (statusFilter.includes(1)) {
|
||||||
|
isPublish = false;
|
||||||
|
} else {
|
||||||
|
isPublish = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
isPublish = undefined;
|
||||||
|
}
|
||||||
|
const res = await listSPIT(pages, limit, search, isPublish);
|
||||||
|
const data = res.data.data.content.map((item: any, index: number) => ({
|
||||||
|
no: (page - 1) * limit + index + 1,
|
||||||
|
title: item.title,
|
||||||
|
categoryName: item.categoryName,
|
||||||
|
creatorGroup: item.creatorGroup,
|
||||||
|
assignmentType: item.assignmentType?.name || "-",
|
||||||
|
createdAt: item.createdAt,
|
||||||
|
isDone: item.isDone,
|
||||||
|
publishedOn: item.publishedOn,
|
||||||
|
isPublish: item.isPublish,
|
||||||
|
isPublishOnPolda: item.isPublishOnPolda,
|
||||||
|
}));
|
||||||
|
|
||||||
|
setSpitTable(data);
|
||||||
|
setTotalPage(res.data.totalPages);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching tasks:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<div className="flex items-center py-4 px-5">
|
<div className="flex items-center py-4 px-5">
|
||||||
|
|
@ -72,12 +309,11 @@ const TableSPIT = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Table>
|
<Table className="overflow-hidden">
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
{table.getHeaderGroups().map((headerGroup) => (
|
{table.getHeaderGroups().map((headerGroup) => (
|
||||||
<TableRow key={headerGroup.id}>
|
<TableRow key={headerGroup.id} className="bg-default-200">
|
||||||
{headerGroup.headers.map((header) => {
|
{headerGroup.headers.map((header) => (
|
||||||
return (
|
|
||||||
<TableHead key={header.id}>
|
<TableHead key={header.id}>
|
||||||
{header.isPlaceholder
|
{header.isPlaceholder
|
||||||
? null
|
? null
|
||||||
|
|
@ -86,8 +322,7 @@ const TableSPIT = () => {
|
||||||
header.getContext()
|
header.getContext()
|
||||||
)}
|
)}
|
||||||
</TableHead>
|
</TableHead>
|
||||||
);
|
))}
|
||||||
})}
|
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
|
|
@ -97,6 +332,7 @@ const TableSPIT = () => {
|
||||||
<TableRow
|
<TableRow
|
||||||
key={row.id}
|
key={row.id}
|
||||||
data-state={row.getIsSelected() && "selected"}
|
data-state={row.getIsSelected() && "selected"}
|
||||||
|
className="h-[75px]"
|
||||||
>
|
>
|
||||||
{row.getVisibleCells().map((cell) => (
|
{row.getVisibleCells().map((cell) => (
|
||||||
<TableCell key={cell.id}>
|
<TableCell key={cell.id}>
|
||||||
|
|
@ -114,7 +350,41 @@ const TableSPIT = () => {
|
||||||
)}
|
)}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
<TablePagination table={table} />
|
<div className="flex items-center justify-center py-4 gap-2 flex-none">
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="icon"
|
||||||
|
onClick={() => table.previousPage()}
|
||||||
|
disabled={!table.getCanPreviousPage()}
|
||||||
|
className="w-8 h-8"
|
||||||
|
>
|
||||||
|
<ChevronLeft className="w-4 h-4" />
|
||||||
|
</Button>
|
||||||
|
{table.getPageOptions().map((page, pageIndex) => (
|
||||||
|
<Button
|
||||||
|
key={`basic-data-table-${pageIndex}`}
|
||||||
|
onClick={() => table.setPageIndex(pageIndex)}
|
||||||
|
size="icon"
|
||||||
|
className="w-8 h-8"
|
||||||
|
variant={
|
||||||
|
table.getState().pagination.pageIndex === pageIndex
|
||||||
|
? "default"
|
||||||
|
: "outline"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{page + 1}
|
||||||
|
</Button>
|
||||||
|
))}
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="icon"
|
||||||
|
onClick={() => table.nextPage()}
|
||||||
|
disabled={!table.getCanNextPage()}
|
||||||
|
className="w-8 h-8"
|
||||||
|
>
|
||||||
|
<ChevronRight className="w-4 h-4" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import {
|
import {
|
||||||
|
ColumnDef,
|
||||||
ColumnFiltersState,
|
ColumnFiltersState,
|
||||||
|
PaginationState,
|
||||||
SortingState,
|
SortingState,
|
||||||
VisibilityState,
|
VisibilityState,
|
||||||
flexRender,
|
flexRender,
|
||||||
|
|
@ -12,7 +14,6 @@ import {
|
||||||
getSortedRowModel,
|
getSortedRowModel,
|
||||||
useReactTable,
|
useReactTable,
|
||||||
} from "@tanstack/react-table";
|
} from "@tanstack/react-table";
|
||||||
import { columns } from "./columns";
|
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
|
@ -26,6 +27,175 @@ import {
|
||||||
|
|
||||||
import { data } from "./data";
|
import { data } from "./data";
|
||||||
import TablePagination from "./table-pagination";
|
import TablePagination from "./table-pagination";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { format } from "date-fns";
|
||||||
|
import {
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuTrigger,
|
||||||
|
} from "@/components/ui/dropdown-menu";
|
||||||
|
import {
|
||||||
|
ChevronLeft,
|
||||||
|
ChevronRight,
|
||||||
|
Eye,
|
||||||
|
MoreVertical,
|
||||||
|
Trash2,
|
||||||
|
} from "lucide-react";
|
||||||
|
import { title } from "process";
|
||||||
|
|
||||||
|
import { getCookiesDecrypt } from "@/lib/utils";
|
||||||
|
import { listDataImage, listDataTeks } from "@/service/content/content";
|
||||||
|
import page from "../page";
|
||||||
|
|
||||||
|
export type CompanyData = {
|
||||||
|
no: number;
|
||||||
|
title: string;
|
||||||
|
categoryName: string;
|
||||||
|
createdAt: string;
|
||||||
|
creatorGroup: string;
|
||||||
|
publishedOn: string;
|
||||||
|
isPublish: any;
|
||||||
|
isPublishOnPolda: any;
|
||||||
|
isDone: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const columns: ColumnDef<CompanyData>[] = [
|
||||||
|
{
|
||||||
|
accessorKey: "no",
|
||||||
|
header: "No",
|
||||||
|
cell: ({ row }) => (
|
||||||
|
<div className="flex items-center gap-5">
|
||||||
|
<div className="flex-1 text-start">
|
||||||
|
<h4 className="text-sm font-medium text-default-600 whitespace-nowrap mb-1">
|
||||||
|
{row.getValue("no")}
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "title",
|
||||||
|
header: "Judul",
|
||||||
|
cell: ({ row }) => (
|
||||||
|
<div className="flex items-center gap-5">
|
||||||
|
<div className="flex-1 text-start">
|
||||||
|
<h4 className="text-sm font-medium text-default-600 whitespace-nowrap mb-1">
|
||||||
|
{row.getValue("title")}
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "categoryName",
|
||||||
|
header: "Kategori",
|
||||||
|
cell: ({ row }) => (
|
||||||
|
<span className="whitespace-nowrap">{row.getValue("categoryName")}</span>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "createdAt",
|
||||||
|
header: "Tanggal Unggah",
|
||||||
|
cell: ({ row }) => {
|
||||||
|
const createdAt = row.getValue("createdAt") as
|
||||||
|
| string
|
||||||
|
| number
|
||||||
|
| undefined;
|
||||||
|
|
||||||
|
const formattedDate =
|
||||||
|
createdAt && !isNaN(new Date(createdAt).getTime())
|
||||||
|
? format(new Date(createdAt), "dd-MM-yyyy HH:mm:ss")
|
||||||
|
: "-";
|
||||||
|
return <span className="whitespace-nowrap">{formattedDate}</span>;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "creatorGroup",
|
||||||
|
header: "Sumber ",
|
||||||
|
cell: ({ row }) => (
|
||||||
|
<span className="whitespace-nowrap">{row.getValue("creatorGroup")}</span>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "publishedOn",
|
||||||
|
header: "Penempatan File",
|
||||||
|
cell: ({ row }) => {
|
||||||
|
const isPublish = row.original.isPublish;
|
||||||
|
const isPublishOnPolda = row.original.isPublishOnPolda;
|
||||||
|
|
||||||
|
let displayText = "-";
|
||||||
|
if (isPublish && !isPublishOnPolda) {
|
||||||
|
displayText = "Mabes";
|
||||||
|
} else if (isPublish && isPublishOnPolda) {
|
||||||
|
displayText = "Mabes & Polda";
|
||||||
|
} else if (!isPublish && isPublishOnPolda) {
|
||||||
|
displayText = "Polda";
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="text-center whitespace-nowrap" title={displayText}>
|
||||||
|
{displayText}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
accessorKey: "isDone",
|
||||||
|
header: "Status",
|
||||||
|
cell: ({ row }) => {
|
||||||
|
const isDone = row.getValue<boolean>("isDone");
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Button
|
||||||
|
size="sm"
|
||||||
|
color="success"
|
||||||
|
variant="outline"
|
||||||
|
className={` btn btn-sm ${
|
||||||
|
isDone ? "btn-outline-success" : "btn-outline-primary"
|
||||||
|
} pill-btn ml-1`}
|
||||||
|
>
|
||||||
|
{isDone ? "Selesai" : "Aktif"}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "actions",
|
||||||
|
accessorKey: "action",
|
||||||
|
header: "Actions",
|
||||||
|
enableHiding: false,
|
||||||
|
cell: ({ row }) => {
|
||||||
|
return (
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger asChild>
|
||||||
|
<Button
|
||||||
|
size="icon"
|
||||||
|
className="bg-transparent ring-offset-transparent hover:bg-transparent hover:ring-0 hover:ring-transparent"
|
||||||
|
>
|
||||||
|
<span className="sr-only">Open menu</span>
|
||||||
|
<MoreVertical className="h-4 w-4 text-default-800" />
|
||||||
|
</Button>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent className="p-0" align="end">
|
||||||
|
<a href="/en/task/detail/[id]">
|
||||||
|
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
|
||||||
|
<Eye className="w-4 h-4 me-1.5" />
|
||||||
|
View
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</a>
|
||||||
|
<DropdownMenuItem className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-destructive-foreground rounded-none">
|
||||||
|
<Trash2 className="w-4 h-4 me-1.5" />
|
||||||
|
Delete
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
const TableTeks = () => {
|
const TableTeks = () => {
|
||||||
const [sorting, setSorting] = React.useState<SortingState>([]);
|
const [sorting, setSorting] = React.useState<SortingState>([]);
|
||||||
|
|
@ -35,9 +205,29 @@ const TableTeks = () => {
|
||||||
const [columnVisibility, setColumnVisibility] =
|
const [columnVisibility, setColumnVisibility] =
|
||||||
React.useState<VisibilityState>({});
|
React.useState<VisibilityState>({});
|
||||||
const [rowSelection, setRowSelection] = React.useState({});
|
const [rowSelection, setRowSelection] = React.useState({});
|
||||||
|
const [imageTable, setImageTable] = React.useState<CompanyData[]>([]);
|
||||||
|
const [pagination, setPagination] = React.useState<PaginationState>({
|
||||||
|
pageIndex: 0, // Halaman pertama
|
||||||
|
pageSize: 10, // Jumlah baris per halaman
|
||||||
|
});
|
||||||
|
const [totalPage, setTotalPage] = React.useState<number>(1);
|
||||||
|
const [limit, setLimit] = React.useState<number>(10); // Jumlah baris per halaman
|
||||||
|
const [search, setSearch] = React.useState<string>("");
|
||||||
|
const userId = getCookiesDecrypt("uie");
|
||||||
|
const userLevelId = getCookiesDecrypt("ulie");
|
||||||
|
|
||||||
|
const [categories, setCategories] = React.useState();
|
||||||
|
const [categoryFilter, setCategoryFilter] = React.useState([]);
|
||||||
|
const [statusFilter, setStatusFilter] = React.useState([]);
|
||||||
|
const [startDateString, setStartDateString] = React.useState("");
|
||||||
|
const [endDateString, setEndDateString] = React.useState("");
|
||||||
|
const [filterByCreator, setFilterByCreator] = React.useState("");
|
||||||
|
const [filterBySource, setFilterBySource] = React.useState("");
|
||||||
|
|
||||||
|
const roleId = getCookiesDecrypt("urie");
|
||||||
|
|
||||||
const table = useReactTable({
|
const table = useReactTable({
|
||||||
data,
|
data: imageTable,
|
||||||
columns,
|
columns,
|
||||||
onSortingChange: setSorting,
|
onSortingChange: setSorting,
|
||||||
onColumnFiltersChange: setColumnFilters,
|
onColumnFiltersChange: setColumnFilters,
|
||||||
|
|
@ -55,6 +245,59 @@ const TableTeks = () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
initState();
|
||||||
|
}, [limit]);
|
||||||
|
|
||||||
|
async function initState() {
|
||||||
|
try {
|
||||||
|
const isForSelf = Number(roleId) === 4;
|
||||||
|
const res = await listDataTeks(
|
||||||
|
pagination.pageSize, // Ambil nilai dari pagination.pageSize
|
||||||
|
pagination.pageIndex + 1, // API sering menggunakan page 1-based
|
||||||
|
isForSelf,
|
||||||
|
!isForSelf,
|
||||||
|
categoryFilter?.sort().join(","),
|
||||||
|
statusFilter?.sort().join(",").includes("1")
|
||||||
|
? "1,2"
|
||||||
|
: statusFilter?.sort().join(","),
|
||||||
|
statusFilter?.sort().join(",").includes("1") ? userLevelId : "",
|
||||||
|
filterByCreator,
|
||||||
|
filterBySource,
|
||||||
|
startDateString,
|
||||||
|
endDateString
|
||||||
|
);
|
||||||
|
|
||||||
|
setupData(res.data?.data);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching tasks:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupData(rawData: {
|
||||||
|
content: any[];
|
||||||
|
totalPages: number;
|
||||||
|
totalElements: number;
|
||||||
|
}) {
|
||||||
|
if (rawData?.content) {
|
||||||
|
const data: CompanyData[] = rawData.content.map((item, index) => ({
|
||||||
|
no: pagination.pageIndex * pagination.pageSize + index + 1,
|
||||||
|
title: item.title,
|
||||||
|
categoryName: item.categoryName,
|
||||||
|
creatorGroup: item.creatorGroup,
|
||||||
|
createdAt: item.createdAt,
|
||||||
|
isDone: item.isDone,
|
||||||
|
publishedOn: item.publishedOn,
|
||||||
|
isPublish: item.isPublish,
|
||||||
|
isPublishOnPolda: item.isPublishOnPolda,
|
||||||
|
}));
|
||||||
|
|
||||||
|
setImageTable(data);
|
||||||
|
setTotalPage(rawData.totalPages);
|
||||||
|
console.log(data, "dataImage");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<div className="flex items-center py-4 px-5">
|
<div className="flex items-center py-4 px-5">
|
||||||
|
|
@ -72,12 +315,11 @@ const TableTeks = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Table>
|
<Table className="overflow-hidden">
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
{table.getHeaderGroups().map((headerGroup) => (
|
{table.getHeaderGroups().map((headerGroup) => (
|
||||||
<TableRow key={headerGroup.id}>
|
<TableRow key={headerGroup.id} className="bg-default-200">
|
||||||
{headerGroup.headers.map((header) => {
|
{headerGroup.headers.map((header) => (
|
||||||
return (
|
|
||||||
<TableHead key={header.id}>
|
<TableHead key={header.id}>
|
||||||
{header.isPlaceholder
|
{header.isPlaceholder
|
||||||
? null
|
? null
|
||||||
|
|
@ -86,8 +328,7 @@ const TableTeks = () => {
|
||||||
header.getContext()
|
header.getContext()
|
||||||
)}
|
)}
|
||||||
</TableHead>
|
</TableHead>
|
||||||
);
|
))}
|
||||||
})}
|
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
|
|
@ -97,6 +338,7 @@ const TableTeks = () => {
|
||||||
<TableRow
|
<TableRow
|
||||||
key={row.id}
|
key={row.id}
|
||||||
data-state={row.getIsSelected() && "selected"}
|
data-state={row.getIsSelected() && "selected"}
|
||||||
|
className="h-[75px]"
|
||||||
>
|
>
|
||||||
{row.getVisibleCells().map((cell) => (
|
{row.getVisibleCells().map((cell) => (
|
||||||
<TableCell key={cell.id}>
|
<TableCell key={cell.id}>
|
||||||
|
|
@ -114,7 +356,41 @@ const TableTeks = () => {
|
||||||
)}
|
)}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
<TablePagination table={table} />
|
<div className="flex items-center justify-center py-4 gap-2 flex-none">
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="icon"
|
||||||
|
onClick={() => table.previousPage()}
|
||||||
|
disabled={!table.getCanPreviousPage()}
|
||||||
|
className="w-8 h-8"
|
||||||
|
>
|
||||||
|
<ChevronLeft className="w-4 h-4" />
|
||||||
|
</Button>
|
||||||
|
{table.getPageOptions().map((page, pageIndex) => (
|
||||||
|
<Button
|
||||||
|
key={`basic-data-table-${pageIndex}`}
|
||||||
|
onClick={() => table.setPageIndex(pageIndex)}
|
||||||
|
size="icon"
|
||||||
|
className="w-8 h-8"
|
||||||
|
variant={
|
||||||
|
table.getState().pagination.pageIndex === pageIndex
|
||||||
|
? "default"
|
||||||
|
: "outline"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{page + 1}
|
||||||
|
</Button>
|
||||||
|
))}
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="icon"
|
||||||
|
onClick={() => table.nextPage()}
|
||||||
|
disabled={!table.getCanNextPage()}
|
||||||
|
className="w-8 h-8"
|
||||||
|
>
|
||||||
|
<ChevronRight className="w-4 h-4" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,23 @@
|
||||||
|
"use client";
|
||||||
import { Card, CardContent } from "@/components/ui/card";
|
import { Card, CardContent } from "@/components/ui/card";
|
||||||
import TaskTable from "./table-task/task-table";
|
import TaskTable from "./table-task/task-table";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { UploadIcon } from "lucide-react";
|
import { UploadIcon } from "lucide-react";
|
||||||
import SiteBreadcrumb from "@/components/site-breadcrumb";
|
import SiteBreadcrumb from "@/components/site-breadcrumb";
|
||||||
import { Link } from "@/components/navigation";
|
import { Link } from "@/components/navigation";
|
||||||
|
import { checkAuthorization, checkLoginSession } from "@/lib/utils";
|
||||||
|
import React, { useEffect } from "react";
|
||||||
|
|
||||||
|
const TaskPage = () => {
|
||||||
|
useEffect(() => {
|
||||||
|
function initState() {
|
||||||
|
checkAuthorization("admin"); // Specify the page, e.g., "admin" or another value
|
||||||
|
checkLoginSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
initState();
|
||||||
|
}, []);
|
||||||
|
|
||||||
const TaskPage = async () => {
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<SiteBreadcrumb />
|
<SiteBreadcrumb />
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,13 @@ import { title } from "process";
|
||||||
import search from "../../app/chat/components/search";
|
import search from "../../app/chat/components/search";
|
||||||
import { format } from "date-fns";
|
import { format } from "date-fns";
|
||||||
import { listTask } from "@/service/task";
|
import { listTask } from "@/service/task";
|
||||||
|
import { getCookiesDecrypt } from "@/lib/utils";
|
||||||
|
import {
|
||||||
|
Select,
|
||||||
|
SelectContent,
|
||||||
|
SelectGroup,
|
||||||
|
SelectItem,
|
||||||
|
} from "@/components/ui/select";
|
||||||
|
|
||||||
export type CompanyData = {
|
export type CompanyData = {
|
||||||
no: number;
|
no: number;
|
||||||
|
|
@ -202,9 +209,13 @@ const TaskTable = () => {
|
||||||
});
|
});
|
||||||
const [page, setPage] = React.useState(1);
|
const [page, setPage] = React.useState(1);
|
||||||
const [totalPage, setTotalPage] = React.useState(1);
|
const [totalPage, setTotalPage] = React.useState(1);
|
||||||
const [limit, setLimit] = React.useState(100);
|
const [limit, setLimit] = React.useState(10);
|
||||||
const [search, setSearch] = React.useState(title);
|
const [search, setSearch] = React.useState(title);
|
||||||
|
|
||||||
|
const userId = getCookiesDecrypt("uie");
|
||||||
|
const userLevelNumber = getCookiesDecrypt("ulne");
|
||||||
|
const userRoleId = getCookiesDecrypt("urie");
|
||||||
|
|
||||||
const table = useReactTable({
|
const table = useReactTable({
|
||||||
data: taskTable,
|
data: taskTable,
|
||||||
columns,
|
columns,
|
||||||
|
|
@ -261,6 +272,18 @@ const TaskTable = () => {
|
||||||
/>
|
/>
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="col-sm-2 col-xs-4 my-1">
|
||||||
|
{/* <Select onValueChange={handleLimit} name="limit">
|
||||||
|
<SelectContent>
|
||||||
|
<SelectGroup>
|
||||||
|
<SelectItem value="10">1-10 Data</SelectItem>
|
||||||
|
<SelectItem value="20">1-20 Data</SelectItem>
|
||||||
|
<SelectItem value="25">1-25 Data</SelectItem>
|
||||||
|
<SelectItem value="50">1-50 Data</SelectItem>
|
||||||
|
</SelectGroup>
|
||||||
|
</SelectContent>
|
||||||
|
</Select> */}
|
||||||
|
</div>
|
||||||
<div className="flex-none">
|
<div className="flex-none">
|
||||||
<Input
|
<Input
|
||||||
placeholder="Filter Status..."
|
placeholder="Filter Status..."
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import SearchSection from "@/components/landing-page/SearchSection";
|
import SearchSection from "@/components/landing-page/SearchSection";
|
||||||
import NewContent from "@/components/landing-page/new-content";
|
import NewContent from "@/components/landing-page/new-content";
|
||||||
import PopularContent from "@/components/landing-page/popular-content";
|
import PopularContent from "@/components/landing-page/popular-content";
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,6 @@ import {
|
||||||
import { Checkbox } from "@/components/ui/checkbox";
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
||||||
import JoditEditor from "jodit-react";
|
import JoditEditor from "jodit-react";
|
||||||
import { type } from "os";
|
|
||||||
import loading from "@/app/[locale]/(protected)/app/projects/loading";
|
|
||||||
import { request } from "http";
|
|
||||||
import { error } from "@/lib/utils";
|
|
||||||
import { createTask } from "@/service/task";
|
import { createTask } from "@/service/task";
|
||||||
|
|
||||||
const taskSchema = z.object({
|
const taskSchema = z.object({
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "../ui/dropdown-menu";
|
import {
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuTrigger,
|
||||||
|
} from "../ui/dropdown-menu";
|
||||||
import { FiFile, FiImage, FiMusic, FiYoutube } from "react-icons/fi";
|
import { FiFile, FiImage, FiMusic, FiYoutube } from "react-icons/fi";
|
||||||
|
|
||||||
const SearchSection = () => {
|
const SearchSection = () => {
|
||||||
|
|
@ -8,10 +13,15 @@ const SearchSection = () => {
|
||||||
<div className="max-w-screen-lg mx-auto text-center">
|
<div className="max-w-screen-lg mx-auto text-center">
|
||||||
{/* Heading */}
|
{/* Heading */}
|
||||||
<h1 className="text-2xl md:text-3xl font-bold text-gray-800 dark:text-white">
|
<h1 className="text-2xl md:text-3xl font-bold text-gray-800 dark:text-white">
|
||||||
<span className="text-[#bb3523] dark:text-white">Eksplorasi</span> dan <span className="text-[#bb3523] dark:text-white">Download</span> Liputan Resmi Kami
|
<span className="text-[#bb3523] dark:text-white">Eksplorasiii</span>{" "}
|
||||||
|
dan <span className="text-[#bb3523] dark:text-white">Download</span>{" "}
|
||||||
|
Liputan Resmi Kami
|
||||||
</h1>
|
</h1>
|
||||||
<div className="w-full h-1 bg-[#bb3523] mx-auto mt-2"></div>
|
<div className="w-full h-1 bg-[#bb3523] mx-auto mt-2"></div>
|
||||||
<p className="text-sm md:text-base text-gray-500 dark:text-gray-100 mt-4">Liputan resmi yang bersumber dari kegiatan Polri di Mabes dan Polda seluruh Indonesia</p>
|
<p className="text-sm md:text-base text-gray-500 dark:text-gray-100 mt-4">
|
||||||
|
Liputan resmi yang bersumber dari kegiatan Polri di Mabes dan Polda
|
||||||
|
seluruh Indonesia
|
||||||
|
</p>
|
||||||
|
|
||||||
{/* Search Form */}
|
{/* Search Form */}
|
||||||
<div className="mt-6 flex flex-col md:flex-row justify-center gap-4">
|
<div className="mt-6 flex flex-col md:flex-row justify-center gap-4">
|
||||||
|
|
@ -20,19 +30,39 @@ const SearchSection = () => {
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
<a className="text-black dark:text-white flex flex-row justify-center items-center ml-5 cursor-pointer">
|
<a className="text-black dark:text-white flex flex-row justify-center items-center ml-5 cursor-pointer">
|
||||||
<svg className="mx-2" width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg
|
||||||
|
className="mx-2"
|
||||||
|
width="25"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 25 24"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
<path
|
<path
|
||||||
d="M20 7.5H5C4.6023 7.5004 4.221 7.65856 3.93978 7.93978C3.65856 8.221 3.5004 8.6023 3.5 9V19.5C3.5004 19.8977 3.65856 20.279 3.93978 20.5602C4.221 20.8414 4.6023 20.9996 5 21H20C20.3977 20.9996 20.779 20.8414 21.0602 20.5602C21.3414 20.279 21.4996 19.8977 21.5 19.5V9C21.4996 8.6023 21.3414 8.221 21.0602 7.93978C20.779 7.65856 20.3977 7.5004 20 7.5ZM10.25 17.25V11.25L15.5 14.25L10.25 17.25ZM5 4.5H20V6H5V4.5ZM6.5 1.5H18.5V3H6.5V1.5Z"
|
d="M20 7.5H5C4.6023 7.5004 4.221 7.65856 3.93978 7.93978C3.65856 8.221 3.5004 8.6023 3.5 9V19.5C3.5004 19.8977 3.65856 20.279 3.93978 20.5602C4.221 20.8414 4.6023 20.9996 5 21H20C20.3977 20.9996 20.779 20.8414 21.0602 20.5602C21.3414 20.279 21.4996 19.8977 21.5 19.5V9C21.4996 8.6023 21.3414 8.221 21.0602 7.93978C20.779 7.65856 20.3977 7.5004 20 7.5ZM10.25 17.25V11.25L15.5 14.25L10.25 17.25ZM5 4.5H20V6H5V4.5ZM6.5 1.5H18.5V3H6.5V1.5Z"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
Konten
|
Konten
|
||||||
<svg className="flex items-center justify-center" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
|
<svg
|
||||||
<path fill="currentColor" fill-rule="evenodd" d="m6 7l6 6l6-6l2 2l-8 8l-8-8z" />
|
className="flex items-center justify-center"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="1em"
|
||||||
|
height="1em"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="m6 7l6 6l6-6l2 2l-8 8l-8-8z"
|
||||||
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent align="end" className="p-0 rounded-md overflow-hidden">
|
<DropdownMenuContent
|
||||||
|
align="end"
|
||||||
|
className="p-0 rounded-md overflow-hidden"
|
||||||
|
>
|
||||||
<DropdownMenuItem className="flex items-center gap-1.5 p-2 border-b text-default-600 group focus:bg-default focus:text-primary-foreground rounded-none group">
|
<DropdownMenuItem className="flex items-center gap-1.5 p-2 border-b text-default-600 group focus:bg-default focus:text-primary-foreground rounded-none group">
|
||||||
<span className="text-default-700c flex flex-row justify-center items-center group-hover:text-primary-foreground">
|
<span className="text-default-700c flex flex-row justify-center items-center group-hover:text-primary-foreground">
|
||||||
<FiYoutube className="mr-2" />
|
<FiYoutube className="mr-2" />
|
||||||
|
|
@ -64,18 +94,29 @@ const SearchSection = () => {
|
||||||
{/* Search Input */}
|
{/* Search Input */}
|
||||||
<div className="flex items-center flex-1 border border-gray-300 rounded-lg overflow-hidden">
|
<div className="flex items-center flex-1 border border-gray-300 rounded-lg overflow-hidden">
|
||||||
<span className="material-icons text-black dark:text-white px-4">
|
<span className="material-icons text-black dark:text-white px-4">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="1em"
|
||||||
|
height="1em"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
<path
|
<path
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
d="m19.6 21l-6.3-6.3q-.75.6-1.725.95T9.5 16q-2.725 0-4.612-1.888T3 9.5t1.888-4.612T9.5 3t4.613 1.888T16 9.5q0 1.1-.35 2.075T14.7 13.3l6.3 6.3zM9.5 14q1.875 0 3.188-1.312T14 9.5t-1.312-3.187T9.5 5T6.313 6.313T5 9.5t1.313 3.188T9.5 14"
|
d="m19.6 21l-6.3-6.3q-.75.6-1.725.95T9.5 16q-2.725 0-4.612-1.888T3 9.5t1.888-4.612T9.5 3t4.613 1.888T16 9.5q0 1.1-.35 2.075T14.7 13.3l6.3 6.3zM9.5 14q1.875 0 3.188-1.312T14 9.5t-1.312-3.187T9.5 5T6.313 6.313T5 9.5t1.313 3.188T9.5 14"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</span>
|
</span>
|
||||||
<input type="text" placeholder="Pencarian" className="w-full py-2 px-2 text-sm text-gray-700 dark:text-gray-100 focus:outline-none" />
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Pencarian"
|
||||||
|
className="w-full py-2 px-2 text-sm text-gray-700 dark:text-gray-100 focus:outline-none"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Button */}
|
{/* Button */}
|
||||||
<button className="px-6 py-2 bg-[#bb3523] text-white rounded-lg hover:bg-red-700">Cari Liputan ></button>
|
<button className="px-6 py-2 bg-[#bb3523] text-white rounded-lg hover:bg-red-700">
|
||||||
|
Cari Liputan >
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
||||||
|
|
@ -4,65 +4,184 @@ import { Button } from "@/components/ui/button";
|
||||||
import { Checkbox } from "@/components/ui/checkbox";
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Label } from "@/components/ui/label";
|
import { Label } from "@/components/ui/label";
|
||||||
import { Link } from "@/i18n/routing";
|
import Cookies from "js-cookie";
|
||||||
import { Icon } from "@/components/ui/icon";
|
import { Icon } from "@/components/ui/icon";
|
||||||
import { useForm, SubmitHandler } from "react-hook-form";
|
import { useForm, SubmitHandler } from "react-hook-form";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn, setCookiesEncrypt } from "@/lib/utils";
|
||||||
import { Loader2 } from "lucide-react";
|
import { Loader2 } from "lucide-react";
|
||||||
import { loginUser } from "@/action/auth-action";
|
import { getProfile, setLogin } from "@/service/auth";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { useRouter } from "@/components/navigation";
|
import { Link, useRouter } from "@/components/navigation";
|
||||||
|
import { warning } from "@/lib/swal";
|
||||||
|
|
||||||
|
// Schema validasi menggunakan zod
|
||||||
const schema = z.object({
|
const schema = z.object({
|
||||||
email: z.string().email({ message: "Your email is invalid." }),
|
username: z.string().min(1, { message: "Judul diperlukan" }),
|
||||||
password: z.string().min(4),
|
password: z
|
||||||
|
.string()
|
||||||
|
.min(4, { message: "Password must be at least 4 characters." }),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Tipe untuk form values
|
||||||
|
type LoginFormValues = {
|
||||||
|
username: string;
|
||||||
|
password: string;
|
||||||
|
};
|
||||||
|
|
||||||
const LoginForm = () => {
|
const LoginForm = () => {
|
||||||
const [isPending, startTransition] = React.useTransition();
|
const [isPending, startTransition] = React.useTransition();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [passwordType, setPasswordType] = React.useState("password");
|
const [passwordType, setPasswordType] = React.useState("password");
|
||||||
|
|
||||||
const togglePasswordType = () => {
|
const togglePasswordType = () => {
|
||||||
if (passwordType === "text") {
|
setPasswordType((prevType) =>
|
||||||
setPasswordType("password");
|
prevType === "password" ? "text" : "password"
|
||||||
} else if (passwordType === "password") {
|
);
|
||||||
setPasswordType("text");
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const {
|
const {
|
||||||
register,
|
register,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
reset,
|
|
||||||
formState: { errors },
|
formState: { errors },
|
||||||
} = useForm({
|
} = useForm<LoginFormValues>({
|
||||||
resolver: zodResolver(schema),
|
resolver: zodResolver(schema),
|
||||||
mode: "all",
|
mode: "all",
|
||||||
defaultValues: {
|
|
||||||
email: "dashcode@codeshaper.net",
|
|
||||||
password: "password",
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
const [isVisible, setIsVisible] = React.useState(false);
|
|
||||||
|
|
||||||
const toggleVisibility = () => setIsVisible(!isVisible);
|
// Fungsi submit form
|
||||||
|
const onSubmit: SubmitHandler<LoginFormValues> = async (data) => {
|
||||||
const onSubmit = (data: z.infer<typeof schema>) => {
|
|
||||||
startTransition(async () => {
|
startTransition(async () => {
|
||||||
try {
|
try {
|
||||||
const response = await loginUser(data);
|
const response = await setLogin({
|
||||||
|
...data,
|
||||||
|
grant_type: "password",
|
||||||
|
client_id: "mediahub-app",
|
||||||
|
});
|
||||||
|
|
||||||
if (!!response.error) {
|
if (response.error) {
|
||||||
toast("Event has been created", {
|
toast.error("Username / Password Tidak Sesuai");
|
||||||
description: "Sunday, December 03, 2023 at 9:00 AM",
|
} else {
|
||||||
|
const { access_token } = response.data;
|
||||||
|
const { refresh_token } = response.data;
|
||||||
|
const dateTime = new Date();
|
||||||
|
const newTime = dateTime.getTime() + 10 * 60 * 1000;
|
||||||
|
|
||||||
|
Cookies.set("access_token", access_token, {
|
||||||
|
expires: 1,
|
||||||
|
});
|
||||||
|
Cookies.set("refresh_token", refresh_token, {
|
||||||
|
expires: 1,
|
||||||
|
});
|
||||||
|
Cookies.set("time_refresh", new Date(newTime).toISOString(), {
|
||||||
|
expires: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
Cookies.set("is_first_login", String(true), {
|
||||||
|
secure: true,
|
||||||
|
sameSite: "strict",
|
||||||
|
});
|
||||||
|
const profile = await getProfile(access_token);
|
||||||
|
console.log("PROFILE : ", profile?.data?.data);
|
||||||
|
|
||||||
|
if (
|
||||||
|
profile?.data?.data?.isInternational == true ||
|
||||||
|
profile?.data?.data?.isActive == false ||
|
||||||
|
profile?.data?.data?.isDelete == true
|
||||||
|
) {
|
||||||
|
Object.keys(Cookies.get()).forEach((cookieName) => {
|
||||||
|
Cookies.remove(cookieName);
|
||||||
|
});
|
||||||
|
warning(
|
||||||
|
"Akun Anda tidak dapat digunakan untuk masuk ke MediaHub Polri",
|
||||||
|
"/auth/login"
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
Cookies.set("home_path", profile.data?.data?.homePath, {
|
||||||
|
expires: 1,
|
||||||
|
});
|
||||||
|
Cookies.set(
|
||||||
|
"profile_picture",
|
||||||
|
profile.data?.data?.profilePictureUrl,
|
||||||
|
{
|
||||||
|
expires: 1,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
Cookies.set("state", profile.data?.data?.userLevel?.name, {
|
||||||
|
expires: 1,
|
||||||
|
});
|
||||||
|
setCookiesEncrypt("uie", profile.data.data?.id, {
|
||||||
|
expires: 1,
|
||||||
|
});
|
||||||
|
setCookiesEncrypt("urie", profile.data.data?.roleId, {
|
||||||
|
expires: 1,
|
||||||
|
});
|
||||||
|
setCookiesEncrypt("urne", profile.data.data?.role?.name, {
|
||||||
|
expires: 1,
|
||||||
|
});
|
||||||
|
setCookiesEncrypt("ulie", profile.data.data?.userLevel?.id, {
|
||||||
|
expires: 1,
|
||||||
|
});
|
||||||
|
setCookiesEncrypt(
|
||||||
|
"ulplie",
|
||||||
|
profile.data.data?.userLevel?.parentLevelId,
|
||||||
|
{
|
||||||
|
expires: 1,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
setCookiesEncrypt(
|
||||||
|
"ulne",
|
||||||
|
profile.data.data?.userLevel?.levelNumber,
|
||||||
|
{
|
||||||
|
expires: 1,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
setCookiesEncrypt("ufne", profile.data.data?.fullname, {
|
||||||
|
expires: 1,
|
||||||
|
});
|
||||||
|
setCookiesEncrypt("ulnae", profile.data.data?.userLevel?.name, {
|
||||||
|
expires: 1,
|
||||||
|
});
|
||||||
|
setCookiesEncrypt("uinse", profile.data.data?.instituteId, {
|
||||||
|
expires: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (
|
||||||
|
Number(profile.data.data?.roleId) == 2 ||
|
||||||
|
Number(profile.data.data?.roleId) == 3 ||
|
||||||
|
Number(profile.data.data?.roleId) == 4 ||
|
||||||
|
Number(profile.data.data?.roleId) == 9 ||
|
||||||
|
Number(profile.data.data?.roleId) == 10 ||
|
||||||
|
Number(profile.data.data?.roleId) == 11 ||
|
||||||
|
Number(profile.data.data?.roleId) == 12
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
profile.data.data?.userLevel?.id == 761 ||
|
||||||
|
profile.data.data?.userLevel?.parentLevelId == 761
|
||||||
|
) {
|
||||||
|
window.location.href = "/admin/welcome";
|
||||||
|
// router.push('/admin/dashboard');
|
||||||
|
Cookies.set("status", "login", {
|
||||||
|
expires: 1,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
router.push("/dashboard");
|
window.location.href = "/en/dashboard";
|
||||||
toast.success("Successfully logged in");
|
// router.push('/admin/dashboard');
|
||||||
|
Cookies.set("status", "login", {
|
||||||
|
expires: 1,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
window.location.href = "/";
|
||||||
|
Cookies.set("status", "login", {
|
||||||
|
expires: 1,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
toast.error(err.message);
|
toast.error(err.message || "An unexpected error occurred.");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
@ -70,41 +189,39 @@ const LoginForm = () => {
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit(onSubmit)} className="mt-5 2xl:mt-7 space-y-4">
|
<form onSubmit={handleSubmit(onSubmit)} className="mt-5 2xl:mt-7 space-y-4">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="email" className=" font-medium text-default-600">
|
<Label htmlFor="username" className="font-medium text-default-600">
|
||||||
Email{" "}
|
Username
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
size="lg"
|
size="lg"
|
||||||
disabled={isPending}
|
disabled={isPending}
|
||||||
{...register("email")}
|
{...register("username")}
|
||||||
type="email"
|
id="username"
|
||||||
id="email"
|
type="username"
|
||||||
className={cn("", {
|
className={cn("", {
|
||||||
"border-destructive ": errors.email,
|
"border-destructive": errors.username,
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
</div>
|
{errors.username?.message && (
|
||||||
{errors.email && (
|
<div className="text-destructive mt-2 text-sm">
|
||||||
<div className=" text-destructive mt-2 text-sm">
|
{errors.username.message}
|
||||||
{errors.email.message}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="mt-3.5 space-y-2">
|
<div className="mt-3.5 space-y-2">
|
||||||
<Label htmlFor="password" className="mb-2 font-medium text-default-600">
|
<Label htmlFor="password" className="mb-2 font-medium text-default-600">
|
||||||
Password{" "}
|
Password
|
||||||
</Label>
|
</Label>
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<Input
|
<Input
|
||||||
size="lg"
|
size="lg"
|
||||||
disabled={isPending}
|
disabled={isPending}
|
||||||
{...register("password")}
|
{...register("password")}
|
||||||
type={passwordType}
|
|
||||||
id="password"
|
id="password"
|
||||||
className="peer "
|
type={passwordType}
|
||||||
placeholder=" "
|
className="peer"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className="absolute top-1/2 -translate-y-1/2 ltr:right-4 rtl:left-4 cursor-pointer"
|
className="absolute top-1/2 -translate-y-1/2 ltr:right-4 rtl:left-4 cursor-pointer"
|
||||||
onClick={togglePasswordType}
|
onClick={togglePasswordType}
|
||||||
|
|
@ -119,12 +236,12 @@ const LoginForm = () => {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{errors.password?.message && (
|
||||||
{errors.password && (
|
<div className="text-destructive mt-2 text-sm">
|
||||||
<div className=" text-destructive mt-2 text-sm">
|
|
||||||
{errors.password.message}
|
{errors.password.message}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
<div className="flex gap-2 items-center">
|
<div className="flex gap-2 items-center">
|
||||||
|
|
@ -145,4 +262,5 @@ const LoginForm = () => {
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default LoginForm;
|
export default LoginForm;
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,6 @@ export async function getAPIInterceptor(url: any) {
|
||||||
data: null,
|
data: null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fungsi postAPIInterceptor
|
// Fungsi postAPIInterceptor
|
||||||
export async function postAPIInterceptor(url: string, data: any) {
|
export async function postAPIInterceptor(url: string, data: any) {
|
||||||
const response = await axiosInterceptor
|
const response = await axiosInterceptor
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
import Swal from "sweetalert2";
|
||||||
|
import withReactContent from "sweetalert2-react-content";
|
||||||
|
|
||||||
|
const MySwal = withReactContent(Swal);
|
||||||
|
|
||||||
|
const Toast = MySwal.mixin({
|
||||||
|
toast: true,
|
||||||
|
position: "top-end",
|
||||||
|
showConfirmButton: false,
|
||||||
|
timer: 3000,
|
||||||
|
timerProgressBar: true,
|
||||||
|
didOpen: (toast) => {
|
||||||
|
toast.addEventListener("mouseenter", Swal.stopTimer);
|
||||||
|
toast.addEventListener("mouseleave", Swal.resumeTimer);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export function loading(msg?: any) {
|
||||||
|
let timerInterval: any;
|
||||||
|
MySwal.fire({
|
||||||
|
title: msg || "Loading...",
|
||||||
|
allowOutsideClick: false,
|
||||||
|
timerProgressBar: true,
|
||||||
|
didOpen: () => {
|
||||||
|
MySwal.showLoading();
|
||||||
|
timerInterval = setInterval(() => {}, 100);
|
||||||
|
},
|
||||||
|
willClose: () => {
|
||||||
|
clearInterval(timerInterval);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function error(msg?: any) {
|
||||||
|
MySwal.fire({
|
||||||
|
icon: "error",
|
||||||
|
title: "Failed...",
|
||||||
|
text: msg || "Unknown Error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function successRouter(redirect: string, router?: any) {
|
||||||
|
MySwal.fire({
|
||||||
|
title: "Success!",
|
||||||
|
icon: "success",
|
||||||
|
confirmButtonColor: "#3085d6",
|
||||||
|
confirmButtonText: "Ok",
|
||||||
|
allowOutsideClick: false,
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
router.push(redirect);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function success(title: string) {
|
||||||
|
MySwal.fire({
|
||||||
|
title: title || "Success!",
|
||||||
|
icon: "success",
|
||||||
|
confirmButtonColor: "#3085d6",
|
||||||
|
confirmButtonText: "OK",
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function close() {
|
||||||
|
MySwal.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function warning(text: string, redirect: string, router?: any) {
|
||||||
|
MySwal.fire({
|
||||||
|
title: text,
|
||||||
|
icon: "warning",
|
||||||
|
confirmButtonColor: "#3085d6",
|
||||||
|
confirmButtonText: "OK",
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
router.push(redirect);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function successToast(title: string, text: string) {
|
||||||
|
Toast.fire({
|
||||||
|
icon: "error",
|
||||||
|
title: title,
|
||||||
|
text: text,
|
||||||
|
});
|
||||||
|
}
|
||||||
82
lib/utils.ts
82
lib/utils.ts
|
|
@ -36,6 +36,47 @@ export const hexToRGB = (hex: any, alpha?: number): any => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function getCookiesDecrypt(param: any) {
|
||||||
|
const cookiesEncrypt = Cookies.get(param);
|
||||||
|
try {
|
||||||
|
if (cookiesEncrypt != undefined) {
|
||||||
|
const output = CryptoJS.AES.decrypt(
|
||||||
|
cookiesEncrypt.toString(),
|
||||||
|
`${param}_EncryptKey@mediahub`
|
||||||
|
).toString(CryptoJS.enc.Utf8);
|
||||||
|
if (output.startsWith('"')) {
|
||||||
|
return output.slice(1, -1);
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log("Error", cookiesEncrypt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function successToast(title: string, text: string) {
|
||||||
|
Toast.fire({
|
||||||
|
icon: "error",
|
||||||
|
title: title,
|
||||||
|
text: text,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setCookiesEncrypt(
|
||||||
|
param: string,
|
||||||
|
data: any,
|
||||||
|
options?: Cookies.CookieAttributes
|
||||||
|
) {
|
||||||
|
// Enkripsi data
|
||||||
|
const cookiesEncrypt = CryptoJS.AES.encrypt(
|
||||||
|
JSON.stringify(data),
|
||||||
|
`${param}_EncryptKey@mediahub`
|
||||||
|
).toString(); // Tambahkan .toString() di sini
|
||||||
|
|
||||||
|
// Simpan data terenkripsi di cookie
|
||||||
|
Cookies.set(param, cookiesEncrypt, options);
|
||||||
|
}
|
||||||
|
|
||||||
export function checkAuthorization(page: any) {
|
export function checkAuthorization(page: any) {
|
||||||
const roleId = getCookiesDecrypt("urie");
|
const roleId = getCookiesDecrypt("urie");
|
||||||
const levelNumber = getCookiesDecrypt("ulne");
|
const levelNumber = getCookiesDecrypt("ulne");
|
||||||
|
|
@ -64,44 +105,3 @@ export function checkLoginSession() {
|
||||||
};
|
};
|
||||||
// doCheckSession(data);
|
// doCheckSession(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getCookiesDecrypt(param: any) {
|
|
||||||
const cookiesEncrypt = Cookies.get(param);
|
|
||||||
try {
|
|
||||||
if (cookiesEncrypt != undefined) {
|
|
||||||
const output = CryptoJS.AES.decrypt(
|
|
||||||
cookiesEncrypt.toString(),
|
|
||||||
`${param}_EncryptKey@mediahub`
|
|
||||||
).toString(CryptoJS.enc.Utf8);
|
|
||||||
if (output.startsWith('"')) {
|
|
||||||
return output.slice(1, -1);
|
|
||||||
}
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.log("Error", cookiesEncrypt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function successToast(title: string, text: string) {
|
|
||||||
Toast.fire({
|
|
||||||
icon: "error",
|
|
||||||
title: title,
|
|
||||||
text: text,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setCookiesEncrypt(param: any, data: any) {
|
|
||||||
// Enkripsi data
|
|
||||||
const cookiesEncrypt = CryptoJS.AES.encrypt(
|
|
||||||
JSON.stringify(data),
|
|
||||||
`${param}_EncryptKey@mediahub`
|
|
||||||
).toString(); // Tambahkan .toString() di sini
|
|
||||||
|
|
||||||
// Simpan data terenkripsi di cookie
|
|
||||||
Cookies.set(param, cookiesEncrypt, { expires: 1 });
|
|
||||||
}
|
|
||||||
|
|
||||||
export function error(msg: any) {
|
|
||||||
MySwal.fire("Gagal", msg, "error");
|
|
||||||
}
|
|
||||||
|
|
|
||||||
102
service/auth.ts
102
service/auth.ts
|
|
@ -3,92 +3,30 @@ import Cookies from "js-cookie";
|
||||||
import { getAPI, postAPI, postAPIWithJson } from "../config/api";
|
import { getAPI, postAPI, postAPIWithJson } from "../config/api";
|
||||||
import { getAPIDummy } from "./http-config/axiosCustom";
|
import { getAPIDummy } from "./http-config/axiosCustom";
|
||||||
|
|
||||||
export async function setLogin(data) {
|
import {
|
||||||
const url = "signin";
|
httpGetInterceptorWithToken,
|
||||||
return postAPI({ url, data });
|
httpPostInterceptor,
|
||||||
|
} from "./http-config/http-interceptor-service";
|
||||||
|
|
||||||
|
export async function setLogin(data: any) {
|
||||||
|
const pathUrl = "signin";
|
||||||
|
return postAPI(pathUrl, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getProfile(token) {
|
export async function getProfile(token: any) {
|
||||||
const url = "users/info";
|
const url = "users/info";
|
||||||
return getAPI({ url, token });
|
return getAPI(url, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function saveSession(data) {
|
// export async function setLogin(data: any) {
|
||||||
const url = "users/save-session";
|
// const pathUrl = `signin`;
|
||||||
return postAPIWithJson({ url, data });
|
// const headers = {
|
||||||
}
|
// "content-type": "application/json",
|
||||||
|
// };
|
||||||
|
// return await httpPost(pathUrl, headers, data);
|
||||||
|
// }
|
||||||
|
|
||||||
export async function checkSession(data) {
|
export async function userInfo(token: any) {
|
||||||
const url = "users/check-session";
|
const pathUrl = `users/info`;
|
||||||
return postAPIWithJson({ url, data });
|
return await httpGetInterceptorWithToken(pathUrl, token);
|
||||||
}
|
|
||||||
|
|
||||||
export async function listProvince() {
|
|
||||||
const url = "public/users/provinces";
|
|
||||||
return getAPI({ url });
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function listCity(id) {
|
|
||||||
const url = `public/users/cities?provId=${id}`;
|
|
||||||
return getAPI({ url });
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function listDistricts(id) {
|
|
||||||
const url = `public/users/districts?cityId=${id}`;
|
|
||||||
return getAPI({ url });
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function listInstitusi(roleId) {
|
|
||||||
const url = `public/users/institutes?categoryRoleId=${roleId}`;
|
|
||||||
return getAPI({ url });
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function listRole() {
|
|
||||||
const url = "public/users/roles";
|
|
||||||
return getAPI({ url });
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function refreshToken() {
|
|
||||||
const url = "signin";
|
|
||||||
const data = {
|
|
||||||
grant_type: "refresh_token",
|
|
||||||
client_id: "mediahub-app",
|
|
||||||
refresh_token: Cookies.get("refresh_token"),
|
|
||||||
};
|
|
||||||
return postAPI({ url, data });
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function postRegistration(data) {
|
|
||||||
const url = "public/users/save";
|
|
||||||
return postAPIWithJson({ url, data });
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function saveInstitutes(data) {
|
|
||||||
const url = "public/users/save-institutes";
|
|
||||||
return postAPIWithJson({ url, data });
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function forgotPassword(username) {
|
|
||||||
const url = `forgot-password?username=${username}`;
|
|
||||||
return postAPIWithJson({ url });
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getDataByNIK(reqid, nik) {
|
|
||||||
const url = `http://spitpolri.com/api/back_end/get_ktp?reqid=${reqid}&nik=${nik}`;
|
|
||||||
return getAPIDummy({ url });
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getDataByNRP(reqid, nrp) {
|
|
||||||
const url = `http://spitpolri.com/api/back_end/get_nrp?reqid=${reqid}&nrp=${nrp}`;
|
|
||||||
return getAPIDummy({ url });
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getDataJournalist(cert) {
|
|
||||||
const url = `public/users/search-journalist?cert=${cert}`;
|
|
||||||
return getAPI({ url });
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getDataPersonil(nrp) {
|
|
||||||
const url = `public/users/search-personil?nrp=${nrp}`;
|
|
||||||
return getAPI({ url });
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
import { httpGetInterceptor } from "../http-config/http-interceptor-service";
|
|
||||||
|
|
||||||
export async function listDataImage(
|
|
||||||
page: any,
|
|
||||||
limit: any,
|
|
||||||
isForSelf: any,
|
|
||||||
isApproval: any,
|
|
||||||
categoryFilter: any,
|
|
||||||
statusFilter: any,
|
|
||||||
needApprovalFromLevel: any,
|
|
||||||
creator: any,
|
|
||||||
source: any,
|
|
||||||
startDate: any,
|
|
||||||
endDate: any
|
|
||||||
) {
|
|
||||||
return await httpGetInterceptor(
|
|
||||||
`media/list?enablePage=1&sortBy=createdAt&sort=desc&size=${limit}&page=${page}&typeId=1&isForSelf=${isForSelf}&isApproval=${isApproval}&categoryId=${categoryFilter}&statusId=${statusFilter}&needApprovalFromLevel=${needApprovalFromLevel}&creatorUserLevelName=${source}&creatorName=${creator}&startDate=${startDate}&endDate=${endDate}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
import { getAPIInterceptor } from "@/config/api";
|
||||||
|
import { httpGetInterceptor } from "../http-config/http-interceptor-service";
|
||||||
|
|
||||||
|
export async function listDataImage(
|
||||||
|
page: any,
|
||||||
|
limit: any,
|
||||||
|
isForSelf: any,
|
||||||
|
isApproval: any,
|
||||||
|
categoryFilter: any,
|
||||||
|
statusFilter: any,
|
||||||
|
needApprovalFromLevel: any,
|
||||||
|
creator: any,
|
||||||
|
source: any,
|
||||||
|
startDate: any,
|
||||||
|
endDate: any
|
||||||
|
) {
|
||||||
|
return await httpGetInterceptor(
|
||||||
|
`media/list?enablePage=1&sortBy=createdAt&sort=desc&size=${limit}&page=${page}&typeId=1&isForSelf=${isForSelf}&isApproval=${isApproval}&categoryId=${categoryFilter}&statusId=${statusFilter}&needApprovalFromLevel=${needApprovalFromLevel}&creatorUserLevelName=${source}&creatorName=${creator}&startDate=${startDate}&endDate=${endDate}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function listDataVideo(
|
||||||
|
page: any,
|
||||||
|
limit: any,
|
||||||
|
isForSelf: any,
|
||||||
|
isApproval: any,
|
||||||
|
categoryFilter: any,
|
||||||
|
statusFilter: any,
|
||||||
|
needApprovalFromLevel: any,
|
||||||
|
creator: any,
|
||||||
|
source: any,
|
||||||
|
startDate: any,
|
||||||
|
endDate: any
|
||||||
|
) {
|
||||||
|
return await httpGetInterceptor(
|
||||||
|
`media/list?enablePage=1&sortBy=createdAt&sort=desc&size=${limit}&page=${page}&typeId=2&isForSelf=${isForSelf}&isApproval=${isApproval}&categoryId=${categoryFilter}&statusId=${statusFilter}&needApprovalFromLevel=${needApprovalFromLevel}&creatorUserLevelName=${source}&creatorName=${creator}&startDate=${startDate}&endDate=${endDate}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function listDataTeks(
|
||||||
|
page: any,
|
||||||
|
limit: any,
|
||||||
|
isForSelf: any,
|
||||||
|
isApproval: any,
|
||||||
|
categoryFilter: any,
|
||||||
|
statusFilter: any,
|
||||||
|
needApprovalFromLevel: any,
|
||||||
|
creator: any,
|
||||||
|
source: any,
|
||||||
|
startDate: any,
|
||||||
|
endDate: any
|
||||||
|
) {
|
||||||
|
return await httpGetInterceptor(
|
||||||
|
`media/list?enablePage=1&sortBy=createdAt&sort=desc&size=${limit}&page=${page}&typeId=3&isForSelf=${isForSelf}&isApproval=${isApproval}&categoryId=${categoryFilter}&statusId=${statusFilter}&needApprovalFromLevel=${needApprovalFromLevel}&creatorUserLevelName=${source}&creatorName=${creator}&startDate=${startDate}&endDate=${endDate}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function listDataAudio(
|
||||||
|
page: any,
|
||||||
|
limit: any,
|
||||||
|
isForSelf: any,
|
||||||
|
isApproval: any,
|
||||||
|
categoryFilter: any,
|
||||||
|
statusFilter: any,
|
||||||
|
needApprovalFromLevel: any,
|
||||||
|
creator: any,
|
||||||
|
source: any,
|
||||||
|
startDate: any,
|
||||||
|
endDate: any
|
||||||
|
) {
|
||||||
|
return await httpGetInterceptor(
|
||||||
|
`media/list?enablePage=1&sortBy=createdAt&sort=desc&size=${limit}&page=${page}&typeId=4&isForSelf=${isForSelf}&isApproval=${isApproval}&categoryId=${categoryFilter}&statusId=${statusFilter}&needApprovalFromLevel=${needApprovalFromLevel}&creatorUserLevelName=${source}&creatorName=${creator}&startDate=${startDate}&endDate=${endDate}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function listSPIT(
|
||||||
|
page: any,
|
||||||
|
limit: any,
|
||||||
|
title = "",
|
||||||
|
isPublish: any
|
||||||
|
) {
|
||||||
|
return await httpGetInterceptor(
|
||||||
|
`media/spit/pagination?enablePage=1&page=${page}&size=${limit}&sort=desc&sortBy=contentTitleId&title=${title}&isPublish=${isPublish}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -40,6 +40,8 @@ axiosInterceptorInstance.interceptors.response.use(
|
||||||
originalRequest._retry = true;
|
originalRequest._retry = true;
|
||||||
const data = {
|
const data = {
|
||||||
refreshToken: refreshToken,
|
refreshToken: refreshToken,
|
||||||
|
grant_type: "refresh_token",
|
||||||
|
client_id: "mediahub-app",
|
||||||
};
|
};
|
||||||
const res = await login(data);
|
const res = await login(data);
|
||||||
if (res.data?.data?.access_token) {
|
if (res.data?.data?.access_token) {
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,56 @@
|
||||||
|
import axiosInstance from "@/config/axiosInstance";
|
||||||
import axiosBaseInstance from "./axios-base-instance";
|
import axiosBaseInstance from "./axios-base-instance";
|
||||||
|
import axios from "axios";
|
||||||
|
import Cookies from "js-cookie";
|
||||||
|
import qs from "qs";
|
||||||
|
|
||||||
export async function httpPost(pathUrl: any, headers: any, data?: any) {
|
// export async function httpPost(pathUrl: any, headers: any, data?: any) {
|
||||||
const response = await axiosBaseInstance
|
// const response = await axiosBaseInstance
|
||||||
.post(pathUrl, data, { headers })
|
// .post(pathUrl, data, { headers })
|
||||||
.catch(function (error: any) {
|
// .catch(function (error: any) {
|
||||||
console.log(error);
|
// console.log(error);
|
||||||
return error.response;
|
// return error.response;
|
||||||
});
|
// });
|
||||||
console.log("Response base svc : ", response);
|
// console.log("Response base svc : ", response);
|
||||||
if (response?.status == 200 || response?.status == 201) {
|
// if (response?.status == 200 || response?.status == 201) {
|
||||||
|
// return {
|
||||||
|
// error: false,
|
||||||
|
// message: "success",
|
||||||
|
// data: response?.data,
|
||||||
|
// };
|
||||||
|
// } else {
|
||||||
|
// return {
|
||||||
|
// error: true,
|
||||||
|
// message: response?.data?.message || response?.data || null,
|
||||||
|
// data: null,
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
const baseURL = "https://netidhub.com/api/";
|
||||||
|
const tokenAuth = Cookies.get("access_token")
|
||||||
|
? Cookies.get("access_token")
|
||||||
|
: null;
|
||||||
|
|
||||||
|
export async function postAPI(url: any, data: any) {
|
||||||
|
const headers = {
|
||||||
|
Authorization: `Bearer ${tokenAuth}`,
|
||||||
|
};
|
||||||
|
const response = await axiosInstance
|
||||||
|
.post(url, qs.stringify(data), { headers })
|
||||||
|
.catch((error) => error.response);
|
||||||
|
if (response?.status > 300) {
|
||||||
|
return {
|
||||||
|
error: true,
|
||||||
|
message: response?.data.error_description,
|
||||||
|
data: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
error: false,
|
error: false,
|
||||||
message: "success",
|
message: "success",
|
||||||
data: response?.data,
|
data: response?.data,
|
||||||
};
|
};
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
error: true,
|
|
||||||
message: response?.data?.message || response?.data || null,
|
|
||||||
data: null,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function httpGet(pathUrl: any, headers: any) {
|
export async function httpGet(pathUrl: any, headers: any) {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { title } from "process";
|
||||||
import {
|
import {
|
||||||
deleteAPIInterceptor,
|
deleteAPIInterceptor,
|
||||||
getAPIInterceptor,
|
getAPIInterceptor,
|
||||||
|
|
@ -8,8 +9,15 @@ import {
|
||||||
httpPostInterceptor,
|
httpPostInterceptor,
|
||||||
} from "./http-config/http-interceptor-service";
|
} from "./http-config/http-interceptor-service";
|
||||||
|
|
||||||
export async function listTask(size: number, page: number) {
|
// export async function listTask(size: number, page: number) {
|
||||||
return await httpGetInterceptor(`assignment/list?size=${size}&page=${page}`);
|
// return await httpGetInterceptor(
|
||||||
|
// `assignment/list?enablePage=1&title=${title}&size=${limit}&page=${page}`
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
export async function listTask(page: any, limit: any) {
|
||||||
|
const url = `assignment/list?size=${limit}&page=${page}`;
|
||||||
|
return getAPIInterceptor(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createTask(data: any) {
|
export async function createTask(data: any) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue