diff --git a/src/MyRoutes.jsx b/src/MyRoutes.jsx index 5e4ff06..2521f66 100644 --- a/src/MyRoutes.jsx +++ b/src/MyRoutes.jsx @@ -7,6 +7,7 @@ import GetStartedPage from './pages/GetStartedPage' import LoginPage from './pages/LoginPage' import HomePage from './pages/HomePage' import myLinks from './myLinks' +import GetLoanPage from './pages/GetLoanPage' export default function MyRoutes() { return ( @@ -16,7 +17,10 @@ export default function MyRoutes() { }> } /> + } /> + + } /> ) } diff --git a/src/authorization/UserExists.jsx b/src/authorization/UserExists.jsx index 867df44..d6ed098 100644 --- a/src/authorization/UserExists.jsx +++ b/src/authorization/UserExists.jsx @@ -13,7 +13,7 @@ export default function UserExists() { const [loading, setLoading] = useState(true) useEffect(()=>{ - if(state?.proceed != 'true'){ + if(!state){ return navigate(myLinks.getStarted, {replace:true}) } setTimeout(()=>{ diff --git a/src/components/GetLoan.jsx b/src/components/GetLoan.jsx new file mode 100644 index 0000000..8ca1cbc --- /dev/null +++ b/src/components/GetLoan.jsx @@ -0,0 +1,32 @@ +import React, { useEffect, useState } from 'react' +import { useLocation, useNavigate } from 'react-router-dom' +import myLinks from '../myLinks' +import Label from './Label' +import InputText from './InputText' + +export default function LoginCom() { + + const {state} = useLocation() + const navigate = useNavigate() + + useEffect(()=>{ + if(!state?.user){ + return navigate(myLinks.getStarted, {replace:true}) + } + },[]) + + return ( +
+
+
+

{state?.user.name}

+ BVN: {state?.user.bvn} +
+ +
+ +
+
+
+ ) +} diff --git a/src/components/HomeCom.jsx b/src/components/HomeCom.jsx index 3a3b851..41535ad 100644 --- a/src/components/HomeCom.jsx +++ b/src/components/HomeCom.jsx @@ -1,59 +1,84 @@ // import React from 'react' import { useQuery } from "@tanstack/react-query"; +import { useNavigate } from 'react-router-dom' import { CiPhone } from "react-icons/ci" -import { IoIosPhonePortrait } from "react-icons/io" +import { CiBank } from "react-icons/ci"; import { MdOutlineEmail } from "react-icons/md" import { demoUsersList } from "../services/siteServices" import queryKeys from "../services/queryKeys" +import myLinks from "../myLinks"; +import TableWrapper from "./TableWrapper"; export default function HomeCom() { + const navigate = useNavigate() + const {data:users, isFetching, isError, error} = useQuery({ queryKey: queryKeys.demoUsers, queryFn: () => demoUsersList() }) - const demoUsers = users?.data - console.log(demoUsers) + const demoUsers = users?.data?.demo_data?.list // LOAN USERS LIST + + const getLoanPage = (user) => { + navigate(myLinks.getLoan, {state:{user}}) + } return ( -
-
Users
-
- - {data.map((item, index) => { - let color = item.place == 'Friends' ? 'text-emerald-500 bg-emerald-100/90' : item.place == 'Office' ? 'text-blue-500 bg-blue-100/90' : 'text-orange-500 bg-orange-100/90' - return ( -
-
-

{item.name}

- {item.place} +
+
+
Users
+ {isFetching ? + <> +
+

Loading...

+
+ + : isError ? +
+

{error.message}

-
-
- - - - {item.contact} -
-
- - - - {item.contact} -
-
- - - - {item.email} -
-
-
- ) - })} + : + + {({ data }) => ( +
+ {data.map((user, index) => { + let color = user.place == 'Friends' ? 'text-emerald-500 bg-emerald-100/90' : user.place == 'Office' ? 'text-blue-500 bg-blue-100/90' : 'text-orange-500 bg-orange-100/90' + return ( +
getLoanPage(user)} key={user?.uid || index} className="w-full rounded p-3 sm:p-5 bg-white shadow flex flex-col gap-5 hover:scale-105 hover:cursor-pointer"> +
+

{user.name}

+ {/* {user.place} */} +
+
+
+ + + + {user.bvn} +
+
+ + + + {user.mobile} +
+
+ + + + {user.email} +
+
+
+ ) + })} +
+ )} +
+ }
) @@ -63,26 +88,26 @@ export default function HomeCom() { -const data = [ - {name:'Jerry Eze', place: 'Home', contact: '021-025-0325', email: 'jerry@example.com'}, - {name:'Mark John', place: 'Office', contact: '011-025-0311', email: 'mark@example.com'}, - {name:'Larry Bon', place: 'Friends', contact: '033-025-0333', email: 'larry@example.com'}, - {name:'Jeff Henry', place: 'Home', contact: '044-025-0344', email: 'jeff@example.com'}, - {name:'Rose Ordor', place: 'Office', contact: '055-025-0355', email: 'rose@example.com'}, - {name:'Mike Timothy', place: 'Friends', contact: '066-025-0366', email: 'mike@example.com'}, +// const data = [ +// {name:'Jerry Eze', place: 'Home', contact: '021-025-0325', email: 'jerry@example.com'}, +// {name:'Mark John', place: 'Office', contact: '011-025-0311', email: 'mark@example.com'}, +// {name:'Larry Bon', place: 'Friends', contact: '033-025-0333', email: 'larry@example.com'}, +// {name:'Jeff Henry', place: 'Home', contact: '044-025-0344', email: 'jeff@example.com'}, +// {name:'Rose Ordor', place: 'Office', contact: '055-025-0355', email: 'rose@example.com'}, +// {name:'Mike Timothy', place: 'Friends', contact: '066-025-0366', email: 'mike@example.com'}, - {name:'Jerry Eze', place: 'Home', contact: '021-025-0325', email: 'jerry@example.com'}, - {name:'Mark John', place: 'Office', contact: '011-025-0311', email: 'mark@example.com'}, - {name:'Larry Bon', place: 'Friends', contact: '033-025-0333', email: 'larry@example.com'}, - {name:'Jeff Henry', place: 'Home', contact: '044-025-0344', email: 'jeff@example.com'}, - {name:'Rose Ordor', place: 'Office', contact: '055-025-0355', email: 'rose@example.com'}, - {name:'Mike Timothy', place: 'Friends', contact: '066-025-0366', email: 'mike@example.com'}, +// {name:'Jerry Eze', place: 'Home', contact: '021-025-0325', email: 'jerry@example.com'}, +// {name:'Mark John', place: 'Office', contact: '011-025-0311', email: 'mark@example.com'}, +// {name:'Larry Bon', place: 'Friends', contact: '033-025-0333', email: 'larry@example.com'}, +// {name:'Jeff Henry', place: 'Home', contact: '044-025-0344', email: 'jeff@example.com'}, +// {name:'Rose Ordor', place: 'Office', contact: '055-025-0355', email: 'rose@example.com'}, +// {name:'Mike Timothy', place: 'Friends', contact: '066-025-0366', email: 'mike@example.com'}, - {name:'Jerry Eze', place: 'Home', contact: '021-025-0325', email: 'jerry@example.com'}, - {name:'Mark John', place: 'Office', contact: '011-025-0311', email: 'mark@example.com'}, - {name:'Larry Bon', place: 'Friends', contact: '033-025-0333', email: 'larry@example.com'}, - {name:'Jeff Henry', place: 'Home', contact: '044-025-0344', email: 'jeff@example.com'}, - {name:'Rose Ordor', place: 'Office', contact: '055-025-0355', email: 'rose@example.com'}, - {name:'Mike Timothy', place: 'Friends', contact: '066-025-0366', email: 'mike@example.com'}, +// {name:'Jerry Eze', place: 'Home', contact: '021-025-0325', email: 'jerry@example.com'}, +// {name:'Mark John', place: 'Office', contact: '011-025-0311', email: 'mark@example.com'}, +// {name:'Larry Bon', place: 'Friends', contact: '033-025-0333', email: 'larry@example.com'}, +// {name:'Jeff Henry', place: 'Home', contact: '044-025-0344', email: 'jeff@example.com'}, +// {name:'Rose Ordor', place: 'Office', contact: '055-025-0355', email: 'rose@example.com'}, +// {name:'Mike Timothy', place: 'Friends', contact: '066-025-0366', email: 'mike@example.com'}, -] \ No newline at end of file +// ] \ No newline at end of file diff --git a/src/components/InputText.jsx b/src/components/InputText.jsx index c9d84e5..cc48267 100644 --- a/src/components/InputText.jsx +++ b/src/components/InputText.jsx @@ -1,9 +1,9 @@ import React from 'react' -export default function InputText({id, name, type='text'}) { +export default function InputText({id, name, type='text', value, handleChange}) { return (
- +
) } diff --git a/src/components/TableWrapper.jsx b/src/components/TableWrapper.jsx new file mode 100644 index 0000000..ebcd158 --- /dev/null +++ b/src/components/TableWrapper.jsx @@ -0,0 +1,148 @@ +import { useEffect, useState } from "react"; + +const data1 = []; + +// type PaginatedListProps = { +// data: { name: string; email: string; status: string; location: string; }[], +// itemsPerPage: number, +// filterItem?: string[], +// titleClass?:string, +// children: (data:any) => ReactNode; +// } + +export default function TableWrapper({ + data = data1, + itemsPerPage = 5, + filterItem, + children, +}) { + const [isLoading, setIsLoading] = useState(true) + const [searchTerm, setSearchTerm] = useState(""); + const [filteredData, setFilteredData] = useState(data); + + const [currentPage, setCurrentPage] = useState(0); + const [newData, setNewData] = useState([]); + + 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 } }, name) => { + setSearchTerm(value); + let newFilteredData = data.filter((item) => + item[name].toLowerCase().startsWith(value.toLowerCase()) + ); + setFilteredData(newFilteredData); + setCurrentPage(0); + }; + + useEffect(() => { + setIsLoading(true) + setTimeout(()=>{ + setNewData( + filteredData?.slice(currentPage, numberOfSelection + currentPage) + ); + setIsLoading(false) + },1000) + }, [currentPage, filteredData]); + + useEffect(()=>{ + setCurrentPage(0) + },[itemsPerPage]) + + return ( +
+ {data.length > 0 && filterItem && ( +
+ {filterItem.map((item, index) => ( + + ))} +
+ )} + +
+
+ {children({ data: newData })} +
+ + {/* PAGINATION BUTTON */} +
+
Showing + {isLoading ? '----' : `${currentPage + 1}-${currentPage + numberOfSelection >= data.length ? data.length : (currentPage + numberOfSelection)}`} of {data.length} +
+
+ + +
+
+
+ + {/* show prev and next button if data exist */} + {/* {data.length > 0 && ( + {data.length && data.map((item, index)=>{ + item = item + if(index%itemsPerPage == 0 && index >= currentPage && index <= currentPage+itemsPerPage){ + return ( + + ) + } + })} +
+ )} */} + {isLoading && } +
+ ); +} + +const TableIsLoading = () => { + return ( +
+

Loading...

+
+ ) +} \ No newline at end of file diff --git a/src/components/auth/LoginCom.jsx b/src/components/auth/LoginCom.jsx index 1a5fc88..eaff995 100644 --- a/src/components/auth/LoginCom.jsx +++ b/src/components/auth/LoginCom.jsx @@ -1,15 +1,51 @@ import React, { useEffect, useState } from 'react' import { useLocation, useNavigate } from 'react-router-dom' +import { useMutation } from '@tanstack/react-query' + import myLinks from '../../myLinks' import Label from '../Label' import InputText from '../InputText' import PageLoader from '../PageLoader' +import { loginUser } from '../../services/siteServices' export default function LoginCom() { + const [loading, setLoading] = useState(true) const {state} = useLocation() const navigate = useNavigate() + const [fields, setFields] = useState({ + username: '', + password: '', + }) + + const handleChange = ({target:{name, value}}) => { + setFields(prev => ({...prev, [name]:value})) + } + + const login = useMutation({ + mutationFn: (fields) => { + if(!fields.username || !fields.password){ + throw new Error('Please provide all fields marked *') + } + return loginUser(fields) + }, + onError: (error) => { + console.log(error) + }, + onSuccess: (res) => { + // const {token, room} = res?.data?.data + // if(token){ + // localStorage.setItem('token', token) + // localStorage.setItem('room', room) + // // const data = {token} + // // dispatch(updateUserDetails({ ...data })); + // } + navigate(myLinks.home, {state:{proceed:'true'}}) // later add redux to dispatch state + } + }) + + useEffect(()=>{ if(state?.proceed != 'true'){ return navigate(myLinks.getStarted, {replace:true}) @@ -28,15 +64,23 @@ export default function LoginCom() {
+ {login.error && + <> +
+

{login.error.message}

+
+ + } +
- +
diff --git a/src/myLinks.js b/src/myLinks.js index f045459..5045a62 100644 --- a/src/myLinks.js +++ b/src/myLinks.js @@ -1,7 +1,9 @@ const myLinks = { + error: '*', getStarted: '/', login: '/login', home: '/home', + getLoan: '/get-loan' } export default myLinks \ No newline at end of file diff --git a/src/pages/GetLoanPage.jsx b/src/pages/GetLoanPage.jsx new file mode 100644 index 0000000..9800529 --- /dev/null +++ b/src/pages/GetLoanPage.jsx @@ -0,0 +1,8 @@ +import React from 'react' +import GetLoan from '../components/GetLoan' + +export default function GetLoanPage() { + return ( + + ) +}