Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
sweepstake
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Arjun Jhukal
sweepstake
Commits
0f9f3779
Commit
0f9f3779
authored
Oct 07, 2025
by
Arjun Jhukal
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
updated the notification listing at admin side
parent
4d2d7d0f
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
428 additions
and
186 deletions
+428
-186
DashboardProvider.tsx
...pp/(dashboard)/(user)/(outsideAuth)/DashboardProvider.tsx
+1
-1
page.tsx
.../(dashboard)/(user)/(outsideAuth)/general/[slug]/page.tsx
+0
-1
page.tsx
src/app/(dashboard)/(user)/(outsideAuth)/page.tsx
+136
-90
globals.css
src/app/globals.css
+5
-0
SelectField.tsx
src/components/atom/SelectField.tsx
+0
-1
index.tsx
src/components/organism/Header/AdminHeader/index.tsx
+10
-5
Notification.tsx
src/components/organism/Header/Notification.tsx
+12
-14
BannerSlider.tsx
.../pages/dashboard/adminDashboard/settings/BannerSlider.tsx
+97
-34
index.tsx
src/components/pages/dashboard/index.tsx
+67
-33
UserCoin.tsx
...ard/games/exclusiveGames/exclusiveGameDetail/UserCoin.tsx
+0
-1
index.tsx
.../pages/dashboard/userDashboard/withdrawlHistory/index.tsx
+0
-1
store.ts
src/hooks/store.ts
+3
-0
pages.ts
src/serverApi/pages.ts
+9
-0
notificationApi.tsx
src/services/notificationApi.tsx
+35
-0
settingApi.ts
src/services/settingApi.ts
+21
-5
notification.ts
src/types/notification.ts
+17
-0
setting.ts
src/types/setting.ts
+15
-0
No files found.
src/app/(dashboard)/(user)/(outsideAuth)/DashboardProvider.tsx
View file @
0f9f3779
...
@@ -5,7 +5,7 @@ import React from 'react'
...
@@ -5,7 +5,7 @@ import React from 'react'
export
default
function
DashboardProvider
({
children
}:
{
children
:
React
.
ReactNode
})
{
export
default
function
DashboardProvider
({
children
}:
{
children
:
React
.
ReactNode
})
{
const
[
search
,
setSearch
]
=
React
.
useState
(
""
);
const
[
search
,
setSearch
]
=
React
.
useState
(
""
);
const
user
=
useAppSelector
(
state
=>
state
.
auth
.
user
);
const
user
=
useAppSelector
(
state
=>
state
?
.
auth
.
user
);
if
(
user
?.
role
&&
user
.
role
.
toUpperCase
()
===
"ADMIN"
)
{
if
(
user
?.
role
&&
user
.
role
.
toUpperCase
()
===
"ADMIN"
)
{
return
<>
return
<>
<
h1
className=
"text-[24px] leading-[120%] mb-6"
>
Dashboard
</
h1
>
<
h1
className=
"text-[24px] leading-[120%] mb-6"
>
Dashboard
</
h1
>
...
...
src/app/(dashboard)/(user)/(outsideAuth)/general/[slug]/page.tsx
View file @
0f9f3779
...
@@ -7,7 +7,6 @@ import React from 'react'
...
@@ -7,7 +7,6 @@ import React from 'react'
export
default
async
function
GeneralPage
(
props
:
{
params
:
Promise
<
{
slug
:
string
}
>
})
{
export
default
async
function
GeneralPage
(
props
:
{
params
:
Promise
<
{
slug
:
string
}
>
})
{
const
{
slug
}
=
await
props
.
params
;
const
{
slug
}
=
await
props
.
params
;
let
pageData
=
null
;
let
pageData
=
null
;
console
.
log
(
pageData
);
try
{
try
{
pageData
=
await
getPageDetail
(
slug
);
pageData
=
await
getPageDetail
(
slug
);
...
...
src/app/(dashboard)/(user)/(outsideAuth)/page.tsx
View file @
0f9f3779
...
@@ -5,12 +5,15 @@ import { getAllGames, getSubGames, getUsp } from "@/serverApi/game";
...
@@ -5,12 +5,15 @@ import { getAllGames, getSubGames, getUsp } from "@/serverApi/game";
import
{
Tooltip
}
from
"@mui/material"
;
import
{
Tooltip
}
from
"@mui/material"
;
import
Image
from
"next/image"
;
import
Image
from
"next/image"
;
import
DashboardProvider
from
"./DashboardProvider"
;
import
DashboardProvider
from
"./DashboardProvider"
;
import
{
getBanners
,
getSubBanners
}
from
"@/serverApi/pages"
;
import
Link
from
"next/link"
;
export
default
async
function
Home
()
{
export
default
async
function
Home
()
{
let
games
=
null
;
let
games
=
null
;
let
usps
=
null
;
let
usps
=
null
;
let
subGames
=
null
;
let
subGames
=
null
;
let
banners
=
null
;
let
subBanners
=
null
;
try
{
try
{
games
=
await
getAllGames
();
games
=
await
getAllGames
();
}
catch
(
err
)
{
}
catch
(
err
)
{
...
@@ -35,15 +38,25 @@ export default async function Home() {
...
@@ -35,15 +38,25 @@ export default async function Home() {
console
.
log
(
"❌ Failed to fetch games:"
,
err
);
console
.
log
(
"❌ Failed to fetch games:"
,
err
);
return
<
p
className=
"text-red-500"
>
Failed to load games.
</
p
>;
return
<
p
className=
"text-red-500"
>
Failed to load games.
</
p
>;
}
}
try
{
banners
=
await
getBanners
();
console
.
log
({
subGames
:
subGames
.
data
,
usps
})
}
catch
(
err
)
{
console
.
log
(
"❌ Failed to fetch banner:"
,
err
);
return
<
p
className=
"text-red-500"
>
Failed to load banner.
</
p
>;
}
try
{
subBanners
=
await
getSubBanners
();
}
catch
(
err
)
{
console
.
log
(
"❌ Failed to fetch sub banner:"
,
err
);
return
<
p
className=
"text-red-500"
>
Failed to load sub banner.
</
p
>;
}
// console.log({ subGames: subGames.data, usps })
return
(
return
(
<
DashboardProvider
>
<
DashboardProvider
>
<>
<>
<
Dashboard
/>
{
banners
?.
data
.
length
?
<
Dashboard
slides=
{
banners
.
data
}
/>
:
""
}
<
div
className=
"grid gap-4 md:grid-cols-2 lg:grid-cols-4 2xl:grid-cols-5 mb-8"
>
<
div
className=
"grid gap-4 md:grid-cols-2 lg:grid-cols-4 2xl:grid-cols-5 mb-8"
>
{
games
?.
data
?.
data
.
map
((
game
)
=>
(
{
games
?.
data
?.
data
.
map
((
game
)
=>
(
...
@@ -88,90 +101,123 @@ export default async function Home() {
...
@@ -88,90 +101,123 @@ export default async function Home() {
))
}
))
}
</
div
>
</
div
>
</
section
>
</
section
>
<
div
className=
"dashboard-card-wrapper grid grid-cols-2 gap-5 justify-center"
>
<
div
className=
"dashboard-card1 flex px-10 gap-2 rounded-[24px]"
{
subBanners
?.
data
.
length
?
style=
{
{
<
div
className=
"dashboard-card-wrapper grid grid-cols-2 gap-5 justify-center"
>
background
:
"rgba(255, 255, 255, 0.20)"
,
{
subBanners
?.
data
?.
length
>
0
&&
}
}
>
subBanners
.
data
.
map
((
subBanner
,
index
)
=>
(
<
div
className=
"py-7 gap-6"
>
<
div
<
h1
key=
{
subBanner
.
name
||
index
}
className=
"text-[40px] mb-[8px]"
className=
"dashboard-card1 flex justify-between px-10 gap-2 rounded-[24px]"
style=
{
{
style=
{
{
color
:
"#FBD230"
,
background
:
lineHeight
:
"96%"
,
index
%
2
===
0
letterSpacing
:
"-0.682px"
,
?
"rgba(255, 255, 255, 0.10)"
}
}
>
:
"rgba(255, 255, 255, 0.20)"
,
Welcome BONUS!!
}
}
</
h1
>
>
<
p
<
div
className=
"py-7 gap-6"
>
className=
"text-[13px] mb-[12px]"
{
/* ✅ Render title if available */
}
style=
{
{
lineHeight
:
"120%"
,
color
:
"#FBD230"
}
}
>
{
subBanner
?.
name
&&
(
10$ on first play.
<
h1
</
p
>
className=
"text-[40px] mb-[8px]"
<
a
style=
{
{
href=
"#"
color
:
"#FBD230"
,
className=
"px-[18px] py-[11px] rounded-[28px]"
lineHeight
:
"96%"
,
style=
{
{
letterSpacing
:
"-0.682px"
,
background
:
}
}
"linear-gradient(270deg, #F9B901 0.09%, #D09F12 95.19%)"
,
>
}
}
>
{
subBanner
.
name
}
Play Now
</
h1
>
</
a
>
)
}
</
div
>
<
div
className=
"dashboard-card-img aspect-[245/245]"
>
{
/* ✅ Render description if available */
}
<
img
{
subBanner
?.
description
&&
(
src=
"/assets/images/card1.png"
<
p
alt=
""
className=
"text-[13px] mb-[12px]"
// className="w-[245px] h-[245px]"
style=
{
{
lineHeight
:
"120%"
,
color
:
"#FBD230"
}
}
className=
"h-auto max-w-full "
>
style=
{
{
width
:
"245px"
,
height
:
"245px"
}
}
{
subBanner
.
description
}
/>
</
p
>
</
div
>
)
}
</
div
>
<
div
{
/* ✅ Render CTA button if link exists */
}
className=
"dashboard-card2 flex px-[45px] gap-2 rounded-[24px]"
{
subBanner
?.
cta_link
&&
(
style=
{
{
<
Link
background
:
"rgba(255, 255, 255, 0.10)"
,
href=
{
subBanner
.
cta_link
}
}
}
>
className=
"px-[18px] py-[11px] rounded-[28px] inline-block"
<
div
className=
"py-[45px] gap-6"
>
style=
{
{
<
h1
background
:
className=
"text-[40px] mb-[10px]"
index
%
2
===
0
style=
{
{
?
"linear-gradient(270deg, #D620D9 0.09%, #B40EF0 95.19%)"
color
:
"#1AF7FE"
,
:
"linear-gradient(270deg, #F9B901 0.09%, #D09F12 95.19%)"
,
letterSpacing
:
"-0.682px"
,
}
}
lineHeight
:
"96%"
,
target=
"_blank"
}
}
>
>
Easy.Set.Play
Play Now
</
h1
>
</
Link
>
<
p
)
}
className=
"text-[13px] mb-[12px]"
</
div
>
style=
{
{
color
:
"#E7BCFE"
,
lineHeight
:
"120%"
}
}
>
Join the Fun today.
{
/* ✅ Render image only if available */
}
</
p
>
{
subBanner
?.
image_url
&&
(
<
a
<
div
className=
"dashboard-card-img aspect-[245/245]"
>
href=
"#"
<
Image
className=
"px-[18px] py-[11px] rounded-[28px]"
src=
{
subBanner
.
image_url
}
style=
{
{
alt=
{
subBanner
.
name
||
"Sub Banner"
}
background
:
className=
"h-auto max-w-full"
"linear-gradient(270deg, #D620D9 0.09%, #B40EF0 95.19%)"
,
width=
{
245
}
}
}
>
height=
{
245
}
Play Now
/>
</
a
>
</
div
>
</
div
>
)
}
<
div
className=
"dashboard-card-img "
>
</
div
>
<
img
))
}
src=
"/assets/images/card2.png"
alt=
""
{
/* <div
// className="w-[245px] h-[245px]"
className="dashboard-card2 flex px-[45px] gap-2 rounded-[24px]"
className=
"h-auto max-w-full "
style={{
style=
{
{
width
:
"245px"
,
height
:
"245px"
}
}
background: "rgba(255, 255, 255, 0.10)",
/>
}}>
</
div
>
<div className="py-[45px] gap-6">
</
div
>
<h1
</
div
>
className="text-[40px] mb-[10px]"
style={{
color: "#1AF7FE",
letterSpacing: "-0.682px",
lineHeight: "96%",
}}>
Easy.Set.Play
</h1>
<p
className="text-[13px] mb-[12px]"
style={{ color: "#E7BCFE", lineHeight: "120%" }}>
Join the Fun today.
</p>
<a
href="#"
className="px-[18px] py-[11px] rounded-[28px] inline-block"
style={{
background:
"linear-gradient(270deg, #D620D9 0.09%, #B40EF0 95.19%)",
}}>
Play Now
</a>
</div>
<div className="dashboard-card-img ">
<img
src="/assets/images/card2.png"
alt=""
// className="w-[245px] h-[245px]"
className="h-auto max-w-full "
style={{ width: "245px", height: "245px" }}
/>
</div>
</div> */
}
</
div
>
:
null
}
<
UspSlider
uspData=
{
usps
.
data
||
[]
}
/>
<
UspSlider
uspData=
{
usps
.
data
||
[]
}
/>
</>
</>
</
DashboardProvider
>
</
DashboardProvider
>
);
);
}
}
src/app/globals.css
View file @
0f9f3779
...
@@ -209,4 +209,8 @@
...
@@ -209,4 +209,8 @@
.lg-backdrop
,
.lg-backdrop
,
.lg-outer
{
.lg-outer
{
z-index
:
9999
;
z-index
:
9999
;
}
.banner-desc
span
{
@apply
text-[47px]
leading-[50%]
text-secondary
font-[700];
}
}
\ No newline at end of file
src/components/atom/SelectField.tsx
View file @
0f9f3779
...
@@ -34,7 +34,6 @@ export default function SelectField({
...
@@ -34,7 +34,6 @@ export default function SelectField({
touched
,
touched
,
}:
SelectFieldProps
)
{
}:
SelectFieldProps
)
{
const
theme
=
useThemeContext
();
const
theme
=
useThemeContext
();
console
.
log
(
"theme"
,
theme
);
return
(
return
(
<
div
className=
"input__field"
>
<
div
className=
"input__field"
>
<
InputLabel
className=
"block text-sm font-semibold mb-2"
>
<
InputLabel
className=
"block text-sm font-semibold mb-2"
>
...
...
src/components/organism/Header/AdminHeader/index.tsx
View file @
0f9f3779
...
@@ -7,20 +7,25 @@ import NotificationPage from '../Notification';
...
@@ -7,20 +7,25 @@ import NotificationPage from '../Notification';
import
Profile
from
'../Profile'
;
import
Profile
from
'../Profile'
;
import
AdminSearchBar
from
'./AdminSearchBar'
;
import
AdminSearchBar
from
'./AdminSearchBar'
;
import
CreatNewRecord
from
'../CreatNewRecord'
;
import
CreatNewRecord
from
'../CreatNewRecord'
;
import
{
useGetAllNotificationQuery
}
from
'@/services/notificationApi'
;
export
default
function
AdminHeader
()
{
export
default
function
AdminHeader
()
{
const
[
mounted
,
setMounted
]
=
React
.
useState
(
false
);
//
const [mounted, setMounted] = React.useState(false);
React
.
useEffect
(()
=>
{
// React.useEffect(() => {
setMounted
(
true
);
// setMounted(true);
},
[]);
// }, []);
const
[
page
,
setPage
]
=
React
.
useState
(
1
);
const
[
pageSize
,
setPageSize
]
=
React
.
useState
(
10
);
const
{
data
}
=
useGetAllNotificationQuery
({
page
:
page
,
per_page
:
pageSize
});
console
.
log
(
data
);
return
(
return
(
<
Box
className=
'flex items-center gap-4 justify-between w-full'
>
<
Box
className=
'flex items-center gap-4 justify-between w-full'
>
<
AdminSearchBar
/>
<
AdminSearchBar
/>
<
div
className=
"right flex items-center gap-4"
>
<
div
className=
"right flex items-center gap-4"
>
<
CreatNewRecord
/>
<
CreatNewRecord
/>
<
NotificationPage
notifications=
{
[]
}
/>
<
NotificationPage
notifications=
{
data
?.
data
?.
data
||
[]
}
pagination=
{
data
?.
data
?.
pagination
}
/>
<
Profile
/>
<
Profile
/>
</
div
>
</
div
>
</
Box
>
</
Box
>
...
...
src/components/organism/Header/Notification.tsx
View file @
0f9f3779
...
@@ -15,16 +15,16 @@ import {
...
@@ -15,16 +15,16 @@ import {
import
Fade
from
'@mui/material/Fade'
;
// ✅ Import Fade
import
Fade
from
'@mui/material/Fade'
;
// ✅ Import Fade
import
{
Notification
}
from
'@wandersonalwes/iconsax-react'
;
import
{
Notification
}
from
'@wandersonalwes/iconsax-react'
;
import
Link
from
'next/link'
;
import
Link
from
'next/link'
;
import
{
NotificationProps
}
from
'@/types/notification'
;
import
{
Pagination
}
from
'@/types/game'
;
type
Notification
=
{
label
:
string
;
description
:
string
;
link
?:
string
;
}
export
default
function
NotificationPage
({
export
default
function
NotificationPage
({
notifications
notifications
,
pagination
}:
{
}:
{
notifications
:
Notification
[]
notifications
:
NotificationProps
[]
pagination
:
Pagination
|
undefined
})
{
})
{
const
anchorRef
=
useRef
<
HTMLButtonElement
|
null
>
(
null
);
const
anchorRef
=
useRef
<
HTMLButtonElement
|
null
>
(
null
);
const
[
open
,
setOpen
]
=
useState
(
false
);
const
[
open
,
setOpen
]
=
useState
(
false
);
...
@@ -38,6 +38,7 @@ export default function NotificationPage({
...
@@ -38,6 +38,7 @@ export default function NotificationPage({
const
id
=
open
?
'popper'
:
undefined
;
const
id
=
open
?
'popper'
:
undefined
;
// const [readNotification,{isLoading}]
return
(
return
(
<
Box
>
<
Box
>
<
IconButton
<
IconButton
...
@@ -79,18 +80,15 @@ export default function NotificationPage({
...
@@ -79,18 +80,15 @@ export default function NotificationPage({
<
Typography
variant=
"h3"
>
<
Typography
variant=
"h3"
>
Notifications
Notifications
</
Typography
>
</
Typography
>
<
Link
href=
{
"#"
}
className=
'text-[12px] leading-[120%] hover:text-primary-dark font-medium'
>
View All
</
Link
>
{
pagination
&&
pagination
?.
count
>
2
?
<
Link
href=
{
"#"
}
className=
'text-[12px] leading-[120%] hover:text-primary-dark font-medium'
>
View All
</
Link
>
:
""
}
</
div
>
</
div
>
{
{
notifications
.
length
?
(
notifications
.
length
?
(
<
List
className=
'max-h-[320px] overflow-auto px-1'
>
<
List
className=
'max-h-[320px] overflow-auto px-1'
>
{
{
notifications
.
map
((
notification
)
=>
(
notifications
.
map
((
notification
,
index
)
=>
(
<
ListItem
className=
'border-b-solid border-b-gray border-b-[1px] !pb-2 mb-2'
key=
{
notification
.
label
}
>
<
ListItem
className=
{
`border-b-solid border-b-gray-100 border-b-[1px] rounded-sm !p-2 cursor-pointer ${notification.has_read ? "" : "bg-gray-100"} ${index > 0 ? "mb-2 " : ""}`
}
key=
{
notification
.
id
}
>
<
Link
href=
{
""
}
>
<
p
className=
'text-[12px] lg:text-[14px] leading-[120%] text-title'
>
{
notification
.
message
}
</
p
>
<
strong
className=
"text-[12px] leading-[120%] font-[500] block mb-1"
>
New User admin404 registerd
</
strong
>
<
p
className=
'text-[10px] leading-[120%] text-para-light'
>
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Nihil, porro!
</
p
>
</
Link
>
</
ListItem
>
</
ListItem
>
))
))
}
}
...
...
src/components/pages/dashboard/adminDashboard/settings/BannerSlider.tsx
View file @
0f9f3779
...
@@ -3,53 +3,100 @@
...
@@ -3,53 +3,100 @@
import
React
from
"react"
;
import
React
from
"react"
;
import
{
useFormik
}
from
"formik"
;
import
{
useFormik
}
from
"formik"
;
import
*
as
Yup
from
"yup"
;
import
*
as
Yup
from
"yup"
;
import
{
Button
,
InputLabel
,
OutlinedInput
,
IconButton
}
from
"@mui/material"
;
import
{
Button
,
InputLabel
,
OutlinedInput
,
IconButton
,
FormControlLabel
,
Typography
,
Switch
,
}
from
"@mui/material"
;
import
InputFile
from
"@/components/atom/InputFile"
;
import
InputFile
from
"@/components/atom/InputFile"
;
import
{
CloseCircle
}
from
"@wandersonalwes/iconsax-react"
;
import
{
CloseCircle
}
from
"@wandersonalwes/iconsax-react"
;
import
{
useAppDispatch
}
from
"@/hooks/hook"
;
import
{
useAppDispatch
}
from
"@/hooks/hook"
;
import
{
showToast
,
ToastVariant
}
from
"@/slice/toastSlice"
;
import
{
showToast
,
ToastVariant
}
from
"@/slice/toastSlice"
;
import
{
useGetAllBannerQuery
,
useUpdateBannerMutation
}
from
"@/services/settingApi"
;
const
validationSchema
=
Yup
.
object
({
banners
:
Yup
.
array
().
of
(
Yup
.
object
({
name
:
Yup
.
string
().
required
(
"Banner title is required"
),
description
:
Yup
.
string
().
required
(
"Banner description is required"
),
cta_link
:
Yup
.
string
().
required
(
"CTA link is required"
),
// image: Yup.mixed().required("Banner image is required"),
type
:
Yup
.
boolean
(),
})
),
});
export
default
function
BannerSlider
()
{
export
default
function
BannerSlider
()
{
const
dispatch
=
useAppDispatch
();
const
dispatch
=
useAppDispatch
();
const
{
data
,
isLoading
}
=
useGetAllBannerQuery
();
const
[
updateBanner
,
{
isLoading
:
updating
}]
=
useUpdateBannerMutation
();
console
.
log
(
"banner data"
,
data
);
const
formik
=
useFormik
({
const
formik
=
useFormik
({
initialValues
:
{
initialValues
:
{
banners
:
[
banners
:
data
?.
data
?.
length
{
?
data
.
data
.
map
((
item
:
any
)
=>
(
{
title
:
""
,
name
:
item
.
name
||
""
,
description
:
""
,
description
:
item
.
description
||
""
,
cta_link
:
""
,
cta_link
:
item
.
cta_link
||
""
,
image
:
null
as
File
|
null
,
image
:
null
as
File
|
null
,
},
type
:
item
.
type
||
false
,
],
image_url
:
item
.
image_url
||
""
,
}))
:
[
{
name
:
""
,
description
:
""
,
cta_link
:
""
,
image
:
null
as
File
|
null
,
type
:
false
,
image_url
:
""
,
},
],
},
},
validationSchema
:
Yup
.
object
({
validationSchema
,
banners
:
Yup
.
array
().
of
(
enableReinitialize
:
true
,
Yup
.
object
({
onSubmit
:
async
(
values
)
=>
{
title
:
Yup
.
string
().
required
(
"Banner title is required"
),
const
formData
=
new
FormData
();
description
:
Yup
.
string
().
required
(
"Banner description is required"
),
cta_link
:
Yup
.
string
().
required
(
"CTA link is required"
),
image
:
Yup
.
mixed
().
required
(
"Banner image is required"
),
})
),
}),
onSubmit
:
(
values
)
=>
{
try
{
try
{
values
.
banners
.
forEach
((
banner
,
index
)
=>
{
formData
.
append
(
`banners[
${
index
}
][name]`
,
banner
.
name
);
formData
.
append
(
`banners[
${
index
}
][description]`
,
banner
.
description
);
formData
.
append
(
`banners[
${
index
}
][cta_link]`
,
banner
.
cta_link
);
formData
.
append
(
`banners[
${
index
}
][type]`
,
banner
.
type
?
"true"
:
"false"
);
if
(
banner
.
image
)
{
formData
.
append
(
`banners[
${
index
}
][image]`
,
banner
.
image
);
}
else
if
(
banner
.
image_url
)
{
formData
.
append
(
`banners[
${
index
}
][image_url]`
,
banner
.
image_url
);
}
});
const
response
=
await
updateBanner
(
formData
).
unwrap
();
dispatch
(
dispatch
(
showToast
({
showToast
({
message
:
"Banner created successfully"
,
message
:
response
?.
message
||
"Banner created successfully"
,
variant
:
ToastVariant
.
ERROR
variant
:
ToastVariant
.
SUCCESS
,
})
})
)
);
}
}
catch
(
e
:
any
)
{
catch
(
e
:
any
)
{
console
.
log
(
e
);
console
.
log
(
e
);
dispatch
(
dispatch
(
showToast
({
showToast
({
message
:
e
.
message
||
"Something went wrong"
,
message
:
e
.
message
||
"Something went wrong"
,
variant
:
ToastVariant
.
ERROR
variant
:
ToastVariant
.
ERROR
,
})
})
)
)
;
}
}
},
},
});
});
...
@@ -62,6 +109,7 @@ export default function BannerSlider() {
...
@@ -62,6 +109,7 @@ export default function BannerSlider() {
description
:
""
,
description
:
""
,
cta_link
:
""
,
cta_link
:
""
,
image
:
null
,
image
:
null
,
isSubBanner
:
false
,
},
},
]);
]);
};
};
...
@@ -75,9 +123,9 @@ export default function BannerSlider() {
...
@@ -75,9 +123,9 @@ export default function BannerSlider() {
return
(
return
(
<
form
<
form
onSubmit=
{
formik
.
handleSubmit
}
onSubmit=
{
formik
.
handleSubmit
}
className=
"form__field__wrapper border
-solid border-[1px]
border-gray rounded-[16px] mb-6"
className=
"form__field__wrapper border border-gray rounded-[16px] mb-6"
>
>
<
div
className=
"form__title py-6 px-10 border-b
-solid border-b-[1px]
border-gray"
>
<
div
className=
"form__title py-6 px-10 border-b border-gray"
>
<
h2
className=
"text-[20px] leading-[140%] font-bold"
>
Banner Slider
</
h2
>
<
h2
className=
"text-[20px] leading-[140%] font-bold"
>
Banner Slider
</
h2
>
</
div
>
</
div
>
...
@@ -90,7 +138,7 @@ export default function BannerSlider() {
...
@@ -90,7 +138,7 @@ export default function BannerSlider() {
{
formik
.
values
.
banners
.
length
>
1
&&
(
{
formik
.
values
.
banners
.
length
>
1
&&
(
<
IconButton
<
IconButton
onClick=
{
()
=>
handleRemoveBanner
(
index
)
}
onClick=
{
()
=>
handleRemoveBanner
(
index
)
}
className=
"!absolute !top-2 !right-2 !text-red-500 !
justify-end !
z-[9] max-w-fit"
className=
"!absolute !top-2 !right-2 !text-red-500 !z-[9] max-w-fit"
>
>
<
CloseCircle
size=
{
18
}
/>
<
CloseCircle
size=
{
18
}
/>
</
IconButton
>
</
IconButton
>
...
@@ -103,16 +151,16 @@ export default function BannerSlider() {
...
@@ -103,16 +151,16 @@ export default function BannerSlider() {
</
InputLabel
>
</
InputLabel
>
<
OutlinedInput
<
OutlinedInput
fullWidth
fullWidth
name=
{
`banners[${index}].
titl
e`
}
name=
{
`banners[${index}].
nam
e`
}
placeholder=
"Enter Banner Title"
placeholder=
"Enter Banner Title"
value=
{
banner
.
titl
e
}
value=
{
banner
.
nam
e
}
onChange=
{
formik
.
handleChange
}
onChange=
{
formik
.
handleChange
}
onBlur=
{
formik
.
handleBlur
}
onBlur=
{
formik
.
handleBlur
}
/>
/>
<
span
className=
"error"
>
<
span
className=
"error"
>
{
formik
.
touched
.
banners
?.[
index
]?.
titl
e
&&
{
formik
.
touched
.
banners
?.[
index
]?.
nam
e
&&
(
formik
.
errors
.
banners
?.[
index
]
as
any
)?.
titl
e
(
formik
.
errors
.
banners
?.[
index
]
as
any
)?.
nam
e
?
(
formik
.
errors
.
banners
?.[
index
]
as
any
).
titl
e
?
(
formik
.
errors
.
banners
?.[
index
]
as
any
).
nam
e
:
""
}
:
""
}
</
span
>
</
span
>
</
div
>
</
div
>
...
@@ -171,6 +219,7 @@ export default function BannerSlider() {
...
@@ -171,6 +219,7 @@ export default function BannerSlider() {
onBlur=
{
()
=>
onBlur=
{
()
=>
formik
.
setFieldTouched
(
`banners[${index}].image`
,
true
)
formik
.
setFieldTouched
(
`banners[${index}].image`
,
true
)
}
}
serverFile=
{
data
?.
data
[
index
]?.
image_url
}
/>
/>
<
span
className=
"error"
>
<
span
className=
"error"
>
{
formik
.
touched
.
banners
?.[
index
]?.
image
&&
{
formik
.
touched
.
banners
?.[
index
]?.
image
&&
...
@@ -179,6 +228,20 @@ export default function BannerSlider() {
...
@@ -179,6 +228,20 @@ export default function BannerSlider() {
:
""
}
:
""
}
</
span
>
</
span
>
</
div
>
</
div
>
{
/* ✅ Banner / Sub Banner Switch */
}
<
div
className=
"input__field"
>
<
FormControlLabel
control=
{
<
Switch
defaultChecked
color=
"primary"
checked=
{
banner
.
type
}
onChange=
{
(
e
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
=>
formik
.
setFieldValue
(
`banners[${index}].type`
,
e
.
target
.
checked
)
}
name=
{
`banners[${index}].type`
}
/>
}
label=
"Mark Sub Banner"
sx=
{
{
color
:
"#000"
,
fontSize
:
"12px"
}
}
/>
</
div
>
</
div
>
</
div
>
))
}
))
}
...
...
src/components/pages/dashboard/index.tsx
View file @
0f9f3779
...
@@ -3,53 +3,87 @@
...
@@ -3,53 +3,87 @@
import
Image
from
"next/image"
;
import
Image
from
"next/image"
;
import
{
motion
,
AnimatePresence
}
from
"framer-motion"
;
import
{
motion
,
AnimatePresence
}
from
"framer-motion"
;
import
{
useState
}
from
"react"
;
import
{
useState
}
from
"react"
;
import
{
BannerProps
}
from
"@/types/setting"
;
import
{
Button
}
from
"@mui/material"
;
import
{
renderHTML
}
from
"@/utils/RenderHTML"
;
const
slides
=
[
export
default
function
Dashboard
({
slides
}:
{
slides
:
BannerProps
[]
})
{
{
id
:
1
,
image
:
"/assets/images/slider1.png"
,
},
// {
// id: 2,
// image: "/assets/images/slider2.jpg",
// },
// {
// id: 3,
// image: "/assets/images/slider1.png",
// },
];
export
default
function
Dashboard
()
{
const
[
current
,
setCurrent
]
=
useState
(
0
);
const
[
current
,
setCurrent
]
=
useState
(
0
);
const
handleDragEnd
=
(
_
:
any
,
info
:
any
)
=>
{
const
swipeThreshold
=
100
;
// min distance to trigger slide change
if
(
info
.
offset
.
x
<
-
swipeThreshold
&&
current
<
slides
.
length
-
1
)
{
setCurrent
((
prev
)
=>
prev
+
1
);
}
else
if
(
info
.
offset
.
x
>
swipeThreshold
&&
current
>
0
)
{
setCurrent
((
prev
)
=>
prev
-
1
);
}
};
return
(
return
(
<
div
className=
"dashboard__root relative w-full mx-auto rounded-2xl mb-8"
>
<
div
className=
"dashboard__root relative w-full mx-auto rounded-2xl mb-8"
>
<
div
className=
"relative h-[240px] w-full overflow-hidden rounded-[50px]"
>
<
AnimatePresence
mode=
"wait"
>
<
AnimatePresence
mode=
"wait"
>
<
motion
.
div
<
motion
.
img
key=
{
slides
[
current
]?.
name
||
current
}
key=
{
slides
[
current
].
id
}
className=
"relative aspect-[1105/240] rounded-3xl overflow-hidden flex justify-center items-center text-center cursor-grab active:cursor-grabbing"
src=
{
slides
[
current
].
image
}
initial=
{
{
opacity
:
0
,
x
:
100
}
}
alt=
{
`slide-${slides[current].id}`
}
animate=
{
{
opacity
:
1
,
x
:
0
}
}
initial=
{
{
opacity
:
0
,
x
:
100
}
}
exit=
{
{
opacity
:
0
,
x
:
-
100
}
}
animate=
{
{
opacity
:
1
,
x
:
0
}
}
transition=
{
{
duration
:
0.6
}
}
exit=
{
{
opacity
:
0
,
x
:
-
100
}
}
drag=
"x"
transition=
{
{
duration
:
0.6
}
}
dragConstraints=
{
{
left
:
0
,
right
:
0
}
}
className=
"absolute inset-0 w-full h-full object-cover rounded-2xl"
onDragEnd=
{
handleDragEnd
}
>
<
Image
src=
{
slides
[
current
].
image_url
||
""
}
alt=
{
slides
[
current
].
name
}
fill
className=
"object-cover z-[-1]"
/>
/>
</
AnimatePresence
>
</
div
>
<
div
className=
"content relative z-10 px-6"
>
<
div
className=
"content relative z-10 px-6 text-center"
>
{
slides
[
current
]?.
name
&&
(
<
h1
className=
"text-[48px] leading-[50%] text-[#3A013F] mb-8"
>
{
slides
[
current
].
name
}
</
h1
>
)
}
{
slides
[
current
]?.
description
&&
(
<
p
className=
"text-[#600167] text-[13px] leading-[120%] font-[700] mb-5 banner-desc"
>
{
renderHTML
(
slides
[
current
].
description
)
}
</
p
>
)
}
{
slides
[
current
]?.
cta_link
&&
(
<
Button
variant=
"contained"
sx=
{
{
borderRadius
:
27
,
background
:
"linear-gradient(270deg, #F9B901 0.09%, #D09F12 95.19%)"
,
}
}
onClick=
{
()
=>
window
.
open
(
slides
[
current
].
cta_link
,
"_blank"
)
}
>
Play Now
</
Button
>
)
}
</
div
>
</
div
>
</
motion
.
div
>
</
AnimatePresence
>
{
/* Dots */
}
{
/* Dots */
}
<
div
className=
"
absolute bottom-[-24px] left-1/2 -translate-x-1/2 flex gap-2
"
>
<
div
className=
"
justify-center flex gap-2 mt-4
"
>
{
slides
.
map
((
_
,
i
)
=>
(
{
slides
.
map
((
_
,
i
)
=>
(
<
button
<
button
key=
{
i
}
key=
{
i
}
onClick=
{
()
=>
setCurrent
(
i
)
}
onClick=
{
()
=>
setCurrent
(
i
)
}
className=
{
`h-[8px] p-0 ${i === current ? "bg-white w-[24px]" : "bg-gray-400 w-[8px]"
className=
{
`h-[8px] p-0
cursor-pointer
${i === current ? "bg-white w-[24px]" : "bg-gray-400 w-[8px]"
}`
}
}`
}
/>
/>
))
}
))
}
</
div
>
</
div
>
</
div
>
</
div
>
)
)
;
}
}
src/components/pages/dashboard/userDashboard/games/exclusiveGames/exclusiveGameDetail/UserCoin.tsx
View file @
0f9f3779
...
@@ -7,7 +7,6 @@ import React from 'react'
...
@@ -7,7 +7,6 @@ import React from 'react'
export
default
function
UserCoin
({
slug
}:
{
slug
:
string
})
{
export
default
function
UserCoin
({
slug
}:
{
slug
:
string
})
{
const
{
data
}
=
useGetUserBalanceBySlugQuery
({
slug
});
const
{
data
}
=
useGetUserBalanceBySlugQuery
({
slug
});
console
.
log
(
data
);
return
(
return
(
<
Box
sx=
{
{
<
Box
sx=
{
{
background
:
"linear-gradient(0deg, rgba(234, 47, 231, 0.10) 0%, rgba(234, 47, 231, 0.10) 100%)"
,
background
:
"linear-gradient(0deg, rgba(234, 47, 231, 0.10) 0%, rgba(234, 47, 231, 0.10) 100%)"
,
...
...
src/components/pages/dashboard/userDashboard/withdrawlHistory/index.tsx
View file @
0f9f3779
...
@@ -51,7 +51,6 @@ export default function WithdrawnHistoryPage() {
...
@@ -51,7 +51,6 @@ export default function WithdrawnHistoryPage() {
}
}
]
]
console
.
log
(
data
);
const
table
=
useReactTable
({
const
table
=
useReactTable
({
data
:
data
?.
data
?.
data
||
[],
data
:
data
?.
data
?.
data
||
[],
...
...
src/hooks/store.ts
View file @
0f9f3779
...
@@ -10,6 +10,7 @@ import { transactionApi } from "@/services/transaction";
...
@@ -10,6 +10,7 @@ import { transactionApi } from "@/services/transaction";
import
{
userApi
}
from
"@/services/userApi"
;
import
{
userApi
}
from
"@/services/userApi"
;
import
{
settingApi
}
from
"@/services/settingApi"
;
import
{
settingApi
}
from
"@/services/settingApi"
;
import
{
pageApi
}
from
"@/services/pageApi"
;
import
{
pageApi
}
from
"@/services/pageApi"
;
import
{
notificationApi
}
from
"@/services/notificationApi"
;
export
const
store
=
configureStore
({
export
const
store
=
configureStore
({
reducer
:
{
reducer
:
{
...
@@ -24,6 +25,7 @@ export const store = configureStore({
...
@@ -24,6 +25,7 @@ export const store = configureStore({
[
userApi
.
reducerPath
]:
userApi
.
reducer
,
[
userApi
.
reducerPath
]:
userApi
.
reducer
,
[
settingApi
.
reducerPath
]:
settingApi
.
reducer
,
[
settingApi
.
reducerPath
]:
settingApi
.
reducer
,
[
pageApi
.
reducerPath
]:
pageApi
.
reducer
,
[
pageApi
.
reducerPath
]:
pageApi
.
reducer
,
[
notificationApi
.
reducerPath
]:
notificationApi
.
reducer
,
},
},
middleware
:
(
getDefaultMiddleware
)
=>
middleware
:
(
getDefaultMiddleware
)
=>
getDefaultMiddleware
()
getDefaultMiddleware
()
...
@@ -35,6 +37,7 @@ export const store = configureStore({
...
@@ -35,6 +37,7 @@ export const store = configureStore({
.
concat
(
userApi
.
middleware
)
.
concat
(
userApi
.
middleware
)
.
concat
(
settingApi
.
middleware
)
.
concat
(
settingApi
.
middleware
)
.
concat
(
pageApi
.
middleware
)
.
concat
(
pageApi
.
middleware
)
.
concat
(
notificationApi
.
middleware
)
})
})
...
...
src/serverApi/pages.ts
View file @
0f9f3779
import
{
PageRequestProps
,
PageResponseProps
}
from
"@/types/page"
;
import
{
PageRequestProps
,
PageResponseProps
}
from
"@/types/page"
;
import
{
cookies
}
from
"next/headers"
;
import
{
cookies
}
from
"next/headers"
;
import
{
serverBaseQuery
}
from
"./serverBaseQuery"
;
import
{
serverBaseQuery
}
from
"./serverBaseQuery"
;
import
{
BannerResponseProps
}
from
"@/types/setting"
;
export
async
function
getPageDetail
(
slug
:
string
):
Promise
<
PageResponseProps
|
undefined
>
{
export
async
function
getPageDetail
(
slug
:
string
):
Promise
<
PageResponseProps
|
undefined
>
{
return
serverBaseQuery
(
`/api/general/page/
${
slug
}
`
);
return
serverBaseQuery
(
`/api/general/page/
${
slug
}
`
);
}
}
export
async
function
getBanners
():
Promise
<
BannerResponseProps
>
{
return
serverBaseQuery
(
`/api/general/home/banner`
)
}
export
async
function
getSubBanners
():
Promise
<
BannerResponseProps
>
{
return
serverBaseQuery
(
`/api/general/home/banner?type=true`
)
}
\ No newline at end of file
src/services/notificationApi.tsx
0 → 100644
View file @
0f9f3779
import
{
createApi
}
from
"@reduxjs/toolkit/query/react"
;
import
{
baseQuery
}
from
"./baseQuery"
;
import
{
NotificationResponse
}
from
"@/types/notification"
;
import
{
GlobalResponse
,
QueryParams
}
from
"@/types/config"
;
export
const
notificationApi
=
createApi
({
reducerPath
:
"notificationApi"
,
baseQuery
:
baseQuery
,
tagTypes
:
[
'Notification'
],
endpoints
:
(
builder
)
=>
({
getAllNotification
:
builder
.
query
<
NotificationResponse
,
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/admin/notifications
${
queryString
?
`?
${
queryString
}
`
:
''
}
`
,
method
:
"GET"
}
},
providesTags
:
[
"Notification"
]
}),
readNotification
:
builder
.
mutation
<
GlobalResponse
,
{
id
:
string
}
>
({
query
:
({
id
})
=>
({
url
:
`/api/admin/notification/
${
id
}
`
,
method
:
"POST"
,
})
})
})
})
export
const
{
useGetAllNotificationQuery
}
=
notificationApi
\ No newline at end of file
src/services/settingApi.ts
View file @
0f9f3779
import
{
createApi
}
from
"@reduxjs/toolkit/query/react"
;
import
{
createApi
}
from
"@reduxjs/toolkit/query/react"
;
import
{
baseQuery
}
from
"./baseQuery"
;
import
{
baseQuery
}
from
"./baseQuery"
;
import
{
GlobalResponse
}
from
"@/types/config"
;
import
{
GlobalResponse
}
from
"@/types/config"
;
import
{
SiteSettingResponseProps
}
from
"@/types/setting"
;
import
{
BannerResponseProps
,
SiteSettingResponseProps
}
from
"@/types/setting"
;
export
const
settingApi
=
createApi
({
export
const
settingApi
=
createApi
({
reducerPath
:
"settingApi"
,
reducerPath
:
"settingApi"
,
baseQuery
:
baseQuery
,
baseQuery
:
baseQuery
,
tagTypes
:
[
'settings'
],
tagTypes
:
[
'settings'
,
'banners'
],
endpoints
:
(
builder
)
=>
({
endpoints
:
(
builder
)
=>
({
updateSetting
:
builder
.
mutation
<
GlobalResponse
,
FormData
>
({
updateSetting
:
builder
.
mutation
<
GlobalResponse
,
FormData
>
({
query
:
(
body
)
=>
({
query
:
(
body
)
=>
({
...
@@ -22,8 +22,24 @@ export const settingApi = createApi({
...
@@ -22,8 +22,24 @@ export const settingApi = createApi({
method
:
"GET"
,
method
:
"GET"
,
}),
}),
providesTags
:
[
'settings'
]
providesTags
:
[
'settings'
]
})
}),
updateBanner
:
builder
.
mutation
<
GlobalResponse
,
FormData
>
({
query
:
(
body
)
=>
({
url
:
"/api/admin/setting/banner"
,
method
:
"POST"
,
body
:
body
,
}),
invalidatesTags
:
[
'banners'
]
}),
getAllBanner
:
builder
.
query
<
BannerResponseProps
,
void
>
({
query
:
()
=>
({
url
:
"/api/admin/setting/banner"
,
method
:
"GET"
,
}),
providesTags
:
[
'banners'
]
}),
})
})
})
})
export
const
{
useUpdateSettingMutation
,
useGetSettingsQuery
}
=
settingApi
;
export
const
{
useUpdateSettingMutation
,
useGetSettingsQuery
,
useUpdateBannerMutation
,
useGetAllBannerQuery
}
=
settingApi
;
\ No newline at end of file
\ No newline at end of file
src/types/notification.ts
0 → 100644
View file @
0f9f3779
import
{
Pagination
}
from
"./game"
;
export
interface
NotificationProps
{
id
:
string
;
message
:
string
,
has_read
:
boolean
}
export
interface
NotificationResponse
{
success
:
boolean
;
message
:
string
;
data
:
{
data
:
NotificationProps
[]
pagination
:
Pagination
}
}
\ No newline at end of file
src/types/setting.ts
x
→
src/types/setting.ts
View file @
0f9f3779
...
@@ -43,3 +43,17 @@ export interface UspProps {
...
@@ -43,3 +43,17 @@ export interface UspProps {
icon_url
?:
string
;
icon_url
?:
string
;
}
}
export
interface
BannerProps
{
name
:
string
;
description
:
string
;
cta_link
:
string
;
image
?:
File
|
null
;
image_url
?:
string
|
null
;
type
:
boolean
/** TYPE TRUE REPRESENT SUB BANNER */
}
export
interface
BannerResponseProps
{
message
:
string
;
success
:
boolean
;
data
:
BannerProps
[];
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment