Compare commits

...

13 Commits

21 changed files with 112 additions and 30 deletions
@@ -1,5 +1,10 @@
const QUERIES = {
USERS_LIST: 'users-list',
STARTED_LIST: 'started-list',
READY_LIST: 'ready-list',
PENDING_LIST: 'pending-list',
APPROVED_LIST: 'approved-list',
REJECTED_LIST: 'rejected-list',
EMPLOYERS_LIST: 'employers-list',
SIGNATORY_LIST: 'signatory-list',
}
@@ -1,4 +1,4 @@
import { FC } from 'react';
import { FC, useEffect } from 'react';
import { Link } from 'react-router-dom';
import { useAuth } from '../../../../app/modules/auth';
import { Languages } from './Languages';
@@ -6,6 +6,42 @@ import { toAbsoluteUrl } from '../../../helpers';
const HeaderUserMenu: FC = () => {
const { currentUser, logout } = useAuth();
// Listen for user activity and trigger logout
useEffect(() => {
let timeout: number;
const inactiveTime: number = 7 * 60 * 1000; //default inactive period (milliseconds)
// Logout user after inactiveTime minutes of inactivity
const resetTimeout = () => {
clearTimeout(timeout);
// Set logout timeout
timeout = window.setTimeout(() => {
logout();
}, inactiveTime);
};
const handleUserActivity: any = () => {
resetTimeout(); // reset session on user activity
};
document.addEventListener('mousemove', handleUserActivity);
document.addEventListener('keydown', handleUserActivity);
document.addEventListener('click', handleUserActivity);
document.addEventListener('focus', handleUserActivity);
// Initialize timeout
resetTimeout();
// Remove event listeners on unmount
return () => {
clearTimeout(timeout);
document.removeEventListener('mousemove', handleUserActivity);
document.removeEventListener('keydown', handleUserActivity);
document.removeEventListener('click', handleUserActivity);
document.removeEventListener('focus', handleUserActivity);
};
}, [logout]);
return (
<div
className="menu menu-sub menu-sub-dropdown menu-column menu-rounded menu-gray-600 menu-state-bg menu-state-primary fw-bold py-4 fs-6 w-275px"
@@ -7,7 +7,7 @@ const UserEditModalHeader = () => {
return (
<div className='modal-header'>
{/* begin::Modal title */}
<h2 className='fw-bolder'>Add User</h2>
<h2 className='fw-bolder'>Edit Signatory</h2>
{/* end::Modal title */}
{/* begin::Close */}
@@ -38,7 +38,7 @@ const editUserSchema = Yup.object().shape({
const ModalForm: FC<Props> = ({ user, isUserLoading }) => {
const {closeCustomModal} = useCustomModal()
const {closeCustomModal, showCustomModal} = useCustomModal()
const { setItemIdForUpdate } = useListView();
const { refetch, isLoading } = useQueryResponse();
@@ -72,7 +72,7 @@ const ModalForm: FC<Props> = ({ user, isUserLoading }) => {
if (isNotEmpty(values.id)) {
await updateUser(values);
} else {
await createSignatory(values);
await createSignatory({employer_uid:showCustomModal?.data?.id, ...values});
}
} catch (ex) {
console.error(ex);
@@ -61,7 +61,7 @@ const UserActionsCell: FC<Props> = ({id}) => {
{/* begin::Menu item */}
<div className='menu-item px-3'>
<a className='menu-link px-3' onClick={()=>{openCustomModal(MODALNAMES.addSignatory, {})}}>
<a className='menu-link px-3' onClick={()=>{openCustomModal(MODALNAMES.addSignatory, {id})}}>
Add Signatory
</a>
</div>
+1
View File
@@ -30,6 +30,7 @@ export type User = {
status?: string
added?: string
updated?: string
employer_name?: string
}
export type UsersQueryResponse = Response<Array<User>>
@@ -1,6 +1,7 @@
import axios, { AxiosResponse } from "axios";
import { ID, Response } from "../../../../_digifi/helpers"
import { User, UsersQueryResponse } from "./_models";
import { postAuxEnd } from "../../auth/core/AxiosCallHelper";
const API_URL = import.meta.env.VITE_APP_THEME_API_URL;
const USER_URL = `${API_URL}/user`;
@@ -43,6 +44,10 @@ const getApprovedUsers = (query: string): Promise<UsersQueryResponse> => { // FU
.then((d: AxiosResponse<UsersQueryResponse>) => d.data);
};
const employersVerify = (uid: ID): Promise<UsersQueryResponse> => { // FUNCTION FOR EMPLOYERS VERIFICATION
return postAuxEnd('/employers/verify', {application_uid:uid})
};
const getUserById = (id: ID): Promise<User | undefined> => {
return axios
.get(`${USER_URL}/${id}`)
@@ -79,6 +84,7 @@ export {
getPendingUsers,
getReadyUsers,
getApprovedUsers,
employersVerify,
deleteUser,
deleteSelectedUsers,
getUserById,
@@ -32,7 +32,7 @@ const QueryResponseProvider: FC<WithChildren> = ({ children }) => {
refetch,
data: response,
} = useQuery(
`${QUERIES.USERS_LIST}-${query}`,
`${QUERIES.APPROVED_LIST}-${query}`,
() => {
return getApprovedUsers(query);
},
@@ -32,7 +32,7 @@ const QueryResponseProvider: FC<WithChildren> = ({ children }) => {
refetch,
data: response,
} = useQuery(
`${QUERIES.USERS_LIST}-${query}`,
`${QUERIES.PENDING_LIST}-${query}`,
() => {
return getPendingUsers(query);
},
@@ -3,7 +3,7 @@ import { QueryRequestProvider } from "./core/QueryRequestProvider";
import { QueryResponseProvider } from "./core/QueryResponseProvider";
import { UsersListHeader } from "./components/header/UsersListHeader";
import { UsersTable } from "./table/UsersTable";
import { UserEditModal } from "./user-edit-modal/UserEditModal";
import { EditLoanModal } from "./edit-loan-modal/EditLoanModal";
import { KTCard } from "../../../../_digifi/helpers";
import { ToolbarWrapper } from "../../../../_digifi/layout/components/toolbar";
import { Content } from "../../../../_digifi/layout/components/content";
@@ -16,7 +16,7 @@ const UsersList = () => {
<UsersListHeader />
<UsersTable />
</KTCard>
{itemIdForUpdate !== undefined && <UserEditModal />}
{itemIdForUpdate !== undefined && <EditLoanModal />}
</>
);
};
@@ -32,7 +32,7 @@ const QueryResponseProvider: FC<WithChildren> = ({ children }) => {
refetch,
data: response,
} = useQuery(
`${QUERIES.USERS_LIST}-${query}`,
`${QUERIES.READY_LIST}-${query}`,
() => {
return getReadyUsers(query);
},
@@ -2,7 +2,7 @@ import {useEffect} from 'react'
import {UserEditModalHeader} from './UserEditModalHeader'
import {UserEditModalFormWrapper} from './UserEditModalFormWrapper'
const UserEditModal = () => {
const EditLoanModal = () => {
useEffect(() => {
document.body.classList.add('modal-open')
return () => {
@@ -41,4 +41,4 @@ const UserEditModal = () => {
)
}
export {UserEditModal}
export {EditLoanModal}
@@ -79,7 +79,8 @@ const UserEditModalForm: FC<Props> = ({ user, isUserLoading }) => {
>
{/* begin::Scroll */}
<div
className="d-flex flex-column scroll-y me-n7 pe-7"
// className="d-flex flex-column scroll-y me-n7 pe-7"
className="d-none flex-column scroll-y me-n7 pe-7"
id="kt_modal_add_user_scroll"
data-kt-scroll="true"
data-kt-scroll-activate="{default: false, lg: true}"
@@ -396,11 +397,11 @@ const UserEditModalForm: FC<Props> = ({ user, isUserLoading }) => {
<button
type="reset"
onClick={() => cancel()}
className="btn btn-light me-3"
className="btn btn-danger me-3"
data-kt-users-modal-action="cancel"
disabled={formik.isSubmitting || isUserLoading}
>
Discard
Cancel
</button>
<button
@@ -2,7 +2,7 @@ import { useQuery } from "react-query";
import { UserEditModalForm } from "./UserEditModalForm";
import { isNotEmpty, QUERIES } from "../../../../../_digifi/helpers";
import { useListView } from "../core/ListViewProvider";
import { getUserById } from "../../core/_requests";
import { getUserById, getApprovedUsers } from "../../core/_requests";
const UserEditModalFormWrapper = () => {
const { itemIdForUpdate, setItemIdForUpdate } = useListView();
@@ -12,9 +12,10 @@ const UserEditModalFormWrapper = () => {
data: user,
error,
} = useQuery(
`${QUERIES.USERS_LIST}-user-${itemIdForUpdate}`,
`${QUERIES.READY_LIST}-user-${itemIdForUpdate}`,
() => {
return getUserById(itemIdForUpdate);
// return getUserById(itemIdForUpdate);
return getApprovedUsers('');
},
{
cacheTime: 0,
@@ -33,7 +34,10 @@ const UserEditModalFormWrapper = () => {
}
if (!isLoading && !error && user) {
return <UserEditModalForm isUserLoading={isLoading} user={user} />;
// return <UserEditModalForm isUserLoading={isLoading} user={user} />;
// REMOVE LATER AND ALLOW UP ALONE
let newUser:any = user?.records
return <UserEditModalForm isUserLoading={isLoading} user={newUser} />;
}
return null;
@@ -7,7 +7,7 @@ const UserEditModalHeader = () => {
return (
<div className="modal-header">
{/* begin::Modal title */}
<h2 className="fw-bolder">Add User</h2>
<h2 className="fw-bolder">Edit Loan</h2>
{/* end::Modal title */}
{/* begin::Close */}
@@ -0,0 +1,11 @@
import {FC} from 'react'
type Props = {
employer_name?: string
}
const EmployerCell: FC<Props> = ({employer_name}) => (
<div className='badge badge-light fw-bolder'>{employer_name}</div>
)
export {EmployerCell}
@@ -4,7 +4,8 @@ import { MenuComponent } from "../../../../../../_digifi/assets/ts/components";
import { ID, KTIcon, QUERIES } from "../../../../../../_digifi/helpers";
import { useListView } from "../../core/ListViewProvider";
import { useQueryResponse } from "../../core/QueryResponseProvider";
import { deleteUser } from "../../../core/_requests";
import { employersVerify } from "../../../core/_requests";
import { User } from "../../../core/_models";
type Props = {
id: ID;
@@ -15,6 +16,8 @@ const UserActionsCell: FC<Props> = ({ id }) => {
const { query } = useQueryResponse();
const queryClient = useQueryClient();
// let selectedUser = data?.filter((item:User) => item.uid == id)[0]
useEffect(() => {
MenuComponent.reinitialization();
}, []);
@@ -23,14 +26,21 @@ const UserActionsCell: FC<Props> = ({ id }) => {
setItemIdForUpdate(id);
};
const deleteItem = useMutation(() => deleteUser(id), {
const empsVerify = useMutation(() => employersVerify(id), {
// 💡 response of the mutation is passed to onSuccess
onSuccess: () => {
// ✅ update detail view directly
queryClient.invalidateQueries([`${QUERIES.USERS_LIST}-${query}`]);
queryClient.invalidateQueries([`${QUERIES.READY_LIST}-${query}`]);
},
});
const resendVerification = async () => { // FUNCTION TO RESEND VERIFICATION
let cont = confirm('Are you sure, you want to send resend verification?')
if(cont){
await empsVerify.mutateAsync()
}
}
return (
<>
<a
@@ -44,7 +54,7 @@ const UserActionsCell: FC<Props> = ({ id }) => {
</a>
{/* begin::Menu */}
<div
className="menu menu-sub menu-sub-dropdown menu-column menu-rounded menu-gray-600 menu-state-bg-light-primary fw-bold fs-7 w-125px py-4"
className="menu menu-sub menu-sub-dropdown menu-column menu-rounded menu-gray-600 menu-state-bg-light-primary fw-bold fs-7 w-175px py-4"
data-kt-menu="true"
>
{/* begin::Menu item */}
@@ -60,9 +70,9 @@ const UserActionsCell: FC<Props> = ({ id }) => {
<a
className="menu-link px-3"
data-kt-users-table-filter="delete_row"
onClick={async () => await deleteItem.mutateAsync()}
onClick={async () => resendVerification()}
>
Delete
Resend Verification
</a>
</div>
{/* end::Menu item */}
@@ -8,6 +8,7 @@ import {UserCustomHeader} from './UserCustomHeader'
import {UserSelectionHeader} from './UserSelectionHeader'
import {User} from '../../../core/_models'
import { AddedCell } from './AddedCell'
import { EmployerCell } from './EmployerCell'
const usersColumns: ReadonlyArray<Column<User>> = [
{
@@ -20,6 +21,13 @@ const usersColumns: ReadonlyArray<Column<User>> = [
id: 'firstname',
Cell: ({...props}) => <UserInfoCell user={props.data[props.row.index]} />,
},
{
Header: (props) => (
<UserCustomHeader tableProps={props} title='Employer' className='min-w-125px' />
),
id: 'employer_name',
Cell: ({...props}) => <EmployerCell employer_name={props.data[props.row.index].employer_name} />,
},
{
Header: (props) => <UserCustomHeader tableProps={props} title='Amount' className='min-w-125px' />,
accessor: 'loan_amount',
@@ -32,7 +32,7 @@ const QueryResponseProvider: FC<WithChildren> = ({children}) => {
refetch,
data: response,
} = useQuery(
`${QUERIES.USERS_LIST}-${query}`,
`${QUERIES.REJECTED_LIST}-${query}`,
() => {
return getRejectedUsers(query)
},
@@ -32,7 +32,7 @@ const QueryResponseProvider: FC<WithChildren> = ({ children }) => {
refetch,
data: response,
} = useQuery(
`${QUERIES.USERS_LIST}-${query}`,
`${QUERIES.STARTED_LIST}-${query}`,
() => {
return getStartedUsers(query);
},
+2 -2
View File
@@ -11,12 +11,12 @@ type ContextProps = {
type ShowModalProps = {
name?: string
data?: {
[index: string]: string | number | undefined;
[index: string]: undefined | null | number | string;
}
}
type DataProps = {
[index: string]: string | number | undefined;
[index: string]: undefined | null | number | string;
}
type ModalNames = {