Commit 9d95be82 by Arjun Jhukal

updated the deposit history and withdrawl history along with user profile

parent d500e4bf
import DepositHistoryPage from '@/components/pages/dashboard/userDashboard/depositHistory'
import React from 'react'
export default function DepositHistory() {
return (
<DepositHistoryPage />
)
}
import AddPlayerForm from '@/components/pages/dashboard/adminDashboard/players/addPlayerForm'
import React from 'react'
export default async function UserAccountUpdate(props: { params: Promise<{ id: string }> }) {
const { id } = await props.params;
return (
<AddPlayerForm />
)
}
import React from 'react'
export default function UserPasswordChanger() {
return (
<div>UserPasswordChanger</div>
)
}
import { Button, InputLabel, OutlinedInput } from '@mui/material'
import { InfoCircle, WalletCheck } from '@wandersonalwes/iconsax-react'
import React from 'react'
export default function UserWallet() {
return (
<form action="#" className="wallet-form">
<InputLabel htmlFor="wallet_address">Wallet Address</InputLabel>
<OutlinedInput
name="wallet_address"
id="wallet_address"
value="17HzyHWNrdS7GpMArshSBLpJpcvrre93P6"
/>
<div className="info my-4">
<p className='flex items-center bg-[#EEFEC4] text-[#547D16] p-2 rounded-lg text-[10px] lg:text-[12px] gap-1 '><InfoCircle size={12} />You can only connect one wallet at a time. To update the wallet address,
change the wallet address and click update</p>
</div>
<Button variant='contained' color='secondary' sx={{
color: "#1E3634",
fontSize: "12px"
}} startIcon={<WalletCheck />}>Update</Button>
</form>
)
}
"use client";
import TabController from "@/components/molecules/TabController";
import UserProfileCard from "@/components/organism/Cards/UserProfileCard";
import Link from "next/link";
import { usePathname } from "next/navigation";
export default function ProfileTabs({ section }: { section: React.ReactNode }) {
const pathname = usePathname();
const links = [
{ href: "/account/profile/account", label: "Account Details" },
{ href: "/account/profile/wallet", label: "Wallet Information" },
{ href: "/account/profile/change-password", label: "Change Password" },
];
return (
<div className='profile__root'>
<div className="grid lg:grid-cols-12 gap-6">
<div className="col-span-12 lg:col-span-5">
<UserProfileCard />
</div>
<div className="col-span-12 lg:col-span-7">
<TabController links={links} />
{section}
</div>
</div>
</div>
);
}
import React from 'react'
export default function ProfilePage() {
return (
<div>ProfilePage</div>
)
}
import WithdrawnHistoryPage from '@/components/pages/dashboard/userDashboard/withdrawlHistory'
import React from 'react'
export default function WithdrawlHistory() {
return (
<WithdrawnHistoryPage />
)
}
import TabController from '@/components/molecules/TabController';
import EditIcon from '@/icons/EditIcon';
import { Coin, User } from '@wandersonalwes/iconsax-react';
import Image from 'next/image';
import Link from 'next/link';
import React from 'react'
export default function AccountLayout({ children, page }: { children: React.ReactNode; page: React.ReactNode }) {
const links = [
{
href: "/account/profile/account", label: "Account", icon: <User className='mx-auto' />
},
{
href: "/account/deposit-history", label: "Deposit History",
icon: <Coin className='mx-auto' />
},
{ href: "/account/withdrawl-history", label: "Withdrawal History", icon: <Coin className='mx-auto' /> },
];
return (
<section className="account__root">
{/* Sidebar */}
<TabController links={links} />
<>
{page}
</>
</section>
);
}
import { redirect } from "next/navigation";
export default function ProfilePage() {
return redirect("/account/profile/account");
}
import GameCredentialsPage from '@/components/pages/dashboard/userDashboard/gameCredentials'
import React from 'react'
export default function Credentials() {
return (
<GameCredentialsPage />
)
}
......@@ -7,7 +7,6 @@ export default async function UserGameDetail(props: { params: Promise<{ id: stri
const game = await getSingleGame(id);
console.log(game);
return <ExlusiveGameDetail game={game} />
}
......@@ -165,7 +165,7 @@
}
.tab__link::after {
@apply absolute left-0 bottom-0 w-full h-[2px] bg-primary opacity-0 translate-x-0 transition-all;
@apply absolute left-0 bottom-0 w-full h-[4px] bg-primary opacity-0 translate-x-0 transition-all;
content: "";
transform-origin: bottom right;
......@@ -179,4 +179,16 @@
.tab__link:hover::after {
@apply opacity-100 translate-x-1;
transform-origin: bottom left;
}
.status.success {
background-color: #12A211;
}
.status.unsuccessful {
background-color: #D03538;
}
.status.pending {
background-color: #F2BF53;
}
\ No newline at end of file
......@@ -8,7 +8,6 @@ import Box from '@mui/material/Box';
// third-party
import 'react-quill-new/dist/quill.snow.css';
import { useState } from 'react';
// project imports
......
"use client";
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import React from 'react'
export default function TabController({ links }: {
links: {
href: string;
label: string;
icon?: React.ReactNode;
}[]
}) {
const pathname = usePathname();
return (
<nav className="flex gap-4 mb-4">
{links.map((link) => {
const isActive = pathname === link.href;
return (
<Link
key={link.href}
href={link.href}
className={`tab__link p-4 text-[14px] text-center ${isActive ? "active " : ""
}`}
>
{link.icon && link.icon}
{link.label}
</Link>
);
})}
</nav>
)
}
import React from 'react'
export default function TransactionFilter() {
return (
<div>TransactionFilter</div>
)
}
import EditIcon from '@/icons/EditIcon'
import Image from 'next/image'
import React from 'react'
export default function UserProfileCard() {
return (
<div className="player__info text-center rounded-xl lg:rounded-3xl p-8 lg:py-10 lg:px-9" style={{
background: "linear-gradient(0deg, rgba(0, 0, 0, 0.20) 0%, rgba(0, 0, 0, 0.20) 100%), rgba(255, 255, 255, 0.10)"
}}>
<div className="player__profile bg-primary-grad p-[1px] rounded-full max-w-fit mx-auto relative">
<Image src={"/assets/images/auth-image.png"} alt='' width={100} height={100} className=' aspect-square rounded-full border-[5px] border-solid border-white' />
<div className="absolute left-[50%] translate-x-[-50%] bottom-[-10px]">
<EditIcon />
</div>
</div>
<h1 className="text-24 lg:text-[32px] text-white my-1">RamboXOX</h1>
<p className="text-white text-[11px] lg:text-[14px]">Joined: 04-09-2025</p>
<div className="grid grid-cols-1 md:grid-cols-2 gap-2 mt-4">
<div className="col-span-1 md:col-span-2 rounded-[14px] p-4 lg:py-6" style={{ background: "rgba(191, 26, 198, 0.10)" }}>
<div className="flex justify-center items-center gap-3">
<Image src={"/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-white block ">$30,000</strong>
<span className="text-white text-[9px]">Current Balance</span>
</div>
</div>
</div>
<div className="col-span-2 flex gap-2">
<div className="w-full rounded-[14px] p-4 lg:py-6" style={{ background: "rgba(191, 26, 198, 0.10)" }}>
<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-white block ">$30,000</strong>
<span className="text-white text-[9px]">Current Balance</span>
</div>
</div>
<div className="w-full rounded-[14px] p-4 lg:py-6" style={{ background: "rgba(191, 26, 198, 0.10)" }}>
<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-white block ">$30,000</strong>
<span className="text-white text-[9px]">Current Balance</span>
</div>
</div>
<div className="w-full rounded-[14px] p-4 lg:py-6" style={{ background: "rgba(191, 26, 198, 0.10)" }}>
<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-white block ">$30,000</strong>
<span className="text-white text-[9px]">Current Balance</span>
</div>
</div>
</div>
</div>
</div>
)
}
......@@ -13,28 +13,22 @@ const UserProfileMenu = () => {
const menuItems = [
{
label: "Profile",
href: "/profile",
href: "/account/profile/account",
icon: <Profile size="20" />,
},
{
label: "Game Credentials",
href: "#",
href: "/credentials",
icon: <Wallet2 size="20" />,
onClick: (e: React.MouseEvent) => {
e.preventDefault();
dispatch(clearTokens());
router.replace("/login");
},
textColor: "text-red-500",
},
{
label: "Deposit History",
href: "/deposit-history",
href: "/account/deposit-history",
icon: <Coin size="20" />,
},
{
label: "Withdraw History",
href: "/withdraw-history",
href: "/account/withdraw-history",
icon: <MoneySend size="20" />,
},
{
......@@ -57,7 +51,7 @@ const UserProfileMenu = () => {
component={item.href ? Link : "button"}
href={item.href || undefined}
onClick={item.onClick}
className={`flex items-center py-3 px-4 hover:bg-[#FBF4FB] ${item.textColor || ""}`}
className={`flex items-center py-3 px-4 hover:bg-[#FBF4FB]`}
>
<ListItemIcon className="min-w-[30px] mr-1">{item.icon}</ListItemIcon>
<ListItemText primary={item.label} />
......
......@@ -92,6 +92,26 @@ export default function AdminMenu({ open }: { open: boolean }) {
/>
</ListItemButton>
</ListItem>
<ListItem>
<ListItemButton
className={[
open ? "expanded" : "collapsed",
[
PATH.ADMIN.SETTINGS.ROOT,
].some(path => pathname.startsWith(path)) ? "active" : ""
].join(" ")}
onClick={() => { router.push(PATH.ADMIN.SETTINGS.ROOT) }}
>
<ListItemIcon className={open ? "expanded" : "collapsed"}>
<Setting2 />
</ListItemIcon>
<ListItemText
primary="Packs"
className={open ? "expanded" : "collapsed"}
/>
</ListItemButton>
</ListItem>
</List>
)
}
......@@ -218,11 +218,11 @@ export default function UserMenu({ open }: { open: boolean }) {
<div className="support">
<button type="button" className="ss-btn support__btn flex items-center gap-2 w-full justify-start">
<SupportIcon />
{open ? <strong className='text-[14px] font-semibold text-text-regular opacity-80'>Support</strong> : null}
{open ? <strong className='text-[14px] font-semibold opacity-80 !text-white'>Support</strong> : null}
</button>
{open ? <p className='mt-2 text-[11px] lg:text-[12px] text-center'>
<div className="w-[8px] h-[8px] bg-green-500 rounded-full inline-block"></div>
<span className='opacity-70'> 24x7 Support available</span>
<span className='opacity-70 !text-white'> 24x7 Support available</span>
</p> : null}
</div>
</Box>
......
......@@ -2,6 +2,7 @@
import React from "react";
import { flexRender, Table } from "@tanstack/react-table";
import { useAppSelector } from "@/hooks/hook";
interface CustomTableProps<TData> {
table: Table<TData>;
......@@ -14,6 +15,65 @@ export default function CustomTable<TData>({ table, loading = false,
emptyMessage = "No records found", skeletonRows = 5, }: CustomTableProps<TData>) {
const rowCount = table.getRowModel().rows.length;
const columnCount = table.getAllLeafColumns().length;
const user = useAppSelector((state) => state.auth.user)
if (user?.role.toUpperCase() === "USER") {
return (
<table className="min-w-full text-left">
<thead>
{table.getHeaderGroups().map((headerGroup) => (
<tr key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<th
key={header.id}
className="text-[12px] font-[600] text-white p-2 lg:p-4"
>
{flexRender(
header.column.columnDef.header,
header.getContext()
)}
</th>
))}
</tr>
))}
</thead>
<tbody>
{loading ? (
Array.from({ length: skeletonRows }).map((_, rowIndex) => (
<tr key={`skeleton-${rowIndex}`} className="animate-pulse">
{Array.from({ length: columnCount }).map((_, colIndex) => (
<td key={`skeleton-cell-${rowIndex}-${colIndex}`} className="text-[14px] p-2 lg:p-4 ">
<div className="h-4 w-full rounded bg-[rgba(255, 255, 255, 0.10)]" />
</td>
))}
</tr>
))
) : rowCount === 0 ? (
<tr>
<td
colSpan={columnCount}
className="text-center px-4 py-4 text-gray-500"
>
{emptyMessage}
</td>
</tr>
) : (
table.getRowModel().rows.map((row) => (
<tr key={row.id} className="">
{row.getVisibleCells().map((cell) => (
<td key={cell.id} className="text-[14px] px-4 py-4 ">
{flexRender(
cell.column.columnDef.cell,
cell.getContext()
)}
</td>
))}
</tr>
))
)}
</tbody>
</table>
)
}
return (
<table className="min-w-full border-collapse border border-gray-200 text-left">
<thead>
......
......@@ -38,6 +38,7 @@ export const PlayerValidationSchema = (isEdit: boolean) => Yup.object().shape({
});
export default function AddPlayerForm({ id }: { id?: string }) {
console.log("user id", id)
const dispatch = useAppDispatch();
const router = useRouter();
......
......@@ -123,7 +123,6 @@ export default function PlayerListing() {
onView={`${PATH.ADMIN.PLAYERS.ROOT}/${row.original.id}`}
onEdit={`${PATH.ADMIN.PLAYERS.EDIT_PLAYER.ROOT}/${row.original.id}`}
onDelete={async () => {
console.log("delete Clicked");
const response = await deletePlayer({ id: row.original.id }).unwrap();
dispatch(
showToast({
......
......@@ -25,7 +25,6 @@ export default function SiteSetting() {
gameProvider: Yup.string().required("Game provider is required"),
}),
onSubmit: (values) => {
console.log(values);
},
});
......
"use client";
import CustomTable from '@/components/organism/Table';
import { useGetAllDepositQuery } from '@/services/transaction';
import { SingleDepositProps } from '@/types/transaction';
import { ColumnDef, getCoreRowModel, getPaginationRowModel, useReactTable } from '@tanstack/react-table';
import React, { useState } from 'react'
export default function DepositHistoryPage() {
const [page, setPage] = useState(1);
const [pageSize, setPageSize] = useState(10);
const { data, isLoading } = useGetAllDepositQuery({
page,
per_page: pageSize
});
const columns: ColumnDef<SingleDepositProps>[] = [
{
accessorKey: 'id',
header: "ID",
cell: ({ row }) => row.original.transaction_id
},
{
accessorKey: 'transaction_date',
header: "Date",
},
{
accessorKey: 'amount',
header: "Amount",
},
{
accessorKey: 'game_name',
header: "Game",
},
{
accessorKey: 'available_balance',
header: "Available Balance",
},
{
accessorKey: "status",
header: "Status",
cell: ({ row }) => {
const status = row.original.status.toLowerCase();
const display = status.charAt(0).toUpperCase() + status.slice(1);
return (
<span className={`px-2 py-1 inline-block lg:text-[10px] text-white status rounded-[8px] ${status}`} >
{display}
</span>
);
},
}
]
const table = useReactTable({
data: data?.data?.data || [],
// data: dummyDeposits,
columns,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
})
return (
<CustomTable table={table} loading={isLoading} emptyMessage="You haven't deposite yet!" />
)
}
import { Refresh } from '@wandersonalwes/iconsax-react'
import React from 'react'
export default function BalanceRefresh({ label, icon }: { label: string; icon: boolean }) {
return (
<p className='text-[10px] lg:text-[12px] leading-[120%] font-[500] bg-primary-grad py-1 px-2 rounded-[12px] flex items-center gap-1 max-w-fit cursor-pointer'>
{icon ? <Refresh size={12} /> : ""}
{label || ""}
</p>
)
}
"use client";
import React from 'react'
import BalanceRefresh from './BalanceRefresh';
import { Eye, EyeSlash } from '@wandersonalwes/iconsax-react';
import { Tooltip } from '@mui/material';
export const CardPasswordField = ({ password }: { password: string }) => {
const [showPassword, setShowPassword] = React.useState(false);
return <>
<div className="flex justify-between items-center">
<Tooltip title={showPassword && password}>
<span className="text-[11px]">
{showPassword
? password.length > 16
? password.slice(0, 16) + "..."
: password
: "xxxxxxxxxxxxx"}
</span>
</Tooltip>
<div className="flex justify-end items-center gap-2">
<p className='cursor-pointer' onClick={() => {
setShowPassword(prev => !prev)
}}>
{
!showPassword ? <Eye size={14} className='text-secondary' /> : <EyeSlash size={14} className='text-secondary' />
}
</p>
<BalanceRefresh label="Reset" icon={false} />
</div>
</div>
</>
}
'use client';
import { Copy } from '@wandersonalwes/iconsax-react';
import { useState } from 'react';
interface CopyToClipboardProps {
text: string;
}
export default function CopyToClipboard({ text }: CopyToClipboardProps) {
const [copied, setCopied] = useState(false);
const handleCopy = async () => {
try {
await navigator.clipboard.writeText(text);
setCopied(true);
setTimeout(() => setCopied(false), 2000); // reset after 2 sec
} catch (error) {
console.error('Failed to copy text:', error);
}
};
return (
<p onClick={handleCopy} className="cursor-pointer text-primary">
<Copy className={`transition-all cursor-pointer ${copied ? 'text-green-500' : 'text-primary'}`} />
</p>
);
}
import { Box, Button } from '@mui/material'
import Image from 'next/image'
import React from 'react'
import BalanceRefresh from './BalanceRefresh'
import { Coin, Copy } from '@wandersonalwes/iconsax-react'
import Link from 'next/link'
import TapIcon from '@/icons/Tap'
import { CredentialsProps } from '@/types/game'
import { CardPasswordField } from './CardPasswordHandler'
import CopyToClipboard from './CopyToClipboard'
export default function CredentialsCard({ cred }: { cred: CredentialsProps }) {
return (
<Box sx={{
borderRadius: "24px",
background: "linear-gradient(0deg, rgba(0, 0, 0, 0.20) 0%, rgba(0, 0, 0, 0.20) 100%), rgba(255, 255, 255, 0.10)",
}} className="p-4 lg:p-6">
<div className="credentials__header flex gap-2">
<Image src={cred?.logo || "/assets/images/fallback.png"} alt={cred?.full_name} className='rounded-full aspect-square' width={74} height={74} />
<div className="game__detail">
<strong className='block text-[16px] text-white'>{cred.full_name}</strong>
<p className='text-[14px] my-[6px]'>SC: 59</p>
<BalanceRefresh label='Refresh Balance' icon={true} />
</div>
</div>
<ul className='mt-4'>
<li className='py-2 border-t border-b border-[rgba(255,255,255,0.2)] grid grid-cols-2'>
<span className='text-[12px] leading-[120%] font-[600]'>Entries :</span>
<span className='text-[11px]'>{cred.entries || "N/A"}</span>
</li>
<li className='py-2 border-b border-[rgba(255,255,255,0.2)] grid grid-cols-2'>
<span className='text-[12px] leading-[120%] font-[600]'>Username :</span>
<div className="flex justify-between items-center">
<span className='text-[11px]'>{cred?.credentials.username || "N/A"}</span>
{cred.credentials.username && <CopyToClipboard text={cred.credentials.username} />}
</div>
</li>
<li className='py-2 border-b border-[rgba(255,255,255,0.2)] grid grid-cols-2'>
<span className='text-[12px] leading-[120%] font-[600]'>Password :</span>
<CardPasswordField password={cred?.credentials.password} />
</li>
</ul>
<div className="action__group mt-4 flex justify-between gap-4">
<Button variant='contained' color='primary'
startIcon={<Coin />}
>Buy Coins</Button>
<Link href={cred.game_url} className='ss-btn bg-secondary-grad flex justify-center items-center text-[#426A66] gap-2 '>
<TapIcon />
Play Game
</Link>
</div>
</Box>
)
}
import React from 'react'
import CredentialsCard from './CredentialsCard'
import { getUserGameCredentials } from '@/serverApi/game';
export default async function GameCredentialsPage() {
const creds = await getUserGameCredentials();
return (
<section className="credentials__listing ">
<div className="section__title mb-8 lg:max-w-[521px]">
<h1 className='mb-2 text-[24px] lg:text-[32px]'>Game Credentials</h1>
<p className='text-[11px] lg:text-[14px]'>To start playing and cashing out your winnings, you’ll need a crypto wallet to purchase E-Credits and receive payouts. Don't worry—it’s quick and easy!</p>
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-2 lg:gap-4">
{creds?.data.length ? creds?.data.map((cred) => (
<div className="col-span-1" key={cred.full_name}>
<CredentialsCard cred={cred} />
</div>
)) : ""}
</div>
</section>
)
}
......@@ -7,12 +7,11 @@ import { Box, Button } from "@mui/material";
import SilverCoinIcon from "@/icons/SilverCoinIcon";
import ScreenShotSlider from "@/components/molecules/Sliders/ScreenShotSlider";
import CustomLightGallery from "@/components/organism/LightGallery";
import Link from "next/link";
export default function ExlusiveGameDetail({ game }: { game: SingleGameResponse }) {
console.log(game);
return (
<>
<section className="detail__banner mb-8">
<div className="grid grid-cols-12 gap-8 lg:gap-20">
......@@ -59,7 +58,7 @@ export default function ExlusiveGameDetail({ game }: { game: SingleGameResponse
</Box>
</div>
<Button variant="contained" color="primary">Play Now</Button>
{game?.data?.game_url ? <Link className="ss-btn bg-primary-grad" href={game?.data?.game_url}>Play Now</Link> : ""}
{game?.data?.screenshots ? <ScreenShotSlider screenshots={game.data.screenshots} /> : ""}
</div>
......@@ -67,7 +66,6 @@ export default function ExlusiveGameDetail({ game }: { game: SingleGameResponse
</div>
</section >
{game?.data?.subgames ? <section className="exclusive__game__gallery">
<div className="section__title">
<h2 className="text-[14px] lg:text-[16px] mb-4">Panda Master Games</h2>
......
"use client";
import CustomTable from '@/components/organism/Table';
import { useGetAllDepositQuery } from '@/services/transaction';
import { SingleDepositProps } from '@/types/transaction';
import { ColumnDef, getCoreRowModel, getPaginationRowModel, useReactTable } from '@tanstack/react-table';
import React, { useState } from 'react'
export default function WithdrawnHistoryPage() {
const [page, setPage] = useState(1);
const [pageSize, setPageSize] = useState(10);
const { data, isLoading } = useGetAllDepositQuery({
page,
per_page: pageSize
});
const columns: ColumnDef<SingleDepositProps>[] = [
{
accessorKey: 'id',
header: "ID",
cell: ({ row }) => row.original.transaction_id
},
{
accessorKey: 'transaction_date',
header: "Date",
},
{
accessorKey: 'amount',
header: "Amount",
},
{
accessorKey: 'game_name',
header: "Game",
},
{
accessorKey: 'available_balance',
header: "Available Balance",
},
{
accessorKey: "status",
header: "Status",
cell: ({ row }) => {
const status = row.original.status.toLowerCase();
const display = status.charAt(0).toUpperCase() + status.slice(1);
return (
<span className={`px-2 py-1 inline-block lg:text-[10px] text-white status rounded-[8px] ${status}`} >
{display}
</span>
);
},
}
]
const table = useReactTable({
data: data?.data?.data || [],
// data: dummyDeposits,
columns,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
})
return (
<CustomTable table={table} loading={isLoading} emptyMessage="You haven't deposite yet!" />
)
}
......@@ -6,6 +6,7 @@ import authModalSlice from "@/slice/authModalSlice";
import { gameApi } from "@/services/gameApi";
import { playerApi } from "@/services/playerApi";
import { providerApi } from "@/services/providerApi";
import { transactionApi } from "@/services/transaction";
export const store = configureStore({
reducer: {
......@@ -16,6 +17,7 @@ export const store = configureStore({
[gameApi.reducerPath]: gameApi.reducer,
[providerApi.reducerPath]: providerApi.reducer,
[playerApi.reducerPath]: playerApi.reducer,
[transactionApi.reducerPath]: transactionApi.reducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware()
......@@ -23,6 +25,7 @@ export const store = configureStore({
.concat(gameApi.middleware)
.concat(playerApi.middleware)
.concat(providerApi.middleware)
.concat(transactionApi.middleware)
})
......
import React from 'react'
export default function TapIcon() {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" fill="none">
<path d="M12.8332 11.4899V13.125C12.8332 13.608 12.4412 14 11.9582 14H2.73332C2.4189 14 2.1179 13.8734 1.89857 13.6482L0.998486 12.7266C0.539402 12.2663 0.431486 11.5226 0.820569 11.0011C1.22599 10.4568 1.94174 10.3372 2.48482 10.64C2.61432 10.7246 2.71232 10.7981 2.7689 10.8541L4.08257 12.1911V3.5C4.08257 2.79125 4.71432 2.23067 5.44524 2.34908C6.01865 2.44242 6.4159 2.98083 6.4159 3.56242V7.875L11.1497 9.24875C12.1466 9.53808 12.8332 10.4516 12.8332 11.4899ZM2.74732 6.59867C3.00865 6.41025 3.06815 6.04567 2.88032 5.78433C2.52215 5.28675 2.33315 4.69875 2.33315 4.08333C2.33315 2.47508 3.64157 1.16667 5.24982 1.16667C6.85807 1.16667 8.16649 2.47508 8.16649 4.08333C8.16649 4.69933 7.97749 5.28733 7.61932 5.78433C7.4309 6.04567 7.4904 6.41025 7.75232 6.59867C7.85557 6.67275 7.97457 6.70833 8.0924 6.70833C8.27382 6.70833 8.45232 6.62375 8.56607 6.46567C9.06774 5.76858 9.33257 4.94492 9.33257 4.08333C9.33257 1.83167 7.5009 0 5.24924 0C2.99757 0 1.16649 1.83167 1.16649 4.08333C1.16649 4.94492 1.4319 5.76858 1.93299 6.46567C2.12082 6.727 2.48482 6.7865 2.74732 6.59867Z" fill="#426A66" />
</svg>
)
}
......@@ -42,6 +42,18 @@ export const PATH = {
USER: {
GAMES: {
ROOT: "/exclusive-games",
},
PROFILE: {
root: "/profile",
ACCOUNT: {
ROOT: "/profile/account"
},
WALLET: {
root: "/profile/wallet"
},
PASSWORD: {
ROOT: "/profile/password"
}
}
}
}
\ No newline at end of file
import { GameResponseProps, SingleGameResponse } from "@/types/game";
import { CredentialsResponseProps, GameResponseProps, SingleGameResponse } from "@/types/game";
import { serverBaseQuery } from "./serverBaseQuery";
import { cookies } from "next/headers";
......@@ -10,9 +10,18 @@ export async function getSingleGame(id: string): Promise<SingleGameResponse> {
const cookieStore = await cookies();
const access_token = cookieStore.get("access_token")?.value;
console.log(access_token);
return serverBaseQuery(`/api/game/${id}`, {
token: access_token,
withAuth: true,
});
}
export async function getUserGameCredentials(): Promise<CredentialsResponseProps> {
const cookieStore = await cookies();
const access_token = cookieStore.get("access_token")?.value;
return serverBaseQuery<CredentialsResponseProps>(`/api/credentials`, {
token: access_token,
withAuth: true,
});
}
\ No newline at end of file
import { createApi } from "@reduxjs/toolkit/query/react";
import { baseQuery } from "./baseQuery";
import { DepositListProps, DepositProps, DepositUrlProps } from "@/types/transaction";
import { QueryParams } from "@/types/config";
export const transactionApi = createApi({
reducerPath: "transactionApi",
baseQuery: baseQuery,
tagTypes: ["transaction"],
endpoints: (builder) => ({
deposit: builder.mutation<DepositUrlProps, DepositProps>({
query: ({ gameId, amount }) => ({
url: `/api/payment/${gameId}`,
method: "POST",
body: amount
}),
invalidatesTags: ["transaction"]
}),
getAllDeposit: builder.query<DepositListProps, QueryParams>({
query: ({ search, page, per_page }) => {
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());
const queryString = params.toString();
return {
url: `/api/deposits${queryString ? `?${queryString}` : ''}`,
method: "GET"
}
},
providesTags: ['transaction']
})
})
})
export const { useDepositMutation, useGetAllDepositQuery } = transactionApi;
\ No newline at end of file
......@@ -6,7 +6,7 @@ export type LoginProps = {
}
export interface User {
id: number | string,
id: string,
name: string,
email: string,
first_name: string,
......
......@@ -27,6 +27,7 @@ export interface GameItem extends CommonGameProps {
thumbnail?: string | null;
screenshots?: string[] | null;
subgames?: string[] | null;
game_url?: string;
}
export interface Pagination {
......@@ -65,3 +66,22 @@ export const gameInitialValues: GameProps = {
provider: "",
profit: "",
};
export interface CredentialsProps {
name: string,
credentials: {
password: string,
username: string
},
logo: string | null,
game_url: string,
full_name: string,
custom_password: boolean
entries: string | number;
}
export interface CredentialsResponseProps {
data: CredentialsProps[];
success: string;
message: string;
}
\ No newline at end of file
import { Pagination } from "./game";
type TransactionStatus = "SUCCESS" | "UNSUCCESSFUL" | "PENDING";
export interface DepositProps {
gameId: string;
amount: number;
}
export interface DepositUrlProps {
payment_id: string;
status: string;
amount: number;
currency: string;
payment_url: string;
}
export interface SingleDepositProps {
id: number;
transaction_id: string;
username: string;
first_name: string;
last_name: string;
method: string;
game_name: string;
type: string;
amount: number;
sweepcoins: number;
transaction_date: string;
available_balance?: string;
status: TransactionStatus;
}
export interface DepositListProps {
data: {
data: SingleDepositProps[];
pagination: Pagination;
}
success: boolean;
message: string;
}
\ 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