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
bd1b5dd7
Commit
bd1b5dd7
authored
Oct 17, 2025
by
Arjun Jhukal
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
updated the chagne password functionality at logged in user profile
parent
bca8509d
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
175 additions
and
144 deletions
+175
-144
AccountTab.tsx
...p/(dashboard)/(user)/(privateUser)/account/AccountTab.tsx
+5
-1
ResetPasswordForm.tsx
...components/pages/auth/resetPassword/ResetPasswordForm.tsx
+136
-0
index.tsx
src/components/pages/auth/resetPassword/index.tsx
+7
-129
Activities.tsx
...pages/dashboard/adminDashboard/activityLog/Activities.tsx
+0
-0
index.tsx
...ents/pages/dashboard/adminDashboard/activityLog/index.tsx
+2
-2
ReduxHydrator.tsx
src/routes/ReduxHydrator.tsx
+4
-4
ServerPrivate.tsx
src/routes/ServerPrivate.tsx
+3
-3
notificationApi.tsx
src/services/notificationApi.tsx
+5
-4
notification.ts
src/types/notification.ts
+13
-1
No files found.
src/app/(dashboard)/(user)/(privateUser)/account/AccountTab.tsx
View file @
bd1b5dd7
...
@@ -2,6 +2,7 @@ import GlassWrapper from '@/components/molecules/GlassWrapper';
...
@@ -2,6 +2,7 @@ import GlassWrapper from '@/components/molecules/GlassWrapper';
import
TabController
from
'@/components/molecules/TabController'
;
import
TabController
from
'@/components/molecules/TabController'
;
import
UserProfileCard
from
"@/components/organism/Cards/UserProfileCard"
;
import
UserProfileCard
from
"@/components/organism/Cards/UserProfileCard"
;
import
ResetPasswordForm
from
'@/components/pages/auth/resetPassword/ResetPasswordForm'
;
import
EditUserProfile
from
'@/components/pages/dashboard/userDashboard/account/profile/editProfile'
;
import
EditUserProfile
from
'@/components/pages/dashboard/userDashboard/account/profile/editProfile'
;
import
EditUserWallet
from
'@/components/pages/dashboard/userDashboard/account/profile/editUserWallet'
;
import
EditUserWallet
from
'@/components/pages/dashboard/userDashboard/account/profile/editUserWallet'
;
import
{
useAppSelector
}
from
'@/hooks/hook'
;
import
{
useAppSelector
}
from
'@/hooks/hook'
;
...
@@ -14,11 +15,14 @@ export default function AccountTab() {
...
@@ -14,11 +15,14 @@ export default function AccountTab() {
const
{
data
,
isLoading
}
=
useGetUserGameBalanceQuery
();
const
{
data
,
isLoading
}
=
useGetUserGameBalanceQuery
();
const
[
currentActiveTab
,
setCurrentActiveTab
]
=
React
.
useState
<
profileTabProps
>
(
"account_detail"
);
const
[
currentActiveTab
,
setCurrentActiveTab
]
=
React
.
useState
<
profileTabProps
>
(
"account_detail"
);
const
handleTabChange
=
(
tab
:
string
)
=>
{
const
handleTabChange
=
(
tab
:
string
)
=>
{
setCurrentActiveTab
(
tab
as
profileTabProps
);
setCurrentActiveTab
(
tab
as
profileTabProps
);
};
};
const
user
=
useAppSelector
((
state
)
=>
state
.
auth
.
user
);
const
user
=
useAppSelector
((
state
)
=>
state
.
auth
.
user
);
console
.
log
(
user
);
const
renderTabContent
=
()
=>
{
const
renderTabContent
=
()
=>
{
switch
(
currentActiveTab
)
{
switch
(
currentActiveTab
)
{
case
"account_detail"
:
case
"account_detail"
:
...
@@ -27,7 +31,7 @@ export default function AccountTab() {
...
@@ -27,7 +31,7 @@ export default function AccountTab() {
return
<
EditUserWallet
/>;
return
<
EditUserWallet
/>;
case
"change_password"
:
case
"change_password"
:
return
(<
div
className=
"px-8 lg:pt-8 pb-8"
>
return
(<
div
className=
"px-8 lg:pt-8 pb-8"
>
<
h2
>
Change Password
</
h2
>
<
ResetPasswordForm
email=
{
user
?.
email
}
/
>
</
div
>);
</
div
>);
default
:
default
:
return
null
;
return
null
;
...
...
src/components/pages/auth/resetPassword/ResetPasswordForm.tsx
0 → 100644
View file @
bd1b5dd7
import
PasswordField
from
'@/components/molecules/PasswordField'
import
{
useAppDispatch
}
from
'@/hooks/hook'
import
{
PATH
}
from
'@/routes/PATH'
import
{
useResetPasswordMutation
}
from
'@/services/authApi'
import
{
clearTokens
}
from
'@/slice/authSlice'
import
{
showToast
,
ToastVariant
}
from
'@/slice/toastSlice'
import
{
Box
,
InputLabel
,
OutlinedInput
}
from
'@mui/material'
import
{
ArrowLeft
}
from
'@wandersonalwes/iconsax-react'
import
{
useFormik
}
from
'formik'
import
Link
from
'next/link'
import
{
useRouter
}
from
'next/navigation'
import
React
from
'react'
import
*
as
Yup
from
'yup'
;
const
validationSchema
=
Yup
.
object
().
shape
({
emailAddress
:
Yup
.
string
()
.
email
(
'Must be a valid email'
)
.
max
(
255
)
.
required
(
'Email is required'
),
password
:
Yup
.
string
()
.
required
(
'Password is required'
)
.
test
(
'no-leading-trailing-whitespace'
,
'Password cannot start or end with spaces'
,
(
value
)
=>
value
===
value
?.
trim
()
)
.
max
(
16
,
'Password must be less than 10 characters'
),
confirmPassword
:
Yup
.
string
()
.
oneOf
([
Yup
.
ref
(
'password'
)],
'Passwords must match'
)
.
required
(
'Confirm Password is required'
),
})
export
default
function
ResetPasswordForm
({
email
}:
{
email
?:
string
})
{
const
router
=
useRouter
();
const
dispatch
=
useAppDispatch
();
const
initialValues
=
{
emailAddress
:
email
||
""
,
password
:
""
,
confirmPassword
:
""
,
}
const
[
resetPassword
,
{
isLoading
}]
=
useResetPasswordMutation
();
const
{
handleSubmit
,
handleBlur
,
handleChange
,
errors
,
dirty
,
values
,
touched
}
=
useFormik
(
{
initialValues
,
validationSchema
,
onSubmit
:
async
(
values
)
=>
{
try
{
const
response
=
await
resetPassword
({
email
:
values
.
emailAddress
,
password
:
values
.
password
,
password_confirmation
:
values
.
confirmPassword
,
}).
unwrap
();
dispatch
(
showToast
({
message
:
response
?.
message
||
"New password is updated"
,
variant
:
ToastVariant
.
SUCCESS
,
autoTime
:
true
,
}),
);
dispatch
(
clearTokens
());
router
.
replace
(
PATH
.
AUTH
.
LOGIN
.
ROOT
);
}
catch
(
e
:
any
)
{
console
.
log
(
"Error"
,
e
);
dispatch
(
showToast
({
message
:
e
?.
data
?.
message
||
"Unable to reset password. Try again later"
,
variant
:
ToastVariant
.
ERROR
,
autoTime
:
true
,
}),
);
}
}
}
)
return
(
<
form
action=
""
onSubmit=
{
handleSubmit
}
>
<
div
className=
"grid md:grid-cols-2 gap-x-3 gap-y-5"
>
{
!
email
?
<
div
className=
"col-span-2"
>
<
div
className=
"input_field"
>
<
InputLabel
htmlFor=
"emailAddress"
>
Email Address*
</
InputLabel
>
<
OutlinedInput
name=
'emailAddress'
id=
'emailAddress'
placeholder=
'example@example.com'
value=
{
values
.
emailAddress
}
onChange=
{
handleChange
}
onBlur=
{
handleBlur
}
error=
{
Boolean
(
touched
.
emailAddress
&&
errors
.
emailAddress
)
}
/>
{
touched
.
emailAddress
&&
errors
.
emailAddress
?
<
span
className=
"error "
>
{
errors
.
emailAddress
}
</
span
>
:
null
}
</
div
>
</
div
>
:
""
}
<
div
className=
"col-span-2"
>
<
div
className=
"input_field"
>
<
PasswordField
name=
"password"
label=
"Password*"
placeholder=
"XXXXXXX"
value=
{
values
.
password
}
onChange=
{
handleChange
}
onBlur=
{
handleBlur
}
error=
{
touched
.
password
?
errors
.
password
:
undefined
}
/>
</
div
>
</
div
>
<
div
className=
"col-span-2"
>
<
div
className=
"input_field"
>
<
PasswordField
name=
"confirmPassword"
label=
"Confirm Password*"
placeholder=
"XXXXXXX"
value=
{
values
.
confirmPassword
}
onChange=
{
handleChange
}
onBlur=
{
handleBlur
}
error=
{
touched
.
confirmPassword
?
errors
.
confirmPassword
:
undefined
}
/>
</
div
>
</
div
>
</
div
>
<
div
className=
"action__group text-center flex flex-col gap-4 mt-8"
>
<
button
className=
'ss-btn bg-primary-grad'
disabled=
{
!
dirty
}
>
{
isLoading
?
"Changing Password"
:
"Reset Password"
}
</
button
>
<
Link
href=
{
PATH
.
DASHBOARD
.
ROOT
}
className=
'ss-btn bg-secondary-grad'
>
Login
</
Link
>
</
div
>
</
form
>
)
}
src/components/pages/auth/resetPassword/index.tsx
View file @
bd1b5dd7
"use client"
;
"use client"
;
import
React
,
{
useEffect
,
useState
}
from
'react'
import
React
from
'react'
import
AuthMessageBlock
from
'../authMessageBlock'
import
AuthMessageBlock
from
'../authMessageBlock'
import
{
Box
,
InputLabel
,
OutlinedInput
}
from
'@mui/material'
import
ResetPasswordForm
from
'./ResetPasswordForm'
;
import
PasswordField
from
'@/components/molecules/PasswordField'
import
{
Box
}
from
'@mui/material'
;
import
{
ArrowLeft
}
from
'@wandersonalwes/iconsax-react'
import
Link
from
'next/link'
;
import
Link
from
'next/link'
import
{
ArrowLeft
}
from
'@wandersonalwes/iconsax-react'
;
import
{
PATH
}
from
'@/routes/PATH'
import
{
PATH
}
from
'@/routes/PATH'
;
import
*
as
Yup
from
'yup'
;
import
{
useFormik
}
from
'formik'
;
import
{
useAppDispatch
}
from
'@/hooks/hook'
import
{
showToast
,
ToastVariant
}
from
'@/slice/toastSlice'
;
import
{
useResetPasswordMutation
}
from
'@/services/authApi'
;
import
{
useRouter
,
useSearchParams
}
from
'next/navigation'
;
const
validationSchema
=
Yup
.
object
().
shape
({
emailAddress
:
Yup
.
string
()
.
email
(
'Must be a valid email'
)
.
max
(
255
)
.
required
(
'Email is required'
),
password
:
Yup
.
string
()
.
required
(
'Password is required'
)
.
test
(
'no-leading-trailing-whitespace'
,
'Password cannot start or end with spaces'
,
(
value
)
=>
value
===
value
?.
trim
()
)
.
max
(
16
,
'Password must be less than 10 characters'
),
confirmPassword
:
Yup
.
string
()
.
oneOf
([
Yup
.
ref
(
'password'
)],
'Passwords must match'
)
.
required
(
'Confirm Password is required'
),
})
export
default
function
ResetPasswordPage
()
{
export
default
function
ResetPasswordPage
()
{
const
router
=
useRouter
();
const
dispatch
=
useAppDispatch
();
const
initialValues
=
{
emailAddress
:
""
,
password
:
""
,
confirmPassword
:
""
,
}
const
[
resetPassword
,
{
isLoading
}]
=
useResetPasswordMutation
();
const
{
handleSubmit
,
handleBlur
,
handleChange
,
errors
,
dirty
,
values
,
touched
}
=
useFormik
(
{
initialValues
,
validationSchema
,
onSubmit
:
async
(
values
)
=>
{
try
{
const
response
=
await
resetPassword
({
email
:
values
.
emailAddress
,
password
:
values
.
password
,
password_confirmation
:
values
.
confirmPassword
,
}).
unwrap
();
dispatch
(
showToast
({
message
:
response
?.
message
||
"New password is updated"
,
variant
:
ToastVariant
.
SUCCESS
,
autoTime
:
true
,
}),
);
router
.
replace
(
PATH
.
AUTH
.
LOGIN
.
ROOT
);
}
catch
(
e
:
any
)
{
console
.
log
(
"Error"
,
e
);
dispatch
(
showToast
({
message
:
e
?.
data
?.
message
||
"Unable to reset password. Try again later"
,
variant
:
ToastVariant
.
ERROR
,
autoTime
:
true
,
}),
);
}
}
}
)
return
(
return
(
<>
<>
<
AuthMessageBlock
<
AuthMessageBlock
...
@@ -95,61 +27,7 @@ export default function ResetPasswordPage() {
...
@@ -95,61 +27,7 @@ export default function ResetPasswordPage() {
<
Link
href=
{
PATH
.
DASHBOARD
.
ROOT
}
className=
'text-[12px] leading-[120%] font-bold lg:text-[16px] hover:text-primary flex gap-2 items-center'
><
ArrowLeft
/>
Back to Dashboard
</
Link
>
<
Link
href=
{
PATH
.
DASHBOARD
.
ROOT
}
className=
'text-[12px] leading-[120%] font-bold lg:text-[16px] hover:text-primary flex gap-2 items-center'
><
ArrowLeft
/>
Back to Dashboard
</
Link
>
<
h1
className=
"text-[24px] leading-[120%] font-bold lg:text-[48px]"
>
Forgot Password
</
h1
>
<
h1
className=
"text-[24px] leading-[120%] font-bold lg:text-[48px]"
>
Forgot Password
</
h1
>
</
div
>
</
div
>
<
ResetPasswordForm
/>
<
form
action=
""
onSubmit=
{
handleSubmit
}
>
<
div
className=
"grid md:grid-cols-2 gap-x-3 gap-y-5"
>
<
div
className=
"col-span-2"
>
<
div
className=
"input_field"
>
<
InputLabel
htmlFor=
"emailAddress"
>
Email Address*
</
InputLabel
>
<
OutlinedInput
name=
'emailAddress'
id=
'emailAddress'
placeholder=
'example@example.com'
value=
{
values
.
emailAddress
}
onChange=
{
handleChange
}
onBlur=
{
handleBlur
}
error=
{
Boolean
(
touched
.
emailAddress
&&
errors
.
emailAddress
)
}
/>
{
touched
.
emailAddress
&&
errors
.
emailAddress
?
<
span
className=
"error "
>
{
errors
.
emailAddress
}
</
span
>
:
null
}
</
div
>
</
div
>
<
div
className=
"col-span-2"
>
<
div
className=
"input_field"
>
<
PasswordField
name=
"password"
label=
"Password*"
placeholder=
"XXXXXXX"
value=
{
values
.
password
}
onChange=
{
handleChange
}
onBlur=
{
handleBlur
}
error=
{
touched
.
password
?
errors
.
password
:
undefined
}
/>
</
div
>
</
div
>
<
div
className=
"col-span-2"
>
<
div
className=
"input_field"
>
<
PasswordField
name=
"confirmPassword"
label=
"Confirm Password*"
placeholder=
"XXXXXXX"
value=
{
values
.
confirmPassword
}
onChange=
{
handleChange
}
onBlur=
{
handleBlur
}
error=
{
touched
.
confirmPassword
?
errors
.
confirmPassword
:
undefined
}
/>
</
div
>
</
div
>
</
div
>
<
div
className=
"action__group text-center flex flex-col gap-4 mt-8"
>
<
button
className=
'ss-btn bg-primary-grad'
disabled=
{
!
dirty
}
>
{
isLoading
?
"Changing Password"
:
"Reset Password"
}
</
button
>
<
Link
href=
{
PATH
.
DASHBOARD
.
ROOT
}
className=
'ss-btn bg-secondary-grad'
>
Login
</
Link
>
</
div
>
</
form
>
</
Box
>
</
Box
>
</>
</>
)
)
...
...
src/components/pages/dashboard/adminDashboard/activityLog/Activities.tsx
View file @
bd1b5dd7
This diff is collapsed.
Click to expand it.
src/components/pages/dashboard/adminDashboard/activityLog/index.tsx
View file @
bd1b5dd7
...
@@ -7,11 +7,11 @@ export default function ActivityLogPage() {
...
@@ -7,11 +7,11 @@ export default function ActivityLogPage() {
return
(
return
(
<
section
className=
"activity__log__root"
>
<
section
className=
"activity__log__root"
>
<
PageHeader
title=
'Activity Log'
/>
<
PageHeader
title=
'Activity Log'
/>
<
div
className=
"grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4 gap-4 mb-8"
>
{
/*
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4 gap-4 mb-8">
{Array.from({ length: 4 }).map((_, index) => (
{Array.from({ length: 4 }).map((_, index) => (
<ActivityAnalyticCard key={index.toString()} />
<ActivityAnalyticCard key={index.toString()} />
))}
))}
</
div
>
</div>
*/
}
<
div
className=
"section-title mb-4"
>
<
div
className=
"section-title mb-4"
>
<
h2
className=
"text-[20px] leading-[140%] font-[600]"
>
<
h2
className=
"text-[20px] leading-[140%] font-[600]"
>
All Activities
All Activities
...
...
src/routes/ReduxHydrator.tsx
View file @
bd1b5dd7
...
@@ -4,12 +4,12 @@ import { useEffect } from "react";
...
@@ -4,12 +4,12 @@ import { useEffect } from "react";
import
{
useAppDispatch
}
from
"@/hooks/hook"
;
import
{
useAppDispatch
}
from
"@/hooks/hook"
;
import
{
setTokens
}
from
"@/slice/authSlice"
;
import
{
setTokens
}
from
"@/slice/authSlice"
;
export
default
function
ReduxHydrator
({
token
,
user
}:
{
token
:
string
;
user
:
any
})
{
export
default
function
ReduxHydrator
({
token
}:
{
token
:
string
;
})
{
const
dispatch
=
useAppDispatch
();
const
dispatch
=
useAppDispatch
();
useEffect
(()
=>
{
//
useEffect(() => {
dispatch
(
setTokens
({
access_token
:
token
,
user
}));
//
dispatch(setTokens({ access_token: token, user }));
},
[
dispatch
,
token
,
user
]);
//
}, [dispatch, token, user]);
return
null
;
return
null
;
}
}
src/routes/ServerPrivate.tsx
View file @
bd1b5dd7
...
@@ -24,13 +24,13 @@ export default async function ServerPrivate({ children }: { children: React.Reac
...
@@ -24,13 +24,13 @@ export default async function ServerPrivate({ children }: { children: React.Reac
redirect
(
"/"
);
redirect
(
"/"
);
}
}
// Optionally, you could fetch user data from your API here if you don't store it in JWT
const
user
=
payload
;
// Or fetch user profile based on token
// const user = payload;
return
(
return
(
<>
<>
{
/* ✅ Hydrate Redux store on client */
}
{
/* ✅ Hydrate Redux store on client */
}
<
ReduxHydrator
token=
{
access_token
}
user=
{
user
}
/>
<
ReduxHydrator
token=
{
access_token
}
/>
{
children
}
{
children
}
</>
</>
);
);
...
...
src/services/notificationApi.tsx
View file @
bd1b5dd7
import
{
createApi
}
from
"@reduxjs/toolkit/query/react"
;
import
{
createApi
}
from
"@reduxjs/toolkit/query/react"
;
import
{
baseQuery
}
from
"./baseQuery"
;
import
{
baseQuery
}
from
"./baseQuery"
;
import
{
NotificationResponse
}
from
"@/types/notification"
;
import
{
ActivityResponse
,
NotificationResponse
}
from
"@/types/notification"
;
import
{
GlobalResponse
,
QueryParams
}
from
"@/types/config"
;
import
{
GlobalResponse
,
QueryParams
}
from
"@/types/config"
;
export
const
notificationApi
=
createApi
({
export
const
notificationApi
=
createApi
({
...
@@ -36,13 +36,14 @@ export const notificationApi = createApi({
...
@@ -36,13 +36,14 @@ export const notificationApi = createApi({
}),
}),
invalidatesTags
:
[
"Notification"
]
invalidatesTags
:
[
"Notification"
]
}),
}),
getAllActivity
:
builder
.
query
<
NotificationResponse
,
{
activity_type
:
string
}
&
QueryParams
>
({
getAllActivity
:
builder
.
query
<
ActivityResponse
,
{
activity_type
:
string
,
status
?
:
string
}
&
QueryParams
>
({
query
:
({
search
,
page
,
per_page
,
activity_type
})
=>
{
query
:
({
search
,
page
,
per_page
,
activity_type
,
status
})
=>
{
const
params
=
new
URLSearchParams
();
const
params
=
new
URLSearchParams
();
if
(
search
)
params
.
append
(
'search'
,
search
);
if
(
search
)
params
.
append
(
'search'
,
search
);
if
(
page
)
params
.
append
(
'page'
,
page
.
toString
());
if
(
page
)
params
.
append
(
'page'
,
page
.
toString
());
if
(
per_page
)
params
.
append
(
'page_size'
,
per_page
.
toString
());
if
(
per_page
)
params
.
append
(
'page_size'
,
per_page
.
toString
());
if
(
per_page
)
params
.
append
(
'activity_type'
,
activity_type
.
toString
());
if
(
activity_type
)
params
.
append
(
'activity_type'
,
activity_type
.
toString
());
if
(
status
)
params
.
append
(
'status'
,
status
.
toString
());
const
queryString
=
params
.
toString
();
const
queryString
=
params
.
toString
();
return
{
return
{
url
:
`/api/admin/activity
${
queryString
?
`?
${
queryString
}
`
:
''
}
`
,
url
:
`/api/admin/activity
${
queryString
?
`?
${
queryString
}
`
:
''
}
`
,
...
...
src/types/notification.ts
View file @
bd1b5dd7
...
@@ -20,7 +20,18 @@ export interface ActivityResponse {
...
@@ -20,7 +20,18 @@ export interface ActivityResponse {
success
:
boolean
;
success
:
boolean
;
message
:
string
;
message
:
string
;
data
:
{
data
:
{
data
:
{}
[];
data
:
ActivityProps
[];
pagination
:
Pagination
;
pagination
:
Pagination
;
}
}
}
export
interface
ActivityProps
{
id
:
number
,
username
:
string
,
email
:
string
,
status
:
string
,
log
:
string
type
:
string
,
timestamp
:
string
;
}
}
\ 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