Application and BVN list added #13
@@ -0,0 +1,137 @@
|
|||||||
|
import { ReactNode, useEffect, useState } from "react";
|
||||||
|
import { RecentBVNProps } from "../../../../app/pages/dashboard/model";
|
||||||
|
|
||||||
|
type PaginatedListProps = {
|
||||||
|
data: RecentBVNProps,
|
||||||
|
itemsPerPage?: number,
|
||||||
|
filterItem?: string[],
|
||||||
|
tableTitle?: string,
|
||||||
|
titleClass?:string,
|
||||||
|
children: (data:RecentBVNProps) => ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function RecentBVNList({
|
||||||
|
data,
|
||||||
|
itemsPerPage = 5,
|
||||||
|
filterItem,
|
||||||
|
tableTitle,
|
||||||
|
titleClass,
|
||||||
|
children,
|
||||||
|
}:PaginatedListProps) {
|
||||||
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
|
const [filteredData, setFilteredData] = useState(data);
|
||||||
|
|
||||||
|
const [currentPage, setCurrentPage] = useState(0);
|
||||||
|
const [newData, setNewData] = useState<any>([]);
|
||||||
|
|
||||||
|
const numberOfSelection = itemsPerPage;
|
||||||
|
|
||||||
|
const handlePrev = () => {
|
||||||
|
if (currentPage != 0) {
|
||||||
|
setCurrentPage((prev) => prev - numberOfSelection);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleNext = () => {
|
||||||
|
if (currentPage < data.length) {
|
||||||
|
setCurrentPage((prev) => prev + numberOfSelection);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSearch = ({ target: { value } }:{target: {value:string}}, name:string) => {
|
||||||
|
setSearchTerm(value);
|
||||||
|
let newFilteredData:any = data.filter((item:any) =>
|
||||||
|
item[name].toLowerCase().startsWith(value.toLowerCase())
|
||||||
|
);
|
||||||
|
setFilteredData(newFilteredData);
|
||||||
|
setCurrentPage(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setNewData(
|
||||||
|
filteredData?.slice(currentPage, numberOfSelection + currentPage)
|
||||||
|
);
|
||||||
|
}, [currentPage, filteredData]);
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
setCurrentPage(0)
|
||||||
|
},[itemsPerPage])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="w-full">
|
||||||
|
<h1 className={`text-2xl mb-5 font-semibold ${titleClass && titleClass}`}>{tableTitle}</h1>
|
||||||
|
|
||||||
|
{data.length > 0 && filterItem && (
|
||||||
|
<div className="mb-10 flex justify-end items-center gap-2">
|
||||||
|
{filterItem.map((item, index) => (
|
||||||
|
<label
|
||||||
|
key={index}
|
||||||
|
className="flex flex-col sm:flex-row items-center gap-2 text-slate-600 dark:text-slate-100 transition-all duration-500"
|
||||||
|
>
|
||||||
|
Search by {item[0].toUpperCase() + item.slice(1)}
|
||||||
|
<input
|
||||||
|
name={item}
|
||||||
|
type="text"
|
||||||
|
className="py-1 px-2 text-sm min-w-[100px] text-black dark:text-white bg-white dark:bg-slate-800 rounded-full border-0 outline-none ring-1 ring-slate-300 dark:ring-white transition-all duration-500"
|
||||||
|
value={searchTerm}
|
||||||
|
onChange={(e) => {
|
||||||
|
handleSearch(e, item);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{children(newData)}
|
||||||
|
|
||||||
|
{/* show prev and next button if data exist */}
|
||||||
|
{(data.length > 0 && data.length > itemsPerPage) && (
|
||||||
|
<div className="mt-2 mt-sm-5 w-full d-flex gap-4 justify-content-center align-items-center">
|
||||||
|
<button
|
||||||
|
onClick={handlePrev}
|
||||||
|
className={`text-sm md:text-lg rounded-circle d-flex justify-content-center align-items-center border-1 transition-all duration-300 ${
|
||||||
|
currentPage == 0
|
||||||
|
? "text-slate-400 border-slate-400 dark:text-slate-400 dark:border-slate-400 pe-none"
|
||||||
|
: "text-slate-600 border-slate-600 dark:text-white dark:border-white"
|
||||||
|
}`}
|
||||||
|
style={{width:'30px', height:'30px'}}
|
||||||
|
>
|
||||||
|
<
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{data.length && data.map((item, index)=>{
|
||||||
|
item = item
|
||||||
|
if(index%itemsPerPage == 0 && index >= currentPage && index <= currentPage+itemsPerPage){
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
key={index}
|
||||||
|
onClick={handleNext}
|
||||||
|
className={`text-sm md:text-lg rounded-circle d-flex justify-content-center align-items-center border-1 transition-all duration-300 ${
|
||||||
|
currentPage != index
|
||||||
|
? "text-slate-400 border-slate-400 dark:text-slate-400 dark:border-slate-400"
|
||||||
|
: "text-slate-600 border-slate-600 dark:text-white dark:border-white pe-none"
|
||||||
|
}`}
|
||||||
|
style={{width:'30px', height:'30px'}}
|
||||||
|
>
|
||||||
|
{index/itemsPerPage +1}
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
|
||||||
|
<button
|
||||||
|
onClick={handleNext}
|
||||||
|
className={`text-sm md:text-lg rounded-circle d-flex justify-content-center align-items-center border-1 transition-all duration-300 ${
|
||||||
|
currentPage + numberOfSelection >= data.length
|
||||||
|
? "text-slate-400 border-slate-400 dark:text-slate-400 dark:border-slate-400 pe-none"
|
||||||
|
: "text-slate-600 border-slate-600 dark:text-white dark:border-white"
|
||||||
|
}`}
|
||||||
|
style={{width:'30px', height:'30px'}}
|
||||||
|
>
|
||||||
|
>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
import { ReactNode, useEffect, useState } from "react";
|
||||||
|
import { RecentApplicationsProps } from "../../../../app/pages/dashboard/model";
|
||||||
|
|
||||||
|
type PaginatedListProps = {
|
||||||
|
data: RecentApplicationsProps,
|
||||||
|
itemsPerPage?: number,
|
||||||
|
filterItem?: string[],
|
||||||
|
tableTitle?: string,
|
||||||
|
titleClass?:string,
|
||||||
|
children: (data:RecentApplicationsProps) => ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function RecentLoanAppList({
|
||||||
|
data,
|
||||||
|
itemsPerPage = 5,
|
||||||
|
filterItem,
|
||||||
|
tableTitle,
|
||||||
|
titleClass,
|
||||||
|
children,
|
||||||
|
}:PaginatedListProps) {
|
||||||
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
|
const [filteredData, setFilteredData] = useState(data);
|
||||||
|
|
||||||
|
const [currentPage, setCurrentPage] = useState(0);
|
||||||
|
const [newData, setNewData] = useState<any>([]);
|
||||||
|
|
||||||
|
const numberOfSelection = itemsPerPage;
|
||||||
|
|
||||||
|
const handlePrev = () => {
|
||||||
|
if (currentPage != 0) {
|
||||||
|
setCurrentPage((prev) => prev - numberOfSelection);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleNext = () => {
|
||||||
|
if (currentPage < data.length) {
|
||||||
|
setCurrentPage((prev) => prev + numberOfSelection);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSearch = ({ target: { value } }:{target: {value:string}}, name:string) => {
|
||||||
|
setSearchTerm(value);
|
||||||
|
let newFilteredData:any = data.filter((item:any) =>
|
||||||
|
item[name].toLowerCase().startsWith(value.toLowerCase())
|
||||||
|
);
|
||||||
|
setFilteredData(newFilteredData);
|
||||||
|
setCurrentPage(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setNewData(
|
||||||
|
filteredData?.slice(currentPage, numberOfSelection + currentPage)
|
||||||
|
);
|
||||||
|
}, [currentPage, filteredData]);
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
setCurrentPage(0)
|
||||||
|
},[itemsPerPage])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="w-full">
|
||||||
|
<h1 className={`text-2xl mb-5 font-semibold ${titleClass && titleClass}`}>{tableTitle}</h1>
|
||||||
|
|
||||||
|
{data.length > 0 && filterItem && (
|
||||||
|
<div className="mb-10 flex justify-end items-center gap-2">
|
||||||
|
{filterItem.map((item, index) => (
|
||||||
|
<label
|
||||||
|
key={index}
|
||||||
|
className="flex flex-col sm:flex-row items-center gap-2 text-slate-600 dark:text-slate-100 transition-all duration-500"
|
||||||
|
>
|
||||||
|
Search by {item[0].toUpperCase() + item.slice(1)}
|
||||||
|
<input
|
||||||
|
name={item}
|
||||||
|
type="text"
|
||||||
|
className="py-1 px-2 text-sm min-w-[100px] text-black dark:text-white bg-white dark:bg-slate-800 rounded-full border-0 outline-none ring-1 ring-slate-300 dark:ring-white transition-all duration-500"
|
||||||
|
value={searchTerm}
|
||||||
|
onChange={(e) => {
|
||||||
|
handleSearch(e, item);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{children(newData)}
|
||||||
|
|
||||||
|
{/* show prev and next button if data exist */}
|
||||||
|
{(data.length > 0 && data.length > itemsPerPage) && (
|
||||||
|
<div className="mt-2 mt-sm-5 w-full d-flex gap-4 justify-content-center align-items-center">
|
||||||
|
<button
|
||||||
|
onClick={handlePrev}
|
||||||
|
className={`text-sm md:text-lg rounded-circle d-flex justify-content-center align-items-center border-1 transition-all duration-300 ${
|
||||||
|
currentPage == 0
|
||||||
|
? "text-slate-400 border-slate-400 dark:text-slate-400 dark:border-slate-400 pe-none"
|
||||||
|
: "text-slate-600 border-slate-600 dark:text-white dark:border-white"
|
||||||
|
}`}
|
||||||
|
style={{width:'30px', height:'30px'}}
|
||||||
|
>
|
||||||
|
<
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{data.length && data.map((item, index)=>{
|
||||||
|
item = item
|
||||||
|
if(index%itemsPerPage == 0 && index >= currentPage && index <= currentPage+itemsPerPage){
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
key={index}
|
||||||
|
onClick={handleNext}
|
||||||
|
className={`text-sm md:text-lg rounded-circle d-flex justify-content-center align-items-center border-1 transition-all duration-300 ${
|
||||||
|
currentPage != index
|
||||||
|
? "text-slate-400 border-slate-400 dark:text-slate-400 dark:border-slate-400"
|
||||||
|
: "text-slate-600 border-slate-600 dark:text-white dark:border-white pe-none"
|
||||||
|
}`}
|
||||||
|
style={{width:'30px', height:'30px'}}
|
||||||
|
>
|
||||||
|
{index/itemsPerPage +1}
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
|
||||||
|
<button
|
||||||
|
onClick={handleNext}
|
||||||
|
className={`text-sm md:text-lg rounded-circle d-flex justify-content-center align-items-center border-1 transition-all duration-300 ${
|
||||||
|
currentPage + numberOfSelection >= data.length
|
||||||
|
? "text-slate-400 border-slate-400 dark:text-slate-400 dark:border-slate-400 pe-none"
|
||||||
|
: "text-slate-600 border-slate-600 dark:text-white dark:border-white"
|
||||||
|
}`}
|
||||||
|
style={{width:'30px', height:'30px'}}
|
||||||
|
>
|
||||||
|
>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -3,11 +3,12 @@ import React from 'react'
|
|||||||
import { NewDateTimeFormatter } from '../../../lib/NewDateTimeFormatter'
|
import { NewDateTimeFormatter } from '../../../lib/NewDateTimeFormatter'
|
||||||
// import {KTIcon} from '../../../helpers'
|
// import {KTIcon} from '../../../helpers'
|
||||||
// import {Dropdown1} from '../../content/dropdown/Dropdown1'
|
// import {Dropdown1} from '../../content/dropdown/Dropdown1'
|
||||||
import { dashDataProps } from '../../../../app/pages/dashboard/model'
|
import { DashDataProps, RecentBVNProps } from '../../../../app/pages/dashboard/model'
|
||||||
|
import RecentBVNList from '../../../layout/components/paginatedListing/RecentBVNList'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
className: string
|
className: string
|
||||||
dashData?: dashDataProps
|
dashData?: DashDataProps
|
||||||
}
|
}
|
||||||
|
|
||||||
const ListsWidget3: React.FC<Props> = ({dashData, className}) => {
|
const ListsWidget3: React.FC<Props> = ({dashData, className}) => {
|
||||||
@@ -38,27 +39,36 @@ const ListsWidget3: React.FC<Props> = ({dashData, className}) => {
|
|||||||
null
|
null
|
||||||
:
|
:
|
||||||
dashData?.data?.recent_bvn && dashData?.data?.recent_bvn.length ?
|
dashData?.data?.recent_bvn && dashData?.data?.recent_bvn.length ?
|
||||||
dashData?.data?.recent_bvn.map(item => (
|
<RecentBVNList
|
||||||
<div key={item?.uid} className='d-flex align-items-center mb-8'>
|
data = {dashData?.data?.recent_bvn}
|
||||||
{/* begin::Bullet */}
|
itemsPerPage={5}
|
||||||
<span className='bullet bullet-vertical h-40px bg-primary'></span>
|
>
|
||||||
{/* end::Bullet */}
|
{(data:RecentBVNProps) => (
|
||||||
{/* begin::Checkbox */}
|
<>
|
||||||
<div className='form-check form-check-custom form-check-solid mx-5'>
|
{data?.map(item => (
|
||||||
<input className='form-check-input' type='checkbox' value='' />
|
<div key={item?.uid} className='d-flex align-items-center mb-8'>
|
||||||
</div>
|
{/* begin::Bullet */}
|
||||||
{/* end::Checkbox */}
|
<span className='bullet bullet-vertical h-40px bg-primary'></span>
|
||||||
{/* begin::Description */}
|
{/* end::Bullet */}
|
||||||
<div className='flex-grow-1'>
|
{/* begin::Checkbox */}
|
||||||
<a href='#' className='text-gray-800 text-hover-primary fw-bold fs-6'>
|
<div className='form-check form-check-custom form-check-solid mx-5'>
|
||||||
{item?.bvn}
|
<input className='form-check-input' type='checkbox' value='' />
|
||||||
</a>
|
</div>
|
||||||
<span className='text-muted fw-semibold d-block'>{NewDateTimeFormatter(item?.added)}</span>
|
{/* end::Checkbox */}
|
||||||
</div>
|
{/* begin::Description */}
|
||||||
{/* end::Description */}
|
<div className='flex-grow-1'>
|
||||||
<span className='badge badge-light-primary fs-8 fw-bold'>New</span>
|
<a href='#' className='text-gray-800 text-hover-primary fw-bold fs-6'>
|
||||||
</div>
|
{item?.bvn}
|
||||||
))
|
</a>
|
||||||
|
<span className='text-muted fw-semibold d-block'>{NewDateTimeFormatter(item?.added)}</span>
|
||||||
|
</div>
|
||||||
|
{/* end::Description */}
|
||||||
|
<span className='badge badge-light-primary fs-8 fw-bold'>New</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</RecentBVNList>
|
||||||
:
|
:
|
||||||
<p>No list Found!</p>
|
<p>No list Found!</p>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,17 @@
|
|||||||
|
|
||||||
import { FC } from 'react'
|
import { FC } from 'react'
|
||||||
import {KTIcon, toAbsoluteUrl} from '../../../helpers'
|
import {KTIcon, toAbsoluteUrl} from '../../../helpers'
|
||||||
import { dashDataProps } from '../../../../app/pages/dashboard/model'
|
import { DashDataProps, RecentApplicationsProps } from '../../../../app/pages/dashboard/model'
|
||||||
import { NewDateTimeFormatter } from '../../../lib/NewDateTimeFormatter'
|
import { NewDateTimeFormatter } from '../../../lib/NewDateTimeFormatter'
|
||||||
|
import RecentLoanAppList from '../../../layout/components/paginatedListing/RecentLoanAppList'
|
||||||
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
className: string
|
className: string
|
||||||
dashData?: dashDataProps
|
dashData?: DashDataProps
|
||||||
}
|
}
|
||||||
|
|
||||||
const TablesWidget10: FC<Props> = ({className, dashData}) => {
|
const TablesWidget10: FC<Props> = ({className, dashData}) => {
|
||||||
console.log('dashData', dashData?.data?.recent_applications)
|
|
||||||
return (
|
return (
|
||||||
<div className={`card ${className}`}>
|
<div className={`card ${className}`}>
|
||||||
{/* begin::Header */}
|
{/* begin::Header */}
|
||||||
@@ -42,116 +41,127 @@ const TablesWidget10: FC<Props> = ({className, dashData}) => {
|
|||||||
{/* begin::Body */}
|
{/* begin::Body */}
|
||||||
{dashData?.loading ?
|
{dashData?.loading ?
|
||||||
null
|
null
|
||||||
|
: dashData?.data?.recent_applications ?
|
||||||
|
<RecentLoanAppList
|
||||||
|
data={dashData?.data?.recent_applications}
|
||||||
|
itemsPerPage={5}
|
||||||
|
>
|
||||||
|
{(data:RecentApplicationsProps)=>(
|
||||||
|
<>
|
||||||
|
<div className='card-body py-3'>
|
||||||
|
{/* begin::Table container */}
|
||||||
|
<div className='table-responsive'>
|
||||||
|
{/* begin::Table */}
|
||||||
|
<table className='table table-row-dashed table-row-gray-300 align-middle gs-0 gy-4'>
|
||||||
|
{/* begin::Table head */}
|
||||||
|
<thead>
|
||||||
|
<tr className='fw-bold text-muted'>
|
||||||
|
<th className='w-25px'>
|
||||||
|
<div className='form-check form-check-sm form-check-custom form-check-solid'>
|
||||||
|
<input
|
||||||
|
className='form-check-input'
|
||||||
|
type='checkbox'
|
||||||
|
value='1'
|
||||||
|
data-kt-check='true'
|
||||||
|
data-kt-check-target='.widget-9-check'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
<th className='min-w-150px'>Authors</th>
|
||||||
|
<th className='min-w-140px'>Amount</th>
|
||||||
|
<th className='min-w-120px'>Progress</th>
|
||||||
|
<th className='min-w-100px text-end'>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
{/* end::Table head */}
|
||||||
|
{/* begin::Table body */}
|
||||||
|
<tbody>
|
||||||
|
{data && data.length ?
|
||||||
|
data.map(item => (
|
||||||
|
<tr key={item?.uid}>
|
||||||
|
<td>
|
||||||
|
<div className='form-check form-check-sm form-check-custom form-check-solid'>
|
||||||
|
<input className='form-check-input widget-9-check' type='checkbox' value='1' />
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div className='d-flex align-items-center'>
|
||||||
|
<div className='symbol symbol-45px me-5'>
|
||||||
|
<img src={toAbsoluteUrl('media/avatars/300-14.jpg')} alt='' />
|
||||||
|
</div>
|
||||||
|
<div className='d-flex justify-content-start flex-column'>
|
||||||
|
<a href='#' className='text-gray-900 fw-bold text-hover-primary fs-6'>
|
||||||
|
{item?.firstname} {item?.lastname}
|
||||||
|
</a>
|
||||||
|
<span className='text-muted fw-semibold text-muted d-block fs-7'>
|
||||||
|
{NewDateTimeFormatter(item?.added)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span className='text-gray-900 fw-bold text-hover-primary d-block fs-6'>
|
||||||
|
{item.loan_amount}
|
||||||
|
</span>
|
||||||
|
<span className='text-muted fw-semibold text-muted d-block fs-7'>
|
||||||
|
{item?.sales_agent? `Agent: ${item?.sales_agent}` : ``}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td className='text-end'>
|
||||||
|
<div className='d-flex flex-column w-100 me-2'>
|
||||||
|
<div className='d-flex flex-stack mb-2'>
|
||||||
|
<span className='text-muted me-2 fs-7 fw-semibold'>50%</span>
|
||||||
|
</div>
|
||||||
|
<div className='progress h-6px w-100'>
|
||||||
|
<div
|
||||||
|
className='progress-bar bg-primary'
|
||||||
|
role='progressbar'
|
||||||
|
style={{width: '50%'}}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div className='d-flex justify-content-end flex-shrink-0'>
|
||||||
|
<a
|
||||||
|
href='#'
|
||||||
|
className='btn btn-icon btn-bg-light btn-active-color-primary btn-sm me-1'
|
||||||
|
>
|
||||||
|
<KTIcon iconName='switch' className='fs-3' />
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href='#'
|
||||||
|
className='btn btn-icon btn-bg-light btn-active-color-primary btn-sm me-1'
|
||||||
|
>
|
||||||
|
<KTIcon iconName='pencil' className='fs-3' />
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href='#'
|
||||||
|
className='btn btn-icon btn-bg-light btn-active-color-primary btn-sm'
|
||||||
|
>
|
||||||
|
<KTIcon iconName='trash' className='fs-3' />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))
|
||||||
|
:
|
||||||
|
<tr>
|
||||||
|
<td colSpan={5}>No data found!</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
{/* end::Table body */}
|
||||||
|
</table>
|
||||||
|
{/* end::Table */}
|
||||||
|
</div>
|
||||||
|
{/* end::Table container */}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</RecentLoanAppList>
|
||||||
:
|
:
|
||||||
<div className='card-body py-3'>
|
null
|
||||||
{/* begin::Table container */}
|
|
||||||
<div className='table-responsive'>
|
|
||||||
{/* begin::Table */}
|
|
||||||
<table className='table table-row-dashed table-row-gray-300 align-middle gs-0 gy-4'>
|
|
||||||
{/* begin::Table head */}
|
|
||||||
<thead>
|
|
||||||
<tr className='fw-bold text-muted'>
|
|
||||||
<th className='w-25px'>
|
|
||||||
<div className='form-check form-check-sm form-check-custom form-check-solid'>
|
|
||||||
<input
|
|
||||||
className='form-check-input'
|
|
||||||
type='checkbox'
|
|
||||||
value='1'
|
|
||||||
data-kt-check='true'
|
|
||||||
data-kt-check-target='.widget-9-check'
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</th>
|
|
||||||
<th className='min-w-150px'>Authors</th>
|
|
||||||
<th className='min-w-140px'>Company</th>
|
|
||||||
<th className='min-w-120px'>Progress</th>
|
|
||||||
<th className='min-w-100px text-end'>Actions</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
{/* end::Table head */}
|
|
||||||
{/* begin::Table body */}
|
|
||||||
<tbody>
|
|
||||||
{dashData?.data.recent_applications && dashData?.data.recent_applications.length ?
|
|
||||||
dashData?.data.recent_applications.map(item => (
|
|
||||||
<tr key={item?.uid}>
|
|
||||||
<td>
|
|
||||||
<div className='form-check form-check-sm form-check-custom form-check-solid'>
|
|
||||||
<input className='form-check-input widget-9-check' type='checkbox' value='1' />
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div className='d-flex align-items-center'>
|
|
||||||
<div className='symbol symbol-45px me-5'>
|
|
||||||
<img src={toAbsoluteUrl('media/avatars/300-14.jpg')} alt='' />
|
|
||||||
</div>
|
|
||||||
<div className='d-flex justify-content-start flex-column'>
|
|
||||||
<a href='#' className='text-gray-900 fw-bold text-hover-primary fs-6'>
|
|
||||||
{item?.firstname} {item?.lastname}
|
|
||||||
</a>
|
|
||||||
<span className='text-muted fw-semibold text-muted d-block fs-7'>
|
|
||||||
{NewDateTimeFormatter(item?.added)}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a href='#' className='text-gray-900 fw-bold text-hover-primary d-block fs-6'>
|
|
||||||
Intertico
|
|
||||||
</a>
|
|
||||||
<span className='text-muted fw-semibold text-muted d-block fs-7'>
|
|
||||||
Web, UI/UX Design
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td className='text-end'>
|
|
||||||
<div className='d-flex flex-column w-100 me-2'>
|
|
||||||
<div className='d-flex flex-stack mb-2'>
|
|
||||||
<span className='text-muted me-2 fs-7 fw-semibold'>50%</span>
|
|
||||||
</div>
|
|
||||||
<div className='progress h-6px w-100'>
|
|
||||||
<div
|
|
||||||
className='progress-bar bg-primary'
|
|
||||||
role='progressbar'
|
|
||||||
style={{width: '50%'}}
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div className='d-flex justify-content-end flex-shrink-0'>
|
|
||||||
<a
|
|
||||||
href='#'
|
|
||||||
className='btn btn-icon btn-bg-light btn-active-color-primary btn-sm me-1'
|
|
||||||
>
|
|
||||||
<KTIcon iconName='switch' className='fs-3' />
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
href='#'
|
|
||||||
className='btn btn-icon btn-bg-light btn-active-color-primary btn-sm me-1'
|
|
||||||
>
|
|
||||||
<KTIcon iconName='pencil' className='fs-3' />
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
href='#'
|
|
||||||
className='btn btn-icon btn-bg-light btn-active-color-primary btn-sm'
|
|
||||||
>
|
|
||||||
<KTIcon iconName='trash' className='fs-3' />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
))
|
|
||||||
:
|
|
||||||
<tr>
|
|
||||||
<td colSpan={5}>No data found!</td>
|
|
||||||
</tr>
|
|
||||||
}
|
|
||||||
</tbody>
|
|
||||||
{/* end::Table body */}
|
|
||||||
</table>
|
|
||||||
{/* end::Table */}
|
|
||||||
</div>
|
|
||||||
{/* end::Table container */}
|
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
{/* begin::Body */}
|
{/* begin::Body */}
|
||||||
|
|
||||||
|
|||||||
@@ -19,9 +19,10 @@ import {
|
|||||||
import { ToolbarWrapper } from '../../../_digifi/layout/components/toolbar';
|
import { ToolbarWrapper } from '../../../_digifi/layout/components/toolbar';
|
||||||
import { Content } from '../../../_digifi/layout/components/content';
|
import { Content } from '../../../_digifi/layout/components/content';
|
||||||
import { getUserDashDetails } from '../../modules/auth/core/_requests';
|
import { getUserDashDetails } from '../../modules/auth/core/_requests';
|
||||||
|
import { DashDataProps } from './model';
|
||||||
|
|
||||||
const DashboardPage: FC = () => {
|
const DashboardPage: FC = () => {
|
||||||
const [dashDetails, setDashDetails] = useState({loading:true, data:{}})
|
const [dashDetails, setDashDetails] = useState<DashDataProps>({loading:true, data:{}})
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
getUserDashDetails().then(res => {
|
getUserDashDetails().then(res => {
|
||||||
|
|||||||
@@ -1,38 +1,43 @@
|
|||||||
export type dashDataProps = {
|
export type RecentApplicationsProps = {
|
||||||
|
firstname?: string
|
||||||
|
lastname?: string
|
||||||
|
uid?: string
|
||||||
|
loan_amount?: string
|
||||||
|
payment_month?: string
|
||||||
|
sales_agent?: string
|
||||||
|
gender?: string | null
|
||||||
|
marital_status?: string
|
||||||
|
email?: string
|
||||||
|
address?: string
|
||||||
|
state?: string
|
||||||
|
country?: string
|
||||||
|
status?: string
|
||||||
|
added?: string
|
||||||
|
updated?: string
|
||||||
|
}[]
|
||||||
|
|
||||||
|
export type RecentBVNProps = {
|
||||||
|
id?: string
|
||||||
|
uid?: string
|
||||||
|
bvn?: string
|
||||||
|
status?: string
|
||||||
|
added?: string
|
||||||
|
updated?: string
|
||||||
|
firstname?: string | null
|
||||||
|
lastname?: string | null
|
||||||
|
middlename?: string | null
|
||||||
|
gender?: string | null
|
||||||
|
birthdate?: string | null
|
||||||
|
phone?: string | null
|
||||||
|
nationality?: string | null
|
||||||
|
}[]
|
||||||
|
|
||||||
|
|
||||||
|
export type DashDataProps = {
|
||||||
loading: boolean,
|
loading: boolean,
|
||||||
data: {
|
data: {
|
||||||
call_return?: string
|
call_return?: string
|
||||||
recent_applications? : {
|
recent_applications? : RecentApplicationsProps
|
||||||
firstname?: string
|
recent_bvn?: RecentBVNProps
|
||||||
lastname?: string
|
|
||||||
uid?: string
|
|
||||||
loan_amount?: string
|
|
||||||
payment_month?: string
|
|
||||||
sales_agent?: string
|
|
||||||
gender?: string | null
|
|
||||||
marital_status?: string
|
|
||||||
email?: string
|
|
||||||
address?: string
|
|
||||||
state?: string
|
|
||||||
country?: string
|
|
||||||
status?: string
|
|
||||||
added?: string
|
|
||||||
updated?: string
|
|
||||||
}[]
|
|
||||||
recent_bvn?: {
|
|
||||||
id?: string
|
|
||||||
uid?: string
|
|
||||||
bvn?: string
|
|
||||||
status?: string
|
|
||||||
added?: string
|
|
||||||
updated?: string
|
|
||||||
firstname?: string | null
|
|
||||||
lastname?: string | null
|
|
||||||
middlename?: string | null
|
|
||||||
gender?: string | null
|
|
||||||
birthdate?: string | null
|
|
||||||
phone?: string | null
|
|
||||||
nationality?: string | null
|
|
||||||
}[]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user