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
6092c896
Commit
6092c896
authored
Apr 08, 2026
by
Arjun Jhukal
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
updated the verif process for the pre registerd user
parent
3aadc4c2
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
171 additions
and
37 deletions
+171
-37
page.tsx
...d)/(user)/(outsideAuth)/buy-coins/[slug]/success/page.tsx
+0
-2
layout.tsx
src/app/(dashboard)/(user)/(privateUser)/layout.tsx
+6
-4
DashboardLayout.tsx
src/components/layouts/DashboardLayout.tsx
+47
-8
ImportantBlock.tsx
src/components/molecules/ImportantBlock.tsx
+59
-0
PaymentModal.tsx
src/components/molecules/PaymentModal.tsx
+40
-15
AddPlayerForm.tsx
...rd/adminDashboard/players/addPlayerForm/AddPlayerForm.tsx
+2
-2
authApi.ts
src/services/authApi.ts
+15
-2
userApi.ts
src/services/userApi.ts
+2
-4
No files found.
src/app/(dashboard)/(user)/(outsideAuth)/buy-coins/[slug]/success/page.tsx
View file @
6092c896
...
...
@@ -28,14 +28,12 @@ export default function PaymentSuccess() {
if
(
result
.
success
&&
result
.
data
)
{
// Update Redux store
dispatch
(
setTokens
({
access_token
:
result
.
data
.
access_token
,
user
:
result
.
data
.
user
,
refreshToken
:
result
.
data
.
refresh_token
}));
// Dispatch custom event for other components
window
.
dispatchEvent
(
new
CustomEvent
(
'auth:hydrated'
,
{
detail
:
{
source
:
result
.
source
,
...
...
src/app/(dashboard)/(user)/(privateUser)/layout.tsx
View file @
6092c896
import
DashboardLayout
from
'@/components/layouts/DashboardLayout'
import
ComingSoonGate
from
'@/components/organism/ComingSoonGate'
import
Private
from
'@/routes/Private'
import
React
from
'react'
"use client"
;
import
DashboardLayout
from
'@/components/layouts/DashboardLayout'
;
import
ComingSoonGate
from
'@/components/organism/ComingSoonGate'
;
import
Private
from
'@/routes/Private'
;
import
React
from
'react'
;
export
default
function
PrivateUserLayout
({
children
}:
{
children
:
React
.
ReactNode
})
{
return
(
<
ComingSoonGate
>
<
Private
>
...
...
src/components/layouts/DashboardLayout.tsx
View file @
6092c896
"use client"
;
import
{
useAppDispatch
,
useAppSelector
}
from
'@/hooks/hook'
;
import
{
useVerifyProfileMutation
}
from
'@/services/authApi'
;
import
{
showToast
,
ToastVariant
}
from
'@/slice/toastSlice'
;
import
{
Box
}
from
'@mui/material'
;
import
{
styled
}
from
'@mui/material/styles'
;
import
{
usePathname
}
from
'next/navigation'
;
import
React
from
'react'
;
import
React
,
{
useState
}
from
'react'
;
import
ImportantBlock
from
'../molecules/ImportantBlock'
;
import
PaymentModal
from
'../molecules/PaymentModal'
;
import
Header
from
'../organism/Header'
;
import
Sidebar
from
'../organism/Sidebar'
;
export
default
function
DashboardLayout
({
children
}:
{
children
:
React
.
ReactNode
})
{
const
[
open
,
setOpen
]
=
React
.
useState
(
true
);
const
[
openMobile
,
setOpenMobile
]
=
React
.
useState
(
false
);
const
[
open
,
setOpen
]
=
useState
(
true
);
const
[
openMobile
,
setOpenMobile
]
=
useState
(
false
);
const
pathname
=
usePathname
();
const
user
=
useAppSelector
((
state
)
=>
state
.
auth
.
user
);
const
dispatch
=
useAppDispatch
();
const
[
verifyAcuity
,
{
isLoading
}]
=
useVerifyProfileMutation
();
const
[
isAcuityModalOpen
,
setIsAcuityModalOpen
]
=
useState
(
false
);
const
[
acuityUrl
,
setAcuityUrl
]
=
useState
(
''
);
const
handleDrawerOpen
=
()
=>
{
setOpen
((
prev
)
=>
!
prev
);
};
...
...
@@ -25,9 +35,7 @@ export default function DashboardLayout({ children }: { children: React.ReactNod
const
handleMobileMenuToggle
=
()
=>
{
setOpenMobile
((
prev
)
=>
!
prev
);
}
// const handleDrawerClose = () => {
// setOpen(false);
// };
const
DrawerHeader
=
styled
(
'div'
)(({
theme
})
=>
({
display
:
'flex'
,
alignItems
:
'center'
,
...
...
@@ -55,8 +63,39 @@ export default function DashboardLayout({ children }: { children: React.ReactNod
mb
:
{
xs
:
'16px'
,
lg
:
0
}
}
}
/>
<
div
className=
"content_box px-4 pt-4 pb-12 lg:pl-11 lg:pr-12 lg:pt-8 lg:pb-16"
>
{
/* {pathname !== '/' && <Breadcrumb />} */
}
{
children
}
</
div
>
{
!
user
?.
is_acuity_verified
?
<
ImportantBlock
title=
'Profile Unverified'
message=
'Your profile is not yet verified. Please complete the verification process.'
onAction=
{
async
()
=>
{
try
{
const
response
=
await
verifyAcuity
().
unwrap
();
dispatch
(
showToast
({
message
:
'Verification successful.'
,
variant
:
ToastVariant
.
SUCCESS
}));
if
(
response
?.
data
?.
redirection_url
)
{
setAcuityUrl
(
response
.
data
.
redirection_url
);
setIsAcuityModalOpen
(
true
);
}
}
catch
(
err
:
any
)
{
dispatch
(
showToast
({
message
:
err
?.
data
?.
message
||
'Verification failed. Please try again.'
,
variant
:
ToastVariant
.
ERROR
}))
}
}
}
actionText=
{
isLoading
?
'Verifying...'
:
'Verify Now'
}
/>
:
""
}
{
children
}
<
PaymentModal
url=
{
acuityUrl
}
isOpen=
{
isAcuityModalOpen
}
onClose=
{
()
=>
setIsAcuityModalOpen
(
false
)
}
onSuccess=
{
()
=>
{
setIsAcuityModalOpen
(
false
);
dispatch
(
showToast
({
message
:
'Verification complete!'
,
variant
:
ToastVariant
.
SUCCESS
,
autoTime
:
true
}));
}
}
onError=
{
(
error
:
{
message
:
string
})
=>
{
console
.
error
(
'Acuity verification error'
,
error
);
dispatch
(
showToast
({
message
:
error
.
message
||
'Verification failed'
,
variant
:
ToastVariant
.
ERROR
,
autoTime
:
true
}));
}
}
successMessage=
"verified"
title=
"Acuity identity verification"
maxWidth=
"md"
height=
{
700
}
/>
</
div
>
</
div
>
</
Box
>
)
...
...
src/components/molecules/ImportantBlock.tsx
0 → 100644
View file @
6092c896
'use client'
;
import
{
Alert
,
AlertTitle
,
Box
,
Button
,
Stack
,
Typography
}
from
'@mui/material'
;
type
Variant
=
'warning'
|
'info'
|
'error'
|
'success'
;
interface
ImportantBlockProps
{
title
:
string
;
message
:
string
|
React
.
ReactNode
;
actionText
?:
string
;
onAction
?:
()
=>
void
;
variant
?:
Variant
;
}
export
default
function
ImportantBlock
({
title
,
message
,
actionText
,
onAction
,
}:
ImportantBlockProps
)
{
return
(
<
Alert
sx=
{
{
borderRadius
:
3
,
mb
:
2
,
alignItems
:
'flex-start'
,
'& .MuiAlert-message'
:
{
width
:
'100%'
},
background
:
(
theme
)
=>
theme
.
palette
.
warning
.
main
,
color
:
(
theme
)
=>
theme
.
palette
.
primary
.
contrastText
,
}
}
icon=
{
false
}
>
<
Stack
direction=
{
{
sm
:
'row'
}
}
justifyContent=
"space-between"
alignItems=
{
{
xs
:
'flex-start'
,
sm
:
'center'
}
}
spacing=
{
2
}
width=
"100%"
>
<
Box
>
<
AlertTitle
sx=
{
{
fontWeight
:
700
}
}
>
{
title
}
</
AlertTitle
>
<
Typography
variant=
"body2"
sx=
{
{
mb
:
actionText
?
2
:
0
}
}
>
{
message
}
</
Typography
>
</
Box
>
{
actionText
&&
onAction
&&
(
<
Stack
direction=
"row"
spacing=
{
1
}
>
<
Button
size=
"small"
variant=
"contained"
color=
'secondary'
onClick=
{
onAction
}
>
{
actionText
}
</
Button
>
</
Stack
>
)
}
</
Stack
>
</
Alert
>
);
}
\ No newline at end of file
src/components/molecules/PaymentModal.tsx
View file @
6092c896
'use client'
;
import
{
useAppDispatch
,
useAppSelector
}
from
'@/hooks/hook'
;
import
{
useLazyGetMeQuery
}
from
'@/services/authApi'
;
import
{
setTokens
}
from
'@/slice/authSlice'
;
import
{
Box
,
CircularProgress
,
Dialog
,
DialogContent
,
Typography
}
from
'@mui/material'
;
import
Cookies
from
'js-cookie'
;
import
{
useRouter
}
from
'next/navigation'
;
import
{
useEffect
,
useRef
,
useState
}
from
'react'
;
import
{
use
Callback
,
use
Effect
,
useRef
,
useState
}
from
'react'
;
export
interface
PaymentModalProps
{
url
:
string
;
...
...
@@ -31,7 +35,7 @@ export default function PaymentModal({
onSuccess
,
onError
,
successMessage
=
'success'
,
successRedirectPaths
=
[
'/login'
,
'/success'
],
successRedirectPaths
=
[
'/login'
,
'/success'
,
'/verified'
],
title
=
'Processing Payment'
,
maxWidth
=
'sm'
,
height
=
600
,
...
...
@@ -42,6 +46,31 @@ export default function PaymentModal({
const
[
error
,
setError
]
=
useState
<
PaymentError
|
null
>
(
null
);
const
[
hasDetectedSuccess
,
setHasDetectedSuccess
]
=
useState
(
false
);
const
route
=
useRouter
();
const
dispatch
=
useAppDispatch
();
const
access_token
=
useAppSelector
((
state
)
=>
state
.
auth
.
access_token
);
const
[
fetchMe
]
=
useLazyGetMeQuery
();
const
syncUserFromServer
=
useCallback
(
async
()
=>
{
try
{
const
result
=
await
fetchMe
().
unwrap
();
const
user
=
result
.
data
?.
user
;
const
token
=
result
.
data
?.
access_token
||
access_token
;
console
.
log
(
"inside sync"
,
{
user
,
token
})
if
(
!
user
)
return
;
dispatch
(
setTokens
({
access_token
:
token
,
user
}));
Cookies
.
set
(
'user'
,
JSON
.
stringify
(
user
),
{
expires
:
1
,
secure
:
process
.
env
.
NODE_ENV
===
'production'
,
sameSite
:
'Strict'
,
});
}
catch
(
error
)
{
console
.
error
(
'[PaymentModal] syncUserFromServer failed'
,
error
);
}
},
[
fetchMe
,
dispatch
,
access_token
]);
useEffect
(()
=>
{
if
(
!
isOpen
)
{
setIsLoading
(
true
);
...
...
@@ -50,7 +79,7 @@ export default function PaymentModal({
return
;
}
const
checkRedirectSuccess
=
():
void
=>
{
const
checkRedirectSuccess
=
async
():
Promise
<
void
>
=>
{
if
(
hasDetectedSuccess
||
!
iframeRef
.
current
?.
contentWindow
)
return
;
try
{
...
...
@@ -70,22 +99,17 @@ export default function PaymentModal({
console
.
log
(
'[PaymentModal] Detected success redirect URL:'
,
currentUrl
);
setHasDetectedSuccess
(
true
);
setIsLoading
(
false
);
if
(
!
isRegistrationFlow
)
await
syncUserFromServer
();
onSuccess
?.();
setTimeout
(()
=>
onClose
(),
300
);
}
}
catch
{
// cross-origin iframe URL access will throw during external provider flow, ignore until same-origin
}
};
const
handleMessage
=
(
event
:
MessageEvent
):
void
=>
{
const
handleMessage
=
async
(
event
:
MessageEvent
):
Promise
<
void
>
=>
{
try
{
// Ignore messages from React DevTools and other injected frames
if
(
event
.
source
!==
iframeRef
.
current
?.
contentWindow
)
{
console
.
debug
(
'[PaymentModal] Ignoring message from non-iframe source'
,
event
.
origin
);
return
;
}
// Security: Verify message origin; allow provider origin and same-host fallback
const
paymentOrigin
=
new
URL
(
url
).
origin
;
const
trustedOrigins
=
new
Set
([
paymentOrigin
,
window
.
location
.
origin
]);
if
(
!
trustedOrigins
.
has
(
event
.
origin
))
{
...
...
@@ -117,15 +141,16 @@ export default function PaymentModal({
console
.
log
(
'[PaymentModal] Payment successful! Closing modal...'
);
setHasDetectedSuccess
(
true
);
setIsLoading
(
false
);
onSuccess
?.();
setTimeout
(()
=>
onClose
(),
500
);
// Small delay for animation
if
(
isRegistrationFlow
)
{
route
.
push
(
'/login'
);
}
else
{
await
syncUserFromServer
();
}
onSuccess
?.();
setTimeout
(()
=>
onClose
(),
500
);
return
;
}
// Check for error status
const
isError
=
data
.
status
===
'error'
||
data
.
type
===
'payment:error'
||
...
...
@@ -165,7 +190,7 @@ export default function PaymentModal({
window
.
clearTimeout
(
readyTimeout
);
window
.
removeEventListener
(
'message'
,
handleMessage
);
};
},
[
isOpen
,
url
,
onClose
,
onSuccess
,
onError
,
successMessage
,
successRedirectPaths
,
hasDetectedSuccess
]);
},
[
isOpen
,
url
,
onClose
,
onSuccess
,
onError
,
successMessage
,
successRedirectPaths
,
hasDetectedSuccess
,
isRegistrationFlow
,
route
,
syncUserFromServer
]);
const
handleIframeLoad
=
():
void
=>
{
console
.
log
(
'[PaymentModal] iframe loaded'
);
...
...
src/components/pages/dashboard/adminDashboard/players/addPlayerForm/AddPlayerForm.tsx
View file @
6092c896
...
...
@@ -136,7 +136,7 @@ export default function AddPlayerForm({ formik, id, data, loading, buttonLabel,
</
span
>
</
div
>
}
{
isAdmin
?
""
:
<>
{
isAdmin
?
""
:
<>
<
div
className=
"input__field col-span-1"
>
<
InputLabel
htmlFor=
"address"
>
Address Line 1
<
span
className=
"text-red-500"
>
*
</
span
></
InputLabel
>
<
OutlinedInput
...
...
@@ -292,7 +292,7 @@ export default function AddPlayerForm({ formik, id, data, loading, buttonLabel,
<
span
className=
"error"
>
{
formik
.
touched
.
gender
&&
formik
.
errors
.
gender
}
</
span
>
</
div
>
{
isAdmin
?
<
div
className=
"input__field"
>
{
!
isAdmin
?
<
div
className=
"input__field"
>
<
InputLabel
htmlFor=
"postal_code"
>
Zip Code
<
span
className=
"text-red-500"
>
*
</
span
></
InputLabel
>
<
OutlinedInput
fullWidth
...
...
src/services/authApi.ts
View file @
6092c896
...
...
@@ -75,8 +75,21 @@ export const authApi = createApi({
method
:
"POST"
,
body
:
{
age_verify_uuid
}
})
}),
getMe
:
builder
.
query
<
LoginResponse
,
void
>
({
query
:
()
=>
({
url
:
`/api/auth/me`
,
method
:
"GET"
,
}),
}),
verifyProfile
:
builder
.
mutation
<
{
data
:
{
redirection_url
:
string
}
},
void
>
({
query
:
()
=>
({
url
:
`/api/acuity/verify`
,
method
:
"POST"
,
}),
})
})
})
export
const
{
useLoginMutation
,
useRegisterUserMutation
,
useSendVerificationLinkAgainMutation
,
useForgotPasswordMutation
,
useVerifyOTPMutation
,
useResetPasswordMutation
,
useVerifyEmailMutation
,
useGetAgeGateUuidMutation
,
useVerifyAgeGateMutation
}
=
authApi
;
\ No newline at end of file
export
const
{
useLoginMutation
,
useRegisterUserMutation
,
useSendVerificationLinkAgainMutation
,
useForgotPasswordMutation
,
useVerifyOTPMutation
,
useResetPasswordMutation
,
useVerifyEmailMutation
,
useGetAgeGateUuidMutation
,
useVerifyAgeGateMutation
,
useGetMeQuery
,
useLazyGetMeQuery
,
useVerifyProfileMutation
}
=
authApi
;
\ No newline at end of file
src/services/userApi.ts
View file @
6092c896
...
...
@@ -26,7 +26,6 @@ export const userApi = createApi({
invalidatesTags
:
[
'user'
,
"wallet"
]
}),
getUserGameCredentials
:
builder
.
query
<
CredentialsResponseProps
,
void
>
({
query
:
()
=>
({
url
:
`/api/credentials`
,
...
...
@@ -64,7 +63,6 @@ export const userApi = createApi({
providesTags
:
[
'user'
,
"wallet"
],
}),
})
})
export
const
{
useAddUserWalletMutation
,
useUpdateUserProfileMutation
,
useGetUserGameCredentialsQuery
,
useChangeUserGamePasswordMutation
,
useUpdateUserGamePasswordMutation
,
useGetGamesPasswordStatusQuery
}
=
userApi
;
\ No newline at end of file
export
const
{
useAddUserWalletMutation
,
useUpdateUserProfileMutation
,
useGetUserGameCredentialsQuery
,
useChangeUserGamePasswordMutation
,
useUpdateUserGamePasswordMutation
,
useGetGamesPasswordStatusQuery
}
=
userApi
;
\ 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