diff --git a/.env b/.env index 5e1b33c..426eb40 100644 --- a/.env +++ b/.env @@ -17,7 +17,8 @@ REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/svs/user" #"https://devapi.mermsemr.com/en/desktop/api/v2/myfituser" -REACT_APP_SESSION_EXPIRE_MINUTES=5 +REACT_APP_SESSION_EXPIRE_MINUTES=300000 +REACT_APP_SESSION_EXPIRE_CHECKER=60000 REACT_APP_LOGIN_ERROR_TIMEOUT=7000 diff --git a/src/components/AuthPages/Login/index.jsx b/src/components/AuthPages/Login/index.jsx index c31e51c..697fbb8 100644 --- a/src/components/AuthPages/Login/index.jsx +++ b/src/components/AuthPages/Login/index.jsx @@ -79,7 +79,6 @@ export default function Login() { } } } catch (error) { - console.log(error) setMsgError('An error occurred') } finally { setTimeout(() => { diff --git a/src/components/AuthPages/SignUp/index.jsx b/src/components/AuthPages/SignUp/index.jsx index 8fbc6b8..3cd6a12 100644 --- a/src/components/AuthPages/SignUp/index.jsx +++ b/src/components/AuthPages/SignUp/index.jsx @@ -1,144 +1,254 @@ -import React, { useState } from "react"; -import loginThumb from "../../../assets/images/auth-thumb.svg"; -import googleLogo from "../../../assets/images/google-logo.svg"; -import logo from "../../../assets/images/light-logo.png"; //logo-1.svg"; -import titleShape from "../../../assets/images/shape/title-shape-two.svg"; +import React, { useEffect, useState } from "react"; +import { useNavigate, Link } from "react-router-dom"; +import facebookLogo from "../../../assets/images/facebook-4.svg"; +import WrenchBoard from "../../../assets/images/wrenchboard.png"; +import usersService from "../../../services/UsersService"; import InputCom from "../../Helpers/Inputs/InputCom"; export default function SignUp() { + const [signUpLoading, setSignUpLoading] = useState(false) const [checked, setValue] = useState(false); + // for the catch error + const [msgError, setMsgError] = useState(''); + const [showPassword, setShowPassword] = useState(false); + const [countries, setCountries] = useState([]); + + const [formData, setFormData] = useState({ + country: "", + first_name: "", + last_name: "", + email: "", + password: "" + }); + + const handleInputChange = (event) => { + const { name, value } = event?.target; + setFormData({ ...formData, [name]: value }); + }; + + // To Show and Hide Password + const togglePasswordVisibility = () => { + setShowPassword(!showPassword); + // return console.log('showPassword') + }; const rememberMe = () => { setValue(!checked); }; + + const navigate = useNavigate(); + const userApi = new usersService(); + // Get Country Api + const getCountryList = async () => { + const res = await userApi.getSignupCountryData() + + try { + if (res.status === 200) { + const { signup_country } = await res.data + setCountries(signup_country) + } else if (res.data.result != 100) { + setCountries('Nothing see here!') + } + } catch (error) { + throw new Error(error) + } + } + + const handleSignUp = async () => { + let { country, first_name, last_name, email, password } = formData + + if (email == '' && password == '' && first_name == '') { + setMsgError('Please fill in fields') + } + + try { + if (email !== '' && password !== '' && first_name !== '' && last_name !== '') { + const reqData = { + country: country, + firstname: first_name, + lastname: last_name, + email: email, + username: email, + password: password, + terms: 1, + news: 1 + } + + const res = await userApi.CreateUser(reqData) + if (res.status === 200) { + const { data } = res + if (data.status == -1 && data.acc == 'DULPICATE') { + setMsgError('This account has been already created') + } + if (data.status > 0 && data.internal_return == 100 && data.session != '') { + localStorage.setItem("email", `${data.email}`); + localStorage.setItem("country", `${data.country}`); + localStorage.setItem("firstname", `${data.firstname}`); + localStorage.setItem("lastname", `${data.lastname}`); + setSignUpLoading(true) + + setTimeout(() => { + navigate("/", { replace: true }); + setSignUpLoading(false) + }, 2000) + console.log('Success') + } else { + setMsgError(data.status) + } + } + } + } catch (error) { + throw new Error(error) + setMsgError('An error occurred') + } finally { + setTimeout(() => { + setMsgError(null) + }, 7000) + } + } + + useEffect(() => { + getCountryList() + }, []) + return ( <> -
-
-
+
+
+
-
-
-
-

- Create Account -

-
- shape +
+
+ + wrenchboard + +
+
+
+
+

+ Create Account +

+ Already have an account? Sign in here
-
-
-
-
+ +
+
+ OR +
+
+
+ +
+
+ +
+
+ +
+
+
-
+
-
-
- -
-
- -
-
- -
-
-
- - - I agree all - {msgError}
} +
+
+ + + I agree with all + + terms and condition + + +
+
+
+
+ +
-
- -
-

- Already have account? - - Log In - -

@@ -150,3 +260,32 @@ export default function SignUp() { ); } + +const SelectOption = ({ + label, + name, + inputHandler, + value, + data // passing the data from parent +}) => { + return ( +
+
+ +
+
+ +
+
+ ) +} diff --git a/src/components/Cards/ActiveJobsCard.jsx b/src/components/Cards/ActiveJobsCard.jsx index fb2ea87..4183771 100644 --- a/src/components/Cards/ActiveJobsCard.jsx +++ b/src/components/Cards/ActiveJobsCard.jsx @@ -77,26 +77,27 @@ export default function ActiveJobsCard({
-
- {datas.isActive && ( - - Active - - )} -
+ + {/*
*/} + {/* {datas.isActive && (*/} + {/* */} + {/* Active*/} + {/**/} + {/* )}*/} + {/*
*/} -
- -
+ {/*
*/} + {/* */} + {/* */} + {/* */} + {/*
*/}
diff --git a/src/components/Cards/AvailableJobsCard.jsx b/src/components/Cards/AvailableJobsCard.jsx new file mode 100644 index 0000000..0eb70d9 --- /dev/null +++ b/src/components/Cards/AvailableJobsCard.jsx @@ -0,0 +1,127 @@ +import React, { useState } from "react"; +import { Link } from "react-router-dom"; +import { toast } from "react-toastify"; +import localImgLoad from "../../lib/localImgLoad"; +import Icons from "../Helpers/Icons"; + +export default function AvailableJobsCard({ + className, + datas, + hidden = false, + }) { + //debugger; + const [addFavorite, setValue] = useState(datas.whishlisted); + const [options, setOption] = useState(false); + const favoriteHandler = () => { + if (!addFavorite) { + setValue(true); + toast.success("Added to Favorite List"); + } else { + setValue(false); + toast.warn("Remove to Favorite List"); + } + }; + return ( +
+
+ +

+ {datas.title} +

+ + +
+
+
+

Added

+

+ {datas.offer_added} +

+
+
+
+
+
+

+ Expires +

+

+ {datas.expire} +

+
+
+
+
+
+
+ {datas.description} +
+ + + + + +
+ +
+
+
+ + {/*
*/} + {/* {datas.isActive && (*/} + {/* */} + {/* Active*/} + {/**/} + {/* )}*/} + {/*
*/} + + + {/*
*/} + {/* */} + {/* */} + {/* */} + {/*
*/} +
+ +
+
+
+

+ {datas.price*0.01}{datas.currency} | {datas.timeline_days} day(s) +

+

+ ( {datas.offer_code}) +

+
+
+
+ +
+
+
+
+
+ ); +} diff --git a/src/components/Helpers/Inputs/InputCom/index.jsx b/src/components/Helpers/Inputs/InputCom/index.jsx index 705e5ce..5c98f9f 100644 --- a/src/components/Helpers/Inputs/InputCom/index.jsx +++ b/src/components/Helpers/Inputs/InputCom/index.jsx @@ -8,9 +8,11 @@ export default function InputCom({ name, placeholder, iconName, + passIcon, inputHandler, value, - forgotPassword + forgotPassword, + onClick }) { return (
@@ -25,7 +27,7 @@ export default function InputCom({ )} {forgotPassword && Forgot Password?}
-
+
{iconName && ( -
+
)} + {passIcon && ( +
+ +
+ )}
); diff --git a/src/components/Home/Hero.jsx b/src/components/Home/Hero.jsx index 435bda2..e370778 100644 --- a/src/components/Home/Hero.jsx +++ b/src/components/Home/Hero.jsx @@ -43,10 +43,10 @@ export default function Hero({ className }) { {/* heading */}

- Lock and Lob x Fiesta Spurs + Welcome

- ID : 2320382 + Last Login : 10-10-2026
{/* user */} @@ -64,9 +64,9 @@ export default function Hero({ className }) { {/* countdown */}
-

Current Bid

+

Current Task

- 75,320 ETH + ABCDEFGH01

773.69 USD

@@ -74,7 +74,7 @@ export default function Hero({ className }) {

Next due in

- +

Hrs @@ -85,19 +85,13 @@ export default function Hero({ className }) {
{/* action */}
- - Place a Bid - {" "} - View Art Work + View All Task(s)
diff --git a/src/components/MarketPlace/MainSection.jsx b/src/components/MarketPlace/MainSection.jsx index 063695a..fec95a8 100644 --- a/src/components/MarketPlace/MainSection.jsx +++ b/src/components/MarketPlace/MainSection.jsx @@ -1,8 +1,9 @@ import React, { useEffect, useState } from "react"; //import ProductCardStyleTwo from "../Cards/ProductCardStyleTwo"; import DataIteration from "../Helpers/DataIteration"; -import SearchCom from "../Helpers/SearchCom"; -import ActiveJobsCard from "../Cards/ActiveJobsCard"; +// import SearchCom from "../Helpers/SearchCom"; +// import ActiveJobsCard from "../Cards/ActiveJobsCard"; +import AvailableJobsCard from "../Cards/AvailableJobsCard"; export default function MainSection({ className, marketPlaceProduct }) { const [tab, setTab] = useState("explore"); @@ -98,7 +99,7 @@ export default function MainSection({ className, marketPlaceProduct }) { endLength={products?.length} > {({ datas }) => ( - + )}
diff --git a/src/components/MyWallet/AddFund.jsx b/src/components/MyWallet/AddFund.jsx index c50dda1..8660c34 100644 --- a/src/components/MyWallet/AddFund.jsx +++ b/src/components/MyWallet/AddFund.jsx @@ -1,6 +1,8 @@ import React, {useState} from 'react' +import RecentActivityTable from './WalletComponent/RecentActivityTable' +import LoadingSpinner from '../Spinners/LoadingSpinner' -function AddFund() { +function AddFund({payment}) { //STATE FOR CONTROLLED INPUTS let [inputs, setInputs] = useState('0') @@ -53,27 +55,14 @@ function AddFund() {
-
+

Recent Activity

Activity Report

- - - - - - - - - - - - - - - - - -
DateRecipientAmount/FeeConf/Status
ItemItemItemItem
+ {payment.loading ? + + : + + }
diff --git a/src/components/MyWallet/AddRecipient.jsx b/src/components/MyWallet/AddRecipient.jsx new file mode 100644 index 0000000..0064eca --- /dev/null +++ b/src/components/MyWallet/AddRecipient.jsx @@ -0,0 +1,166 @@ +import React, {useState} from 'react' +import { Link } from 'react-router-dom' +import Icons from '../Helpers/Icons' + +function AddRecipient() { + + //STATE FOR CONTROLLED INPUTS + let [inputs, setInputs] = useState({ + firstname: '', + lastname: '', + country: '', + 'bank-name': '', + 'account-number': '', + 'repeat-account-number': '', + 'account-type': '', + state: '', + city: '' + }) + + // FUNCTION TO HANDLE INPUT CHANGE + const handleChange = ({target:{name, value}}) => { + setInputs(prev => ({...prev, [name]:value})) + } + + //FUNCTION TO HANDLE SUBMIT + const handleSubmit = (e) => { + e.preventDefault(); + + //valid inputs before submitting. Just for texting remove later + + // setInputs((prev)=>{ + // for(let input in prev){ + // prev[input] = '' + // } + // }) + // RETURN INPUTS TO EMPTY STRING + setInputs({ + firstname: '', + lastname: '', + country: '', + 'bank-name': '', + 'account-number': '', + 'repeat-account-number': '', + 'account-type': '', + state: '', + city: '' + }) + } + return ( +
+
+
+

ADD BANK ACCOUNT

+
+ + {/* inputs starts here */} +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ + {/* end of inputs starts here */} + +
+ +
+
+
+
+ +
+ ) +} + +export default AddRecipient \ No newline at end of file diff --git a/src/components/MyWallet/Balance.jsx b/src/components/MyWallet/Balance.jsx index 46e6965..3125134 100644 --- a/src/components/MyWallet/Balance.jsx +++ b/src/components/MyWallet/Balance.jsx @@ -1,10 +1,15 @@ import React, {useState} from 'react' import { Link } from 'react-router-dom' +import RecentActivityTable from './WalletComponent/RecentActivityTable' +import PurchasesTable from './WalletComponent/PurchasesTable' +import CouponTable from './WalletComponent/CouponTable' +import LoadingSpinner from '../Spinners/LoadingSpinner' -function Balance() { +function Balance({wallet, payment, coupon, purchase}) { return (
+ {/* WALLET SECTION */}
@@ -12,20 +17,25 @@ function Balance() {

Add New Wallet

{/* wallet balance */} -
+ {wallet.loading ? + + : + wallet.data.length ? + wallet.data.map((item, index)=> ( +

Currency

- Naira -

Naira

+ {item.description} +

{item.symbol}

balance

- ₦0.00 + {item.symbol}{(item.amount*1).toFixed(2)}

Escrow

- ₦0.00 + {item.symbol}{(item.escrow*1).toFixed(2)}
@@ -34,85 +44,71 @@ function Balance() { Top Up
+ )) + : + wallet.error ? + ( +
+

Opps! An Error occurred, please try again

+
+ ) + : + ( +
+

No Wallets Found!

+
+ ) + } {/* end of wallet balance */}
- + {/* END OF WALLET SECTION */} + + + {/* RECENT ACTIVITY SECTION */}
-
+

Recent Activity

Activity Report

- - - - - - - - - - - - - - - - - -
DateRecipientAmount/FeeConf/Status
ItemItemItemItem
+ {payment.loading ? + + : + + }
+ {/* END OF RECENT ACTIVITY SECTION */}
- + +
-
-
-

Purchases

- - - - - - - - - - - - - - - - - -
DateDescriptionAmountFee
ItemItemItemItem
-
-
- + {/* PURCHASE SECTION */}
-
-

Coupons

- - - - - - - - - - - - - - - - - -
DateDescriptionAmountActive
ItemItemItemItem
+
+

Purchases

+ {purchase.loading ? + + : + + }
+ {/* END OF PURCHASE SECTION */} + + {/* COUPON SECTION */} +
+
+

Coupons

+ {coupon.loading ? + + : + + } +
+
+ {/* END OF COUPON SECTION */}
+
) } diff --git a/src/components/MyWallet/TransferFund.jsx b/src/components/MyWallet/TransferFund.jsx index a754224..06c90dc 100644 --- a/src/components/MyWallet/TransferFund.jsx +++ b/src/components/MyWallet/TransferFund.jsx @@ -1,17 +1,58 @@ -import React, {useState} from 'react' +import React, {useEffect, useState} from 'react' import { Link } from 'react-router-dom' +import RecentActivityTable from './WalletComponent/RecentActivityTable' +import LoadingSpinner from '../Spinners/LoadingSpinner' + +import usersService from '../../services/UsersService' + +function TransferFund({payment, wallet}) { + const apiCall = new usersService() + + let [newFee, setNewFee] = useState(false) + + let [recepients, setRecipients] = useState({ // FOR COUPON HISTORY + loading: true, + data: [], + error: false + }) + + let [sendMoneyFee, setSendMoneyFee] = useState({fee: 0, total: 0}) // HOLD THE VALUE FOR SEND MONEY FEE -function TransferFund() { - //STATE FOR CONTROLLED INPUTS let [inputs, setInputs] = useState({ amount: '0', - fee: '0', recipient: '', - total: '0', comment: '' }) + //FUNCTION TO GET RECIPIENT LIST + const getRecipients = ()=>{ + apiCall.getRecipient().then((res)=>{ + if(res.data.internal_return < 0){ // success but no data + setRecipients(prev => ({...prev, loading: false})) + return + } + setRecipients(prev => ({...prev, loading: false, data: res.data.result_list})) + }).catch((error)=>{ + setRecipients(prev => ({...prev, loading: false, error: true})) + }) + } + + //FUNCTION TO GET SEND MONEY FEE + const getSendMoneyFee = ()=>{ + let {amount} = inputs + if(Number(amount) <= 0 || amount=='' || isNaN(amount)){ + setSendMoneyFee({fee: 0, total: 0}) + return + } + apiCall.getSendMoneyFee(Number(amount)).then((res)=>{ + setSendMoneyFee({fee: res.data.processing_fee, total: res.data.total_amount}) + }).catch((error)=>{ + setSendMoneyFee({fee: 0, total: 0}) + }) + } + + // FUNCTION TO HANDLE INPUT CHANGE const handleChange = ({target:{name, value}}) => { setInputs(prev => ({...prev, [name]:value})) @@ -21,22 +62,41 @@ function TransferFund() { const handleSubmit = (e) => { e.preventDefault(); - //valid inputs before submitting. Just for texting remove later + //valid inputs before submitting. Just for texting remove later. check amoutn to be number setInputs({ amount: '0', - fee: '0', recipient: '', - total: '0', comment: '' }) } + + useEffect(()=>{ + getRecipients() + getSendMoneyFee() + },[newFee]) return (
-
-

Withdraw from Naira Wallet : ₦0.00

+ + {wallet.loading ? + + : + wallet.data.length ? +

+ {wallet.data.map(item => { + if(item.description == 'Naira'){ + return `Withdraw from Naira Wallet : ${item.symbol}${(item.amount*1).toFixed(2)}` + } + })} +

+ : + wallet.error ? +

Opps! An Error Occured

+ : +

No Wallet Information Found!

+ }
@@ -47,31 +107,33 @@ function TransferFund() { placeholder='Amount' required onChange={handleChange} + onMouseEnter={()=>{setNewFee(false)}} + onMouseLeave={()=>{setNewFee(true)}} />
-
- - Total * +
@@ -83,10 +145,25 @@ function TransferFund() { * ! - Add New + Add New
- + {recepients.loading ? + + : + recepients.data.length ? + <> + + {recepients.data.map((item, index)=>( + + ))} + + : + recepients.error ? + + : + + }
@@ -106,32 +183,21 @@ function TransferFund() {
- +
-
+

Recent Activity

Activity Report

- - - - - - - - - - - - - - - -
DateRecipientAmount/FeeConf/Status
ItemItemItem
+ {payment.loading ? + + : + + }
diff --git a/src/components/MyWallet/Wallet.jsx b/src/components/MyWallet/Wallet.jsx index 71c0680..0af9a45 100644 --- a/src/components/MyWallet/Wallet.jsx +++ b/src/components/MyWallet/Wallet.jsx @@ -1,11 +1,13 @@ -import React from 'react' +import React, { useEffect, useState } from 'react' import {Routes, Route, Outlet, Navigate} from 'react-router-dom' +import usersService from '../../services/UsersService' import Layout from '../Partials/Layout' import Balance from './Balance' import TransferFund from './TransferFund' import AddFund from './AddFund' +import AddRecipient from './AddRecipient' function Wallet() { return ( @@ -20,13 +22,99 @@ function Wallet() { const WalletRoutes = () => { + const apiCall = new usersService() + + let [walletList, setWalletList] = useState({ // FOR WALLET LIST + loading: true, + data: [], + error: false + }) + + let [paymentHistory, setPaymentHistory] = useState({ // FOR PAYMENT HISTORY + loading: true, + data: [], + error: false + }) + + let [purchaseHistory, setPurchaseHistory] = useState({ // FOR PURCHASE HISTORY + loading: true, + data: [], + error: false + }) + + let [couponHistory, setCouponHistory] = useState({ // FOR COUPON HISTORY + loading: true, + data: [], + error: false + }) + + //FUNCTION TO GET WALLET LIST + const getWalletList = ()=>{ + apiCall.getUserWallets(null).then((res)=>{ + if(res.data.internal_return < 0){ // success but no data + setWalletList(prev => ({...prev, loading: false})) + return + } + setWalletList(prev => ({...prev, loading: false, data: res.data.result_list})) + }).catch((error)=>{ + setWalletList(prev => ({...prev, loading: false, error: true})) + }) + } + + //FUNCTION TO GET PAYMENT HISTORY + const getPaymentHistory = ()=>{ + apiCall.getPaymentHx().then((res)=>{ + if(res.data.internal_return < 0){ // success but no data + setPaymentHistory(prev => ({...prev, loading: false})) + return + } + setPaymentHistory(prev => ({...prev, loading: false, data: res.data.result_list})) + }).catch((error)=>{ + setPaymentHistory(prev => ({...prev, loading: false, error: true})) + }) + } + + //FUNCTION TO GET PURCHASE HISTORY + const getPurchaseHistory = ()=>{ + apiCall.getPurchaseHx().then((res)=>{ + if(res.data.internal_return < 0){ // success but no data + setPurchaseHistory(prev => ({...prev, loading: false})) + return + } + // console.log('purchase',res.data) + setPurchaseHistory(prev => ({...prev, loading: false, data: res.data.result_list})) + }).catch((error)=>{ + setPurchaseHistory(prev => ({...prev, loading: false, error: true})) + }) + } + + //FUNCTION TO GET COUPON HISTORY + const getCouponHistory = ()=>{ + apiCall.getCouponHx().then((res)=>{ + if(res.data.internal_return < 0){ // success but no data + setCouponHistory(prev => ({...prev, loading: false})) + return + } + setCouponHistory(prev => ({...prev, loading: false, data: res.data.result_list})) + }).catch((error)=>{ + setCouponHistory(prev => ({...prev, loading: false, error: true})) + }) + } + + useEffect(()=>{ + getWalletList() + getPaymentHistory() + getPurchaseHistory() + getCouponHistory() + }, []) return ( }> - } /> - } /> - } /> + } /> + } /> + } /> } /> + } /> ) diff --git a/src/components/MyWallet/WalletComponent/CouponTable.jsx b/src/components/MyWallet/WalletComponent/CouponTable.jsx new file mode 100644 index 0000000..29a695c --- /dev/null +++ b/src/components/MyWallet/WalletComponent/CouponTable.jsx @@ -0,0 +1,47 @@ +import React from 'react' + +function CouponTable({coupon}) { + return ( + + + + + + + + + + {coupon.data.length ? + ( + + {coupon.data.map((item, index) => ( + + + + + + + ))} + + ) + : + coupon.error ? + ( + + + + + + ) + : + + + + + + } +
DateDescriptionAmountActive
{item.added}{item.code}{item.amount}{item.status}
Opps! an error occurred. Please try again!
No Purchase History Found!
+ ) +} + +export default CouponTable \ No newline at end of file diff --git a/src/components/MyWallet/WalletComponent/PurchasesTable.jsx b/src/components/MyWallet/WalletComponent/PurchasesTable.jsx new file mode 100644 index 0000000..20202ae --- /dev/null +++ b/src/components/MyWallet/WalletComponent/PurchasesTable.jsx @@ -0,0 +1,47 @@ +import React from 'react' + +function PurchasesTable({purchase}) { + return ( + + + + + + + + + + {purchase.data.length ? + ( + + {purchase.data.map((item, index) => ( + + + + + + + ))} + + ) + : + purchase.error ? + ( + + + + + + ) + : + + + + + + } +
DateDescriptionAmountFee
{item.added_date}{item.confirmation}{item.amount}{item.fee}
Opps! an error occurred. Please try again!
No Purchase History Found!
+ ) +} + +export default PurchasesTable \ No newline at end of file diff --git a/src/components/MyWallet/WalletComponent/RecentActivityTable.jsx b/src/components/MyWallet/WalletComponent/RecentActivityTable.jsx new file mode 100644 index 0000000..841002d --- /dev/null +++ b/src/components/MyWallet/WalletComponent/RecentActivityTable.jsx @@ -0,0 +1,47 @@ +import React from 'react' + +function RecentActivityTable({payment}) { + return ( + + + + + + + + + + {payment.data.length ? + ( + + {payment.data.map((item, index) => ( + + + + + + + ))} + + ) + : + payment.error ? + ( + + + + + + ) + : + + + + + + } +
DateRecipientAmount/FeeConf/Status
{item.trx_date}{item.amount}/{item.fee}{item.status}
Opps! an error occurred. Please try again!
No Payment History Found!
+ ) +} + +export default RecentActivityTable \ No newline at end of file diff --git a/src/components/MyWallet/WalletHeader.jsx b/src/components/MyWallet/WalletHeader.jsx index 1c19632..d769841 100644 --- a/src/components/MyWallet/WalletHeader.jsx +++ b/src/components/MyWallet/WalletHeader.jsx @@ -1,3 +1,4 @@ +import {Link} from 'react-router-dom' import Icons from "../Helpers/Icons"; import bank1 from "../../assets/images/bank-1.png"; import bank2 from "../../assets/images/bank-2.png"; @@ -41,33 +42,30 @@ export default function WalletHeader(props) { {props.myWalletList && props.myWalletList?.result_list?.length > 0 && - props.myWalletList.result_list.map((value) => ( - <> -
  • -
    -
    -
    - -
    -
    -

    - {value.description} -

    -
    + props.myWalletList.result_list.map((value, index) => ( +
  • +
    +
    +
    +
    -
    -

    - {value.amount*0.01} {value.code} -

    -

    - {/*(773.69 USD)*/} +

    +

    + {value.description}

    -
  • - - +
    +

    + {(value.amount*1).toFixed(2)} {value.code} +

    +

    + {/*(773.69 USD)*/} +

    +
    +
    + ))} {/*
  • */} @@ -163,14 +161,15 @@ export default function WalletHeader(props) { {/*
  • */} {/**/} -
    - + */} + Manage
    diff --git a/src/components/Partials/MobileSideBar.jsx b/src/components/Partials/MobileSideBar.jsx index 0bc25bc..15835f2 100644 --- a/src/components/Partials/MobileSideBar.jsx +++ b/src/components/Partials/MobileSideBar.jsx @@ -122,7 +122,7 @@ export default function MobileSidebar({ sidebar, action, logoutModalHandler }) { className="nav-item flex items-center justify-start space-x-3.5" > - + Messages diff --git a/src/components/Partials/Sidebar.jsx b/src/components/Partials/Sidebar.jsx index d21d62e..7fdd242 100644 --- a/src/components/Partials/Sidebar.jsx +++ b/src/components/Partials/Sidebar.jsx @@ -122,7 +122,7 @@ export default function Sidebar({ sidebar, action, logoutModalHandler }) { }`} > - + - + - + { + setReferralList({ + loading: true, + error: false, + data: [] + }) + apiCall.getReferralHx().then((res)=>{ + setReferralList((prev)=>{ + return {...prev, loading: false, data:[...res.data.result_list]} + }) + }).catch((error)=>{ + setReferralList(prev => ({...prev, loading: false, error: true})) + }) + } + + //FUNCTION TO SEND REFERRAL MESSAGE + const sendReferralMsg = (postData) => { + apiCall.sendReferralMsg(postData).then((res)=>{ + if(res.data.internal_return < 0){ + setError({message:'Email already referred', loading: false}) + return + }else{ + setInputs({ firstname: '', lastname: '', email: '',}) + toast.success("Message Sent"); + setError({message:'', loading: false}) + setRefHistoryReload(prev => !prev) + } + }).catch((error)=>{ + setError({message:'Opps! an error occured, try again later', loading: false}) + }) + } //STATE FOR CONTROLLED INPUTS let [inputs, setInputs] = useState({ firstname: '', lastname: '', - email: '', - status: 'pending' + email: '' }) // FUNCTION TO HANDLE INPUT CHANGE @@ -19,17 +66,30 @@ function ReferralDisplay() { //FUNCTION TO HANDLE SUBMIT const handleSubmit = (e) => { e.preventDefault(); + setError({message: '', loading: true}) + let {firstname, lastname, email} = inputs + if(!firstname || !lastname || !email){ + setError({message: 'Please fill all fields', loading: false}) + return + } - //valid inputs before submitting. Just for texting remove later - setReferralList(prev => [...prev, inputs]) - setInputs({ - firstname: '', - lastname: '', - email: '', - status: 'pending' - }) + var postData = { + uid: localStorage.getItem("uid"), + member_id: localStorage.getItem("member_id"), + sessionid: localStorage.getItem("session_token"), + action: 11032, + ref_firstname: firstname, + ref_lastname: lastname, + ref_email: email + }; + + sendReferralMsg(postData) // FUNCTION TO SEND REFERRAL MESSAGE } + useEffect(()=>{ + allReferrals() + }, [refHistoryReload]) + return (
    @@ -43,7 +103,6 @@ function ReferralDisplay() { name='firstname' type="text" placeholder='Firstname' - required onChange={handleChange} />
    @@ -55,7 +114,6 @@ function ReferralDisplay() { name='lastname' type="text" placeholder='Lastname' - required onChange={handleChange} />
    @@ -67,46 +125,80 @@ function ReferralDisplay() { name='email' type="email" placeholder='Email' - required onChange={handleChange} />

    + {error.message != '' &&

    {error.message}

    }
    + {error.loading ? +
    +
    + +
    +
    + : + }
    -
    -

    Referral List

    +
    +

    Referral List

    + {referralList.loading ? + ( +
    +
    + +
    +
    + ) + : + ( - - - + + + - {referralList.length ? - referralList.map(item => ( - - - - + {referralList.data.length ? + referralList.data.map((item, index) => ( + + + + )) : - ( + ( + referralList.error ? + + + + : + ( + ) + ) }
    Added/NameEmailStatusAdded/NameEmailStatus
    {item.firstname} {item.lastname}{item.email}{item.status}
    {item.added_date} / {item.firstname} {item.lastname}{item.email}{item.status}
    Opps! couldn't get referral history. Try reloading the page
    No Item Found on referral List
    + ) + }
    diff --git a/src/components/Spinners/LoadingSpinner.jsx b/src/components/Spinners/LoadingSpinner.jsx new file mode 100644 index 0000000..ed48666 --- /dev/null +++ b/src/components/Spinners/LoadingSpinner.jsx @@ -0,0 +1,16 @@ +import React from 'react' + +function LoadingSpinner({size, color}) { + return ( +
    +
    + +
    +
    + ) +} + +export default LoadingSpinner \ No newline at end of file diff --git a/src/index.css b/src/index.css index b2004bf..313642e 100644 --- a/src/index.css +++ b/src/index.css @@ -712,4 +712,18 @@ TODO: Responsive =========================== .content-wrapper.login{ --bg-color: 255,255,255; background: linear-gradient(90deg, rgba(236,237,240,1) 0%, rgba(255,255,255,1) 50%, rgba(236,237,240,1) 100%); +} + +.content-wrapper select { + /* for Firefox */ + -moz-appearance: none; + /* for Chrome */ + -webkit-appearance: none; + appearance: none; + padding-inline: 1rem; +} + +/* For IE10 */ +.content-wrapper select::-ms-expand { + display: none; } \ No newline at end of file diff --git a/src/middleware/AuthRoute.jsx b/src/middleware/AuthRoute.jsx index 9f557fc..f7b4b9c 100644 --- a/src/middleware/AuthRoute.jsx +++ b/src/middleware/AuthRoute.jsx @@ -1,7 +1,55 @@ -import { Navigate, Outlet } from "react-router-dom"; +import { useEffect, useState } from "react"; +import { Navigate, Outlet, useLocation, useNavigate } from "react-router-dom"; const AuthRoute = ({ redirectPath = "/login", children }) => { + const [lastActivityTime, setLastActivityTime] = useState(Date.now()); const isLogin = localStorage.getItem("email"); + + const navigate = useNavigate(); + const { pathname } = useLocation(); + + + //Removing Data stored at localStorage after session expires + const expireSession = () => { + localStorage.removeItem("email"); + localStorage.removeItem('session_token'); + localStorage.removeItem('firstname'); + localStorage.removeItem('member_id'); + localStorage.removeItem('lastname'); + localStorage.removeItem('state'); + localStorage.removeItem('last_login'); + localStorage.removeItem('uid'); + localStorage.removeItem('session'); + localStorage.removeItem('city'); + localStorage.removeItem('country'); + localStorage.removeItem('loglevel'); + localStorage.removeItem('zip_code'); + localStorage.removeItem('added'); + navigate("/login", { replace: true }); // redirects user to login page after session expires + }; + + const checkInactivity = setInterval(() => { + if (Date.now() - lastActivityTime > process.env.REACT_APP_SESSION_EXPIRE_MINUTES) { + expireSession() + } + }, process.env.REACT_APP_SESSION_EXPIRE_CHECKER) // Checks for inactivity every minute + + // Reset last activity time on user input + const resetTime = () => { + setLastActivityTime(Date.now()); + } + window.addEventListener('mousemove', resetTime) + window.addEventListener('keydown', resetTime) + + useEffect(() => { + // cleaning up listeners + return () => { + clearInterval(checkInactivity) + window.removeEventListener('mousemove', resetTime) + window.removeEventListener('keydown', resetTime) + } + }, [pathname, lastActivityTime]) + if (!isLogin) { return ; } diff --git a/src/services/UsersService.js b/src/services/UsersService.js index 1e1dd37..cab41ac 100644 --- a/src/services/UsersService.js +++ b/src/services/UsersService.js @@ -48,9 +48,9 @@ class usersService { return this.postAuxEnd("/apigate", null); } - CreateUser(){ - // localStorage.setItem("session_token", ``); - return this.postAuxEnd("/createuser", null); + CreateUser(reqData){ + localStorage.setItem("session_token", ``); + return this.postAuxEnd("/createuser", reqData); } getLoadProfile(){ @@ -140,15 +140,85 @@ class usersService { return this.postAuxEnd("/couponpending", postData); } + // API FUNCTION TO GET COUPON HISTORY + getRecipient(){ + var postData = { + uid: localStorage.getItem("uid"), + member_id: localStorage.getItem("member_id"), + sessionid: localStorage.getItem("session_token"), + page:1, + limit :20, + action: 11175 + }; + return this.postAuxEnd("/recipients", postData); + } + + // API FUNCTION TO GET SEND MONEY FEE + getSendMoneyFee(amount){ + var postData = { + uid: localStorage.getItem("uid"), + member_id: localStorage.getItem("member_id"), + sessionid: localStorage.getItem("session_token"), + amount, + action: 33025 + }; + return this.postAuxEnd("/sendmoneyfee", postData); + } + + // API FUNCTION TO GET COUPON HISTORY getCouponHx(){ - var postData = { - uuid: localStorage.getItem("uid"), + var postData = { + uid: localStorage.getItem("uid"), + member_id: localStorage.getItem("member_id"), + sessionid: localStorage.getItem("session_token"), + page:1, + limit :20, + action: 85025 + }; + return this.postAuxEnd("/couponhx", postData); + } + + getPurchaseHx(){ + var postData = { + uid: localStorage.getItem("uid"), + member_id: localStorage.getItem("member_id"), + sessionid: localStorage.getItem("session_token"), + page:1, + limit :20, + action: 15049 + }; + return this.postAuxEnd("/purchasehx", postData); + } + + // API FUNCTION TO GET PAYMENT HISTORY + getPaymentHx(){ + var postData = { + uid: localStorage.getItem("uid"), + member_id: localStorage.getItem("member_id"), + sessionid: localStorage.getItem("session_token"), + page:1, + limit :20, + action: 15046 + }; + return this.postAuxEnd("/paymenthx", postData); + } + + //END POINT CALL FOR REFERRAL HISTORY + getReferralHx(){ + var postData = { + uid: localStorage.getItem("uid"), member_id: localStorage.getItem("member_id"), sessionid: localStorage.getItem("session_token"), - page:0, - limit :100 -}; - return this.postAuxEnd("/couponhx", postData); + offset: 1, + limit :100, + action: 11064 + }; + return this.postAuxEnd("/refferhx", postData); + } + + //END POINT CALL FOR SENDING REFERRAL MESSAGE + sendReferralMsg(postData){ + return this.postAuxEnd("/sendreferral", postData); } getCouponRedeem(){ @@ -162,6 +232,11 @@ class usersService { return this.postAuxEnd("/couponredeem", postData); } + // Country Data {GET} + getSignupCountryData() { + return this.postAuxEnd("/signupcountry", null); + } + /* - 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(username) - 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(password)