Commit b8138d45 by Arjun Jhukal

updated the transaction page, game transaction and player transaction

parent 2bff9543
import PlayerDetailPage from '@/components/pages/dashboard/adminDashboard/players/playerDetail'
import React from 'react'
export default function PlayerDetail() {
export default async function PlayerDetail({ params }: { params: Promise<{ id: number }> }) {
const { id } = await params;
return (
<PlayerDetailPage />
<PlayerDetailPage id={id} />
)
}
import AllTransactionsPage from '@/components/pages/dashboard/adminDashboard/transaction'
import React from 'react'
export default function AllTransactions() {
return (
<AllTransactionsPage />
)
}
import { PATH } from '@/routes/PATH';
import { List, ListItem, ListItemButton, ListItemIcon, ListItemText } from '@mui/material'
import { Game, Notification, Paperclip2, Setting, Setting2, StatusUp, UserSearch } from '@wandersonalwes/iconsax-react'
import { ArrowSwapHorizontal, Game, Notification, Paperclip2, Setting, Setting2, StatusUp, UserSearch } from '@wandersonalwes/iconsax-react'
import { usePathname, useRouter } from 'next/navigation'
import React from 'react'
......@@ -17,7 +17,6 @@ export default function AdminMenu({ open }: { open: boolean }) {
].join(" ")}
onClick={() => { router.push(PATH.DASHBOARD.ROOT) }}
>
<ListItemIcon className={open ? "expanded" : "collapsed"}>
<StatusUp />
......@@ -32,6 +31,24 @@ export default function AdminMenu({ open }: { open: boolean }) {
<ListItemButton
className={[
open ? "expanded" : "collapsed",
pathname === "/transactions" ? "active" : ""
].join(" ")}
onClick={() => { router.push(PATH.ADMIN.TRANSACTIONS.ROOT) }}
>
<ListItemIcon className={open ? "expanded" : "collapsed"}>
<ArrowSwapHorizontal />
</ListItemIcon>
<ListItemText
primary="Transactions"
className={open ? "expanded" : "collapsed"}
/>
</ListItemButton>
</ListItem>
<ListItem>
<ListItemButton
className={[
open ? "expanded" : "collapsed",
[
PATH.ADMIN.GAMES.ROOT,
PATH.ADMIN.GAMES.ADD_GAME.ROOT,
......
......@@ -61,7 +61,7 @@ export default function CustomTable<TData>({ table, loading = false,
table.getRowModel().rows.map((row) => (
<tr key={row.id} className="">
{row.getVisibleCells().map((cell) => (
<td key={cell.id} className="px-4 py-4 ">
<td key={cell.id} className="px-4 py-4 text-[12px] text-title">
{flexRender(
cell.column.columnDef.cell,
cell.getContext()
......
......@@ -9,6 +9,7 @@ import { useParams } from 'next/navigation';
import { useGetGameByIdQuery } from '@/services/gameApi';
import { PATH } from '@/routes/PATH';
import { renderHTML } from '@/utils/RenderHTML';
import TransactionTable from '../../transaction/TransactionTable';
export default function GameDetailPage() {
const params = useParams();
......@@ -105,13 +106,19 @@ export default function GameDetailPage() {
{relatedGames.length ? <section className="game__screenshots mb-14">
<div className="section-title mb-4">
<h2 className="text-[20px] leading-[140%] font-[600]">
Games Under Diner Frenzy Spins
Games Under {data?.data?.name}
</h2>
</div>
<CustomLightGallery images={relatedGames} aspectRatio='aspect-[148/164]' column="7" />
</section> : null}
<TransactionBlock />
{/* <TransactionBlock /> */}
<div className="section-title mb-4">
<h2 className="text-[20px] leading-[140%] font-[600]">
All Transactions
</h2>
</div>
{data?.data?.id ? <TransactionTable game_id={data?.data?.id} /> : ""}
</>
)
......
"use client"
import CreditCard from '@/components/organism/Charts/CreditCard'
import EditIcon from '@/icons/EditIcon'
import { PATH } from '@/routes/PATH'
......@@ -5,6 +6,10 @@ import Image from 'next/image'
import Link from 'next/link'
import React from 'react'
import GameTransactionTable from '../../games/GameDetail/Transaction'
import TransactionTable from '../../transaction/TransactionTable'
import { useAppSelector } from '@/hooks/hook'
import { formatDateTime } from '@/utils/formatDateTime'
import { useGetPlayerBalanceByIdQuery, useGetPlayerByIdQuery } from '@/services/playerApi'
const games = [
{
......@@ -33,7 +38,19 @@ const games = [
},
];
export default function PlayerDetailPage() {
export default function PlayerDetailPage({ id }: { id: number }) {
const { data, isLoading } = useGetPlayerByIdQuery({ id }, {
skip: !id
})
const { data: userBalance, isLoading: loadingBalance } = useGetPlayerBalanceByIdQuery(
{ id: String(id) },
{ skip: !id }
);
const { date } = formatDateTime(data?.data?.registered_date as string);
console.log("user balance", userBalance);
return (
<>
<section className="player__detail__intro mb-12 lg:mb-16">
......@@ -46,15 +63,16 @@ export default function PlayerDetailPage() {
<EditIcon />
</div>
</div>
<h1 className="text-24 lg:text-[32px] text-title my-1">RamboXOX</h1>
<p className="text-para-light text-[11px] lg:text-[14px]">Joined: 04-09-2025</p>
<h1 className="text-24 lg:text-[32px] text-title my-1">{data?.data?.name}</h1>
<p className="text-para-light text-[11px] lg:text-[14px]">Joined: {date}</p>
<div className="grid grid-cols-1 md:grid-cols-2 gap-2 mt-4">
<div className="col-span-1 md:col-span-2 bg-light-gray rounded-[14px] p-4 lg:py-6">
<div className="flex justify-center items-center gap-3">
<Image src={"/assets/images/current-balance.svg"} alt='' width={48} height={48} />
<Image src={data?.data?.profile_image_file || "/assets/images/current-balance.svg"} alt='' width={48} height={48} />
<div className="content mt-3 text-start">
<strong className="text-[12px] leading-[120%] font-[700] text-primary block ">$30,000</strong>
<strong className="text-[12px] leading-[120%] font-[700] text-primary block ">${userBalance?.data?.current_balance || 0}</strong>
<span className="text-para-light text-[9px]">Current Balance</span>
</div>
</div>
......@@ -62,15 +80,15 @@ export default function PlayerDetailPage() {
<div className="col-span-1 bg-light-gray rounded-[14px] p-4 lg:py-6">
<Image src={"/assets/images/deposit.svg"} alt='' width={48} height={48} className='mx-auto' />
<div className="content mt-3 ">
<strong className="text-[12px] leading-[120%] font-[700] text-primary block ">$30,000</strong>
<span className="text-para-light text-[9px]">Current Balance</span>
<strong className="text-[12px] leading-[120%] font-[700] text-primary block ">${userBalance?.data?.total_deposited || 0}</strong>
<span className="text-para-light text-[9px]">Total Deposited</span>
</div>
</div>
<div className="col-span-1 bg-light-gray rounded-[14px] p-4 lg:py-6">
<Image src={"/assets/images/withdrawn.svg"} alt='' width={48} height={48} className='mx-auto' />
<div className="content mt-3">
<strong className="text-[12px] leading-[120%] font-[700] text-primary block ">$30,000</strong>
<span className="text-para-light text-[9px]">Current Balance</span>
<strong className="text-[12px] leading-[120%] font-[700] text-primary block ">${userBalance?.data?.total_withdrawl || 0}</strong>
<span className="text-para-light text-[9px]">Total Withdrawn</span>
</div>
</div>
</div>
......@@ -88,47 +106,47 @@ export default function PlayerDetailPage() {
<ul className="">
<li className="grid grid-cols-2 gap-y-4 gap-x-8 pb-4 mb-4 border-b border-b-gray">
<p className="text-[16px] font-[400] text-title">First Name</p>
<p className="text-para-light">Rambo</p>
<p className="text-para-light">{data?.data?.first_name}</p>
</li>
<li className="grid grid-cols-2 gap-y-4 gap-x-8 pb-4 mb-4 border-b border-b-gray">
<p className="text-[16px] font-[400] text-title">Last Name</p>
<p className="text-para-light">Shah</p>
<p className="text-para-light">{data?.data?.last_name}</p>
</li>
<li className="grid grid-cols-2 gap-y-4 gap-x-8 pb-4 mb-4 border-b border-b-gray">
<p className="text-[16px] font-[400] text-title">Display Name</p>
<p className="text-para-light">RamboXOX</p>
<p className="text-para-light">{data?.data?.name}</p>
</li>
<li className="grid grid-cols-2 gap-y-4 gap-x-8 pb-4 mb-4 border-b border-b-gray">
<p className="text-[16px] font-[400] text-title">Email Address</p>
<p className="text-para-light">rambo@gmail.com</p>
<p className="text-para-light">{data?.data?.email}</p>
</li>
<li className="grid grid-cols-2 gap-y-4 gap-x-8 pb-4 mb-4 border-b border-b-gray">
<p className="text-[16px] font-[400] text-title">Phone Number</p>
<p className="text-para-light">-</p>
<p className="text-para-light">{data?.data?.phone || "N/A"}</p>
</li>
<li className="grid grid-cols-2 gap-y-4 gap-x-8 pb-4 mb-4 border-b border-b-gray">
<p className="text-[16px] font-[400] text-title">Address Line</p>
<p className="text-para-light">-</p>
<p className="text-para-light">{data?.data?.address || "N/A"}</p>
</li>
<li className="grid grid-cols-2 gap-y-4 gap-x-8 pb-4 mb-4 border-b border-b-gray">
{/* <li className="grid grid-cols-2 gap-y-4 gap-x-8 pb-4 mb-4 border-b border-b-gray">
<p className="text-[16px] font-[400] text-title">State</p>
<p className="text-para-light">-</p>
</li>
<p className="text-para-light">{data?.data?.sta || "N/A"}</p>
</li> */}
<li className="grid grid-cols-2 gap-y-4 gap-x-8 pb-4 mb-4 border-b border-b-gray">
{/* <li className="grid grid-cols-2 gap-y-4 gap-x-8 pb-4 mb-4 border-b border-b-gray">
<p className="text-[16px] font-[400] text-title">City</p>
<p className="text-para-light">-</p>
</li>
<p className="text-para-light">{data?.data?.phone || "N/A"}</p>
</li> */}
<li className="grid grid-cols-2 gap-y-4 gap-x-8 pb-4 mb-4 border-b border-b-gray">
<p className="text-[16px] font-[400] text-title">Wallet Address</p>
<p className="text-para-light">17HzyHWNrdS7GpMArshSBLpJpcvrre93P6</p>
<p className="text-para-light">{data?.data?.wallet_address || "N/A"}</p>
</li>
</ul>
......@@ -137,7 +155,7 @@ export default function PlayerDetailPage() {
</div>
</section>
<section className="player__current__holdings">
<section className="player__current__holdings mb-8 lg:mb-16">
<div className="grid sm:grid-cols-2 lg:grid-cols-4 gap-2">
{games.map((game) => (
<div className="col-span-1" key={game.name}>
......@@ -147,6 +165,13 @@ export default function PlayerDetailPage() {
</div>
</section>
{/* <TransactionBlock /> */}
<div className="section-title mb-4">
<h2 className="text-[20px] leading-[140%] font-[600]">
All Transactions
</h2>
</div>
{data?.data?.id ? <TransactionTable user_id={data?.data?.id} /> : ""}
{/* <GameTransactionTable /> */}
</>
)
......
"use client";
import TableHeader from '@/components/molecules/TableHeader';
import CustomTable from '@/components/organism/Table';
import { useGetAllTransactionQuery } from '@/services/transaction';
import { SingleDepositProps } from '@/types/transaction';
import { formatDateTime } from '@/utils/formatDateTime';
import { getInitials } from '@/utils/getInitials';
import { Box, Pagination } from '@mui/material';
import {
ColumnDef,
getCoreRowModel,
getPaginationRowModel,
getSortedRowModel,
useReactTable
} from '@tanstack/react-table';
import React, { useMemo, useState } from 'react';
export default function TransactionTable({ user_id, game_id }: { user_id?: string; game_id?: number }) {
const [search, setSearch] = useState("");
const [sorting, setSorting] = useState<{ id: string; desc: boolean }[]>([]);
const [page, setPage] = useState(1);
const [pageSize, setPageSize] = useState(10);
const queryArgs = useMemo(
() => ({
page,
per_page: pageSize,
search: search || "",
game_id,
user_id,
}),
[page, pageSize, search, game_id, user_id]
);
const { data, isLoading: loadingTransaction } = useGetAllTransactionQuery(queryArgs);
console.log("all transaction", data);
const tableData = useMemo(() => data?.data?.data || [], [data]);
const columns = useMemo<ColumnDef<SingleDepositProps>[]>(() => [
{
accessorKey: "id",
header: "ID",
},
{
accessorKey: "name",
header: "Player Name",
cell: ({ row }) => {
const { first_name, last_name } = row.original;
const initials = getInitials(first_name, last_name);
return (
<Box className="flex justify-start items-center gap-2">
<small className="text-[10px] w-[24px] h-[24px] flex items-center justify-center uppercase rounded-[4px] bg-[#1EB41B]/10 font-[500] text-[#1EB41B]">
{initials}
</small>
<div className="name-detail">
<strong className="text-primary block text-[12px] leading-[120%] font-[500] capitalize">
{first_name} {last_name}
</strong>
<small className="text-[10px] text-para-light font-[500]">
{first_name} {last_name}
</small>
</div>
</Box>
);
},
},
{
accessorKey: "method",
header: "Method",
},
{
accessorKey: "game_name",
header: "Game Name",
},
{
accessorKey: "type",
header: "Type",
cell: ({ row }) => {
const status = row.original.status.toLowerCase();
const display = status.charAt(0).toUpperCase() + status.slice(1);
return (
<span
className={`px-2 py-1 max-w-[50px] block lg:text-[10px] text-white status rounded-[8px] text-center ${status}`}
>
{display}
</span>
);
},
},
{
accessorKey: "amount",
header: "Amount USD",
},
{
accessorKey: "sweepcoins",
header: "Sweepcoins",
},
{
accessorKey: "transaction_date",
header: "Transaction Date",
cell: ({ row }) => {
const { date, time } = formatDateTime(row.original.transaction_date as string);
return (
<Box>
<span className="text-[12px] font-[500] block">{date}</span>
<small className="text-[10px] text-para-light font-[500]">[{time}]</small>
</Box>
);
},
},
], []);
const table = useReactTable({
data: tableData,
columns,
state: { sorting },
onSortingChange: setSorting,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
});
return (
<div className="border-gray border-solid border-[1px] rounded-[8px] lg:rounded-[16px]">
<TableHeader search={search} setSearch={setSearch} onDownloadCSV={() => { }} />
<CustomTable
key={`${page}-${pageSize}-${search}-${game_id}-${user_id}`}
table={table} loading={loadingTransaction} />
{tableData.length > 10 ? <div className="flex justify-between items-center mt-4 px-8 py-6">
<div>
<span>Row per page:</span>
<select
value={pageSize}
onChange={(e) => setPageSize(Number(e.target.value))}
className="ml-2 border border-gray-300 rounded p-1"
>
{[5, 10, 15, 20].map((size) => (
<option key={size} value={size}>
{size}
</option>
))}
</select>
</div>
<Pagination
count={data?.data?.pagination?.total_pages || 1}
page={page}
onChange={(_, value) => setPage(value)}
variant="outlined"
shape="rounded"
sx={{ gap: "8px" }}
/>
</div> : ""}
</div>
);
}
import PageHeader from '@/components/molecules/PageHeader'
import React from 'react'
import TransactionTable from './TransactionTable'
export default function AllTransactionsPage() {
return (
<>
<PageHeader title='Tranactions' />
<TransactionTable />
</>
)
}
......@@ -74,8 +74,8 @@ export default function CoinCalculator({ slug }: { slug: string }) {
</p>
</div>
<div className="bonus">
<strong className='text-[16px] block'>+{bonusCoins}</strong>
<span className='text-[12px]'>bonus</span>
<strong className='text-[16px] block'>+ 10</strong>
{/* <span className='text-[12px]'>bonus</span> */}
</div>
</div>
......
......@@ -43,7 +43,7 @@ export default function CheckoutPage({ amount, slug, bonus }: {
<span className='text-[12px]'>Gold Coins</span>
</div>
<p>
<strong className='text-[16px] block'>500</strong>
<strong className='text-[16px] block'>{amount ? amount * 10 : ""}</strong>
</p>
</div>
......@@ -55,7 +55,7 @@ export default function CheckoutPage({ amount, slug, bonus }: {
>
<div className="coin flex items-center gap-1">
<GoldCoinIcon />
<span className='text-[12px]'>Bonus Coins</span>
<span className='text-[12px]'>Free Sweeps Coins</span>
</div>
<p>
<strong className='text-[16px] block'>{bonus}</strong>
......
......@@ -17,6 +17,9 @@ export const PATH = {
}
},
ADMIN: {
TRANSACTIONS: {
ROOT: "/transactions",
},
GAMES: {
ROOT: "/games",
ADD_GAME: {
......
......@@ -52,7 +52,23 @@ export const transactionApi = createApi({
},
providesTags: ["withdrawl"]
}),
getAllTransaction: builder.query<DepositListProps, QueryParams & { user_id?: string | number; game_id?: string | number }>({
query: ({ search, page, per_page, user_id, game_id }) => {
const params = new URLSearchParams();
if (search) params.append('search', search);
if (page) params.append('page', page.toString());
if (per_page) params.append('page_size', per_page.toString());
if (user_id) params.append('user', user_id.toString());
if (game_id) params.append('game', game_id.toString());
const queryString = params.toString();
return {
url: `/api/admin/transactions${queryString ? `?${queryString}` : ''}`,
method: "GET"
}
},
providesTags: ["withdrawl", "deposit"]
}),
})
})
export const { useDepositMutation, useGetAllDepositQuery, useWithdrawlMutation, useGetAllWithdrawlQuery } = transactionApi;
\ No newline at end of file
export const { useDepositMutation, useGetAllDepositQuery, useWithdrawlMutation, useGetAllWithdrawlQuery, useGetAllTransactionQuery } = transactionApi;
\ No newline at end of file
......@@ -43,6 +43,7 @@ export interface PlayerItem extends CommonPlayerProps {
id: string;
registered_date: string | Date;
current_credit?: string,
current_balance?: string,
total_withdrawl?: string,
total_deposited?: string
profile_image_file?: string;
......
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