Commit bd1b5dd7 by Arjun Jhukal

updated the chagne password functionality at logged in user profile

parent bca8509d
...@@ -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;
......
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>
)
}
"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>
</> </>
) )
......
...@@ -7,22 +7,14 @@ import { useReactTable, getCoreRowModel, getPaginationRowModel, getSortedRowMode ...@@ -7,22 +7,14 @@ import { useReactTable, getCoreRowModel, getPaginationRowModel, getSortedRowMode
import { Pagination, Box } from '@mui/material'; import { Pagination, Box } from '@mui/material';
import { TransactionStatusProps } from '../transaction/TransactionTable'; import { TransactionStatusProps } from '../transaction/TransactionTable';
import { StatusOptions } from '@/types/config'; import { StatusOptions } from '@/types/config';
import { useGetAllActivityQuery } from '@/services/notificationApi';
import { ActivityProps } from '@/types/notification';
interface Activity {
id: number;
type: string;
user: string;
userId: string;
action: string;
details: string;
timestamp: string;
status: string;
icon: React.ReactNode;
}
export default function Activities() { export default function Activities() {
const activityTypes = [ const activityTypes = [
{ value: 'all', label: 'All Activities' }, { value: '', label: 'All Activities' },
{ value: 'registration', label: 'Registration' }, { value: 'registration', label: 'Registration' },
{ value: 'login', label: 'Login/Logout' }, { value: 'login', label: 'Login/Logout' },
{ value: 'deposit', label: 'Deposits' }, { value: 'deposit', label: 'Deposits' },
...@@ -33,140 +25,6 @@ export default function Activities() { ...@@ -33,140 +25,6 @@ export default function Activities() {
{ value: 'bonus', label: 'Bonuses' } { value: 'bonus', label: 'Bonuses' }
]; ];
const activities: Activity[] = [
{
id: 1,
type: 'registration',
user: 'john_doe',
userId: 'USR001',
action: 'New user registered',
details: 'Account created successfully',
timestamp: '2025-10-16 14:30:25',
status: 'success',
icon: <User />
},
{
id: 2,
type: 'deposit',
user: 'sarah_smith',
userId: 'USR042',
action: 'Cash deposit',
details: 'Amount: $500.00 via Credit Card',
timestamp: '2025-10-16 14:25:10',
status: 'success',
icon: <User />
},
{
id: 3,
type: 'withdrawal',
user: 'mike_wilson',
userId: 'USR078',
action: 'Withdrawal request',
details: 'Amount: $250.00 to Bank Account',
timestamp: '2025-10-16 14:20:45',
status: 'pending',
icon: <User />
},
{
id: 4,
type: 'password_update',
user: 'emma_brown',
userId: 'USR023',
action: 'Password changed',
details: 'Security credentials updated',
timestamp: '2025-10-16 14:15:30',
status: 'success',
icon: <Lock />
},
{
id: 5,
type: 'login',
user: 'david_lee',
userId: 'USR056',
action: 'User login',
details: 'IP: 192.168.1.100, Location: New York, USA',
timestamp: '2025-10-16 14:10:15',
status: 'success',
icon: <User />
},
{
id: 6,
type: 'game_play',
user: 'lisa_garcia',
userId: 'USR089',
action: 'Game played',
details: 'Super Stakes Poker - Bet: $50, Won: $125',
timestamp: '2025-10-16 14:05:00',
status: 'success',
icon: <User />
},
{
id: 7,
type: 'withdrawal',
user: 'alex_martinez',
userId: 'USR034',
action: 'Withdrawal failed',
details: 'Amount: $1000.00 - Insufficient funds',
timestamp: '2025-10-16 14:00:45',
status: 'failed',
icon: <User />
},
{
id: 8,
type: 'profile_update',
user: 'rachel_white',
userId: 'USR067',
action: 'Profile updated',
details: 'Changed email and phone number',
timestamp: '2025-10-16 13:55:30',
status: 'success',
icon: <User />
},
{
id: 9,
type: 'bonus',
user: 'chris_taylor',
userId: 'USR045',
action: 'Bonus claimed',
details: 'Welcome Bonus: $100 credited',
timestamp: '2025-10-16 13:50:15',
status: 'success',
icon: <User />
},
{
id: 10,
type: 'logout',
user: 'olivia_anderson',
userId: 'USR091',
action: 'User logout',
details: 'Session ended normally',
timestamp: '2025-10-16 13:45:00',
status: 'success',
icon: <User />
},
{
id: 11,
type: 'deposit',
user: 'james_thomas',
userId: 'USR012',
action: 'Cash deposit',
details: 'Amount: $1,200.00 via Bank Transfer',
timestamp: '2025-10-16 13:40:45',
status: 'success',
icon: <User />
},
{
id: 12,
type: 'password_update',
user: 'sophia_jackson',
userId: 'USR073',
action: 'Password reset',
details: 'Reset via email verification',
timestamp: '2025-10-16 13:35:30',
status: 'success',
icon: <Lock />
}
];
const [search, setSearch] = React.useState(""); const [search, setSearch] = React.useState("");
const [page, setPage] = React.useState(1); const [page, setPage] = React.useState(1);
...@@ -175,22 +33,21 @@ export default function Activities() { ...@@ -175,22 +33,21 @@ export default function Activities() {
const [activityType, setActivityType] = React.useState("all"); const [activityType, setActivityType] = React.useState("all");
const [sorting, setSorting] = React.useState<any>([]); const [sorting, setSorting] = React.useState<any>([]);
const queryArgs = useMemo(
() => ({
page,
per_page: pageSize,
search: search || "",
activity_type: activityType,
status
}),
[page, pageSize, search, status]
);
const filteredData = useMemo(() => {
return activities.filter(activity => {
const matchesSearch = search === "" ||
activity.user.toLowerCase().includes(search.toLowerCase()) ||
activity.userId.toLowerCase().includes(search.toLowerCase()) ||
activity.action.toLowerCase().includes(search.toLowerCase()) ||
activity.details.toLowerCase().includes(search.toLowerCase());
const matchesType = activityType === "all" || activity.type === activityType;
return matchesSearch && matchesType; const { data, isLoading } = useGetAllActivityQuery(queryArgs)
});
}, [search, activityType]);
const columns = useMemo<ColumnDef<Activity>[]>(() => [ const columns = useMemo<ColumnDef<ActivityProps>[]>(() => [
{ {
accessorKey: "id", accessorKey: "id",
header: ({ column }) => { header: ({ column }) => {
...@@ -216,23 +73,16 @@ export default function Activities() { ...@@ -216,23 +73,16 @@ export default function Activities() {
accessorKey: "user", accessorKey: "user",
header: "User", header: "User",
cell: ({ row }) => { cell: ({ row }) => {
const { user, userId } = row.original; const { username, email } = row.original
const initials = user.split('_').map(n => n[0]).join('').toUpperCase();
return ( return (
<Box className="flex justify-start items-center gap-2"> <div className="name-detail">
<small className="text-[10px] w-[24px] h-[24px] flex items-center justify-center uppercase rounded-[4px] bg-[#1EB41B]/10 font-[500] text-[#1EB41B]"> <strong className="text-primary block text-[12px] leading-[120%] font-[500] capitalize">
{initials} {username}
</strong>
<small className="text-[10px] text-para-light font-[500]">
{email}
</small> </small>
<div className="name-detail"> </div>
<strong className="text-primary block text-[12px] leading-[120%] font-[500] capitalize">
{user.replace('_', ' ')}
</strong>
<small className="text-[10px] text-para-light font-[500]">
{userId}
</small>
</div>
</Box>
); );
}, },
}, },
...@@ -253,18 +103,11 @@ export default function Activities() { ...@@ -253,18 +103,11 @@ export default function Activities() {
}, },
}, },
{ {
accessorKey: "action",
header: "Action",
cell: ({ row }) => (
<span className="text-[12px] font-[500]">{row.original.action}</span>
),
},
{
accessorKey: "details", accessorKey: "details",
header: "Details", header: "Details",
cell: ({ row }) => ( cell: ({ row }) => (
<span className="text-[11px] text-para-light max-w-[250px] block truncate"> <span className="text-[11px] text-para-light max-w-[250px] block truncate">
{row.original.details} {row.original.log}
</span> </span>
), ),
}, },
...@@ -300,7 +143,7 @@ export default function Activities() { ...@@ -300,7 +143,7 @@ export default function Activities() {
], []); ], []);
const table = useReactTable({ const table = useReactTable({
data: filteredData, data: data?.data?.data || [],
columns, columns,
state: { sorting }, state: { sorting },
onSortingChange: setSorting, onSortingChange: setSorting,
...@@ -309,8 +152,6 @@ export default function Activities() { ...@@ -309,8 +152,6 @@ export default function Activities() {
getSortedRowModel: getSortedRowModel(), getSortedRowModel: getSortedRowModel(),
}); });
const totalPages = Math.ceil(filteredData.length / pageSize);
return ( return (
<div className="border-gray border-solid border-[1px] rounded-[8px] lg:rounded-[16px]"> <div className="border-gray border-solid border-[1px] rounded-[8px] lg:rounded-[16px]">
...@@ -332,15 +173,12 @@ export default function Activities() { ...@@ -332,15 +173,12 @@ export default function Activities() {
/> />
<div className="flex flex-col md:flex-row justify-between items-start md:items-center mt-4 px-8 py-6 gap-4"> <div className="flex flex-col md:flex-row justify-between items-start md:items-center mt-4 px-8 py-6 gap-4">
<div className="flex items-center gap-2"> <div>
<span className="text-[12px] font-[500]">Rows per page:</span> <span>Row per page:</span>
<select <select
value={pageSize} value={pageSize}
onChange={(e) => { onChange={(e) => setPageSize(Number(e.target.value))}
setPageSize(Number(e.target.value)); className="ml-2 border border-gray-300 rounded p-1"
setPage(1);
}}
className="border border-gray-300 rounded p-1 text-[12px]"
> >
{[5, 10, 15, 20].map((size) => ( {[5, 10, 15, 20].map((size) => (
<option key={size} value={size}> <option key={size} value={size}>
...@@ -348,18 +186,10 @@ export default function Activities() { ...@@ -348,18 +186,10 @@ export default function Activities() {
</option> </option>
))} ))}
</select> </select>
{/* <span className="text-[12px] text-para-light ml-4">
Showing {filteredData.length > 0 ? ((page - 1) * pageSize) + 1 : 0} to {Math.min(page * pageSize, filteredData.length)} of {filteredData.length} activities
</span> */}
</div> </div>
<Pagination <Pagination count={data?.data?.pagination?.total_pages || 1}
count={totalPages || 1}
page={page} page={page}
onChange={(_, value) => setPage(value)} onChange={(_, value) => setPage(value)} variant="outlined" shape="rounded" sx={{ gap: "8px" }} />
variant="outlined"
shape="rounded"
sx={{ gap: "8px" }}
/>
</div> </div>
</div> </div>
); );
......
...@@ -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
......
...@@ -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;
} }
...@@ -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}
</> </>
); );
......
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}` : ''}`,
......
...@@ -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
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