fix:login page, table:image,audio,audio-visual,teks

This commit is contained in:
Anang Yusman 2024-12-07 01:37:45 +07:00
parent 8edaedc9d5
commit 60edcc288f
20 changed files with 1773 additions and 358 deletions

View File

@ -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,22 +304,20 @@ 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 : flexRender(
: flexRender( header.column.columnDef.header,
header.column.columnDef.header, 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>
); );
}; };

View File

@ -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,22 +308,20 @@ 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 : flexRender(
: flexRender( header.column.columnDef.header,
header.column.columnDef.header, 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>
); );
}; };

View File

@ -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);
} }
} }

View File

@ -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,22 +309,20 @@ 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 : flexRender(
: flexRender( header.column.columnDef.header,
header.column.columnDef.header, 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>
); );
}; };

View File

@ -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,22 +315,20 @@ 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 : flexRender(
: flexRender( header.column.columnDef.header,
header.column.columnDef.header, 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>
); );
}; };

View File

@ -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 />

View File

@ -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..."

View File

@ -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";

View File

@ -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({

View File

@ -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 &gt;</button> <button className="px-6 py-2 bg-[#bb3523] text-white rounded-lg hover:bg-red-700">
Cari Liputan &gt;
</button>
</div> </div>
</div> </div>
</section> </section>

View File

@ -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 { } else {
router.push("/dashboard"); const { access_token } = response.data;
toast.success("Successfully logged in"); 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 {
window.location.href = "/en/dashboard";
// 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,
})} })}
/> />
{errors.username?.message && (
<div className="text-destructive mt-2 text-sm">
{errors.username.message}
</div>
)}
</div> </div>
{errors.email && (
<div className=" text-destructive mt-2 text-sm">
{errors.email.message}
</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>
{errors.password?.message && (
<div className="text-destructive mt-2 text-sm">
{errors.password.message}
</div>
)}
</div> </div>
{errors.password && (
<div className=" text-destructive mt-2 text-sm">
{errors.password.message}
</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;

View File

@ -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

92
lib/swal.ts Normal file
View File

@ -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,
});
}

View File

@ -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");
}

View File

@ -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 });
} }

View File

@ -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}`
);
}

View File

@ -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}`
);
}

View File

@ -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) {

View File

@ -1,70 +1,100 @@
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 { // return {
error: false, // error: false,
message: "success", // message: "success",
data: response?.data, // data: response?.data,
}; // };
} else { // } else {
return { // return {
error: true, // error: true,
message: response?.data?.message || response?.data || null, // message: response?.data?.message || response?.data || null,
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 {
error: false,
message: "success",
data: response?.data,
};
} }
export async function httpGet(pathUrl: any, headers: any) { export async function httpGet(pathUrl: any, headers: any) {
const response = await axiosBaseInstance const response = await axiosBaseInstance
.get(pathUrl, { headers }) .get(pathUrl, { 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 { return {
error: false, error: false,
message: "success", message: "success",
data: response?.data, data: response?.data,
}; };
} else { } else {
return { return {
error: true, error: true,
message: response?.data?.message || response?.data || null, message: response?.data?.message || response?.data || null,
data: null, data: null,
}; };
} }
} }
export async function httpPut(pathUrl: any, headers: any, data?: any) { export async function httpPut(pathUrl: any, headers: any, data?: any) {
const response = await axiosBaseInstance const response = await axiosBaseInstance
.put(pathUrl, data, { headers }) .put(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 { return {
error: false, error: false,
message: "success", message: "success",
data: response?.data, data: response?.data,
}; };
} else { } else {
return { return {
error: true, error: true,
message: response?.data?.message || response?.data || null, message: response?.data?.message || response?.data || null,
data: null, data: null,
}; };
} }
} }

View File

@ -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) {