diff --git a/app/[locale]/(protected)/supervisor/communications/account-report/components/column.tsx b/app/[locale]/(protected)/supervisor/communications/account-report/components/column.tsx index ee7f653b..0c2bd4db 100644 --- a/app/[locale]/(protected)/supervisor/communications/account-report/components/column.tsx +++ b/app/[locale]/(protected)/supervisor/communications/account-report/components/column.tsx @@ -1,15 +1,7 @@ - import * as React from "react"; -import { - ColumnDef, -} from "@tanstack/react-table"; +import { ColumnDef } from "@tanstack/react-table"; -import { - Eye, - MoreVertical, - SquarePen, - Trash2, -} from "lucide-react"; +import { Eye, MoreVertical, SquarePen, Trash2 } from "lucide-react"; import { cn } from "@/lib/utils"; import { DropdownMenu, @@ -27,50 +19,60 @@ const columns: ColumnDef[] = [ cell: ({ row }) => {row.getValue("no")}, }, { - accessorKey: "question", - header: "Question", - cell: ({ row }) => {row.getValue("question")}, + accessorKey: "report", + header: "Pelapor", + cell: ({ row }) => {row.getValue("report")}, }, { - accessorKey: "answer", - header: "Answer", - cell: ({ row }) => {row.getValue("answer")}, + accessorKey: "reportDetail", + header: "Detail Laporan", + cell: ({ row }) => {row.getValue("reportDetail")}, }, { - id: "actions", - accessorKey: "action", - header: "Actions", - enableHiding: false, - cell: ({ row }) => { - return ( - - - - - - - - View - - - - Edit - - - - Delete - - - - ); - }, + accessorKey: "reportAccount", + header: "Terlapor", + cell: ({ row }) => {row.getValue("reportAccount")}, }, + { + accessorKey: "status", + header: "Status", + cell: ({ row }) => {row.getValue("status")}, + }, + // { + // id: "actions", + // accessorKey: "action", + // header: "Actions", + // enableHiding: false, + // cell: ({ row }) => { + // return ( + // + // + // + // + // + // + // + // View + // + // + // + // Edit + // + // + // + // Delete + // + // + // + // ); + // }, + // }, ]; -export default columns; \ No newline at end of file +export default columns; diff --git a/app/[locale]/(protected)/supervisor/communications/account-report/components/table.tsx b/app/[locale]/(protected)/supervisor/communications/account-report/components/table.tsx index b8a5f027..f778cbbc 100644 --- a/app/[locale]/(protected)/supervisor/communications/account-report/components/table.tsx +++ b/app/[locale]/(protected)/supervisor/communications/account-report/components/table.tsx @@ -51,7 +51,7 @@ import TablePagination from "@/components/table/table-pagination"; import { getFaqList } from "@/service/master/faq"; import columns from "./column"; -const FaqTable = () => { +const ReportTable = () => { const router = useRouter(); const searchParams = useSearchParams(); @@ -94,11 +94,11 @@ const FaqTable = () => { }); React.useEffect(() => { - const pageFromUrl = searchParams?.get('page'); + const pageFromUrl = searchParams?.get("page"); if (pageFromUrl) { setPage(Number(pageFromUrl)); } - }, [searchParams]); + }, [searchParams]); React.useEffect(() => { fetchData(); @@ -191,9 +191,14 @@ const FaqTable = () => { )} - + ); }; -export default FaqTable; +export default ReportTable; diff --git a/app/[locale]/(protected)/supervisor/communications/account-report/page.tsx b/app/[locale]/(protected)/supervisor/communications/account-report/page.tsx index 8ba136f7..de1c0ef4 100644 --- a/app/[locale]/(protected)/supervisor/communications/account-report/page.tsx +++ b/app/[locale]/(protected)/supervisor/communications/account-report/page.tsx @@ -3,35 +3,44 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import FaqTable from "./components/table"; import { Button } from "@/components/ui/button"; import { Plus } from "lucide-react"; +import { StatisticsBlock } from "@/components/blocks/statistics-block"; +import ReportTable from "./components/table"; const FaqPage = async () => { return (
+
+
+ Pelaporan Akun +
+
+
- - -
-
- FAQ Data -
-
- -
-
-
-
- - + +
+ + + +
+
); diff --git a/app/[locale]/(protected)/supervisor/communications/contact/components/columns.tsx b/app/[locale]/(protected)/supervisor/communications/contact/components/columns.tsx new file mode 100644 index 00000000..ff72d9ff --- /dev/null +++ b/app/[locale]/(protected)/supervisor/communications/contact/components/columns.tsx @@ -0,0 +1,109 @@ +import * as React from "react"; +import { ColumnDef } from "@tanstack/react-table"; + +import { Eye, MoreVertical, SquarePen, Trash2 } from "lucide-react"; +import { cn } from "@/lib/utils"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuTrigger, + DropdownMenuItem, +} from "@/components/ui/dropdown-menu"; +import { Button } from "@/components/ui/button"; +import { Badge } from "@/components/ui/badge"; +import { format } from "date-fns"; +import { Link } from "@/components/navigation"; + +const columns: ColumnDef[] = [ + { + accessorKey: "no", + header: "No", + cell: ({ row }) => {row.getValue("no")}, + }, + { + accessorKey: "title", + header: "Nama", + cell: ({ row }) => ( + {row.getValue("title")} + ), + }, + { + accessorKey: "phoneNumber", + header: "No.Telp", + cell: ({ row }) => { + const createdBy = row.original.createdBy; // Akses properti category + return ( + {createdBy?.fullname || "N/A"} + ); + }, + }, + { + accessorKey: "email", + header: "Email", + cell: ({ row }) => { + const sendTo = row.original.sendTo; // Akses properti category + return {sendTo?.fullname || "N/A"}; + }, + }, + { + accessorKey: "createdName", + header: "Admin", + 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 {formattedDate}; + }, + }, + // { + // id: "actions", + // accessorKey: "action", + // header: "Actions", + // enableHiding: false, + // cell: ({ row }) => { + // return ( + // + // + // + // + // + // + // + // + // View + // + // + // + // + // + // Edit + // + // + // + // + // Delete + // + // + // + // ); + // }, + // }, +]; + +export default columns; diff --git a/app/[locale]/(protected)/supervisor/communications/contact/components/contact-table.tsx b/app/[locale]/(protected)/supervisor/communications/contact/components/contact-table.tsx new file mode 100644 index 00000000..733cd1ff --- /dev/null +++ b/app/[locale]/(protected)/supervisor/communications/contact/components/contact-table.tsx @@ -0,0 +1,299 @@ +"use client"; + +import * as React from "react"; +import { + ColumnDef, + ColumnFiltersState, + PaginationState, + SortingState, + VisibilityState, + flexRender, + getCoreRowModel, + getFilteredRowModel, + getPaginationRowModel, + getSortedRowModel, + useReactTable, +} from "@tanstack/react-table"; +import { Button } from "@/components/ui/button"; + +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/components/ui/table"; +import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; +import { + ChevronLeft, + ChevronRight, + Eye, + MoreVertical, + Search, + SquarePen, + Trash2, + TrendingDown, + TrendingUp, + UploadIcon, +} from "lucide-react"; +import { cn, getCookiesDecrypt } from "@/lib/utils"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuRadioGroup, + DropdownMenuRadioItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import { Input } from "@/components/ui/input"; +import { InputGroup, InputGroupText } from "@/components/ui/input-group"; +import { paginationBlog } from "@/service/blog/blog"; +import { ticketingPagination } from "@/service/ticketing/ticketing"; +import { Badge } from "@/components/ui/badge"; +import { useRouter, useSearchParams } from "next/navigation"; +import TablePagination from "@/components/table/table-pagination"; +import columns from "./columns"; +import { + listDataAudio, + listDataImage, + listDataVideo, +} from "@/service/content/content"; +import { listTicketingInternal } from "@/service/communication/communication"; +import { Link } from "@/components/navigation"; +import { Card } from "nextra-theme-docs"; +import { CardContent } from "@/components/ui/card"; + +const ContactTable = () => { + const router = useRouter(); + const searchParams = useSearchParams(); + + const [dataTable, setDataTable] = React.useState([]); + const [totalData, setTotalData] = React.useState(1); + const [sorting, setSorting] = React.useState([]); + const [columnFilters, setColumnFilters] = React.useState( + [] + ); + const [columnVisibility, setColumnVisibility] = + React.useState({}); + const [rowSelection, setRowSelection] = React.useState({}); + const [showData, setShowData] = React.useState("10"); + + const [pagination, setPagination] = React.useState({ + pageIndex: 0, + pageSize: Number(showData), + }); + const [page, setPage] = React.useState(1); + const [totalPage, setTotalPage] = React.useState(1); + const [search, setSearch] = React.useState(""); + const userId = getCookiesDecrypt("uie"); + const userLevelId = getCookiesDecrypt("ulie"); + const [activeCategory, setActiveCategory] = React.useState( + null + ); + + const roleId = getCookiesDecrypt("urie"); + + const table = useReactTable({ + data: dataTable, + columns, + onSortingChange: setSorting, + onColumnFiltersChange: setColumnFilters, + getCoreRowModel: getCoreRowModel(), + getPaginationRowModel: getPaginationRowModel(), + getSortedRowModel: getSortedRowModel(), + getFilteredRowModel: getFilteredRowModel(), + onColumnVisibilityChange: setColumnVisibility, + onRowSelectionChange: setRowSelection, + onPaginationChange: setPagination, + state: { + sorting, + columnFilters, + columnVisibility, + rowSelection, + pagination, + }, + }); + + React.useEffect(() => { + const pageFromUrl = searchParams?.get("page"); + if (pageFromUrl) { + setPage(Number(pageFromUrl)); + } + }, [searchParams]); + + // React.useEffect(() => { + // fetchData(); + // setPagination({ + // pageIndex: 0, + // pageSize: Number(showData), + // }); + // }, [page, showData]); + React.useEffect(() => { + if (activeCategory) { + fetchData(); + setPagination({ + pageIndex: 0, + pageSize: Number(showData), + }); + } + }, [page, showData, activeCategory]); + + let typingTimer: any; + const doneTypingInterval = 1500; + + const handleKeyUp = () => { + clearTimeout(typingTimer); + typingTimer = setTimeout(doneTyping, doneTypingInterval); + }; + + const handleKeyDown = () => { + clearTimeout(typingTimer); + }; + + async function doneTyping() { + fetchData(); + } + + // async function fetchData() { + // try { + // const res = await listTicketingInternal( + // page - 1, + // Number(showData), + // search + // ); + // const data = res?.data?.data; + // const contentData = data?.content; + // contentData.forEach((item: any, index: number) => { + // item.no = (page - 1) * Number(showData) + index + 1; + // }); + + // console.log("contentData : ", contentData); + + // setDataTable(contentData); + // setTotalData(data?.totalElements); + // setTotalPage(data?.totalPages); + // } catch (error) { + // console.error("Error fetching tasks:", error); + // } + // } + + async function fetchData() { + try { + const res = await listTicketingInternal( + page - 1, + Number(showData), + search, + activeCategory + ); + const data = res?.data?.data; + const contentData = data?.content || []; + contentData.forEach((item: any, index: number) => { + item.no = (page - 1) * Number(showData) + index + 1; + }); + setDataTable(contentData); + setTotalData(data?.totalElements); + setTotalPage(data?.totalPages); + } catch (error) { + console.error("Error fetching tasks:", error); + } + } + + return ( +
+
+
+ + + + + setSearch(e.target.value)} + onKeyDown={handleKeyDown} + onKeyUp={handleKeyUp} + /> + +
+
+
+ {["Polda", "Satker Humas", "Satker Mabes"].map((category, index) => ( + setActiveCategory(category)} + > +
+

+ {index === 0 ? 34 : index === 1 ? 1 : 43} +

+

{category}

+

Lihat Kontak

+
+
+ ))} +
+ {activeCategory && ( +
+ + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => ( + + {header.isPlaceholder + ? null + : flexRender( + header.column.columnDef.header, + header.getContext() + )} + + ))} + + ))} + + + {table.getRowModel().rows?.length ? ( + table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map((cell) => ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext() + )} + + ))} + + )) + ) : ( + + + No results. + + + )} + +
+ +
+ )} +
+ ); +}; + +export default ContactTable; diff --git a/app/[locale]/(protected)/supervisor/communications/contact/create/page.tsx b/app/[locale]/(protected)/supervisor/communications/contact/create/page.tsx new file mode 100644 index 00000000..ef2beaf4 --- /dev/null +++ b/app/[locale]/(protected)/supervisor/communications/contact/create/page.tsx @@ -0,0 +1,359 @@ +"use client"; +import SiteBreadcrumb from "@/components/site-breadcrumb"; +import { Button } from "@/components/ui/button"; +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; +import { z } from "zod"; +import { useForm } from "react-hook-form"; +import { zodResolver } from "@hookform/resolvers/zod"; +import withReactContent from "sweetalert2-react-content"; +import Swal from "sweetalert2"; +import { Link, useRouter } from "@/i18n/routing"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { useEffect, useState } from "react"; +import { + AdministrationLevelList, + getListCompetencies, + getListExperiences, + saveUserInternal, + saveUserRolePlacements, +} from "@/service/management-user/management-user"; +import { loading } from "@/config/swal"; +import { Label } from "@/components/ui/label"; + +const FormSchema = z.object({ + name: z.string({ + required_error: "Required", + }), + username: z.string({ + required_error: "Required", + }), + password: z.string({ + required_error: "Required", + }), + phoneNumber: z.string({ + required_error: "Required", + }), + email: z.string({ + required_error: "Required", + }), + skills: z.string({ + required_error: "Required", + }), + experiences: z.string({ + required_error: "Required", + }), + company: z.string({ + required_error: "Required", + }), +}); + +export type Placements = { + index: number; + roleId?: string; + userLevelId?: number; +}; + +export default function AddContactForm() { + const MySwal = withReactContent(Swal); + const router = useRouter(); + const form = useForm>({ + resolver: zodResolver(FormSchema), + }); + const [incrementId, setIncrementId] = useState(1); + const [placementRows, setPlacementRows] = useState([ + { index: 0, roleId: "", userLevelId: 0 }, + ]); + const [userCompetencies, setUserCompetencies] = useState(); + const [userExperiences, setUserExperiences] = useState(); + const [userLevels, setUserLevels] = useState(); + + const roleSelection = [ + { + id: "11", + name: "Polda", + }, + { + id: "12", + name: "Satker Humas", + }, + { + id: "13", + name: "Satker Mabes", + }, + ]; + + const onSubmit = async (data: z.infer) => { + 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); + } + }); + }; + + const save = async (data: z.infer) => { + console.log("data", data); + + const dataReq = { + firstName: data.name, + username: data.username, + email: data.email, + password: data.password, + adress: "", + roleId: "EXP-ID", + phoneNumber: data.phoneNumber, + userCompetencyId: data.skills, + userExperienceId: data.experiences, + companyName: data.company, + }; + + loading(); + const res = await saveUserInternal(dataReq); + const resData = res?.data?.data; + const userProfileId = resData?.id; + + var placementArr: any[] = []; + placementRows.forEach((row: any) => { + placementArr.push({ + roleId: Number(row.roleId), + userLevelId: Number(row.userLevelId), + userProfileId: userProfileId, + }); + }); + + const dataReq2 = { + userId: userProfileId, + placements: placementArr, + }; + const res2 = await saveUserRolePlacements(dataReq2); + const resData2 = res2?.data?.data; + + success("/admin/add-experts"); + }; + + function success(redirect: string): void { + MySwal.fire({ + title: '

Sukses

', + icon: "success", + confirmButtonColor: "#3085d6", + confirmButtonText: 'OK', + allowOutsideClick: false, + }).then((result) => { + if (result.isConfirmed) { + router.push(redirect); + } + }); + } + + function successSubmit() { + MySwal.fire({ + title: "Sukses", + icon: "success", + confirmButtonColor: "#3085d6", + confirmButtonText: "OK", + }).then((result) => { + if (result.isConfirmed) { + router.push("/admin/add-experts"); + } + }); + } + + const handleSelectionChange = ( + index: number, + type: "roleId" | "userLevelId", + value: string + ) => { + setPlacementRows((prevRows) => + prevRows.map((row) => + row.index === index ? { ...row, [type]: value } : row + ) + ); + }; + + const handleRemoveRow = (index: number) => { + console.log(index); + console.log(placementRows); + const newPlacements = placementRows.filter((row) => row.index != index); + console.log(newPlacements); + setPlacementRows(newPlacements); + }; + + const handleAddRow = () => { + setPlacementRows((prevRows: any) => [ + ...prevRows, + { index: incrementId, roleId: "", userLevelId: 0 }, + ]); + setIncrementId((prevId) => prevId + 1); + }; + + return ( +
+ + +
+ + ( + + Email + + + + )} + /> + ( + + Nama Lengkap + + + + + )} + /> + ( + + No. HP + + + + )} + /> +
+ + Kategori Akun * + + +
+ ( + + Username Admin + + + + + )} + /> + ( + + Username Approver + + + + + )} + /> + ( + + Username Kontributor + + + + + )} + /> + +
+ + + + +
+ + +
+ ); +} diff --git a/app/[locale]/(protected)/supervisor/communications/contact/import-contact/components/columns.tsx b/app/[locale]/(protected)/supervisor/communications/contact/import-contact/components/columns.tsx new file mode 100644 index 00000000..28aef6a4 --- /dev/null +++ b/app/[locale]/(protected)/supervisor/communications/contact/import-contact/components/columns.tsx @@ -0,0 +1,142 @@ +import * as React from "react"; +import { ColumnDef } from "@tanstack/react-table"; + +import { Eye, MoreVertical, SquarePen, Trash2 } from "lucide-react"; +import { cn } from "@/lib/utils"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuTrigger, + DropdownMenuItem, +} from "@/components/ui/dropdown-menu"; +import { Button } from "@/components/ui/button"; +import { Badge } from "@/components/ui/badge"; +import { format } from "date-fns"; +import { Link } from "@/components/navigation"; + +const columns: ColumnDef[] = [ + { + accessorKey: "no", + header: "No", + cell: ({ row }) => {row.getValue("no")}, + }, + { + accessorKey: "title", + header: "Nama", + cell: ({ row }) => ( + {row.getValue("title")} + ), + }, + { + accessorKey: "phoneNumber", + header: "No.Telp", + cell: ({ row }) => { + const createdBy = row.original.createdBy; // Akses properti category + return ( + {createdBy?.fullname || "N/A"} + ); + }, + }, + { + accessorKey: "email", + header: "Email", + cell: ({ row }) => { + const sendTo = row.original.sendTo; // Akses properti category + return {sendTo?.fullname || "N/A"}; + }, + }, + { + accessorKey: "createdName", + header: "Admin", + 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 {formattedDate}; + }, + }, + + { + accessorKey: "approver", + header: "Approver", + 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 {formattedDate}; + }, + }, + { + accessorKey: "contributor", + header: "Contributor", + 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 {formattedDate}; + }, + }, + // { + // id: "actions", + // accessorKey: "action", + // header: "Actions", + // enableHiding: false, + // cell: ({ row }) => { + // return ( + // + // + // + // + // + // + // + // + // View + // + // + // + // + // + // Edit + // + // + // + // + // Delete + // + // + // + // ); + // }, + // }, +]; + +export default columns; diff --git a/app/[locale]/(protected)/supervisor/communications/contact/import-contact/components/contact-table.tsx b/app/[locale]/(protected)/supervisor/communications/contact/import-contact/components/contact-table.tsx new file mode 100644 index 00000000..4961a02f --- /dev/null +++ b/app/[locale]/(protected)/supervisor/communications/contact/import-contact/components/contact-table.tsx @@ -0,0 +1,293 @@ +"use client"; + +import * as React from "react"; +import { + ColumnDef, + ColumnFiltersState, + PaginationState, + SortingState, + VisibilityState, + flexRender, + getCoreRowModel, + getFilteredRowModel, + getPaginationRowModel, + getSortedRowModel, + useReactTable, +} from "@tanstack/react-table"; +import { Button } from "@/components/ui/button"; + +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/components/ui/table"; +import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; +import { + ChevronLeft, + ChevronRight, + Eye, + MoreVertical, + Search, + SquarePen, + Trash2, + TrendingDown, + TrendingUp, + UploadIcon, +} from "lucide-react"; +import { cn, getCookiesDecrypt } from "@/lib/utils"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuRadioGroup, + DropdownMenuRadioItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import { Input } from "@/components/ui/input"; +import { InputGroup, InputGroupText } from "@/components/ui/input-group"; +import { paginationBlog } from "@/service/blog/blog"; +import { ticketingPagination } from "@/service/ticketing/ticketing"; +import { Badge } from "@/components/ui/badge"; +import { useRouter, useSearchParams } from "next/navigation"; +import TablePagination from "@/components/table/table-pagination"; +import columns from "./columns"; +import { + listDataAudio, + listDataImage, + listDataVideo, +} from "@/service/content/content"; +import { listTicketingInternal } from "@/service/communication/communication"; +import { Link } from "@/components/navigation"; +import { Card } from "nextra-theme-docs"; +import { CardContent } from "@/components/ui/card"; + +const ImportTable = () => { + const router = useRouter(); + const searchParams = useSearchParams(); + + const [dataTable, setDataTable] = React.useState([]); + const [totalData, setTotalData] = React.useState(1); + const [sorting, setSorting] = React.useState([]); + const [columnFilters, setColumnFilters] = React.useState( + [] + ); + const [columnVisibility, setColumnVisibility] = + React.useState({}); + const [rowSelection, setRowSelection] = React.useState({}); + const [showData, setShowData] = React.useState("10"); + + const [pagination, setPagination] = React.useState({ + pageIndex: 0, + pageSize: Number(showData), + }); + const [page, setPage] = React.useState(1); + const [totalPage, setTotalPage] = React.useState(1); + const [search, setSearch] = React.useState(""); + const userId = getCookiesDecrypt("uie"); + const userLevelId = getCookiesDecrypt("ulie"); + const [activeCategory, setActiveCategory] = React.useState( + null + ); + + const [selectedFile, setSelectedFile] = React.useState(null); + + const handleFileChange = (event: any) => { + const file = event.target.files[0]; + setSelectedFile(file); + }; + + const roleId = getCookiesDecrypt("urie"); + + const table = useReactTable({ + data: dataTable, + columns, + onSortingChange: setSorting, + onColumnFiltersChange: setColumnFilters, + getCoreRowModel: getCoreRowModel(), + getPaginationRowModel: getPaginationRowModel(), + getSortedRowModel: getSortedRowModel(), + getFilteredRowModel: getFilteredRowModel(), + onColumnVisibilityChange: setColumnVisibility, + onRowSelectionChange: setRowSelection, + onPaginationChange: setPagination, + state: { + sorting, + columnFilters, + columnVisibility, + rowSelection, + pagination, + }, + }); + + React.useEffect(() => { + const pageFromUrl = searchParams?.get("page"); + if (pageFromUrl) { + setPage(Number(pageFromUrl)); + } + }, [searchParams]); + + // React.useEffect(() => { + // fetchData(); + // setPagination({ + // pageIndex: 0, + // pageSize: Number(showData), + // }); + // }, [page, showData]); + React.useEffect(() => { + if (activeCategory) { + fetchData(); + setPagination({ + pageIndex: 0, + pageSize: Number(showData), + }); + } + }, [page, showData, activeCategory]); + + let typingTimer: any; + const doneTypingInterval = 1500; + + const handleKeyUp = () => { + clearTimeout(typingTimer); + typingTimer = setTimeout(doneTyping, doneTypingInterval); + }; + + const handleKeyDown = () => { + clearTimeout(typingTimer); + }; + + async function doneTyping() { + fetchData(); + } + + // async function fetchData() { + // try { + // const res = await listTicketingInternal( + // page - 1, + // Number(showData), + // search + // ); + // const data = res?.data?.data; + // const contentData = data?.content; + // contentData.forEach((item: any, index: number) => { + // item.no = (page - 1) * Number(showData) + index + 1; + // }); + + // console.log("contentData : ", contentData); + + // setDataTable(contentData); + // setTotalData(data?.totalElements); + // setTotalPage(data?.totalPages); + // } catch (error) { + // console.error("Error fetching tasks:", error); + // } + // } + + async function fetchData() { + try { + const res = await listTicketingInternal( + page - 1, + Number(showData), + search, + activeCategory + ); + const data = res?.data?.data; + const contentData = data?.content || []; + contentData.forEach((item: any, index: number) => { + item.no = (page - 1) * Number(showData) + index + 1; + }); + setDataTable(contentData); + setTotalData(data?.totalElements); + setTotalPage(data?.totalPages); + } catch (error) { + console.error("Error fetching tasks:", error); + } + } + + return ( +
+
+ + {/* {selectedFile && ( +

File: {selectedFile.name}

+ )} */} +
+
+ +
+ +
+ + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => ( + + {header.isPlaceholder + ? null + : flexRender( + header.column.columnDef.header, + header.getContext() + )} + + ))} + + ))} + + + {table.getRowModel().rows?.length ? ( + table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map((cell) => ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext() + )} + + ))} + + )) + ) : ( + + + No results. + + + )} + +
+ +
+
+ + + +
+
+ ); +}; + +export default ImportTable; diff --git a/app/[locale]/(protected)/supervisor/communications/contact/import-contact/page.tsx b/app/[locale]/(protected)/supervisor/communications/contact/import-contact/page.tsx new file mode 100644 index 00000000..cfa1b2d7 --- /dev/null +++ b/app/[locale]/(protected)/supervisor/communications/contact/import-contact/page.tsx @@ -0,0 +1,24 @@ +import SiteBreadcrumb from "@/components/site-breadcrumb"; +import { Button } from "@/components/ui/button"; +import { Link } from "@/i18n/routing"; +import { PlusIcon, User } from "lucide-react"; +import ContactTable from "../components/contact-table"; +import ImportTable from "./components/contact-table"; + +const ImportPage = async () => { + return ( +
+ +
+
+
+

Kontak

+
+ +
+
+
+ ); +}; + +export default ImportPage; diff --git a/app/[locale]/(protected)/supervisor/communications/contact/layout.tsx b/app/[locale]/(protected)/supervisor/communications/contact/layout.tsx new file mode 100644 index 00000000..5a0ee05c --- /dev/null +++ b/app/[locale]/(protected)/supervisor/communications/contact/layout.tsx @@ -0,0 +1,11 @@ +import { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Dashboard Media Hub", + description: "Dashboard Media Hub.", +}; +const Layout = ({ children }: { children: React.ReactNode }) => { + return <>{children}; +}; + +export default Layout; diff --git a/app/[locale]/(protected)/supervisor/communications/contact/page.tsx b/app/[locale]/(protected)/supervisor/communications/contact/page.tsx new file mode 100644 index 00000000..0f18abde --- /dev/null +++ b/app/[locale]/(protected)/supervisor/communications/contact/page.tsx @@ -0,0 +1,42 @@ +import SiteBreadcrumb from "@/components/site-breadcrumb"; +import { Button } from "@/components/ui/button"; +import { Link } from "@/i18n/routing"; +import { PlusIcon, User } from "lucide-react"; +import InternalSpvTable from "../internal/components/internal-table"; +import ContactTable from "./components/contact-table"; + +const ContactPage = async () => { + return ( +
+ +
+
+
+

Kontak

+
+
+

Semua Kontak

+
+ + + {" "} + + + +
+
+ + +
+
+
+ ); +}; + +export default ContactPage; diff --git a/app/[locale]/(protected)/supervisor/communications/web-chat/page.tsx b/app/[locale]/(protected)/supervisor/communications/web-chat/page.tsx new file mode 100644 index 00000000..687c615f --- /dev/null +++ b/app/[locale]/(protected)/supervisor/communications/web-chat/page.tsx @@ -0,0 +1,197 @@ +"use client"; +import SiteBreadcrumb from "@/components/site-breadcrumb"; +import { Card, CardContent } from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { useState } from "react"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog"; +import { Label } from "@/components/ui/label"; +import { Search } from "lucide-react"; + +const messages = [ + { name: "Miles Esther", initials: "ME", time: "06.00" }, + { name: "Flores Juanita", initials: "FJ", time: "06.00" }, + { name: "Henry Arthur", initials: "HA", time: "06.00" }, + { name: "Polres Jakarta Selatan", initials: "PJ", time: "06.00" }, +]; + +const WebChatPage = () => { + const [selectedChat, setSelectedChat] = useState(null); + return ( +
+ +
+ {!selectedChat ? ( + // Tampilan daftar pesan + <> +
+

Web Chat

+
+
+
+ + + + + + + + + New Chat + + +
+ + +
+
+

+ Group Chat

+
+
+

+ Frequently contacted +

+
+
+
+ ME +
+ + Miles Esther + +
+
+
+ HA +
+ + Henry Arthur + +
+
+
+
+
+
+
+ + +
+ {messages.map((msg: any, index) => ( +
setSelectedChat(msg)} + > +
+
+ {msg.initials} +
+
+

{msg.name}

+

+ ✅ Hallo, untuk patroli hari ini sudah bisa di akses + di daily tasks, silahkan anda periksa +

+
+
+

{msg.time}

+
+ ))} +
+
+
+ + ) : ( + // Tampilan chat +
+
+

Web Chat

+
+ + + {/* Header Chat */} +
+ +
+
+ {selectedChat.initials} +
+

{selectedChat.name}

+
+
+ + {/* Body Chat */} +
+

Today

+ + {/* Pesan masuk */} +
+
+ Hallo, untuk patroli hari ini sudah bisa di akses di daily + tasks, silahkan anda periksa +
+

06.00

+
+ + {/* Pesan keluar */} +
+

06.00

+
+ Hallo, bisakah mengirimkan rute patroli untuk hari ini? +
+
+ + {/* Pesan keluar lainnya */} +
+

06.00

+
+ Terima kasih banyak +
+
+
+ + {/* Input Chat */} +
+ + + +
+
+
+
+ )} +
+
+ ); +}; + +export default WebChatPage; diff --git a/lib/menus.ts b/lib/menus.ts index d03f9fd7..e999da9a 100644 --- a/lib/menus.ts +++ b/lib/menus.ts @@ -2734,6 +2734,13 @@ export function getMenuList(pathname: string, t: any): Group[] { icon: "ri:chat-private-line", children: [], }, + { + href: "/supervisor/communications/contact", + label: t("contact"), + active: pathname.includes("/communications/contact"), + icon: "ri:share-forward-2-fill", + children: [], + }, { href: "/supervisor/communications/forward", label: t("forward"), @@ -2748,6 +2755,7 @@ export function getMenuList(pathname: string, t: any): Group[] { icon: "clarity:employee-group-line", children: [], }, + { href: "/supervisor/communications/account-report", label: t("account-report"), @@ -2755,6 +2763,20 @@ export function getMenuList(pathname: string, t: any): Group[] { icon: "uiw:user-delete", children: [], }, + { + href: "/supervisor/communications/ptt", + label: t("ptt"), + active: pathname.includes("/communications/ptt"), + icon: "clarity:employee-group-line", + children: [], + }, + { + href: "/supervisor/communications/web-chat", + label: t("web-chat"), + active: pathname.includes("/communications/web-chat"), + icon: "clarity:employee-group-line", + children: [], + }, ], }, ], diff --git a/messages/en.json b/messages/en.json index 36d622b5..8f5f769b 100644 --- a/messages/en.json +++ b/messages/en.json @@ -334,7 +334,10 @@ "tags": "Tags", "add-tags": "Add Tags", "add": "Add", - "privacy": "Privacy Policy" + "privacy": "Privacy Policy", + "contact": "Contact", + "ptt": "PTT", + "web-chat": "Web-Chat" }, "Changelog": { "version": "Version's", diff --git a/messages/in.json b/messages/in.json index 36199c24..8cc09c09 100644 --- a/messages/in.json +++ b/messages/in.json @@ -335,7 +335,10 @@ "tags": "Tag", "add-tags": "Tambah Tag", "add": "Tambah", - "privacy": "Kebijakan Privacy" + "privacy": "Kebijakan Privacy", + "contact": "kontak", + "ptt": "PTT", + "web-chat": "Web-Chat" }, "Changelog": { "version": "Version's", diff --git a/service/communication/communication.ts b/service/communication/communication.ts index 40f95596..b70ab31a 100644 --- a/service/communication/communication.ts +++ b/service/communication/communication.ts @@ -8,10 +8,11 @@ import { title } from "process"; export async function listTicketingInternal( page: number, size: any, - title: string = "" + title: string = "", + category: any ) { return await httpGetInterceptor( - `ticketing/internal/pagination?enablePage=1&size=${size}&page=${page}&title=${title}` + `ticketing/internal/pagination?enablePage=1&size=${size}&page=${page}&title=${title}&category=${category}` ); }