diff --git a/app/[locale]/(protected)/admin/broadcast/campaign-list/account-list/component/table.tsx b/app/[locale]/(protected)/admin/broadcast/campaign-list/account-list/component/table.tsx index 20b53a64..c08b0a36 100644 --- a/app/[locale]/(protected)/admin/broadcast/campaign-list/account-list/component/table.tsx +++ b/app/[locale]/(protected)/admin/broadcast/campaign-list/account-list/component/table.tsx @@ -127,7 +127,7 @@ const AccountListTable = () => { return (
-
+

Daftar Akun

diff --git a/app/[locale]/(protected)/admin/broadcast/campaign-list/account-list/detail/[id]/page.tsx b/app/[locale]/(protected)/admin/broadcast/campaign-list/account-list/detail/[id]/page.tsx new file mode 100644 index 00000000..e69de29b diff --git a/app/[locale]/(protected)/admin/broadcast/campaign-list/detail/[id]/page.tsx b/app/[locale]/(protected)/admin/broadcast/campaign-list/detail/[id]/page.tsx new file mode 100644 index 00000000..76cd9e5e --- /dev/null +++ b/app/[locale]/(protected)/admin/broadcast/campaign-list/detail/[id]/page.tsx @@ -0,0 +1,387 @@ +'use client' + +import "react-datepicker/dist/react-datepicker.css"; +import { Icon } from "@iconify/react"; +import Link from "next/link"; +import { useRouter, usePathname } from "next/navigation"; +import { useEffect, useState } from "react"; +import { useMediaQuery } from "react-responsive"; +import { close, loading } from "@/config/swal"; +import ReactDatePicker from "react-datepicker"; +import { getOnlyDate } from "@/utils/globals"; +import AccountListTable from "../../account-list/component/table"; +import { + ColumnDef, + ColumnFiltersState, + PaginationState, + SortingState, + VisibilityState, + flexRender, + getCoreRowModel, + getFilteredRowModel, + getPaginationRowModel, + getSortedRowModel, + useReactTable, +} from "@tanstack/react-table"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/components/ui/table"; +import { Button } from "@/components/ui/button"; +import TablePagination from "@/components/table/table-pagination"; +import { + getMediaBlastCampaignById, + getMediaBlastBroadcastList +} from "@/service/broadcast/broadcast"; + +// Types +interface CampaignData { + id: string; + no: number; + mediaBlastCampaignId: string; + mediaBlastCampaign: { + title: string; + }; + subject: string; + type: string; + status: string; + sendDate: string; +} + +interface PaginatedResponse { + content: CampaignData[]; + totalPages: number; + totalElements: number; +} + +interface PageProps { + params: { + id: string; + locale: string; + }; + searchParams: { + page?: string; + size?: string; + }; +} + +export default function BroadcastCampaignDetail({ params, searchParams }: PageProps) { + const router = useRouter(); + const pathname = usePathname(); + const { id, locale } = params; + const [getData, setGetData] = useState([]); + const [totalPage, setTotalPage] = useState(0); + const [totalData, setTotalData] = useState(0); + const [activeTab, setActiveTab] = useState<"sent" | "schedule" | "account-list">("sent"); + const { page, size } = searchParams; + + const [calenderState, setCalenderState] = useState(false); + const [typeFilter, setTypeFilter] = useState("email"); + const [dateRange, setDateRange] = useState<[Date, Date]>([new Date(), new Date()]); + const [startDate, endDate] = dateRange; + + const [startDateString, setStartDateString] = useState(); + const [endDateString, setEndDateString] = useState(); + + // Table state + const [sorting, setSorting] = useState([]); + const [columnFilters, setColumnFilters] = useState([]); + const [columnVisibility, setColumnVisibility] = useState({}); + const [rowSelection, setRowSelection] = useState({}); + const [pagination, setPagination] = useState({ + pageIndex: 0, + pageSize: parseInt(size || "10"), + }); + + const pages = page ? parseInt(page) - 1 : 0; + const currentPage = page ? parseInt(page) : 1; + const pageSize = parseInt(size || "10"); + + const isFHD = useMediaQuery({ + minWidth: 1920, + }); + + const setCurrentPage = (pageNumber: number) => { + const params = new URLSearchParams(searchParams); + params.set('page', pageNumber.toString()); + router.push(`${pathname}?${params.toString()}`); + }; + + async function getListPaginationData() { + loading(); + console.log("Type : ", typeFilter); + console.log("Date : ", startDateString, endDateString); + + try { + const res = await getMediaBlastBroadcastList( + pages, + activeTab === "schedule", + startDateString || "", + endDateString || "", + typeFilter, + id + ); + + close(); + if (res?.data?.data) { + setupData(res.data.data); + } + } catch (error) { + console.error("Error fetching data:", error); + close(); + } + } + + useEffect(() => { + getListPaginationData(); + }, [currentPage, pageSize, activeTab, endDateString, startDateString, typeFilter]); + + function setupData(rawData: PaginatedResponse) { + console.log("raw", rawData); + if (rawData !== undefined) { + const dataContent = rawData?.content; + const data: CampaignData[] = []; + + dataContent.forEach((element, i) => { + element.no = (currentPage - 1) * pageSize + i + 1; + data.push(element); + }); + + setGetData(data); + setTotalPage(rawData?.totalPages); + setTotalData(rawData?.totalElements); + } + } + + const columns: ColumnDef[] = [ + { + accessorKey: "no", + header: "No", + cell: ({ row }) => {row.getValue("no")}, + }, + { + accessorKey: "mediaBlastCampaign.title", + header: "Campaign", + cell: ({ row }) => ( + + {row.original.mediaBlastCampaign?.title} + + ), + }, + { + accessorKey: "subject", + header: "Judul", + cell: ({ row }) => ( + + {row.getValue("subject")} + + ), + }, + { + accessorKey: "type", + header: "Tipe", + cell: ({ row }) => ( +
+ {row.getValue("type")} +
+ ) + }, + { + accessorKey: "status", + header: "Status", + cell: ({ row }) => ( +
+ {row.getValue("status")} +
+ ) + }, + { + accessorKey: "sendDate", + header: "Tanggal & Waktu", + cell: ({ row }) => ( +
+ {row.getValue("sendDate")} +
+ ) + } + ]; + + const table = useReactTable({ + data: getData, + 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, + }, + }); + + useEffect(() => { + function initState() { + if (startDate != null && endDate != null) { + setStartDateString(getOnlyDate(startDate)); + setEndDateString(getOnlyDate(endDate)); + } + } + console.log('date range', dateRange); + initState(); + }, [calenderState, startDate, endDate]); + + const handleTypeFilter = (type: string) => { + setTypeFilter(type); + }; + + return ( +
+
+
+ + + +
+ + {activeTab === "account-list" ? ( + + ) : ( + <> +
+
+ + +
+
+
+ { + setDateRange(update as [Date, Date]); + }} + placeholderText="Pilih Tanggal" + onCalendarClose={() => setCalenderState(!calenderState)} + className="form-control rounded-pill" + /> +
+
+
+ +
+ + + {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. + + + )} + +
+ +
+ + )} +
+
+ ); +} diff --git a/app/[locale]/(protected)/admin/broadcast/page.tsx b/app/[locale]/(protected)/admin/broadcast/page.tsx index d3dd5505..5a4f4936 100644 --- a/app/[locale]/(protected)/admin/broadcast/page.tsx +++ b/app/[locale]/(protected)/admin/broadcast/page.tsx @@ -17,32 +17,6 @@ export default function AdminBroadcast() {
-
- - -
{tab === "Email Blast" && } {tab === "WhatsApp Blast" && }
diff --git a/service/broadcast/broadcast.ts b/service/broadcast/broadcast.ts index ffc82665..e55d5138 100644 --- a/service/broadcast/broadcast.ts +++ b/service/broadcast/broadcast.ts @@ -100,6 +100,18 @@ export async function saveMediaBlastBroadcast(data: any) { return httpPostInterceptor(url, data); } +export async function getMediaBlastBroadcastList( + page: number, + isScheduled: boolean, + startDate: string, + endDate: string, + type: string, + campaignId: string +) { + const url = `media/blast/broadcast/list?enablePage=1&page=${page}&isScheduled=${isScheduled}&type=${type}&startDate=${startDate}&endDate=${endDate}&campaignId=${campaignId}`; + return httpGetInterceptor(url); +} + export async function listDataPopUp( page: number, limit: string,