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 {
|
||||
ColumnDef,
|
||||
ColumnFiltersState,
|
||||
PaginationState,
|
||||
SortingState,
|
||||
VisibilityState,
|
||||
flexRender,
|
||||
|
|
@ -12,7 +14,6 @@ import {
|
|||
getSortedRowModel,
|
||||
useReactTable,
|
||||
} from "@tanstack/react-table";
|
||||
import { columns } from "./columns";
|
||||
import { Input } from "@/components/ui/input";
|
||||
|
||||
import {
|
||||
|
|
@ -26,8 +27,177 @@ import {
|
|||
|
||||
import { data } from "./data";
|
||||
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 [videoTable, setVideoTable] = React.useState<CompanyData[]>([]);
|
||||
const [sorting, setSorting] = React.useState<SortingState>([]);
|
||||
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
|
||||
[]
|
||||
|
|
@ -35,9 +205,29 @@ const TableVideo = () => {
|
|||
const [columnVisibility, setColumnVisibility] =
|
||||
React.useState<VisibilityState>({});
|
||||
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({
|
||||
data,
|
||||
data: videoTable,
|
||||
columns,
|
||||
onSortingChange: setSorting,
|
||||
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 (
|
||||
<div className="w-full">
|
||||
<div className="flex items-center py-4 px-5">
|
||||
|
|
@ -72,22 +304,20 @@ const TableVideo = () => {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<Table>
|
||||
<Table className="overflow-hidden">
|
||||
<TableHeader>
|
||||
{table.getHeaderGroups().map((headerGroup) => (
|
||||
<TableRow key={headerGroup.id}>
|
||||
{headerGroup.headers.map((header) => {
|
||||
return (
|
||||
<TableHead key={header.id}>
|
||||
{header.isPlaceholder
|
||||
? null
|
||||
: flexRender(
|
||||
header.column.columnDef.header,
|
||||
header.getContext()
|
||||
)}
|
||||
</TableHead>
|
||||
);
|
||||
})}
|
||||
<TableRow key={headerGroup.id} className="bg-default-200">
|
||||
{headerGroup.headers.map((header) => (
|
||||
<TableHead key={header.id}>
|
||||
{header.isPlaceholder
|
||||
? null
|
||||
: flexRender(
|
||||
header.column.columnDef.header,
|
||||
header.getContext()
|
||||
)}
|
||||
</TableHead>
|
||||
))}
|
||||
</TableRow>
|
||||
))}
|
||||
</TableHeader>
|
||||
|
|
@ -97,6 +327,7 @@ const TableVideo = () => {
|
|||
<TableRow
|
||||
key={row.id}
|
||||
data-state={row.getIsSelected() && "selected"}
|
||||
className="h-[75px]"
|
||||
>
|
||||
{row.getVisibleCells().map((cell) => (
|
||||
<TableCell key={cell.id}>
|
||||
|
|
@ -114,7 +345,41 @@ const TableVideo = () => {
|
|||
)}
|
||||
</TableBody>
|
||||
</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>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
import * as React from "react";
|
||||
import {
|
||||
ColumnDef,
|
||||
ColumnFiltersState,
|
||||
PaginationState,
|
||||
SortingState,
|
||||
VisibilityState,
|
||||
flexRender,
|
||||
|
|
@ -12,7 +14,6 @@ import {
|
|||
getSortedRowModel,
|
||||
useReactTable,
|
||||
} from "@tanstack/react-table";
|
||||
import { columns } from "./columns";
|
||||
import { Input } from "@/components/ui/input";
|
||||
|
||||
import {
|
||||
|
|
@ -26,8 +27,181 @@ import {
|
|||
|
||||
import { data } from "./data";
|
||||
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 [videoTable, setVideoTable] = React.useState<CompanyData[]>([]);
|
||||
const [sorting, setSorting] = React.useState<SortingState>([]);
|
||||
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
|
||||
[]
|
||||
|
|
@ -35,9 +209,29 @@ const TableAudio = () => {
|
|||
const [columnVisibility, setColumnVisibility] =
|
||||
React.useState<VisibilityState>({});
|
||||
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({
|
||||
data,
|
||||
data: videoTable,
|
||||
columns,
|
||||
onSortingChange: setSorting,
|
||||
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 (
|
||||
<div className="w-full">
|
||||
<div className="flex items-center py-4 px-5">
|
||||
|
|
@ -72,22 +308,20 @@ const TableAudio = () => {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<Table>
|
||||
<Table className="overflow-hidden">
|
||||
<TableHeader>
|
||||
{table.getHeaderGroups().map((headerGroup) => (
|
||||
<TableRow key={headerGroup.id}>
|
||||
{headerGroup.headers.map((header) => {
|
||||
return (
|
||||
<TableHead key={header.id}>
|
||||
{header.isPlaceholder
|
||||
? null
|
||||
: flexRender(
|
||||
header.column.columnDef.header,
|
||||
header.getContext()
|
||||
)}
|
||||
</TableHead>
|
||||
);
|
||||
})}
|
||||
<TableRow key={headerGroup.id} className="bg-default-200">
|
||||
{headerGroup.headers.map((header) => (
|
||||
<TableHead key={header.id}>
|
||||
{header.isPlaceholder
|
||||
? null
|
||||
: flexRender(
|
||||
header.column.columnDef.header,
|
||||
header.getContext()
|
||||
)}
|
||||
</TableHead>
|
||||
))}
|
||||
</TableRow>
|
||||
))}
|
||||
</TableHeader>
|
||||
|
|
@ -97,6 +331,7 @@ const TableAudio = () => {
|
|||
<TableRow
|
||||
key={row.id}
|
||||
data-state={row.getIsSelected() && "selected"}
|
||||
className="h-[75px]"
|
||||
>
|
||||
{row.getVisibleCells().map((cell) => (
|
||||
<TableCell key={cell.id}>
|
||||
|
|
@ -114,7 +349,41 @@ const TableAudio = () => {
|
|||
)}
|
||||
</TableBody>
|
||||
</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>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -45,7 +45,8 @@ import {
|
|||
import { title } from "process";
|
||||
|
||||
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 = {
|
||||
no: number;
|
||||
|
|
@ -197,7 +198,6 @@ export const columns: ColumnDef<CompanyData>[] = [
|
|||
];
|
||||
|
||||
const TableImage = () => {
|
||||
const [imageTable, setImageTable] = React.useState<CompanyData[]>([]);
|
||||
const [sorting, setSorting] = React.useState<SortingState>([]);
|
||||
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
|
||||
[]
|
||||
|
|
@ -205,14 +205,14 @@ const TableImage = () => {
|
|||
const [columnVisibility, setColumnVisibility] =
|
||||
React.useState<VisibilityState>({});
|
||||
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 [page, setPage] = React.useState(1); // Halaman aktif
|
||||
const [totalPage, setTotalPage] = React.useState(1); // Total halaman
|
||||
const [limit, setLimit] = React.useState(10); // Jumlah baris per halaman
|
||||
const [search, setSearch] = React.useState(title);
|
||||
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");
|
||||
|
||||
|
|
@ -247,14 +247,14 @@ const TableImage = () => {
|
|||
|
||||
React.useEffect(() => {
|
||||
initState();
|
||||
}, [page, limit]);
|
||||
}, [limit]);
|
||||
|
||||
async function initState() {
|
||||
try {
|
||||
const isForSelf = Number(roleId) == 4;
|
||||
const isForSelf = Number(roleId) === 4;
|
||||
const res = await listDataImage(
|
||||
limit,
|
||||
page,
|
||||
pagination.pageSize, // Ambil nilai dari pagination.pageSize
|
||||
pagination.pageIndex + 1, // API sering menggunakan page 1-based
|
||||
isForSelf,
|
||||
!isForSelf,
|
||||
categoryFilter?.sort().join(","),
|
||||
|
|
@ -267,12 +267,24 @@ const TableImage = () => {
|
|||
startDateString,
|
||||
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,
|
||||
categoryName: item.categoryName,
|
||||
creatorGroup: item.creatorGroup,
|
||||
assignmentType: item.assignmentType?.name || "-",
|
||||
createdAt: item.createdAt,
|
||||
isDone: item.isDone,
|
||||
publishedOn: item.publishedOn,
|
||||
|
|
@ -281,9 +293,8 @@ const TableImage = () => {
|
|||
}));
|
||||
|
||||
setImageTable(data);
|
||||
setTotalPage(res.data.totalPages);
|
||||
} catch (error) {
|
||||
console.error("Error fetching tasks:", error);
|
||||
setTotalPage(rawData.totalPages);
|
||||
console.log(data, "dataImage");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
import * as React from "react";
|
||||
import {
|
||||
ColumnDef,
|
||||
ColumnFiltersState,
|
||||
PaginationState,
|
||||
SortingState,
|
||||
VisibilityState,
|
||||
flexRender,
|
||||
|
|
@ -12,7 +14,6 @@ import {
|
|||
getSortedRowModel,
|
||||
useReactTable,
|
||||
} from "@tanstack/react-table";
|
||||
import { columns } from "./columns";
|
||||
import { Input } from "@/components/ui/input";
|
||||
|
||||
import {
|
||||
|
|
@ -26,8 +27,183 @@ import {
|
|||
|
||||
import { data } from "./data";
|
||||
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 [spitTable, setSpitTable] = React.useState<CompanyData[]>([]);
|
||||
const [sorting, setSorting] = React.useState<SortingState>([]);
|
||||
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
|
||||
[]
|
||||
|
|
@ -35,9 +211,29 @@ const TableSPIT = () => {
|
|||
const [columnVisibility, setColumnVisibility] =
|
||||
React.useState<VisibilityState>({});
|
||||
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({
|
||||
data,
|
||||
data: spitTable,
|
||||
columns,
|
||||
onSortingChange: setSorting,
|
||||
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 (
|
||||
<div className="w-full">
|
||||
<div className="flex items-center py-4 px-5">
|
||||
|
|
@ -72,22 +309,20 @@ const TableSPIT = () => {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<Table>
|
||||
<Table className="overflow-hidden">
|
||||
<TableHeader>
|
||||
{table.getHeaderGroups().map((headerGroup) => (
|
||||
<TableRow key={headerGroup.id}>
|
||||
{headerGroup.headers.map((header) => {
|
||||
return (
|
||||
<TableHead key={header.id}>
|
||||
{header.isPlaceholder
|
||||
? null
|
||||
: flexRender(
|
||||
header.column.columnDef.header,
|
||||
header.getContext()
|
||||
)}
|
||||
</TableHead>
|
||||
);
|
||||
})}
|
||||
<TableRow key={headerGroup.id} className="bg-default-200">
|
||||
{headerGroup.headers.map((header) => (
|
||||
<TableHead key={header.id}>
|
||||
{header.isPlaceholder
|
||||
? null
|
||||
: flexRender(
|
||||
header.column.columnDef.header,
|
||||
header.getContext()
|
||||
)}
|
||||
</TableHead>
|
||||
))}
|
||||
</TableRow>
|
||||
))}
|
||||
</TableHeader>
|
||||
|
|
@ -97,6 +332,7 @@ const TableSPIT = () => {
|
|||
<TableRow
|
||||
key={row.id}
|
||||
data-state={row.getIsSelected() && "selected"}
|
||||
className="h-[75px]"
|
||||
>
|
||||
{row.getVisibleCells().map((cell) => (
|
||||
<TableCell key={cell.id}>
|
||||
|
|
@ -114,7 +350,41 @@ const TableSPIT = () => {
|
|||
)}
|
||||
</TableBody>
|
||||
</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>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
import * as React from "react";
|
||||
import {
|
||||
ColumnDef,
|
||||
ColumnFiltersState,
|
||||
PaginationState,
|
||||
SortingState,
|
||||
VisibilityState,
|
||||
flexRender,
|
||||
|
|
@ -12,7 +14,6 @@ import {
|
|||
getSortedRowModel,
|
||||
useReactTable,
|
||||
} from "@tanstack/react-table";
|
||||
import { columns } from "./columns";
|
||||
import { Input } from "@/components/ui/input";
|
||||
|
||||
import {
|
||||
|
|
@ -26,6 +27,175 @@ import {
|
|||
|
||||
import { data } from "./data";
|
||||
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 [sorting, setSorting] = React.useState<SortingState>([]);
|
||||
|
|
@ -35,9 +205,29 @@ const TableTeks = () => {
|
|||
const [columnVisibility, setColumnVisibility] =
|
||||
React.useState<VisibilityState>({});
|
||||
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({
|
||||
data,
|
||||
data: imageTable,
|
||||
columns,
|
||||
onSortingChange: setSorting,
|
||||
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 (
|
||||
<div className="w-full">
|
||||
<div className="flex items-center py-4 px-5">
|
||||
|
|
@ -72,22 +315,20 @@ const TableTeks = () => {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<Table>
|
||||
<Table className="overflow-hidden">
|
||||
<TableHeader>
|
||||
{table.getHeaderGroups().map((headerGroup) => (
|
||||
<TableRow key={headerGroup.id}>
|
||||
{headerGroup.headers.map((header) => {
|
||||
return (
|
||||
<TableHead key={header.id}>
|
||||
{header.isPlaceholder
|
||||
? null
|
||||
: flexRender(
|
||||
header.column.columnDef.header,
|
||||
header.getContext()
|
||||
)}
|
||||
</TableHead>
|
||||
);
|
||||
})}
|
||||
<TableRow key={headerGroup.id} className="bg-default-200">
|
||||
{headerGroup.headers.map((header) => (
|
||||
<TableHead key={header.id}>
|
||||
{header.isPlaceholder
|
||||
? null
|
||||
: flexRender(
|
||||
header.column.columnDef.header,
|
||||
header.getContext()
|
||||
)}
|
||||
</TableHead>
|
||||
))}
|
||||
</TableRow>
|
||||
))}
|
||||
</TableHeader>
|
||||
|
|
@ -97,6 +338,7 @@ const TableTeks = () => {
|
|||
<TableRow
|
||||
key={row.id}
|
||||
data-state={row.getIsSelected() && "selected"}
|
||||
className="h-[75px]"
|
||||
>
|
||||
{row.getVisibleCells().map((cell) => (
|
||||
<TableCell key={cell.id}>
|
||||
|
|
@ -114,7 +356,41 @@ const TableTeks = () => {
|
|||
)}
|
||||
</TableBody>
|
||||
</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>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,11 +1,23 @@
|
|||
"use client";
|
||||
import { Card, CardContent } from "@/components/ui/card";
|
||||
import TaskTable from "./table-task/task-table";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { UploadIcon } from "lucide-react";
|
||||
import SiteBreadcrumb from "@/components/site-breadcrumb";
|
||||
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 (
|
||||
<div>
|
||||
<SiteBreadcrumb />
|
||||
|
|
|
|||
|
|
@ -51,6 +51,13 @@ import { title } from "process";
|
|||
import search from "../../app/chat/components/search";
|
||||
import { format } from "date-fns";
|
||||
import { listTask } from "@/service/task";
|
||||
import { getCookiesDecrypt } from "@/lib/utils";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectGroup,
|
||||
SelectItem,
|
||||
} from "@/components/ui/select";
|
||||
|
||||
export type CompanyData = {
|
||||
no: number;
|
||||
|
|
@ -202,9 +209,13 @@ const TaskTable = () => {
|
|||
});
|
||||
const [page, setPage] = 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 userId = getCookiesDecrypt("uie");
|
||||
const userLevelNumber = getCookiesDecrypt("ulne");
|
||||
const userRoleId = getCookiesDecrypt("urie");
|
||||
|
||||
const table = useReactTable({
|
||||
data: taskTable,
|
||||
columns,
|
||||
|
|
@ -261,6 +272,18 @@ const TaskTable = () => {
|
|||
/>
|
||||
</InputGroup>
|
||||
</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">
|
||||
<Input
|
||||
placeholder="Filter Status..."
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
"use client";
|
||||
|
||||
import SearchSection from "@/components/landing-page/SearchSection";
|
||||
import NewContent from "@/components/landing-page/new-content";
|
||||
import PopularContent from "@/components/landing-page/popular-content";
|
||||
|
|
|
|||
|
|
@ -20,10 +20,6 @@ import {
|
|||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
||||
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";
|
||||
|
||||
const taskSchema = z.object({
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
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";
|
||||
|
||||
const SearchSection = () => {
|
||||
|
|
@ -8,10 +13,15 @@ const SearchSection = () => {
|
|||
<div className="max-w-screen-lg mx-auto text-center">
|
||||
{/* Heading */}
|
||||
<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>
|
||||
<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 */}
|
||||
<div className="mt-6 flex flex-col md:flex-row justify-center gap-4">
|
||||
|
|
@ -20,19 +30,39 @@ const SearchSection = () => {
|
|||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<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
|
||||
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"
|
||||
/>
|
||||
</svg>
|
||||
Konten
|
||||
<svg 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
|
||||
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>
|
||||
</a>
|
||||
</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">
|
||||
<span className="text-default-700c flex flex-row justify-center items-center group-hover:text-primary-foreground">
|
||||
<FiYoutube className="mr-2" />
|
||||
|
|
@ -64,18 +94,29 @@ const SearchSection = () => {
|
|||
{/* Search Input */}
|
||||
<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">
|
||||
<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
|
||||
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"
|
||||
/>
|
||||
</svg>
|
||||
</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>
|
||||
|
||||
{/* 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>
|
||||
</section>
|
||||
|
|
|
|||
|
|
@ -4,65 +4,184 @@ import { Button } from "@/components/ui/button";
|
|||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Link } from "@/i18n/routing";
|
||||
import Cookies from "js-cookie";
|
||||
import { Icon } from "@/components/ui/icon";
|
||||
import { useForm, SubmitHandler } from "react-hook-form";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { z } from "zod";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { cn, setCookiesEncrypt } from "@/lib/utils";
|
||||
import { Loader2 } from "lucide-react";
|
||||
import { loginUser } from "@/action/auth-action";
|
||||
import { getProfile, setLogin } from "@/service/auth";
|
||||
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({
|
||||
email: z.string().email({ message: "Your email is invalid." }),
|
||||
password: z.string().min(4),
|
||||
username: z.string().min(1, { message: "Judul diperlukan" }),
|
||||
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 [isPending, startTransition] = React.useTransition();
|
||||
const router = useRouter();
|
||||
const [passwordType, setPasswordType] = React.useState("password");
|
||||
|
||||
const togglePasswordType = () => {
|
||||
if (passwordType === "text") {
|
||||
setPasswordType("password");
|
||||
} else if (passwordType === "password") {
|
||||
setPasswordType("text");
|
||||
}
|
||||
setPasswordType((prevType) =>
|
||||
prevType === "password" ? "text" : "password"
|
||||
);
|
||||
};
|
||||
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
reset,
|
||||
formState: { errors },
|
||||
} = useForm({
|
||||
} = useForm<LoginFormValues>({
|
||||
resolver: zodResolver(schema),
|
||||
mode: "all",
|
||||
defaultValues: {
|
||||
email: "dashcode@codeshaper.net",
|
||||
password: "password",
|
||||
},
|
||||
});
|
||||
const [isVisible, setIsVisible] = React.useState(false);
|
||||
|
||||
const toggleVisibility = () => setIsVisible(!isVisible);
|
||||
|
||||
const onSubmit = (data: z.infer<typeof schema>) => {
|
||||
// Fungsi submit form
|
||||
const onSubmit: SubmitHandler<LoginFormValues> = async (data) => {
|
||||
startTransition(async () => {
|
||||
try {
|
||||
const response = await loginUser(data);
|
||||
const response = await setLogin({
|
||||
...data,
|
||||
grant_type: "password",
|
||||
client_id: "mediahub-app",
|
||||
});
|
||||
|
||||
if (!!response.error) {
|
||||
toast("Event has been created", {
|
||||
description: "Sunday, December 03, 2023 at 9:00 AM",
|
||||
});
|
||||
if (response.error) {
|
||||
toast.error("Username / Password Tidak Sesuai");
|
||||
} else {
|
||||
router.push("/dashboard");
|
||||
toast.success("Successfully logged in");
|
||||
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 {
|
||||
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) {
|
||||
toast.error(err.message);
|
||||
toast.error(err.message || "An unexpected error occurred.");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
@ -70,41 +189,39 @@ const LoginForm = () => {
|
|||
return (
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="mt-5 2xl:mt-7 space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="email" className=" font-medium text-default-600">
|
||||
Email{" "}
|
||||
<Label htmlFor="username" className="font-medium text-default-600">
|
||||
Username
|
||||
</Label>
|
||||
<Input
|
||||
size="lg"
|
||||
disabled={isPending}
|
||||
{...register("email")}
|
||||
type="email"
|
||||
id="email"
|
||||
{...register("username")}
|
||||
id="username"
|
||||
type="username"
|
||||
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>
|
||||
{errors.email && (
|
||||
<div className=" text-destructive mt-2 text-sm">
|
||||
{errors.email.message}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="mt-3.5 space-y-2">
|
||||
<Label htmlFor="password" className="mb-2 font-medium text-default-600">
|
||||
Password{" "}
|
||||
Password
|
||||
</Label>
|
||||
<div className="relative">
|
||||
<Input
|
||||
size="lg"
|
||||
disabled={isPending}
|
||||
{...register("password")}
|
||||
type={passwordType}
|
||||
id="password"
|
||||
className="peer "
|
||||
placeholder=" "
|
||||
type={passwordType}
|
||||
className="peer"
|
||||
/>
|
||||
|
||||
<div
|
||||
className="absolute top-1/2 -translate-y-1/2 ltr:right-4 rtl:left-4 cursor-pointer"
|
||||
onClick={togglePasswordType}
|
||||
|
|
@ -119,12 +236,12 @@ const LoginForm = () => {
|
|||
)}
|
||||
</div>
|
||||
</div>
|
||||
{errors.password?.message && (
|
||||
<div className="text-destructive mt-2 text-sm">
|
||||
{errors.password.message}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{errors.password && (
|
||||
<div className=" text-destructive mt-2 text-sm">
|
||||
{errors.password.message}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex justify-between">
|
||||
<div className="flex gap-2 items-center">
|
||||
|
|
@ -145,4 +262,5 @@ const LoginForm = () => {
|
|||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
export default LoginForm;
|
||||
|
|
|
|||
|
|
@ -123,7 +123,6 @@ export async function getAPIInterceptor(url: any) {
|
|||
data: null,
|
||||
};
|
||||
}
|
||||
|
||||
// Fungsi postAPIInterceptor
|
||||
export async function postAPIInterceptor(url: string, data: any) {
|
||||
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) {
|
||||
const roleId = getCookiesDecrypt("urie");
|
||||
const levelNumber = getCookiesDecrypt("ulne");
|
||||
|
|
@ -64,44 +105,3 @@ export function checkLoginSession() {
|
|||
};
|
||||
// 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 { getAPIDummy } from "./http-config/axiosCustom";
|
||||
|
||||
export async function setLogin(data) {
|
||||
const url = "signin";
|
||||
return postAPI({ url, data });
|
||||
import {
|
||||
httpGetInterceptorWithToken,
|
||||
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";
|
||||
return getAPI({ url, token });
|
||||
return getAPI(url, token);
|
||||
}
|
||||
|
||||
export async function saveSession(data) {
|
||||
const url = "users/save-session";
|
||||
return postAPIWithJson({ url, data });
|
||||
}
|
||||
// export async function setLogin(data: any) {
|
||||
// const pathUrl = `signin`;
|
||||
// const headers = {
|
||||
// "content-type": "application/json",
|
||||
// };
|
||||
// return await httpPost(pathUrl, headers, data);
|
||||
// }
|
||||
|
||||
export async function checkSession(data) {
|
||||
const url = "users/check-session";
|
||||
return postAPIWithJson({ url, data });
|
||||
}
|
||||
|
||||
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 });
|
||||
export async function userInfo(token: any) {
|
||||
const pathUrl = `users/info`;
|
||||
return await httpGetInterceptorWithToken(pathUrl, token);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
const data = {
|
||||
refreshToken: refreshToken,
|
||||
grant_type: "refresh_token",
|
||||
client_id: "mediahub-app",
|
||||
};
|
||||
const res = await login(data);
|
||||
if (res.data?.data?.access_token) {
|
||||
|
|
|
|||
|
|
@ -1,70 +1,100 @@
|
|||
import axiosInstance from "@/config/axiosInstance";
|
||||
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) {
|
||||
const response = await axiosBaseInstance
|
||||
.post(pathUrl, data, { headers })
|
||||
.catch(function (error: any) {
|
||||
console.log(error);
|
||||
return error.response;
|
||||
});
|
||||
console.log("Response base svc : ", response);
|
||||
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,
|
||||
};
|
||||
}
|
||||
// export async function httpPost(pathUrl: any, headers: any, data?: any) {
|
||||
// const response = await axiosBaseInstance
|
||||
// .post(pathUrl, data, { headers })
|
||||
// .catch(function (error: any) {
|
||||
// console.log(error);
|
||||
// return error.response;
|
||||
// });
|
||||
// console.log("Response base svc : ", response);
|
||||
// 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 {
|
||||
error: false,
|
||||
message: "success",
|
||||
data: response?.data,
|
||||
};
|
||||
}
|
||||
|
||||
export async function httpGet(pathUrl: any, headers: any) {
|
||||
const response = await axiosBaseInstance
|
||||
.get(pathUrl, { headers })
|
||||
.catch(function (error: any) {
|
||||
console.log(error);
|
||||
return error.response;
|
||||
});
|
||||
console.log("Response base svc : ", response);
|
||||
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 response = await axiosBaseInstance
|
||||
.get(pathUrl, { headers })
|
||||
.catch(function (error: any) {
|
||||
console.log(error);
|
||||
return error.response;
|
||||
});
|
||||
console.log("Response base svc : ", response);
|
||||
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,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export async function httpPut(pathUrl: any, headers: any, data?: any) {
|
||||
const response = await axiosBaseInstance
|
||||
.put(pathUrl, data, { headers })
|
||||
.catch(function (error: any) {
|
||||
console.log(error);
|
||||
return error.response;
|
||||
});
|
||||
console.log("Response base svc : ", response);
|
||||
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 response = await axiosBaseInstance
|
||||
.put(pathUrl, data, { headers })
|
||||
.catch(function (error: any) {
|
||||
console.log(error);
|
||||
return error.response;
|
||||
});
|
||||
console.log("Response base svc : ", response);
|
||||
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,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { title } from "process";
|
||||
import {
|
||||
deleteAPIInterceptor,
|
||||
getAPIInterceptor,
|
||||
|
|
@ -8,8 +9,15 @@ import {
|
|||
httpPostInterceptor,
|
||||
} from "./http-config/http-interceptor-service";
|
||||
|
||||
export async function listTask(size: number, page: number) {
|
||||
return await httpGetInterceptor(`assignment/list?size=${size}&page=${page}`);
|
||||
// export async function listTask(size: number, page: number) {
|
||||
// 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) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue