Merge branch 'dev-anang' of https://gitlab.com/hanifsalafi/mediahub_redesign
This commit is contained in:
commit
d912f8576b
|
|
@ -46,17 +46,33 @@ import {
|
|||
} from "@/components/ui/dropdown-menu";
|
||||
|
||||
export type CompanyData = {
|
||||
no: number;
|
||||
title: string;
|
||||
category: string;
|
||||
date: string;
|
||||
tag: string;
|
||||
status: string;
|
||||
createdAt: string;
|
||||
tags: string;
|
||||
statusName: string;
|
||||
};
|
||||
import { data } from "./data";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { InputGroup, InputGroupText } from "@/components/ui/input-group";
|
||||
import { listTask } from "@/service/ppid-categories-services";
|
||||
import { paginationBlog } from "@/service/blog/blog";
|
||||
|
||||
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",
|
||||
|
|
@ -71,33 +87,33 @@ export const columns: ColumnDef<CompanyData>[] = [
|
|||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "category",
|
||||
accessorKey: "categoryName",
|
||||
header: "Kategori ",
|
||||
cell: ({ row }) => (
|
||||
<span className="whitespace-nowrap">{row.getValue("category")}</span>
|
||||
<span className="whitespace-nowrap">{row.getValue("categoryName")}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "date",
|
||||
accessorKey: "createdAt",
|
||||
header: "Tanggal Unggah ",
|
||||
cell: ({ row }) => (
|
||||
<span className="whitespace-nowrap">{row.getValue("date")}</span>
|
||||
<span className="whitespace-nowrap">{row.getValue("createdAt")}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "tag",
|
||||
accessorKey: "tags",
|
||||
header: "Tag ",
|
||||
cell: ({ row }) => (
|
||||
<span className="whitespace-nowrap">{row.getValue("tag")}</span>
|
||||
<span className="whitespace-nowrap">{row.getValue("tags")}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "status",
|
||||
accessorKey: "statusName",
|
||||
header: "Status",
|
||||
cell: ({ row }) => {
|
||||
return (
|
||||
<span className="whitespace-nowrap text-blue-600">
|
||||
{row.getValue("status")}
|
||||
{row.getValue("statusName")}
|
||||
</span>
|
||||
);
|
||||
},
|
||||
|
|
@ -140,6 +156,7 @@ export const columns: ColumnDef<CompanyData>[] = [
|
|||
];
|
||||
|
||||
const BlogTable = () => {
|
||||
const [blogTable, setBlogTable] = React.useState<CompanyData[]>([]);
|
||||
const [sorting, setSorting] = React.useState<SortingState>([]);
|
||||
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
|
||||
[]
|
||||
|
|
@ -149,11 +166,14 @@ const BlogTable = () => {
|
|||
const [rowSelection, setRowSelection] = React.useState({});
|
||||
const [pagination, setPagination] = React.useState<PaginationState>({
|
||||
pageIndex: 0,
|
||||
pageSize: 6,
|
||||
pageSize: 10,
|
||||
});
|
||||
const [page, setPage] = React.useState(1);
|
||||
const [totalPage, setTotalPage] = React.useState(1);
|
||||
const [limit, setLimit] = React.useState(10);
|
||||
|
||||
const table = useReactTable({
|
||||
data,
|
||||
data: blogTable,
|
||||
columns,
|
||||
onSortingChange: setSorting,
|
||||
onColumnFiltersChange: setColumnFilters,
|
||||
|
|
@ -173,6 +193,30 @@ const BlogTable = () => {
|
|||
},
|
||||
});
|
||||
|
||||
React.useEffect(() => {
|
||||
initState();
|
||||
}, [page, limit]);
|
||||
|
||||
async function initState() {
|
||||
try {
|
||||
const res = await paginationBlog(limit, page);
|
||||
const data = res.data.data.content.map((item: any, index: number) => ({
|
||||
no: (page - 1) * limit + index + 1,
|
||||
title: item.title,
|
||||
categoryName: item.categoryName,
|
||||
tags: item.tags,
|
||||
assignmentType: item.assignmentType?.name || "-",
|
||||
createdAt: item.createdAt,
|
||||
statusName: item.statusName,
|
||||
}));
|
||||
|
||||
setBlogTable(data);
|
||||
setTotalPage(res.data.totalPages);
|
||||
} catch (error) {
|
||||
console.error("Error fetching tasks:", error);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="w-full overflow-x-auto">
|
||||
<div className="flex justify-between items-center py-4 px-5">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
import SiteBreadcrumb from "@/components/site-breadcrumb";
|
||||
import FormInternal from "@/components/form/communication/internal-form";
|
||||
import FormCollaboration from "@/components/form/communication/collaboration-form";
|
||||
|
||||
const CollaborationCreatePage = async () => {
|
||||
return (
|
||||
<div>
|
||||
<SiteBreadcrumb />
|
||||
<div className="space-y-4">
|
||||
<FormCollaboration />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CollaborationCreatePage;
|
||||
|
|
@ -56,6 +56,7 @@ export type CompanyData = {
|
|||
import { data } from "./data";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { InputGroup, InputGroupText } from "@/components/ui/input-group";
|
||||
import { Link } from "@/components/navigation";
|
||||
|
||||
export const columns: ColumnDef<CompanyData>[] = [
|
||||
{
|
||||
|
|
@ -181,10 +182,12 @@ const CollaborationTable = () => {
|
|||
<div className="flex justify-between items-center py-4 px-5">
|
||||
<div className="flex flex-row items-center gap-3">
|
||||
<div>
|
||||
<Button color="primary" className="text-white">
|
||||
<UploadIcon />
|
||||
Kolaborasi Baru
|
||||
</Button>
|
||||
<Link href={"/communication/collaboration/create"}>
|
||||
<Button color="primary" className="text-white">
|
||||
<UploadIcon />
|
||||
Kolaborasi Baru
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
<div>
|
||||
<InputGroup merged>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
import SiteBreadcrumb from "@/components/site-breadcrumb";
|
||||
import FormInternal from "@/components/form/communication/internal-form";
|
||||
|
||||
const InternalCreatePage = async () => {
|
||||
return (
|
||||
<div>
|
||||
<SiteBreadcrumb />
|
||||
<div className="space-y-4">
|
||||
<FormInternal />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default InternalCreatePage;
|
||||
|
|
@ -47,16 +47,31 @@ import {
|
|||
} from "@/components/ui/dropdown-menu";
|
||||
|
||||
export type CompanyData = {
|
||||
no: number;
|
||||
title: string;
|
||||
createBy: string;
|
||||
sendTo: string;
|
||||
date: string;
|
||||
commentFromUserName: string;
|
||||
commentToUserName: string;
|
||||
createdAt: string;
|
||||
};
|
||||
import { data } from "./data";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { InputGroup, InputGroupText } from "@/components/ui/input-group";
|
||||
import { listTicketingInternal } from "@/service/communication/communication";
|
||||
import { Link } from "@/components/navigation";
|
||||
|
||||
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: "Pertanyaan",
|
||||
|
|
@ -71,24 +86,28 @@ export const columns: ColumnDef<CompanyData>[] = [
|
|||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "createBy",
|
||||
accessorKey: "commentFromUserName",
|
||||
header: "Pengirim ",
|
||||
cell: ({ row }) => (
|
||||
<span className="whitespace-nowrap">{row.getValue("createBy")}</span>
|
||||
<span className="whitespace-nowrap">
|
||||
{row.getValue("commentFromUserName")}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "sendTo",
|
||||
accessorKey: "commentToUserName",
|
||||
header: "Penerima",
|
||||
cell: ({ row }) => (
|
||||
<span className="whitespace-nowrap">{row.getValue("sendTo")}</span>
|
||||
<span className="whitespace-nowrap">
|
||||
{row.getValue("commentToUserName")}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "date",
|
||||
accessorKey: "createdAt",
|
||||
header: "Waktu ",
|
||||
cell: ({ row }) => (
|
||||
<span className="whitespace-nowrap">{row.getValue("date")}</span>
|
||||
<span className="whitespace-nowrap">{row.getValue("createdAt")}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
|
|
@ -129,6 +148,7 @@ export const columns: ColumnDef<CompanyData>[] = [
|
|||
];
|
||||
|
||||
const InternalTable = () => {
|
||||
const [internalTable, setInternalTable] = React.useState<CompanyData[]>([]);
|
||||
const [sorting, setSorting] = React.useState<SortingState>([]);
|
||||
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
|
||||
[]
|
||||
|
|
@ -140,9 +160,12 @@ const InternalTable = () => {
|
|||
pageIndex: 0,
|
||||
pageSize: 6,
|
||||
});
|
||||
const [page, setPage] = React.useState(1);
|
||||
const [totalPage, setTotalPage] = React.useState(1);
|
||||
const [limit, setLimit] = React.useState(10);
|
||||
|
||||
const table = useReactTable({
|
||||
data,
|
||||
data: internalTable,
|
||||
columns,
|
||||
onSortingChange: setSorting,
|
||||
onColumnFiltersChange: setColumnFilters,
|
||||
|
|
@ -162,15 +185,41 @@ const InternalTable = () => {
|
|||
},
|
||||
});
|
||||
|
||||
React.useEffect(() => {
|
||||
initState();
|
||||
}, [page, limit]);
|
||||
|
||||
async function initState() {
|
||||
try {
|
||||
const res = await listTicketingInternal(page);
|
||||
|
||||
const data = res.data.content.map((item: any, index: number) => ({
|
||||
no: (page - 1) * limit + index + 1,
|
||||
title: item.title,
|
||||
commentFromUserName: item.commentFromUserName,
|
||||
commentToUserName: item.commentToUserName,
|
||||
createdAt: item.createdAt,
|
||||
}));
|
||||
|
||||
setInternalTable(data);
|
||||
setTotalPage(res.data.totalPages);
|
||||
console.log(res?.data?.data);
|
||||
} catch (error) {
|
||||
console.error("Error fetching tasks:", error);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="w-full overflow-x-auto">
|
||||
<div className="flex justify-between items-center py-4 px-5">
|
||||
<div className="flex flex-row items-center gap-3">
|
||||
<div>
|
||||
<Button color="primary" className="text-white">
|
||||
<UploadIcon />
|
||||
Pertanyaan Baru
|
||||
</Button>
|
||||
<Link href={"/communication/internal/create"}>
|
||||
<Button color="primary" className="text-white">
|
||||
<UploadIcon />
|
||||
Pertanyaan Baru
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
<div>
|
||||
<InputGroup merged>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
import { Card, CardContent } from "@/components/ui/card";
|
||||
import SiteBreadcrumb from "@/components/site-breadcrumb";
|
||||
import FormTask from "@/components/form/task/task-form";
|
||||
import FormImage from "@/components/form/content/create-form";
|
||||
|
||||
const ImageCreatePage = async () => {
|
||||
return (
|
||||
<div>
|
||||
<SiteBreadcrumb />
|
||||
<div className="space-y-4">
|
||||
<FormImage />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ImageCreatePage;
|
||||
|
|
@ -5,6 +5,7 @@ import TableImage from "./table-image";
|
|||
import { Newspaper, NewspaperIcon, UploadIcon } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Icon } from "@iconify/react/dist/iconify.js";
|
||||
import { Link } from "@/components/navigation";
|
||||
|
||||
const ReactTableImagePage = () => {
|
||||
return (
|
||||
|
|
@ -54,10 +55,12 @@ const ReactTableImagePage = () => {
|
|||
Konten Foto
|
||||
</div>
|
||||
<div>
|
||||
<Button color="primary" className="text-white">
|
||||
<UploadIcon />
|
||||
Unggah Foto
|
||||
</Button>
|
||||
<Link href={"/content/image/create"}>
|
||||
<Button color="primary" className="text-white">
|
||||
<UploadIcon />
|
||||
Unggah Foto
|
||||
</Button>
|
||||
</Link>
|
||||
<Button color="primary" className="text-white ml-3">
|
||||
<UploadIcon />
|
||||
Unggah Foto Dengan AI
|
||||
|
|
|
|||
|
|
@ -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 } 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 TableImage = () => {
|
||||
const [sorting, setSorting] = React.useState<SortingState>([]);
|
||||
|
|
@ -35,9 +205,29 @@ 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 [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 TableImage = () => {
|
|||
},
|
||||
});
|
||||
|
||||
React.useEffect(() => {
|
||||
initState();
|
||||
}, [limit]);
|
||||
|
||||
async function initState() {
|
||||
try {
|
||||
const isForSelf = Number(roleId) === 4;
|
||||
const res = await listDataImage(
|
||||
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 TableImage = () => {
|
|||
</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 TableImage = () => {
|
|||
<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 TableImage = () => {
|
|||
)}
|
||||
</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,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>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -46,20 +46,36 @@ import {
|
|||
} from "@/components/ui/dropdown-menu";
|
||||
|
||||
export type CompanyData = {
|
||||
code: string;
|
||||
title: string;
|
||||
no: number;
|
||||
hastagCode: string;
|
||||
theme: string;
|
||||
duration: string;
|
||||
targetOutput: string;
|
||||
targetParticipant: string;
|
||||
status: string;
|
||||
targetParticipantTopLevel: string;
|
||||
isPublishForAll: string;
|
||||
};
|
||||
import { data } from "./data";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { InputGroup, InputGroupText } from "@/components/ui/input-group";
|
||||
import { listTask } from "@/service/task";
|
||||
import { listContest } from "@/service/contest/contest";
|
||||
|
||||
export const columns: ColumnDef<CompanyData>[] = [
|
||||
{
|
||||
accessorKey: "code",
|
||||
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: "hastagCode",
|
||||
header: "Kode",
|
||||
cell: ({ row }) => (
|
||||
<div className="flex items-center gap-5">
|
||||
|
|
@ -68,20 +84,20 @@ export const columns: ColumnDef<CompanyData>[] = [
|
|||
className="text-sm font-bold
|
||||
text-default-600 whitespace-nowrap mb-1"
|
||||
>
|
||||
{row.getValue("code")}
|
||||
{row.getValue("hastagCode")}
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "title",
|
||||
accessorKey: "theme",
|
||||
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")}
|
||||
{row.getValue("theme")}
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -96,27 +112,27 @@ export const columns: ColumnDef<CompanyData>[] = [
|
|||
},
|
||||
{
|
||||
accessorKey: "targetOutput",
|
||||
header: "Tanggal Unggah ",
|
||||
header: "Target Output ",
|
||||
cell: ({ row }) => (
|
||||
<span className="whitespace-nowrap">{row.getValue("targetOutput")}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "targetParticipant",
|
||||
accessorKey: "targetParticipantTopLevel",
|
||||
header: "Tag ",
|
||||
cell: ({ row }) => (
|
||||
<span className="whitespace-nowrap">
|
||||
{row.getValue("targetParticipant")}
|
||||
{row.getValue("targetParticipantTopLevel")}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "status",
|
||||
accessorKey: "isPublishForAll",
|
||||
header: "Status",
|
||||
cell: ({ row }) => {
|
||||
return (
|
||||
<span className="whitespace-nowrap text-blue-600">
|
||||
{row.getValue("status")}
|
||||
{row.getValue("isPublishForAll")}
|
||||
</span>
|
||||
);
|
||||
},
|
||||
|
|
@ -159,6 +175,7 @@ export const columns: ColumnDef<CompanyData>[] = [
|
|||
];
|
||||
|
||||
const ContestTable = () => {
|
||||
const [contestTable, setContestTable] = React.useState<CompanyData[]>([]);
|
||||
const [sorting, setSorting] = React.useState<SortingState>([]);
|
||||
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
|
||||
[]
|
||||
|
|
@ -170,9 +187,12 @@ const ContestTable = () => {
|
|||
pageIndex: 0,
|
||||
pageSize: 6,
|
||||
});
|
||||
const [page, setPage] = React.useState(1);
|
||||
const [totalPage, setTotalPage] = React.useState(1);
|
||||
const [limit, setLimit] = React.useState(10);
|
||||
|
||||
const table = useReactTable({
|
||||
data,
|
||||
data: contestTable,
|
||||
columns,
|
||||
onSortingChange: setSorting,
|
||||
onColumnFiltersChange: setColumnFilters,
|
||||
|
|
@ -192,6 +212,30 @@ const ContestTable = () => {
|
|||
},
|
||||
});
|
||||
|
||||
React.useEffect(() => {
|
||||
initState();
|
||||
}, [page, limit]);
|
||||
|
||||
async function initState() {
|
||||
try {
|
||||
const res = await listContest(limit, page);
|
||||
const data = res.data.data.content.map((item: any, index: number) => ({
|
||||
no: (page - 1) * limit + index + 1,
|
||||
hastagCode: item.hastagCode,
|
||||
theme: item.theme,
|
||||
targetOutput: item.targetOutput,
|
||||
targetParticipantTopLevel: item.targetParticipantTopLevel,
|
||||
duration: item.duration,
|
||||
isDone: item.isDone,
|
||||
}));
|
||||
|
||||
setContestTable(data);
|
||||
setTotalPage(res.data.totalPages);
|
||||
} catch (error) {
|
||||
console.error("Error fetching tasks:", error);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="w-full overflow-x-auto">
|
||||
<div className="flex justify-between items-center py-4 px-5">
|
||||
|
|
|
|||
|
|
@ -46,15 +46,32 @@ import {
|
|||
} from "@/components/ui/dropdown-menu";
|
||||
|
||||
export type CompanyData = {
|
||||
no: number;
|
||||
title: string;
|
||||
date: string;
|
||||
status: string;
|
||||
isActive: boolean;
|
||||
};
|
||||
import { data } from "./data";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { InputGroup, InputGroupText } from "@/components/ui/input-group";
|
||||
import { listTask } from "@/service/ppid-categories-services";
|
||||
import page from "../page";
|
||||
import { getPlanningSentPagination } from "@/service/planning/planning";
|
||||
|
||||
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",
|
||||
|
|
@ -69,20 +86,26 @@ export const columns: ColumnDef<CompanyData>[] = [
|
|||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "date",
|
||||
accessorKey: "createdAt",
|
||||
header: "Tanggal Unggah ",
|
||||
cell: ({ row }) => (
|
||||
<span className="whitespace-nowrap">{row.getValue("date")}</span>
|
||||
<span className="whitespace-nowrap">{row.getValue("createdAt")}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "status",
|
||||
accessorKey: "isActive",
|
||||
header: "Status",
|
||||
cell: ({ row }) => {
|
||||
const isActive = row.getValue<boolean>("isActive");
|
||||
console.log("isActive value:", isActive); // TypeScript type is inferred correctly
|
||||
return (
|
||||
<span className="whitespace-nowrap text-blue-600">
|
||||
{row.getValue("status")}
|
||||
</span>
|
||||
<div>
|
||||
{isActive ? (
|
||||
<b className="text-info">Terkirim</b>
|
||||
) : (
|
||||
<b className="text-danger">Belum Terkirim</b>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
|
|
@ -124,6 +147,7 @@ export const columns: ColumnDef<CompanyData>[] = [
|
|||
];
|
||||
|
||||
const MediahubTable = () => {
|
||||
const [mediahubTable, setMediahubTable] = React.useState<CompanyData[]>([]);
|
||||
const [sorting, setSorting] = React.useState<SortingState>([]);
|
||||
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
|
||||
[]
|
||||
|
|
@ -133,11 +157,15 @@ const MediahubTable = () => {
|
|||
const [rowSelection, setRowSelection] = React.useState({});
|
||||
const [pagination, setPagination] = React.useState<PaginationState>({
|
||||
pageIndex: 0,
|
||||
pageSize: 6,
|
||||
pageSize: 10,
|
||||
});
|
||||
const [page, setPage] = React.useState(1);
|
||||
const [totalPage, setTotalPage] = React.useState(1);
|
||||
const [limit, setLimit] = React.useState(10);
|
||||
// const [search, setSearch] = React.useState(title);
|
||||
|
||||
const table = useReactTable({
|
||||
data,
|
||||
data: mediahubTable,
|
||||
columns,
|
||||
onSortingChange: setSorting,
|
||||
onColumnFiltersChange: setColumnFilters,
|
||||
|
|
@ -157,6 +185,27 @@ const MediahubTable = () => {
|
|||
},
|
||||
});
|
||||
|
||||
React.useEffect(() => {
|
||||
initState();
|
||||
}, [page, limit]);
|
||||
|
||||
async function initState() {
|
||||
try {
|
||||
const res = await getPlanningSentPagination(limit, page, 1);
|
||||
const data = res.data.data.content.map((item: any, index: number) => ({
|
||||
no: (page - 1) * limit + index + 1,
|
||||
title: item.title,
|
||||
createdAt: item.createdAt,
|
||||
isActive: item.isActive === true,
|
||||
}));
|
||||
|
||||
setMediahubTable(data);
|
||||
setTotalPage(res.data.totalPages);
|
||||
} catch (error) {
|
||||
console.error("Error fetching tasks:", error);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="w-full overflow-x-auto">
|
||||
<div className="flex justify-between items-center py-4 px-5">
|
||||
|
|
|
|||
|
|
@ -46,15 +46,32 @@ import {
|
|||
} from "@/components/ui/dropdown-menu";
|
||||
|
||||
export type CompanyData = {
|
||||
no: number;
|
||||
title: string;
|
||||
date: string;
|
||||
status: string;
|
||||
isActive: boolean;
|
||||
};
|
||||
import { data } from "./data";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { InputGroup, InputGroupText } from "@/components/ui/input-group";
|
||||
import { listTask } from "@/service/ppid-categories-services";
|
||||
import page from "../page";
|
||||
import { getPlanningSentPagination } from "@/service/planning/planning";
|
||||
|
||||
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",
|
||||
|
|
@ -69,20 +86,26 @@ export const columns: ColumnDef<CompanyData>[] = [
|
|||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "date",
|
||||
accessorKey: "createdAt",
|
||||
header: "Tanggal Unggah ",
|
||||
cell: ({ row }) => (
|
||||
<span className="whitespace-nowrap">{row.getValue("date")}</span>
|
||||
<span className="whitespace-nowrap">{row.getValue("createdAt")}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "status",
|
||||
accessorKey: "isActive",
|
||||
header: "Status",
|
||||
cell: ({ row }) => {
|
||||
const isActive = row.getValue<boolean>("isActive");
|
||||
console.log("isActive value:", isActive);
|
||||
return (
|
||||
<span className="whitespace-nowrap text-blue-600">
|
||||
{row.getValue("status")}
|
||||
</span>
|
||||
<div>
|
||||
{isActive ? (
|
||||
<b className="text-info">Terkirim</b>
|
||||
) : (
|
||||
<b className="text-danger">Belum Terkirim</b>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
|
|
@ -124,6 +147,7 @@ export const columns: ColumnDef<CompanyData>[] = [
|
|||
];
|
||||
|
||||
const MedsosTable = () => {
|
||||
const [mediahubTable, setMediahubTable] = React.useState<CompanyData[]>([]);
|
||||
const [sorting, setSorting] = React.useState<SortingState>([]);
|
||||
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
|
||||
[]
|
||||
|
|
@ -133,11 +157,15 @@ const MedsosTable = () => {
|
|||
const [rowSelection, setRowSelection] = React.useState({});
|
||||
const [pagination, setPagination] = React.useState<PaginationState>({
|
||||
pageIndex: 0,
|
||||
pageSize: 6,
|
||||
pageSize: 10,
|
||||
});
|
||||
const [page, setPage] = React.useState(1);
|
||||
const [totalPage, setTotalPage] = React.useState(1);
|
||||
const [limit, setLimit] = React.useState(10);
|
||||
// const [search, setSearch] = React.useState(title);
|
||||
|
||||
const table = useReactTable({
|
||||
data,
|
||||
data: mediahubTable,
|
||||
columns,
|
||||
onSortingChange: setSorting,
|
||||
onColumnFiltersChange: setColumnFilters,
|
||||
|
|
@ -157,6 +185,27 @@ const MedsosTable = () => {
|
|||
},
|
||||
});
|
||||
|
||||
React.useEffect(() => {
|
||||
initState();
|
||||
}, [page, limit]);
|
||||
|
||||
async function initState() {
|
||||
try {
|
||||
const res = await getPlanningSentPagination(limit, page, 2);
|
||||
const data = res.data.data.content.map((item: any, index: number) => ({
|
||||
no: (page - 1) * limit + index + 1,
|
||||
title: item.title,
|
||||
createdAt: item.createdAt,
|
||||
isActive: item.isActive === true,
|
||||
}));
|
||||
|
||||
setMediahubTable(data);
|
||||
setTotalPage(res.data.totalPages);
|
||||
} catch (error) {
|
||||
console.error("Error fetching tasks:", error);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="w-full overflow-x-auto">
|
||||
<div className="flex justify-between items-center py-4 px-5">
|
||||
|
|
|
|||
|
|
@ -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 />
|
||||
|
|
|
|||
|
|
@ -1,106 +0,0 @@
|
|||
export const data = [
|
||||
{
|
||||
title: "Giat Pimpinan",
|
||||
code: "PNMH-1287",
|
||||
status: "paid",
|
||||
date: "$231.26",
|
||||
category: "amplifikasi",
|
||||
typeTask: "Mediahub",
|
||||
},
|
||||
{
|
||||
title: "Liputan Kegiatan",
|
||||
code: "PNMH-1287",
|
||||
status: "due",
|
||||
date: "$432.81",
|
||||
category: "amplifikasi",
|
||||
typeTask: "Mediahub",
|
||||
},
|
||||
{
|
||||
title: "Giat Pimpinan",
|
||||
code: "PNMH-1287",
|
||||
status: "due",
|
||||
date: "$437.65",
|
||||
category: "amplifikasi",
|
||||
typeTask: "Mediahub",
|
||||
},
|
||||
{
|
||||
title: "Pers Rilis",
|
||||
code: "PNMH-1287",
|
||||
status: "canceled",
|
||||
date: "$387.55",
|
||||
category: "amplifikasi",
|
||||
typeTask: "Mediahub",
|
||||
},
|
||||
{
|
||||
title: "Giat Pimpinan",
|
||||
code: "PNMH-1287",
|
||||
status: "canceled",
|
||||
date: "$489.80",
|
||||
category: "amplifikasi",
|
||||
typeTask: "Mediahub",
|
||||
},
|
||||
{
|
||||
title: "Liputan Kegiatan",
|
||||
code: "PNMH-1287",
|
||||
status: "canceled",
|
||||
date: "$421.45",
|
||||
category: "amplifikasi",
|
||||
typeTask: "Mediahub",
|
||||
},
|
||||
{
|
||||
title: "Pers Rilis",
|
||||
code: "PNMH-1287",
|
||||
status: "canceled",
|
||||
date: "$207.61",
|
||||
category: "amplifikasi",
|
||||
typeTask: "Mediahub",
|
||||
},
|
||||
{
|
||||
title: "Giat Pimpinan",
|
||||
code: "PNMH-1287",
|
||||
status: "paid",
|
||||
date: "$392.86",
|
||||
category: "amplifikasi",
|
||||
typeTask: "Mediahub",
|
||||
},
|
||||
{
|
||||
title: "Pers Rilis",
|
||||
code: "PNMH-1287",
|
||||
status: "paid",
|
||||
date: "$162.87",
|
||||
category: "amplifikasi",
|
||||
typeTask: "Mediahub",
|
||||
},
|
||||
{
|
||||
title: "Giat Pimpinan",
|
||||
code: "PNMH-1287",
|
||||
status: "paid",
|
||||
date: "$268.58",
|
||||
category: "amplifikasi",
|
||||
typeTask: "Mediahub",
|
||||
},
|
||||
{
|
||||
title: "Liputan Kegiatan",
|
||||
code: "PNMH-1287",
|
||||
status: "paid",
|
||||
date: "$369.19",
|
||||
category: "amplifikasi",
|
||||
typeTask: "Mediahub",
|
||||
},
|
||||
{
|
||||
title: "Liputan Kegiatan",
|
||||
code: "PNMH-1287",
|
||||
status: "paid",
|
||||
date: "$420.87",
|
||||
category: "amplifikasi",
|
||||
typeTask: "Mediahub",
|
||||
},
|
||||
{
|
||||
title: "Giat Pimpinan",
|
||||
code: "PNMH-1287",
|
||||
status: "paid",
|
||||
date: "$420.26",
|
||||
category: "amplifikasi",
|
||||
typeTask: "Mediahub",
|
||||
},
|
||||
];
|
||||
|
|
@ -37,7 +37,6 @@ import {
|
|||
TrendingDown,
|
||||
TrendingUp,
|
||||
} from "lucide-react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
|
|
@ -45,20 +44,45 @@ import {
|
|||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
|
||||
export type CompanyData = {
|
||||
title: string;
|
||||
code: string;
|
||||
typeTask: string;
|
||||
category: string;
|
||||
date: string;
|
||||
status: string;
|
||||
};
|
||||
import { data } from "./data";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { InputGroup, InputGroupText } from "@/components/ui/input-group";
|
||||
import { Link } from "@/components/navigation";
|
||||
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;
|
||||
title: string;
|
||||
uniqueCode: string;
|
||||
assignmentMainType: string;
|
||||
assignmentType: string;
|
||||
createdAt: string;
|
||||
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",
|
||||
|
|
@ -73,47 +97,65 @@ export const columns: ColumnDef<CompanyData>[] = [
|
|||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "code",
|
||||
accessorKey: "uniqueCode",
|
||||
header: "Kode ",
|
||||
cell: ({ row }) => (
|
||||
<span className="whitespace-nowrap">{row.getValue("code")}</span>
|
||||
<span className="whitespace-nowrap">{row.getValue("uniqueCode")}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "typeTask",
|
||||
header: "Kode ",
|
||||
accessorKey: "assignmentMainType",
|
||||
header: "Tipe Tugas ",
|
||||
cell: ({ row }) => (
|
||||
<span className="whitespace-nowrap">{row.getValue("typeTask")}</span>
|
||||
<span className="whitespace-nowrap">
|
||||
{row.getValue("assignmentMainType")}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "category",
|
||||
accessorKey: "assignmentType",
|
||||
header: "Jenis Tugas ",
|
||||
cell: ({ row }) => (
|
||||
<span className="whitespace-nowrap">{row.getValue("category")}</span>
|
||||
<span className="whitespace-nowrap">
|
||||
{row.getValue("assignmentType")}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "date",
|
||||
header: "Tanggal Unggah ",
|
||||
cell: ({ row }) => (
|
||||
<span className="whitespace-nowrap">{row.getValue("date")}</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: "status",
|
||||
accessorKey: "isDone",
|
||||
header: "Status",
|
||||
cell: ({ row }) => {
|
||||
const statusColors: Record<CompanyData["status"], string> = {
|
||||
paid: "bg-success/20 text-success",
|
||||
due: "bg-warning/20 text-warning",
|
||||
canceled: "bg-destructive/20 text-destructive",
|
||||
};
|
||||
const status = row.getValue<CompanyData["status"]>("status");
|
||||
const isDone = row.getValue<boolean>("isDone");
|
||||
return (
|
||||
<Badge className={cn("rounded-full px-5", statusColors[status])}>
|
||||
{status}
|
||||
</Badge>
|
||||
<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>
|
||||
);
|
||||
},
|
||||
},
|
||||
|
|
@ -154,6 +196,7 @@ export const columns: ColumnDef<CompanyData>[] = [
|
|||
|
||||
const TaskTable = () => {
|
||||
const [sorting, setSorting] = React.useState<SortingState>([]);
|
||||
const [taskTable, setTaskTable] = React.useState<CompanyData[]>([]);
|
||||
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
|
||||
[]
|
||||
);
|
||||
|
|
@ -162,30 +205,58 @@ const TaskTable = () => {
|
|||
const [rowSelection, setRowSelection] = React.useState({});
|
||||
const [pagination, setPagination] = React.useState<PaginationState>({
|
||||
pageIndex: 0,
|
||||
pageSize: 6,
|
||||
pageSize: 10,
|
||||
});
|
||||
const [page, setPage] = React.useState(1);
|
||||
const [totalPage, setTotalPage] = React.useState(1);
|
||||
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,
|
||||
data: taskTable,
|
||||
columns,
|
||||
onSortingChange: setSorting,
|
||||
onColumnFiltersChange: setColumnFilters,
|
||||
onPaginationChange: setPagination,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
getPaginationRowModel: getPaginationRowModel(),
|
||||
getSortedRowModel: getSortedRowModel(),
|
||||
getFilteredRowModel: getFilteredRowModel(),
|
||||
onColumnVisibilityChange: setColumnVisibility,
|
||||
onRowSelectionChange: setRowSelection,
|
||||
onPaginationChange: setPagination,
|
||||
state: {
|
||||
sorting,
|
||||
columnFilters,
|
||||
columnVisibility,
|
||||
rowSelection,
|
||||
pagination,
|
||||
},
|
||||
});
|
||||
|
||||
React.useEffect(() => {
|
||||
initState();
|
||||
}, [page, limit]);
|
||||
|
||||
async function initState() {
|
||||
try {
|
||||
const res = await listTask(limit, page);
|
||||
const data = res.data.data.content.map((item: any, index: number) => ({
|
||||
no: (page - 1) * limit + index + 1,
|
||||
title: item.title,
|
||||
uniqueCode: item.uniqueCode || "-",
|
||||
assignmentMainType: item.assignmentMainType?.name || "-",
|
||||
assignmentType: item.assignmentType?.name || "-",
|
||||
createdAt: item.createdAt,
|
||||
isDone: item.isDone,
|
||||
}));
|
||||
|
||||
setTaskTable(data);
|
||||
setTotalPage(res.data.totalPages);
|
||||
} catch (error) {
|
||||
console.error("Error fetching tasks:", error);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="w-full overflow-x-auto">
|
||||
<div className="flex justify-between items-center py-4 px-5">
|
||||
|
|
@ -201,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..."
|
||||
|
|
|
|||
|
|
@ -22,17 +22,25 @@ const Login = ({ params: { locale } }: { params: { locale: string } }) => {
|
|||
className="lg:block hidden flex-1 overflow-hidden text-[40px] leading-[48px] text-default-600
|
||||
relative z-[1] bg-default-50"
|
||||
>
|
||||
<div className="max-w-[520px] pt-20 ps-20 ">
|
||||
<div className="max-w-[520px] pt-16 ps-20 ">
|
||||
<Link href="/" className="mb-6 inline-block">
|
||||
<Logo />
|
||||
<Image
|
||||
src="/assets/mediahub-logo.png"
|
||||
alt=""
|
||||
width={250}
|
||||
height={250}
|
||||
className="mb-10 w-full h-full"
|
||||
/>
|
||||
</Link>
|
||||
<h4>
|
||||
Unlock your Project
|
||||
<span className="text-default-800 font-bold ms-2">performance</span>
|
||||
</h4>
|
||||
</div>
|
||||
<div className="absolute left-0 2xl:bottom-[-160px] bottom-[-130px] h-full w-full z-[-1]">
|
||||
<Image src="/images/auth/ils1.svg" alt="" width={300} height={300} className="mb-10 w-full h-full" />
|
||||
<Image
|
||||
src="/assets/vector-login.svg"
|
||||
alt=""
|
||||
width={300}
|
||||
height={300}
|
||||
className="mb-10 w-full h-full"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-1 relative">
|
||||
|
|
@ -43,20 +51,30 @@ const Login = ({ params: { locale } }: { params: { locale: string } }) => {
|
|||
<Logo />
|
||||
</Link>
|
||||
</div>
|
||||
<div className="text-center 2xl:mb-10 mb-4">
|
||||
<h4 className="font-medium">Sign in</h4>
|
||||
<div className="text-default-500 text-base">Sign in to your account to start using Dashcode</div>
|
||||
<div className="text-left 2xl:mb-10 mb-4 mt-10">
|
||||
<h4 className="font-semibold text-3xl text-left">
|
||||
Silahkan Masuk Ke akun anda terlebih dahulu
|
||||
</h4>
|
||||
<div className="text-default-500 text-base">
|
||||
Belum punya akun?{" "}
|
||||
<span className="text-red-500">registrasi</span>
|
||||
</div>
|
||||
</div>
|
||||
<LoginForm />
|
||||
<div className="relative border-b-[#9AA2AF] border-opacity-[16%] border-b pt-6">
|
||||
<div className="absolute inline-block bg-default-50 dark:bg-default-100 left-1/2 top-1/2 transform -translate-x-1/2 px-4 min-w-max text-sm text-default-500 font-normal">Or continue with</div>
|
||||
<div className="absolute inline-block bg-default-50 dark:bg-default-100 left-1/2 top-1/2 transform -translate-x-1/2 px-4 min-w-max text-sm text-default-500 font-normal">
|
||||
Or continue with
|
||||
</div>
|
||||
</div>
|
||||
<div className="max-w-[242px] mx-auto mt-8 w-full">
|
||||
<Social locale={locale} />
|
||||
</div>
|
||||
<div className="md:max-w-[345px] mx-auto font-normal text-default-500 mt-12 uppercase text-sm">
|
||||
Don’t have an account?{" "}
|
||||
<Link href="/auth/register" className="text-default-900 font-medium hover:underline">
|
||||
<Link
|
||||
href="/auth/register"
|
||||
className="text-default-900 font-medium hover:underline"
|
||||
>
|
||||
Sign up
|
||||
</Link>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,20 +1,18 @@
|
|||
"use client";
|
||||
|
||||
|
||||
import SearchSection from "@/components/landing-page/search-section";
|
||||
import NewContent from "@/components/landing-page/new-content";
|
||||
import PopularContent from "@/components/landing-page/popular-content";
|
||||
import ContentCategory from "@/components/landing-page/content-category";
|
||||
import Coverage from "@/components/landing-page/coverage";
|
||||
import Navbar from "@/components/landing-page/navbar";
|
||||
import Hero from "@/components/landing-page/hero";
|
||||
import Hero from "@/components/landing-page/Hero";
|
||||
import Footer from "@/components/landing-page/footer";
|
||||
import Division from "@/components/landing-page/division";
|
||||
|
||||
const Home = ({ params: { locale } }: { params: { locale: string } }) => {
|
||||
return (
|
||||
<>
|
||||
|
||||
<Navbar />
|
||||
<Hero />
|
||||
<SearchSection />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,296 @@
|
|||
"use client";
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import { useForm, Controller } from "react-hook-form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Card } from "@/components/ui/card";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import * as z from "zod";
|
||||
import Swal from "sweetalert2";
|
||||
import withReactContent from "sweetalert2-react-content";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
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";
|
||||
import { options } from "@fullcalendar/core/preact.js";
|
||||
import { setOptions } from "leaflet";
|
||||
import {
|
||||
getCuratorUser,
|
||||
getTicketingPriority,
|
||||
saveTicketing,
|
||||
saveTicketingInternal,
|
||||
} from "@/service/communication/communication";
|
||||
import makeAnimated from "react-select/animated";
|
||||
import Select from "react-select";
|
||||
import {
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
} from "@radix-ui/react-select";
|
||||
import { SelectGroup } from "@/components/ui/select";
|
||||
|
||||
const taskSchema = z.object({
|
||||
title: z.string().min(1, { message: "Judul diperlukan" }),
|
||||
naration: z.string().min(2, {
|
||||
message: "Narasi Penugasan harus lebih dari 2 karakter.",
|
||||
}),
|
||||
});
|
||||
|
||||
interface Option {
|
||||
id: string;
|
||||
label: string;
|
||||
value: string;
|
||||
fullname: string;
|
||||
userLevel: string;
|
||||
userLevelId: string;
|
||||
}
|
||||
|
||||
export default function FormCollaboration() {
|
||||
const MySwal = withReactContent(Swal);
|
||||
const router = useRouter();
|
||||
const editor = useRef(null);
|
||||
type TaskSchema = z.infer<typeof taskSchema>;
|
||||
|
||||
// State for various form fields
|
||||
const [taskOutput, setTaskOutput] = useState({
|
||||
all: false,
|
||||
video: false,
|
||||
audio: false,
|
||||
image: false,
|
||||
text: false,
|
||||
});
|
||||
|
||||
const [assignmentType, setAssignmentType] = useState("mediahub");
|
||||
const [assignmentCategory, setAssignmentCategory] = useState("publication");
|
||||
const [mainType, setMainType] = useState<number>(1); // untuk Tipe Penugasan
|
||||
const [type, setType] = useState<string>("1");
|
||||
const [options, setOptions] = useState<Option[]>([]);
|
||||
const [ticketPriority, setTicketPriority] = useState([]);
|
||||
const [selectedOption, setSelectedOption] = useState<Option | undefined>(
|
||||
undefined
|
||||
);
|
||||
const animatedComponent = makeAnimated();
|
||||
const [platformTypeVisible, setPlatformTypeVisible] = useState(false);
|
||||
const [selectedTarget, setSelectedTarget] = useState("");
|
||||
|
||||
// Opsi untuk dropdown
|
||||
const priority = [
|
||||
{ value: "low", label: "Low" },
|
||||
{ value: "medium", label: "Medium" },
|
||||
{ value: "high", label: "High" },
|
||||
];
|
||||
|
||||
const {
|
||||
control,
|
||||
handleSubmit,
|
||||
formState: { errors },
|
||||
} = useForm<TaskSchema>({
|
||||
resolver: zodResolver(taskSchema),
|
||||
});
|
||||
|
||||
const handleRadioChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const selectedValue = Number(event.target.value);
|
||||
setMainType(selectedValue);
|
||||
|
||||
setPlatformTypeVisible(selectedValue === 2);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
getUser();
|
||||
getTicketPriority();
|
||||
});
|
||||
|
||||
const handleChange = (e: any) => {
|
||||
const selected = e;
|
||||
setSelectedOption(selected);
|
||||
};
|
||||
|
||||
const formatOptionLabel = (option: Option) => (
|
||||
<>
|
||||
<div className="row">
|
||||
<div className="col">
|
||||
{option.value} | {option.fullname}
|
||||
</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col">
|
||||
<b>{option.userLevel}</b>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
async function getTicketPriority() {
|
||||
const res = await getTicketingPriority();
|
||||
|
||||
if (res.data !== null) {
|
||||
const rawData = res.data?.data;
|
||||
setTicketPriority(rawData);
|
||||
}
|
||||
}
|
||||
|
||||
async function getUser() {
|
||||
const res = await getCuratorUser();
|
||||
|
||||
if (res.data !== null) {
|
||||
const rawUser = res.data?.data?.content;
|
||||
console.log("raw user", rawUser);
|
||||
|
||||
// Tentukan tipe array sebagai Option[]
|
||||
const optionArr: Option[] = rawUser.map((option: any) => ({
|
||||
id: option?.id,
|
||||
label: option?.username + option?.fullname + option?.userLevel?.name,
|
||||
value: option?.username,
|
||||
fullname: option?.fullname,
|
||||
userLevel: option?.userLevel?.name,
|
||||
userLevelId: option?.userLevel?.id,
|
||||
}));
|
||||
|
||||
setOptions(optionArr);
|
||||
}
|
||||
}
|
||||
|
||||
const save = async (data: TaskSchema) => {
|
||||
const requestData = {
|
||||
title: data.title,
|
||||
narration: data.naration,
|
||||
target: selectedTarget,
|
||||
sendToId: selectedOption?.id, // This should work now without the error
|
||||
};
|
||||
|
||||
const response = await saveTicketing(requestData);
|
||||
|
||||
console.log("Form Data Submitted:", requestData);
|
||||
console.log("response", response);
|
||||
|
||||
MySwal.fire({
|
||||
title: "Sukses",
|
||||
text: "Data berhasil disimpan.",
|
||||
icon: "success",
|
||||
confirmButtonColor: "#3085d6",
|
||||
confirmButtonText: "OK",
|
||||
}).then(() => {
|
||||
router.push("/en/communication");
|
||||
});
|
||||
};
|
||||
|
||||
const onSubmit = (data: TaskSchema) => {
|
||||
MySwal.fire({
|
||||
title: "Simpan Data",
|
||||
text: "Apakah Anda yakin ingin menyimpan data ini?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
cancelButtonColor: "#d33",
|
||||
confirmButtonColor: "#3085d6",
|
||||
confirmButtonText: "Simpan",
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
save(data);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<div className="px-6 py-6">
|
||||
<p className="text-lg font-semibold mb-3">Form Penugasan</p>
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<div className="gap-5 mb-5">
|
||||
{/* Input Title */}
|
||||
<div className="space-y-2">
|
||||
<Label>Judul</Label>
|
||||
<Controller
|
||||
control={control}
|
||||
name="title"
|
||||
render={({ field }) => (
|
||||
<Input
|
||||
size="md"
|
||||
type="text"
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
placeholder="Enter Title"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{errors.title?.message && (
|
||||
<p className="text-red-400 text-sm">{errors.title.message}</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<div className="mt-5">
|
||||
<Label>
|
||||
Priority<span className="text-red-500">*</span>
|
||||
</Label>
|
||||
<Select
|
||||
id="target-select"
|
||||
options={priority}
|
||||
onChange={(selectedOption) =>
|
||||
setSelectedTarget(selectedOption?.value || "")
|
||||
}
|
||||
placeholder="Pilih"
|
||||
styles={{
|
||||
control: (base) => ({
|
||||
...base,
|
||||
minHeight: "40px", // Ukuran sesuai dengan size="md"
|
||||
}),
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<div className="mt-5">
|
||||
<Label>
|
||||
Eskalasi Untuk <span className="text-red-500">*</span>
|
||||
</Label>
|
||||
<Select
|
||||
options={options}
|
||||
className="w-100"
|
||||
closeMenuOnSelect={false}
|
||||
components={animatedComponent}
|
||||
onChange={handleChange}
|
||||
formatOptionLabel={formatOptionLabel}
|
||||
isMulti={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-5">
|
||||
<Label>Narasi Penugasan</Label>
|
||||
<Controller
|
||||
control={control}
|
||||
name="naration"
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<JoditEditor
|
||||
ref={editor}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
className="dark:text-black"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{errors.naration?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.naration.message}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Submit Button */}
|
||||
<div className="mt-4">
|
||||
<Button type="submit" color="primary">
|
||||
Submit
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,291 @@
|
|||
"use client";
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import { useForm, Controller } from "react-hook-form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Card } from "@/components/ui/card";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import * as z from "zod";
|
||||
import Swal from "sweetalert2";
|
||||
import withReactContent from "sweetalert2-react-content";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
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";
|
||||
import { options } from "@fullcalendar/core/preact.js";
|
||||
import { setOptions } from "leaflet";
|
||||
import {
|
||||
getCuratorUser,
|
||||
getTicketingPriority,
|
||||
saveTicketingInternal,
|
||||
} from "@/service/communication/communication";
|
||||
import makeAnimated from "react-select/animated";
|
||||
import Select from "react-select";
|
||||
import {
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
} from "@radix-ui/react-select";
|
||||
import { SelectGroup } from "@/components/ui/select";
|
||||
|
||||
const taskSchema = z.object({
|
||||
title: z.string().min(1, { message: "Judul diperlukan" }),
|
||||
naration: z.string().min(2, {
|
||||
message: "Narasi Penugasan harus lebih dari 2 karakter.",
|
||||
}),
|
||||
});
|
||||
|
||||
interface Option {
|
||||
id: string;
|
||||
label: string;
|
||||
value: string;
|
||||
fullname: string;
|
||||
userLevel: string;
|
||||
userLevelId: string;
|
||||
}
|
||||
|
||||
export default function FormInternal() {
|
||||
const MySwal = withReactContent(Swal);
|
||||
const router = useRouter();
|
||||
const editor = useRef(null);
|
||||
type TaskSchema = z.infer<typeof taskSchema>;
|
||||
|
||||
// State for various form fields
|
||||
const [taskOutput, setTaskOutput] = useState({
|
||||
all: false,
|
||||
video: false,
|
||||
audio: false,
|
||||
image: false,
|
||||
text: false,
|
||||
});
|
||||
|
||||
const [assignmentType, setAssignmentType] = useState("mediahub");
|
||||
const [assignmentCategory, setAssignmentCategory] = useState("publication");
|
||||
const [mainType, setMainType] = useState<number>(1); // untuk Tipe Penugasan
|
||||
const [type, setType] = useState<string>("1");
|
||||
const [options, setOptions] = useState<Option[]>([]);
|
||||
const [ticketPriority, setTicketPriority] = useState([]);
|
||||
const [selectedOption, setSelectedOption] = useState<Option | undefined>(
|
||||
undefined
|
||||
);
|
||||
const animatedComponent = makeAnimated();
|
||||
const [platformTypeVisible, setPlatformTypeVisible] = useState(false);
|
||||
const [selectedTarget, setSelectedTarget] = useState("");
|
||||
|
||||
// Opsi untuk dropdown
|
||||
const priority = [
|
||||
{ value: "low", label: "Low" },
|
||||
{ value: "medium", label: "Medium" },
|
||||
{ value: "high", label: "High" },
|
||||
];
|
||||
|
||||
const {
|
||||
control,
|
||||
handleSubmit,
|
||||
formState: { errors },
|
||||
} = useForm<TaskSchema>({
|
||||
resolver: zodResolver(taskSchema),
|
||||
});
|
||||
|
||||
const handleRadioChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const selectedValue = Number(event.target.value);
|
||||
setMainType(selectedValue);
|
||||
|
||||
setPlatformTypeVisible(selectedValue === 2);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
getUser();
|
||||
getTicketPriority();
|
||||
});
|
||||
|
||||
const handleChange = (e: any) => {
|
||||
const selected = e;
|
||||
setSelectedOption(selected);
|
||||
};
|
||||
|
||||
const formatOptionLabel = (option: Option) => (
|
||||
<>
|
||||
<div className="row">
|
||||
<div className="col">
|
||||
{option.value} | {option.fullname}
|
||||
</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col">
|
||||
<b>{option.userLevel}</b>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
async function getTicketPriority() {
|
||||
const res = await getTicketingPriority();
|
||||
|
||||
if (res.data !== null) {
|
||||
const rawData = res.data?.data;
|
||||
setTicketPriority(rawData);
|
||||
}
|
||||
}
|
||||
|
||||
async function getUser() {
|
||||
const res = await getCuratorUser();
|
||||
|
||||
if (res.data !== null) {
|
||||
const rawUser = res.data?.data?.content;
|
||||
console.log("raw user", rawUser);
|
||||
|
||||
// Tentukan tipe array sebagai Option[]
|
||||
const optionArr: Option[] = rawUser.map((option: any) => ({
|
||||
id: option?.id,
|
||||
label: option?.username + option?.fullname + option?.userLevel?.name,
|
||||
value: option?.username,
|
||||
fullname: option?.fullname,
|
||||
userLevel: option?.userLevel?.name,
|
||||
userLevelId: option?.userLevel?.id,
|
||||
}));
|
||||
|
||||
setOptions(optionArr);
|
||||
}
|
||||
}
|
||||
|
||||
const save = async (data: TaskSchema) => {
|
||||
const requestData = {
|
||||
title: data.title,
|
||||
narration: data.naration,
|
||||
target: selectedTarget,
|
||||
sendToId: selectedOption?.id, // This should work now without the error
|
||||
};
|
||||
|
||||
const response = await saveTicketingInternal(requestData);
|
||||
|
||||
console.log("Form Data Submitted:", requestData);
|
||||
console.log("response", response);
|
||||
|
||||
MySwal.fire({
|
||||
title: "Sukses",
|
||||
text: "Data berhasil disimpan.",
|
||||
icon: "success",
|
||||
confirmButtonColor: "#3085d6",
|
||||
confirmButtonText: "OK",
|
||||
}).then(() => {
|
||||
router.push("/en/communication");
|
||||
});
|
||||
};
|
||||
|
||||
const onSubmit = (data: TaskSchema) => {
|
||||
MySwal.fire({
|
||||
title: "Simpan Data",
|
||||
text: "Apakah Anda yakin ingin menyimpan data ini?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
cancelButtonColor: "#d33",
|
||||
confirmButtonColor: "#3085d6",
|
||||
confirmButtonText: "Simpan",
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
save(data);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<div className="px-6 py-6">
|
||||
<p className="text-lg font-semibold mb-3">Form Penugasan</p>
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<div className="gap-5 mb-5">
|
||||
{/* Input Title */}
|
||||
<div className="space-y-2">
|
||||
<Label>Judul</Label>
|
||||
<Controller
|
||||
control={control}
|
||||
name="title"
|
||||
render={({ field }) => (
|
||||
<Input
|
||||
size="md"
|
||||
type="text"
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
placeholder="Enter Title"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{errors.title?.message && (
|
||||
<p className="text-red-400 text-sm">{errors.title.message}</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<div className="mt-5">
|
||||
<Label>Priority</Label>
|
||||
<Select
|
||||
id="target-select"
|
||||
options={priority}
|
||||
onChange={(selectedOption) =>
|
||||
setSelectedTarget(selectedOption?.value || "")
|
||||
}
|
||||
placeholder="Pilih"
|
||||
styles={{
|
||||
control: (base) => ({
|
||||
...base,
|
||||
minHeight: "40px", // Ukuran sesuai dengan size="md"
|
||||
}),
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<div className="mt-5">
|
||||
<Label>Ditunjukan Untuk</Label>
|
||||
<Select
|
||||
options={options}
|
||||
className="w-100"
|
||||
closeMenuOnSelect={false}
|
||||
components={animatedComponent}
|
||||
onChange={handleChange}
|
||||
formatOptionLabel={formatOptionLabel}
|
||||
isMulti={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-5">
|
||||
<Label>Narasi Penugasan</Label>
|
||||
<Controller
|
||||
control={control}
|
||||
name="naration"
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<JoditEditor
|
||||
ref={editor}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
className="dark:text-black"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{errors.naration?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.naration.message}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Submit Button */}
|
||||
<div className="mt-4">
|
||||
<Button type="submit" color="primary">
|
||||
Submit
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,381 @@
|
|||
"use client";
|
||||
import React, { ChangeEvent, useRef, useState } from "react";
|
||||
import { useForm, Controller } from "react-hook-form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Card } from "@/components/ui/card";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import * as z from "zod";
|
||||
import Swal from "sweetalert2";
|
||||
import withReactContent from "sweetalert2-react-content";
|
||||
import { useRouter } from "next/navigation";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
||||
import JoditEditor from "jodit-react";
|
||||
import { register } from "module";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
|
||||
const taskSchema = z.object({
|
||||
title: z.string().min(1, { message: "Judul diperlukan" }),
|
||||
naration: z.string().min(2, {
|
||||
message: "Narasi Penugasan harus lebih dari 2 karakter.",
|
||||
}),
|
||||
creator: z.string().min(1, { message: "Judul diperlukan" }),
|
||||
tags: z.string().min(1, { message: "Judul diperlukan" }),
|
||||
});
|
||||
|
||||
export default function FormImage() {
|
||||
const MySwal = withReactContent(Swal);
|
||||
const router = useRouter();
|
||||
const editor = useRef(null);
|
||||
type TaskSchema = z.infer<typeof taskSchema>;
|
||||
const [tags, setTags] = useState<string[]>([]);
|
||||
const [selectedFiles, setSelectedFiles] = useState<File[]>([]);
|
||||
|
||||
// State for various form fields
|
||||
const [output, setOutput] = useState({
|
||||
all: false,
|
||||
video: false,
|
||||
audio: false,
|
||||
image: false,
|
||||
text: false,
|
||||
});
|
||||
|
||||
const [assignmentType, setAssignmentType] = useState("mediahub");
|
||||
const [assignmentCategory, setAssignmentCategory] = useState("publication");
|
||||
|
||||
const [selectedTarget, setSelectedTarget] = useState("all");
|
||||
const [unitSelection, setUnitSelection] = useState({
|
||||
allUnit: false,
|
||||
mabes: false,
|
||||
polda: false,
|
||||
polres: false,
|
||||
});
|
||||
|
||||
const {
|
||||
control,
|
||||
handleSubmit,
|
||||
setValue,
|
||||
formState: { errors },
|
||||
} = useForm<TaskSchema>({
|
||||
resolver: zodResolver(taskSchema),
|
||||
});
|
||||
|
||||
const handleKeyDown = (e: any) => {
|
||||
const newTag = e.target.value.trim(); // Ambil nilai input
|
||||
if (e.key === "Enter" && newTag) {
|
||||
e.preventDefault(); // Hentikan submit form
|
||||
if (!tags.includes(newTag)) {
|
||||
setTags((prevTags) => [...prevTags, newTag]); // Tambah tag baru
|
||||
setValue("tags", ""); // Kosongkan input
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleRemoveTag = (index: any) => {
|
||||
setTags((prevTags) => prevTags.filter((_, i) => i !== index));
|
||||
};
|
||||
|
||||
const handleImageChange = (event: ChangeEvent<HTMLInputElement>) => {
|
||||
if (event.target.files) {
|
||||
const files = Array.from(event.target.files);
|
||||
setSelectedFiles((prevImages: any) => [...prevImages, ...files]);
|
||||
console.log("DATAFILE::", selectedFiles);
|
||||
}
|
||||
};
|
||||
|
||||
const handleRemoveImage = (index: number) => {
|
||||
setSelectedFiles((prevImages) => prevImages.filter((_, i) => i !== index));
|
||||
};
|
||||
|
||||
const save = async (data: TaskSchema) => {
|
||||
const requestData = {
|
||||
...data,
|
||||
output,
|
||||
assignmentType,
|
||||
assignmentCategory,
|
||||
target: selectedTarget,
|
||||
unitSelection,
|
||||
};
|
||||
|
||||
console.log("Form Data Submitted:", requestData);
|
||||
|
||||
MySwal.fire({
|
||||
title: "Sukses",
|
||||
text: "Data berhasil disimpan.",
|
||||
icon: "success",
|
||||
confirmButtonColor: "#3085d6",
|
||||
confirmButtonText: "OK",
|
||||
}).then(() => {
|
||||
router.push("/en/content/image");
|
||||
});
|
||||
};
|
||||
|
||||
const onSubmit = (data: TaskSchema) => {
|
||||
MySwal.fire({
|
||||
title: "Simpan Data",
|
||||
text: "Apakah Anda yakin ingin menyimpan data ini?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
cancelButtonColor: "#d33",
|
||||
confirmButtonColor: "#3085d6",
|
||||
confirmButtonText: "Simpan",
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
save(data);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<div className="flex lg:flex-row gap-10">
|
||||
<Card className="w-full lg:w-8/12">
|
||||
<div className="px-6 py-6">
|
||||
<p className="text-lg font-semibold mb-3">Form Konten Foto</p>
|
||||
<div className="gap-5 mb-5">
|
||||
{/* Input Title */}
|
||||
<div className="space-y-2 py-3">
|
||||
<Label>Judul</Label>
|
||||
<Controller
|
||||
control={control}
|
||||
name="title"
|
||||
render={({ field }) => (
|
||||
<Input
|
||||
size="md"
|
||||
type="text"
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
placeholder="Enter Title"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{errors.title?.message && (
|
||||
<p className="text-red-400 text-sm">{errors.title.message}</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<div className="py-3 w-full">
|
||||
<Label>Kategory</Label>
|
||||
<Select onValueChange={setSelectedTarget}>
|
||||
<SelectTrigger size="md">
|
||||
<SelectValue placeholder="Pilih" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="all">Mediapool</SelectItem>
|
||||
<SelectItem value="contributor">
|
||||
Liputan Kegiatan
|
||||
</SelectItem>
|
||||
<SelectItem value="approver">Press Tour</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
<div className="py-3">
|
||||
<Label>Deskripsi</Label>
|
||||
<Controller
|
||||
control={control}
|
||||
name="naration"
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<JoditEditor
|
||||
ref={editor}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
className="dark:text-black"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{errors.naration?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.naration.message}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="py-3">
|
||||
<Label>Attachment</Label>
|
||||
<div className="flex items-center justify-center w-full pt-2">
|
||||
<label
|
||||
htmlFor="dropzone-file"
|
||||
className="flex flex-col items-center justify-center w-full h-[155px] border-2 border-black border-dashed rounded-lg cursor-pointer dark:bg-black dark:hover:bg-bray-800 hover:bg-gray-100 dark:border-gray-600 dark:hover:border-gray-500 dark:hover:bg-gray-600"
|
||||
>
|
||||
<div className="flex flex-col items-center justify-center pt-5 pb-6 ">
|
||||
<svg
|
||||
className="w-10 h-10 mb-3 text-gray-400"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"
|
||||
></path>
|
||||
</svg>
|
||||
<p className="mb-2 text-sm text-gray-500 dark:text-gray-400">
|
||||
{/* or{" "} */}
|
||||
<span className="font-semibold underline text-amber-800">
|
||||
Click to upload
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<input
|
||||
id="dropzone-file"
|
||||
type="file"
|
||||
className="hidden"
|
||||
onChange={handleImageChange}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<div className="flex flex-row items-center gap-3 py-3">
|
||||
<Label>Gunakan Watermark</Label>
|
||||
<div className="flex items-center gap-3">
|
||||
<Switch defaultChecked color="primary" id="c2" />
|
||||
</div>
|
||||
</div>
|
||||
{selectedFiles?.length > 0 ? (
|
||||
<div className="pt-2">
|
||||
<div className="flex gap-3">
|
||||
{selectedFiles.map((image, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="flex flex-row items-center justify-between gap-1"
|
||||
>
|
||||
<img
|
||||
src={URL.createObjectURL(image)}
|
||||
alt="Pratinjau Gambar"
|
||||
style={{ maxWidth: "200px", maxHeight: "200px" }}
|
||||
className="rounded-md"
|
||||
/>
|
||||
<button
|
||||
className="text-blue-600 hover:text-blue-800 focus:outline-none"
|
||||
onClick={() => handleRemoveImage(index)}
|
||||
>
|
||||
X
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Submit Button */}
|
||||
</div>
|
||||
</Card>
|
||||
<div className="w-4/12">
|
||||
<Card className=" h-[500px]">
|
||||
<div className="px-3 py-3">
|
||||
<div className="space-y-2">
|
||||
<Label>Kreator</Label>
|
||||
<Controller
|
||||
control={control}
|
||||
name="creator"
|
||||
render={({ field }) => (
|
||||
<Input
|
||||
size="md"
|
||||
type="text"
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
placeholder="Enter Title"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{errors.creator?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.creator.message}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="px-3 py-3">
|
||||
<Label>Tags</Label>
|
||||
<Controller
|
||||
control={control}
|
||||
name="tags"
|
||||
render={({ field }) => (
|
||||
<Input
|
||||
size="md"
|
||||
type="text"
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
placeholder="Enter Title"
|
||||
onKeyDown={handleKeyDown}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<div className="text-sm text-red-500">
|
||||
{tags.length === 0 && "Please add at least one tag."}
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-2 border border-gray-300 mt-2 rounded-md p-2 items-center">
|
||||
{tags.map((tag, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="flex items-center gap-1 bg-blue-100 text-blue-800 rounded-full px-3 py-1 text-sm font-medium"
|
||||
>
|
||||
<span>{tag}</span>
|
||||
<button
|
||||
className="text-blue-600 hover:text-blue-800 focus:outline-none"
|
||||
onClick={() => handleRemoveTag(index)}
|
||||
>
|
||||
×
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="px-3 py-3">
|
||||
<div className="flex flex-col gap-6">
|
||||
<Label>Target Publish</Label>
|
||||
<div className="flex gap-2 items-center">
|
||||
<Checkbox id="all" />
|
||||
<Label htmlFor="all">SEMUA</Label>
|
||||
</div>
|
||||
<div className="flex gap-2 items-center">
|
||||
<Checkbox id="umum" />
|
||||
<Label htmlFor="umum">UMUM</Label>
|
||||
</div>
|
||||
<div className="flex gap-2 items-center">
|
||||
<Checkbox id="journalist" />
|
||||
<Label htmlFor="journalist">JOURNALIS</Label>
|
||||
</div>
|
||||
<div className="flex gap-2 items-center">
|
||||
<Checkbox id="polri" />
|
||||
<Label htmlFor="polri">POLRI</Label>
|
||||
</div>
|
||||
<div className="flex gap-2 items-center">
|
||||
<Checkbox id="ksp" />
|
||||
<Label htmlFor="ksp">KSP</Label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
<div className="flex flex-row justify-end gap-3">
|
||||
<div className="mt-4">
|
||||
<Button type="submit" color="primary">
|
||||
Submit
|
||||
</Button>
|
||||
</div>
|
||||
<div className="mt-4">
|
||||
<Button type="submit" color="primary" variant="outline">
|
||||
Cancel
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
|
@ -20,6 +20,7 @@ import {
|
|||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
||||
import JoditEditor from "jodit-react";
|
||||
import { createTask } from "@/service/task";
|
||||
|
||||
const taskSchema = z.object({
|
||||
title: z.string().min(1, { message: "Judul diperlukan" }),
|
||||
|
|
@ -35,7 +36,7 @@ export default function FormTask() {
|
|||
type TaskSchema = z.infer<typeof taskSchema>;
|
||||
|
||||
// State for various form fields
|
||||
const [output, setOutput] = useState({
|
||||
const [taskOutput, setTaskOutput] = useState({
|
||||
all: false,
|
||||
video: false,
|
||||
audio: false,
|
||||
|
|
@ -45,8 +46,11 @@ export default function FormTask() {
|
|||
|
||||
const [assignmentType, setAssignmentType] = useState("mediahub");
|
||||
const [assignmentCategory, setAssignmentCategory] = useState("publication");
|
||||
|
||||
const [mainType, setMainType] = useState<number>(1); // untuk Tipe Penugasan
|
||||
const [type, setType] = useState<string>("1");
|
||||
const [selectedTarget, setSelectedTarget] = useState("all");
|
||||
|
||||
const [platformTypeVisible, setPlatformTypeVisible] = useState(false);
|
||||
const [unitSelection, setUnitSelection] = useState({
|
||||
allUnit: false,
|
||||
mabes: false,
|
||||
|
|
@ -62,17 +66,40 @@ export default function FormTask() {
|
|||
resolver: zodResolver(taskSchema),
|
||||
});
|
||||
|
||||
const handleRadioChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const selectedValue = Number(event.target.value);
|
||||
setMainType(selectedValue);
|
||||
|
||||
setPlatformTypeVisible(selectedValue === 2);
|
||||
};
|
||||
|
||||
const save = async (data: TaskSchema) => {
|
||||
const requestData = {
|
||||
...data,
|
||||
output,
|
||||
assignmentType,
|
||||
assignmentCategory,
|
||||
target: selectedTarget,
|
||||
unitSelection,
|
||||
assignedToRole: "3",
|
||||
assignmentMainTypeId: 1,
|
||||
assignmentPurpose: "1",
|
||||
assignmentTypeId: type,
|
||||
fileTypeOutput: taskOutput,
|
||||
id: null,
|
||||
narration: data.naration,
|
||||
platformType: "",
|
||||
title: data.title,
|
||||
};
|
||||
|
||||
const response = await createTask(requestData);
|
||||
|
||||
// if (response.error) {
|
||||
// error(response.message);
|
||||
// return false;
|
||||
// }
|
||||
|
||||
console.log("Form Data Submitted:", requestData);
|
||||
console.log("response", response);
|
||||
|
||||
MySwal.fire({
|
||||
title: "Sukses",
|
||||
|
|
@ -161,13 +188,13 @@ export default function FormTask() {
|
|||
<div className="mt-5">
|
||||
<Label>Tipe Penugasan</Label>
|
||||
<RadioGroup
|
||||
value={assignmentType}
|
||||
onValueChange={setAssignmentType}
|
||||
value={String(mainType)}
|
||||
onValueChange={(value) => setMainType(Number(value))}
|
||||
className="flex flex-wrap gap-6"
|
||||
>
|
||||
<RadioGroupItem value="mediahub" id="mediahub" />
|
||||
<RadioGroupItem value="1" id="mediahub" />
|
||||
<Label htmlFor="mediahub">Mediahub</Label>
|
||||
<RadioGroupItem value="medsos-mediahub" id="medsos-mediahub" />
|
||||
<RadioGroupItem value="2" id="medsos-mediahub" />
|
||||
<Label htmlFor="medsos-mediahub">Medsos Mediahub</Label>
|
||||
</RadioGroup>
|
||||
</div>
|
||||
|
|
@ -176,28 +203,35 @@ export default function FormTask() {
|
|||
<div className="mt-5">
|
||||
<Label>Jenis Penugasan</Label>
|
||||
<RadioGroup
|
||||
value={assignmentCategory}
|
||||
onValueChange={setAssignmentCategory}
|
||||
value={type} // State yang dipetakan ke value RadioGroup
|
||||
onValueChange={(value) => setType(value)} // Mengubah nilai state ketika pilihan berubah
|
||||
className="flex flex-wrap gap-6"
|
||||
>
|
||||
<RadioGroupItem value="publication" id="publication" />
|
||||
<Label htmlFor="publication">Publikasi</Label>
|
||||
<RadioGroupItem value="amplification" id="amplification" />
|
||||
<Label htmlFor="amplification">Amplifikasi</Label>
|
||||
<RadioGroupItem value="contra" id="contra" />
|
||||
<Label htmlFor="contra">Kontra</Label>
|
||||
<div className="flex items-center gap-2">
|
||||
<RadioGroupItem value="1" id="publication" />
|
||||
<Label htmlFor="publication">Publikasi</Label>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<RadioGroupItem value="2" id="amplification" />
|
||||
<Label htmlFor="amplification">Amplifikasi</Label>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<RadioGroupItem value="3" id="contra" />
|
||||
<Label htmlFor="contra">Kontra</Label>
|
||||
</div>
|
||||
</RadioGroup>
|
||||
</div>
|
||||
|
||||
<div className="mt-5">
|
||||
<Label>Output Tugas</Label>
|
||||
<div className="flex flex-wrap gap-3">
|
||||
{Object.keys(output).map((key) => (
|
||||
{Object.keys(taskOutput).map((key) => (
|
||||
<div className="flex items-center gap-2" key={key}>
|
||||
<Checkbox
|
||||
id={key}
|
||||
checked={output[key as keyof typeof output]}
|
||||
checked={taskOutput[key as keyof typeof taskOutput]}
|
||||
onCheckedChange={(value) =>
|
||||
setOutput({ ...output, [key]: value })
|
||||
setTaskOutput({ ...taskOutput, [key]: value })
|
||||
}
|
||||
/>
|
||||
<Label htmlFor={key}>
|
||||
|
|
|
|||
|
|
@ -2,11 +2,18 @@
|
|||
|
||||
import React, { useState } from "react";
|
||||
import ThemeSwitcher from "@/components/partials/header/theme-switcher";
|
||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "../ui/dropdown-menu";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "../ui/dropdown-menu";
|
||||
import Link from "next/link";
|
||||
import { FiFile, FiImage, FiMusic, FiYoutube } from "react-icons/fi";
|
||||
import { useParams, usePathname, useRouter } from "next/navigation";
|
||||
import { generateLocalizedPath } from "@/utils/globals";
|
||||
import { locale } from "dayjs";
|
||||
import router from "next/router";
|
||||
|
||||
const Navbar = () => {
|
||||
const [menuOpen, setMenuOpen] = useState(false);
|
||||
|
|
@ -27,18 +34,41 @@ const Navbar = () => {
|
|||
<div className="flex items-center justify-between lg:justify-center px-4 lg:px-23 py-4 ">
|
||||
{/* Logo */}
|
||||
<a href="/" className="flex items-center px-3">
|
||||
<img src="/assets/mediahub-logo.gif" alt="Media Hub Logo" className="w-30 h-20 lg:max-w-screen-md md:h-24 flex" />
|
||||
<img
|
||||
src="/assets/mediahub-logo.gif"
|
||||
alt="Media Hub Logo"
|
||||
className="w-30 h-20 lg:max-w-screen-md md:h-24 flex"
|
||||
/>
|
||||
</a>
|
||||
|
||||
{/* Mobile Menu Toggle */}
|
||||
<button className="text-black dark:text-white size-20 h-10 w-10 lg:hidden" onClick={() => setMenuOpen(!menuOpen)}>
|
||||
<button
|
||||
className="text-black dark:text-white size-20 h-10 w-10 lg:hidden"
|
||||
onClick={() => setMenuOpen(!menuOpen)}
|
||||
>
|
||||
{menuOpen ? (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path fill="#000" d="m13.41 12l4.3-4.29a1 1 0 1 0-1.42-1.42L12 10.59l-4.29-4.3a1 1 0 0 0-1.42 1.42l4.3 4.29l-4.3 4.29a1 1 0 0 0 0 1.42a1 1 0 0 0 1.42 0l4.29-4.3l4.29 4.3a1 1 0 0 0 1.42 0a1 1 0 0 0 0-1.42Z" />
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
fill="#000"
|
||||
d="m13.41 12l4.3-4.29a1 1 0 1 0-1.42-1.42L12 10.59l-4.29-4.3a1 1 0 0 0-1.42 1.42l4.3 4.29l-4.3 4.29a1 1 0 0 0 0 1.42a1 1 0 0 0 1.42 0l4.29-4.3l4.29 4.3a1 1 0 0 0 1.42 0a1 1 0 0 0 0-1.42Z"
|
||||
/>
|
||||
</svg>
|
||||
) : (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path fill="#000" d="M4 6a1 1 0 0 1 1-1h14a1 1 0 1 1 0 2H5a1 1 0 0 1-1-1m0 6a1 1 0 0 1 1-1h14a1 1 0 1 1 0 2H5a1 1 0 0 1-1-1m1 5a1 1 0 1 0 0 2h14a1 1 0 1 0 0-2z" />
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
fill="#000"
|
||||
d="M4 6a1 1 0 0 1 1-1h14a1 1 0 1 1 0 2H5a1 1 0 0 1-1-1m0 6a1 1 0 0 1 1-1h14a1 1 0 1 1 0 2H5a1 1 0 0 1-1-1m1 5a1 1 0 1 0 0 2h14a1 1 0 1 0 0-2z"
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
</button>
|
||||
|
|
@ -48,38 +78,86 @@ const Navbar = () => {
|
|||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<a className=" dark:text-white text-black flex flex-row justify-center items-center ml-5 cursor-pointer">
|
||||
<svg className="mx-2 dark:" width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg
|
||||
className="mx-2 dark:"
|
||||
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="start" className="p-0 rounded-md overflow-hidden">
|
||||
<DropdownMenuItem onClick={() => router.push(generateLocalizedPath("/video/filter", String(locale)))} className="flex items-start gap-1.5 p-2 hover:bg-white">
|
||||
<DropdownMenuContent
|
||||
align="start"
|
||||
className="p-0 rounded-md overflow-hidden"
|
||||
>
|
||||
<DropdownMenuItem
|
||||
onClick={() =>
|
||||
router.push(
|
||||
generateLocalizedPath("/video/filter", String(locale))
|
||||
)
|
||||
}
|
||||
className="flex items-start gap-1.5 p-2 hover:bg-white"
|
||||
>
|
||||
<span className="text-slate-600 hover:text-[#bb3523] flex flex-row justify-center items-center px-5 py-2">
|
||||
<FiYoutube className="mr-2" />
|
||||
Audio Visual
|
||||
</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => router.push(generateLocalizedPath("/audio/filter", String(locale)))} className="flex place-items-start gap-1.5 p-2 hover:bg-white">
|
||||
<DropdownMenuItem
|
||||
onClick={() =>
|
||||
router.push(
|
||||
generateLocalizedPath("/audio/filter", String(locale))
|
||||
)
|
||||
}
|
||||
className="flex place-items-start gap-1.5 p-2 hover:bg-white"
|
||||
>
|
||||
<span className="text-slate-600 hover:text-[#bb3523] flex flex-row justify-center items-center px-5 py-2">
|
||||
<FiMusic className="mr-2" />
|
||||
Audio
|
||||
</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => router.push(generateLocalizedPath("/image/filter", String(locale)))} className="flex place-items-start gap-1.5 p-2 hover:bg-white">
|
||||
<DropdownMenuItem
|
||||
onClick={() =>
|
||||
router.push(
|
||||
generateLocalizedPath("/image/filter", String(locale))
|
||||
)
|
||||
}
|
||||
className="flex place-items-start gap-1.5 p-2 hover:bg-white"
|
||||
>
|
||||
<span className="text-slate-600 hover:text-[#bb3523] flex flex-row justify-center items-center px-5 py-2">
|
||||
<FiImage className="mr-2" />
|
||||
Foto
|
||||
</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => router.push(generateLocalizedPath("/document/filter", String(locale)))} className="flex place-items-start gap-1.5 p-2 hover:bg-white">
|
||||
<DropdownMenuItem
|
||||
onClick={() =>
|
||||
router.push(
|
||||
generateLocalizedPath("/document/filter", String(locale))
|
||||
)
|
||||
}
|
||||
className="flex place-items-start gap-1.5 p-2 hover:bg-white"
|
||||
>
|
||||
<span className="text-slate-600 hover:text-[#bb3523] flex flex-row justify-center items-center px-5 py-2">
|
||||
<FiFile className="mr-2" />
|
||||
Teks
|
||||
|
|
@ -87,9 +165,19 @@ const Navbar = () => {
|
|||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
<Link href={generateLocalizedPath("/schedule", String(locale))} className="dark:text-white text-black font-medium flex flex-row items-center justify-center hover:text-gray-800">
|
||||
<Link
|
||||
href={generateLocalizedPath("/schedule", String(locale))}
|
||||
className="dark:text-white text-black font-medium flex flex-row items-center justify-center hover:text-gray-800"
|
||||
>
|
||||
<span>
|
||||
<svg className="mr-2" width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg
|
||||
className="mr-2"
|
||||
width="25"
|
||||
height="24"
|
||||
viewBox="0 0 25 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M19.5 4H18.5V3C18.5 2.4 18.1 2 17.5 2C16.9 2 16.5 2.4 16.5 3V4H8.5V3C8.5 2.4 8.1 2 7.5 2C6.9 2 6.5 2.4 6.5 3V4H5.5C3.8 4 2.5 5.3 2.5 7V8H22.5V7C22.5 5.3 21.2 4 19.5 4ZM2.5 19C2.5 20.7 3.8 22 5.5 22H19.5C21.2 22 22.5 20.7 22.5 19V10H2.5V19ZM17.5 12C18.1 12 18.5 12.4 18.5 13C18.5 13.6 18.1 14 17.5 14C16.9 14 16.5 13.6 16.5 13C16.5 12.4 16.9 12 17.5 12ZM17.5 16C18.1 16 18.5 16.4 18.5 17C18.5 17.6 18.1 18 17.5 18C16.9 18 16.5 17.6 16.5 17C16.5 16.4 16.9 16 17.5 16ZM12.5 12C13.1 12 13.5 12.4 13.5 13C13.5 13.6 13.1 14 12.5 14C11.9 14 11.5 13.6 11.5 13C11.5 12.4 11.9 12 12.5 12ZM12.5 16C13.1 16 13.5 16.4 13.5 17C13.5 17.6 13.1 18 12.5 18C11.9 18 11.5 17.6 11.5 17C11.5 16.4 11.9 16 12.5 16ZM7.5 12C8.1 12 8.5 12.4 8.5 13C8.5 13.6 8.1 14 7.5 14C6.9 14 6.5 13.6 6.5 13C6.5 12.4 6.9 12 7.5 12ZM7.5 16C8.1 16 8.5 16.4 8.5 17C8.5 17.6 8.1 18 7.5 18C6.9 18 6.5 17.6 6.5 17C6.5 16.4 6.9 16 7.5 16Z"
|
||||
fill="currentColor"
|
||||
|
|
@ -98,9 +186,19 @@ const Navbar = () => {
|
|||
</span>
|
||||
Jadwal
|
||||
</Link>
|
||||
<Link href={pathname?.includes("/in") ? `/indeks` : `${locale}/indeks`} className="dark:text-white text-black flex flex-row items-center justify-center font-medium hover:text-gray-800">
|
||||
<Link
|
||||
href={pathname?.includes("/in") ? `/indeks` : `${locale}/indeks`}
|
||||
className="dark:text-white text-black flex flex-row items-center justify-center font-medium hover:text-gray-800"
|
||||
>
|
||||
<span>
|
||||
<svg className="mr-2" width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg
|
||||
className="mr-2"
|
||||
width="25"
|
||||
height="24"
|
||||
viewBox="0 0 25 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
|
|
@ -117,7 +215,10 @@ const Navbar = () => {
|
|||
</Link>
|
||||
<div className="flex items-center space-x-1 ">
|
||||
<a href="https://tvradio.polri.go.id/">
|
||||
<img src="/assets/polriTv.png" className="w-20 lg:max-w-screen-lg h-10 flex-auto " />
|
||||
<img
|
||||
src="/assets/polriTv.png"
|
||||
className="w-20 lg:max-w-screen-lg h-10 flex-auto "
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<div className="relative inline-block text-left">
|
||||
|
|
@ -179,38 +280,86 @@ const Navbar = () => {
|
|||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<a className=" text-white flex flex-row items-center cursor-pointer">
|
||||
<svg className="mr-2" width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg
|
||||
className="mr-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="white"
|
||||
/>
|
||||
</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="start" className="p-0 rounded-md overflow-hidden">
|
||||
<DropdownMenuItem onClick={() => router.push(generateLocalizedPath("/video/filter", String(locale)))} className="flex items-start gap-1.5 p-2 hover:bg-white">
|
||||
<DropdownMenuContent
|
||||
align="start"
|
||||
className="p-0 rounded-md overflow-hidden"
|
||||
>
|
||||
<DropdownMenuItem
|
||||
onClick={() =>
|
||||
router.push(
|
||||
generateLocalizedPath("/video/filter", String(locale))
|
||||
)
|
||||
}
|
||||
className="flex items-start gap-1.5 p-2 hover:bg-white"
|
||||
>
|
||||
<span className="text-slate-600 hover:text-[#bb3523] flex flex-row justify-center items-center p-3">
|
||||
<FiYoutube className="mr-2" />
|
||||
Audio Visual
|
||||
</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => router.push(generateLocalizedPath("/audio/filter", String(locale)))} className="flex place-items-start gap-1.5 p-2 hover:bg-white">
|
||||
<DropdownMenuItem
|
||||
onClick={() =>
|
||||
router.push(
|
||||
generateLocalizedPath("/audio/filter", String(locale))
|
||||
)
|
||||
}
|
||||
className="flex place-items-start gap-1.5 p-2 hover:bg-white"
|
||||
>
|
||||
<span className="text-slate-600 hover:text-[#bb3523] flex flex-row justify-center items-center p-3">
|
||||
<FiMusic className="mr-2" />
|
||||
Audio
|
||||
</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => router.push(generateLocalizedPath("/image/filter", String(locale)))} className="flex place-items-start gap-1.5 p-2 hover:bg-white">
|
||||
<DropdownMenuItem
|
||||
onClick={() =>
|
||||
router.push(
|
||||
generateLocalizedPath("/image/filter", String(locale))
|
||||
)
|
||||
}
|
||||
className="flex place-items-start gap-1.5 p-2 hover:bg-white"
|
||||
>
|
||||
<span className="text-slate-600 hover:text-[#bb3523] flex flex-row justify-center items-center p-3">
|
||||
<FiImage className="mr-2" />
|
||||
Foto
|
||||
</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => router.push(generateLocalizedPath("/document/filter", String(locale)))} className="flex place-items-start gap-1.5 p-2 hover:bg-white">
|
||||
<DropdownMenuItem
|
||||
onClick={() =>
|
||||
router.push(
|
||||
generateLocalizedPath("/document/filter", String(locale))
|
||||
)
|
||||
}
|
||||
className="flex place-items-start gap-1.5 p-2 hover:bg-white"
|
||||
>
|
||||
<span className="text-slate-600 hover:text-[#bb3523] flex flex-row justify-center items-center p-3">
|
||||
<FiFile className="mr-2" />
|
||||
Teks
|
||||
|
|
@ -218,9 +367,19 @@ const Navbar = () => {
|
|||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
<Link href="#" className="flex text-white flex-row items-center font-medium hover:text-gray-800">
|
||||
<Link
|
||||
href="#"
|
||||
className="flex text-white flex-row items-center font-medium hover:text-gray-800"
|
||||
>
|
||||
<span>
|
||||
<svg className="mr-2" width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg
|
||||
className="mr-2"
|
||||
width="25"
|
||||
height="24"
|
||||
viewBox="0 0 25 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M19.5 4H18.5V3C18.5 2.4 18.1 2 17.5 2C16.9 2 16.5 2.4 16.5 3V4H8.5V3C8.5 2.4 8.1 2 7.5 2C6.9 2 6.5 2.4 6.5 3V4H5.5C3.8 4 2.5 5.3 2.5 7V8H22.5V7C22.5 5.3 21.2 4 19.5 4ZM2.5 19C2.5 20.7 3.8 22 5.5 22H19.5C21.2 22 22.5 20.7 22.5 19V10H2.5V19ZM17.5 12C18.1 12 18.5 12.4 18.5 13C18.5 13.6 18.1 14 17.5 14C16.9 14 16.5 13.6 16.5 13C16.5 12.4 16.9 12 17.5 12ZM17.5 16C18.1 16 18.5 16.4 18.5 17C18.5 17.6 18.1 18 17.5 18C16.9 18 16.5 17.6 16.5 17C16.5 16.4 16.9 16 17.5 16ZM12.5 12C13.1 12 13.5 12.4 13.5 13C13.5 13.6 13.1 14 12.5 14C11.9 14 11.5 13.6 11.5 13C11.5 12.4 11.9 12 12.5 12ZM12.5 16C13.1 16 13.5 16.4 13.5 17C13.5 17.6 13.1 18 12.5 18C11.9 18 11.5 17.6 11.5 17C11.5 16.4 11.9 16 12.5 16ZM7.5 12C8.1 12 8.5 12.4 8.5 13C8.5 13.6 8.1 14 7.5 14C6.9 14 6.5 13.6 6.5 13C6.5 12.4 6.9 12 7.5 12ZM7.5 16C8.1 16 8.5 16.4 8.5 17C8.5 17.6 8.1 18 7.5 18C6.9 18 6.5 17.6 6.5 17C6.5 16.4 6.9 16 7.5 16Z"
|
||||
fill="white"
|
||||
|
|
@ -229,9 +388,19 @@ const Navbar = () => {
|
|||
</span>
|
||||
Jadwal
|
||||
</Link>
|
||||
<Link href="#" className="flex text-white flex-row items-center font-medium hover:text-gray-800">
|
||||
<Link
|
||||
href="#"
|
||||
className="flex text-white flex-row items-center font-medium hover:text-gray-800"
|
||||
>
|
||||
<span>
|
||||
<svg className="mr-2" width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg
|
||||
className="mr-2"
|
||||
width="25"
|
||||
height="24"
|
||||
viewBox="0 0 25 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
|
|
@ -248,15 +417,25 @@ const Navbar = () => {
|
|||
</div>
|
||||
<div className="flex items-center space-x-1 text-yellow-600 font-medium">
|
||||
<a href="https://tvradio.polri.go.id/">
|
||||
<img src="/assets/polriTv.png" className="w-32 h-11 flex items-center" />
|
||||
<img
|
||||
src="/assets/polriTv.png"
|
||||
className="w-32 h-11 flex items-center"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<select className="w-full bg-transparent text-black border border-gray-300 py-1 px-2 rounded focus:outline-none" defaultValue="Indonesia">
|
||||
<select
|
||||
className="w-full bg-transparent text-black border border-gray-300 py-1 px-2 rounded focus:outline-none"
|
||||
defaultValue="Indonesia"
|
||||
>
|
||||
<option>Indonesia</option>
|
||||
<option>English</option>
|
||||
</select>
|
||||
<div className="px-4 py-1 w-24">
|
||||
<input type="text" placeholder="Pencarian" className="border rounded-full text-sm text-gray-600" />
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Pencarian"
|
||||
className="border rounded-full text-sm text-gray-600"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col space-y-2">
|
||||
<Link href="/auth" className="w-full px-4 py-1 bg-[#bb3523] text-white font-semibold rounded-md hover:bg-red-700 md:flex">
|
||||
|
|
|
|||
|
|
@ -1,6 +1,12 @@
|
|||
import React, { useState } from "react";
|
||||
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from "@/components/ui/carousel";
|
||||
import {
|
||||
Carousel,
|
||||
CarouselContent,
|
||||
CarouselItem,
|
||||
CarouselNext,
|
||||
CarouselPrevious,
|
||||
} from "@/components/ui/carousel";
|
||||
import Link from "next/link";
|
||||
import { useParams, usePathname, useRouter } from "next/navigation";
|
||||
import { Icon } from "@iconify/react/dist/iconify.js";
|
||||
|
|
@ -8,24 +14,128 @@ import { textEllipsis } from "@/utils/globals";
|
|||
import { generateLocalizedPath } from "@/utils/globals";
|
||||
|
||||
const dummyImage = [
|
||||
{ id: 1, thumbnail: "/assets/banner-sample.png", date: "17 MEI 2024", title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", time: "18.00 WIB" },
|
||||
{ id: 2, thumbnail: "/assets/banner-sample.png", date: "17 MEI 2024", title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", time: "18.00 WIB" },
|
||||
{ id: 3, thumbnail: "/assets/banner-sample.png", date: "17 MEI 2024", title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", time: "18.00 WIB" },
|
||||
{ id: 4, thumbnail: "/assets/banner-sample.png", date: "17 MEI 2024", title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", time: "18.00 WIB" },
|
||||
{ id: 5, thumbnail: "/assets/banner-sample.png", date: "17 MEI 2024", title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", time: "18.00 WIB" },
|
||||
{ id: 6, thumbnail: "/assets/banner-sample.png", date: "17 MEI 2024", title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", time: "18.00 WIB" },
|
||||
{ id: 7, thumbnail: "/assets/banner-sample.png", date: "17 MEI 2024", title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", time: "18.00 WIB" },
|
||||
{ id: 8, thumbnail: "/assets/banner-sample.png", date: "17 MEI 2024", title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", time: "18.00 WIB" },
|
||||
{ id: 9, thumbnail: "/assets/banner-sample.png", date: "17 MEI 2024", title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", time: "18.00 WIB" },
|
||||
{
|
||||
id: 1,
|
||||
thumbnail: "/assets/banner-sample.png",
|
||||
date: "17 MEI 2024",
|
||||
title:
|
||||
"Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait",
|
||||
time: "18.00 WIB",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
thumbnail: "/assets/banner-sample.png",
|
||||
date: "17 MEI 2024",
|
||||
title:
|
||||
"Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait",
|
||||
time: "18.00 WIB",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
thumbnail: "/assets/banner-sample.png",
|
||||
date: "17 MEI 2024",
|
||||
title:
|
||||
"Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait",
|
||||
time: "18.00 WIB",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
thumbnail: "/assets/banner-sample.png",
|
||||
date: "17 MEI 2024",
|
||||
title:
|
||||
"Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait",
|
||||
time: "18.00 WIB",
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
thumbnail: "/assets/banner-sample.png",
|
||||
date: "17 MEI 2024",
|
||||
title:
|
||||
"Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait",
|
||||
time: "18.00 WIB",
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
thumbnail: "/assets/banner-sample.png",
|
||||
date: "17 MEI 2024",
|
||||
title:
|
||||
"Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait",
|
||||
time: "18.00 WIB",
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
thumbnail: "/assets/banner-sample.png",
|
||||
date: "17 MEI 2024",
|
||||
title:
|
||||
"Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait",
|
||||
time: "18.00 WIB",
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
thumbnail: "/assets/banner-sample.png",
|
||||
date: "17 MEI 2024",
|
||||
title:
|
||||
"Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait",
|
||||
time: "18.00 WIB",
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
thumbnail: "/assets/banner-sample.png",
|
||||
date: "17 MEI 2024",
|
||||
title:
|
||||
"Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait",
|
||||
time: "18.00 WIB",
|
||||
},
|
||||
];
|
||||
|
||||
const dummyDescription = [
|
||||
{ id: 1, title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", date: "28 November 2024", time: "11.15 WIB", duration: "00:24:55" },
|
||||
{ id: 2, title: "Kapolres Lahat Himbau Cipta Kondisi Cooling System Pasca Pemungutan Suara Pilkada 2024", date: "28 November 2024", time: "11.15 WIB", duration: "00:24:55" },
|
||||
{ id: 3, title: "17 Ton Pupuk Bersubsidi yang Akan Diselewengkan ke Banyuasin Berhasil Digagalkan", date: "28 November 2024", time: "11.15 WIB", duration: "00:24:55" },
|
||||
{ id: 4, title: "Kapolda Sumsel Apelkan 1471 Personel Persiapan Pengamanan Pengawalan Tahan Pungut dan Hitung Suara", date: "28 November 2024", time: "11.15 WIB", duration: "00:24:55" },
|
||||
{ id: 5, title: "Polrestabes Palembang Berhasil Mengungkap Kasus Penganiayaan Berat di Ilir Barat II", date: "28 November 2024", time: "11.15 WIB", duration: "00:24:55" },
|
||||
{ id: 6, title: "Tahapan Pilkada di Sumsel Berlangsung Kondusif", date: "28 November 2024", time: "11.15 WIB", duration: "00:24:55" },
|
||||
{
|
||||
id: 1,
|
||||
title:
|
||||
"Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait",
|
||||
date: "28 November 2024",
|
||||
time: "11.15 WIB",
|
||||
duration: "00:24:55",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title:
|
||||
"Kapolres Lahat Himbau Cipta Kondisi Cooling System Pasca Pemungutan Suara Pilkada 2024",
|
||||
date: "28 November 2024",
|
||||
time: "11.15 WIB",
|
||||
duration: "00:24:55",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title:
|
||||
"17 Ton Pupuk Bersubsidi yang Akan Diselewengkan ke Banyuasin Berhasil Digagalkan",
|
||||
date: "28 November 2024",
|
||||
time: "11.15 WIB",
|
||||
duration: "00:24:55",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title:
|
||||
"Kapolda Sumsel Apelkan 1471 Personel Persiapan Pengamanan Pengawalan Tahan Pungut dan Hitung Suara",
|
||||
date: "28 November 2024",
|
||||
time: "11.15 WIB",
|
||||
duration: "00:24:55",
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
title:
|
||||
"Polrestabes Palembang Berhasil Mengungkap Kasus Penganiayaan Berat di Ilir Barat II",
|
||||
date: "28 November 2024",
|
||||
time: "11.15 WIB",
|
||||
duration: "00:24:55",
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
title: "Tahapan Pilkada di Sumsel Berlangsung Kondusif",
|
||||
date: "28 November 2024",
|
||||
time: "11.15 WIB",
|
||||
duration: "00:24:55",
|
||||
},
|
||||
];
|
||||
|
||||
const NewContent = () => {
|
||||
|
|
@ -102,11 +212,24 @@ const NewContent = () => {
|
|||
<Carousel>
|
||||
<CarouselContent>
|
||||
{dummyDescription.map((description) => (
|
||||
<CarouselItem key={description.id} className="md:basis-1/2 lg:basis-1/3">
|
||||
<CarouselItem
|
||||
key={description.id}
|
||||
className="md:basis-1/2 lg:basis-1/3"
|
||||
>
|
||||
<div className="flex flex-row gap-6">
|
||||
<a href="#" key={description.id} className="flex flex-col sm:flex-row items-center bg-white dark:bg-gray-800 cursor-pointer shadow-md rounded-lg p-4 gap-4 w-full">
|
||||
<a
|
||||
href="#"
|
||||
key={description.id}
|
||||
className="flex flex-col sm:flex-row items-center bg-white dark:bg-gray-800 cursor-pointer shadow-md rounded-lg p-4 gap-4 w-full"
|
||||
>
|
||||
<div className="flex items-center justify-center bg-red-500 text-white rounded-lg w-16 h-8 lg:h-16">
|
||||
<svg width="32" height="34" viewBox="0 0 32 34" fill="null" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg
|
||||
width="32"
|
||||
height="34"
|
||||
viewBox="0 0 32 34"
|
||||
fill="null"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M23.404 0.452014C23.7033 0.35857 24.0204 0.336816 24.3297 0.388509C24.639 0.440203 24.9318 0.563895 25.1845 0.749599C25.4371 0.935304 25.6426 1.17782 25.7843 1.45756C25.9259 1.73731 25.9998 2.04644 26 2.36001V14.414C25.3462 14.2296 24.6766 14.1064 24 14.046V8.36001L10 12.736V27C10 28.1264 9.6197 29.2197 8.92071 30.1029C8.22172 30.9861 7.24499 31.6075 6.14877 31.8663C5.05255 32.125 3.90107 32.0061 2.88089 31.5287C1.86071 31.0514 1.03159 30.2435 0.52787 29.2361C0.024152 28.2286 -0.124656 27.0806 0.105556 25.9781C0.335768 24.8755 0.931513 23.883 1.79627 23.1613C2.66102 22.4396 3.74413 22.031 4.87009 22.0017C5.99606 21.9724 7.09893 22.3242 8.00001 23V6.73601C7.99982 6.30956 8.13596 5.8942 8.38854 5.55059C8.64112 5.20698 8.99692 4.9531 9.40401 4.82601L23.404 0.452014ZM10 10.64L24 6.26601V2.36001L10 6.73601V10.64ZM5.00001 24C4.20436 24 3.44129 24.3161 2.87869 24.8787C2.31608 25.4413 2.00001 26.2044 2.00001 27C2.00001 27.7957 2.31608 28.5587 2.87869 29.1213C3.44129 29.6839 4.20436 30 5.00001 30C5.79566 30 6.55872 29.6839 7.12133 29.1213C7.68394 28.5587 8.00001 27.7957 8.00001 27C8.00001 26.2044 7.68394 25.4413 7.12133 24.8787C6.55872 24.3161 5.79566 24 5.00001 24ZM32 25C32 27.387 31.0518 29.6761 29.364 31.364C27.6761 33.0518 25.387 34 23 34C20.6131 34 18.3239 33.0518 16.636 31.364C14.9482 29.6761 14 27.387 14 25C14 22.6131 14.9482 20.3239 16.636 18.6361C18.3239 16.9482 20.6131 16 23 16C25.387 16 27.6761 16.9482 29.364 18.6361C31.0518 20.3239 32 22.6131 32 25ZM27.47 24.128L21.482 20.828C21.3298 20.7443 21.1583 20.7016 20.9846 20.7043C20.8108 20.707 20.6408 20.7549 20.4912 20.8433C20.3416 20.9317 20.2176 21.0576 20.1315 21.2086C20.0453 21.3595 20 21.5302 20 21.704V28.304C20 28.4778 20.0453 28.6486 20.1315 28.7995C20.2176 28.9504 20.3416 29.0763 20.4912 29.1647C20.6408 29.2531 20.8108 29.301 20.9846 29.3037C21.1583 29.3064 21.3298 29.2638 21.482 29.18L27.47 25.88C27.6268 25.7937 27.7575 25.6669 27.8486 25.5128C27.9397 25.3587 27.9877 25.183 27.9877 25.004C27.9877 24.825 27.9397 24.6493 27.8486 24.4952C27.7575 24.3412 27.6268 24.2143 27.47 24.128Z"
|
||||
fill="white"
|
||||
|
|
@ -116,9 +239,13 @@ const NewContent = () => {
|
|||
|
||||
<div className="flex flex-col flex-1">
|
||||
<div className="text-gray-500 dark:text-gray-400 flex flex-row text-sm">
|
||||
{description.date} | <Icon icon="formkit:eye" width="15" height="15" /> 518
|
||||
{description.date} |{" "}
|
||||
<Icon icon="formkit:eye" width="15" height="15" />{" "}
|
||||
518
|
||||
</div>
|
||||
<div className="font-semibold text-gray-900 dark:text-white mt-1 text-sm">
|
||||
{textEllipsis(description.title, 50)}
|
||||
</div>
|
||||
<div className="font-semibold text-gray-900 dark:text-white mt-1 text-sm">{textEllipsis(description.title, 50)}</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
|
@ -158,11 +285,23 @@ const NewContent = () => {
|
|||
<Carousel>
|
||||
<CarouselContent>
|
||||
{dummyImage.map((description) => (
|
||||
<CarouselItem key={description.id} className="md:basis-1/2 lg:basis-1/3">
|
||||
<CarouselItem
|
||||
key={description.id}
|
||||
className="md:basis-1/2 lg:basis-1/3"
|
||||
>
|
||||
<div className="md:basis-1/2 lg:basis-1/3">
|
||||
<a href="#" className="flex flex-col bg-yellow-500 sm:flex-row items-center dark:bg-gray-800 cursor-pointer shadow-md rounded-lg p-4 gap-4 w-full">
|
||||
<a
|
||||
href="#"
|
||||
className="flex flex-col bg-yellow-500 sm:flex-row items-center dark:bg-gray-800 cursor-pointer shadow-md rounded-lg p-4 gap-4 w-full"
|
||||
>
|
||||
<div className="flex items-center justify-center rounded-lg w-16 h-2 lg:h-16">
|
||||
<svg width="28" height="34" viewBox="0 0 28 34" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg
|
||||
width="28"
|
||||
height="34"
|
||||
viewBox="0 0 28 34"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M5.6665 17.4167C5.6665 17.0851 5.7982 16.7672 6.03262 16.5328C6.26704 16.2984 6.58498 16.1667 6.9165 16.1667C7.24802 16.1667 7.56597 16.2984 7.80039 16.5328C8.03481 16.7672 8.1665 17.0851 8.1665 17.4167C8.1665 17.7482 8.03481 18.0661 7.80039 18.3005C7.56597 18.535 7.24802 18.6667 6.9165 18.6667C6.58498 18.6667 6.26704 18.535 6.03262 18.3005C5.7982 18.0661 5.6665 17.7482 5.6665 17.4167ZM6.9165 21.1667C6.58498 21.1667 6.26704 21.2984 6.03262 21.5328C5.7982 21.7672 5.6665 22.0851 5.6665 22.4167C5.6665 22.7482 5.7982 23.0661 6.03262 23.3005C6.26704 23.535 6.58498 23.6667 6.9165 23.6667C7.24802 23.6667 7.56597 23.535 7.80039 23.3005C8.03481 23.0661 8.1665 22.7482 8.1665 22.4167C8.1665 22.0851 8.03481 21.7672 7.80039 21.5328C7.56597 21.2984 7.24802 21.1667 6.9165 21.1667ZM5.6665 27.4167C5.6665 27.0851 5.7982 26.7672 6.03262 26.5328C6.26704 26.2984 6.58498 26.1667 6.9165 26.1667C7.24802 26.1667 7.56597 26.2984 7.80039 26.5328C8.03481 26.7672 8.1665 27.0851 8.1665 27.4167C8.1665 27.7482 8.03481 28.0661 7.80039 28.3005C7.56597 28.535 7.24802 28.6667 6.9165 28.6667C6.58498 28.6667 6.26704 28.535 6.03262 28.3005C5.7982 28.0661 5.6665 27.7482 5.6665 27.4167ZM11.9165 16.1667C11.585 16.1667 11.267 16.2984 11.0326 16.5328C10.7982 16.7672 10.6665 17.0851 10.6665 17.4167C10.6665 17.7482 10.7982 18.0661 11.0326 18.3005C11.267 18.535 11.585 18.6667 11.9165 18.6667H21.0832C21.4147 18.6667 21.7326 18.535 21.9671 18.3005C22.2015 18.0661 22.3332 17.7482 22.3332 17.4167C22.3332 17.0851 22.2015 16.7672 21.9671 16.5328C21.7326 16.2984 21.4147 16.1667 21.0832 16.1667H11.9165ZM10.6665 22.4167C10.6665 22.0851 10.7982 21.7672 11.0326 21.5328C11.267 21.2984 11.585 21.1667 11.9165 21.1667H21.0832C21.4147 21.1667 21.7326 21.2984 21.9671 21.5328C22.2015 21.7672 22.3332 22.0851 22.3332 22.4167C22.3332 22.7482 22.2015 23.0661 21.9671 23.3005C21.7326 23.535 21.4147 23.6667 21.0832 23.6667H11.9165C11.585 23.6667 11.267 23.535 11.0326 23.3005C10.7982 23.0661 10.6665 22.7482 10.6665 22.4167ZM11.9165 26.1667C11.585 26.1667 11.267 26.2984 11.0326 26.5328C10.7982 26.7672 10.6665 27.0851 10.6665 27.4167C10.6665 27.7482 10.7982 28.0661 11.0326 28.3005C11.267 28.535 11.585 28.6667 11.9165 28.6667H21.0832C21.4147 28.6667 21.7326 28.535 21.9671 28.3005C22.2015 28.0661 22.3332 27.7482 22.3332 27.4167C22.3332 27.0851 22.2015 26.7672 21.9671 26.5328C21.7326 26.2984 21.4147 26.1667 21.0832 26.1667H11.9165ZM26.3565 11.0233L16.6415 1.31C16.6157 1.28605 16.5885 1.26378 16.5598 1.24333C16.5392 1.22742 16.5192 1.21074 16.4998 1.19333C16.3852 1.08512 16.2632 0.984882 16.1348 0.893332C16.0922 0.865802 16.0476 0.841298 16.0015 0.819999L15.9215 0.779999L15.8382 0.731666C15.7482 0.679999 15.6565 0.626665 15.5615 0.586665C15.2296 0.454104 14.8783 0.376423 14.5215 0.356665C14.4885 0.354519 14.4557 0.350625 14.4232 0.344999C14.3779 0.338012 14.3323 0.334114 14.2865 0.333332H3.99984C3.11578 0.333332 2.26794 0.684521 1.64281 1.30964C1.01769 1.93476 0.666504 2.78261 0.666504 3.66667V30.3333C0.666504 31.2174 1.01769 32.0652 1.64281 32.6904C2.26794 33.3155 3.11578 33.6667 3.99984 33.6667H23.9998C24.8839 33.6667 25.7317 33.3155 26.3569 32.6904C26.982 32.0652 27.3332 31.2174 27.3332 30.3333V13.38C27.333 12.496 26.9817 11.6483 26.3565 11.0233ZM24.8332 30.3333C24.8332 30.5543 24.7454 30.7663 24.5891 30.9226C24.4328 31.0789 24.2208 31.1667 23.9998 31.1667H3.99984C3.77882 31.1667 3.56686 31.0789 3.41058 30.9226C3.2543 30.7663 3.1665 30.5543 3.1665 30.3333V3.66667C3.1665 3.44565 3.2543 3.23369 3.41058 3.07741C3.56686 2.92113 3.77882 2.83333 3.99984 2.83333H13.9998V10.3333C13.9998 11.2174 14.351 12.0652 14.9761 12.6904C15.6013 13.3155 16.4491 13.6667 17.3332 13.6667H24.8332V30.3333ZM16.4998 4.70166L22.9632 11.1667H17.3332C17.1122 11.1667 16.9002 11.0789 16.7439 10.9226C16.5876 10.7663 16.4998 10.5543 16.4998 10.3333V4.70166Z"
|
||||
fill="black"
|
||||
|
|
@ -172,12 +311,24 @@ const NewContent = () => {
|
|||
|
||||
<div className="flex flex-col flex-1">
|
||||
<div className="text-gray-500 dark:text-gray-400 flex flex-row text-sm">
|
||||
{description.date} | <Icon icon="formkit:eye" width="15" height="15" /> 518
|
||||
{description.date} |{" "}
|
||||
<Icon icon="formkit:eye" width="15" height="15" />{" "}
|
||||
518
|
||||
</div>
|
||||
<div className="font-semibold text-gray-900 dark:text-white mt-1 text-sm">
|
||||
{textEllipsis(description.title, 50)}
|
||||
</div>
|
||||
<div className="font-semibold text-gray-900 dark:text-white mt-1 text-sm">{textEllipsis(description.title, 50)}</div>
|
||||
<div className="flex gap-2 items-center text-sm text-red-500 dark:text-red-500">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 512 512">
|
||||
<path fill="#f00" d="M224 30v256h-64l96 128l96-128h-64V30zM32 434v48h448v-48z" />
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="1em"
|
||||
height="1em"
|
||||
viewBox="0 0 512 512"
|
||||
>
|
||||
<path
|
||||
fill="#f00"
|
||||
d="M224 30v256h-64l96 128l96-128h-64V30zM32 434v48h448v-48z"
|
||||
/>
|
||||
</svg>
|
||||
Download Dokumen
|
||||
</div>
|
||||
|
|
@ -194,7 +345,10 @@ const NewContent = () => {
|
|||
</div>
|
||||
</div>
|
||||
<div className="flex items-center flex-row justify-center">
|
||||
<Link href="#" className="border text-[#bb3523] text-sm lg:text-md px-4 py-1 border-[#bb3523]">
|
||||
<Link
|
||||
href="#"
|
||||
className="border text-[#bb3523] text-sm lg:text-md px-4 py-1 border-[#bb3523]"
|
||||
>
|
||||
LIHAT SEMUA
|
||||
</Link>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -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,23 +123,24 @@ export async function getAPIInterceptor(url: any) {
|
|||
data: null,
|
||||
};
|
||||
}
|
||||
|
||||
export async function postAPIInterceptor(url: any, data: any) {
|
||||
// Fungsi postAPIInterceptor
|
||||
export async function postAPIInterceptor(url: string, data: any) {
|
||||
const response = await axiosInterceptor
|
||||
.post(url, data)
|
||||
.catch((error) => error.response);
|
||||
if (response?.status == 401) {
|
||||
|
||||
if (response?.status === 401) {
|
||||
Object.keys(Cookies.get()).forEach((cookieName) => {
|
||||
Cookies.remove(cookieName);
|
||||
});
|
||||
window.location.href = "/";
|
||||
} else if (response?.status > 300 && response?.status != 401) {
|
||||
} else if (response?.status > 300 && response?.status !== 401) {
|
||||
return {
|
||||
error: true,
|
||||
message: response?.data?.message,
|
||||
data: null,
|
||||
};
|
||||
} else if (response?.data.success) {
|
||||
} else if (response?.data?.success) {
|
||||
return {
|
||||
error: false,
|
||||
message: "success",
|
||||
|
|
@ -149,11 +150,17 @@ export async function postAPIInterceptor(url: any, data: any) {
|
|||
|
||||
return {
|
||||
error: true,
|
||||
message: response?.data.message,
|
||||
message: response?.data?.message,
|
||||
data: null,
|
||||
};
|
||||
}
|
||||
|
||||
// Fungsi createTask
|
||||
export async function createTask(data: any) {
|
||||
const url = "assignment";
|
||||
return postAPIInterceptor(url, data); // Perbaikan: Memisahkan parameter url dan data
|
||||
}
|
||||
|
||||
export async function deleteAPIInterceptor(url: any, data: any) {
|
||||
const response = await axiosInterceptor
|
||||
.delete(url, { data })
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ export function getMenuList(pathname: string, t: any): Group[] {
|
|||
menus: [
|
||||
{
|
||||
id: "dashboard",
|
||||
href: "/dashboard/tabs",
|
||||
href: "/dashboard",
|
||||
label: t("dashboard"),
|
||||
active: pathname.includes("/dashboard"),
|
||||
icon: "material-symbols:dashboard",
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
});
|
||||
}
|
||||
97
lib/utils.ts
97
lib/utils.ts
|
|
@ -1,10 +1,29 @@
|
|||
import { type ClassValue, clsx } from "clsx"
|
||||
import { twMerge } from "tailwind-merge"
|
||||
import { type ClassValue, clsx } from "clsx";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
import Cookies from "js-cookie";
|
||||
import CryptoJS from "crypto-js";
|
||||
import Swal from "sweetalert2";
|
||||
import withReactContent from "sweetalert2-react-content";
|
||||
import Loading from "@/app/[locale]/(protected)/app/projects/loading";
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs))
|
||||
return twMerge(clsx(inputs));
|
||||
}
|
||||
|
||||
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 const hexToRGB = (hex: any, alpha?: number): any => {
|
||||
const r = parseInt(hex.slice(1, 3), 16);
|
||||
const g = parseInt(hex.slice(3, 5), 16);
|
||||
|
|
@ -15,4 +34,74 @@ export const hexToRGB = (hex: any, alpha?: number): any => {
|
|||
} else {
|
||||
return `rgb(${r}, ${g}, ${b})`;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
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");
|
||||
if (
|
||||
(Number(roleId) !== 3 &&
|
||||
Number(roleId) !== 4 &&
|
||||
Number(roleId) !== 11 &&
|
||||
Number(roleId) !== 12 &&
|
||||
Number(roleId) !== 2) ||
|
||||
roleId == undefined
|
||||
) {
|
||||
console.log("Wrong Authentication");
|
||||
window.location.href = "/";
|
||||
} else if (page == "admin" && Number(levelNumber) !== 1) {
|
||||
console.log("Wrong Authentication Admin");
|
||||
window.location.href = "/";
|
||||
}
|
||||
}
|
||||
|
||||
export function checkLoginSession() {
|
||||
const userId = getCookiesDecrypt("uie");
|
||||
const jwt = Cookies.get("access_token");
|
||||
const data = {
|
||||
userId,
|
||||
jwt,
|
||||
};
|
||||
// doCheckSession(data);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,8 +54,10 @@
|
|||
"@south-paw/react-vector-maps": "^3.2.0",
|
||||
"@tanstack/react-table": "^8.19.2",
|
||||
"@types/cleave.js": "^1.4.12",
|
||||
"@types/crypto-js": "^4.2.2",
|
||||
"@types/js-cookie": "^3.0.6",
|
||||
"@types/qs": "^6.9.17",
|
||||
"@types/react-google-recaptcha": "^2.1.9",
|
||||
"@types/react-syntax-highlighter": "^15.5.13",
|
||||
"@vercel/analytics": "^1.3.1",
|
||||
"apexcharts": "^3.49.2",
|
||||
|
|
@ -66,6 +68,7 @@
|
|||
"clsx": "^2.1.1",
|
||||
"cmdk": "^1.0.0",
|
||||
"cookie": "^1.0.2",
|
||||
"crypto-js": "^4.2.0",
|
||||
"date-fns": "^3.6.0",
|
||||
"dayjs": "^1.11.11",
|
||||
"embla-carousel-autoplay": "^8.1.3",
|
||||
|
|
@ -107,7 +110,7 @@
|
|||
"react-quill": "^0.0.2",
|
||||
"react-resizable-panels": "^2.0.19",
|
||||
"react-responsive": "^10.0.0",
|
||||
"react-select": "^5.8.0",
|
||||
"react-select": "^5.8.3",
|
||||
"react-slick": "^0.30.2",
|
||||
"react-syntax-highlighter": "^15.5.0",
|
||||
"react-time-picker": "^7.0.0",
|
||||
|
|
@ -145,6 +148,7 @@
|
|||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
|
||||
"integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
|
|
@ -1209,6 +1213,7 @@
|
|||
"version": "8.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
|
||||
"integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"string-width": "^5.1.2",
|
||||
"string-width-cjs": "npm:string-width@^4.2.0",
|
||||
|
|
@ -1225,6 +1230,7 @@
|
|||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
|
||||
"integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
|
|
@ -1236,6 +1242,7 @@
|
|||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
|
||||
"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-regex": "^6.0.1"
|
||||
},
|
||||
|
|
@ -1766,6 +1773,7 @@
|
|||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||
"integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@nodelib/fs.stat": "2.0.5",
|
||||
"run-parallel": "^1.1.9"
|
||||
|
|
@ -1778,6 +1786,7 @@
|
|||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
|
||||
"integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
|
|
@ -1786,6 +1795,7 @@
|
|||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
|
||||
"integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@nodelib/fs.scandir": "2.1.5",
|
||||
"fastq": "^1.6.0"
|
||||
|
|
@ -1815,6 +1825,7 @@
|
|||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
|
||||
"integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
|
|
@ -3446,6 +3457,11 @@
|
|||
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
|
||||
"integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA=="
|
||||
},
|
||||
"node_modules/@types/crypto-js": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.2.2.tgz",
|
||||
"integrity": "sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ=="
|
||||
},
|
||||
"node_modules/@types/d3-array": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz",
|
||||
|
|
@ -3639,7 +3655,7 @@
|
|||
"version": "18.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.1.tgz",
|
||||
"integrity": "sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
|
|
@ -3650,6 +3666,14 @@
|
|||
"integrity": "sha512-vkDID5kZwYRplECuUtAbPnRN9XyrzE+9lxl0VBV+h7pFDOc6hn+0xieswO7Wrzne/J9HstA3Nlb6OeMuuQxjuw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/react-google-recaptcha": {
|
||||
"version": "2.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-google-recaptcha/-/react-google-recaptcha-2.1.9.tgz",
|
||||
"integrity": "sha512-nT31LrBDuoSZJN4QuwtQSF3O89FVHC4jLhM+NtKEmVF5R1e8OY0Jo4//x2Yapn2aNHguwgX5doAq8Zo+Ehd0ug==",
|
||||
"dependencies": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react-syntax-highlighter": {
|
||||
"version": "15.5.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-15.5.13.tgz",
|
||||
|
|
@ -3916,6 +3940,7 @@
|
|||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
|
|
@ -3929,6 +3954,7 @@
|
|||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1"
|
||||
},
|
||||
|
|
@ -3942,12 +3968,14 @@
|
|||
"node_modules/any-promise": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
|
||||
"integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="
|
||||
"integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/anymatch": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
|
||||
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"normalize-path": "^3.0.0",
|
||||
"picomatch": "^2.0.4"
|
||||
|
|
@ -3992,7 +4020,8 @@
|
|||
"node_modules/arg": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
|
||||
"integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="
|
||||
"integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/argparse": {
|
||||
"version": "2.0.1",
|
||||
|
|
@ -4283,12 +4312,14 @@
|
|||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/binary-extensions": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
|
||||
"integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
|
|
@ -4310,6 +4341,7 @@
|
|||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fill-range": "^7.1.1"
|
||||
},
|
||||
|
|
@ -4358,6 +4390,7 @@
|
|||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
|
||||
"integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
|
|
@ -4457,6 +4490,7 @@
|
|||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
|
||||
"integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"anymatch": "~3.1.2",
|
||||
"braces": "~3.0.2",
|
||||
|
|
@ -4480,6 +4514,7 @@
|
|||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-glob": "^4.0.1"
|
||||
},
|
||||
|
|
@ -4664,6 +4699,7 @@
|
|||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"path-key": "^3.1.0",
|
||||
"shebang-command": "^2.0.0",
|
||||
|
|
@ -4673,6 +4709,11 @@
|
|||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/crypto-js": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
|
||||
"integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="
|
||||
},
|
||||
"node_modules/css-mediaquery": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/css-mediaquery/-/css-mediaquery-0.1.2.tgz",
|
||||
|
|
@ -4682,6 +4723,7 @@
|
|||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
|
||||
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"cssesc": "bin/cssesc"
|
||||
},
|
||||
|
|
@ -5344,7 +5386,8 @@
|
|||
"node_modules/didyoumean": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
|
||||
"integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw=="
|
||||
"integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/diff": {
|
||||
"version": "5.2.0",
|
||||
|
|
@ -5369,7 +5412,8 @@
|
|||
"node_modules/dlv": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
|
||||
"integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="
|
||||
"integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/doctrine": {
|
||||
"version": "3.0.0",
|
||||
|
|
@ -5457,7 +5501,8 @@
|
|||
"node_modules/eastasianwidth": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
|
||||
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
|
||||
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/elkjs": {
|
||||
"version": "0.9.3",
|
||||
|
|
@ -5505,7 +5550,8 @@
|
|||
"node_modules/emoji-regex": {
|
||||
"version": "9.2.2",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
|
||||
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="
|
||||
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/enhanced-resolve": {
|
||||
"version": "5.17.1",
|
||||
|
|
@ -6348,6 +6394,7 @@
|
|||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
|
||||
"integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@nodelib/fs.stat": "^2.0.2",
|
||||
"@nodelib/fs.walk": "^1.2.3",
|
||||
|
|
@ -6363,6 +6410,7 @@
|
|||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-glob": "^4.0.1"
|
||||
},
|
||||
|
|
@ -6386,6 +6434,7 @@
|
|||
"version": "1.17.1",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
|
||||
"integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"reusify": "^1.0.4"
|
||||
}
|
||||
|
|
@ -6429,6 +6478,7 @@
|
|||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
},
|
||||
|
|
@ -6519,6 +6569,7 @@
|
|||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
|
||||
"integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"cross-spawn": "^7.0.0",
|
||||
"signal-exit": "^4.0.1"
|
||||
|
|
@ -6739,6 +6790,7 @@
|
|||
"version": "10.3.10",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz",
|
||||
"integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"foreground-child": "^3.1.0",
|
||||
"jackspeak": "^2.3.5",
|
||||
|
|
@ -6760,6 +6812,7 @@
|
|||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
|
||||
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-glob": "^4.0.3"
|
||||
},
|
||||
|
|
@ -6771,6 +6824,7 @@
|
|||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
|
|
@ -6779,6 +6833,7 @@
|
|||
"version": "9.0.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
|
||||
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
|
|
@ -7745,6 +7800,7 @@
|
|||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
|
||||
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"binary-extensions": "^2.0.0"
|
||||
},
|
||||
|
|
@ -7876,6 +7932,7 @@
|
|||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
|
|
@ -7899,6 +7956,7 @@
|
|||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
|
|
@ -7922,6 +7980,7 @@
|
|||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-extglob": "^2.1.1"
|
||||
},
|
||||
|
|
@ -7966,6 +8025,7 @@
|
|||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.12.0"
|
||||
}
|
||||
|
|
@ -8214,6 +8274,7 @@
|
|||
"version": "2.3.6",
|
||||
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz",
|
||||
"integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@isaacs/cliui": "^8.0.2"
|
||||
},
|
||||
|
|
@ -8231,6 +8292,7 @@
|
|||
"version": "1.21.6",
|
||||
"resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz",
|
||||
"integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"jiti": "bin/jiti.js"
|
||||
}
|
||||
|
|
@ -8592,7 +8654,8 @@
|
|||
"node_modules/lru-cache": {
|
||||
"version": "10.4.3",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
|
||||
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="
|
||||
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/lucide-react": {
|
||||
"version": "0.390.0",
|
||||
|
|
@ -9306,6 +9369,7 @@
|
|||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
||||
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
|
|
@ -10093,6 +10157,7 @@
|
|||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
|
||||
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"braces": "^3.0.3",
|
||||
"picomatch": "^2.3.1"
|
||||
|
|
@ -10153,6 +10218,7 @@
|
|||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
|
||||
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
}
|
||||
|
|
@ -10201,6 +10267,7 @@
|
|||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
|
||||
"integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"any-promise": "^1.0.0",
|
||||
"object-assign": "^4.0.1",
|
||||
|
|
@ -10495,6 +10562,7 @@
|
|||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
|
|
@ -10549,6 +10617,7 @@
|
|||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
|
||||
"integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
|
|
@ -10847,6 +10916,7 @@
|
|||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
||||
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
|
|
@ -10860,6 +10930,7 @@
|
|||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
|
||||
"integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"lru-cache": "^10.2.0",
|
||||
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
|
||||
|
|
@ -10898,6 +10969,7 @@
|
|||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8.6"
|
||||
},
|
||||
|
|
@ -10909,6 +10981,7 @@
|
|||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
|
||||
"integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
|
|
@ -10917,6 +10990,7 @@
|
|||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
|
||||
"integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
|
|
@ -10934,6 +11008,7 @@
|
|||
"version": "8.4.49",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
|
||||
"integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
|
|
@ -10961,6 +11036,7 @@
|
|||
"version": "15.1.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
|
||||
"integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"postcss-value-parser": "^4.0.0",
|
||||
"read-cache": "^1.0.0",
|
||||
|
|
@ -10977,6 +11053,7 @@
|
|||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz",
|
||||
"integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"camelcase-css": "^2.0.1"
|
||||
},
|
||||
|
|
@ -10995,6 +11072,7 @@
|
|||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz",
|
||||
"integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
|
|
@ -11029,6 +11107,7 @@
|
|||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.1.tgz",
|
||||
"integrity": "sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"yaml": "bin.mjs"
|
||||
},
|
||||
|
|
@ -11040,6 +11119,7 @@
|
|||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz",
|
||||
"integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
|
|
@ -11064,6 +11144,7 @@
|
|||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
|
||||
"integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"cssesc": "^3.0.0",
|
||||
"util-deprecate": "^1.0.2"
|
||||
|
|
@ -11075,7 +11156,8 @@
|
|||
"node_modules/postcss-value-parser": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
|
||||
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
|
||||
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/preact": {
|
||||
"version": "10.12.1",
|
||||
|
|
@ -11180,6 +11262,7 @@
|
|||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
|
|
@ -11691,6 +11774,7 @@
|
|||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
||||
"integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"pify": "^2.3.0"
|
||||
}
|
||||
|
|
@ -11699,6 +11783,7 @@
|
|||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"picomatch": "^2.2.1"
|
||||
},
|
||||
|
|
@ -12120,6 +12205,7 @@
|
|||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
||||
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"iojs": ">=1.0.0",
|
||||
"node": ">=0.10.0"
|
||||
|
|
@ -12192,6 +12278,7 @@
|
|||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
|
||||
"integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
|
|
@ -12383,6 +12470,7 @@
|
|||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"shebang-regex": "^3.0.0"
|
||||
},
|
||||
|
|
@ -12394,6 +12482,7 @@
|
|||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
||||
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
|
|
@ -12430,6 +12519,7 @@
|
|||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
|
||||
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
|
|
@ -12559,6 +12649,7 @@
|
|||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
|
||||
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"eastasianwidth": "^0.2.0",
|
||||
"emoji-regex": "^9.2.2",
|
||||
|
|
@ -12576,6 +12667,7 @@
|
|||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
|
|
@ -12588,12 +12680,14 @@
|
|||
"node_modules/string-width-cjs/node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/string-width/node_modules/ansi-regex": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
|
||||
"integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
|
|
@ -12605,6 +12699,7 @@
|
|||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
|
||||
"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-regex": "^6.0.1"
|
||||
},
|
||||
|
|
@ -12740,6 +12835,7 @@
|
|||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
|
|
@ -12752,6 +12848,7 @@
|
|||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
|
|
@ -12856,6 +12953,7 @@
|
|||
"version": "3.35.0",
|
||||
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
|
||||
"integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/gen-mapping": "^0.3.2",
|
||||
"commander": "^4.0.0",
|
||||
|
|
@ -12877,6 +12975,7 @@
|
|||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
|
||||
"integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
|
|
@ -13109,6 +13208,7 @@
|
|||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
|
||||
"integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"any-promise": "^1.0.0"
|
||||
}
|
||||
|
|
@ -13117,6 +13217,7 @@
|
|||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
|
||||
"integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"thenify": ">= 3.1.0 < 4"
|
||||
},
|
||||
|
|
@ -13224,6 +13325,7 @@
|
|||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-number": "^7.0.0"
|
||||
},
|
||||
|
|
@ -13281,7 +13383,8 @@
|
|||
"node_modules/ts-interface-checker": {
|
||||
"version": "0.1.13",
|
||||
"resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
|
||||
"integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="
|
||||
"integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/tsconfig-paths": {
|
||||
"version": "3.15.0",
|
||||
|
|
@ -13760,7 +13863,8 @@
|
|||
"node_modules/util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/uuid": {
|
||||
"version": "9.0.1",
|
||||
|
|
@ -13999,6 +14103,7 @@
|
|||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"isexe": "^2.0.0"
|
||||
},
|
||||
|
|
@ -14105,6 +14210,7 @@
|
|||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
|
||||
"integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^6.1.0",
|
||||
"string-width": "^5.0.1",
|
||||
|
|
@ -14122,6 +14228,7 @@
|
|||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
|
|
@ -14137,12 +14244,14 @@
|
|||
"node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/wrap-ansi-cjs/node_modules/string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
|
|
@ -14156,6 +14265,7 @@
|
|||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
|
||||
"integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
|
|
@ -14167,6 +14277,7 @@
|
|||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
|
||||
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
|
|
@ -14178,6 +14289,7 @@
|
|||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
|
||||
"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-regex": "^6.0.1"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -55,8 +55,10 @@
|
|||
"@south-paw/react-vector-maps": "^3.2.0",
|
||||
"@tanstack/react-table": "^8.19.2",
|
||||
"@types/cleave.js": "^1.4.12",
|
||||
"@types/crypto-js": "^4.2.2",
|
||||
"@types/js-cookie": "^3.0.6",
|
||||
"@types/qs": "^6.9.17",
|
||||
"@types/react-google-recaptcha": "^2.1.9",
|
||||
"@types/react-syntax-highlighter": "^15.5.13",
|
||||
"@vercel/analytics": "^1.3.1",
|
||||
"apexcharts": "^3.49.2",
|
||||
|
|
@ -67,6 +69,7 @@
|
|||
"clsx": "^2.1.1",
|
||||
"cmdk": "^1.0.0",
|
||||
"cookie": "^1.0.2",
|
||||
"crypto-js": "^4.2.0",
|
||||
"date-fns": "^3.6.0",
|
||||
"dayjs": "^1.11.11",
|
||||
"embla-carousel-autoplay": "^8.1.3",
|
||||
|
|
@ -108,7 +111,7 @@
|
|||
"react-quill": "^0.0.2",
|
||||
"react-resizable-panels": "^2.0.19",
|
||||
"react-responsive": "^10.0.0",
|
||||
"react-select": "^5.8.0",
|
||||
"react-select": "^5.8.3",
|
||||
"react-slick": "^0.30.2",
|
||||
"react-syntax-highlighter": "^15.5.0",
|
||||
"react-time-picker": "^7.0.0",
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 332 KiB |
|
|
@ -0,0 +1,103 @@
|
|||
<svg width="717" height="644" viewBox="0 0 717 644" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<mask id="mask0_5413_6301" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="717" height="652">
|
||||
<line x1="2.5" y1="651.047" x2="2.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="10.5" y1="651.047" x2="10.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="18.5" y1="651.047" x2="18.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="26.5" y1="651.047" x2="26.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="34.5" y1="651.047" x2="34.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="42.5" y1="651.047" x2="42.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="50.5" y1="651.047" x2="50.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="58.5" y1="651.047" x2="58.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="66.5" y1="651.047" x2="66.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="74.5" y1="651.047" x2="74.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="82.5" y1="651.047" x2="82.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="90.5" y1="651.047" x2="90.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="98.5" y1="651.047" x2="98.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="106.5" y1="651.047" x2="106.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="114.5" y1="651.047" x2="114.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="122.5" y1="651.047" x2="122.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="130.5" y1="651.047" x2="130.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="138.5" y1="651.047" x2="138.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="146.5" y1="651.047" x2="146.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="154.5" y1="651.047" x2="154.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="162.5" y1="651.047" x2="162.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="170.5" y1="651.047" x2="170.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="178.5" y1="651.047" x2="178.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="186.5" y1="651.047" x2="186.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="194.5" y1="651.047" x2="194.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="202.5" y1="651.047" x2="202.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="210.5" y1="651.047" x2="210.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="218.5" y1="651.047" x2="218.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="226.5" y1="651.047" x2="226.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="234.5" y1="651.047" x2="234.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="242.5" y1="651.047" x2="242.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="250.5" y1="651.047" x2="250.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="258.5" y1="651.047" x2="258.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="266.5" y1="651.047" x2="266.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="274.5" y1="651.047" x2="274.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="282.5" y1="651.047" x2="282.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="290.5" y1="651.047" x2="290.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="298.5" y1="651.047" x2="298.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="306.5" y1="651.047" x2="306.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="314.5" y1="651.047" x2="314.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="322.5" y1="651.047" x2="322.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="330.5" y1="651.047" x2="330.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="338.5" y1="651.047" x2="338.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="346.5" y1="651.047" x2="346.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="354.5" y1="651.047" x2="354.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="362.5" y1="651.047" x2="362.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="370.5" y1="651.047" x2="370.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="378.5" y1="651.047" x2="378.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="386.5" y1="651.047" x2="386.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="394.5" y1="651.047" x2="394.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="402.5" y1="651.047" x2="402.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="410.5" y1="651.047" x2="410.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="418.5" y1="651.047" x2="418.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="426.5" y1="651.047" x2="426.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="434.5" y1="651.047" x2="434.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="442.5" y1="651.047" x2="442.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="450.5" y1="651.047" x2="450.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="458.5" y1="651.047" x2="458.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="466.5" y1="651.047" x2="466.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="474.5" y1="651.047" x2="474.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="482.5" y1="651.047" x2="482.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="490.5" y1="651.047" x2="490.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="498.5" y1="651.047" x2="498.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="506.5" y1="651.047" x2="506.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="514.5" y1="651.047" x2="514.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="522.5" y1="651.047" x2="522.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="530.5" y1="651.047" x2="530.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="538.5" y1="651.047" x2="538.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="546.5" y1="651.047" x2="546.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="554.5" y1="651.047" x2="554.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="562.5" y1="651.047" x2="562.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="570.5" y1="651.047" x2="570.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="578.5" y1="651.047" x2="578.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="586.5" y1="651.047" x2="586.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="594.5" y1="651.047" x2="594.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="602.5" y1="651.047" x2="602.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="610.5" y1="651.047" x2="610.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="618.5" y1="651.047" x2="618.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="626.5" y1="651.047" x2="626.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="634.5" y1="651.047" x2="634.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="642.5" y1="651.047" x2="642.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="650.5" y1="651.047" x2="650.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="658.5" y1="651.047" x2="658.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="666.5" y1="651.047" x2="666.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="674.5" y1="651.047" x2="674.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="682.5" y1="651.047" x2="682.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="690.5" y1="651.047" x2="690.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="698.5" y1="651.047" x2="698.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="706.5" y1="651.047" x2="706.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
<line x1="714.5" y1="651.047" x2="714.5" y2="0.954285" stroke="black" stroke-width="4"/>
|
||||
</mask>
|
||||
<g mask="url(#mask0_5413_6301)">
|
||||
<path d="M54.5008 225.366V381.119H18.2463H-8V643.953H717V381.119H656V288.006V215.208H618V260.918V288.006H579.129V355.724H560.626V172.883L549.883 164.419V128.866H543.915V164.419L530.784 172.883V355.724L499.748 335.409V100.086H414.996V335.409H378V260.918H324.275V225.366H258.622V30.6738H168V381.119H112.992V240.602H85.5368V172.883L54.5008 225.366Z" fill="url(#paint0_linear_5413_6301)"/>
|
||||
</g>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_5413_6301" x1="354" y1="348.689" x2="354.78" y2="741.493" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#8B8686"/>
|
||||
<stop offset="1" stop-color="#1B1A1A" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.7 KiB |
|
|
@ -0,0 +1,32 @@
|
|||
import Cookies from "js-cookie";
|
||||
|
||||
import { getAPI, postAPI, postAPIWithJson } from "../config/api";
|
||||
import { getAPIDummy } from "./http-config/axiosCustom";
|
||||
|
||||
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: any) {
|
||||
const url = "users/info";
|
||||
return getAPI(url, token);
|
||||
}
|
||||
|
||||
// export async function setLogin(data: any) {
|
||||
// const pathUrl = `signin`;
|
||||
// const headers = {
|
||||
// "content-type": "application/json",
|
||||
// };
|
||||
// return await httpPost(pathUrl, headers, data);
|
||||
// }
|
||||
|
||||
export async function userInfo(token: any) {
|
||||
const pathUrl = `users/info`;
|
||||
return await httpGetInterceptorWithToken(pathUrl, token);
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import { title } from "process";
|
||||
import { httpGetInterceptor } from "../http-config/http-interceptor-service";
|
||||
|
||||
export async function paginationBlog(size: number, page: number) {
|
||||
return await httpGetInterceptor(
|
||||
`blog/pagination?enablePage=1&page=${page}&size=${size}`
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
import { getAPIInterceptor } from "@/config/api";
|
||||
import {
|
||||
httpGetInterceptor,
|
||||
httpPostInterceptor,
|
||||
} from "../http-config/http-interceptor-service";
|
||||
|
||||
export async function listTicketingInternal(page: number) {
|
||||
return await httpGetInterceptor(
|
||||
`ticketing/internal/pagination?enablePage=1&size=10&page=${page}`
|
||||
);
|
||||
}
|
||||
|
||||
export async function getCuratorUser() {
|
||||
return await httpGetInterceptor("users/collaboration?enablePage=0");
|
||||
}
|
||||
|
||||
export async function getTicketingPriority() {
|
||||
return await httpGetInterceptor("ticketing/priority");
|
||||
}
|
||||
|
||||
export async function saveTicketingInternal(data: any) {
|
||||
const url = "ticketing/internal";
|
||||
return httpPostInterceptor(url, data);
|
||||
}
|
||||
|
||||
export async function saveTicketing(data: any) {
|
||||
const url = "ticketing";
|
||||
return httpPostInterceptor(url, data);
|
||||
}
|
||||
|
|
@ -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}`
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
import {
|
||||
httpGetInterceptor,
|
||||
httpPostInterceptor,
|
||||
} from "../http-config/http-interceptor-service";
|
||||
|
||||
export async function listContest(size: number, page: number) {
|
||||
return await httpGetInterceptor(
|
||||
`contest/pagination?enablePage=1&size=${size}&page=${page}`
|
||||
);
|
||||
}
|
||||
|
||||
export async function createTask(data: any) {
|
||||
const url = "assignment";
|
||||
return httpPostInterceptor(url, data);
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import axios from "axios";
|
||||
|
||||
const baseURL = "https://netidhub.com/api/";
|
||||
|
||||
const axiosBaseInstance = axios.create({
|
||||
baseURL,
|
||||
headers: {
|
||||
"content-type": "application/json",
|
||||
},
|
||||
});
|
||||
|
||||
export default axiosBaseInstance;
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
import axios from "axios";
|
||||
import Cookies from "js-cookie";
|
||||
import { login } from "../login-services";
|
||||
|
||||
const baseURL = "https://netidhub.com/api/";
|
||||
|
||||
const refreshToken = Cookies.get("refresh_token");
|
||||
|
||||
const axiosInterceptorInstance = axios.create({
|
||||
baseURL,
|
||||
headers: {
|
||||
"content-type": "application/json",
|
||||
},
|
||||
});
|
||||
|
||||
// Request interceptor
|
||||
axiosInterceptorInstance.interceptors.request.use(
|
||||
(config) => {
|
||||
console.log("Config interceptor : ", config);
|
||||
const accessToken = Cookies.get("access_token");
|
||||
if (accessToken) {
|
||||
if (config.headers)
|
||||
config.headers.Authorization = "Bearer " + accessToken;
|
||||
}
|
||||
return config;
|
||||
},
|
||||
(error) => {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
// Response interceptor
|
||||
axiosInterceptorInstance.interceptors.response.use(
|
||||
(response) => {
|
||||
return response;
|
||||
},
|
||||
async function (error) {
|
||||
const originalRequest = error.config;
|
||||
if (error.response.status === 401 && !originalRequest._retry) {
|
||||
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) {
|
||||
Cookies.set("access_token", res.data.data.access_token);
|
||||
Cookies.set("refresh_token", res.data.data.refresh_token);
|
||||
return axiosInterceptorInstance(originalRequest);
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
export default axiosInterceptorInstance;
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
import axios from "axios";
|
||||
|
||||
export async function getAPIDummy(url: any) {
|
||||
const response = await axios.get(url).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,
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +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,
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
|
||||
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,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
import { useRouter } from "next/navigation";
|
||||
import axiosInterceptorInstance from "./axios-interceptor-instance";
|
||||
import Cookies from "js-cookie";
|
||||
|
||||
export async function httpGetInterceptor(pathUrl: any) {
|
||||
const response = await axiosInterceptorInstance
|
||||
.get(pathUrl)
|
||||
.catch((error) => error.response);
|
||||
console.log("Response interceptor : ", response);
|
||||
if (response?.status == 200 || response?.status == 201) {
|
||||
return {
|
||||
error: false,
|
||||
message: "success",
|
||||
data: response?.data,
|
||||
};
|
||||
} else if (response?.status == 401) {
|
||||
Cookies.set("is_logout", "true");
|
||||
window.location.href = "/";
|
||||
return {
|
||||
error: true,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
error: true,
|
||||
message: response?.data?.message || response?.data || null,
|
||||
data: null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export async function httpPostInterceptor(
|
||||
pathUrl: any,
|
||||
data: any,
|
||||
headers?: any
|
||||
) {
|
||||
const response = await axiosInterceptorInstance
|
||||
.post(pathUrl, data)
|
||||
.catch((error) => error.response);
|
||||
console.log("Response interceptor : ", response);
|
||||
if (response?.status == 200 || response?.status == 201) {
|
||||
return {
|
||||
error: false,
|
||||
message: "success",
|
||||
data: response?.data,
|
||||
};
|
||||
} else if (response?.status == 401) {
|
||||
Cookies.set("is_logout", "true");
|
||||
window.location.href = "/";
|
||||
} else {
|
||||
return {
|
||||
error: true,
|
||||
message: response?.data?.message || response?.data || null,
|
||||
data: null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export async function httpPutInterceptor(
|
||||
pathUrl: any,
|
||||
data: any,
|
||||
headers?: any
|
||||
) {
|
||||
const response = await axiosInterceptorInstance
|
||||
.put(pathUrl, data, { headers })
|
||||
.catch((error) => error.response);
|
||||
console.log("Response interceptor : ", response);
|
||||
if (response?.status == 200 || response?.status == 201) {
|
||||
return {
|
||||
error: false,
|
||||
message: "success",
|
||||
data: response?.data,
|
||||
};
|
||||
} else if (response?.status == 401) {
|
||||
Cookies.set("is_logout", "true");
|
||||
window.location.href = "/";
|
||||
} else {
|
||||
return {
|
||||
error: true,
|
||||
message: response?.data?.message || response?.data || null,
|
||||
data: null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export async function httpDeleteInterceptor(pathUrl: any) {
|
||||
const response = await axiosInterceptorInstance
|
||||
.delete(pathUrl)
|
||||
.catch((error) => error.response);
|
||||
console.log("Response interceptor : ", response);
|
||||
if (response?.status == 200 || response?.status == 201) {
|
||||
return {
|
||||
error: false,
|
||||
message: "success",
|
||||
data: response?.data,
|
||||
};
|
||||
} else if (response?.status == 401) {
|
||||
Cookies.set("is_logout", "true");
|
||||
window.location.href = "/";
|
||||
} else {
|
||||
return {
|
||||
error: true,
|
||||
message: response?.data?.message || response?.data || null,
|
||||
data: null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export async function httpGetInterceptorWithToken(pathUrl: any, headers?: any) {
|
||||
const response = await axiosInterceptorInstance
|
||||
.get(pathUrl, headers)
|
||||
.catch((error) => error.response);
|
||||
console.log("Response interceptor : ", response);
|
||||
if (response?.status == 200 || response?.status == 201) {
|
||||
return {
|
||||
error: false,
|
||||
message: "success",
|
||||
data: response?.data,
|
||||
};
|
||||
} else if (response?.status == 401) {
|
||||
Cookies.set("is_logout", "true");
|
||||
window.location.href = "/";
|
||||
} else {
|
||||
return {
|
||||
error: true,
|
||||
message: response?.data?.message || response?.data || null,
|
||||
data: null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
import { getAPI, getAPIInterceptor } from "@/config/api";
|
||||
import { httpGet, httpPost } from "./http-config/http-base-service";
|
||||
import {
|
||||
httpGetInterceptor,
|
||||
httpGetInterceptorWithToken,
|
||||
} from "./http-config/http-interceptor-service";
|
||||
|
||||
export async function login(data: any) {
|
||||
const pathUrl = `signin`;
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpPost(pathUrl, headers, data);
|
||||
}
|
||||
|
||||
export async function userInfo(token: any) {
|
||||
const pathUrl = `users/info`;
|
||||
return await httpGetInterceptorWithToken(pathUrl, token);
|
||||
}
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
import {
|
||||
deleteAPIInterceptor,
|
||||
getAPI,
|
||||
getAPIInterceptor,
|
||||
postAPIInterceptor,
|
||||
} from "../config/api";
|
||||
|
||||
export async function listDataMedia(
|
||||
page: any,
|
||||
limit: any,
|
||||
search: any,
|
||||
categoryFilter: any,
|
||||
statusFilter: any
|
||||
) {
|
||||
const name = search || "";
|
||||
const url = `media/list?isForAdmin=true&title=${name}&enablePage=1&sortBy=createdAt&sort=desc&size=${limit}&page=${page}&typeId=1&categoryId=${categoryFilter}&statusId=${statusFilter}`;
|
||||
return getAPIInterceptor({ url });
|
||||
}
|
||||
|
||||
export async function listDataVideo(
|
||||
isForSelf: any,
|
||||
isApproval: any,
|
||||
page: any,
|
||||
limit: any,
|
||||
search: any,
|
||||
categoryFilter: any,
|
||||
statusFilter: any,
|
||||
needApprovalFromLevel: any,
|
||||
creator: any,
|
||||
source: any,
|
||||
startDate: any,
|
||||
endDate: any
|
||||
) {
|
||||
const name = search || "";
|
||||
const url = `media/list?title=${name}&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}`;
|
||||
return getAPIInterceptor({ url });
|
||||
}
|
||||
|
||||
export async function listDataImage(
|
||||
isForSelf: any,
|
||||
isApproval: any,
|
||||
page: any,
|
||||
limit: any,
|
||||
search: any,
|
||||
categoryFilter: any,
|
||||
statusFilter: any,
|
||||
needApprovalFromLevel: any,
|
||||
creator: any,
|
||||
source: any,
|
||||
startDate: any,
|
||||
endDate: any
|
||||
) {
|
||||
const name = search || "";
|
||||
const url = `media/list?title=${name}&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}`;
|
||||
return getAPIInterceptor({ url });
|
||||
}
|
||||
|
||||
export async function listDataAll(
|
||||
isForSelf: any,
|
||||
isApproval: any,
|
||||
page: any,
|
||||
limit: any,
|
||||
search: any,
|
||||
fileTypeFilter: any,
|
||||
statusFilter: any,
|
||||
startDate: any,
|
||||
endDate: any,
|
||||
needApprovalFromLevel: any
|
||||
) {
|
||||
const name = search || "";
|
||||
const url = `media/list?title=${name}&enablePage=1&sortBy=createdAt&sort=desc&size=${limit}&page=${page}&isForSelf=${isForSelf}&isApproval=${isApproval}&typeId=${fileTypeFilter}&statusId=${statusFilter}&startDate=${
|
||||
startDate == undefined ? "" : startDate
|
||||
}&endDate=${
|
||||
endDate == undefined ? "" : endDate
|
||||
}&needApprovalFromLevel=${needApprovalFromLevel}`;
|
||||
return getAPIInterceptor({ url });
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
import { httpGetInterceptor } from "../http-config/http-interceptor-service";
|
||||
|
||||
export async function getPlanningSentPagination(
|
||||
size: number,
|
||||
page: number,
|
||||
typeId: number
|
||||
) {
|
||||
return await httpGetInterceptor(
|
||||
`planning/pagination/sent?enablePage=1&size=${size}&page=${page}&typeId=${typeId}`
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
import { httpGet, httpPost } from "./http-config/http-base-service";
|
||||
import {
|
||||
httpDeleteInterceptor,
|
||||
httpGetInterceptor,
|
||||
httpPostInterceptor,
|
||||
httpPutInterceptor,
|
||||
} from "./http-config/http-interceptor-service";
|
||||
|
||||
export async function getPublicListPpidData(categoryId: number) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpGet(`/ppid-datas?categoryId=${categoryId}`, headers);
|
||||
}
|
||||
|
||||
export async function getListCategories(size: number, page: number) {
|
||||
return await httpGetInterceptor(
|
||||
`/ppid-data-categories?page=${page}&size=${size}&isOnlyTop=true`
|
||||
);
|
||||
}
|
||||
|
||||
export async function updateCategoryPosition(category: any) {
|
||||
const pathUrl = `/ppid-data-categories/position`;
|
||||
return await httpPostInterceptor(pathUrl, category);
|
||||
}
|
||||
|
||||
export async function getListSubCategories(
|
||||
size: number,
|
||||
page: number,
|
||||
parentId: number
|
||||
) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpGetInterceptor(
|
||||
`/ppid-data-categories?page=${page}&size=${size}&parentId=${parentId}`
|
||||
);
|
||||
}
|
||||
|
||||
export async function getPublicListCategoriesByParentId(
|
||||
id: any,
|
||||
limit: number,
|
||||
levelGroup?: string
|
||||
) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpGet(
|
||||
`/ppid-data-categories?parentId=${id}&isPpidDataIncluded=true&sort=asc&sortBy=position&limit=${limit}${
|
||||
levelGroup ? `&levelGroup=${levelGroup}` : ""
|
||||
}`,
|
||||
headers
|
||||
);
|
||||
}
|
||||
|
||||
export async function getListCategoriesByParentId(
|
||||
id: any,
|
||||
limit: number,
|
||||
levelGroup?: string
|
||||
) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpGetInterceptor(
|
||||
`/ppid-data-categories?parentId=${id}&isPpidDataIncluded=true&sort=asc&sortBy=position&limit=${limit}${
|
||||
levelGroup ? `&levelGroup=${levelGroup}` : ""
|
||||
}`
|
||||
);
|
||||
}
|
||||
|
||||
export async function getListCategoriesById(id: any) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpGetInterceptor(`/ppid-data-categories/${id}`);
|
||||
}
|
||||
|
||||
export async function getListCategoriesBySlug(slug: any) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpGetInterceptor(`/ppid-data-categories/slug/${slug}`);
|
||||
}
|
||||
|
||||
export async function getPublicListCategoriesBySlug(slug: any) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpGet(`/ppid-data-categories/slug/${slug}`, headers);
|
||||
}
|
||||
|
||||
export async function getList(categoryId: number) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpGetInterceptor(`/ppid-datas?categoryId=1`);
|
||||
}
|
||||
|
||||
export async function createArticle(data: any) {
|
||||
const pathUrl = `/articles`;
|
||||
return await httpPostInterceptor(pathUrl, data);
|
||||
}
|
||||
|
||||
export async function createPublicCategory(request: any) {
|
||||
const pathUrl = `/ppid-data-categories`;
|
||||
return await httpPostInterceptor(pathUrl, request);
|
||||
}
|
||||
|
||||
export async function uploadPublicThumbnail(id: number, data: any) {
|
||||
const headers = {
|
||||
"Content-Type": "multipart/form-data",
|
||||
};
|
||||
const pathUrl = `ppid-data-categories/thumbnail/${id}`;
|
||||
return await httpPost(pathUrl, headers, data);
|
||||
}
|
||||
|
||||
export async function getPublicCategoryById(id: any) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpGetInterceptor(`/ppid-data-categories/${id}`);
|
||||
}
|
||||
|
||||
export async function updatePublicCategory(id: any, request: any) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpPutInterceptor(`/ppid-data-categories/${id}`, request);
|
||||
}
|
||||
|
||||
export async function deletePublicCategory(id: any) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpDeleteInterceptor(`/ppid-data-categories/${id}`);
|
||||
}
|
||||
|
||||
export async function getParentCategories() {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpGet(`ppid-data-categories?isOnlyTop=true`, headers);
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
import { title } from "process";
|
||||
import {
|
||||
deleteAPIInterceptor,
|
||||
getAPIInterceptor,
|
||||
postAPIInterceptor,
|
||||
} from "../config/api";
|
||||
import {
|
||||
httpGetInterceptor,
|
||||
httpPostInterceptor,
|
||||
} from "./http-config/http-interceptor-service";
|
||||
|
||||
// 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) {
|
||||
const url = "assignment";
|
||||
return httpPostInterceptor(url, data);
|
||||
}
|
||||
|
||||
export async function getTask(id: any) {
|
||||
const url = `/assignment?id=${id}`;
|
||||
return getAPIInterceptor({ url });
|
||||
}
|
||||
|
||||
export async function forwardTask(data: any) {
|
||||
const url = "assignment/forward";
|
||||
return postAPIInterceptor(url, data);
|
||||
}
|
||||
|
||||
export async function finishTask(id: any) {
|
||||
const url = `assignment/finish?id=${id}`;
|
||||
return postAPIInterceptor(url, id);
|
||||
}
|
||||
|
||||
export async function deleteTask(id: any) {
|
||||
const url = `assignment?id=${id}`;
|
||||
return deleteAPIInterceptor(url, id);
|
||||
}
|
||||
|
||||
export async function getUserLevelForAssignments() {
|
||||
const url = "/users/user-levels/assignment";
|
||||
return getAPIInterceptor({ url });
|
||||
}
|
||||
|
||||
export async function getAssignmentResponseList(id: any) {
|
||||
const url = `assignment/response?assignmentId=${id}`;
|
||||
return getAPIInterceptor({ url });
|
||||
}
|
||||
|
||||
export async function createAssignmentResponse(data: any) {
|
||||
const url = "assignment/response";
|
||||
return postAPIInterceptor(url, data);
|
||||
}
|
||||
|
||||
export async function deleteAssignmentResponse(id: any) {
|
||||
const url = `assignment/response?id=${id}`;
|
||||
return deleteAPIInterceptor(url, id);
|
||||
}
|
||||
|
||||
export async function getAcceptance(id: any, isAccept: any) {
|
||||
const url = `assignment/acceptance?id=${id}&isAccept=${isAccept}`;
|
||||
return getAPIInterceptor({ url });
|
||||
}
|
||||
|
||||
export async function acceptAssignment(id: any, isAccept: any) {
|
||||
const url = `assignment/acceptance?id=${id}`;
|
||||
return postAPIInterceptor(url, id);
|
||||
}
|
||||
|
||||
export async function postFinishAcceptance(id: any) {
|
||||
const url = `assignment/finish-acceptance?id=${id}`;
|
||||
return postAPIInterceptor(url, id);
|
||||
}
|
||||
|
||||
export async function getAcceptanceAssignmentStatus(id: any) {
|
||||
const url = `assignment/acceptance/status?id=${id}`;
|
||||
return getAPIInterceptor({ url });
|
||||
}
|
||||
|
||||
export async function getListAttachment(assignmentId: any, isForCreator: any) {
|
||||
const url = `media/list?&enablePage=0&assignmentId=${assignmentId}&isForAdmin=${isForCreator}`;
|
||||
return getAPIInterceptor({ url });
|
||||
}
|
||||
Loading…
Reference in New Issue