Commit a36b8a6b by Arjun Jhukal

updated the downloading functionality for the transaction tble

parent b9b84d7b
// // import { Button, IconButton, InputAdornment, OutlinedInput, useMediaQuery } from "@mui/material";
// // import SelectField from "../atom/SelectField";
// // import { DocumentDownload, SearchNormal } from "@wandersonalwes/iconsax-react";
// // interface TableHeaderProps {
// // search: string;
// // setSearch?: (value: string) => void;
// // filterMethod?: string;
// // setFilterMethod?: (value: string) => void;
// // onDownloadCSV: () => void;
// // }
// // export default function TableHeader({
// // search,
// // setSearch,
// // filterMethod,
// // setFilterMethod,
// // onDownloadCSV,
// // }: TableHeaderProps) {
// // const downMD = useMediaQuery((theme) => theme.breakpoints.down('md'));
// // return (
// // <div className="table__header p-4 mb-4 flex justify-between">
// // <div className="inpute__field relative">
// // <OutlinedInput
// // placeholder="Search keywords..."
// // name="search"
// // id="search"
// // value={search}
// // onChange={(e) => setSearch && setSearch(e.target.value)}
// // startAdornment={
// // <InputAdornment position="start">
// // <IconButton edge="start">
// // <SearchNormal size={20} />
// // </IconButton>
// // </InputAdornment>
// // }
// // />
// // </div>
// // {filterMethod ? <div className="header-right flex justify-end items-center gap-2">
// // <SelectField
// // name="search"
// // value={filterMethod}
// // onChange={(e) => setFilterMethod && setFilterMethod(e.target.value)}
// // options={[
// // { value: "all", name: "All Method" },
// // { value: "crypto", name: "Crypto" },
// // { value: "paypal", name: "USD/Paypal" },
// // ]}
// // />
// // </div> : ""}
// // <Button
// // startIcon={
// // !downMD && <DocumentDownload size={16} />
// // }
// // onClick={onDownloadCSV} sx={{
// // borderRadius: "8px",
// // border: "1px solid var(--Gray, #E0E0E3)",
// // padding: "8px 16px",
// // color: "#0E0E11",
// // maxWidth: "fit-content",
// // }}>{downMD ? <DocumentDownload size={16} /> : "Download CSV"}</Button>
// // </div>
// // );
// // }
// import { Button, IconButton, InputAdornment, OutlinedInput, useMediaQuery } from "@mui/material";
// import SelectField from "../atom/SelectField";
// import { DocumentDownload, SearchNormal } from "@wandersonalwes/iconsax-react";
// interface FilterOption {
// value: string;
// label: string;
// }
// interface TableHeaderProps {
// search: string;
// setSearch?: (value: string) => void;
// filterMethod?: string;
// setFilterMethod?: (value: string) => void;
// filterOptions?: FilterOption[];
// onDownloadCSV: () => void;
// }
// export default function TableHeader({
// search,
// setSearch,
// filterMethod,
// setFilterMethod,
// filterOptions,
// onDownloadCSV,
// }: TableHeaderProps) {
// const downMD = useMediaQuery((theme: any) => theme.breakpoints.down('md'));
// return (
// <div className="table__header p-4 mb-4 flex justify-between items-center gap-4">
// <div className="inpute__field relative">
// <OutlinedInput
// placeholder="Search keywords..."
// name="search"
// id="search"
// value={search}
// onChange={(e) => setSearch && setSearch(e.target.value)}
// startAdornment={
// <InputAdornment position="start">
// <IconButton edge="start">
// <SearchNormal size={20} />
// </IconButton>
// </InputAdornment>
// }
// />
// </div>
// <div className="header-right flex justify-end items-center gap-2">
// {filterOptions && (
// <SelectField
// name="filter"
// value={filterMethod || ""}
// onChange={(e) => setFilterMethod && setFilterMethod(e.target.value)}
// options={filterOptions.map(option => ({
// value: option.value,
// name: option.label
// }))}
// />
// )}
// {onDownloadCSV ? <Button
// startIcon={!downMD && <DocumentDownload size={16} />}
// onClick={onDownloadCSV}
// sx={{
// borderRadius: "8px",
// border: "1px solid var(--Gray, #E0E0E3)",
// padding: "8px 16px",
// color: "#0E0E11",
// maxWidth: "fit-content",
// }}
// >
// {downMD ? <DocumentDownload size={16} /> : "Download CSV"}
// </Button> : ""}
// </div>
// </div>
// );
// }
import { Button, IconButton, InputAdornment, OutlinedInput, useMediaQuery } from "@mui/material";
import SelectField from "../atom/SelectField";
import { DocumentDownload, SearchNormal } from "@wandersonalwes/iconsax-react";
import React from "react";
interface FilterOption {
value: string;
......@@ -161,6 +21,8 @@ interface TableHeaderProps {
filters?: { value: string; setValue: (value: string) => void; options: FilterOption[], placeholder?: string }[];
filterOptions?: FilterOption[];
onDownloadCSV: () => void;
downloading?: boolean;
debounceDelay?: number;
}
export default function TableHeader({
......@@ -171,10 +33,29 @@ export default function TableHeader({
filters,
onDownloadCSV,
filterOptions,
downloading,
debounceDelay = 500,
}: TableHeaderProps) {
const downMD = useMediaQuery((theme: any) => theme.breakpoints.down('md'));
const [localSearch, setLocalSearch] = React.useState(search);
React.useEffect(() => {
const handler = setTimeout(() => {
if (setSearch && localSearch !== search) {
setSearch(localSearch);
}
}, debounceDelay);
return () => {
clearTimeout(handler);
};
}, [localSearch, debounceDelay]);
React.useEffect(() => {
setLocalSearch(search);
}, [search]);
return (
<div className="table__header p-4 mb-4 flex flex-wrap justify-between items-center gap-4">
{/* Search Field */}
......@@ -232,7 +113,7 @@ export default function TableHeader({
maxWidth: "fit-content",
}}
>
{downMD ? <DocumentDownload size={16} /> : "Download CSV"}
{downMD ? <DocumentDownload size={16} /> : downloading ? "Downloading..." : "Download CSV"}
</Button>
</div>
</div>
......
......@@ -132,7 +132,7 @@ export default function RegisterPage() {
}
</div>
</div>
<div className="col-span-1">
<div className="col-span-2 lg:col-span-1">
<div className="input_field">
<PasswordField
name="password"
......@@ -145,7 +145,7 @@ export default function RegisterPage() {
/>
</div>
</div>
<div className="col-span-1">
<div className="col-span-2 lg:col-span-1">
<div className="input_field">
<PasswordField
name="confirmPassword"
......
......@@ -32,7 +32,7 @@ export default function Activities() {
const [pageSize, setPageSize] = React.useState(10);
const [activityType, setActivityType] = React.useState("");
const [sorting, setSorting] = React.useState<any>([]);
// const [download, { isLoading: downloading }] = useStartDownloadMutation();
const queryArgs = useMemo(
() => ({
page,
......@@ -164,6 +164,7 @@ export default function Activities() {
{ value: status || "", setValue: (value) => setStatus(value as TransactionStatusProps), options: StatusOptions, placeholder: "Filter by status" }
]}
onDownloadCSV={() => { }}
// downloading={downloading}
/>
<CustomTable
......
......@@ -9,7 +9,6 @@ import { useGetGameByIdQuery } from '@/services/gameApi';
import { PATH } from '@/routes/PATH';
import { renderHTML } from '@/utils/RenderHTML';
import TransactionTable from '../../transaction/TransactionTable';
import TableHeader from '@/components/molecules/TableHeader';
export default function GameDetailPage() {
const params = useParams();
......
"use client";
import TableHeader from '@/components/molecules/TableHeader';
import CustomTable from '@/components/organism/Table';
import { useAppDispatch } from '@/hooks/hook';
import { useDownloadTransactionMutation } from '@/services/downloadApi';
import { useGetAllTransactionQuery } from '@/services/transaction';
import { showToast, ToastVariant } from '@/slice/toastSlice';
import { StatusOptions } from '@/types/config';
import { SingleDepositProps } from '@/types/transaction';
import { formatDateTime } from '@/utils/formatDateTime';
......@@ -20,6 +23,8 @@ import React, { useMemo, useState } from 'react';
export type TransactionStatusProps = "success" | "failed" | "pending";
export default function TransactionTable({ user_id, game_id, search, setSearch }: { user_id?: string; game_id?: number, search: string, setSearch?: (newvalue: string) => void }) {
const dispatch = useAppDispatch();
const [sorting, setSorting] = useState<{ id: string; desc: boolean }[]>([]);
const [page, setPage] = useState(1);
const [pageSize, setPageSize] = useState(10);
......@@ -38,6 +43,7 @@ export default function TransactionTable({ user_id, game_id, search, setSearch }
);
const { data, isLoading: loadingTransaction } = useGetAllTransactionQuery(queryArgs);
const [downloadTransaction, { isLoading: downloading }] = useDownloadTransactionMutation();
const tableData = useMemo(() => data?.data?.data || [], [data]);
......@@ -156,7 +162,26 @@ export default function TransactionTable({ user_id, game_id, search, setSearch }
<TableHeader
search={search}
setSearch={setSearch && setSearch}
onDownloadCSV={() => { }}
onDownloadCSV={async () => {
try {
const response = await downloadTransaction({ user: user_id, game: game_id?.toString() }).unwrap();
dispatch(
showToast({
variant: ToastVariant.SUCCESS,
message: response.message || "CSV Downloaded successfully."
})
)
}
catch (e: any) {
dispatch(
showToast({
variant: ToastVariant.ERROR,
message: e.message || "Unable to download CSV."
})
)
}
}}
downloading={downloading}
filters={[
{ value: status || "", setValue: (value) => setStatus(value as TransactionStatusProps), options: StatusOptions, placeholder: "Filter by status" }
]}
......
......@@ -13,6 +13,7 @@ import { pageApi } from "@/services/pageApi";
import { notificationApi } from "@/services/notificationApi";
import { menuApi, userMenuApi } from "@/services/menuApi";
import { dashboardApi } from "@/services/dashboardApi";
import { downloadApi } from "@/services/downloadApi";
export const store = configureStore({
reducer: {
......@@ -31,6 +32,7 @@ export const store = configureStore({
[menuApi.reducerPath]: menuApi.reducer,
[userMenuApi.reducerPath]: userMenuApi.reducer,
[dashboardApi.reducerPath]: dashboardApi.reducer,
[downloadApi.reducerPath]: downloadApi.reducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware()
......@@ -46,6 +48,7 @@ export const store = configureStore({
.concat(menuApi.middleware)
.concat(userMenuApi.middleware)
.concat(dashboardApi.middleware)
.concat(downloadApi.middleware)
})
export type RootState = ReturnType<typeof store.getState>;
......
import { createApi } from "@reduxjs/toolkit/query/react";
import { baseQuery } from "./baseQuery";
import { GlobalResponse } from "@/types/config";
export const downloadApi = createApi({
reducerPath: "downloadApi",
baseQuery: baseQuery,
tagTypes: ["Download"],
endpoints: (builder) => ({
downloadTransaction: builder.mutation<GlobalResponse, { user?: string; game?: string }>({
query: ({ user, game }) => {
const params = new URLSearchParams();
if (user) params.append('user', user.toString());
if (game) params.append('game', game.toString());
const queryString = params.toString();
return {
url: `/api/admin/download/transactions${queryString ? `?${queryString}` : ''}`,
method: "GET",
}
}
})
})
})
export const { useDownloadTransactionMutation } = downloadApi;
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment