Compare commits

..

10 Commits

Author SHA1 Message Date
CHIEFSOFT\ameye 37b371faf5 added data 2026-05-24 16:43:06 -04:00
CHIEFSOFT\ameye 601babbcae added data 2026-05-24 16:36:00 -04:00
ameye 7ca70d7f55 Turnstile 2026-05-23 14:50:37 -04:00
ameye 39c99f68bc Sign up reports 2026-05-02 08:52:27 -04:00
ameye 21a43b9c21 more pages 2026-05-02 02:38:47 -04:00
ameye 2b1ec53131 fix banner 2026-05-01 19:19:31 -04:00
ameye 1054fa0fd1 add acc page 2026-05-01 19:15:49 -04:00
ameye 094b8b15d5 Merge branch 'update-profile' of MERMS/MermsFirstOffice into master 2026-04-30 16:13:42 +00:00
victorAnumudu b0263ae768 update profile addded 2026-04-30 13:43:35 +01:00
ameye 0fb267e3f4 Merge branch 'account-edit-page-fixed' of MERMS/MermsFirstOffice into master 2026-04-29 18:21:29 +00:00
19 changed files with 624 additions and 31 deletions
+3 -1
View File
@@ -7,7 +7,7 @@ INSTAGRAM_URL=https://www.instagram.com
# BACKEND END POINTS
REACT_APP_MAIN_API="https://devapi.mermsemr.com"
# REACT_APP_MAIN_API="http://localhost:14700"
#REACT_APP_MAIN_API="http://localhost:14700"
# ENQUIRIES CONTACTS
VITE_CALL_ENDPOINT='09099000000'
@@ -20,4 +20,6 @@ VITE_BANK_NAME_SHORT='FCMB'
# Inactivity timeout/logout AT 10MINS
REACT_APP_TIMEOUT=600000
#CLOUDFLARE
REACT_APP_TURNSTILE_SITE_KEY=0x4AAAAAADQV82wuocFR-u5O
+4 -1
View File
@@ -18,4 +18,7 @@ VITE_BANK_NAME='First City Monument Bank'
VITE_BANK_NAME_SHORT='FCMB'
# Inactivity timeout/logout AT 10MINS
REACT_APP_TIMEOUT=600000
REACT_APP_TIMEOUT=600000
#CLOUDFLARE
REACT_APP_TURNSTILE_SITE_KEY=0x4AAAAAADQV82wuocFR-u5O
+5 -2
View File
@@ -7,7 +7,7 @@ INSTAGRAM_URL=https://www.instagram.com
# BACKEND END POINTS
REACT_APP_MAIN_API="https://api.mermsemr.com"
#REACT_APP_MAIN_API="http://localhost:14700"
# REACT_APP_MAIN_API="http://localhost:14700"
# ENQUIRIES CONTACTS
VITE_CALL_ENDPOINT='09099000000'
@@ -18,4 +18,7 @@ VITE_BANK_NAME='First City Monument Bank'
VITE_BANK_NAME_SHORT='FCMB'
# Inactivity timeout/logout AT 10MINS
REACT_APP_TIMEOUT=600000
REACT_APP_TIMEOUT=600000
#CLOUDFLARE
REACT_APP_TURNSTILE_SITE_KEY=0x4AAAAAADQV82wuocFR-u5O
+1
View File
@@ -5,6 +5,7 @@
"dependencies": {
"@reduxjs/toolkit": "^2.5.1",
"@tanstack/react-query": "^5.66.0",
"@marsidev/react-turnstile": "^1.5.2",
"apexcharts": "^4.5.0",
"axios": "^1.7.9",
"cra-template": "1.2.0",
+1
View File
@@ -9,6 +9,7 @@ const RouteLinks = {
billings: '/billings',
files_uploads: '/files-uploads',
recentSignup: '/recent-signup',
recentAccount: '/recent-account',
loansPage: '/loans',
transactionsPage: '/transactions',
countrySettings: '/country',
+3
View File
@@ -25,6 +25,7 @@ import CountrySettingsPage from "./pages/CountrySettingsPage";
import ProductViewPage from "./pages/ProductViewPage";
import FilesUploadPage from "./pages/FilesUploadPage"; // TRANSACTION DETAILS PAGE
import AccountEditpage from "./pages/AccountEditPage";
import RecentAccountsPage from "./pages/RecentAccountsPage";
// const Home = lazy(() => import('./pages/Home'));
@@ -35,6 +36,8 @@ export default function SiteRoutes() {
<Route element={<UserExist/>}>
<Route path={RouteLinks.homePage} element={<HomePage/>}/> {`*/HOME PAGE*/`}
<Route path={RouteLinks.recentAccount} element={<RecentAccountsPage/>}/> {`*/RECENT SIGNUP PAGE*/`}
<Route path={RouteLinks.recentSignup} element={<RecentSignupPage/>}/> {`*/RECENT SIGNUP PAGE*/`}
<Route path={RouteLinks.subscriptions} element={<SubscriptionsPage/>}/> {`*/SUBSCRIPTIONS PAGE*/`}
<Route path={RouteLinks.customerPage} element={<CustomerPage/>}/> {`*/CUSTOMER PAGE*/`}
+2 -2
View File
@@ -1,9 +1,9 @@
import React from 'react'
export default function InputText({id, name, type='text', placeholder, value, handleChange}) {
export default function InputText({id, name, type='text', placeholder, disabled, value, handleChange}) {
return (
<div className='w-full h-12 overflow-hidden'>
<input id={id} name={name} type={type} value={value} placeholder={placeholder} onChange={handleChange} className='p-2 w-full h-full text-black outline-0 ring-0 border border-slate-300 focus:border-purple-600 rounded-md' />
<input id={id} name={name} type={type} value={value} placeholder={placeholder} disabled={disabled} onChange={handleChange} className='p-2 w-full h-full text-black outline-0 ring-0 border border-slate-300 focus:border-purple-600 rounded-md' />
</div>
)
}
@@ -30,9 +30,6 @@ export default function AccountBannerCom({accountInfo}) {
<th scope="col" className="px-2">
Country
</th>
<th scope="col" className="px-2 text-right">
Action
</th>
</tr>
</thead>
<tbody>
+22 -5
View File
@@ -8,6 +8,8 @@ import RouteLinks from "../../RouteLinks";
import { getAccountView } from "../../services/siteServices";
import queryKeys from "../../services/queryKeys";
import AccountBannerCom from "./AccountBannerCom";
import UpdateProfile from "./UpdateProfile";
import UpdatePassword from "./UpdatePassword";
export default function AccountEditCom() {
@@ -38,7 +40,6 @@ export default function AccountEditCom() {
const accountsViewData = data?.data; // ACCOUNT EDIT DATA
const account_info = accountsViewData?.account;
useEffect(() => {
queryClient.refetchQueries({
queryKey: [...queryKeys.account_view],
@@ -53,20 +54,36 @@ export default function AccountEditCom() {
title={`Account Edit [${state?.memberUID}]`}
paths={["Dashboard", "Account Edit"]}
/>
<div className="box bg-white dark:bg-black-box text-black-body dark:text-white-body">
{isFetching ? (
<>
<div className="box bg-white dark:bg-black-box text-black-body dark:text-white-body">
<p className="text-slate-800">Loading...</p>
</div>
</>
) : isError ? (
<p className="text-red-500">{error.message}</p>
<div className="box bg-white dark:bg-black-box text-black-body dark:text-white-body">
<p className="text-red-500">{error.message}</p>
</div>
) : (
<>
<div className="box bg-white dark:bg-black-box text-black-body dark:text-white-body">
<AccountBannerCom accountInfo={account_info} />
</div>
<div className="box bg-white dark:bg-black-box text-black-body dark:text-white-body">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-12 gap-5">
<div className="p-4 col-span-12 lg:col-span-7 xl:col-span-8 shadow border rounded-xl">
<UpdateProfile accountInfo={account_info} />
</div>
<div className="p-4 max-h-96 col-span-12 lg:col-span-5 xl:col-span-4 shadow border rounded-xl">
<UpdatePassword />
</div>
</div>
</div>
</>
)}
</div>
</div>
);
}
@@ -0,0 +1,124 @@
import {Link} from 'react-router-dom'
import Icons from "../Icons";
import {useMutation} from '@tanstack/react-query'
import {Formik, Form} from 'formik'
import * as Yup from "yup";
import InputText from '../InputText'
export default function UpdatePassword() {
const initialValues = {
newPassword: "",
confirmPassword: ""
};
// To get the validation schema
const validationSchema = Yup.object().shape({
newPassword: Yup.string()
.min(6, 'must be upto 6 characters')
.max(25, 'must not exceed 25 characters')
.required("New password is required"),
confirmPassword: Yup.string()
.oneOf([Yup.ref("newPassword"), null], "Passwords do not match")
.required("Confirm password is required"),
});
const updatePassword = useMutation({
mutationFn: (fields) => {
if (!fields.newPassword || !fields.confirmPassword) {
throw new Error('Please provide all fields marked *')
}
// return loginUser(fields)
},
onError: (error) => {
console.log(error)
},
onSuccess: (res) => {
// const {jwt_token, user} = res?.data
setTimeout(() => {
updatePassword.reset()
}, 3000);
}
})
//FUNCTION TO HANDLE LOGIN
const handleSubmit = (values, helper) => {
updatePassword.mutate(values)
};
return <>
<div className="flex flex-col gap-1">
<div className="w-full">
<h4 className="mb-3 font-semibold text-lg">Change Password</h4>
</div>
<div className="w-full">
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={handleSubmit}
>
{(props) => (
<Form>
<div className='flex flex-col gap-8 w-full'>
<div className='flex flex-col gap-6'>
<div className='relative text-input flex flex-col gap-2'>
<p className='flex items-center gap-1'>
<label className='text-lg'>New Password</label>
<span className='text-red-500 text-10'>{(props.errors.newPassword && props.touched.newPassword) ? props.errors.newPassword : ''}</span>
</p>
<InputText
id='newPassword'
placeholder='New Password'
name='newPassword'
type='password'
value={props.values.newPassword}
handleChange={props.handleChange}
/>
</div>
<div className='relative text-input flex flex-col gap-2'>
<p className='flex items-center gap-1'>
<label className='text-lg'>Confirm Password</label>
<span className='text-red-500 text-10'>{(props.errors.confirmPassword && props.touched.confirmPassword) ? props.errors.confirmPassword : ''}</span>
</p>
<InputText
id='confirmPassword'
placeholder='Confirm Password'
name='confirmPassword'
type='password'
value={props.values.confirmPassword}
handleChange={props.handleChange}
/>
</div>
<div className='flex justify-end h-10 mb-10'>
<button type='submit' disabled={updatePassword.isPending} className='px-4 h-full bg-primary text-white font-bold rounded-md'>{updatePassword.isPending ? 'loading...' : 'Update Password'}</button>
</div>
{updatePassword.error &&
<>
<div className="w-full text-center">
<p className='text-red-500 text-sm'>{updatePassword.error.message}</p>
</div>
</>
}
{updatePassword.success &&
<>
<div className="w-full text-center">
<p className='text-emerald-500 text-sm'>{'Password Updated Successfully'}</p>
</div>
</>
}
</div>
</div>
</Form>
)}
</Formik>
</div>
</div>
</>
}
@@ -0,0 +1,204 @@
import {Link} from 'react-router-dom'
import Icons from "../Icons";
import {useMutation} from '@tanstack/react-query'
import {Formik, Form} from 'formik'
import * as Yup from "yup";
import InputText from '../InputText'
import { useEffect } from 'react';
import { useQuery, useQueryClient } from "@tanstack/react-query";
import queryKeys from '../../services/queryKeys';
import {updateUserProfile} from '../../services/siteServices'
export default function UpdateProfile({accountInfo}) {
const queryClient = useQueryClient();
const initialValues = {
firstname: accountInfo?.firstname || "",
lastname: accountInfo?.lastname || "",
account_name: accountInfo?.account_name || "",
phone_number: accountInfo?.phone_number || "",
email: accountInfo?.email || "",
address: accountInfo?.address || "",
};
// To get the validation schema
const validationSchema = Yup.object().shape({
firstname: Yup.string().required("First name is required").min(3, 'must be upto 3 characters').max(25, 'must not exceed 25 characters'),
lastname: Yup.string().required("Last name is required").min(3, 'must be upto 3 characters').max(25, 'must not exceed 25 characters'),
account_name: Yup.string().required("Account name is required").min(3, 'must be upto 3 characters').max(25, 'must not exceed 25 characters'),
phone_number: Yup.string().required("Phone number is required").min(6, 'must be upto 6 characters').max(25, 'must not exceed 25 characters'),
email: Yup.string().email('Invalid email format').required("Email is required").max(50, 'must not exceed 50 characters'),
address: Yup.string().required("Address is required").min(10, 'must be at least 10 characters').max(255, 'must not exceed 255 characters'),
});
const updateProfile = useMutation({
mutationFn: (fields) => {
return updateUserProfile(fields)
},
onError: (error) => {
console.log(error)
},
onSuccess: (res) => {
// if(res?.data?.resultCode != '0') {
// throw new Error(res?.data?.message || res?.data?.resultDescription || 'An error occurred while updating profile')
// }
queryClient.refetchQueries({
queryKey: [...queryKeys.account_view],
// type: 'active',
// exact: true,
});
},
onSettled: () => {
setTimeout(() => {
updateProfile.reset()
}, 3000);
}
})
//FUNCTION TO HANDLE LOGIN
const handleSubmit = (values, helper) => {
const newValues= {
member_uid: accountInfo?.uid || "",
member_account_name: values?.account_name || "",
member_firstname: values?.firstname || "",
member_full_address: values?.address || "",
member_lastname: values?.lastname || "",
member_email: values?.email || "",
member_phone: values?.phone_number || ""
}
updateProfile.mutate(newValues)
console.log('values', newValues)
};
return <>
<div className="flex flex-col gap-1">
<div className="w-full">
<h4 className="mb-3 font-semibold text-lg">Edit Your Personal Settings</h4>
</div>
<div className="w-full">
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={handleSubmit}
>
{(props) => (
<Form>
<div className='flex flex-col gap-8 w-full'>
<div className='flex flex-col gap-6'>
<div className='relative text-input flex flex-col gap-2'>
<p className='flex items-center gap-1'>
<label className='text-lg'>First Name</label>
<span className='text-red-500 text-10'>{(props.errors.firstname && props.touched.firstname) ? props.errors.firstname : ''}</span>
</p>
<InputText
id='firstname'
placeholder='First Name'
name='firstname'
value={props.values.firstname}
handleChange={props.handleChange}
/>
</div>
<div className='relative text-input flex flex-col gap-2'>
<p className='flex items-center gap-1'>
<label className='text-lg'>Last Name</label>
<span className='text-red-500 text-10'>{(props.errors.lastname && props.touched.lastname) ? props.errors.lastname : ''}</span>
</p>
<InputText
id='lastname'
placeholder='Last Name'
name='lastname'
value={props.values.lastname}
handleChange={props.handleChange}
/>
</div>
<div className='relative text-input flex flex-col gap-2'>
<p className='flex items-center gap-1'>
<label className='text-lg'>Account Name</label>
<span className='text-red-500 text-10'>{(props.errors.account_name && props.touched.account_name) ? props.errors.account_name : ''}</span>
</p>
<InputText
id='account_name'
placeholder='Account Name'
name='account_name'
value={props.values.account_name}
handleChange={props.handleChange}
/>
</div>
<div className='relative text-input flex flex-col gap-2'>
<p className='flex items-center gap-1'>
<label className='text-lg'>Phone Number</label>
<span className='text-red-500 text-10'>{(props.errors.phone_number && props.touched.phone_number) ? props.errors.phone_number : ''}</span>
</p>
<InputText
id='phone_number'
placeholder='Phone Number'
name='phone_number'
value={props.values.phone_number}
handleChange={props.handleChange}
/>
</div>
<div className='relative text-input flex flex-col gap-2'>
<p className='flex items-center gap-1'>
<label className='text-lg'>Email</label>
<span className='text-red-500 text-10'>{(props.errors.email && props.touched.email) ? props.errors.email : ''}</span>
</p>
<InputText
id='email'
placeholder='Email'
disabled={true}
name='email'
value={props.values.email}
handleChange={props.handleChange}
/>
</div>
<div className='relative text-input flex flex-col gap-2'>
<p className='flex items-center gap-1'>
<label className='text-lg'>Address</label>
<span className='text-red-500 text-10'>{(props.errors.address && props.touched.address) ? props.errors.address : ''}</span>
</p>
<InputText
id='address'
placeholder='Address'
name='address'
value={props.values.address}
handleChange={props.handleChange}
/>
</div>
<div className='flex justify-end h-10 mb-10'>
<button type='submit' disabled={updateProfile.isPending} className='px-4 h-full bg-primary text-white font-bold rounded-md'>{updateProfile.isPending ? 'loading...' : 'Update Profile'}</button>
</div>
{updateProfile.error &&
<>
<div className="w-full text-center">
<p className='text-red-500 text-sm'>{updateProfile.error.message}</p>
</div>
</>
}
{updateProfile.error &&
<>
<div className="w-full text-center">
<p className='text-emerald-500 text-sm'>{'Profile Updated Successfully'}</p>
</div>
</>
}
</div>
</div>
</Form>
)}
</Formik>
</div>
</div>
</>
}
+15 -5
View File
@@ -4,6 +4,7 @@ import {useNavigate} from 'react-router-dom'
import {useMutation} from '@tanstack/react-query'
import {Formik, Form} from 'formik'
import * as Yup from "yup";
import {Turnstile} from '@marsidev/react-turnstile'
import InputText from '../InputText'
import {updateUserDetails} from "../../store/UserDetails";
@@ -30,6 +31,7 @@ export default function LoginCom() {
const navigate = useNavigate()
const [loading, setLoading] = useState(false)
const [turnstileToken, setTurnstileToken] = useState(null)
const login = useMutation({
mutationFn: (fields) => {
@@ -53,9 +55,9 @@ export default function LoginCom() {
})
//FUNCTION TO HANDLE LOGIN
const handleSubmit = (values, helper) => {
login.mutate(values)
// handleLogin()
const handleSubmit = (values) => {
if (!turnstileToken) return
login.mutate({...values, cf_turnstile_response: turnstileToken})
};
return (
@@ -107,9 +109,17 @@ export default function LoginCom() {
/>
{/* <p className='text-sm text-end font-medium text-primary'>Forget password ?</p> */}
</div>
<div className="text-center col-12 mt-3">
<Turnstile
siteKey={process.env.REACT_APP_TURNSTILE_SITE_KEY}
onSuccess={setTurnstileToken}
onExpire={() => setTurnstileToken(null)}
onError={() => setTurnstileToken(null)}
/>
</div>
<div className='h-10 mb-10'>
<button type='submit' disabled={login.isPending}
className='w-full h-full bg-primary text-white font-bold rounded-md'>{login.isPending || loading ? 'loading...' : 'Login'}</button>
<button type='submit' disabled={login.isPending || !turnstileToken}
className='w-full h-full bg-primary text-white font-bold rounded-md disabled:opacity-50 disabled:cursor-not-allowed'>{login.isPending || loading ? 'loading...' : 'Login'}</button>
</div>
{login.error &&
@@ -151,8 +151,9 @@ export default function DashboardAside() {
const asideNavLinks = [
{name: 'Dashboard', status: 1, icon: 'dashboard', to: RouteLinks.homePage},
{
name: 'Deployments', title: 'Activities', status: 1, icon: 'arrow-right', subLinks: [
name: 'Front Office', title: 'Activities', status: 1, icon: 'arrow-right', subLinks: [
{name: 'Recent Signup', status: 1, icon: 'dot', to: RouteLinks.recentSignup},
{name: 'Recent Accounts(30)', status: 1, icon: 'dot', to: RouteLinks.recentAccount},
{name: 'Provisions', status: 1, icon: 'dot', to: RouteLinks.subscriptions},
{name: 'Customers', status: 1, icon: 'dot', to: RouteLinks.customerPage},
{name: 'Billings', status: 1, icon: 'dot', to: RouteLinks.billings},
@@ -86,6 +86,7 @@ export default function RecentPaymentsBar({
<Link
to={item.url}
key={index}
target="_blank"
className="flex gap-3 items-center"
>
<div className="px-4 py-2 bg-[#0E172E] rounded-md">
@@ -0,0 +1,203 @@
import { useState } from "react";
import { useQuery } from "@tanstack/react-query";
import queryKeys from "../../services/queryKeys";
import BreadcrumbCom from "../breadcrumb/BreadcrumbCom";
import TablePaginatedWrapper from "../tableWrapper/TablePaginatedWrapper";
import Icons from "../Icons";
import { getRecentAccount } from "../../services/siteServices";
import getDateTimeFromDateString from "../../helpers/getDateTimeFromDateString";
import {Link} from 'react-router-dom';
export default function RecentAccounts() {
const [page, setPage] = useState(1);
const [filter, setFilter] = useState({ type: "", id: "" });
const [willFilter, setWillFilter] = useState(false);
const handleFilter = ({ target: { name, value } }) => {
setFilter((prev) => ({ ...prev, [name]: value }));
};
const handleFilterByParams = () => {
if (filter.type && !filter.id) {
return;
} else if (!filter.type) {
setPage(1);
setWillFilter((prev) => !prev);
setFilter({ type: "", id: "" });
} else {
setPage(1);
setWillFilter((prev) => !prev);
}
};
const { data, isFetching, isError, error } = useQuery({
queryKey: [...queryKeys.recent_account, page, willFilter],
queryFn: () => {
const filterData = filter?.type ? { [filter?.type]: filter.id } : {};
const reqData = {
page,
...filterData,
};
return getRecentAccount(reqData);
},
staleTime: 0, //0 mins
});
const recentSignupData = data?.data?.members; // BILLINGS LIST
const pagination = data?.data?.pagination;
// console.log('DATA', data?.data)
return (
<div className="w-full flex flex-col gap-8">
<BreadcrumbCom
title="Recent Accounts"
paths={["Dashboard", "Recent Acc"]}
/>
<div className="box bg-white dark:bg-black-box text-black-body dark:text-white-body">
{isError ? (
<p className="text-red-500">{error?.message}</p>
) : (
<>
{/* filter section */}
<div className="px-2 py-2 mb-4 flex flex-col sm:flex-row flex-wrap sm:items-center gap-2">
<Icons name="filter" className="text-3xl" />
<div className="w-full sm:max-w-48">
<select
name="type"
value={filter?.type}
className="h-10 w-full p-2 rounded-md"
onChange={handleFilter}
>
<option value="">All</option>
<option value="username">Username</option>
</select>
</div>
<div className="w-full sm:max-w-48">
<input
name="id"
value={filter?.id}
disabled={!filter.type}
className={`h-10 w-full p-2 rounded-md outline-none border border-black-aside ${!filter.type && "opacity-30"}`}
onChange={handleFilter}
/>
</div>
<button
onClick={handleFilterByParams}
disabled={filter.type && !filter.id}
className={`h-10 bg-primary px-2 py-1 rounded-md text-white font-medium sm:self-end ${filter.type && !filter.id && "opacity-50"}`}
>
Submit
</button>
</div>
{/* end of filter section */}
<TablePaginatedWrapper
data={recentSignupData}
isFetching={isFetching}
setPage={setPage}
itemsPerPage={pagination?.limit}
pagination={pagination}
>
{({ data }) => (
<>
<table className="py-2 w-full text-sm">
<thead className="py-2 text-sm text-slate-500 text-left">
<tr>
<th scope="col" className="px-2 py-2">
Added
</th>
<th scope="col" className="px-2">
User Name /Email
</th>
<th scope="col" className="px-2 text-right">
Name
</th>
<th scope="col" className="px-2 text-right">
Country
</th>
<th scope="col" className="px-2 text-right">
Action
</th>
</tr>
</thead>
<tbody>
{data && data.length > 0 ? (
data?.map((item, index) => (
<tr
key={index}
className="py-2 border-t border-dashed border-slate-300"
>
<td className="px-2 py-2">
<div className="w-full min-w-48 flex items-center gap-2 whitespace-nowrap">
<div className="text-left">
<div className="text-base font-semibold">
{getDateTimeFromDateString(item?.added)}
</div>
</div>
</div>
</td>
<td className="px-2">
<div className="text-left">
<div className="text-base font-semibold">
{item?.username}
</div>
<div className="text-base font-semibold">
{item?.email}
</div>
</div>
</td>
<td className="px-2">
<div className="text-right">
<div className="text-base font-semibold">
{item?.firstname} {item?.lastname}
</div>
{/* <div className="font-normal text-gray-500">{item?.external_url}</div> */}
</div>
</td>
<td className="px-2">
<div className="text-right">
<div className="text-base font-semibold">
{item?.country}
</div>
</div>
</td>
<td className="px-2 text-right">
<div className="flex items-center justify-end gap-3 md:gap-4">
<div className="p-2 flex justify-center items-center text-slate-500 bg-white-body dark:text-white-body dark:bg-black-body rounded-md">
<Link
to={`/account-view/${item?.member_uid}`}
state={{
customerID: item?.id,
memberUID: item?.member_uid,
}}
>
<Icons name="eye" />
</Link>
</div>
</div>
</td>
</tr>
))
) : (
<tr className="py-2 border-t border-dashed border-slate-300">
<td className="px-3 py-2" colSpan={4}>
<div className="flex justify-center items-center">
No Record Found
</div>
</td>
</tr>
)}
</tbody>
</table>
</>
)}
</TablePaginatedWrapper>
</>
)}
</div>
</div>
);
}
+11 -11
View File
@@ -51,7 +51,7 @@ export default function RecentSignup() {
return (
<div className="w-full flex flex-col gap-8">
<BreadcrumbCom
title="Recent Signup"
title="Signup Started Report"
paths={["Dashboard", "Recent Acc"]}
/>
@@ -106,20 +106,20 @@ export default function RecentSignup() {
<thead className="py-2 text-sm text-slate-500 text-left">
<tr>
<th scope="col" className="px-2 py-2">
Added
Signup Stareted Added
</th>
<th scope="col" className="px-2">
User Name /Email
Email
</th>
<th scope="col" className="px-2 text-right">
Name
</th>
<th scope="col" className="px-2 text-right">
Country
Status
</th>
<th scope="col" className="px-2 text-right">
{/* <th scope="col" className="px-2 text-right">
Action
</th>
</th> */}
</tr>
</thead>
<tbody>
@@ -140,9 +140,9 @@ export default function RecentSignup() {
</td>
<td className="px-2">
<div className="text-left">
<div className="text-base font-semibold">
{/* <div className="text-base font-semibold">
{item?.username}
</div>
</div> */}
<div className="text-base font-semibold">
{item?.email}
</div>
@@ -159,12 +159,12 @@ export default function RecentSignup() {
<td className="px-2">
<div className="text-right">
<div className="text-base font-semibold">
{item?.country}
{item?.status}
</div>
</div>
</td>
<td className="px-2 text-right">
{/* <td className="px-2 text-right">
<div className="flex items-center justify-end gap-3 md:gap-4">
<div className="p-2 flex justify-center items-center text-slate-500 bg-white-body dark:text-white-body dark:bg-black-body rounded-md">
<Link
@@ -178,7 +178,7 @@ export default function RecentSignup() {
</Link>
</div>
</div>
</td>
</td> */}
</tr>
))
) : (
+8
View File
@@ -0,0 +1,8 @@
import React from 'react'
import RecentAccounts from "../components/recent_accounts/RecentAccounts";
export default function RecentAccountsPage() {
return (
<RecentAccounts />
)
}
+2
View File
@@ -16,10 +16,12 @@ const queryKeys = {
billings: ['billings'],
right_sidebar: ['right_sidebar'],
recent_signup: ['recent_signup'],
recent_account: ['recent_account'],
products: ['products'],
products_template: ['products_template'],
custom_template: ['custom_template'],
account_view: ['account_view'],
account_edit: ['account_edit'],
subscriptions_view: ['subscriptions_view'],
users_admin: ['users_admin'],
country_list: ['country_list'],
+13
View File
@@ -112,6 +112,11 @@ export const getRecentSignup = (reqData) => {
return getAuxEnd(`/recent-signup`, postData)
}
export const getRecentAccount = (reqData) => {
const postData = { ...reqData }
return getAuxEnd(`/recent-account`, postData)
}
// FUNCTION TO GET PRODUCTS DATA
export const getProducts = (reqData) => {
const postData = { ...reqData }
@@ -124,6 +129,14 @@ export const getUsers = (reqData) => {
return getAuxEnd(`/users`, postData)
}
// FUNCTION TO UPDATE USER PROFILE
export const updateUserProfile = (reqData) => {
let postData = {
...reqData
}
return postAuxEnd('/office/update-profile', postData, false)
}
// FUNCTION TO GET PRODUCTS TEMPLATE DATA
export const getProductsTemplate = (reqData) => {
const postData = { ...reqData }