Compare commits
114 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 96972dbe2f | |||
| 7146048aee | |||
| 39f1f5bc73 | |||
| 752fc6a4a8 | |||
| 608d5b92f1 | |||
| 45563cc59b | |||
| b027e20c20 | |||
| bbe0777496 | |||
| 27efbe362b | |||
| 878539a56a | |||
| 6ae408029d | |||
| 8016d1bd12 | |||
| 0e9fef218f | |||
| 8116665045 | |||
| e4addc47d9 | |||
| 1682f11efd | |||
| 80b2abf9e3 | |||
| 5edecb6464 | |||
| 3a479b3573 | |||
| 4034909836 | |||
| 8fc61a6289 | |||
| 940a12a2e9 | |||
| a9f671eeaa | |||
| 481924fa02 | |||
| 6b712089d1 | |||
| 85ca2cb15a | |||
| d01c4928ff | |||
| b81e62988c | |||
| a8b63917fb | |||
| 9cf6d13716 | |||
| c1af2b7fc9 | |||
| 494c1f3271 | |||
| 9f0c33521f | |||
| 1d5875d4e2 | |||
| 6f6b12f4b5 | |||
| f3ad4d576e | |||
| e01d0106ad | |||
| 68472f8c66 | |||
| 8def463d80 | |||
| 0320999f72 | |||
| 78a97d8b0b | |||
| 6bf6c5d2d4 | |||
| 33284600e5 | |||
| 68bf995078 | |||
| fa05f47941 | |||
| 2391857309 | |||
| ed38cadcee | |||
| ea447a9366 | |||
| 4e2f120ab5 | |||
| 20ce9bf749 | |||
| 04e1bcc5f1 | |||
| cbaa8b6f7b | |||
| f6bdb1c299 | |||
| d4061d72da | |||
| 2d9a8b55b5 | |||
| 920eafed29 | |||
| 21d926eb5c | |||
| ec9d793d6b | |||
| 2fd04dc86d | |||
| d7752cb70b | |||
| dc592f60db | |||
| 675ba2989e | |||
| b201224fd6 | |||
| c24013eefd | |||
| 234f04ca8f | |||
| 5f222a2d88 | |||
| 258434a109 | |||
| ed148612a7 | |||
| 2287fb5ebb | |||
| 24545baad5 | |||
| ead7589c92 | |||
| 51bb8fc421 | |||
| d2166d9578 | |||
| c4872f522b | |||
| 0aef8c5e1e | |||
| 767b5c1b32 | |||
| 6fed51443d | |||
| 017ba7bd2f | |||
| 86d876b013 | |||
| fcd8898439 | |||
| 690f496807 | |||
| f804e13b56 | |||
| 5e248bc108 | |||
| 26647b088f | |||
| ae8ada33f4 | |||
| c31dab92e7 | |||
| c16764269e | |||
| afe6a1afcb | |||
| e98929627f | |||
| 3919a2bc4b | |||
| 93e89f996c | |||
| 7ede9883ba | |||
| 7edc7b08e5 | |||
| 7990959e9f | |||
| 6ead632c79 | |||
| 9c575716cd | |||
| cc93d5980d | |||
| e899e5eb2a | |||
| c53ee2833f | |||
| 9475961c2d | |||
| 97ae9dd136 | |||
| ded088c70f | |||
| 4dacee11e8 | |||
| 960579384c | |||
| bcca701a6b | |||
| 6c29f37a60 | |||
| cc22e1a458 | |||
| d274a5c56a | |||
| dfe90fbdc2 | |||
| a2f3c95671 | |||
| 6daa4d6d43 | |||
| 2e25b33110 | |||
| a216ab1098 | |||
| 8511db6961 |
@@ -42,9 +42,28 @@ REACT_APP_GOOGLE_CLIENT_SECRET=aozK_2G8UjaCmLgPPkv9abIm
|
||||
REACT_APP_GOOGLE_CLIENT_SCOPE="https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile"
|
||||
REACT_APP_GOOGLE_REDIRECT_URL=http://localhost:9082/login/auth/
|
||||
|
||||
REACT_APP_FACEBOOK_CLIENT_ID=390204307987009
|
||||
REACT_APP_FACEBOOK_CLIENT_SECRET=19f778e312f2ab96d147bacb612910c2
|
||||
REACT_APP_FACEBOOK_CLIENT_SCOPE="email, public_profile"
|
||||
#Real Account
|
||||
REACT_APP_FACEBOOK_CLIENT_ID2=390204307987009
|
||||
REACT_APP_FACEBOOK_CLIENT_SECRET2=19f778e312f2ab96d147bacb612910c2
|
||||
|
||||
#developenet Account
|
||||
REACT_APP_FACEBOOK_CLIENT_ID=677857427521030
|
||||
REACT_APP_FACEBOOK_CLIENT_SECRET=4801375f22072d8a75f64483fdd89829
|
||||
|
||||
#my Account
|
||||
REACT_APP_FACEBOOK_CLIENT_ID3=1598725580610908
|
||||
|
||||
|
||||
REACT_APP_FACEBOOK_CLIENT_SCOPE="email,public_profile"
|
||||
REACT_APP_FACEBOOK_REDIRECT_URL="http://localhost:9082/login/auth/flogin"
|
||||
|
||||
REACT_APP_APPLE_CLIENT_ID='com.wrenchboard.users.client'
|
||||
REACT_APP_APPLE_REDIRECT_URL='http://localhost:9082/login/auth/apple'
|
||||
|
||||
|
||||
# /* 'client_id' => */ 'com.wrenchboard.users.client',
|
||||
# /* 'client_secret' => */ 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6Ilc1V1RXQzlEVEoifQ.eyJpc3MiOiJKUjM2M0ZFWThSIiwiaWF0IjoxNjU0MDgzODQxLCJleHAiOjE2NTkyNjc4NDEsImF1ZCI6Imh0dHBzOi8vYXBwbGVpZC5hcHBsZS5jb20iLCJzdWIiOiJjb20ud3JlbmNoYm9hcmQudXNlcnMuY2xpZW50In0.TIPMwjS2MgSysqEuw3yu1nrOcrH-6omzerDhx0CadjWn2yCO8wZhQiAlhIFs7F-WPektIJ6h-2BT62yGrILiTA',
|
||||
# /* 'redirect_uri' => */ site_url('login/auth/apple')
|
||||
|
||||
REACT_APP_MAX_FILE_SIZE=1000000
|
||||
REACT_APP_TOTAL_NUM_FILE=4
|
||||
|
||||
@@ -40,6 +40,11 @@ REACT_APP_GOOGLE_CLIENT_SECRET=aozK_2G8UjaCmLgPPkv9abIm
|
||||
REACT_APP_GOOGLE_CLIENT_SCOPE="https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile"
|
||||
REACT_APP_GOOGLE_REDIRECT_URL=https://users.wrenchboard.com/login/auth/
|
||||
|
||||
REACT_APP_FACEBOOK_CLIENT_ID2=390204307987009
|
||||
REACT_APP_FACEBOOK_CLIENT_SECRET2=19f778e312f2ab96d147bacb612910c2
|
||||
REACT_APP_FACEBOOK_CLIENT_SCOPE="email,public_profile"
|
||||
REACT_APP_FACEBOOK_REDIRECT_URL="https://users.wrenchboard.com/login/auth/flogin"
|
||||
|
||||
DISABLE_ESLINT_PLUGIN=true
|
||||
|
||||
REACT_APP_MAX_FILE_SIZE=1000000
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
"flutterwave-react-v3": "^1.3.0",
|
||||
"formik": "^2.2.9",
|
||||
"react": "^18.2.0",
|
||||
"react-apple-login": "^1.1.6",
|
||||
"react-chartjs-2": "^4.1.0",
|
||||
"react-countup": "^6.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
|
||||
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 84 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 713 B |
|
After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 15 KiB |
@@ -47,6 +47,8 @@ import OffersInterestPage from "./views/OffersInterestPage";
|
||||
import ManageInterestOfferPage from './views/ManageInterestOfferPage'
|
||||
import MyWaitingJobsPage from "./views/MyWaitingJobsPage";
|
||||
import FamilyMarketPage from "./views/FamilyMarketPage";
|
||||
import FacebookRedirect from "./views/FacebookRedirect";
|
||||
import AppleRedirectPage from "./views/AppleRedirectPage";
|
||||
|
||||
export default function Routers() {
|
||||
return (
|
||||
@@ -56,6 +58,8 @@ export default function Routers() {
|
||||
<Route exact path="/login" element={<LoginPage />} />
|
||||
<Route exact path="/signup" element={<SignupPage />} />
|
||||
<Route exact path="/login/auth" element={<AuthRedirect />} />
|
||||
<Route exact path="/login/auth/flogin" element={<FacebookRedirect />} />
|
||||
<Route exact path="/login/auth/apple" element={<AppleRedirectPage />} />
|
||||
<Route
|
||||
exact
|
||||
path="/forgot-password"
|
||||
|
||||
|
After Width: | Height: | Size: 215 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" id="naira"><path fill="#fff" d="M24,5A19,19,0,1,0,43,24,19,19,0,0,0,24,5Zm7,20a1,1,0,0,1,0,2H29v3A1.94,1.94,0,0,1,27.45,32a2,2,0,0,1-2.26-1.08L20,17.05l0,14a1,1,0,0,1-2,0V27H16a1,1,0,0,1,0-2h2V22H16a1,1,0,0,1,0-2h2V17a1.94,1.94,0,0,1,1.55-1.92,2,2,0,0,1,2.26,1.08L27,30,27,16a1,1,0,0,1,2,0v4h2a1,1,0,0,1,0,2H29v3Z" class="color3b3c3d svgShape"></path><path fill="#e3e3e3" d="M24,48A24,24,0,1,1,48,24,24,24,0,0,1,24,48ZM24,2A22,22,0,1,0,46,24,22,22,0,0,0,24,2Z" class="color3b3c3d svgShape"></path></svg>
|
||||
|
After Width: | Height: | Size: 563 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16.933 16.933" id="Coin"><path d="M8.452 281.052a7.487 7.487 0 0 0-7.483 7.482 7.485 7.485 0 0 0 7.483 7.48 7.484 7.484 0 0 0 7.48-7.48 7.486 7.486 0 0 0-7.48-7.482zm0 1.232a6.253 6.253 0 0 1 6.248 6.25 6.25 6.25 0 0 1-6.248 6.248c-3.449 0-6.25-2.8-6.25-6.248a6.254 6.254 0 0 1 6.25-6.25zm0 .53a5.717 5.717 0 0 0-5.721 5.72 5.715 5.715 0 0 0 5.72 5.719 5.713 5.713 0 0 0 5.72-5.719 5.715 5.715 0 0 0-5.72-5.72zm-.004 2.011a.265.265 0 0 1 .267.268v.596H9.74a.265.265 0 1 1 0 .529H8.715v2.05h.17c.856 0 1.551.697 1.551 1.555s-.696 1.555-1.549 1.555h-.172v.596a.265.265 0 1 1-.529 0v-.596H7.161a.265.265 0 1 1 0-.53h1.025v-2.05h-.172a1.552 1.552 0 0 1-1.547-1.555c0-.858.694-1.554 1.547-1.554h.172v-.596a.265.265 0 0 1 .262-.268zm-.434 1.393a1.01 1.01 0 0 0-1.018 1.025 1.01 1.01 0 0 0 1.018 1.026h.172v-2.051zm.701 2.58v2.05h.172c.57 0 1.02-.448 1.02-1.025s-.449-1.025-1.022-1.025z" color="#e3e3e3" font-family="sans-serif" font-weight="400" overflow="visible" transform="translate(0 -280.067)" style="line-height:normal;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000;text-transform:none;text-orientation:mixed;shape-padding:0;isolation:auto;mix-blend-mode:normal" fill="#fff" class="color000000 svgShape"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 5.5 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30" id="Visacard"><g fill="#767fad" class="color303c42 svgShape"><path d="M28 4H2C.897 4 0 4.897 0 6v18c0 1.103.897 2 2 2h26c1.103 0 2-.897 2-2V6c0-1.103-.897-2-2-2zm1 20c0 .551-.449 1-1 1H2c-.551 0-1-.449-1-1V6c0-.551.449-1 1-1h26c.551 0 1 .449 1 1v18z" fill="#5218ed" class="color000000 svgShape"></path><path d="M7.677 14.266a.2.2 0 0 0 .228.053.17.17 0 0 0 .106-.194l-.314-1.368a.121.121 0 0 0-.002-.009c-.113-.39-.47-.449-.729-.459H6.96l-1.768-.002c-.091 0-.17.06-.185.143a.172.172 0 0 0 .121.193c1.078.358 1.96.926 2.55 1.643zM23.535 12.303h-1.15c-.46 0-.724.141-.883.473l-2.383 4.981a.162.162 0 0 0 .014.165c.035.05.094.079.158.079h1.35a.189.189 0 0 0 .176-.112c.165-.404.272-.661.307-.744h.974l1.183.002c.039.151.134.552.173.717.019.08.095.137.184.137h1.177c.057 0 .11-.024.146-.065s.05-.095.038-.146l-1.28-5.351a.185.185 0 0 0-.184-.136zm-1.926 3.675.895-2.138.114.492.39 1.646h-1.4z" fill="#5218ed" class="color000000 svgShape"></path><path d="M11.816 12.38a.193.193 0 0 0-.157-.078h-1.37a.188.188 0 0 0-.175.11L8.511 16.19l-.172-.575a.142.142 0 0 0-.009-.023c-.253-.542-.933-1.39-1.881-2.062-.065-.046-.154-.048-.221-.006s-.097.12-.074.192L7.47 17.87a.187.187 0 0 0 .18.124l1.518-.002a.19.19 0 0 0 .173-.104l2.49-5.344a.162.162 0 0 0-.016-.164zM14.088 12.297h-1.303a.184.184 0 0 0-.186.144l-.989 5.355a.165.165 0 0 0 .042.141c.036.04.088.062.144.062h1.302c.092 0 .17-.061.186-.145l.99-5.354a.164.164 0 0 0-.042-.141.195.195 0 0 0-.144-.062zM17.696 13.452h.05c.51 0 .87.107 1.097.187a.202.202 0 0 0 .16-.011.175.175 0 0 0 .093-.122l.152-.826c.016-.085-.039-.168-.128-.194a4.634 4.634 0 0 0-1.3-.182c-1.607 0-2.735.746-2.744 1.814-.01.79.807 1.231 1.422 1.494.632.269.844.441.841.682-.004.369-.506.536-.97.536a3.676 3.676 0 0 1-1.522-.285.202.202 0 0 0-.163.008.175.175 0 0 0-.095.123l-.161.87a.173.173 0 0 0 .123.193c.444.144 1.064.233 1.66.24h.001c1.705-.001 2.815-.739 2.827-1.88.006-.627-.427-1.1-1.36-1.49-.57-.256-.92-.426-.917-.686 0-.234.32-.47.934-.47z" fill="#5218ed" class="color000000 svgShape"></path></g></svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 94 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 19 KiB |
@@ -0,0 +1,69 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { useLocation, useNavigate } from 'react-router-dom';
|
||||
import usersService from '../../../services/UsersService';
|
||||
import {updateUserDetails} from "../../../store/UserDetails";
|
||||
import { useDispatch } from "react-redux";
|
||||
import AuthLayout from "../AuthLayout";
|
||||
|
||||
function AppleRedirect() {
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const userApi = new usersService();
|
||||
const dispatch = useDispatch()
|
||||
|
||||
const queryParams = new URLSearchParams(location?.search);
|
||||
const codeResponse = queryParams.get("code");
|
||||
|
||||
useEffect(()=>{
|
||||
if(!codeResponse){
|
||||
navigate('/login', {state: {error: true}})
|
||||
return
|
||||
}
|
||||
console.log(codeResponse);
|
||||
|
||||
setTimeout(()=>{ // remove LATER
|
||||
navigate('/login', {state: {error: true}})
|
||||
},2000)
|
||||
|
||||
/*
|
||||
POST /token HTTP/1.1
|
||||
Host: oauth2.googleapis.com
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
|
||||
client_id=your_client_id&
|
||||
client_secret=your_client_secret&
|
||||
redirect_uri=https%3A//oauth2.example.com/code&
|
||||
grant_type=authorization_code
|
||||
*/
|
||||
var reqData = {
|
||||
auth_type: "APPLE",
|
||||
code: codeResponse,
|
||||
redirect_uri: process.env.REACT_APP_GOOGLE_REDIRECT_URL,
|
||||
};
|
||||
// userApi
|
||||
// .authStart(reqData)
|
||||
// .then((res) => {
|
||||
// if (res.status == 200 && res.data.internal_return >= 0 && res.data.member_id && res.data.uid && res.data.session) {
|
||||
// localStorage.setItem("member_id", `${res.data.member_id}`);
|
||||
// localStorage.setItem("uid", `${res.data.uid}`);
|
||||
// localStorage.setItem("session_token", `${res.data.session}`);
|
||||
// dispatch(updateUserDetails({...res.data}));
|
||||
// navigate('/', {replace: true})
|
||||
// return
|
||||
// }
|
||||
// navigate('/login', {state: {error: true}})
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// navigate('/login', {state: {error: true}})
|
||||
// console.log(error);
|
||||
// });
|
||||
},[])
|
||||
return (
|
||||
<AuthLayout>
|
||||
<div className='min-h-[70vh]'>Redirecting ... </div>
|
||||
</AuthLayout>
|
||||
)
|
||||
}
|
||||
|
||||
export default AppleRedirect
|
||||
@@ -0,0 +1,65 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { useLocation, useNavigate } from 'react-router-dom';
|
||||
import usersService from '../../../services/UsersService';
|
||||
import {updateUserDetails} from "../../../store/UserDetails";
|
||||
import { useDispatch } from "react-redux";
|
||||
import AuthLayout from "../AuthLayout";
|
||||
|
||||
function FbookRedirect() {
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const userApi = new usersService();
|
||||
const dispatch = useDispatch()
|
||||
|
||||
const queryParams = new URLSearchParams(location?.search);
|
||||
const codeResponse = queryParams.get("code");
|
||||
|
||||
useEffect(()=>{
|
||||
if(!codeResponse){
|
||||
navigate('/login', {state: {error: true}})
|
||||
return
|
||||
}
|
||||
console.log(codeResponse);
|
||||
|
||||
/*
|
||||
POST /token HTTP/1.1
|
||||
Host: oauth2.googleapis.com
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
|
||||
client_id=your_client_id&
|
||||
client_secret=your_client_secret&
|
||||
redirect_uri=https%3A//oauth2.example.com/code&
|
||||
grant_type=authorization_code
|
||||
*/
|
||||
var reqData = {
|
||||
auth_type: "FACEBOOK",
|
||||
code: codeResponse,
|
||||
redirect_uri: process.env.REACT_APP_GOOGLE_REDIRECT_URL,
|
||||
};
|
||||
// userApi
|
||||
// .authStart(reqData)
|
||||
// .then((res) => {
|
||||
// if (res.status == 200 && res.data.internal_return >= 0 && res.data.member_id && res.data.uid && res.data.session) {
|
||||
// localStorage.setItem("member_id", `${res.data.member_id}`);
|
||||
// localStorage.setItem("uid", `${res.data.uid}`);
|
||||
// localStorage.setItem("session_token", `${res.data.session}`);
|
||||
// dispatch(updateUserDetails({...res.data}));
|
||||
// navigate('/', {replace: true})
|
||||
// return
|
||||
// }
|
||||
// navigate('/login', {state: {error: true}})
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// navigate('/login', {state: {error: true}})
|
||||
// console.log(error);
|
||||
// });
|
||||
},[])
|
||||
return (
|
||||
<AuthLayout>
|
||||
<div className='min-h-[70vh]'>Redirecting ... </div>
|
||||
</AuthLayout>
|
||||
)
|
||||
}
|
||||
|
||||
export default FbookRedirect
|
||||
@@ -77,15 +77,14 @@ export default function Login() {
|
||||
return;
|
||||
}
|
||||
|
||||
//checks if email is a valid email address
|
||||
let regEx = /^[^0-9][a-zA-Z0-9._%+-]+@[a-zA-Z]+(\.[a-zA-Z]+)+$/;
|
||||
if (regEx.test(email) == false) {
|
||||
setLoginLoading(false);
|
||||
setMsgError("Invalid Email");
|
||||
return setTimeout(()=>{setMsgError("");},3000)
|
||||
}
|
||||
|
||||
if (name == "full") {
|
||||
//checks if email is a valid email address
|
||||
let regEx = /^[^0-9][a-zA-Z0-9._%+-]+@[a-zA-Z]+(\.[a-zA-Z]+)+$/;
|
||||
if (regEx.test(email) == false) {
|
||||
setLoginLoading(false);
|
||||
setMsgError("Invalid Email");
|
||||
return setTimeout(()=>{setMsgError("");},3000)
|
||||
}
|
||||
// Post Data Info for normal Login
|
||||
postData = {
|
||||
username: email,
|
||||
@@ -322,25 +321,33 @@ export default function Login() {
|
||||
</button>
|
||||
</div>
|
||||
<div className="sm:flex sm:justify-between sm:items-center sm:space-x-2">
|
||||
<BrandBtn
|
||||
link="#"
|
||||
imgSrc={googleLogo}
|
||||
brand="Google"
|
||||
onClick={googleLogin}
|
||||
/>
|
||||
<BrandBtn link="#" imgSrc={appleLogo} brand="Apple" />
|
||||
<BrandBtn
|
||||
link="#"
|
||||
imgSrc={googleLogo}
|
||||
brand="Google"
|
||||
onClick={googleLogin}
|
||||
/>
|
||||
<BrandBtn
|
||||
// link={`https://appleid.apple.com/auth/authorize?response_type=code&response_mode=form_post&client_id=${process.env.REACT_APP_APPLE_CLIENT_ID}&redirect_uri=https%3A%2F%2Fwork.wrenchboard.com%2Flogin%2Fauth%2Fapple&state=4b2c4456b7&scope=name+email`}
|
||||
link={`https://appleid.apple.com/auth/authorize?response_type=code&response_mode=form_post&client_id=${process.env.REACT_APP_APPLE_CLIENT_ID}&redirect_uri=${process.env.REACT_APP_APPLE_REDIRECT_URL}&state=4b2c4456b7&scope=name+email`}
|
||||
imgSrc={appleLogo}
|
||||
brand="Apple"
|
||||
isAnchor={true}
|
||||
/>
|
||||
</div>
|
||||
<div className="sm:flex sm:justify-between sm:items-center sm:space-x-2">
|
||||
<BrandBtn
|
||||
link="#"
|
||||
imgSrc={facebookLogo}
|
||||
brand="Facebook"
|
||||
/>
|
||||
<BrandBtn
|
||||
link="#"
|
||||
imgSrc={linkedInLogo}
|
||||
brand="LinkedIn"
|
||||
/>
|
||||
<BrandBtn
|
||||
link={`https://www.facebook.com/v14.0/dialog/oauth?client_id=${process.env.REACT_APP_FACEBOOK_CLIENT_ID}&redirect_uri=${process.env.REACT_APP_FACEBOOK_REDIRECT_URL}&scope=${process.env.REACT_APP_FACEBOOK_CLIENT_SCOPE}`}
|
||||
imgSrc={facebookLogo}
|
||||
brand="Facebook"
|
||||
isAnchor={true}
|
||||
/>
|
||||
<BrandBtn
|
||||
// link="https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&scope=comma-separated-list-of-scopes&state=YOUR_STATE_VALUE"
|
||||
imgSrc={linkedInLogo}
|
||||
brand="LinkedIn"
|
||||
isAnchor={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -428,7 +435,7 @@ export default function Login() {
|
||||
);
|
||||
}
|
||||
|
||||
const BrandBtn = ({ link, imgSrc, brand, onClick }) => {
|
||||
const BrandBtn = ({ link, imgSrc, brand, onClick, isAnchor=false }) => {
|
||||
// const doGoogle = async () => {
|
||||
// alert("start google");
|
||||
// };
|
||||
@@ -447,10 +454,23 @@ const BrandBtn = ({ link, imgSrc, brand, onClick }) => {
|
||||
// const doFacebook = async () => {
|
||||
// alert("start facebook");
|
||||
// };
|
||||
|
||||
return (
|
||||
<div className="w-full sm:w-1/2 flex justify-center bottomMargin">
|
||||
<button
|
||||
{isAnchor ?
|
||||
(
|
||||
<a
|
||||
href={link}
|
||||
className="w-full border border-light-purple dark:border-[#5356fb29] rounded-[0.475rem] h-[48px] flex justify-center bg-[#FAFAFA] hover:bg-[#eff2f5] hover:text-[#7e8299] transition duration-300 dark:bg-[#11131F] items-center font-medium cursor-pointer"
|
||||
>
|
||||
<img className="mr-3 h-6" src={imgSrc} alt="logo-icon(s)" />
|
||||
<span className="text-lg text-thin-light-gray font-normal text-[15px]">
|
||||
Continue with {brand}
|
||||
</span>
|
||||
</a>
|
||||
)
|
||||
:
|
||||
(
|
||||
<button
|
||||
onClick={onClick}
|
||||
// href="#dd"
|
||||
className="w-full border border-light-purple dark:border-[#5356fb29] rounded-[0.475rem] h-[48px] flex justify-center bg-[#FAFAFA] hover:bg-[#eff2f5] hover:text-[#7e8299] transition duration-300 dark:bg-[#11131F] items-center font-medium cursor-pointer"
|
||||
@@ -460,6 +480,9 @@ const BrandBtn = ({ link, imgSrc, brand, onClick }) => {
|
||||
Continue with {brand}
|
||||
</span>
|
||||
</button>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
);
|
||||
)
|
||||
};
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ export default function BlogItem(props) {
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
Blog Items Details
|
||||
Blog Items Details need implenet
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -214,28 +214,28 @@ export default function FamilyManageTabs({
|
||||
browseProfileImg={browseProfileImg}
|
||||
accountDetails={accountDetails}
|
||||
/>
|
||||
<div className="mt-4 flex justify-center items-center gap-2">
|
||||
<div className="mt-4 flex justify-start items-center gap-2">
|
||||
<button
|
||||
onClick={() => tabHandler("Account")}
|
||||
className="family-icon p-2 border-2 border-sky-blue rounded-2xl flex flex-col justify-between items-center"
|
||||
className="family-icon p-2 border-2 border-sky-blue rounded-2xl flex flex-col justify-between items-center max-w-[65px] w-full"
|
||||
>
|
||||
<img
|
||||
src={localImgLoad("images/icons/account.svg")}
|
||||
className="w-[70px] h-[70px]"
|
||||
className="max-w-[30px] w-full"
|
||||
alt="Settings-Icon"
|
||||
/>
|
||||
<p className="mt-2 text-lg text-sky-blue">Account</p>
|
||||
<p className="text-lg text-sky-blue">Acc.</p>
|
||||
</button>
|
||||
<button
|
||||
onClick={() => tabHandler("Profile")}
|
||||
className="family-icon p-2 border-2 border-sky-blue rounded-2xl flex flex-col justify-between items-center"
|
||||
className="family-icon p-2 border-2 border-sky-blue rounded-2xl flex flex-col justify-between items-center max-w-[65px] w-full"
|
||||
>
|
||||
<img
|
||||
src={localImgLoad("images/icons/profile.svg")}
|
||||
className="w-[70px] h-[70px]"
|
||||
className="max-w-[30px] w-full"
|
||||
alt="Settings-Icon"
|
||||
/>
|
||||
<p className="mt-2 text-lg text-sky-blue">Profile</p>
|
||||
<p className="text-lg text-sky-blue">Profile</p>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useState } from "react";
|
||||
import dataImage1 from "../../assets/images/data-table-user-1.png";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import { useNavigate, useLocation, Link } from "react-router-dom";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { handlePagingFunc } from "../Pagination/HandlePagination";
|
||||
import PaginatedList from "../Pagination/PaginatedList";
|
||||
|
||||
|
||||
@@ -1,148 +1,152 @@
|
||||
import { useState, useMemo, memo } from "react";
|
||||
import { handlePagingFunc, PaginatedList } from "../../Pagination";
|
||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||
import { memo, useMemo, useState } from "react";
|
||||
import SuggestTask from "../../FamilyPopup/SuggestTask";
|
||||
import { PaginatedList, handlePagingFunc } from "../../Pagination";
|
||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||
import AssignTaskPopout from "../FamilyPopout/AssignTaskPopout";
|
||||
|
||||
const FamilyWaitlist = memo(({ familyData, className, accountDetails, loader }) => {
|
||||
const [popUp, setPopUp] = useState({ show: false, data: {} });
|
||||
const [continueTaskPopup, setContinueTaskPopup] = useState({
|
||||
show: false,
|
||||
data: {},
|
||||
});
|
||||
const filteredFamilyData = useMemo(
|
||||
() =>
|
||||
familyData?.result_list?.filter(
|
||||
(data) => data?.family_uid === accountDetails?.family_uid
|
||||
),
|
||||
[familyData, accountDetails]
|
||||
);
|
||||
const FamilyWaitlist = memo(
|
||||
({ familyData, className, accountDetails, loader }) => {
|
||||
const [popUp, setPopUp] = useState({ show: false, data: {} });
|
||||
const [continueTaskPopup, setContinueTaskPopup] = useState({
|
||||
show: false,
|
||||
data: {},
|
||||
});
|
||||
const filteredFamilyData = useMemo(
|
||||
() =>
|
||||
familyData?.result_list?.filter(
|
||||
(data) => data?.family_uid === accountDetails?.family_uid
|
||||
),
|
||||
[familyData, accountDetails]
|
||||
);
|
||||
|
||||
const [currentPage, setCurrentPage] = useState(0);
|
||||
const itemsPerPage = Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
||||
const indexOfFirstItem = currentPage;
|
||||
const indexOfLastItem = currentPage + itemsPerPage;
|
||||
const currentTask = useMemo(
|
||||
() => filteredFamilyData?.slice(indexOfFirstItem, indexOfLastItem),
|
||||
[filteredFamilyData, indexOfFirstItem, indexOfLastItem]
|
||||
);
|
||||
const [currentPage, setCurrentPage] = useState(0);
|
||||
const itemsPerPage = Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
||||
const indexOfFirstItem = currentPage;
|
||||
const indexOfLastItem = currentPage + itemsPerPage;
|
||||
const currentTask = useMemo(
|
||||
() => filteredFamilyData?.slice(indexOfFirstItem, indexOfLastItem),
|
||||
[filteredFamilyData, indexOfFirstItem, indexOfLastItem]
|
||||
);
|
||||
|
||||
const handlePagination = (e) => handlePagingFunc(e, setCurrentPage);
|
||||
const handlePagination = (e) => handlePagingFunc(e, setCurrentPage);
|
||||
|
||||
const openPopUp = (value) => {
|
||||
setPopUp({ show: true, data: { ...value } });
|
||||
};
|
||||
const openPopUp = (value) => {
|
||||
setPopUp({ show: true, data: { ...value } });
|
||||
};
|
||||
|
||||
const closePopUp = () => {
|
||||
setPopUp({ show: false, data: {} });
|
||||
};
|
||||
const closePopUp = () => {
|
||||
setPopUp({ show: false, data: {} });
|
||||
};
|
||||
|
||||
const openContinueTaskPopup = (value) => {
|
||||
setContinueTaskPopup({ show: true, data: { ...value } });
|
||||
};
|
||||
const openContinueTaskPopup = (value) => {
|
||||
setContinueTaskPopup({ show: true, data: { ...value } });
|
||||
};
|
||||
|
||||
const closeContinueTaskPopup = () => {
|
||||
setContinueTaskPopup({ show: false, data: {} });
|
||||
};
|
||||
const closeContinueTaskPopup = () => {
|
||||
setContinueTaskPopup({ show: false, data: {} });
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`update-table w-full bg-white dark:bg-dark-white h-full lg:min-h-[450px] overflow-hidden rounded-2xl section-shadow ${
|
||||
className || ""
|
||||
}`}
|
||||
>
|
||||
{loader ? (
|
||||
<div className="w-full h-full flex justify-center items-center lg:min-h-[470px]">
|
||||
<LoadingSpinner size={16} color="sky-blue" />
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{filteredFamilyData && (
|
||||
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between h-full">
|
||||
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
||||
<tbody>
|
||||
{currentTask.map((value) => {
|
||||
const addedDate = value?.added.split(" ")[0];
|
||||
const selectedImage = require(`../../../assets/images/family/${
|
||||
value?.banner || "default.jpg"
|
||||
}`);
|
||||
return (
|
||||
<tr
|
||||
className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50"
|
||||
key={value.uid}
|
||||
>
|
||||
<td className="py-4">
|
||||
<div className="w-full flex justify-between items-center">
|
||||
<div className="account-name flex space-x-4 items-center">
|
||||
<div className="icon w-14 h-14 flex justify-center items-center">
|
||||
<img
|
||||
src={selectedImage}
|
||||
alt="task_img"
|
||||
className="w-full object-cover"
|
||||
/>
|
||||
return (
|
||||
<div
|
||||
className={`update-table w-full bg-white dark:bg-dark-white h-full lg:min-h-[450px] overflow-hidden rounded-2xl section-shadow ${
|
||||
className || ""
|
||||
}`}
|
||||
>
|
||||
{loader ? (
|
||||
<div className="w-full h-full flex justify-center items-center lg:min-h-[470px]">
|
||||
<LoadingSpinner size={16} color="sky-blue" />
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{filteredFamilyData && (
|
||||
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between h-full">
|
||||
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
||||
<tbody>
|
||||
{currentTask.map((value) => {
|
||||
const addedDate = value?.added.split(" ")[0];
|
||||
const selectedImage = require(`../../../assets/images/family/${
|
||||
value?.banner || "default.jpg"
|
||||
}`);
|
||||
return (
|
||||
<tr
|
||||
className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50"
|
||||
key={value.uid}
|
||||
>
|
||||
<td className="py-4">
|
||||
<div className="w-full flex justify-between items-center">
|
||||
<div className="account-name flex space-x-4 items-center">
|
||||
<div className="icon w-14 h-14 flex justify-center items-center">
|
||||
<img
|
||||
src={selectedImage}
|
||||
alt="task_img"
|
||||
className="w-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<div className="">
|
||||
<p className="text-xl font-bold text-dark-gray dark:text-white mb-2 capitalize line-clamp-1">
|
||||
{value.title}
|
||||
</p>
|
||||
<p className="text-sm text-thin-light-gray font-medium">
|
||||
{value.description}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="">
|
||||
<p className="text-xl font-bold text-dark-gray dark:text-white mb-2 capitalize line-clamp-1">
|
||||
{value.title}
|
||||
<div className="px-2 flex flex-col items-center justify-center">
|
||||
<p className="text-sm font-bold text-dark-gray dark:text-white">
|
||||
{addedDate}
|
||||
</p>
|
||||
<p className="text-sm text-thin-light-gray font-medium">
|
||||
{value.description}
|
||||
<p className="text-xs py-1.5 w-[70px] cursor-default tracking-wide rounded-full bg-gold text-white flex justify-center items-center">
|
||||
{value.status_text}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="px-2 flex flex-col items-center justify-center">
|
||||
<p className="text-sm font-bold text-dark-gray dark:text-white">
|
||||
{addedDate}
|
||||
</p>
|
||||
<p className="text-xs py-1.5 w-[70px] cursor-default tracking-wide rounded-full bg-gold text-white flex justify-center items-center">
|
||||
{value.status_text}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td className="text-right py-4 px-2">
|
||||
<button
|
||||
onClick={() => openPopUp(value)}
|
||||
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
View
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
<PaginatedList
|
||||
onClick={handlePagination}
|
||||
prev={currentPage === 0}
|
||||
next={currentPage + itemsPerPage >= filteredFamilyData?.length}
|
||||
data={filteredFamilyData}
|
||||
start={indexOfFirstItem}
|
||||
stop={indexOfLastItem}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{popUp.show && (
|
||||
<SuggestTask
|
||||
details={popUp.data}
|
||||
onClose={closePopUp}
|
||||
continuePopupData={openContinueTaskPopup}
|
||||
situation={popUp.show}
|
||||
/>
|
||||
)}
|
||||
</td>
|
||||
<td className="text-right py-4 px-2">
|
||||
<button
|
||||
onClick={() => openPopUp(value)}
|
||||
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
View
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
<PaginatedList
|
||||
onClick={handlePagination}
|
||||
prev={currentPage === 0}
|
||||
next={
|
||||
currentPage + itemsPerPage >= filteredFamilyData?.length
|
||||
}
|
||||
data={filteredFamilyData}
|
||||
start={indexOfFirstItem}
|
||||
stop={indexOfLastItem}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{popUp.show && (
|
||||
<SuggestTask
|
||||
details={popUp.data}
|
||||
onClose={closePopUp}
|
||||
continuePopupData={openContinueTaskPopup}
|
||||
situation={popUp.show}
|
||||
/>
|
||||
)}
|
||||
|
||||
{continueTaskPopup.show && (
|
||||
<AssignTaskPopout
|
||||
details={continueTaskPopup.data}
|
||||
action={closeContinueTaskPopup}
|
||||
situation={continueTaskPopup.show}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
{continueTaskPopup.show && (
|
||||
<AssignTaskPopout
|
||||
details={continueTaskPopup.data}
|
||||
action={closeContinueTaskPopup}
|
||||
situation={continueTaskPopup.show}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export default FamilyWaitlist;
|
||||
|
||||
@@ -8,13 +8,13 @@ export default function ProfileInfo({
|
||||
accountDetails,
|
||||
}) {
|
||||
return (
|
||||
<div className="flex flex-col items-center gap-6">
|
||||
<div className="flex flex-col items-center gap-4">
|
||||
<div className="flex justify-center">
|
||||
<div className="w-full relative">
|
||||
<img
|
||||
src={profileImg}
|
||||
alt=""
|
||||
className="sm:w-[198px] sm:h-[198px] w-[120px] h-[120px] rounded-full overflow-hidden object-cover"
|
||||
className="sm:w-[180px] sm:h-[180px] w-[120px] h-[120px] rounded-full overflow-hidden object-cover"
|
||||
/>
|
||||
<input
|
||||
ref={profileImgInput}
|
||||
|
||||
@@ -63,7 +63,7 @@ export default function InputCom({
|
||||
</span>
|
||||
)}
|
||||
{/* displays error is any */}
|
||||
{error && <span className="text-[12px] text-red-500">{error}</span>}
|
||||
{error && <span className="text-[12px] text-red-500 italic">{error}</span>}
|
||||
</label>
|
||||
)}
|
||||
{forgotPassword && (
|
||||
@@ -97,7 +97,7 @@ export default function InputCom({
|
||||
dir={direction}
|
||||
/>
|
||||
{iconName && (
|
||||
<div className="absolute right-6 bottom-[10px] z-10 flex gap-2">
|
||||
<div className="absolute right-6 bottom-3 z-10 flex gap-2">
|
||||
{iconName.split(" ").map((item, index) => (
|
||||
<Icons key={index} name={item} />
|
||||
))}
|
||||
@@ -105,7 +105,7 @@ export default function InputCom({
|
||||
)}
|
||||
{passIcon && (
|
||||
<div
|
||||
className="absolute right-6 bottom-[10px] z-10"
|
||||
className="absolute right-6 bottom-3 z-10"
|
||||
onClick={onClick}
|
||||
>
|
||||
<Icons name={passIcon} />
|
||||
|
||||
@@ -20,7 +20,8 @@ import React from "react";
|
||||
export const PriceFormatter = (
|
||||
price = "00",
|
||||
currency = "",
|
||||
currencyName = ""
|
||||
currencyName = "",
|
||||
priceClass
|
||||
) => {
|
||||
// Convert the number to a string
|
||||
let numStr = String(price);
|
||||
@@ -44,7 +45,7 @@ export const PriceFormatter = (
|
||||
return (
|
||||
<span className="text-sm flex items-center">
|
||||
<sup>{currency || currencyName || ""}</sup>
|
||||
<span className="px-1 font-bold text-lg">{formattedInteger || ""}</span>
|
||||
<span className={`px-1 font-bold ${priceClass ? priceClass : "text-lg"}`}>{formattedInteger || ""}</span>
|
||||
<sup>{formattedDecimal || ""}</sup>
|
||||
</span>
|
||||
);
|
||||
|
||||
@@ -217,22 +217,22 @@ export default function History() {
|
||||
{/* <TopHxBox className="mb-11" /> */}
|
||||
<div className='w-full p-4 md:p-8 bg-white dark:bg-dark-white rounded-2xl shadow bottomMargin'>
|
||||
{/* switch button */}
|
||||
<div className="my-1 flex items-center border-b border-slate-300">
|
||||
<div className="pl-7 my-2 flex items-center border-b border-slate-300 gap-3">
|
||||
<button
|
||||
name="purchases"
|
||||
onClick={(e) => setTab(e.target.name)}
|
||||
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border ${
|
||||
tab == "purchases" ? "border-sky-blue" : "border-slate-300"
|
||||
} tracking-wide transition duration-200`}
|
||||
className={`px-4 py-1 rounded-t-2xl ${
|
||||
tab == "purchases" ? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white" : "bg-white text-[#000] border-t-[2px]"
|
||||
}`}
|
||||
>
|
||||
Purchases
|
||||
</button>
|
||||
<button
|
||||
name="recent"
|
||||
onClick={(e) => setTab(e.target.name)}
|
||||
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border ${
|
||||
tab == "recent" ? "border-sky-blue" : "border-slate-300"
|
||||
} tracking-wide transition duration-200`}
|
||||
className={`px-4 py-1 rounded-t-2xl ${
|
||||
tab == "recent" ? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white" : "bg-white text-[#000] border-t-[2px]"
|
||||
}`}
|
||||
>
|
||||
Recent Activity
|
||||
</button>
|
||||
|
||||
@@ -11,12 +11,6 @@ import HomeActivities from "./HomeActivities";
|
||||
|
||||
export default function FullAccountDash(props) {
|
||||
console.log("PROPS IN HOME->", props);
|
||||
|
||||
const trending = datas.datas;
|
||||
const jobData = datas.datas; // api calls or cache
|
||||
|
||||
const userApi = new usersService();
|
||||
|
||||
const { userDetails } = useSelector((state) => state?.userDetails);
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import ModalCom from "../../Helpers/ModalCom";
|
||||
import { useMemo, useState } from "react";
|
||||
import { toast } from "react-toastify";
|
||||
import usersService from "../../../services/UsersService";
|
||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||
import ModalCom from "../../Helpers/ModalCom";
|
||||
import { PriceFormatter } from "../../Helpers/PriceFormatter";
|
||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||
|
||||
const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
||||
const [textValue, setTextValue] = useState("");
|
||||
const apiCall = useMemo(() => new usersService(), []);
|
||||
|
||||
const handleInputChange = ({ target: { value } }) => {
|
||||
setTextValue(value);
|
||||
};
|
||||
|
||||
const MarketCalls = (details) => {
|
||||
const [marketMsg, setMarketMsg] = useState({
|
||||
loading: false,
|
||||
@@ -24,8 +31,8 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
||||
|
||||
const MarketDetail = async () => {
|
||||
try {
|
||||
setMarketMsg({ loading: true });
|
||||
if (!textValue) return;
|
||||
setMarketMsg({ loading: true });
|
||||
|
||||
reqData.yourmessage = textValue;
|
||||
|
||||
@@ -87,22 +94,11 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
||||
}
|
||||
};
|
||||
|
||||
// useEffect(() => {
|
||||
// ManageInterest();
|
||||
// }, []);
|
||||
|
||||
return { MarketDetail, ManageInterest, manageInt, marketMsg };
|
||||
};
|
||||
|
||||
const [textValue, setTextValue] = useState("");
|
||||
|
||||
const handleInputChange = ({ target: { value } }) => {
|
||||
setTextValue(value);
|
||||
};
|
||||
|
||||
const apiCall = useMemo(() => new usersService(), []);
|
||||
|
||||
let { manageInt, ManageInterest, MarketDetail, marketMsg } = MarketCalls(details);
|
||||
let { manageInt, ManageInterest, MarketDetail, marketMsg } =
|
||||
MarketCalls(details);
|
||||
|
||||
let thePrice = PriceFormatter(
|
||||
details?.price * 0.01,
|
||||
@@ -270,9 +266,7 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
||||
Interest: <b className="ml-1">{details.interest_count}</b>
|
||||
</p>
|
||||
<hr />
|
||||
<p className="my-1">
|
||||
Expire: {details.expire}
|
||||
</p>
|
||||
<p className="my-1">Expire: {details.expire}</p>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
|
||||
@@ -9,59 +9,61 @@ import PaginatedList from "../Pagination/PaginatedList";
|
||||
import { handlePagingFunc } from "../Pagination/HandlePagination";
|
||||
|
||||
export default function ActiveJobMessage({ activeJobMesList }) {
|
||||
const [currentPage, setCurrentPage] = useState(0);
|
||||
const indexOfFirstItem = Number(currentPage);
|
||||
const indexOfLastItem = Number(indexOfFirstItem)+Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
||||
const currentActiveJobMesList = activeJobMesList?.data?.slice(indexOfFirstItem, indexOfLastItem);
|
||||
// const [currentPage, setCurrentPage] = useState(0);
|
||||
// const indexOfFirstItem = Number(currentPage);
|
||||
// const indexOfLastItem = Number(indexOfFirstItem)+Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
||||
// const currentActiveJobMesList = activeJobMesList?.data?.slice(indexOfFirstItem, indexOfLastItem);
|
||||
|
||||
const handlePagination = (e) => {
|
||||
handlePagingFunc(e,setCurrentPage)
|
||||
}
|
||||
// const handlePagination = (e) => {
|
||||
// handlePagingFunc(e,setCurrentPage)
|
||||
// }
|
||||
|
||||
return (
|
||||
<div className='flex flex-col justify-between h-full'>
|
||||
<table className="wallet-activity w-full table-auto border-collapse text-left">
|
||||
<thead className='border-b-2'>
|
||||
<tr className='text-slate-600'>
|
||||
<th className="p-2"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
{activeJobMesList.data.length ?
|
||||
(
|
||||
<tbody>
|
||||
{currentActiveJobMesList.map((item, index) => (
|
||||
<tr key={index} className='text-slate-500'>
|
||||
<td>
|
||||
<div className="msg_box">
|
||||
<div className="msg_header">{item.msg_date} {item.msg_firstname}</div>
|
||||
<span className="p-2" dangerouslySetInnerHTML={{__html: item.message}}></span>
|
||||
</div>
|
||||
<div className='flex flex-col justify-between'>
|
||||
<div className="w-full min-h-[450px] max-h-[450px] overflow-y-scroll">
|
||||
<table className="wallet-activity w-full table-auto border-collapse text-left">
|
||||
<thead className='border-b-2'>
|
||||
<tr className='text-slate-600'>
|
||||
<th className="p-2"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
{activeJobMesList?.data?.length ?
|
||||
(
|
||||
<tbody>
|
||||
{activeJobMesList.data.map((item, index) => (
|
||||
<tr key={index} className='text-slate-500'>
|
||||
<td>
|
||||
<div className={`msg_box ${item.who}`}>
|
||||
<div className="msg_header">{item.msg_date} {item.msg_firstname}</div>
|
||||
<span className="p-2" dangerouslySetInnerHTML={{__html: item.message}}></span>
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
)
|
||||
:
|
||||
activeJobMesList.error ?
|
||||
(
|
||||
<tbody>
|
||||
<tr className='text-slate-500'>
|
||||
<td className="p-2" colSpan={4}>Opps! an error occurred. Please try again!</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
)
|
||||
:
|
||||
<tbody>
|
||||
<tr className='text-slate-500'>
|
||||
<td className="p-2" colSpan={4}>No Message Found!</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
}
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
)
|
||||
:
|
||||
activeJobMesList.error ?
|
||||
(
|
||||
<tbody>
|
||||
<tr className='text-slate-500'>
|
||||
<td className="p-2" colSpan={4}>Opps! an error occurred. Please try again!</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
)
|
||||
:
|
||||
<tbody>
|
||||
<tr className='text-slate-500'>
|
||||
<td className="p-2" colSpan={4}>No Message Found!</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
}
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{/* PAGINATION BUTTON */}
|
||||
<PaginatedList onClick={handlePagination} prev={currentPage == 0 ? true : false} next={currentPage+Number(process.env.REACT_APP_ITEM_PER_PAGE) >= activeJobMesList?.data?.length ? true : false} data={activeJobMesList?.data} start={indexOfFirstItem} stop={indexOfLastItem} />
|
||||
{/* <PaginatedList onClick={handlePagination} prev={currentPage == 0 ? true : false} next={currentPage+Number(process.env.REACT_APP_ITEM_PER_PAGE) >= activeJobMesList?.data?.length ? true : false} data={activeJobMesList?.data} start={indexOfFirstItem} stop={indexOfLastItem} /> */}
|
||||
{/* END OF PAGINATION BUTTON */}
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -353,7 +353,7 @@ function ActiveJobs(props) {
|
||||
</div>
|
||||
|
||||
<div className="my-4 py-[20px] bg-white dark:bg-black px-4 rounded-2xl shadow-md lg:flex justify-between items-start space-y-4 lg:space-x-4 lg:space-y-0">
|
||||
<div className="w-full lg:w-1/2">
|
||||
<div className="w-full lg:w-1/2 mb-4 border-b pb-4 lg:pb-0 lg:mb-0 lg:border-b-0">
|
||||
<div className="">
|
||||
<h1 className="text-lg font-bold text-dark-gray dark:text-white tracking-wide">
|
||||
Actions
|
||||
@@ -367,23 +367,25 @@ function ActiveJobs(props) {
|
||||
{/* TEXTAREA SECTION */}
|
||||
<div className="mt-5">
|
||||
<div className="">
|
||||
{/* <p className="relative py-2 my-2 text-lg font-bold text-slate-600 dark:text-black border-b-2 border-slate-300 tracking-wide after:absolute after:-bottom-0.5 after:content-[''] after:w-[100px] after:h-[2px] after:bg-sky-blue after:left-0">Message(s)</p> */}
|
||||
<div className="my-2 flex items-center border-b border-slate-300">
|
||||
<div
|
||||
className="pl-7 my-2 flex items-center border-b border-slate-300 gap-3"
|
||||
// className='ml-7 flex justify-start items-center gap-3'
|
||||
>
|
||||
<button
|
||||
name="message"
|
||||
onClick={(e) => setTab(e.target.name)}
|
||||
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border ${
|
||||
tab == "message" ? "border-sky-blue" : "border-slate-300"
|
||||
} tracking-wide transition duration-200`}
|
||||
className={`px-4 py-1 rounded-t-2xl ${
|
||||
tab == "message" ? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white" : "bg-white text-[#000] border-t-[2px]"
|
||||
}`}
|
||||
>
|
||||
Send Message
|
||||
</button>
|
||||
<button
|
||||
name="files"
|
||||
onClick={(e) => setTab(e.target.name)}
|
||||
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border ${
|
||||
tab == "files" ? "border-sky-blue" : "border-slate-300"
|
||||
} tracking-wide transition duration-200`}
|
||||
className={`px-4 py-1 rounded-t-2xl ${
|
||||
tab == "files" ? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white" : "bg-white text-[#000] border-t-[2px]"
|
||||
}`}
|
||||
>
|
||||
Send Files
|
||||
</button>
|
||||
@@ -457,7 +459,7 @@ function ActiveJobs(props) {
|
||||
|
||||
{/* Buttons Sections */}
|
||||
<div className="py-2 sm:flex sm:justify-end sm:items-center">
|
||||
<div className="w-full sm:w-2/4 flex justify-between items-center space-x-2">
|
||||
<div className="w-full sm:w-3/4 flex justify-between items-center space-x-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleClearAll}
|
||||
|
||||
@@ -4,15 +4,15 @@ function CurrentJobAction() {
|
||||
return (
|
||||
<div className='job-action dark:bg-black'>
|
||||
<p className="my-3 py-1 text-base active-owner">
|
||||
<table className="w-full text-sm text-left text-gray-500">
|
||||
<table className="w-full text-sm text-left text-gray-500 ">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div className="flex space-x-2 items-center w-full">
|
||||
<div className="flex space-x-2 items-center w-full task_action_panel">
|
||||
|
||||
<h1 className="text-xl text-dark-gray dark:text-white">
|
||||
<div>
|
||||
Waiting for the completion message from the client before you can approve.
|
||||
</h1>
|
||||
</div>
|
||||
{/*<div className="flex flex-col flex-[0.9]"> </div>*/}
|
||||
</div>
|
||||
</td>
|
||||
|
||||
@@ -62,14 +62,14 @@ function CurrentTaskAction({jobDetails}) {
|
||||
return (
|
||||
<div className='job-action dark:bg-black'>
|
||||
|
||||
<table className="w-full text-sm text-left text-gray-500 active-worker">
|
||||
<table className="w-full text-sm text-left text-gray-500 active-worker ">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div className="flex space-x-2 items-center w-full">
|
||||
<h1 className="text-xl text-dark-gray dark:text-white">
|
||||
<div className="flex space-x-2 items-center w-full task_action_panel">
|
||||
<div>
|
||||
I completed this task and ready for review and acceptance.
|
||||
</h1>
|
||||
</div>
|
||||
{/*<div className="flex flex-col flex-[0.9]">*/}
|
||||
|
||||
{/*</div>*/}
|
||||
|
||||
@@ -107,19 +107,18 @@ function PastDueJobAction({jobDetails}) {
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div className="flex space-x-2 items-center w-full">
|
||||
<div className="flex space-x-2 items-center w-full task_action_panel">
|
||||
|
||||
<h1 className="text-xl text-dark-gray dark:text-white">
|
||||
<div className="dark:text-red-700">
|
||||
Time allocated has passed
|
||||
</h1>
|
||||
{/*<div className="flex flex-col flex-[0.9]"> </div>*/}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div className="flex justify-center items-center">
|
||||
<button type="button" onClick={popUpHandler} className="w-[150px] h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white">
|
||||
<button type="button" onClick={popUpHandler} className="w-[180px] h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white">
|
||||
Cancel or Extend Timeline
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -8,11 +8,11 @@ function PastDueTaskAction() {
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div className="flex space-x-2 items-center w-full">
|
||||
<div className="flex space-x-2 items-center w-full task_action_panel">
|
||||
|
||||
<h1 className="text-xl text-dark-gray dark:text-white">
|
||||
<div>
|
||||
You have missed the allocated time
|
||||
</h1>
|
||||
</div>
|
||||
{/*<div className="flex flex-col flex-[0.9]"> </div>*/}
|
||||
</div>
|
||||
</td>
|
||||
|
||||
@@ -96,11 +96,11 @@ function ReviewJobAction({jobDetails}) {
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div className="flex space-x-2 items-center w-full">
|
||||
<div className="flex space-x-2 items-center w-full task_action_panel">
|
||||
|
||||
<h1 className="text-xl text-dark-gray dark:text-white">
|
||||
<div>
|
||||
This Job is Ready for your review
|
||||
</h1>
|
||||
</div>
|
||||
{/*<div className="flex flex-col flex-[0.9]"> </div>*/}
|
||||
</div>
|
||||
</td>
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react'
|
||||
|
||||
function ReviewTaskAction() {
|
||||
return (
|
||||
<div className='job-action dark:bg-black'>
|
||||
<div className='job-action dark:bg-black task_action_panel'>
|
||||
<p className="my-3 py-1 text-base text-dark-gray dark:text-white">
|
||||
Waiting for the completion message from the client before you can approve. Worker True & Review Job
|
||||
</p>
|
||||
|
||||
@@ -1,140 +0,0 @@
|
||||
import React, {useState} from 'react'
|
||||
import RecentActivityTable from './WalletComponent/RecentActivityTable'
|
||||
import LoadingSpinner from '../Spinners/LoadingSpinner'
|
||||
import { useNavigate, useLocation } from 'react-router-dom'
|
||||
import InputCom from '../Helpers/Inputs/InputCom'
|
||||
|
||||
import AddFundDollars from './AddFundDollars'
|
||||
|
||||
function AddFund({payment}) {
|
||||
|
||||
const navigate = useNavigate()
|
||||
const {currency} = useLocation()?.state //GETS THE USER CURRENCY FOR ADD FUND
|
||||
|
||||
//STATE FOR CONTROLLED INPUT
|
||||
let [input, setInput] = useState('')
|
||||
|
||||
let [inputError, setInputError] = useState('')
|
||||
|
||||
// FUNCTION TO HANDLE INPUT CHANGE
|
||||
const handleChange = ({target:{name, value}}) => {
|
||||
setInput(value)
|
||||
}
|
||||
|
||||
//FUNCTION TO HANDLE SUBMIT
|
||||
const handleSubmit = () => {
|
||||
setInputError('')
|
||||
if(!input || input == '0'){
|
||||
setInputError('Please Enter Amount')
|
||||
return setTimeout(()=>{setInputError('')}, 5000)
|
||||
}
|
||||
|
||||
if(isNaN(input)){
|
||||
setInputError('Amount must be a Number')
|
||||
return setTimeout(()=>{setInputError('')}, 5000)
|
||||
}
|
||||
|
||||
const stateData = {amount: Number(input), currency: 'naira'}
|
||||
navigate('confirm-add-fund', {state: stateData})
|
||||
|
||||
setInput('')
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
{/* heading */}
|
||||
<div className="sm:flex justify-between items-center mb-6">
|
||||
<div className="w-full flex justify-start space-x-3 items-center">
|
||||
<button
|
||||
type="button"
|
||||
className="min-w-[45px] h-auto text-[#374557] border border-sky-blue p-1 rounded-full"
|
||||
onClick={() =>
|
||||
navigate('/my-wallet', { replace: true })
|
||||
}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="35"
|
||||
height="35"
|
||||
viewBox="0 0 24 24"
|
||||
fill="skyblue"
|
||||
>
|
||||
<path d="M19 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H19v-2z" />
|
||||
</svg>
|
||||
</button>
|
||||
<h1 className="text-26 font-bold inline-flex gap-3 text-dark-gray dark:text-white items-center">
|
||||
Add Credit
|
||||
</h1>
|
||||
</div>
|
||||
<div className="slider-btns flex space-x-4">
|
||||
<div
|
||||
onClick={() => filterHandler("today")}
|
||||
className="relative"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="content-wrapper w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin">
|
||||
<div className="lg:w-2/2 w-full mb-10 lg:mb-0">
|
||||
<div className="add-fund w-full bg-white dark:bg-dark-white rounded-2xl shadow">
|
||||
{/*<h2 className='md:p-8 p-4 text-slate-900 dark:text-white text-xl lg:text-2xl font-medium'>Add Credit with Account Deposit</h2>*/}
|
||||
{/*<hr />*/}
|
||||
<form className='md:p-8 p-4 add-fund-info'>
|
||||
<div className="field w-full mb-6">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
label={currency == 'US Dollars' ? "Amount (USD)" : "Amount (Naira)"}
|
||||
type="text"
|
||||
name="amount"
|
||||
placeholder="0"
|
||||
value={input}
|
||||
inputHandler={handleChange}
|
||||
/>
|
||||
{inputError && <p className='text-base text-red-500'>{inputError}</p>}
|
||||
</div>
|
||||
</form>
|
||||
<hr />
|
||||
|
||||
{/* SHOWS THIS IF USER CURRENCY IS DOLLARS */}
|
||||
{currency == 'US Dollars' &&
|
||||
<div className='w-full md:p-8 p-4 bg-white dark:bg-dark-white rounded-2xl shadow'>
|
||||
<AddFundDollars setInputError={setInputError} input={input} setInput={setInput} />
|
||||
</div>
|
||||
}
|
||||
|
||||
{/* HIDES THIS BUTTON IF CURENCY IS NAIRA */}
|
||||
{currency != 'US Dollars' &&
|
||||
<div className='md:p-8 p-4 add-fund-btn flex justify-end items-center py-4'>
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
type="button"
|
||||
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
<span className="text-white">Continue</span>
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* HIDES THIS SECTION IF CURENCY IS NAIRA */}
|
||||
{currency != 'US Dollars' &&
|
||||
<div className="content-wrapper w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin">
|
||||
<div className="lg:w-2/2 w-full mb-10 lg:mb-0">
|
||||
<div className="wallet w-full md:p-8 p-4 h-full min-h-[590px] bg-white dark:bg-dark-white rounded-2xl shadow">
|
||||
<h2 className='text-gray-900 dark:text-white text-xl lg:text-2xl font-medium'>Recent Activity</h2>
|
||||
{/* <p className='text-base text-gray-600 dark:text-white'>Activity Report</p> */}
|
||||
{payment.loading ?
|
||||
<LoadingSpinner size='16' color='sky-blue' />
|
||||
:
|
||||
<RecentActivityTable payment={payment}/>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default AddFund
|
||||
@@ -1,480 +0,0 @@
|
||||
import React,{useEffect, useState} from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import InputCom from '../Helpers/Inputs/InputCom';
|
||||
import PaginatedList from '../Pagination/PaginatedList';
|
||||
import { handlePagingFunc } from '../Pagination/HandlePagination';
|
||||
import LoadingSpinner from '../Spinners/LoadingSpinner';
|
||||
import usersService from '../../services/UsersService';
|
||||
|
||||
import { Form, Formik } from "formik";
|
||||
import * as Yup from "yup";
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
name: Yup.string()
|
||||
.min(3, "Minimum 3 characters")
|
||||
.max(50, "Maximum 50 characters")
|
||||
.required("Name is required"),
|
||||
cardNum: Yup.string()
|
||||
.min(3, "Minimum 3 characters")
|
||||
.max(25, "Maximum 25 characters")
|
||||
.required("Card Number is required"),
|
||||
code: Yup.string()
|
||||
.min(3, "Minimum 3 characters")
|
||||
.max(25, "Maximum 25 characters")
|
||||
.required("Postal Code is required"),
|
||||
state: Yup.string()
|
||||
.min(3, "Minimum 3 characters")
|
||||
.max(25, "Maximum 25 characters")
|
||||
.required("State is required"),
|
||||
address: Yup.string()
|
||||
.min(3, "Minimum 3 characters")
|
||||
.max(50, "Maximum 50 characters")
|
||||
.required("Address is required"),
|
||||
expirationYear: Yup.string()
|
||||
.min(4, "Minimum 4 characters")
|
||||
.max(4, "Maximum 4 characters")
|
||||
.required("Expiration Year is required"),
|
||||
expirationMonth: Yup.string()
|
||||
.min(1, "Minimum 1 characters")
|
||||
.max(2, "Maximum 2 characters")
|
||||
.required("Expiration Month is required"),
|
||||
cvv: Yup.string()
|
||||
.min(3, "Minimum 3 characters")
|
||||
.max(4, "Maximum 4 characters")
|
||||
.required("CVV Year is required"),
|
||||
});
|
||||
|
||||
const initialValues = {
|
||||
name: '',
|
||||
cardNum: '',
|
||||
code: '',
|
||||
state: '',
|
||||
address: '',
|
||||
expirationYear: '',
|
||||
expirationMonth: '',
|
||||
cvv: ''
|
||||
};
|
||||
|
||||
|
||||
function AddFundDollars(props) {
|
||||
const navigate = useNavigate()
|
||||
let apiCall = new usersService()
|
||||
|
||||
let [tab, setTab] = useState("previous"); //STATE FOR SWITCHING BETWEEN TABS
|
||||
|
||||
let [prevCardDetails, setPrevCardDetails] = useState(null) // STATE TO HOLD PREVIOUS CARD SELECTED
|
||||
|
||||
let [payListCard, setPayListCard] = useState({loading: true, data:[]}) //USER PREVIOUS CARDS
|
||||
|
||||
const [currentPage, setCurrentPage] = useState(0);
|
||||
const indexOfFirstItem = Number(currentPage);
|
||||
const indexOfLastItem = Number(indexOfFirstItem)+Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
||||
const currentPreviousCards = payListCard?.data?.slice(indexOfFirstItem, indexOfLastItem);
|
||||
|
||||
const handlePagination = (e) => {
|
||||
handlePagingFunc(e,setCurrentPage)
|
||||
}
|
||||
|
||||
// FUNCTION TO SUBMIT
|
||||
const handleSubmit = (values, helpers) => {
|
||||
props.setInputError('')
|
||||
if(!props.input || props.input == '0'){
|
||||
props.setInputError('Please Enter Amount')
|
||||
return setTimeout(()=>{props.setInputError('')}, 5000)
|
||||
}
|
||||
|
||||
if(isNaN(props.input)){
|
||||
props.setInputError('Amount must be a Number')
|
||||
return setTimeout(()=>{props.setInputError('')}, 5000)
|
||||
}
|
||||
if(tab == 'previous'){
|
||||
const stateData = {amount: Number(props.input), currency: 'dollars'}
|
||||
navigate('confirm-add-fund', {state: stateData}) // State will change later dummy for now
|
||||
}
|
||||
if(tab == 'new'){
|
||||
const stateData = {amount: Number(props.input), currency: 'dollars', ...values}
|
||||
navigate('confirm-add-fund', {state: stateData}) // State will change later dummy for now
|
||||
}
|
||||
props.setInput('')
|
||||
}
|
||||
|
||||
useEffect(()=>{
|
||||
apiCall.payListCard().then(res => {
|
||||
setPayListCard({loading: false, data: res.data.result_list})
|
||||
}).catch(err => {
|
||||
console.log('PAYCARDLIST ERROR', err)
|
||||
setPayListCard({loading: false, data: []})
|
||||
})
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<>
|
||||
<h1 className='mb-2 text-xl font-bold text-dark-gray dark:text-white'>Payment Method</h1>
|
||||
<div className="w-full">
|
||||
{/* switch button */}
|
||||
<div className="my-1 flex items-center border-b border-slate-300">
|
||||
<button
|
||||
name="previous"
|
||||
onClick={(e) => setTab(e.target.name)}
|
||||
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border ${
|
||||
tab == "previous" ? "border-sky-blue" : "border-slate-300"
|
||||
} tracking-wide transition duration-200`}
|
||||
>
|
||||
Previous Cards
|
||||
</button>
|
||||
<button
|
||||
name="new"
|
||||
onClick={(e) => setTab(e.target.name)}
|
||||
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border ${
|
||||
tab == "new" ? "border-sky-blue" : "border-slate-300"
|
||||
} tracking-wide transition duration-200`}
|
||||
>
|
||||
Add New Card
|
||||
</button>
|
||||
</div>
|
||||
{/* END OF switch button */}
|
||||
|
||||
{/* previous tab */}
|
||||
{tab == 'previous' ?
|
||||
<div className="p-4 previous-details w-full border min-h-[300px] flex flex-col justify-between items-center">
|
||||
{ payListCard.loading ?
|
||||
<LoadingSpinner size='10' color='sky-blue' />
|
||||
:
|
||||
payListCard?.data?.length ?
|
||||
<table className="my-3 w-full">
|
||||
<tbody>
|
||||
{currentPreviousCards.map((item, index)=>(
|
||||
<tr key={index} className={index != 0 && 'border-t-2'}>
|
||||
<td>
|
||||
<div className='my-2 flex items-center gap-5'>
|
||||
<input type="radio" className='w-8 h-8' name='card' value='value' />
|
||||
<div className='card-details'>
|
||||
<h1 className='text-lg font-bold text-dark-gray dark:text-white tracking-wide'>{item.description} Card</h1>
|
||||
<p className='text-base font-bold text-dark-gray dark:text-white tracking-wide'>Bank **************{item.digits}</p>
|
||||
<div className='w-full sm:flex items-center gap-5'>
|
||||
<p className='text-base font-bold text-dark-gray dark:text-white tracking-wide'>{item.added}</p>
|
||||
<p className='text-sm font-bold text-green-700 dark:text-white tracking-wide'>Verified</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
// onClick={handleSubmit}
|
||||
type="button"
|
||||
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
<span className="text-white">Manage</span>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
))
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
:
|
||||
<div className='w-full flex flex-col items-center'>
|
||||
<p className='my-5 text-base font-bold text-dark-gray dark:text-white tracking-wide'>No Previous Card Found!</p>
|
||||
<button
|
||||
onClick={()=> setTab('new')}
|
||||
type="button"
|
||||
className="my-5 px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
<span className="text-white">Add Card</span>
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
{/* PAGINATION BUTTON */}
|
||||
<div className='w-full'>
|
||||
<PaginatedList onClick={handlePagination} prev={currentPage == 0 ? true : false} next={currentPage+Number(process.env.REACT_APP_ITEM_PER_PAGE) >= payListCard?.data?.length ? true : false} data={payListCard?.data} start={indexOfFirstItem} stop={indexOfLastItem} />
|
||||
</div>
|
||||
{/* END OF PAGINATION BUTTON */}
|
||||
</div>
|
||||
:
|
||||
<div className="new-details w-full min-h-[300px] border-t">
|
||||
<div className="w-full flex flex-col justify-between">
|
||||
<Formik
|
||||
initialValues={initialValues}
|
||||
validationSchema={validationSchema}
|
||||
onSubmit={handleSubmit}
|
||||
>
|
||||
{(props) => {
|
||||
return (
|
||||
<Form>
|
||||
<div className="flex flex-col-reverse sm:flex-row">
|
||||
<div className="flex-1 sm:mr-10">
|
||||
<div className="fields w-full">
|
||||
{/* inputs starts here */}
|
||||
{/* Name */}
|
||||
<div className="field w-full my-6">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
spanTag='*'
|
||||
label="Name on Card"
|
||||
type="text"
|
||||
name="name"
|
||||
placeholder="DUMMY NAME"
|
||||
value={props.values.name}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
/>
|
||||
{props.errors.name && props.touched.name && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.name}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* CARD NUMBER */}
|
||||
<div className="field w-full mb-6">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
spanTag='*'
|
||||
iconName='master-card visa-card atm-card'
|
||||
label="Card Number"
|
||||
type="text"
|
||||
name="cardNum"
|
||||
placeholder="Enter Card Number"
|
||||
value={props.values.cardNum}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
/>
|
||||
{props.errors.cardNum && props.touched.cardNum && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.cardNum}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
{/* EXPIRE YEAR, YEAR AND CVV */}
|
||||
<div className="sm:grid gap-5 grid-cols-3 mb-6">
|
||||
<div className="field w-full mb-6 xl:mb-0 col-span-1">
|
||||
<div className="select-option">
|
||||
<div className={`flex items-center justify-between mb-2.5`}>
|
||||
<label
|
||||
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"
|
||||
htmlFor='expiration'
|
||||
>Expiration Month <span className="text-red-700 text-sm tracking-wide">*</span></label>
|
||||
</div>
|
||||
<div
|
||||
className={`input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base`}
|
||||
>
|
||||
<select
|
||||
className={`input-field placeholder:text-base text-dark-gray w-full h-full tracking-wide dark:bg-[#11131F] bg-[#f5f8fa] focus:ring-0 focus:outline-none`}
|
||||
value={props.values.expirationMonth}
|
||||
onChange={props.handleChange}
|
||||
onBlur={props.handleBlur}
|
||||
name='expirationMonth'
|
||||
>
|
||||
<option value=''>Select...</option>
|
||||
{expireMonth?.length &&
|
||||
expireMonth.map((item, index) => (
|
||||
<option key={index} value={item.value}>{item.name}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
{props.errors.expirationMonth && props.touched.expirationMonth && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.expirationMonth}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="field w-full mb-6 xl:mb-0 col-span-1">
|
||||
<div className="select-option">
|
||||
<div className={`flex items-center justify-between mb-2.5`}>
|
||||
<label
|
||||
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"
|
||||
htmlFor='expiration'
|
||||
>Expiration Year <span className="text-red-700 text-sm tracking-wide">*</span>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
className={`input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base`}
|
||||
>
|
||||
<select
|
||||
className={`input-field placeholder:text-base text-dark-gray w-full h-full tracking-wide dark:bg-[#11131F] bg-[#f5f8fa] focus:ring-0 focus:outline-none`}
|
||||
value={props.values.expirationYear}
|
||||
onChange={props.handleChange}
|
||||
onBlur={props.handleBlur}
|
||||
name='expirationYear'
|
||||
>
|
||||
<option value=''>Select...</option>
|
||||
{expireYear?.length &&
|
||||
expireYear.map((item, index) => (
|
||||
<option key={index} value={item}>{item}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
{props.errors.expirationYear && props.touched.expirationYear && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.expirationYear}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="field w-full col-span-1">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
spanTag='*'
|
||||
iconName='atm-card'
|
||||
label="CVV"
|
||||
type="text"
|
||||
name="cvv"
|
||||
placeholder="CVV"
|
||||
value={props.values.cvv}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
/>
|
||||
{props.errors.cvv && props.touched.cvv && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.cvv}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{/* Address */}
|
||||
<div className="field w-full my-6">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
spanTag='*'
|
||||
label="Billing Address"
|
||||
type="text"
|
||||
name="address"
|
||||
placeholder="Billing Address"
|
||||
value={props.values.Address}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
/>
|
||||
{props.errors.address && props.touched.address && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.address}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
{/* postal code and state */}
|
||||
<div className="sm:grid gap-5 grid-cols-3 mb-6">
|
||||
<div className="field w-full mb-6 xl:mb-0 col-span-1">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
spanTag='*'
|
||||
label="Postal Code"
|
||||
type="text"
|
||||
name="code"
|
||||
placeholder="Postal Code"
|
||||
value={props.values.code}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
/>
|
||||
{props.errors.code && props.touched.code && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.code}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="field w-full col-span-1">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
spanTag='*'
|
||||
label="State"
|
||||
type="text"
|
||||
name="state"
|
||||
placeholder="State"
|
||||
value={props.values.state}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
/>
|
||||
{props.errors.state && props.touched.state && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.state}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* <div className="w-full">
|
||||
{requestStatus.message != "" && (
|
||||
<p
|
||||
className={`text-center text-base ${
|
||||
requestStatus.status ? "text-green-800" : "text-red-600"
|
||||
}`}
|
||||
>
|
||||
{requestStatus.message}
|
||||
</p>
|
||||
)}
|
||||
<div className="w-full h-[120px] border-t border-light-purple dark:border-[#5356fb29] flex justify-end items-center">
|
||||
<div className="flex items-center space-x-4 mr-9">
|
||||
<Link
|
||||
to="/"
|
||||
className="text-18 text-light-red tracking-wide "
|
||||
>
|
||||
<span className="border-b dark:border-[#5356fb29] border-light-red">
|
||||
{" "}
|
||||
Cancel
|
||||
</span>
|
||||
</Link>
|
||||
|
||||
{requestStatus.loading ? (
|
||||
<LoadingSpinner size="8" color="sky-blue" />
|
||||
) : (
|
||||
<button
|
||||
type="submit"
|
||||
className="w-[152px] h-[46px] flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
Update Profile
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div> */}
|
||||
<div className='md:p-8 p-4 add-fund-btn flex justify-end items-center py-4'>
|
||||
<button
|
||||
type="submit"
|
||||
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
<span className="text-white">Continue</span>
|
||||
</button>
|
||||
</div>
|
||||
</Form>
|
||||
);
|
||||
}}
|
||||
</Formik>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
{ tab == 'previous' &&
|
||||
<div className='md:p-8 p-4 add-fund-btn flex justify-end items-center py-4'>
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
type="button"
|
||||
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
<span className="text-white">Continue</span>
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default AddFundDollars
|
||||
|
||||
|
||||
// FORMS ARRAY OF EXPIRATION YEAR FOR CARD
|
||||
const expireYear = []
|
||||
let currentYear = new Date().getFullYear()
|
||||
for(let i=0; i<=6; i++){
|
||||
expireYear.push(currentYear + i)
|
||||
}
|
||||
|
||||
// FORMS ARRAY OF EXPIRATION MONTH FOR CARD
|
||||
let month = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
|
||||
const expireMonth = []
|
||||
for(let i=0; i<month.length; i++){
|
||||
expireMonth.push({name:month[i], value:i+1})
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import { toast } from "react-toastify";
|
||||
import InputCom from "../Helpers/Inputs/InputCom";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import RecentActivityTable from "./WalletComponent/RecentActivityTable";
|
||||
|
||||
import usersService from "../../services/UsersService";
|
||||
|
||||
import { FlutterWaveButton, closePaymentModal } from "flutterwave-react-v3";
|
||||
|
||||
function ConfirmAddFund({ payment }) {
|
||||
let { userDetails } = useSelector((state) => state.userDetails); // TO GET LOGGEDIN USER DETAILS
|
||||
|
||||
let [pageLoading, setPageLoading] = useState(true);
|
||||
|
||||
let [requestStatus, setRequestStatus] = useState({
|
||||
message: "",
|
||||
loading: false,
|
||||
status: false,
|
||||
}); // STATE FOR API REQUEST
|
||||
|
||||
const apiURL = new usersService();
|
||||
const navigate = useNavigate();
|
||||
|
||||
let { state } = useLocation();
|
||||
|
||||
//FUNCTION TO HANDLE SUBMIT
|
||||
const onSuccessPayment = () => {
|
||||
setRequestStatus({ message: "", loading: true, status: false });
|
||||
let reqData = { amount: state?.account, currency: "NGN" };
|
||||
apiURL
|
||||
.startTopUp(reqData)
|
||||
.then((res) => {
|
||||
if (res.data.internal_return < 0) {
|
||||
setRequestStatus({
|
||||
message: "Could not finish transaction",
|
||||
loading: false,
|
||||
status: false,
|
||||
});
|
||||
toast.success("Opps! something went wrong");
|
||||
}
|
||||
// do something
|
||||
setRequestStatus({
|
||||
message: "Topup successful",
|
||||
loading: false,
|
||||
status: true,
|
||||
});
|
||||
toast.success("Account Topup was sucessful");
|
||||
setTimeout(() => {
|
||||
navigate("/my-wallet", { replace: true });
|
||||
}, 1000);
|
||||
})
|
||||
.catch((err) => {
|
||||
// do something
|
||||
setRequestStatus({
|
||||
message: "Opps! An Error Occured",
|
||||
loading: false,
|
||||
status: false,
|
||||
});
|
||||
toast.success("Opps! something went wrong");
|
||||
});
|
||||
};
|
||||
|
||||
const config = {
|
||||
public_key: process.env.REACT_APP_FLUTTERWAVE_APIKEY,
|
||||
tx_ref: Date.now(),
|
||||
amount: state?.amount,
|
||||
currency: "NGN",
|
||||
payment_options: "card,mobilemoney,ussd",
|
||||
customer: {
|
||||
email: `${userDetails.email}`,
|
||||
phone_number: userDetails.phone,
|
||||
name: `${userDetails.lastname} ${userDetails.firstname}`,
|
||||
},
|
||||
customizations: {
|
||||
title: "WrenchBoard",
|
||||
description: "Topup Payment",
|
||||
logo: "https://st2.depositphotos.com/4403291/7418/v/450/depositphotos_74189661-stock-illustration-online-shop-log.jpg",
|
||||
},
|
||||
};
|
||||
|
||||
const fwConfig = {
|
||||
...config,
|
||||
text: "Proceed",
|
||||
callback: (response) => {
|
||||
onSuccessPayment();
|
||||
closePaymentModal(); // this will close the modal programmatically
|
||||
},
|
||||
onClose: () => {},
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// what happens if not state redirect user
|
||||
if (!state) {
|
||||
navigate("/my-wallet/add-fund", { replace: true });
|
||||
} else {
|
||||
setPageLoading(false);
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="content-wrapper w-full">
|
||||
{pageLoading ? (
|
||||
<LoadingSpinner size="8" color="sky-blue" />
|
||||
) : (
|
||||
<div className="w-full mb-10">
|
||||
<div className="add-fund w-full bg-white dark:bg-dark-white rounded-2xl shadow">
|
||||
<h2 className="md:p-8 p-4 text-slate-900 dark:text-white text-xl lg:text-2xl font-medium">
|
||||
Confirm Add Fund To Account
|
||||
</h2>
|
||||
<hr />
|
||||
<div className="px-4 md:px-8 py-4 add-fund-info">
|
||||
<div className="field w-full mb-3">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
label={state.currency == 'naira' ? "Amount (Naira):" : "Amount (Dollars):"}
|
||||
type="text"
|
||||
name="amount"
|
||||
value={state.amount || ""}
|
||||
disable={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
<div className="md:p-8 p-4 add-fund-btn flex justify-end items-center py-4">
|
||||
{
|
||||
state.currency == 'naira' ?
|
||||
<FlutterWaveButton
|
||||
{...fwConfig}
|
||||
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
/>
|
||||
:
|
||||
<button
|
||||
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
onClick={()=>console.log('WORKING')}
|
||||
>
|
||||
Continue
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="w-full mb-10">
|
||||
<div className="wallet w-full md:p-8 p-4 h-full min-h-[600px] bg-white dark:bg-dark-white rounded-2xl shadow">
|
||||
<h2 className="text-gray-900 dark:text-white text-xl lg:text-2xl font-medium">
|
||||
Recent Activity
|
||||
</h2>
|
||||
{/* <p className='text-base text-gray-600 dark:text-white'>Activity Report</p> */}
|
||||
{payment.loading ? (
|
||||
<LoadingSpinner size="16" color="sky-blue" />
|
||||
) : (
|
||||
<RecentActivityTable payment={payment} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ConfirmAddFund;
|
||||
@@ -0,0 +1,154 @@
|
||||
import React, { useState } from "react";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import InputCom from "../Helpers/Inputs/InputCom";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import RecentActivityTable from "./WalletComponent/RecentActivityTable";
|
||||
|
||||
import AddFundDollars from "./AddFundDollars";
|
||||
|
||||
function AddFund({ payment }) {
|
||||
const navigate = useNavigate();
|
||||
const { currency } = useLocation()?.state; //GETS THE USER CURRENCY FOR ADD FUND
|
||||
|
||||
//STATE FOR CONTROLLED INPUT
|
||||
let [input, setInput] = useState("");
|
||||
|
||||
let [inputError, setInputError] = useState("");
|
||||
|
||||
// FUNCTION TO HANDLE INPUT CHANGE
|
||||
const handleChange = ({ target: { name, value } }) => {
|
||||
setInput(value);
|
||||
};
|
||||
|
||||
//FUNCTION TO HANDLE SUBMIT
|
||||
const handleSubmit = () => {
|
||||
setInputError("");
|
||||
if (!input || input == "0") {
|
||||
setInputError("Please Enter Amount");
|
||||
return setTimeout(() => {
|
||||
setInputError("");
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
if (isNaN(input)) {
|
||||
setInputError("Amount must be a Number");
|
||||
return setTimeout(() => {
|
||||
setInputError("");
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
const stateData = { amount: Number(input), currency: "naira" };
|
||||
navigate("confirm-add-fund", { state: stateData });
|
||||
|
||||
setInput("");
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
{/* heading */}
|
||||
{/* <div className="sm:flex justify-between items-center mb-6">
|
||||
<div className="w-full flex justify-start space-x-3 items-center">
|
||||
<button
|
||||
type="button"
|
||||
className="min-w-[45px] h-auto text-[#374557] border border-sky-blue p-1 rounded-full"
|
||||
onClick={() =>
|
||||
navigate('/my-wallet', { replace: true })
|
||||
}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="35"
|
||||
height="35"
|
||||
viewBox="0 0 24 24"
|
||||
fill="skyblue"
|
||||
>
|
||||
<path d="M19 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H19v-2z" />
|
||||
</svg>
|
||||
</button>
|
||||
<h1 className="text-26 font-bold inline-flex gap-3 text-dark-gray dark:text-white items-center">
|
||||
Add Credit
|
||||
</h1>
|
||||
</div>
|
||||
<div className="slider-btns flex space-x-4">
|
||||
<div
|
||||
onClick={() => filterHandler("today")}
|
||||
className="relative"
|
||||
></div>
|
||||
</div>
|
||||
</div> */}
|
||||
|
||||
<div className="content-wrapper w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin">
|
||||
<div className="lg:w-2/2 w-full mb-10 lg:mb-0">
|
||||
<div className="add-fund w-full bg-white dark:bg-dark-white rounded-2xl shadow">
|
||||
{/*<h2 className='md:p-8 p-4 text-slate-900 dark:text-white text-xl lg:text-2xl font-medium'>Add Credit with Account Deposit</h2>*/}
|
||||
{/*<hr />*/}
|
||||
<form className="md:p-8 p-4 add-fund-info">
|
||||
<div className="field w-full mb-6">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
label={
|
||||
currency == "US Dollars" ? "Amount (USD)" : "Amount (Naira)"
|
||||
}
|
||||
type="text"
|
||||
name="amount"
|
||||
placeholder="0"
|
||||
value={input}
|
||||
inputHandler={handleChange}
|
||||
/>
|
||||
{inputError && (
|
||||
<p className="text-base text-red-500">{inputError}</p>
|
||||
)}
|
||||
</div>
|
||||
</form>
|
||||
<hr />
|
||||
|
||||
{/* SHOWS THIS IF USER CURRENCY IS DOLLARS */}
|
||||
{currency == "US Dollars" && (
|
||||
<div className="w-full md:p-8 p-4 bg-white dark:bg-dark-white rounded-2xl shadow">
|
||||
<AddFundDollars
|
||||
setInputError={setInputError}
|
||||
input={input}
|
||||
setInput={setInput}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* HIDES THIS BUTTON IF CURENCY IS NAIRA */}
|
||||
{currency != "US Dollars" && (
|
||||
<div className="md:p-8 p-4 add-fund-btn flex justify-end items-center py-4">
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
type="button"
|
||||
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
<span className="text-white">Continue</span>
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* HIDES THIS SECTION IF CURENCY IS NAIRA */}
|
||||
{currency != "US Dollars" && (
|
||||
<div className="content-wrapper w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin">
|
||||
<div className="lg:w-2/2 w-full mb-10 lg:mb-0">
|
||||
<div className="wallet w-full md:p-8 p-4 h-full min-h-[590px] bg-white dark:bg-dark-white rounded-2xl shadow">
|
||||
<h2 className="text-gray-900 dark:text-white text-xl lg:text-2xl font-medium">
|
||||
Recent Activity
|
||||
</h2>
|
||||
{/* <p className='text-base text-gray-600 dark:text-white'>Activity Report</p> */}
|
||||
{payment.loading ? (
|
||||
<LoadingSpinner size="16" color="sky-blue" />
|
||||
) : (
|
||||
<RecentActivityTable payment={payment} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default AddFund;
|
||||
@@ -0,0 +1,556 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import usersService from "../../../services/UsersService";
|
||||
import InputCom from "../../Helpers/Inputs/InputCom";
|
||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||
|
||||
import { Form, Formik } from "formik";
|
||||
import { useSelector } from "react-redux";
|
||||
import * as Yup from "yup";
|
||||
import Icons from "../../Helpers/Icons";
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
name: Yup.string()
|
||||
.min(3, "3 chars min.")
|
||||
.max(50, "50 chars max.")
|
||||
.required("required"),
|
||||
cardNum: Yup.string()
|
||||
.min(3, "3 chars min.")
|
||||
.max(25, "25 chars max.")
|
||||
.required("required"),
|
||||
code: Yup.string()
|
||||
.min(3, "3 chars min.")
|
||||
.max(25, "25 chars max.")
|
||||
.required("required"),
|
||||
state: Yup.string()
|
||||
.min(3, "3 chars min.")
|
||||
.max(25, "25 chars max.")
|
||||
.required("required"),
|
||||
address: Yup.string()
|
||||
.min(3, "3 chars min.")
|
||||
.max(50, "50 chars max.")
|
||||
.required("required"),
|
||||
expirationYear: Yup.string()
|
||||
.min(4, "4 chars min.")
|
||||
.max(4, "4 chars max.")
|
||||
.required("required"),
|
||||
expirationMonth: Yup.string()
|
||||
.min(1, "1 chars min.")
|
||||
.max(2, "2 chars max.")
|
||||
.required("required"),
|
||||
cvv: Yup.string()
|
||||
.min(3, "3 chars min.")
|
||||
.max(4, "4 chars max.")
|
||||
.required("required"),
|
||||
});
|
||||
|
||||
const initialValues = {
|
||||
name: "",
|
||||
cardNum: "",
|
||||
code: "",
|
||||
state: "",
|
||||
address: "",
|
||||
expirationYear: "",
|
||||
expirationMonth: "",
|
||||
cvv: "",
|
||||
};
|
||||
|
||||
function AddFundDollars(props) {
|
||||
const navigate = useNavigate();
|
||||
const apiCall = new usersService();
|
||||
let countryWallet = props.walletItem.country;
|
||||
const [tab, setTab] = useState("previous");
|
||||
const [loader, setLoader] = useState(false);
|
||||
const { userDetails } = useSelector((state) => state?.userDetails);
|
||||
const { firstname, lastname } = userDetails;
|
||||
const [prevCardDetails, setPrevCardDetails] = useState({});
|
||||
const [payListCards, setPayListCards] = useState({ loading: true, data: [] });
|
||||
let __awaitComponent = props.confirmCredit.show.awaitConfirm;
|
||||
let __acceptComponent = props.confirmCredit.show.awaitConfirm;
|
||||
const handleInputChange = (event) => {
|
||||
const { name, value } = event.target;
|
||||
setPrevCardDetails((prevState) => ({
|
||||
...prevState,
|
||||
[name]: value,
|
||||
}));
|
||||
};
|
||||
|
||||
const indexOfFirstItem = 0;
|
||||
const indexOfLastItem =
|
||||
indexOfFirstItem + Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
||||
const currentPreviousCards = payListCards?.data?.slice(
|
||||
indexOfFirstItem,
|
||||
indexOfLastItem
|
||||
);
|
||||
|
||||
const handleSubmit = async (values, helpers) => {
|
||||
props.setInputError("");
|
||||
|
||||
if (!props.input || props.input === "0") {
|
||||
props.setInputError("Please Enter Amount");
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNaN(props.input)) {
|
||||
props.setInputError("Amount must be a Number");
|
||||
return;
|
||||
}
|
||||
|
||||
if (tab === "previous") {
|
||||
if (!prevCardDetails) {
|
||||
return;
|
||||
}
|
||||
|
||||
props.setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
show: { awaitConfirm: { loader: true } },
|
||||
}));
|
||||
|
||||
let stateData = {
|
||||
amount: Number(props.input) * 100,
|
||||
currency: props.walletItem?.code,
|
||||
};
|
||||
|
||||
try {
|
||||
const res = await apiCall.getStartCredit(stateData);
|
||||
if (res.data.internal_return < 0) {
|
||||
props.setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
show: { awaitConfirm: { loader: false } },
|
||||
}));
|
||||
props.setInputError("An Error Occurred");
|
||||
setTimeout(() => props.setInputError(""), 5000);
|
||||
return;
|
||||
}
|
||||
|
||||
const _response = res.data;
|
||||
stateData.amount = Number(props.input);
|
||||
stateData.card = prevCardDetails["payment-card"];
|
||||
stateData.cardType = "prev";
|
||||
stateData = { ...stateData, ..._response };
|
||||
|
||||
setTimeout(() => {
|
||||
props.setConfirmCredit({
|
||||
show: {
|
||||
awaitConfirm: { loader: false, state: true },
|
||||
acceptConfirm: { loader: false, state: false },
|
||||
},
|
||||
data: stateData,
|
||||
});
|
||||
}, 1500);
|
||||
} catch (error) {
|
||||
props.setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
show: { awaitConfirm: { loader: false } },
|
||||
}));
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
if (tab === "new") {
|
||||
const stateData = {
|
||||
amount: Number(props.input),
|
||||
currency: props.currency,
|
||||
...values,
|
||||
};
|
||||
|
||||
// Rest of the code for tab "new"
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
apiCall
|
||||
.payListCard()
|
||||
.then((res) => {
|
||||
setPayListCards({ loading: false, data: res.data.result_list });
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("PAYCARDLIST ERROR", err);
|
||||
setPayListCards({ loading: false, data: [] });
|
||||
});
|
||||
}, []);
|
||||
|
||||
const handleClose = props.onClose;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="w-full">
|
||||
{/* switch button */}
|
||||
<div className="flex">
|
||||
<form className="add-fund-info flex items-center gap-3">
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
{countryWallet == "US" && "Payment Method"}
|
||||
</h1>
|
||||
<div className="my-1 flex items-center gap-2">
|
||||
<label
|
||||
onClick={() => setTab("previous")}
|
||||
htmlFor="previous"
|
||||
className="cursor-pointer flex items-center gap-1"
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
id="previous"
|
||||
name="card-option"
|
||||
checked={tab === "previous"}
|
||||
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border pointer-events-none w-7 h-7 ${
|
||||
tab == "previous" ? "" : ""
|
||||
} tracking-wide transition duration-200`}
|
||||
/>
|
||||
Previous Cards
|
||||
</label>
|
||||
<label
|
||||
onClick={() => setTab("new")}
|
||||
htmlFor="new"
|
||||
className="cursor-pointer flex items-center gap-1"
|
||||
>
|
||||
<input
|
||||
id="new"
|
||||
type="radio"
|
||||
name="card-option"
|
||||
checked={tab === "new"}
|
||||
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border pointer-events-none w-7 h-7 ${
|
||||
tab == "new" ? "" : ""
|
||||
} tracking-wide transition duration-200`}
|
||||
/>
|
||||
Add New Card
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<hr />
|
||||
{/* END OF switch button */}
|
||||
|
||||
{/* previous tab */}
|
||||
{tab === "previous" ? (
|
||||
<div className="p-4 previous-details w-full min-h-[16rem] flex flex-col justify-between items-center">
|
||||
{payListCards.loading ? (
|
||||
<LoadingSpinner size="10" color="sky-blue" />
|
||||
) : payListCards?.data?.length ? (
|
||||
<select
|
||||
className="my-3 w-full rounded-full p-2 outline-none text-base text-black dark:text-gray-100 bg-[#FAFAFA] dark:bg-[#11131F] border"
|
||||
value={prevCardDetails["payment-card"]?.card_uid}
|
||||
id="payment-card"
|
||||
name="payment-card"
|
||||
onChange={handleInputChange}
|
||||
>
|
||||
<option value="">Select a card</option>
|
||||
{currentPreviousCards.map((item, index) => (
|
||||
<option
|
||||
key={index}
|
||||
className={index !== 0 && "border-t-2"}
|
||||
value={JSON.stringify(item)}
|
||||
>
|
||||
<div className="my-2 flex items-center gap-5">
|
||||
<div className="card-details">
|
||||
<h1 className="text-lg font-bold text-dark-gray dark:text-white tracking-wide">
|
||||
{item.description} Card
|
||||
</h1>
|
||||
<p className="text-base font-bold text-dark-gray dark:text-white tracking-wide">
|
||||
Bank **************{item.digits}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
) : (
|
||||
<div className="w-full flex flex-col items-center">
|
||||
<p className="my-5 text-base font-bold text-dark-gray dark:text-white tracking-wide">
|
||||
No Previous Card Found!
|
||||
</p>
|
||||
<button
|
||||
onClick={() => setTab("new")}
|
||||
type="button"
|
||||
className="my-5 px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
<span className="text-white">Add Card</span>
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<div className="new-details w-full max-h-[23rem]">
|
||||
<div className="w-full flex flex-col justify-between">
|
||||
<Formik
|
||||
initialValues={initialValues}
|
||||
validationSchema={validationSchema}
|
||||
onSubmit={handleSubmit}
|
||||
>
|
||||
{(props) => {
|
||||
return (
|
||||
<Form className="md:pl-8">
|
||||
<div className="flex flex-col-reverse sm:flex-row">
|
||||
<div className="flex-1 sm:mr-10">
|
||||
<div className="fields w-full">
|
||||
{/* Inputs */}
|
||||
{/* Name */}
|
||||
<div className="flex items-center field w-full my-2 flex-[0.4] gap-3">
|
||||
<label className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold flex items-center gap-1">
|
||||
Name:
|
||||
</label>
|
||||
<p className="input-label text-[#181c32] dark:text-white text-[16px] leading-[20.9625px] font-semibold flex items-center gap-1">{`${firstname} ${lastname}`}</p>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center flex-1 gap-3 my-2">
|
||||
{/* Card Number */}
|
||||
<div className="field w-full flex-[0.6]">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
spanTag="*"
|
||||
iconName="master-card visa-card atm-card"
|
||||
label="Card Number"
|
||||
type="text"
|
||||
name="cardNum"
|
||||
placeholder="Enter Card Number"
|
||||
value={props.values.cardNum}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
error={props.errors.cardNum}
|
||||
/>
|
||||
</div>
|
||||
{/* Expire Year, Year */}
|
||||
<div className="sm:grid gap-5 grid-cols-2 flex-[0.4]">
|
||||
<div className="field w-full mb-6 xl:mb-0 col-span-1">
|
||||
<div className="select-option">
|
||||
<div
|
||||
className={`flex items-center justify-between mb-2.5`}
|
||||
>
|
||||
<label
|
||||
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold line-clamp-3 flex items-center"
|
||||
htmlFor="expiration"
|
||||
>
|
||||
Exp Month{" "}
|
||||
<span className="text-red-700 text-sm italic">
|
||||
*
|
||||
</span>
|
||||
<span className="text-[12px] text-red-500 ml-1">
|
||||
{props.errors.expirationMonth && "**"}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
className={`input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base`}
|
||||
>
|
||||
<select
|
||||
className={`input-field placeholder:text-base text-dark-gray w-full h-full tracking-wide dark:bg-[#11131F] bg-[#fafafa] focus:ring-0 focus:outline-none`}
|
||||
value={props.values.expirationMonth}
|
||||
onChange={props.handleChange}
|
||||
onBlur={props.handleBlur}
|
||||
name="expirationMonth"
|
||||
>
|
||||
<option
|
||||
value=""
|
||||
className="text-dark-gray"
|
||||
>
|
||||
Month
|
||||
</option>
|
||||
{expireMonth?.length &&
|
||||
expireMonth.map((item, index) => (
|
||||
<option
|
||||
key={index}
|
||||
value={item.value}
|
||||
>
|
||||
{item.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="field w-full mb-6 xl:mb-0 col-span-1">
|
||||
<div className="select-option">
|
||||
<div
|
||||
className={`flex items-center justify-between mb-2.5`}
|
||||
>
|
||||
<label
|
||||
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold flex items-center line-clamp-3"
|
||||
htmlFor="expiration"
|
||||
>
|
||||
Exp Year{" "}
|
||||
<span className="text-red-700 text-sm tracking-wide">
|
||||
*
|
||||
</span>
|
||||
<span className="text-[12px] text-red-500 italic">
|
||||
{props.errors.expirationYear && "**"}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
className={`input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base`}
|
||||
>
|
||||
<select
|
||||
className={`input-field placeholder:text-base text-dark-gray w-full h-full tracking-wide dark:bg-[#11131F] bg-[#fafafa] focus:ring-0 focus:outline-none`}
|
||||
value={props.values.expirationYear}
|
||||
onChange={props.handleChange}
|
||||
onBlur={props.handleBlur}
|
||||
name="expirationYear"
|
||||
>
|
||||
<option
|
||||
value=""
|
||||
className="text-dark-gray"
|
||||
>
|
||||
Year
|
||||
</option>
|
||||
{expireYear?.length &&
|
||||
expireYear.map((item, index) => (
|
||||
<option key={index} value={item}>
|
||||
{item}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center flex-1 gap-3 my-2">
|
||||
{/* Address and CVV */}
|
||||
<div className="field w-full col-span-1 flex-[0.4]">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
spanTag="*"
|
||||
iconName="atm-card"
|
||||
label="CVV"
|
||||
type="text"
|
||||
name="cvv"
|
||||
placeholder="CVV"
|
||||
value={props.values.cvv}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
error={props.errors.cvv}
|
||||
/>
|
||||
</div>
|
||||
<div className="field w-full flex-[0.6]">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
spanTag="*"
|
||||
label="Billing Address"
|
||||
type="text"
|
||||
name="address"
|
||||
placeholder="Billing Address"
|
||||
value={props.values.Address}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
error={props.errors.address}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Postal Code and State */}
|
||||
<div className="sm:grid gap-5 grid-cols-3 my-2">
|
||||
<div className="field w-full mb-6 xl:mb-0 col-span-1">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
spanTag="*"
|
||||
label="Postal Code"
|
||||
type="text"
|
||||
name="code"
|
||||
placeholder="Postal Code"
|
||||
value={props.values.code}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
error={props.errors.code}
|
||||
/>
|
||||
</div>
|
||||
<div className="field w-full col-span-1">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
spanTag="*"
|
||||
label="State"
|
||||
type="text"
|
||||
name="state"
|
||||
placeholder="State"
|
||||
value={props.values.state}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
error={props.errors.state}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="md:px-8 md:pt-4 px-4 pt-2 add-fund-btn flex justify-end items-center gap-3">
|
||||
<button
|
||||
className="px-4 py-1 h-11 max-w-[100px] w-full flex justify-center items-center border-gradient text-base rounded-full"
|
||||
onClick={handleClose}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
className="px-4 py-1 h-11 max-w-[100px] w-full flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
{loader ? (
|
||||
<LoadingSpinner size="6" color="sky-blue" />
|
||||
) : (
|
||||
<>
|
||||
<span className="text-white">Continue</span>{" "}
|
||||
<Icons name="chevron-right" />
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</Form>
|
||||
);
|
||||
}}
|
||||
</Formik>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{tab == "previous" && (
|
||||
<div className="md:py-8 px-[38px] add-fund-btn flex justify-end items-center gap-4 py-4">
|
||||
<button
|
||||
className="px-4 py-1 h-11 max-w-[100px] w-full flex justify-center items-center border-gradient text-base rounded-full"
|
||||
onClick={props.onClose}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
type="button"
|
||||
className="px-4 py-1 h-11 max-w-[100px] w-full flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
{props.confirmCredit?.show?.awaitConfirm?.loader ? (
|
||||
<LoadingSpinner size="6" color="sky-blue" />
|
||||
) : (
|
||||
<span className="text-white">Continue</span>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default AddFundDollars;
|
||||
|
||||
// FORMS ARRAY OF EXPIRATION YEAR FOR CARD
|
||||
const expireYear = [];
|
||||
let currentYear = new Date().getFullYear();
|
||||
for (let i = 0; i <= 6; i++) {
|
||||
expireYear.push(currentYear + i);
|
||||
}
|
||||
|
||||
// FORMS ARRAY OF EXPIRATION MONTH FOR CARD
|
||||
let month = [
|
||||
"January",
|
||||
"February",
|
||||
"March",
|
||||
"April",
|
||||
"May",
|
||||
"June",
|
||||
"July",
|
||||
"August",
|
||||
"September",
|
||||
"October",
|
||||
"November",
|
||||
"December",
|
||||
];
|
||||
const expireMonth = [];
|
||||
for (let i = 0; i < month.length; i++) {
|
||||
expireMonth.push({ name: month[i], value: i + 1 });
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
import React, { useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import usersService from "../../../services/UsersService";
|
||||
import Icons from "../../Helpers/Icons";
|
||||
import InputCom from "../../Helpers/Inputs/InputCom";
|
||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||
import AddFundDollars from "./AddFundDollars";
|
||||
|
||||
function AddFundPop({
|
||||
_payment,
|
||||
input,
|
||||
setInput,
|
||||
onClose,
|
||||
confirmCredit,
|
||||
setConfirmCredit,
|
||||
walletItem,
|
||||
}) {
|
||||
const navigate = useNavigate();
|
||||
const apiCall = new usersService();
|
||||
let countryWallet = walletItem?.country;
|
||||
const { payment, currency } = _payment;
|
||||
|
||||
const [inputError, setInputError] = useState("");
|
||||
let __awaitComponent = confirmCredit.show.awaitConfirm;
|
||||
|
||||
const handleChange = ({ target: { name, value } }) => {
|
||||
setInput(value);
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
setInputError("");
|
||||
setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
show: { awaitConfirm: { loader: true } },
|
||||
}));
|
||||
|
||||
if (!input || input === "0") {
|
||||
setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
show: { awaitConfirm: { loader: false } },
|
||||
}));
|
||||
setInputError("Please Enter Amount");
|
||||
setTimeout(() => setInputError(""), 5000);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNaN(input)) {
|
||||
setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
show: { awaitConfirm: { loader: false } },
|
||||
}));
|
||||
setInputError("Amount must be a Number");
|
||||
setTimeout(() => setInputError(""), 5000);
|
||||
return;
|
||||
}
|
||||
|
||||
let stateData = {
|
||||
amount: Number(input) * 100,
|
||||
currency: walletItem?.code,
|
||||
};
|
||||
|
||||
try {
|
||||
const res = await apiCall.getStartCredit(stateData);
|
||||
if (res.data.internal_return < 0) {
|
||||
setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
show: { awaitConfirm: { loader: false } },
|
||||
}));
|
||||
setInputError("An Error Occurred");
|
||||
setTimeout(() => setInputError(""), 5000);
|
||||
return;
|
||||
}
|
||||
|
||||
const _response = res.data;
|
||||
stateData.amount = Number(input);
|
||||
stateData.currency = currency;
|
||||
stateData = { ...stateData, ..._response };
|
||||
|
||||
setTimeout(() => {
|
||||
setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
show: {
|
||||
awaitConfirm: { loader: false, state: true },
|
||||
acceptConfirm: { loader: false, state: false },
|
||||
},
|
||||
data: stateData,
|
||||
}));
|
||||
}, 1500);
|
||||
} catch (error) {
|
||||
setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
show: { awaitConfirm: { loader: false } },
|
||||
}));
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="h-[33rem] w-full">
|
||||
<div className="content-wrapper w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin">
|
||||
<div className="lg:w-2/2 w-full mb-10 lg:mb-0">
|
||||
<div className="add-fund w-full bg-white dark:bg-dark-white rounded-2xl">
|
||||
<form className="md:px-8 md:pt-4 px-4 pt-2 add-fund-info flex items-center gap-[2.1rem]">
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
Amount({currency})
|
||||
</h1>
|
||||
<div className="field w-full max-w-[250px]">
|
||||
<InputCom
|
||||
fieldClass="px-6"
|
||||
type="text"
|
||||
name="amount"
|
||||
placeholder="0"
|
||||
value={input}
|
||||
inputHandler={handleChange}
|
||||
/>
|
||||
<p className="text-base text-red-500 h-5">
|
||||
{inputError && inputError}
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{countryWallet === "US" && (
|
||||
<div className="w-full md:px-8 md:pt-4 px-4 pt-2 bg-white dark:bg-dark-white rounded-2xl">
|
||||
<AddFundDollars
|
||||
setInputError={setInputError}
|
||||
walletItem={walletItem}
|
||||
input={input}
|
||||
setInput={setInput}
|
||||
currency={currency}
|
||||
onClose={onClose}
|
||||
confirmCredit={confirmCredit}
|
||||
setConfirmCredit={setConfirmCredit}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{countryWallet == "NG" && <div className="h-[18rem]"></div>}
|
||||
|
||||
{countryWallet == "NG" && (
|
||||
<div className="md:p-8 p-4 add-fund-btn flex justify-end items-center py-4 gap-4">
|
||||
<button
|
||||
className="px-4 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
onClick={onClose}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
type="button"
|
||||
className="px-4 py-1 h-11 flex justify-center space-x-1 items-center btn-gradient text-base rounded-full text-white max-w-[100px] w-full"
|
||||
>
|
||||
{__awaitComponent.loader ? (
|
||||
<LoadingSpinner size="6" color="sky-blue" />
|
||||
) : (
|
||||
<>
|
||||
<span className="text-white">Continue</span>{" "}
|
||||
<Icons name="chevron-right" />
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default AddFundPop;
|
||||
@@ -0,0 +1,106 @@
|
||||
import React from "react";
|
||||
|
||||
function CompleteConfirmCredit({ onClose, confirmCredit }) {
|
||||
console.log(confirmCredit);
|
||||
const { data } = confirmCredit;
|
||||
return (
|
||||
<div className="logout-modal-body w-full flex flex-col items-center">
|
||||
<div className="content-wrapper w-full h-[32rem]">
|
||||
<div className="w-full mb-10">
|
||||
<div className="add-fund w-full bg-white dark:bg-dark-white rounded-2xl">
|
||||
<div className="px-4 md:p-8 py-4 add-fund-info">
|
||||
<div className="field w-full mb-3 min-h-[45px]">
|
||||
<div className="flex flex-col gap-4">
|
||||
{/* Success Icon for now */}
|
||||
<div className="flex items-center w-full justify-center">
|
||||
{data?.result == "Charge success" ? (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="100"
|
||||
height="100"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="green"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
className="feather feather-check-circle"
|
||||
>
|
||||
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path>
|
||||
<polyline points="22 4 12 14.01 9 11.01"></polyline>
|
||||
</svg>
|
||||
) : (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
width="100"
|
||||
height="100"
|
||||
stroke="red"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
className="feather feather-x-circle"
|
||||
>
|
||||
<circle cx="12" cy="12" r="10"></circle>
|
||||
<line x1="15" y1="9" x2="9" y2="15"></line>
|
||||
<line x1="9" y1="9" x2="15" y2="15"></line>
|
||||
</svg>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className={`flex items-center`}>
|
||||
<h1 className="text-xl font-semibold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
{data?.result == "Charge success"
|
||||
? "Credit was Successful!"
|
||||
: "Credit was Unsuccessful"}
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-8">
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
Amount({data?.currency || ""})
|
||||
</h1>
|
||||
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
{`${data?.symbol || ""} ${
|
||||
Number(data?.amount * 0.01).toLocaleString() || ""
|
||||
}`}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-8">
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
Wallet Balance
|
||||
</h1>
|
||||
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
{data?.curr_balance}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-8">
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
Confirmation Number
|
||||
</h1>
|
||||
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
{data?.confirmation}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="md:p-8 p-4 add-fund-btn flex justify-end items-center py-4 gap-4">
|
||||
<button
|
||||
className="px-4 h-11 flex justify-center items-center btn-gradient text-white text-base rounded-full w-[100px]"
|
||||
onClick={onClose}
|
||||
>
|
||||
Ok
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default CompleteConfirmCredit;
|
||||
@@ -0,0 +1,295 @@
|
||||
import { FlutterWaveButton, closePaymentModal } from "flutterwave-react-v3";
|
||||
import React, { useState } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { toast } from "react-toastify";
|
||||
import usersService from "../../../services/UsersService";
|
||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||
|
||||
function ConfirmAddFund({
|
||||
confirmCredit,
|
||||
onClose,
|
||||
walletItem,
|
||||
setConfirmCredit,
|
||||
}) {
|
||||
const __confirmData = confirmCredit?.data;
|
||||
const __confirmCountry = walletItem?.country;
|
||||
const __confirmCardDetails = __confirmData.card
|
||||
? JSON.parse(__confirmData.card)
|
||||
: "";
|
||||
let { userDetails } = useSelector((state) => state.userDetails); // TO GET LOGGEDIN USER DETAILS
|
||||
|
||||
let [requestStatus, setRequestStatus] = useState({
|
||||
message: "",
|
||||
loading: false,
|
||||
status: false,
|
||||
}); // STATE FOR API REQUEST
|
||||
|
||||
const apiURL = new usersService();
|
||||
const navigate = useNavigate();
|
||||
|
||||
//FUNCTION TO HANDLE SUBMIT
|
||||
const onSuccessPayment = () => {
|
||||
setRequestStatus({ message: "", loading: true, status: false });
|
||||
let reqData = { amount: __confirmData?.account, currency: "NGN" };
|
||||
apiURL
|
||||
.startTopUp(reqData)
|
||||
.then((res) => {
|
||||
if (res.data.internal_return < 0) {
|
||||
setRequestStatus({
|
||||
message: "Could not finish transaction",
|
||||
loading: false,
|
||||
status: false,
|
||||
});
|
||||
toast.success("Opps! something went wrong");
|
||||
}
|
||||
// do something
|
||||
setRequestStatus({
|
||||
message: "Topup successful",
|
||||
loading: false,
|
||||
status: true,
|
||||
});
|
||||
toast.success("Account Topup was successful");
|
||||
setTimeout(() => {
|
||||
navigate("/my-wallet", { replace: true });
|
||||
}, 1000);
|
||||
})
|
||||
.catch((err) => {
|
||||
// do something
|
||||
setRequestStatus({
|
||||
message: "Opps! An Error Occured",
|
||||
loading: false,
|
||||
status: false,
|
||||
});
|
||||
toast.success("Opps! something went wrong");
|
||||
});
|
||||
};
|
||||
|
||||
const config = {
|
||||
public_key: process.env.REACT_APP_FLUTTERWAVE_APIKEY,
|
||||
tx_ref: Date.now(),
|
||||
amount: __confirmData?.amount,
|
||||
currency: "NGN",
|
||||
payment_options: "card,mobilemoney,ussd",
|
||||
customer: {
|
||||
email: `${userDetails.email}`,
|
||||
phone_number: userDetails.phone,
|
||||
name: `${userDetails.lastname} ${userDetails.firstname}`,
|
||||
},
|
||||
customizations: {
|
||||
title: "WrenchBoard",
|
||||
description: "Topup Payment",
|
||||
logo: "https://st2.depositphotos.com/4403291/7418/v/450/depositphotos_74189661-stock-illustration-online-shop-log.jpg",
|
||||
},
|
||||
};
|
||||
|
||||
const fwConfig = {
|
||||
...config,
|
||||
text: "Proceed",
|
||||
callback: (response) => {
|
||||
onSuccessPayment();
|
||||
closePaymentModal(); // this will close the modal programmatically
|
||||
},
|
||||
onClose: () => {},
|
||||
};
|
||||
|
||||
// Handling Previous Card
|
||||
const handlePrevCard = async () => {
|
||||
const { amount, credit_reference, currency } = __confirmData;
|
||||
const { card_uid } = __confirmCardDetails;
|
||||
|
||||
const reqData = {
|
||||
amount: amount * 100,
|
||||
card_uid,
|
||||
credit_reference,
|
||||
currency,
|
||||
};
|
||||
|
||||
try {
|
||||
setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
show: {
|
||||
acceptConfirm: { loader: true },
|
||||
},
|
||||
}));
|
||||
const res = await apiURL.getPaidPrevCard(reqData);
|
||||
const _response = res.data;
|
||||
if (res.data.internal_return < 0) {
|
||||
setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
show: {
|
||||
acceptConfirm: { loader: false },
|
||||
},
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
return setTimeout(
|
||||
() =>
|
||||
setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
show: {
|
||||
awaitConfirm: { loader: false, state: false },
|
||||
acceptConfirm: { loader: false, state: true },
|
||||
},
|
||||
data: _response,
|
||||
})),
|
||||
1500
|
||||
);
|
||||
} catch (error) {
|
||||
setConfirmCredit((prev) => ({
|
||||
...prev,
|
||||
show: {
|
||||
acceptConfirm: { loader: false },
|
||||
},
|
||||
}));
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
const ThePaymentText = ({ value }) => (
|
||||
<div className="my-2 flex items-center gap-5">
|
||||
<div className="card-details flex items-center gap-3">
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
{value.description} Card
|
||||
</h1>
|
||||
<p className="text-base font-bold text-dark-gray dark:text-white tracking-wide">
|
||||
Bank **************{value.digits}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="content-wrapper w-full h-[32rem]">
|
||||
<div className="w-full mb-10">
|
||||
<div className="add-fund w-full bg-white dark:bg-dark-white rounded-2xl">
|
||||
<div className="px-4 md:p-8 py-4 add-fund-info">
|
||||
<div className="field w-full mb-3 min-h-[45px]">
|
||||
{confirmCredit?.show?.awaitConfirm?.state ? (
|
||||
<div className="flex flex-col gap-2">
|
||||
{/* Amount */}
|
||||
<div
|
||||
className={`flex items-center ${
|
||||
__confirmCountry == "US" ? "gap-14" : "gap-4"
|
||||
}`}
|
||||
>
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
Amount({__confirmData?.currency})
|
||||
</h1>
|
||||
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
{`${walletItem?.symbol} ${
|
||||
Number(__confirmData?.amount).toLocaleString() || ""
|
||||
}`}
|
||||
</span>
|
||||
</div>
|
||||
{/* Transaction Fee */}
|
||||
<div
|
||||
className={`flex items-center border-b border-gray-600 ${
|
||||
__confirmCountry == "US" ? "gap-[2.7rem]" : "gap-4"
|
||||
}`}
|
||||
>
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
Transaction Fee
|
||||
</h1>
|
||||
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
{`${walletItem?.symbol} ${
|
||||
Number(__confirmData?.fee).toLocaleString() || ""
|
||||
}`}
|
||||
</span>
|
||||
</div>
|
||||
{/* Total */}
|
||||
<div
|
||||
className={`flex items-center ${
|
||||
__confirmCountry == "US" ? "gap-[8rem]" : "gap-4"
|
||||
}`}
|
||||
>
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
Total
|
||||
</h1>
|
||||
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
{`${walletItem?.symbol} ${
|
||||
(
|
||||
Number(__confirmData?.amount) +
|
||||
Number(__confirmData?.fee)
|
||||
).toLocaleString() || ""
|
||||
}`}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{__confirmCountry == "US" && (
|
||||
<div className="flex items-center gap-8">
|
||||
<label
|
||||
htmlFor="payment"
|
||||
className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1"
|
||||
>
|
||||
{__confirmCountry == "US" && "Payment Method"}
|
||||
</label>
|
||||
<span className="text-[#181c32] dark:text-white ">
|
||||
{__confirmCardDetails ? (
|
||||
<ThePaymentText value={__confirmCardDetails} />
|
||||
) : null}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div
|
||||
className={`${
|
||||
__confirmCountry == "US" ? "gap-[3.7rem]" : "gap-8"
|
||||
} flex items-center`}
|
||||
>
|
||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
Reference No
|
||||
</h1>
|
||||
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||
{__confirmData?.credit_reference}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={
|
||||
__confirmCountry == "US" ? "min-h-[96px]" : "min-h-[200px]"
|
||||
}
|
||||
></div>
|
||||
<hr />
|
||||
<div className="md:p-8 p-4 add-fund-btn flex justify-end items-center py-4 gap-4">
|
||||
<button
|
||||
className="px-4 h-11 flex justify-center items-center border-gradient text-base rounded-full"
|
||||
onClick={onClose}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
{__confirmCountry == "US" && (
|
||||
<button
|
||||
className="px-4 h-11 flex justify-center items-center btn-gradient text-white text-base rounded-full"
|
||||
onClick={
|
||||
__confirmData?.cardType === "prev"
|
||||
? handlePrevCard
|
||||
: () => console.log("Test me")
|
||||
}
|
||||
>
|
||||
{confirmCredit?.show?.acceptConfirm?.loader ? (
|
||||
<LoadingSpinner size="6" color="sky-blue" />
|
||||
) : (
|
||||
"Proceed"
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
{__confirmCountry == "NG" && (
|
||||
<FlutterWaveButton
|
||||
{...fwConfig}
|
||||
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ConfirmAddFund;
|
||||
@@ -1,8 +1,8 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import { toast } from "react-toastify";
|
||||
import InputCom from "../Helpers/Inputs/InputCom";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import InputCom from "../../Helpers/Inputs/InputCom";
|
||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||
import RecentActivityTable from "./WalletComponent/RecentActivityTable";
|
||||
|
||||
import usersService from "../../services/UsersService";
|
||||
@@ -0,0 +1,100 @@
|
||||
import { useState } from "react";
|
||||
import ModalCom from "../../Helpers/ModalCom";
|
||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||
import AddFundPop from "./AddFundPop";
|
||||
import CompleteConfirmCredit from "./CompleteConfirmCredit";
|
||||
import ConfirmAddFund from "./ConfirmAddFund";
|
||||
|
||||
const CreditPopup = ({ details, onClose, situation, walletItem }) => {
|
||||
let [input, setInput] = useState("");
|
||||
const [confirmCredit, setConfirmCredit] = useState({
|
||||
show: {
|
||||
awaitConfirm: { loader: false, state: false },
|
||||
acceptConfirm: { loader: false, state: false },
|
||||
},
|
||||
data: {},
|
||||
});
|
||||
|
||||
return (
|
||||
<ModalCom
|
||||
action={onClose}
|
||||
situation={situation}
|
||||
className="assign-task-popup"
|
||||
>
|
||||
<div className="logout-modal-wrapper lw-[90%] md:w-[768px] h-full lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl overflow-y-auto">
|
||||
<div className="logout-modal-header w-full flex items-center justify-between lg:p-6 px-[30px] py-[23px] border-b dark:border-[#5356fb29] border-light-purple">
|
||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
|
||||
{confirmCredit?.show?.acceptConfirm?.loader
|
||||
? "Confirming Credit..."
|
||||
: confirmCredit?.show?.awaitConfirm?.state
|
||||
? "Confirm Credit Add"
|
||||
: confirmCredit?.show?.acceptConfirm?.state
|
||||
? "Credit Add Completed"
|
||||
: "Add Credit"}
|
||||
</h1>
|
||||
<button
|
||||
type="button"
|
||||
className="text-[#374557] dark:text-red-500"
|
||||
onClick={onClose}
|
||||
>
|
||||
<svg
|
||||
width="36"
|
||||
height="36"
|
||||
viewBox="0 0 36 36"
|
||||
fill="none"
|
||||
className="fill-current"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M36 16.16C36 17.4399 36 18.7199 36 20.0001C35.7911 20.0709 35.8636 20.2554 35.8385 20.4001C34.5321 27.9453 30.246 32.9248 22.9603 35.2822C21.9006 35.6251 20.7753 35.7657 19.6802 35.9997C18.4003 35.9997 17.1204 35.9997 15.8401 35.9997C15.5896 35.7086 15.2189 35.7732 14.9034 35.7093C7.77231 34.2621 3.08728 30.0725 0.769671 23.187C0.435002 22.1926 0.445997 21.1199 0 20.1599C0 18.7198 0 17.2798 0 15.8398C0.291376 15.6195 0.214408 15.2656 0.270759 14.9808C1.71321 7.69774 6.02611 2.99691 13.0428 0.700951C14.0118 0.383805 15.0509 0.386897 15.9999 0C17.2265 0 18.4532 0 19.6799 0C19.7156 0.124041 19.8125 0.136067 19.9225 0.146719C27.3 0.868973 33.5322 6.21922 35.3801 13.427C35.6121 14.3313 35.7945 15.2484 36 16.16ZM33.011 18.0787C33.0433 9.77105 26.3423 3.00309 18.077 2.9945C9.78479 2.98626 3.00344 9.658 2.98523 17.8426C2.96667 26.1633 9.58859 32.9601 17.7602 33.0079C26.197 33.0577 32.9787 26.4186 33.011 18.0787Z"
|
||||
fill=""
|
||||
fillOpacity="0.6"
|
||||
/>
|
||||
<path
|
||||
d="M15.9309 18.023C13.9329 16.037 12.007 14.1207 10.0787 12.2072C9.60071 11.733 9.26398 11.2162 9.51996 10.506C9.945 9.32677 11.1954 9.0811 12.1437 10.0174C13.9067 11.7585 15.6766 13.494 17.385 15.2879C17.9108 15.8401 18.1633 15.7487 18.6375 15.258C20.3586 13.4761 22.1199 11.7327 23.8822 9.99096C24.8175 9.06632 26.1095 9.33639 26.4967 10.517C26.7286 11.2241 26.3919 11.7413 25.9133 12.2178C24.1757 13.9472 22.4477 15.6855 20.7104 17.4148C20.5228 17.6018 20.2964 17.7495 20.0466 17.9485C22.0831 19.974 24.0372 21.8992 25.9689 23.8468C26.9262 24.8119 26.6489 26.1101 25.4336 26.4987C24.712 26.7292 24.2131 26.3441 23.7455 25.8757C21.9945 24.1227 20.2232 22.3892 18.5045 20.6049C18.0698 20.1534 17.8716 20.2269 17.4802 20.6282C15.732 22.4215 13.9493 24.1807 12.1777 25.951C11.7022 26.4262 11.193 26.7471 10.4738 26.4537C9.31345 25.9798 9.06881 24.8398 9.98589 23.8952C11.285 22.5576 12.6138 21.2484 13.9387 19.9355C14.5792 19.3005 15.2399 18.6852 15.9309 18.023Z"
|
||||
fill="#"
|
||||
fillOpacity="0.6"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div className="logout-modal-body w-full flex flex-col items-center">
|
||||
{confirmCredit?.show?.acceptConfirm?.loader ? (
|
||||
<div className="h-[32rem] flex items-center justify-center">
|
||||
<LoadingSpinner size="12" color="sky-blue" />
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{confirmCredit?.show?.awaitConfirm?.state ? (
|
||||
<ConfirmAddFund
|
||||
confirmCredit={confirmCredit}
|
||||
setConfirmCredit={setConfirmCredit}
|
||||
walletItem={walletItem}
|
||||
onClose={onClose}
|
||||
/>
|
||||
) : confirmCredit?.show?.acceptConfirm?.state ? (
|
||||
<CompleteConfirmCredit
|
||||
walletItem={walletItem}
|
||||
confirmCredit={confirmCredit}
|
||||
onClose={onClose}
|
||||
/>
|
||||
) : (
|
||||
<AddFundPop
|
||||
_payment={details}
|
||||
walletItem={walletItem}
|
||||
input={input}
|
||||
setInput={setInput}
|
||||
onClose={onClose}
|
||||
confirmCredit={confirmCredit}
|
||||
setConfirmCredit={setConfirmCredit}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</ModalCom>
|
||||
);
|
||||
};
|
||||
|
||||
export default CreditPopup;
|
||||
@@ -1,10 +1,10 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import InputCom from "../Helpers/Inputs/InputCom";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import RecentActivityTable from "./WalletComponent/RecentActivityTable";
|
||||
import InputCom from "../../Helpers/Inputs/InputCom";
|
||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||
// import RecentActivityTable
|
||||
|
||||
import usersService from "../../services/UsersService";
|
||||
import usersService from "../../../services/UsersService";
|
||||
|
||||
import { Form, Formik } from "formik";
|
||||
import * as Yup from "yup";
|
||||
@@ -91,6 +91,7 @@ function TransferFund({ payment, wallet }) {
|
||||
|
||||
//FUNCTION TO HANDLE SUBMIT
|
||||
const handleSubmit = (values, helpers) => {
|
||||
if(!values?.amount && !values.recipientID) return
|
||||
setRequestStatus(true);
|
||||
let recipientDetails = recipients.data?.filter(
|
||||
(item) => item.recipient_id == values.recipientID
|
||||
@@ -302,6 +303,7 @@ function TransferFund({ payment, wallet }) {
|
||||
) : (
|
||||
<button
|
||||
type="submit"
|
||||
disabled={props.isSubmitting}
|
||||
className="text-lg text-white bg-sky-blue px-4 py-2 hover:opacity-90 rounded-md"
|
||||
>
|
||||
Continue
|
||||
@@ -324,7 +326,8 @@ function TransferFund({ payment, wallet }) {
|
||||
{payment.loading ? (
|
||||
<LoadingSpinner size="16" color="sky-blue" />
|
||||
) : (
|
||||
<RecentActivityTable payment={payment} />
|
||||
// <RecentActivityTable payment={payment} />
|
||||
null
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,85 +1,136 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import {Routes, Route, Outlet, Navigate} from 'react-router-dom'
|
||||
import usersService from '../../services/UsersService'
|
||||
import React, {
|
||||
Suspense,
|
||||
lazy,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useReducer,
|
||||
} from "react";
|
||||
import { Routes, Route, Outlet, Navigate } from "react-router-dom";
|
||||
import usersService from "../../services/UsersService";
|
||||
import Layout from "../Partials/Layout";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
|
||||
import Layout from '../Partials/Layout'
|
||||
|
||||
import Balance from './Balance'
|
||||
import TransferFund from './TransferFund'
|
||||
import AddFund from './AddFund'
|
||||
import AddRecipient from './AddRecipient'
|
||||
import ConfirmTransfer from './ConfirmTransfer'
|
||||
import ConfirmAddFund from './ConfirmAddFund'
|
||||
import WalletBox from "./WalletBox";
|
||||
// const AddFund = lazy(() => import("./AddFund"));
|
||||
// const ConfirmAddFund = lazy(() => import("./ConfirmAddFund"));
|
||||
// const TransferFund = lazy(() => import("./TransferFund"));
|
||||
const WalletBox = lazy(() => import("./WalletBox"));
|
||||
// const AddRecipient = lazy(() => import("./AddRecipient"));
|
||||
// const ConfirmTransfer = lazy(() => import("./ConfirmTransfer"));
|
||||
|
||||
function Wallet() {
|
||||
return (
|
||||
<Layout>
|
||||
<Outlet />
|
||||
<Outlet />
|
||||
</Layout>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const initialState = {
|
||||
loading: true,
|
||||
data: [],
|
||||
error: false,
|
||||
};
|
||||
|
||||
// Currently learning better about useReducer, so I converted this since it seemed like something complex
|
||||
const reducer = (state, action) => {
|
||||
switch (action.type) {
|
||||
case "FETCH_SUCCESS":
|
||||
return {
|
||||
...state,
|
||||
loading: false,
|
||||
data: action.payload,
|
||||
};
|
||||
case "FETCH_ERROR":
|
||||
return {
|
||||
...state,
|
||||
loading: false,
|
||||
error: true,
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
const WalletRoutes = () => {
|
||||
const apiCall = new usersService()
|
||||
const apiCall = useMemo(() => new usersService(), []);
|
||||
|
||||
let [walletList, setWalletList] = useState({ // FOR WALLET LIST
|
||||
loading: true,
|
||||
data: [],
|
||||
error: false
|
||||
})
|
||||
const [walletList, dispatchWalletList] = useReducer(reducer, initialState);
|
||||
const [paymentHistory, dispatchPaymentHistory] = useReducer(
|
||||
reducer,
|
||||
initialState
|
||||
);
|
||||
|
||||
let [paymentHistory, setPaymentHistory] = useState({ // FOR PAYMENT HISTORY
|
||||
loading: true,
|
||||
data: [],
|
||||
error: false
|
||||
})
|
||||
const getWalletList = useCallback(() => {
|
||||
apiCall
|
||||
.getUserWallets(null)
|
||||
.then((res) => {
|
||||
if (res.data.internal_return < 0) {
|
||||
dispatchWalletList({ type: "FETCH_SUCCESS", payload: [] });
|
||||
} else {
|
||||
dispatchWalletList({
|
||||
type: "FETCH_SUCCESS",
|
||||
payload: res.data.result_list,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
dispatchWalletList({ type: "FETCH_ERROR" });
|
||||
});
|
||||
}, [apiCall]);
|
||||
|
||||
//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}))
|
||||
})
|
||||
const getPaymentHistory = useCallback(() => {
|
||||
apiCall
|
||||
.getPaymentHx()
|
||||
.then((res) => {
|
||||
if (res.data.internal_return < 0) {
|
||||
dispatchPaymentHistory({ type: "FETCH_SUCCESS", payload: [] });
|
||||
} else {
|
||||
dispatchPaymentHistory({
|
||||
type: "FETCH_SUCCESS",
|
||||
payload: res.data.result_list,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
dispatchPaymentHistory({ type: "FETCH_ERROR" });
|
||||
});
|
||||
}, [apiCall]);
|
||||
|
||||
useEffect(() => {
|
||||
let isMounted = true;
|
||||
|
||||
if (isMounted) {
|
||||
getWalletList();
|
||||
getPaymentHistory();
|
||||
}
|
||||
|
||||
//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}))
|
||||
})
|
||||
}
|
||||
return () => {
|
||||
isMounted = false;
|
||||
};
|
||||
}, [getWalletList, getPaymentHistory]);
|
||||
|
||||
useEffect(()=>{
|
||||
getWalletList()
|
||||
getPaymentHistory()
|
||||
}, [])
|
||||
return (
|
||||
<Routes>
|
||||
<Route element={<Wallet />}>
|
||||
<Route path='add-fund' element={<AddFund payment={paymentHistory} />} />
|
||||
<Route path='add-fund/confirm-add-fund' element={<ConfirmAddFund payment={paymentHistory} />} />
|
||||
<Route path='transfer-fund' element={<TransferFund payment={paymentHistory} wallet={walletList} />} />
|
||||
{/*<Route index element={<Balance wallet={walletList} />} />*/}
|
||||
<Route index element={<WalletBox wallet={walletList} />} />
|
||||
<Route path='transfer-fund/add-recipient' element={<AddRecipient />} />
|
||||
<Route path='transfer-fund/confirm-transfer' element={<ConfirmTransfer payment={paymentHistory} wallet={walletList} />} />
|
||||
<Route path='*' element={<Navigate to='/' />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<Routes>
|
||||
<Route
|
||||
element={
|
||||
<Suspense fallback={<LoadingSpinner size="16" color="sky-blue" />}>
|
||||
<Wallet />
|
||||
</Suspense>
|
||||
}
|
||||
>
|
||||
<Route
|
||||
index
|
||||
element={
|
||||
<Suspense fallback={<LoadingSpinner size="16" color="sky-blue" />}>
|
||||
<WalletBox wallet={walletList} payment={paymentHistory} />
|
||||
</Suspense>
|
||||
}
|
||||
/>
|
||||
<Route path="*" element={<Navigate to="/" />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
);
|
||||
};
|
||||
|
||||
export default WalletRoutes
|
||||
export default WalletRoutes;
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import React from 'react'
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
function WalletAction({walletItem, payment, openPopUp}) {
|
||||
return (
|
||||
<div className="counters w-full flex justify-between gap-2">
|
||||
<div className='w-1/2 flex justify-center items-center'>
|
||||
<Link
|
||||
to="transfer-fund"
|
||||
className={`${
|
||||
walletItem.code != "NAIRA" && "invisible"
|
||||
} px-4 h-10 flex justify-center items-center btn-gradient text-base rounded-full text-white`}
|
||||
>
|
||||
Spend
|
||||
</Link>
|
||||
</div>
|
||||
<div className='w-1/2 flex justify-center items-center'>
|
||||
<button
|
||||
className='px-4 h-10 flex justify-center items-center btn-gradient text-base rounded-full text-white'
|
||||
onClick={() => {
|
||||
openPopUp({
|
||||
payment: payment,
|
||||
currency: walletItem?.description,
|
||||
});
|
||||
}}
|
||||
>
|
||||
{/* <span className="">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="38"
|
||||
height="38"
|
||||
viewBox="0 0 42 42"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M21 0C16.8466 0 12.7865 1.23163 9.33303 3.53914C5.8796 5.84665 3.18798 9.1264 1.59854 12.9636C0.00909901 16.8009 -0.406771 21.0233 0.403518 25.0969C1.21381 29.1705 3.21386 32.9123 6.15077 35.8492C9.08767 38.7861 12.8295 40.7862 16.9031 41.5965C20.9767 42.4068 25.1991 41.9909 29.0364 40.4015C32.8736 38.812 36.1534 36.1204 38.4609 32.667C40.7684 29.2135 42 25.1534 42 21C41.994 15.4323 39.7796 10.0944 35.8426 6.15741C31.9056 2.22045 26.5677 0.00602189 21 0ZM28 22.75H22.75V28C22.75 28.4641 22.5656 28.9092 22.2374 29.2374C21.9093 29.5656 21.4641 29.75 21 29.75C20.5359 29.75 20.0908 29.5656 19.7626 29.2374C19.4344 28.9092 19.25 28.4641 19.25 28V22.75H14C13.5359 22.75 13.0908 22.5656 12.7626 22.2374C12.4344 21.9092 12.25 21.4641 12.25 21C12.25 20.5359 12.4344 20.0907 12.7626 19.7626C13.0908 19.4344 13.5359 19.25 14 19.25H19.25V14C19.25 13.5359 19.4344 13.0908 19.7626 12.7626C20.0908 12.4344 20.5359 12.25 21 12.25C21.4641 12.25 21.9093 12.4344 22.2374 12.7626C22.5656 13.0908 22.75 13.5359 22.75 14V19.25H28C28.4641 19.25 28.9093 19.4344 29.2374 19.7626C29.5656 20.0907 29.75 20.5359 29.75 21C29.75 21.4641 29.5656 21.9092 29.2374 22.2374C28.9093 22.5656 28.4641 22.75 28 22.75Z"
|
||||
// fill="white"
|
||||
className="stroke-black fill-white"
|
||||
></path>
|
||||
</svg>
|
||||
</span> */}
|
||||
<span className="">Add Credit</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default WalletAction
|
||||
@@ -1,273 +1,262 @@
|
||||
import React from "react";
|
||||
import bank1 from "../../assets/images/bank-1.png";
|
||||
import bank2 from "../../assets/images/bank-2.png";
|
||||
import bank3 from "../../assets/images/bank-3.png";
|
||||
import bank4 from "../../assets/images/bank-4.png";
|
||||
import Layout from "../Partials/Layout";
|
||||
import CurrencyStaticsSection from "./CurrencyStaticsSection";
|
||||
import CurrentBalanceWidget from "./CurrentBalanceWidget";
|
||||
import InvestmentSection from "./InvestmentSection";
|
||||
import RecentTransactionWidget from "./RecentTransactionWidget";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
import WalletItemCard from "./WalletItemCard";
|
||||
|
||||
export default function WalletBox({wallet, coupon}) {
|
||||
return (
|
||||
<>
|
||||
|
||||
<div className="my-wallet-wrapper w-full mb-10">
|
||||
<div className="main-wrapper w-full">
|
||||
<div className="balance-inquery w-full lg:h-[436px] lg:flex lg:space-x-11 mb-11">
|
||||
{wallet.loading ?
|
||||
<LoadingSpinner size='16' color='sky-blue' />
|
||||
:
|
||||
wallet.data.length ?
|
||||
wallet.data.map((item, index)=> (
|
||||
<div className="lg:w-1/2 h-full mb-10 lg:mb-0">
|
||||
<WalletItemCard walletItem={item} />
|
||||
</div>
|
||||
)) : ''
|
||||
}
|
||||
|
||||
{/*<div className="flex-1">*/}
|
||||
{/* <CurrentBalanceWidget />*/}
|
||||
{/*</div>*/}
|
||||
{/* <div className="flex-1">*/}
|
||||
{/* <div className="my-wallets w-full h-full bg-white dark:bg-dark-white rounded-lg p-6">*/}
|
||||
{/* <div className="mb-4">*/}
|
||||
{/* <h1 className="text-xl font-bold tracking-wide text-dark-gray dark:text-white">*/}
|
||||
{/* My Wallet*/}
|
||||
{/* </h1>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="content-area">*/}
|
||||
{/* <div className="flex justify-between items-center mb-6">*/}
|
||||
{/* <div className="flex space-x-5 items-center">*/}
|
||||
{/* <div className="account-name flex space-x-4 items-center">*/}
|
||||
{/* <div className="icon w-14 h-14 transition duration-300 ease-in-out rounded-full flex justify-center items-center bg-light-purple dark:bg-dark-light-purple ">*/}
|
||||
{/* <img src={bank1} alt="" />*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="name">*/}
|
||||
{/* <p className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">*/}
|
||||
{/* MetaMask*/}
|
||||
{/* </p>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="flex space-x-5 items-center">*/}
|
||||
{/* <div>*/}
|
||||
{/* <p className="text-xl font-bold text-dark-gray dark:text-white text-right mb-3">*/}
|
||||
{/* $734.79*/}
|
||||
{/* </p>*/}
|
||||
{/* <p className="text-sm text-thin-light-gray">*/}
|
||||
{/* New Add*/}
|
||||
{/* <span className="text-light-green ml-1">*/}
|
||||
{/* +324.75*/}
|
||||
{/* </span>*/}
|
||||
{/* </p>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div>*/}
|
||||
{/*<span className="dark:text-thin-light-gray text-[#374557]">*/}
|
||||
{/* <svg*/}
|
||||
{/* width="6"*/}
|
||||
{/* height="26"*/}
|
||||
{/* viewBox="0 0 6 26"*/}
|
||||
{/* fill="none"*/}
|
||||
{/* className="fill-current"*/}
|
||||
{/* xmlns="http://www.w3.org/2000/svg"*/}
|
||||
{/* >*/}
|
||||
{/* <circle cx="3" cy="3" r="3" fillOpacity="0.6" />*/}
|
||||
{/* <circle*/}
|
||||
{/* cx="3"*/}
|
||||
{/* cy="12.75"*/}
|
||||
{/* r="3"*/}
|
||||
{/* fillOpacity="0.6"*/}
|
||||
{/* />*/}
|
||||
{/* <circle*/}
|
||||
{/* cx="3"*/}
|
||||
{/* cy="22.5"*/}
|
||||
{/* r="3"*/}
|
||||
{/* fillOpacity="0.6"*/}
|
||||
{/* />*/}
|
||||
{/* </svg>*/}
|
||||
{/*</span>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="flex justify-between items-center mb-6">*/}
|
||||
{/* <div className="flex space-x-5 items-center">*/}
|
||||
{/* <div className="account-name flex space-x-4 items-center">*/}
|
||||
{/* <div className="icon w-14 h-14 transition duration-300 ease-in-out rounded-full flex justify-center items-center bg-light-purple dark:bg-dark-light-purple ">*/}
|
||||
{/* <img src={bank2} alt="" />*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="name">*/}
|
||||
{/* <p className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">*/}
|
||||
{/* Coinbase Wallet*/}
|
||||
{/* </p>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="flex space-x-5 items-center">*/}
|
||||
{/* <div>*/}
|
||||
{/* <p className="text-xl font-bold text-dark-gray dark:text-white text-right mb-3">*/}
|
||||
{/* $734.79*/}
|
||||
{/* </p>*/}
|
||||
{/* <p className="text-sm text-thin-light-gray">*/}
|
||||
{/* New Add*/}
|
||||
{/* <span className="text-light-green ml-1">*/}
|
||||
{/* +324.75*/}
|
||||
{/* </span>*/}
|
||||
{/* </p>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div>*/}
|
||||
{/*<span className="dark:text-thin-light-gray text-[#374557]">*/}
|
||||
{/* <svg*/}
|
||||
{/* width="6"*/}
|
||||
{/* height="26"*/}
|
||||
{/* viewBox="0 0 6 26"*/}
|
||||
{/* fill="none"*/}
|
||||
{/* className="fill-current"*/}
|
||||
{/* xmlns="http://www.w3.org/2000/svg"*/}
|
||||
{/* >*/}
|
||||
{/* <circle cx="3" cy="3" r="3" fillOpacity="0.6" />*/}
|
||||
{/* <circle*/}
|
||||
{/* cx="3"*/}
|
||||
{/* cy="12.75"*/}
|
||||
{/* r="3"*/}
|
||||
{/* fillOpacity="0.6"*/}
|
||||
{/* />*/}
|
||||
{/* <circle*/}
|
||||
{/* cx="3"*/}
|
||||
{/* cy="22.5"*/}
|
||||
{/* r="3"*/}
|
||||
{/* fillOpacity="0.6"*/}
|
||||
{/* />*/}
|
||||
{/* </svg>*/}
|
||||
{/*</span>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="flex justify-between items-center mb-6">*/}
|
||||
{/* <div className="flex space-x-5 items-center">*/}
|
||||
{/* <div className="account-name flex space-x-4 items-center">*/}
|
||||
{/* <div className="icon w-14 h-14 transition duration-300 ease-in-out rounded-full flex justify-center items-center bg-light-purple dark:bg-dark-light-purple ">*/}
|
||||
{/* <img src={bank3} alt="" />*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="name">*/}
|
||||
{/* <p className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">*/}
|
||||
{/* Bitski*/}
|
||||
{/* </p>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="flex space-x-5 items-center">*/}
|
||||
{/* <div>*/}
|
||||
{/* <p className="text-xl font-bold text-dark-gray dark:text-white text-right mb-3">*/}
|
||||
{/* $734.79*/}
|
||||
{/* </p>*/}
|
||||
{/* <p className="text-sm text-thin-light-gray">*/}
|
||||
{/* New Add*/}
|
||||
{/* <span className="text-light-green ml-1">*/}
|
||||
{/* +324.75*/}
|
||||
{/* </span>*/}
|
||||
{/* </p>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div>*/}
|
||||
{/*<span className="dark:text-thin-light-gray text-[#374557]">*/}
|
||||
{/* <svg*/}
|
||||
{/* width="6"*/}
|
||||
{/* height="26"*/}
|
||||
{/* viewBox="0 0 6 26"*/}
|
||||
{/* fill="none"*/}
|
||||
{/* className="fill-current"*/}
|
||||
{/* xmlns="http://www.w3.org/2000/svg"*/}
|
||||
{/* >*/}
|
||||
{/* <circle cx="3" cy="3" r="3" fillOpacity="0.6" />*/}
|
||||
{/* <circle*/}
|
||||
{/* cx="3"*/}
|
||||
{/* cy="12.75"*/}
|
||||
{/* r="3"*/}
|
||||
{/* fillOpacity="0.6"*/}
|
||||
{/* />*/}
|
||||
{/* <circle*/}
|
||||
{/* cx="3"*/}
|
||||
{/* cy="22.5"*/}
|
||||
{/* r="3"*/}
|
||||
{/* fillOpacity="0.6"*/}
|
||||
{/* />*/}
|
||||
{/* </svg>*/}
|
||||
{/*</span>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="flex justify-between items-center mb-6">*/}
|
||||
{/* <div className="flex space-x-5 items-center">*/}
|
||||
{/* <div className="account-name flex space-x-4 items-center">*/}
|
||||
{/* <div className="icon w-14 h-14 transition duration-300 ease-in-out rounded-full flex justify-center items-center bg-light-purple dark:bg-dark-light-purple ">*/}
|
||||
{/* <img src={bank4} alt="" />*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="name">*/}
|
||||
{/* <p className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">*/}
|
||||
{/* WalletConnect*/}
|
||||
{/* </p>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="flex space-x-5 items-center">*/}
|
||||
{/* <div>*/}
|
||||
{/* <p className="text-xl font-bold text-dark-gray dark:text-white text-right mb-3">*/}
|
||||
{/* $734.79*/}
|
||||
{/* </p>*/}
|
||||
{/* <p className="text-sm text-thin-light-gray">*/}
|
||||
{/* New Add*/}
|
||||
{/* <span className="text-light-green ml-1">*/}
|
||||
{/* +324.75*/}
|
||||
{/* </span>*/}
|
||||
{/* </p>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div>*/}
|
||||
{/*<span className="dark:text-thin-light-gray text-[#374557]">*/}
|
||||
{/* <svg*/}
|
||||
{/* width="6"*/}
|
||||
{/* height="26"*/}
|
||||
{/* viewBox="0 0 6 26"*/}
|
||||
{/* fill="none"*/}
|
||||
{/* className="fill-current"*/}
|
||||
{/* xmlns="http://www.w3.org/2000/svg"*/}
|
||||
{/* >*/}
|
||||
{/* <circle cx="3" cy="3" r="3" fillOpacity="0.6" />*/}
|
||||
{/* <circle*/}
|
||||
{/* cx="3"*/}
|
||||
{/* cy="12.75"*/}
|
||||
{/* r="3"*/}
|
||||
{/* fillOpacity="0.6"*/}
|
||||
{/* />*/}
|
||||
{/* <circle*/}
|
||||
{/* cx="3"*/}
|
||||
{/* cy="22.5"*/}
|
||||
{/* r="3"*/}
|
||||
{/* fillOpacity="0.6"*/}
|
||||
{/* />*/}
|
||||
{/* </svg>*/}
|
||||
{/*</span>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
</div>
|
||||
{/* flex space-x-11 */}
|
||||
{/*<div className="recent-and-investment grid lg:grid-cols-2 grid-cols-1 2xl:gap-[40px] xl:gap-7 gap-4 lg:h-[416px] w-full justify-between">*/}
|
||||
{/* <div className=" h-full">*/}
|
||||
{/* <RecentTransactionWidget />*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className=" h-full">*/}
|
||||
{/* <InvestmentSection />*/}
|
||||
{/* </div>*/}
|
||||
{/*</div>*/}
|
||||
</div>
|
||||
export default function WalletBox({ wallet, coupon, payment }) {
|
||||
return (
|
||||
<>
|
||||
<div className="my-wallet-wrapper w-full mb-10">
|
||||
<div className="main-wrapper w-full">
|
||||
<div className="balance-inquery w-full lg:grid grid-cols-[repeat(auto-fill,_minmax(325px,_1fr))] gap-5 mb-11 h-[22rem]">
|
||||
{wallet.loading ? (
|
||||
<div className="w-full h-full flex items-center justify-center">
|
||||
<LoadingSpinner size="16" color="sky-blue" />
|
||||
</div>
|
||||
) : wallet.data.length ? (
|
||||
wallet.data.map((item, index) => (
|
||||
<div className="lg:w-full h-full mb-10 lg:mb-0">
|
||||
<WalletItemCard walletItem={item} payment={payment} />
|
||||
</div>
|
||||
))
|
||||
) : null}
|
||||
|
||||
</>
|
||||
);
|
||||
{/*<div className="flex-1">*/}
|
||||
{/* <CurrentBalanceWidget />*/}
|
||||
{/*</div>*/}
|
||||
{/* <div className="flex-1">*/}
|
||||
{/* <div className="my-wallets w-full h-full bg-white dark:bg-dark-white rounded-lg p-6">*/}
|
||||
{/* <div className="mb-4">*/}
|
||||
{/* <h1 className="text-xl font-bold tracking-wide text-dark-gray dark:text-white">*/}
|
||||
{/* My Wallet*/}
|
||||
{/* </h1>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="content-area">*/}
|
||||
{/* <div className="flex justify-between items-center mb-6">*/}
|
||||
{/* <div className="flex space-x-5 items-center">*/}
|
||||
{/* <div className="account-name flex space-x-4 items-center">*/}
|
||||
{/* <div className="icon w-14 h-14 transition duration-300 ease-in-out rounded-full flex justify-center items-center bg-light-purple dark:bg-dark-light-purple ">*/}
|
||||
{/* <img src={bank1} alt="" />*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="name">*/}
|
||||
{/* <p className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">*/}
|
||||
{/* MetaMask*/}
|
||||
{/* </p>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="flex space-x-5 items-center">*/}
|
||||
{/* <div>*/}
|
||||
{/* <p className="text-xl font-bold text-dark-gray dark:text-white text-right mb-3">*/}
|
||||
{/* $734.79*/}
|
||||
{/* </p>*/}
|
||||
{/* <p className="text-sm text-thin-light-gray">*/}
|
||||
{/* New Add*/}
|
||||
{/* <span className="text-light-green ml-1">*/}
|
||||
{/* +324.75*/}
|
||||
{/* </span>*/}
|
||||
{/* </p>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div>*/}
|
||||
{/*<span className="dark:text-thin-light-gray text-[#374557]">*/}
|
||||
{/* <svg*/}
|
||||
{/* width="6"*/}
|
||||
{/* height="26"*/}
|
||||
{/* viewBox="0 0 6 26"*/}
|
||||
{/* fill="none"*/}
|
||||
{/* className="fill-current"*/}
|
||||
{/* xmlns="http://www.w3.org/2000/svg"*/}
|
||||
{/* >*/}
|
||||
{/* <circle cx="3" cy="3" r="3" fillOpacity="0.6" />*/}
|
||||
{/* <circle*/}
|
||||
{/* cx="3"*/}
|
||||
{/* cy="12.75"*/}
|
||||
{/* r="3"*/}
|
||||
{/* fillOpacity="0.6"*/}
|
||||
{/* />*/}
|
||||
{/* <circle*/}
|
||||
{/* cx="3"*/}
|
||||
{/* cy="22.5"*/}
|
||||
{/* r="3"*/}
|
||||
{/* fillOpacity="0.6"*/}
|
||||
{/* />*/}
|
||||
{/* </svg>*/}
|
||||
{/*</span>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="flex justify-between items-center mb-6">*/}
|
||||
{/* <div className="flex space-x-5 items-center">*/}
|
||||
{/* <div className="account-name flex space-x-4 items-center">*/}
|
||||
{/* <div className="icon w-14 h-14 transition duration-300 ease-in-out rounded-full flex justify-center items-center bg-light-purple dark:bg-dark-light-purple ">*/}
|
||||
{/* <img src={bank2} alt="" />*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="name">*/}
|
||||
{/* <p className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">*/}
|
||||
{/* Coinbase Wallet*/}
|
||||
{/* </p>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="flex space-x-5 items-center">*/}
|
||||
{/* <div>*/}
|
||||
{/* <p className="text-xl font-bold text-dark-gray dark:text-white text-right mb-3">*/}
|
||||
{/* $734.79*/}
|
||||
{/* </p>*/}
|
||||
{/* <p className="text-sm text-thin-light-gray">*/}
|
||||
{/* New Add*/}
|
||||
{/* <span className="text-light-green ml-1">*/}
|
||||
{/* +324.75*/}
|
||||
{/* </span>*/}
|
||||
{/* </p>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div>*/}
|
||||
{/*<span className="dark:text-thin-light-gray text-[#374557]">*/}
|
||||
{/* <svg*/}
|
||||
{/* width="6"*/}
|
||||
{/* height="26"*/}
|
||||
{/* viewBox="0 0 6 26"*/}
|
||||
{/* fill="none"*/}
|
||||
{/* className="fill-current"*/}
|
||||
{/* xmlns="http://www.w3.org/2000/svg"*/}
|
||||
{/* >*/}
|
||||
{/* <circle cx="3" cy="3" r="3" fillOpacity="0.6" />*/}
|
||||
{/* <circle*/}
|
||||
{/* cx="3"*/}
|
||||
{/* cy="12.75"*/}
|
||||
{/* r="3"*/}
|
||||
{/* fillOpacity="0.6"*/}
|
||||
{/* />*/}
|
||||
{/* <circle*/}
|
||||
{/* cx="3"*/}
|
||||
{/* cy="22.5"*/}
|
||||
{/* r="3"*/}
|
||||
{/* fillOpacity="0.6"*/}
|
||||
{/* />*/}
|
||||
{/* </svg>*/}
|
||||
{/*</span>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="flex justify-between items-center mb-6">*/}
|
||||
{/* <div className="flex space-x-5 items-center">*/}
|
||||
{/* <div className="account-name flex space-x-4 items-center">*/}
|
||||
{/* <div className="icon w-14 h-14 transition duration-300 ease-in-out rounded-full flex justify-center items-center bg-light-purple dark:bg-dark-light-purple ">*/}
|
||||
{/* <img src={bank3} alt="" />*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="name">*/}
|
||||
{/* <p className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">*/}
|
||||
{/* Bitski*/}
|
||||
{/* </p>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="flex space-x-5 items-center">*/}
|
||||
{/* <div>*/}
|
||||
{/* <p className="text-xl font-bold text-dark-gray dark:text-white text-right mb-3">*/}
|
||||
{/* $734.79*/}
|
||||
{/* </p>*/}
|
||||
{/* <p className="text-sm text-thin-light-gray">*/}
|
||||
{/* New Add*/}
|
||||
{/* <span className="text-light-green ml-1">*/}
|
||||
{/* +324.75*/}
|
||||
{/* </span>*/}
|
||||
{/* </p>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div>*/}
|
||||
{/*<span className="dark:text-thin-light-gray text-[#374557]">*/}
|
||||
{/* <svg*/}
|
||||
{/* width="6"*/}
|
||||
{/* height="26"*/}
|
||||
{/* viewBox="0 0 6 26"*/}
|
||||
{/* fill="none"*/}
|
||||
{/* className="fill-current"*/}
|
||||
{/* xmlns="http://www.w3.org/2000/svg"*/}
|
||||
{/* >*/}
|
||||
{/* <circle cx="3" cy="3" r="3" fillOpacity="0.6" />*/}
|
||||
{/* <circle*/}
|
||||
{/* cx="3"*/}
|
||||
{/* cy="12.75"*/}
|
||||
{/* r="3"*/}
|
||||
{/* fillOpacity="0.6"*/}
|
||||
{/* />*/}
|
||||
{/* <circle*/}
|
||||
{/* cx="3"*/}
|
||||
{/* cy="22.5"*/}
|
||||
{/* r="3"*/}
|
||||
{/* fillOpacity="0.6"*/}
|
||||
{/* />*/}
|
||||
{/* </svg>*/}
|
||||
{/*</span>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="flex justify-between items-center mb-6">*/}
|
||||
{/* <div className="flex space-x-5 items-center">*/}
|
||||
{/* <div className="account-name flex space-x-4 items-center">*/}
|
||||
{/* <div className="icon w-14 h-14 transition duration-300 ease-in-out rounded-full flex justify-center items-center bg-light-purple dark:bg-dark-light-purple ">*/}
|
||||
{/* <img src={bank4} alt="" />*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="name">*/}
|
||||
{/* <p className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">*/}
|
||||
{/* WalletConnect*/}
|
||||
{/* </p>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className="flex space-x-5 items-center">*/}
|
||||
{/* <div>*/}
|
||||
{/* <p className="text-xl font-bold text-dark-gray dark:text-white text-right mb-3">*/}
|
||||
{/* $734.79*/}
|
||||
{/* </p>*/}
|
||||
{/* <p className="text-sm text-thin-light-gray">*/}
|
||||
{/* New Add*/}
|
||||
{/* <span className="text-light-green ml-1">*/}
|
||||
{/* +324.75*/}
|
||||
{/* </span>*/}
|
||||
{/* </p>*/}
|
||||
{/* </div>*/}
|
||||
{/* <div>*/}
|
||||
{/*<span className="dark:text-thin-light-gray text-[#374557]">*/}
|
||||
{/* <svg*/}
|
||||
{/* width="6"*/}
|
||||
{/* height="26"*/}
|
||||
{/* viewBox="0 0 6 26"*/}
|
||||
{/* fill="none"*/}
|
||||
{/* className="fill-current"*/}
|
||||
{/* xmlns="http://www.w3.org/2000/svg"*/}
|
||||
{/* >*/}
|
||||
{/* <circle cx="3" cy="3" r="3" fillOpacity="0.6" />*/}
|
||||
{/* <circle*/}
|
||||
{/* cx="3"*/}
|
||||
{/* cy="12.75"*/}
|
||||
{/* r="3"*/}
|
||||
{/* fillOpacity="0.6"*/}
|
||||
{/* />*/}
|
||||
{/* <circle*/}
|
||||
{/* cx="3"*/}
|
||||
{/* cy="22.5"*/}
|
||||
{/* r="3"*/}
|
||||
{/* fillOpacity="0.6"*/}
|
||||
{/* />*/}
|
||||
{/* </svg>*/}
|
||||
{/*</span>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
</div>
|
||||
{/* flex space-x-11 */}
|
||||
{/*<div className="recent-and-investment grid lg:grid-cols-2 grid-cols-1 2xl:gap-[40px] xl:gap-7 gap-4 lg:h-[416px] w-full justify-between">*/}
|
||||
{/* <div className=" h-full">*/}
|
||||
{/* <RecentTransactionWidget />*/}
|
||||
{/* </div>*/}
|
||||
{/* <div className=" h-full">*/}
|
||||
{/* <InvestmentSection />*/}
|
||||
{/* </div>*/}
|
||||
{/*</div>*/}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,66 +1,87 @@
|
||||
import React, {useState} from 'react'
|
||||
import React, { useState } from "react";
|
||||
|
||||
import PaginatedList from '../../Pagination/PaginatedList';
|
||||
import {handlePagingFunc} from '../../Pagination/HandlePagination';
|
||||
import PaginatedList from "../../Pagination/PaginatedList";
|
||||
import { handlePagingFunc } from "../../Pagination/HandlePagination";
|
||||
|
||||
function RecentActivityTable({payment}) {
|
||||
function RecentActivityTable({ payment }) {
|
||||
const [currentPage, setCurrentPage] = useState(0);
|
||||
const indexOfFirstItem = Number(currentPage);
|
||||
const indexOfLastItem =
|
||||
Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
||||
const currentActivity = payment?.data?.slice(
|
||||
indexOfFirstItem,
|
||||
indexOfLastItem
|
||||
);
|
||||
|
||||
const [currentPage, setCurrentPage] = useState(0);
|
||||
const indexOfFirstItem = Number(currentPage);
|
||||
const indexOfLastItem = Number(indexOfFirstItem)+Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
||||
const currentActivity = payment?.data?.slice(indexOfFirstItem, indexOfLastItem);
|
||||
|
||||
const handlePagination = (e) => {
|
||||
handlePagingFunc(e,setCurrentPage)
|
||||
}
|
||||
const handlePagination = (e) => {
|
||||
handlePagingFunc(e, setCurrentPage);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className='flex flex-col justify-between min-h-[500px]'>
|
||||
<table className="wallet-activity w-full table-auto border-collapse text-left">
|
||||
<thead className='border-b-2'>
|
||||
<tr className='text-slate-600'>
|
||||
<div className="flex flex-col justify-between min-h-[500px]">
|
||||
<table className="wallet-activity w-full table-auto border-collapse text-left">
|
||||
<thead className="border-b-2">
|
||||
<tr className="text-slate-600">
|
||||
<th className="p-2">Date</th>
|
||||
<th className="p-4">Trx.</th>
|
||||
<th className="p-4">Trx.</th>
|
||||
<th className="p-2">Amnt./Fee</th>
|
||||
<th className="p-2">Status</th>
|
||||
</tr>
|
||||
</tr>
|
||||
</thead>
|
||||
{payment.data.length ?
|
||||
(
|
||||
<tbody>
|
||||
{payment?.data?.length > 0 ? (
|
||||
<tbody>
|
||||
{currentActivity.map((item, index) => (
|
||||
<tr key={index} className='text-slate-500'>
|
||||
<tr key={index} className="text-slate-500">
|
||||
<td className="p-2">{item.trx_date}</td>
|
||||
<td className="p-4" dangerouslySetInnerHTML={{__html:item.recipient}}></td>
|
||||
<td className="p-2">{item.amount}<br />{item.fee}</td>
|
||||
<td
|
||||
className="p-4"
|
||||
dangerouslySetInnerHTML={{ __html: item.recipient }}
|
||||
></td>
|
||||
<td className="p-2">
|
||||
{item.amount}
|
||||
<br />
|
||||
{item.fee}
|
||||
</td>
|
||||
<td className="p-2">{item.status}</td>
|
||||
</tr>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
)
|
||||
:
|
||||
payment.error ?
|
||||
(
|
||||
<tbody>
|
||||
<tr className='text-slate-500'>
|
||||
<td className="p-2" colSpan={4}>Opps! an error occurred. Please try again!</td>
|
||||
</tbody>
|
||||
) : payment?.error ? (
|
||||
<tbody>
|
||||
<tr className="text-slate-500">
|
||||
<td className="p-2" colSpan={4}>
|
||||
Opps! an error occurred. Please try again!
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
)
|
||||
:
|
||||
<tbody>
|
||||
<tr className='text-slate-500'>
|
||||
<td className="p-2" colSpan={4}>No Payment History Found!</td>
|
||||
</tbody>
|
||||
) : (
|
||||
<tbody>
|
||||
<tr className="text-slate-500">
|
||||
<td className="p-2" colSpan={4}>
|
||||
No Payment History Found!
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
}
|
||||
</table>
|
||||
</tbody>
|
||||
)}
|
||||
</table>
|
||||
|
||||
{/* PAGINATION BUTTON */}
|
||||
<PaginatedList onClick={handlePagination} prev={currentPage == 0 ? true : false} next={currentPage+Number(process.env.REACT_APP_ITEM_PER_PAGE) >= payment?.data?.length ? true : false} data={payment?.data} start={indexOfFirstItem} stop={indexOfLastItem} />
|
||||
{/* END OF PAGINATION BUTTON */}
|
||||
{/* PAGINATION BUTTON */}
|
||||
<PaginatedList
|
||||
onClick={handlePagination}
|
||||
prev={currentPage == 0 ? true : false}
|
||||
next={
|
||||
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
|
||||
payment?.data?.length
|
||||
? true
|
||||
: false
|
||||
}
|
||||
data={payment?.data}
|
||||
start={indexOfFirstItem}
|
||||
stop={indexOfLastItem}
|
||||
/>
|
||||
{/* END OF PAGINATION BUTTON */}
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export default RecentActivityTable
|
||||
export default RecentActivityTable;
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { Link, useLocation, useNavigate } 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";
|
||||
import bank3 from "../../assets/images/bank-3.png";
|
||||
import bank4 from "../../assets/images/bank-4.png";
|
||||
// import bank1 from "../../assets/images/bank-1.png";
|
||||
// import bank2 from "../../assets/images/bank-2.png";
|
||||
// import bank3 from "../../assets/images/bank-3.png";
|
||||
// import bank4 from "../../assets/images/bank-4.png";
|
||||
import Accordion from "../Helpers/Accordion";
|
||||
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
||||
import localImgLoad from "../../lib/localImgLoad";
|
||||
|
||||
export default function WalletHeader(props) {
|
||||
// debugger;
|
||||
@@ -41,30 +42,35 @@ export default function WalletHeader(props) {
|
||||
<ul>
|
||||
{props.myWalletList &&
|
||||
props.myWalletList?.result_list?.length > 0 &&
|
||||
props.myWalletList.result_list.map((value, index) => (
|
||||
<li
|
||||
key={index}
|
||||
className="content-item py-4 border-b dark:border-[#5356fb29] border-light-purple hover:border-purple dark:hover:border-purple"
|
||||
>
|
||||
<div className="sm:flex justify-between items-center">
|
||||
<div className="account-name flex space-x-4 items-center mb-2 sm:mb-0">
|
||||
<div className="icon w-14 h-14 transition duration-300 ease-in-out rounded-full flex justify-center items-center bg-light-purple dark:bg-dark-light-purple ">
|
||||
<img src={bank1} alt="" />
|
||||
props.myWalletList.result_list.map((value, index) =>
|
||||
{
|
||||
let image = value.code ? `${value.code.toLocaleLowerCase()}.svg` : 'default.png'
|
||||
return(
|
||||
<li
|
||||
key={index}
|
||||
className="content-item py-4 border-b dark:border-[#5356fb29] border-light-purple hover:border-purple dark:hover:border-purple"
|
||||
>
|
||||
<div className="sm:flex justify-between items-center">
|
||||
<div className="account-name flex space-x-4 items-center mb-2 sm:mb-0">
|
||||
<div className="icon w-14 h-14 transition duration-300 ease-in-out rounded-full flex justify-center items-center bg-light-purple dark:bg-dark-light-purple ">
|
||||
<img src={localImgLoad(`images/currency/${image}`)} className="w-14 h-14" alt="" />
|
||||
</div>
|
||||
<div className="name">
|
||||
<p className="text-base text-dark-gray dark:text-white font-medium">
|
||||
{value.description}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="name">
|
||||
<p className="text-base text-dark-gray dark:text-white font-medium">
|
||||
{value.description}
|
||||
<div>
|
||||
<p className="eth text-xl font-bold text-purple">
|
||||
{PriceFormatter(value.amount * 0.01, value.code)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="eth text-xl font-bold text-purple">
|
||||
{PriceFormatter(value.amount * 0.01, value.code)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
</li>
|
||||
)
|
||||
}
|
||||
)}
|
||||
|
||||
{/*<li className="content-item py-4 border-b dark:border-[#5356fb29] border-light-purple hover:border-purple dark:hover:border-purple">*/}
|
||||
{/* <div className="sm:flex justify-between items-center">*/}
|
||||
|
||||
@@ -1,72 +1,101 @@
|
||||
import React, { useState } from "react";
|
||||
import background from "../../assets/images/bg-sky-blue.jpg" //shape/balance-bg.svg";
|
||||
import {PriceFormatter} from "../Helpers/PriceFormatter";
|
||||
import {Link} from "react-router-dom";
|
||||
import { useSelector } from "react-redux";
|
||||
import background from "../../assets/images/bg-sky-blue.jpg"; //shape/balance-bg.svg";
|
||||
import localImgLoad from "../../lib/localImgLoad";
|
||||
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
||||
import CreditPopup from "./Popup/CreditPopup";
|
||||
import WalletAction from "./WalletAction";
|
||||
|
||||
export default function WalletItemCard({walletItem}) {
|
||||
const [eth] = useState(90);
|
||||
const [btc] = useState(85);
|
||||
const [ltc] = useState(20);
|
||||
return (
|
||||
<div
|
||||
className="current-balance-widget w-full h-full rounded-2xl overflow-hidden flex flex-col justify-between px-8 py-9"
|
||||
style={{
|
||||
background: `url(${background}) 0% 0% / cover no-repeat`,
|
||||
}}
|
||||
>
|
||||
<div className="wallet flex justify-between">
|
||||
<div className="w-[100px] h-[100px] rounded-full bg-[#485199] flex justify-center items-center">
|
||||
<div>
|
||||
<p className="text-26 font-bold text-white tracking-wide text-center">
|
||||
.
|
||||
</p>
|
||||
<p className="text-lg text-white tracking-wide text-center">
|
||||
{walletItem.code}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
{/*<p className="text-26 font-bold tracking-wide text-white text-right">*/}
|
||||
{/* 6,572.00*/}
|
||||
{/*</p>*/}
|
||||
{/*<p className="tracking-wide text-white text-lg opacity-[70%]">*/}
|
||||
{/* Total Transactions*/}
|
||||
{/*</p>*/}
|
||||
</div>
|
||||
</div>
|
||||
<div className="balance">
|
||||
<p className="text-lg text-white opacity-[70%] tracking-wide mb-6">
|
||||
Current Balance
|
||||
</p>
|
||||
<p className="text-[44px] font-bold text-white tracking-wide leading-10 mb-2">
|
||||
{walletItem.amount * 0.01} {walletItem.code}
|
||||
</p>
|
||||
<p className="text-lg text-white tracking-wide">
|
||||
HOLDINGS : {PriceFormatter(walletItem.escrow * 0.01, walletItem.code)}
|
||||
{/*<span className="text-light-green">(11.5%)</span>*/}
|
||||
</p>
|
||||
</div>
|
||||
<div className="counters flex space-x-16">
|
||||
<div>
|
||||
{
|
||||
walletItem.action_type != 'AC_AD_FD_ONLY' ?
|
||||
<Link to='transfer-fund' className='px-2 py-1 flex items-center gap-2 user-balance cursor-pointer h-[40px] rounded-full relative bg-purple lg:text-xl text-lg font-bold text-white'>Transfer</Link>:''
|
||||
}
|
||||
</div>
|
||||
<div>
|
||||
<Link to='add-fund' state={{currency:walletItem.description}} className='px-2 py-1 flex items-center gap-2 user-balance cursor-pointer h-[40px] rounded-full relative bg-white lg:text-xl text-lg font-bold'>
|
||||
<span className="">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="38"
|
||||
height="38" viewBox="0 0 42 42" fill="none"><path
|
||||
d="M21 0C16.8466 0 12.7865 1.23163 9.33303 3.53914C5.8796 5.84665 3.18798 9.1264 1.59854 12.9636C0.00909901 16.8009 -0.406771 21.0233 0.403518 25.0969C1.21381 29.1705 3.21386 32.9123 6.15077 35.8492C9.08767 38.7861 12.8295 40.7862 16.9031 41.5965C20.9767 42.4068 25.1991 41.9909 29.0364 40.4015C32.8736 38.812 36.1534 36.1204 38.4609 32.667C40.7684 29.2135 42 25.1534 42 21C41.994 15.4323 39.7796 10.0944 35.8426 6.15741C31.9056 2.22045 26.5677 0.00602189 21 0ZM28 22.75H22.75V28C22.75 28.4641 22.5656 28.9092 22.2374 29.2374C21.9093 29.5656 21.4641 29.75 21 29.75C20.5359 29.75 20.0908 29.5656 19.7626 29.2374C19.4344 28.9092 19.25 28.4641 19.25 28V22.75H14C13.5359 22.75 13.0908 22.5656 12.7626 22.2374C12.4344 21.9092 12.25 21.4641 12.25 21C12.25 20.5359 12.4344 20.0907 12.7626 19.7626C13.0908 19.4344 13.5359 19.25 14 19.25H19.25V14C19.25 13.5359 19.4344 13.0908 19.7626 12.7626C20.0908 12.4344 20.5359 12.25 21 12.25C21.4641 12.25 21.9093 12.4344 22.2374 12.7626C22.5656 13.0908 22.75 13.5359 22.75 14V19.25H28C28.4641 19.25 28.9093 19.4344 29.2374 19.7626C29.5656 20.0907 29.75 20.5359 29.75 21C29.75 21.4641 29.5656 21.9092 29.2374 22.2374C28.9093 22.5656 28.4641 22.75 28 22.75Z"
|
||||
fill="white"></path>
|
||||
</svg>
|
||||
</span>
|
||||
<span className='text-black'>Add Credit</span>
|
||||
</Link>
|
||||
</div>
|
||||
export default function WalletItemCard({ walletItem, payment }) {
|
||||
// const [eth] = useState(90);
|
||||
// const [btc] = useState(85);
|
||||
// const [ltc] = useState(20);
|
||||
|
||||
const { userDetails } = useSelector((state) => state?.userDetails);
|
||||
let accountType = userDetails?.account_type == "FAMILY";
|
||||
|
||||
// Credit popup
|
||||
const [creditPopup, setCreditPopup] = useState({ show: false, data: {} });
|
||||
const openPopUp = (value) => {
|
||||
setCreditPopup({
|
||||
show: true,
|
||||
data: { ...value },
|
||||
});
|
||||
};
|
||||
|
||||
const closePopUp = () => {
|
||||
setCreditPopup({ show: false, data: {} });
|
||||
};
|
||||
|
||||
let image = walletItem.code
|
||||
? `${walletItem.code.toLocaleLowerCase()}.svg`
|
||||
: "default.png"; // HOLDS THE VALUE NAME PROPERTY FOR IMAGE ICON
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className={`current-balance-widget w-full h-full rounded-2xl overflow-hidden flex flex-col items-center gap-2 px-8 pt-9 pb-20`}
|
||||
style={{
|
||||
background: `url(${background}) 0% 0% / cover no-repeat`,
|
||||
}}
|
||||
>
|
||||
{/* <div className="w-[350px]"> */}
|
||||
<div className="wallet w-full flex justify-between items-start gap-3">
|
||||
<div className="min-w-[100px] min-h-[100px] max-w-[100px] max-h-[100px] rounded-full bg-[#e3e3e3] flex justify-center items-center">
|
||||
<img
|
||||
src={localImgLoad(`images/currency/${image}`)}
|
||||
className="w-full h-full"
|
||||
alt="curreny-icon"
|
||||
/>
|
||||
</div>
|
||||
<div className="balance w-full mt-2 flex justify-center">
|
||||
<div className="">
|
||||
<p className="text-lg text-white opacity-[70%] tracking-wide mb-6">
|
||||
Current Balance
|
||||
</p>
|
||||
<p className="text-[44px] font-bold text-white tracking-wide leading-10 mb-2">
|
||||
{PriceFormatter(
|
||||
walletItem.amount * 0.01,
|
||||
walletItem.code,
|
||||
undefined,
|
||||
"text-[2rem]"
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
<p className="my-5 text-lg text-white tracking-wide flex justify-center items-center gap-2">
|
||||
HOLDINGS :{" "}
|
||||
<span className="mt-1">
|
||||
{PriceFormatter(
|
||||
walletItem.escrow * 0.01,
|
||||
walletItem.code,
|
||||
undefined,
|
||||
"text-[2rem]"
|
||||
)}
|
||||
</span>
|
||||
</p>
|
||||
{/* for white underline */}
|
||||
<div className="my-2 w-full h-[1px] bg-white"></div>
|
||||
|
||||
{!accountType ? (
|
||||
<WalletAction
|
||||
walletItem={walletItem}
|
||||
payment={payment}
|
||||
openPopUp={openPopUp}
|
||||
/>
|
||||
) : null}
|
||||
{/* </div> */}
|
||||
</div>
|
||||
{creditPopup.show && (
|
||||
<CreditPopup
|
||||
details={creditPopup.data}
|
||||
walletItem={walletItem}
|
||||
onClose={closePopUp}
|
||||
situation={openPopUp}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
const PaginatedList = ({ onClick, prev, next, data, start, stop }) => {
|
||||
if (data.length > process.env.REACT_APP_ITEM_PER_PAGE) {
|
||||
if (data?.length > process.env.REACT_APP_ITEM_PER_PAGE) {
|
||||
return (
|
||||
<div className="p-3 flex justify-center items-center min-h-[70px] space-x-2 border-t-2">
|
||||
{/* Render pagination buttons */}
|
||||
{!prev && (
|
||||
<button
|
||||
className={`p-2 border ${
|
||||
prev ? "border-black dark:border-white dark:text-white" : "border-transparent dark:text-white"
|
||||
prev
|
||||
? "border-black dark:border-white dark:text-white"
|
||||
: "border-transparent dark:text-white"
|
||||
} btn-shine rounded-full h-11 w-11`}
|
||||
name="prev"
|
||||
onClick={onClick}
|
||||
@@ -15,7 +17,7 @@ const PaginatedList = ({ onClick, prev, next, data, start, stop }) => {
|
||||
</button>
|
||||
)}
|
||||
|
||||
{data.map((item, index) => {
|
||||
{data?.map((item, index) => {
|
||||
if (
|
||||
index % process.env.REACT_APP_ITEM_PER_PAGE == 0 &&
|
||||
index >= start &&
|
||||
@@ -26,7 +28,9 @@ const PaginatedList = ({ onClick, prev, next, data, start, stop }) => {
|
||||
key={index}
|
||||
value={index}
|
||||
className={`p-2 border ${
|
||||
index === start ? "border-black dark:border-white dark:text-white" : "border-transparent dark:text-white"
|
||||
index === start
|
||||
? "border-black dark:border-white dark:text-white"
|
||||
: "border-transparent dark:text-white"
|
||||
} btn-shine rounded-full h-11 w-11`}
|
||||
onClick={onClick}
|
||||
name="page_num"
|
||||
@@ -43,7 +47,9 @@ const PaginatedList = ({ onClick, prev, next, data, start, stop }) => {
|
||||
{!next && (
|
||||
<button
|
||||
className={`p-2 border ${
|
||||
next ? "border-black dark:border-white dark:text-white" : "border-transparent dark:text-white"
|
||||
next
|
||||
? "border-black dark:border-white dark:text-white"
|
||||
: "border-transparent dark:text-white"
|
||||
} btn-shine rounded-full h-11 w-11`}
|
||||
name="next"
|
||||
onClick={onClick}
|
||||
|
||||
@@ -9,6 +9,7 @@ import products from "../../data/product_data.json";
|
||||
import Layout from "../Partials/Layout";
|
||||
import {
|
||||
ActivitiesTab, BlogTab,
|
||||
QuestionsTab,
|
||||
CollectionTab,
|
||||
CreatedTab,
|
||||
HiddenProductsTab,
|
||||
@@ -39,7 +40,7 @@ export default function Resources(props) {
|
||||
// Category Components
|
||||
const tabComponents = {
|
||||
blog: <BlogTab blogdata={blogItems} />,
|
||||
onsale: <OnSaleTab products={onSaleProducts} />,
|
||||
onsale: <QuestionsTab products={onSaleProducts} />,
|
||||
owned: <OwnTab products={ownProducts} />,
|
||||
created: (
|
||||
<CreatedTab marketProducts={CreatedSell} mainProducts={CreatedBits} />
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import ProductCardStyleTwo from "../../Cards/ProductCardStyleTwo";
|
||||
import DataIteration from "../../Helpers/DataIteration";
|
||||
import SearchCom from "../../Helpers/SearchCom";
|
||||
|
||||
export default function QuestionsTab({ className, products }) {
|
||||
return (
|
||||
<>
|
||||
<div className={`onsale-tab-wrapper w-full ${className || ""}`}>
|
||||
<div className="main-container w-full">
|
||||
<div className="filter-section w-full items-center sm:flex justify-between mb-6">
|
||||
{/* filter-search */}
|
||||
<div className="sm:w-1/2 w-full sm:pr-20 pr-0 mb-5 sm:mb-0">
|
||||
<SearchCom />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div className="content-section w-full-width">
|
||||
<div className="grid lg:grid-cols-3 sm:grid-cols-2 grid-cols-1 gap-[30px]">
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -5,9 +5,11 @@ import HiddenProductsTab from "./HiddenProductsTab";
|
||||
import OnSaleTab from "./OnSaleTab";
|
||||
import OwnTab from "./OwnTab";
|
||||
import BlogTab from "./BlogTab";
|
||||
import QuestionsTab from "./QuestionsTab";
|
||||
|
||||
export {
|
||||
BlogTab,
|
||||
QuestionsTab,
|
||||
ActivitiesTab,
|
||||
CollectionTab,
|
||||
CreatedTab,
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
import React, {useEffect, useState} from 'react'
|
||||
import method1 from "../../../assets/images/payment-cards/discover-card.svg";
|
||||
import LoadingSpinner from '../../Spinners/LoadingSpinner';
|
||||
import localImgLoad from '../../../lib/localImgLoad';
|
||||
|
||||
import usersService from "../../../services/UsersService";
|
||||
import { handlePagingFunc } from '../../Pagination';
|
||||
import PaginatedList from '../../Pagination/PaginatedList';
|
||||
|
||||
import DeleteCardPopout from './DeleteCardPopout';
|
||||
|
||||
function CardList() {
|
||||
const api = new usersService();
|
||||
|
||||
const [reloadCardList, setReloadCardList] = useState(false) // STATE TO DETERMINE WHEN CARD LIST RELOADS. EG: WHEN USER DELETES A CARD
|
||||
|
||||
const [cardList, setCardList] = useState({loading: true, data: []})
|
||||
|
||||
const [deleteCardModal, setDeleteCardModal] = useState({show: false, data: {}}) // STATE TO HOLD WHEN DELETE MODAL POPS UP
|
||||
const handleDeleteCardModal = () => {
|
||||
setDeleteCardModal(prev => ({...prev, show:!prev.show}))
|
||||
}
|
||||
|
||||
const [currentPage, setCurrentPage] = useState(0);
|
||||
const indexOfFirstItem = Number(currentPage);
|
||||
const indexOfLastItem =
|
||||
Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
||||
const currentCardList = cardList?.data?.slice(indexOfFirstItem, indexOfLastItem);
|
||||
|
||||
const handlePagination = (e) => {
|
||||
handlePagingFunc(e, setCurrentPage);
|
||||
};
|
||||
|
||||
useEffect(()=>{
|
||||
setCardList({loading: true, data: []})
|
||||
api.payListCard().then(res=>{
|
||||
setCardList({loading: false, data:res.data?.result_list})
|
||||
}).catch(err => {
|
||||
setCardList({loading: false, data:[]})
|
||||
console.log('ERROR', err)
|
||||
})
|
||||
},[reloadCardList])
|
||||
return (
|
||||
<div className='w-full'>
|
||||
<ul className="payment-items w-full min-h-[400px]">
|
||||
{cardList.loading ?
|
||||
<div className='w-full h-[300px] flex justify-center items-center'>
|
||||
<LoadingSpinner size='8' color='sky-blue' />
|
||||
</div>
|
||||
:
|
||||
cardList.data.length ?
|
||||
currentCardList.map(item =>{
|
||||
let image = item.description && localImgLoad(`images/payment-cards/${item.description.toLowerCase()}-card.svg`)
|
||||
return(
|
||||
<li key={item.card_uid} className="sm:flex justify-between items-center w-full py-3 border-b border-light-purple dark:border-[#5356fb29] ">
|
||||
<div className="flex space-x-5 mb-2 sm:mb-0">
|
||||
<div className="w-[70px] h-[70px] flex items-center justify-center rounded-full sm:bg-light-purple dark:bg-dark-light-purple ">
|
||||
<img src={image ? image : method1} className='w-[50px] h-[50px]' alt="payment" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="sm:text-xl text-lg tracking-wide text-dark-gray dark:text-white">
|
||||
Added: {item.added}
|
||||
</p>
|
||||
<p className="text-thin-light-gray sm:text-18 text-sm tracking-wide">
|
||||
{item.description} **********{item.digits}
|
||||
</p>
|
||||
{/* <p className="sm:text-18 text-sm tracking-wide text-light-green">
|
||||
Verified
|
||||
</p> */}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={()=>{setDeleteCardModal({show: true, data:item})}}
|
||||
className="w-[95px] sm:h-[46px] h-[40px] rounded-full btn-gradient text-white sm:text-18 text-md tracking-wide"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
)}
|
||||
)
|
||||
:
|
||||
<h1 className='font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap'>No Cards Found</h1>
|
||||
}
|
||||
</ul>
|
||||
|
||||
{/* PAGINATION BUTTON */}
|
||||
<PaginatedList
|
||||
onClick={handlePagination}
|
||||
prev={currentPage == 0 ? true : false}
|
||||
next={
|
||||
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
|
||||
cardList?.data?.length
|
||||
? true
|
||||
: false
|
||||
}
|
||||
data={cardList?.data}
|
||||
start={indexOfFirstItem}
|
||||
stop={indexOfLastItem}
|
||||
/>
|
||||
{/* END OF PAGINATION BUTTON */}
|
||||
|
||||
{deleteCardModal.show &&
|
||||
<DeleteCardPopout action={handleDeleteCardModal} situation={deleteCardModal.show} data={deleteCardModal.data} setReloadCardList={setReloadCardList} />
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default CardList
|
||||
@@ -3,11 +3,39 @@
|
||||
import React, { useState } from "react";
|
||||
import Icons from "../../Helpers/Icons";
|
||||
import PasswordSvg from "../PasswordSvg";
|
||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||
import usersService from "../../../services/UsersService";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
export default function ChangePasswordTab() {
|
||||
const apiUrl = new usersService()
|
||||
const navigate = useNavigate()
|
||||
|
||||
const [oldPass, setOldPass] = useState("hide-password");
|
||||
const [newPass, setNewPass] = useState("hide-password");
|
||||
const [confirmPass, setConfirmPass] = useState("hide-password");
|
||||
|
||||
const [requestStatus, setRequestStatus] = useState({loading: false, status: false, message: ''})
|
||||
|
||||
const [inputEmpty, setInputEmpty] = useState(false)
|
||||
let [inputs, setInputs] = useState({
|
||||
old_pwd: '',
|
||||
new_pwd: '',
|
||||
confirm_new_pwd: ''
|
||||
})
|
||||
|
||||
const handleInputChange = ({target:{name, value}}) => { // FUNCTION TO HANDLE WHEN AN INPUT CHANGES
|
||||
setInputs(prev => ({...prev, [name]:value}))
|
||||
}
|
||||
|
||||
const handleCancel = () => { // FUNCTION TO CLEAR ALL TYPED INPUTS
|
||||
setInputs({
|
||||
old_pwd: '',
|
||||
new_pwd: '',
|
||||
confirm_new_pwd: ''
|
||||
})
|
||||
}
|
||||
|
||||
const showPassword = (value) => {
|
||||
const password = document.getElementById(`${value}`);
|
||||
if (value && value === "old_password") {
|
||||
@@ -38,16 +66,61 @@ export default function ChangePasswordTab() {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handlePwdUpdate = () => {
|
||||
setInputEmpty(false) // SETS THE STATE OF ANY INPUT IS EMPTY TO FALSE
|
||||
if(!inputs.old_pwd || !inputs.new_pwd || !inputs.confirm_new_pwd){ // CHECKS IF ANY INPUT FIELD IS EMPTY AND SETS INPUT EMPTY TO TRUE
|
||||
setInputEmpty(true)
|
||||
return setTimeout(()=>{setInputEmpty(false)},3000)
|
||||
}
|
||||
|
||||
if(inputs.new_pwd != inputs.confirm_new_pwd){ // CHECKS IF PASSWORD MATCHES CONFIRM PASSWORD
|
||||
setRequestStatus({loading: false, status: false, message: 'new password must match confirm password'})
|
||||
return setTimeout(()=>{setRequestStatus({loading: false, status: false, message: ''})},3000)
|
||||
}
|
||||
|
||||
if(/^[a-zA-Z0-9]*$/.test(inputs.new_pwd) == false){ // CHECKS IF PASSWORD IS ALPHANUMERIC
|
||||
setRequestStatus({loading: false, status: false, message: 'password must be alphanumeric'})
|
||||
return setTimeout(()=>{setRequestStatus({loading: false, status: false, message: ''})},3000)
|
||||
}
|
||||
|
||||
if(inputs.new_pwd.length < 6){ // CHECKS IF PASSWORD IS UPTO SIX CHARACTERS
|
||||
setRequestStatus({loading: false, status: false, message: 'password must be upto six characters'})
|
||||
return setTimeout(()=>{setRequestStatus({loading: false, status: false, message: ''})},3000)
|
||||
}
|
||||
|
||||
|
||||
let reqData = { // REQUEST PAYLOAD
|
||||
current_pass: inputs.old_pwd,
|
||||
new_pass: inputs.new_pwd
|
||||
}
|
||||
|
||||
|
||||
setRequestStatus({loading: true, status: false, message: ''})
|
||||
|
||||
apiUrl.profilePassChange(reqData).then(res => {
|
||||
if(res.status != 200 || res.data.internal_return < 0){
|
||||
setRequestStatus({loading: false, status: false, message: 'unable to complete request'})
|
||||
return
|
||||
}
|
||||
setRequestStatus({loading: false, status: true, message: 'password update was successful'})
|
||||
setTimeout(()=>{navigate('/settings', {replace: true})}, 5000)
|
||||
}).catch(err => {
|
||||
setRequestStatus({loading: false, status: false, message: 'unable to complete request'})
|
||||
}).finally(()=>{
|
||||
setTimeout(()=>{setRequestStatus({loading: false, status: false, message: ''})},4000)
|
||||
})
|
||||
}
|
||||
return (
|
||||
<div className="changePasswordTab w-full">
|
||||
<div className="w-full flex xl:flex-row flex-col-reverse space-x-5 xl:items-center">
|
||||
<div className="w-full flex xxl:flex-row flex-col-reverse space-x-5 xxl:items-start">
|
||||
<div className="flex-1 mb-10">
|
||||
<div className="input-field mb-6">
|
||||
<label
|
||||
className="input-label text-dark-gray dark:text-white text-xl font-bold block mb-2.5"
|
||||
htmlFor="old_password"
|
||||
>
|
||||
Old Password
|
||||
Old Password <span className="text-[10px] text-red-500 italic px-2">{(inputEmpty && !inputs.old_pwd) && 'required'}</span>
|
||||
</label>
|
||||
<div className="input-wrapper border border-light-purple dark:border-[#5356fb29] w-full rounded-[50px] h-[58px] overflow-hidden relative ">
|
||||
<div className="absolute left-6 bottom-[17px] z-10">
|
||||
@@ -58,6 +131,10 @@ export default function ChangePasswordTab() {
|
||||
className="input-field placeholder:text-base text-bese px-12 text-dark-gray dark:text-white w-full h-full bg-[#FAFAFA] dark:bg-[#11131F] focus:ring-0 focus:outline-none"
|
||||
type="password"
|
||||
id="old_password"
|
||||
value={inputs.old_pwd}
|
||||
name='old_pwd'
|
||||
onChange={handleInputChange}
|
||||
autoComplete='false'
|
||||
/>
|
||||
<div
|
||||
className="absolute right-6 bottom-[17px] z-10 cursor-pointer"
|
||||
@@ -72,7 +149,7 @@ export default function ChangePasswordTab() {
|
||||
className="input-label text-dark-gray dark:text-white text-xl font-bold block mb-2.5"
|
||||
htmlFor="new_password"
|
||||
>
|
||||
New Password
|
||||
New Password <span className="text-[10px] text-red-500 italic px-2">{(inputEmpty && !inputs.new_pwd) && 'required'}</span>
|
||||
</label>
|
||||
<div className="input-wrapper border border-light-purple dark:border-[#5356fb29] w-full rounded-[50px] h-[58px] overflow-hidden relative ">
|
||||
<div className="absolute left-6 bottom-[17px] z-10">
|
||||
@@ -83,6 +160,10 @@ export default function ChangePasswordTab() {
|
||||
className="input-field placeholder:text-base text-bese px-12 text-dark-gray dark:text-white w-full h-full bg-[#FAFAFA] dark:bg-[#11131F] focus:ring-0 focus:outline-none"
|
||||
type="password"
|
||||
id="new_password"
|
||||
value={inputs.new_pwd}
|
||||
name='new_pwd'
|
||||
onChange={handleInputChange}
|
||||
autoComplete='false'
|
||||
/>
|
||||
<div
|
||||
className="absolute right-6 bottom-[17px] z-10 cursor-pointer"
|
||||
@@ -97,7 +178,7 @@ export default function ChangePasswordTab() {
|
||||
className="input-label text-dark-gray dark:text-white text-xl font-bold block mb-2.5"
|
||||
htmlFor="confirm_password"
|
||||
>
|
||||
Confirm Password
|
||||
Confirm Password <span className="text-[10px] text-red-500 italic px-2">{(inputEmpty && !inputs.confirm_new_pwd) && 'required'}</span>
|
||||
</label>
|
||||
<div className="input-wrapper border border-light-purple dark:border-[#5356fb29] w-full rounded-[50px] h-[58px] overflow-hidden relative ">
|
||||
<div className="absolute left-6 bottom-[17px] z-10">
|
||||
@@ -108,6 +189,10 @@ export default function ChangePasswordTab() {
|
||||
className="input-field placeholder:text-base text-bese px-12 text-dark-gray dark:text-white w-full h-full bg-[#FAFAFA] dark:bg-[#11131F] focus:ring-0 focus:outline-none"
|
||||
type="password"
|
||||
id="confirm_password"
|
||||
value={inputs.confirm_new_pwd}
|
||||
name='confirm_new_pwd'
|
||||
onChange={handleInputChange}
|
||||
autoComplete='false'
|
||||
/>
|
||||
<div
|
||||
className="absolute right-6 bottom-[17px] z-10 cursor-pointer"
|
||||
@@ -120,19 +205,46 @@ export default function ChangePasswordTab() {
|
||||
<div className="flex justify-center space-x-4 items-center">
|
||||
<button
|
||||
type="button"
|
||||
className="text-light-red text-18 tracking-wide border-b dark:border-[#5356fb29] border-light-red "
|
||||
className="text-light-red text-18 tracking-wide border-b dark:border-[#5356fb29] border-light-red"
|
||||
disabled={requestStatus.loading}
|
||||
onClick={handleCancel}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="btn-gradient tracking-wide rounded-full w-[173px] h-[46px] flex justify-center items-center"
|
||||
>
|
||||
<span className="font-thin text-18 tracking-wide antialiased text-white">
|
||||
Change Password
|
||||
</span>
|
||||
</button>
|
||||
{requestStatus.loading ?
|
||||
<LoadingSpinner size='8' color='sky-blue' />
|
||||
:
|
||||
<button
|
||||
type="button"
|
||||
className="btn-gradient tracking-wide rounded-full w-[173px] h-[46px] flex justify-center items-center"
|
||||
disabled={requestStatus.loading}
|
||||
onClick={handlePwdUpdate}
|
||||
>
|
||||
<span className="font-thin text-18 tracking-wide antialiased text-white">
|
||||
Change Password
|
||||
</span>
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
|
||||
{/* error or success display */}
|
||||
{requestStatus.message != "" &&
|
||||
(!requestStatus.status ? (
|
||||
<div
|
||||
className={`relative p-4 my-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
|
||||
>
|
||||
{requestStatus.message}
|
||||
</div>
|
||||
) : (
|
||||
requestStatus.status && (
|
||||
<div
|
||||
className={`relative p-4 my-4 text-green-700 bg-slate-200 border-slate-800 mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
|
||||
>
|
||||
{requestStatus.message}
|
||||
</div>
|
||||
)
|
||||
))}
|
||||
{/* End of error or success display */}
|
||||
</div>
|
||||
<div className="w-[440px] sm:flex hidden justify-end">
|
||||
<PasswordSvg />
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
import React, { useState } from 'react'
|
||||
import ModalCom from '../../Helpers/ModalCom'
|
||||
import LoadingSpinner from '../../Spinners/LoadingSpinner'
|
||||
import usersService from '../../../services/UsersService'
|
||||
|
||||
function DeleteCardPopout({action, situation, data, setReloadCardList}) {
|
||||
const api = new usersService()
|
||||
|
||||
const [requestStatus, setRequestStatus] = useState({loading: false, status:false, message: ''})
|
||||
|
||||
let handleDeleteCard = () => { // FUNCTION TO DELETE A CARD
|
||||
setRequestStatus(prev => ({...prev, loading: true}))
|
||||
api.payRemCard({card_uid:data.card_uid}).then(res=>{
|
||||
if(res.status != 200 || res.data.internal_return < 0){
|
||||
setRequestStatus({loading: false, status:false, message: 'unable to delete card. Try Again'})
|
||||
return
|
||||
}
|
||||
setRequestStatus({loading: false, status:true, message: 'Card deleted'})
|
||||
setReloadCardList(prev => !prev) // RELOADS PAY CARD LIST
|
||||
setTimeout(()=>{action()},3000) // CLOSES MODAL AFTER SOME SECONDS
|
||||
}).catch(err => {
|
||||
setRequestStatus({loading: false, status:false, message: 'network error. Try Again'})
|
||||
}).finally(()=>{
|
||||
setTimeout(()=>{
|
||||
setRequestStatus(prev => ({...prev, message: ''}))
|
||||
},4000)
|
||||
})
|
||||
}
|
||||
return (
|
||||
<ModalCom action={action} situation={situation}>
|
||||
<div className="logout-modal-wrapper lg:w-[460px] h-full lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl">
|
||||
<div className="logout-modal-header w-full flex items-center justify-between lg:px-10 lg:py-8 px-[30px] py-[23px] border-b dark:border-[#5356fb29] border-light-purple">
|
||||
<h1 className="text-26 font-bold text-red-500 tracking-wide">
|
||||
Confirm Card Delete
|
||||
</h1>
|
||||
<button
|
||||
type="button"
|
||||
disabled={requestStatus.loading}
|
||||
className="text-[#374557] dark:text-red-500"
|
||||
onClick={action}
|
||||
>
|
||||
<svg
|
||||
width="36"
|
||||
height="36"
|
||||
viewBox="0 0 36 36"
|
||||
fill="none"
|
||||
className="fill-current"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M36 16.16C36 17.4399 36 18.7199 36 20.0001C35.7911 20.0709 35.8636 20.2554 35.8385 20.4001C34.5321 27.9453 30.246 32.9248 22.9603 35.2822C21.9006 35.6251 20.7753 35.7657 19.6802 35.9997C18.4003 35.9997 17.1204 35.9997 15.8401 35.9997C15.5896 35.7086 15.2189 35.7732 14.9034 35.7093C7.77231 34.2621 3.08728 30.0725 0.769671 23.187C0.435002 22.1926 0.445997 21.1199 0 20.1599C0 18.7198 0 17.2798 0 15.8398C0.291376 15.6195 0.214408 15.2656 0.270759 14.9808C1.71321 7.69774 6.02611 2.99691 13.0428 0.700951C14.0118 0.383805 15.0509 0.386897 15.9999 0C17.2265 0 18.4532 0 19.6799 0C19.7156 0.124041 19.8125 0.136067 19.9225 0.146719C27.3 0.868973 33.5322 6.21922 35.3801 13.427C35.6121 14.3313 35.7945 15.2484 36 16.16ZM33.011 18.0787C33.0433 9.77105 26.3423 3.00309 18.077 2.9945C9.78479 2.98626 3.00344 9.658 2.98523 17.8426C2.96667 26.1633 9.58859 32.9601 17.7602 33.0079C26.197 33.0577 32.9787 26.4186 33.011 18.0787Z"
|
||||
fill=""
|
||||
fillOpacity="0.6"
|
||||
/>
|
||||
<path
|
||||
d="M15.9309 18.023C13.9329 16.037 12.007 14.1207 10.0787 12.2072C9.60071 11.733 9.26398 11.2162 9.51996 10.506C9.945 9.32677 11.1954 9.0811 12.1437 10.0174C13.9067 11.7585 15.6766 13.494 17.385 15.2879C17.9108 15.8401 18.1633 15.7487 18.6375 15.258C20.3586 13.4761 22.1199 11.7327 23.8822 9.99096C24.8175 9.06632 26.1095 9.33639 26.4967 10.517C26.7286 11.2241 26.3919 11.7413 25.9133 12.2178C24.1757 13.9472 22.4477 15.6855 20.7104 17.4148C20.5228 17.6018 20.2964 17.7495 20.0466 17.9485C22.0831 19.974 24.0372 21.8992 25.9689 23.8468C26.9262 24.8119 26.6489 26.1101 25.4336 26.4987C24.712 26.7292 24.2131 26.3441 23.7455 25.8757C21.9945 24.1227 20.2232 22.3892 18.5045 20.6049C18.0698 20.1534 17.8716 20.2269 17.4802 20.6282C15.732 22.4215 13.9493 24.1807 12.1777 25.951C11.7022 26.4262 11.193 26.7471 10.4738 26.4537C9.31345 25.9798 9.06881 24.8398 9.98589 23.8952C11.285 22.5576 12.6138 21.2484 13.9387 19.9355C14.5792 19.3005 15.2399 18.6852 15.9309 18.023Z"
|
||||
fill="#"
|
||||
fillOpacity="0.6"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div className="logout-modal-body w-full flex flex-col items-center px-10 py-8">
|
||||
<div className="what-icon mb-6 cursor-pointer">
|
||||
<svg
|
||||
width="136"
|
||||
height="136"
|
||||
viewBox="0 0 136 136"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<circle cx="68" cy="68" r="68" fill="#5356FB" />
|
||||
<path
|
||||
d="M69.8844 35.7891C71.1588 36.0357 72.4569 36.1967 73.7044 36.5423C81.5447 38.7098 87.2705 45.5378 87.9574 53.6156C88.5113 60.1147 86.3075 65.6006 81.5043 70.0195C79.8359 71.5545 78.0497 72.9604 76.3408 74.4534C76.127 74.6397 75.9654 75.0037 75.9604 75.2872C75.9284 77.2752 75.9435 79.2649 75.9435 81.2965C70.8895 81.2965 65.8758 81.2965 60.7915 81.2965C60.7915 81.0616 60.7915 80.8385 60.7915 80.6137C60.7915 76.5454 60.7999 72.4772 60.7797 68.4106C60.778 67.9392 60.9312 67.649 61.2831 67.3537C64.5643 64.5957 67.8271 61.8175 71.1033 59.0545C72.2616 58.0781 72.9215 56.8702 72.9081 55.3419C72.8878 52.916 70.8608 50.9146 68.423 50.8911C65.9701 50.8693 63.9145 52.8053 63.832 55.2328C63.8084 55.8988 63.8286 56.5665 63.8286 57.2695C58.7745 57.2695 53.7744 57.2695 48.6917 57.2695C48.6917 56.3149 48.6462 55.3385 48.6984 54.3655C49.222 44.699 56.7442 36.8745 66.4331 35.8914C66.5762 35.8763 66.7142 35.8243 66.854 35.7891C67.8641 35.7891 68.8742 35.7891 69.8844 35.7891Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M67.485 100.21C66.1617 99.9268 64.9041 99.5091 63.803 98.6787C61.3804 96.8484 60.2877 93.7699 61.0386 90.7888C61.7726 87.8747 64.2138 85.6703 67.2089 85.2157C71.273 84.6 75.2024 87.3681 75.8135 91.277C76.4937 95.6153 73.8202 99.3782 69.544 100.103C69.4429 100.12 69.3487 100.172 69.2527 100.209C68.6635 100.21 68.0742 100.21 67.485 100.21Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div className="mb-6">
|
||||
<p className="text-2xl tracking-wide text-center text-dark-gray dark:text-white">
|
||||
Are you sure you want to delete?
|
||||
</p>
|
||||
<div className='my-1 text-center'>
|
||||
<p className="py-1 sm:text-xl text-lg tracking-wide text-dark-gray dark:text-white">
|
||||
Added: {data.added}
|
||||
</p>
|
||||
<p className="py-1 text-thin-light-gray sm:text-18 text-sm tracking-wide">
|
||||
{data.description} **********{data.digits}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{/* error or success display */}
|
||||
{requestStatus.message != "" &&
|
||||
(!requestStatus.status ? (
|
||||
<div
|
||||
className={`relative p-2 mb-2 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
|
||||
>
|
||||
{requestStatus.message}
|
||||
</div>
|
||||
) : (
|
||||
requestStatus.status && (
|
||||
<div
|
||||
className={`relative p-2 mb-2 text-green-700 bg-slate-200 border-slate-800 mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
|
||||
>
|
||||
{requestStatus.message}
|
||||
</div>
|
||||
)
|
||||
))}
|
||||
{/* End of error or success display */}
|
||||
<div className="flex space-x-2.5">
|
||||
<button
|
||||
onClick={action}
|
||||
disabled={requestStatus.loading}
|
||||
type="button"
|
||||
className=" border-gradient text-18 tracking-wide px-4 py-3 rounded-full"
|
||||
>
|
||||
<span className="text-gradient">Cancel</span>
|
||||
</button>
|
||||
{requestStatus.loading ?
|
||||
<LoadingSpinner size='10' color='sky-blue' />
|
||||
:
|
||||
<button
|
||||
onClick={handleDeleteCard}
|
||||
disabled={requestStatus.loading}
|
||||
type="button"
|
||||
className="text-white primary-gradient text-18 tracking-wide px-4 py-3 rounded-full"
|
||||
>
|
||||
Confirm Delete
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ModalCom>
|
||||
)
|
||||
}
|
||||
|
||||
export default DeleteCardPopout
|
||||
@@ -1,237 +1,112 @@
|
||||
import React, { useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import SwitchCom from "../../Helpers/SwitchCom";
|
||||
|
||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||
import usersService from "../../../services/UsersService";
|
||||
import localImgLoad from "../../../lib/localImgLoad";
|
||||
import { toast } from "react-toastify";
|
||||
|
||||
import defaultImage from '../../../assets/images/banner-job-due.jpg'
|
||||
|
||||
|
||||
export default function NotificationSettingTab() {
|
||||
const [updateNotification, setUpdateNotification] = useState(false);
|
||||
const [uploadProduct, setUploadProduct] = useState(true);
|
||||
const [saleProduct, setSaleProduct] = useState(true);
|
||||
const [getProduct, setGetProduct] = useState(false);
|
||||
const [authLevel, setAuthLevel] = useState(true);
|
||||
const api = new usersService();
|
||||
|
||||
const [accSettings, setAccSettings] = useState({loading: true, data: []}) // STATE TO HOLD ACCOUNT SETTINGS
|
||||
|
||||
let [notificationChange, setNotificationChange] = useState({loading: false, uid: ''})
|
||||
|
||||
// const [updateNotification, setUpdateNotification] = useState(false);
|
||||
// const [uploadProduct, setUploadProduct] = useState(true);
|
||||
// const [saleProduct, setSaleProduct] = useState(true);
|
||||
// const [getProduct, setGetProduct] = useState(false);
|
||||
// const [authLevel, setAuthLevel] = useState(true);
|
||||
|
||||
const NotificationInterfaceChange = (item) => {
|
||||
setAccSettings(prev => {
|
||||
let newAccSettings = prev.data.map(data => {
|
||||
if(data.uid == item.uid){
|
||||
let newPrefValue = data.pref_value == null || data.pref_value == '0' ? '100' : '0'
|
||||
return {...data, pref_value: newPrefValue}
|
||||
}else{
|
||||
return data
|
||||
}
|
||||
})
|
||||
return {...prev, data: newAccSettings}
|
||||
})
|
||||
}
|
||||
|
||||
let handleNotificationChange = (item) => { // FUNCTION TO SET ACCOUNT SETTING
|
||||
setNotificationChange({loading: true, uid: item.uid})
|
||||
let reqData = { // API PAYLOADS
|
||||
pref_id: item.pref_id,
|
||||
status: item.pref_value == null || item.pref_value == 0 ? 100 : 0
|
||||
}
|
||||
api.setAccSettings(reqData).then(res => {
|
||||
if(res.status != 200 || res.data.internal_return < 0){
|
||||
toast.error("unable to complete");
|
||||
}
|
||||
toast.success("successful");
|
||||
NotificationInterfaceChange(item) // CHANGES NOTIFICATION UI INTERFACE
|
||||
}).catch(errer => {
|
||||
toast.error("unable to complete");
|
||||
}).finally(()=>{
|
||||
setNotificationChange({loading: false, uid: {}})
|
||||
// setTimeout(()=>{setNotificationChange({loading: false, uid: {}})},2000)
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(()=>{
|
||||
api.getAccSettings().then(res => {
|
||||
setAccSettings({loading: false, data: res.data?.result_list || []})
|
||||
}).catch(errer => {
|
||||
setAccSettings({loading: false, data: []})
|
||||
})
|
||||
},[])
|
||||
|
||||
return (
|
||||
<div className="notification-setting-tab w-full">
|
||||
<div className="notification-settings-wrapper w-full">
|
||||
<ul className="notification-settings-items w-full">
|
||||
<li className="notification-settings-item sm:flex justify-between items-center mb-4 pb-4 border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] ">
|
||||
<div className="sm:flex sm:space-x-4 items-center">
|
||||
<div className="w-16 h-16">
|
||||
<svg
|
||||
width="60"
|
||||
height="60"
|
||||
viewBox="0 0 60 60"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<circle
|
||||
cx="30"
|
||||
cy="30"
|
||||
r="30"
|
||||
fill="url(#paint0_linear_41_74037)"
|
||||
/>
|
||||
<path
|
||||
d="M29.9703 43.9959C27.4494 43.9959 24.9286 44.0078 22.4077 43.9919C20.2721 43.9799 19.0338 42.7656 19.0197 40.6347C18.9955 37.2735 18.9915 33.9123 19.0197 30.5511C19.0378 28.4521 20.3265 27.2158 22.4481 27.2118C27.4212 27.2019 32.3964 27.2039 37.3695 27.2118C39.604 27.2158 40.8564 28.4641 40.8644 30.6909C40.8745 33.9862 40.8786 37.2815 40.8644 40.5767C40.8544 42.7616 39.6242 43.9819 37.43 43.9939C34.9434 44.0058 32.4569 43.9959 29.9703 43.9959ZM27.5321 33.9722C27.6108 34.1699 27.6592 34.789 27.9919 35.0466C28.8954 35.7476 28.7542 36.6544 28.7563 37.567C28.7563 37.9984 28.6272 38.5057 28.8107 38.8412C29.0467 39.2706 29.5367 39.8358 29.9219 39.8398C30.3131 39.8438 30.8496 39.3026 31.0613 38.8752C31.261 38.4698 31.1319 37.9006 31.1319 37.4053C31.1319 36.5525 31.0936 35.7716 31.868 35.0706C32.6041 34.4036 32.4871 33.1354 31.8841 32.3086C31.2811 31.4817 30.2002 31.1262 29.2019 31.4258C28.2521 31.7114 27.5483 32.6621 27.5321 33.9722Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M37.5315 26.2691C36.3356 26.2691 35.2466 26.2691 34.0345 26.2691C34.0345 25.4044 34.0446 24.5856 34.0325 23.7647C33.9982 21.3202 32.2397 19.4709 29.9467 19.4589C27.6497 19.4469 25.8851 21.2803 25.8448 23.7368C25.8306 24.5596 25.8427 25.3844 25.8427 26.2672C24.6448 26.2672 23.5558 26.2672 22.4729 26.2672C21.7126 21.3322 23.5054 17.6674 27.7546 16.3473C32.5603 14.8535 37.3984 18.3624 37.5274 23.3493C37.5516 24.304 37.5315 25.2606 37.5315 26.2691Z"
|
||||
fill="white"
|
||||
/>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="paint0_linear_41_74037"
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="63.3708"
|
||||
y2="62.0225"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stopColor="#F539F8" />
|
||||
<stop offset="0.416763" stopColor="#C342F9" />
|
||||
<stop offset="1" stopColor="#5356FB" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
<ul className="notification-settings-items w-full min-h-[300px]">
|
||||
{accSettings.loading ?
|
||||
<LoadingSpinner size='8' color='sky-blue' height='h-full'/>
|
||||
:
|
||||
accSettings.data.length ?
|
||||
accSettings.data.map(item =>{
|
||||
let image = item.banner && localImgLoad(`images/settings/${item.banner.toLowerCase()}`)
|
||||
return(
|
||||
<li key={item.uid} className="notification-settings-item sm:flex justify-between items-center mb-3 pb-3 border-b border-light-purple dark:border-[#5356fb29] ">
|
||||
<div className="sm:flex sm:space-x-4 items-center">
|
||||
<div className="w-10 h-10">
|
||||
<img className="w-full h-full" src={image ? image: defaultImage} alt='account-settings' />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-xl tracking-wide text-dark-gray dark:text-white font-bold">
|
||||
{item.title}
|
||||
</p>
|
||||
<p className="text-base tracking-wide text-thin-light-gray">
|
||||
{item.description}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-xl tracking-wide text-dark-gray dark:text-white font-bold">
|
||||
All Notifcation update off
|
||||
</p>
|
||||
<p className="text-base tracking-wide text-thin-light-gray">
|
||||
Unlockable content, only revealed by the owner of the item.
|
||||
</p>
|
||||
<div className="mt-5 sm:mt-0">
|
||||
{notificationChange.loading && notificationChange.uid == item.uid ?
|
||||
<LoadingSpinner size='8' color='sky-blue' />
|
||||
:
|
||||
<SwitchCom
|
||||
value={item.pref_value == null || item.pref_value == '0' ? 0 : 100}
|
||||
handler={ notificationChange.loading ? ()=>{} : () => handleNotificationChange(item)}
|
||||
// value={updateNotification}
|
||||
// handler={() => setUpdateNotification(!updateNotification)}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-5 sm:mt-0">
|
||||
<SwitchCom
|
||||
value={updateNotification}
|
||||
handler={() => setUpdateNotification(!updateNotification)}
|
||||
/>
|
||||
</div>
|
||||
</li>
|
||||
<li className="notification-settings-item sm:flex justify-between items-center mb-4 pb-4 border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] ">
|
||||
<div className="sm:flex sm:space-x-4 items-center">
|
||||
<div className="w-16 h-16">
|
||||
<svg
|
||||
width="60"
|
||||
height="60"
|
||||
viewBox="0 0 60 60"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<circle cx="30" cy="30" r="30" fill="#5356FB" />
|
||||
<path
|
||||
d="M29.9407 28.117C29.3978 27.9377 28.8874 27.8356 28.4342 27.6115C24.4201 25.6243 20.4135 23.6173 16.4044 21.6202C16.1106 21.4733 15.884 21.2841 15.879 20.933C15.874 20.5669 16.1006 20.3627 16.4094 20.2083C20.3911 18.2237 24.3728 16.2341 28.352 14.2445C29.4974 13.6718 30.6255 13.7365 31.756 14.3068C34.3133 15.5942 36.8806 16.8691 39.443 18.149C40.7503 18.8014 42.0551 19.4563 43.3599 20.1112C43.4346 20.1486 43.5093 20.1834 43.5865 20.2208C43.8853 20.3602 44.092 20.5769 44.092 20.923C44.092 21.2741 43.8704 21.4708 43.5766 21.6153C41.7214 22.5391 39.8688 23.4679 38.0136 24.3917C35.8721 25.46 33.7406 26.5432 31.5866 27.5841C31.0737 27.8331 30.4935 27.9426 29.9407 28.117Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M28.9083 38.6004C28.9083 40.8266 28.9108 43.0527 28.9058 45.2789C28.9033 46.0707 28.4576 46.3496 27.728 46.0135C24.0775 44.3326 20.4245 42.6568 16.7814 40.9635C15.6086 40.4182 15.0109 39.4645 15.006 38.1746C14.996 33.9314 15.001 29.6883 15.0035 25.4451C15.0035 24.6259 15.4641 24.3221 16.1962 24.6607C19.9713 26.4013 23.7438 28.1519 27.5213 29.885C28.48 30.3257 28.9232 31.0429 28.9158 32.0912C28.9008 34.2626 28.9108 36.4315 28.9108 38.6029C28.9108 38.6004 28.9108 38.6004 28.9083 38.6004Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M31.0596 38.5382C31.0596 36.3544 31.0646 34.1705 31.0571 31.9867C31.0546 31.0006 31.5054 30.3208 32.3894 29.9124C36.1893 28.1594 39.9917 26.4113 43.7916 24.6608C44.4839 24.342 44.9595 24.6284 44.9595 25.3829C44.9644 29.6684 44.9719 33.9514 44.9545 38.2369C44.9495 39.5492 44.2772 40.4655 43.0944 41.0134C40.1411 42.378 37.1853 43.74 34.232 45.1021C33.5995 45.3935 32.9695 45.6848 32.3395 45.9762C31.4829 46.3696 31.0571 46.1032 31.0571 45.1719C31.0571 42.9606 31.0571 40.7469 31.0571 38.5357C31.0596 38.5382 31.0596 38.5382 31.0596 38.5382Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-xl tracking-wide text-dark-gray dark:text-white font-bold">
|
||||
When you upload prodcuts
|
||||
</p>
|
||||
<p className="text-base tracking-wide text-thin-light-gray">
|
||||
Evey new prodcuts upload seccessfullly doen you can get
|
||||
notifcation
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-5 sm:mt-0">
|
||||
<SwitchCom
|
||||
value={uploadProduct}
|
||||
handler={() => setUploadProduct(!uploadProduct)}
|
||||
/>
|
||||
</div>
|
||||
</li>
|
||||
<li className="notification-settings-item sm:flex justify-between items-center mb-4 pb-4 border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] ">
|
||||
<div className="sm:flex sm:space-x-4 items-center">
|
||||
<div className="w-16 h-16">
|
||||
<svg
|
||||
width="60"
|
||||
height="60"
|
||||
viewBox="0 0 60 60"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<circle cx="30" cy="30" r="30" fill="#F539F8" />
|
||||
<path
|
||||
d="M41.8287 28.0141C41.4077 29.4703 41.0646 30.8583 40.5811 32.1937C40.4622 32.5232 39.8851 32.8897 39.5147 32.8936C35.1811 32.9443 30.8474 32.9267 26.5138 32.9287C25.8724 32.9287 25.463 32.6129 25.3168 31.9988C24.6306 29.1292 23.9385 26.2596 23.2835 23.3841C23.0847 22.5146 23.4804 21.9785 24.3187 21.9727C27.8511 21.9493 31.3835 21.9629 35.0037 21.9629C34.9608 23.8383 35.4716 25.4778 36.8927 26.7274C38.2827 27.9575 39.9261 28.324 41.8287 28.0141Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M24.4176 33.9331C27.334 33.9331 30.1997 33.9331 33.0654 33.9331C34.9408 33.9331 36.8162 33.9292 38.6915 33.9351C39.5649 33.937 40.0601 34.3289 40.0835 35.0053C40.1069 35.7169 39.5961 36.1497 38.6877 36.1497C33.7224 36.1536 28.759 36.1536 23.7938 36.1497C22.7878 36.1497 22.5091 35.904 22.2888 34.8884C21.3452 30.5255 20.3939 26.1645 19.4679 21.7977C19.3587 21.285 19.1579 20.9965 18.6296 20.8347C17.419 20.4643 16.2318 20.0159 15.0368 19.5948C14.0328 19.24 13.6605 18.6981 13.9334 18.0021C14.2024 17.314 14.7853 17.1385 15.7386 17.4699C17.2221 17.9846 18.692 18.5382 20.1912 19.0061C20.9476 19.242 21.3082 19.6689 21.4681 20.4331C22.3824 24.7746 23.3317 29.1082 24.2733 33.4438C24.3006 33.5725 24.3474 33.7012 24.4176 33.9331Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M35.6934 22.6285C35.6798 19.9227 37.8729 17.7237 40.5788 17.7334C43.23 17.7412 45.4134 19.9441 45.4095 22.609C45.4056 25.2662 43.2144 27.4632 40.5573 27.469C37.9022 27.4749 35.7071 25.2915 35.6934 22.6285ZM42.6257 20.4685C41.7465 21.4101 40.8848 22.3342 39.8614 23.4317C39.3721 22.7669 38.9763 22.2328 38.524 21.6207C38.0698 22.0963 37.7696 22.4102 37.5747 22.6168C38.4051 23.4746 39.1986 24.2914 39.9316 25.0498C41.1207 23.8567 42.345 22.6305 43.6726 21.299C43.4562 21.1274 43.1969 20.9208 42.9357 20.7142C42.8538 20.6459 42.77 20.5835 42.6257 20.4685Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M37.4854 37.0509C39.2068 37.0353 40.6104 38.3882 40.6436 40.096C40.6767 41.8329 39.2653 43.258 37.5147 43.258C35.805 43.258 34.4072 41.868 34.3994 40.1662C34.3936 38.4565 35.7699 37.0685 37.4854 37.0509ZM38.8929 40.1447C38.891 39.3903 38.2984 38.7781 37.5537 38.7625C36.7817 38.745 36.1384 39.3825 36.1423 40.1603C36.1462 40.907 36.7485 41.5269 37.4854 41.5464C38.2574 41.5659 38.8968 40.9303 38.8929 40.1447Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M24.8751 43.2571C23.1556 43.2434 21.7754 41.8613 21.7793 40.1555C21.7852 38.3951 23.179 37.0286 24.9491 37.0481C26.6569 37.0676 28.0273 38.4751 28.0078 40.1886C27.9864 41.9022 26.5906 43.2688 24.8751 43.2571ZM26.2709 40.1574C26.2728 39.3738 25.6334 38.7441 24.8556 38.7636C24.1226 38.7831 23.4968 39.4167 23.4968 40.1458C23.4948 40.8768 24.1148 41.5182 24.8439 41.5435C25.6178 41.5708 26.2689 40.9372 26.2709 40.1574Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-xl tracking-wide text-dark-gray dark:text-white font-bold">
|
||||
You got sell your prodcuts
|
||||
</p>
|
||||
<p className="text-base tracking-wide text-thin-light-gray">
|
||||
Evey new prodcuts sell you can get notifcation
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-5 sm:mt-0">
|
||||
<SwitchCom
|
||||
value={saleProduct}
|
||||
handler={() => setSaleProduct(!saleProduct)}
|
||||
/>
|
||||
</div>
|
||||
</li>
|
||||
<li className="notification-settings-item sm:flex justify-between items-center mb-4 pb-4 border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] ">
|
||||
<div className="sm:flex sm:space-x-4 items-center">
|
||||
<div className="w-16 h-16">
|
||||
<svg
|
||||
width="60"
|
||||
height="60"
|
||||
viewBox="0 0 60 60"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<circle cx="30" cy="30" r="30" fill="#56CCF2" />
|
||||
<path
|
||||
d="M26.6593 16.1563C28.3179 16.165 29.6518 16.3439 30.8831 16.9656C33.0228 18.0459 34.1639 19.8365 34.4921 22.1742C34.7023 23.6678 34.5338 25.144 34.176 26.5977C33.7436 28.3484 33.16 30.0452 32.2326 31.603C31.6404 32.5982 30.904 33.4701 29.9106 34.0936C28.0678 35.252 25.8396 35.1339 24.0264 33.7931C22.9322 32.9838 22.1559 31.9157 21.5428 30.719C20.6658 29.0031 20.1743 27.1656 19.8356 25.2795C19.6428 24.2079 19.5768 23.1381 19.7505 22.0595C20.1986 19.2668 21.8103 17.4658 24.4502 16.5401C25.2612 16.2553 26.0984 16.1372 26.6593 16.1563Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M36.2459 45.0001C36.166 45.0001 36.0982 45.0001 36.0288 45.0001C28.7239 45.0001 21.4191 45.0001 14.1143 45.0001C13.8538 45.0001 13.8451 45.0001 13.8468 44.7448C13.8538 43.6993 13.8382 42.6503 13.8833 41.6065C13.9319 40.5227 14.4929 39.696 15.3352 39.0482C16.1689 38.4091 17.131 38.0409 18.1227 37.7352C20.1061 37.1239 22.1451 36.8095 24.2066 36.6324C26.0059 36.4778 27.8087 36.4709 29.6114 36.5681C30.0977 36.5942 30.5805 36.6567 31.0668 36.688C31.2388 36.7001 31.2787 36.7678 31.2787 36.9328C31.2735 38.5498 31.6243 40.0816 32.4493 41.4832C33.3125 42.9507 34.516 44.0605 36.0288 44.8403C36.093 44.8733 36.1573 44.9046 36.2215 44.9393C36.2302 44.9463 36.2302 44.9619 36.2459 45.0001Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M33.9961 35.6042C34.0881 35.6042 34.1663 35.6042 34.2444 35.6042C35.4098 35.6042 36.5734 35.6042 37.7388 35.6042C37.9993 35.6042 38.0011 35.6042 38.0011 35.3332C38.0011 34.1678 38.0011 33.0042 38.0011 31.8389C38.0011 31.7624 38.0011 31.6843 38.0011 31.5957C39.1473 31.5957 40.2675 31.5957 41.4155 31.5957C41.4155 32.9295 41.4155 34.2529 41.4155 35.6024C42.7667 35.6024 44.0902 35.6024 45.4257 35.6024C45.4257 36.7296 45.4257 37.8324 45.4257 38.9596C44.0954 38.9596 42.7702 38.9596 41.4173 38.9596C41.4173 40.316 41.4173 41.6463 41.4173 42.9906C41.327 42.9958 41.2627 43.0028 41.1984 43.0028C40.205 43.0028 39.2116 42.9993 38.2182 43.008C38.0445 43.0097 37.9959 42.9611 37.9959 42.7874C38.0028 41.6029 37.9993 40.4185 37.9993 39.234C37.9993 39.1558 37.9993 39.0777 37.9993 38.9717C36.6568 38.9717 35.3334 38.9717 33.9961 38.9717C33.9961 37.8394 33.9961 36.7383 33.9961 35.6042Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-xl tracking-wide text-dark-gray dark:text-white font-bold">
|
||||
Got new follower
|
||||
</p>
|
||||
<p className="text-base tracking-wide text-thin-light-gray">
|
||||
Evey new follower you can get notifcation
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-5 sm:mt-0">
|
||||
<SwitchCom
|
||||
value={getProduct}
|
||||
handler={() => setGetProduct(!getProduct)}
|
||||
/>
|
||||
</div>
|
||||
</li>
|
||||
<li className="notification-settings-item sm:flex justify-between items-center mb-4 pb-4 border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] ">
|
||||
<div className="sm:flex sm:space-x-4 items-center">
|
||||
<div className="w-16 h-16">
|
||||
<svg
|
||||
width="60"
|
||||
height="60"
|
||||
viewBox="0 0 60 60"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<circle cx="30" cy="30" r="30" fill="#9B51E0" />
|
||||
<path
|
||||
d="M37.9128 13.8507C38.2013 13.9992 38.2864 14.246 38.2814 14.5546C38.2714 15.1718 38.2781 15.7906 38.2781 16.4478C38.4182 16.4478 38.5299 16.4478 38.6417 16.4478C40.1145 16.4495 41.5857 16.4495 43.0586 16.4511C43.9126 16.4528 44.2879 16.8431 44.2696 17.6955C44.2229 19.7822 44.0077 21.8471 43.4005 23.8538C42.9368 25.39 42.283 26.8245 41.0787 27.9404C40.3331 28.6309 39.4523 29.0513 38.4415 29.1764C38.2514 29.1997 38.1863 29.2681 38.1463 29.4566C37.4691 32.6492 35.5742 34.7325 32.4467 35.6866C32.3116 35.7283 32.2032 35.76 32.2032 35.9485C32.2099 37.9251 32.2099 39.9017 32.2115 41.8783C32.2115 41.9083 32.2249 41.9383 32.2399 41.9984C32.345 42.0034 32.4567 42.0134 32.5685 42.0134C33.2307 42.0151 33.8929 42.0184 34.5551 42.0117C34.842 42.0084 35.0538 42.1101 35.2206 42.352C35.8878 43.3211 36.565 44.2852 37.2389 45.2493C37.3773 45.4478 37.5125 45.6797 37.3306 45.8798C37.2005 46.0216 36.9637 46.1384 36.7735 46.1401C32.4 46.1551 28.0248 46.1501 23.6513 46.1534C23.4178 46.1534 23.2109 46.1134 23.0858 45.8899C22.9524 45.6497 23.0491 45.4495 23.1892 45.2493C23.8581 44.2936 24.5287 43.3395 25.1875 42.377C25.3677 42.1151 25.5945 42.0084 25.9031 42.0117C26.6587 42.0201 27.4143 42.0134 28.2033 42.0134C28.21 41.8783 28.22 41.7665 28.22 41.6548C28.2216 39.7933 28.2166 37.9334 28.225 36.0719C28.2266 35.8368 28.1633 35.7383 27.9214 35.6633C24.8823 34.7158 22.9974 32.6909 22.3119 29.5767C22.2502 29.2965 22.1551 29.2014 21.8598 29.1547C20.407 28.9295 19.3128 28.1239 18.4738 26.9446C17.5047 25.5818 16.9993 24.0289 16.659 22.4159C16.3287 20.8497 16.1769 19.2601 16.1536 17.6588C16.1419 16.8214 16.5255 16.4478 17.3679 16.4461C18.8291 16.4445 20.2919 16.4428 21.7531 16.4428C21.8682 16.4428 21.9833 16.4428 22.1484 16.4428C22.1484 16.1476 22.1484 15.869 22.1484 15.5904C22.1484 15.2435 22.1567 14.8965 22.1467 14.5496C22.1367 14.241 22.2268 13.9925 22.5154 13.8457C27.6478 13.8507 32.7803 13.8507 37.9128 13.8507ZM30.2132 19.1633C29.8947 19.8072 29.561 20.361 29.3425 20.9581C29.109 21.5969 28.7154 21.8538 28.0482 21.8805C27.4177 21.9072 26.7922 22.0523 26.1116 22.1524C26.2217 22.2692 26.2901 22.3442 26.3635 22.4159C26.8972 22.938 27.4393 23.4518 27.9581 23.9872C28.0548 24.0873 28.1165 24.2791 28.1015 24.4176C28.0565 24.8346 27.9631 25.2449 27.8914 25.6586C27.8196 26.0839 27.7513 26.5109 27.6729 26.9913C28.4652 26.5743 29.2041 26.199 29.9297 25.7987C30.1415 25.6819 30.3 25.6936 30.5051 25.8053C31.2307 26.2023 31.968 26.5793 32.7236 26.9746C32.7236 26.8812 32.7319 26.8195 32.7219 26.7628C32.5902 25.9972 32.4667 25.2299 32.3183 24.4676C32.2749 24.2424 32.3233 24.0973 32.4884 23.9438C32.9338 23.5285 33.3624 23.0932 33.8011 22.6695C33.9629 22.5127 34.1331 22.3642 34.3649 22.1541C33.4609 22.024 32.6652 21.9005 31.8662 21.7971C31.6077 21.7637 31.4409 21.6837 31.3225 21.4201C30.9872 20.6829 30.6086 19.959 30.2132 19.1633ZM42.2813 18.4761C40.9219 18.4761 39.6075 18.4761 38.3014 18.4761C38.3014 21.3884 38.3014 24.2724 38.3014 27.2365C38.6517 27.088 38.9753 26.9913 39.2555 26.8228C40.1512 26.2841 40.6617 25.43 41.057 24.4993C41.5991 23.2249 41.8943 21.8838 42.0745 20.5177C42.1612 19.8422 42.2112 19.165 42.2813 18.4761ZM22.1301 27.1781C22.1301 24.2608 22.1301 21.3684 22.1301 18.4694C20.8023 18.4694 19.4963 18.4694 18.1819 18.4694C18.1785 18.5311 18.1719 18.5712 18.1735 18.6112C18.2753 20.2826 18.4988 21.9339 19.0142 23.5318C19.3278 24.5026 19.7198 25.445 20.4287 26.2107C20.8874 26.7077 21.4262 27.0664 22.1301 27.1781Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-xl tracking-wide text-dark-gray dark:text-white font-bold">
|
||||
Auther leavel up
|
||||
</p>
|
||||
<p className="text-base tracking-wide text-thin-light-gray">
|
||||
Evey new prodcuts sell you can get notifcation
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-5 sm:mt-0">
|
||||
<SwitchCom
|
||||
value={authLevel}
|
||||
handler={() => setAuthLevel(!authLevel)}
|
||||
/>
|
||||
</div>
|
||||
</li>
|
||||
</li>
|
||||
)}
|
||||
)
|
||||
:
|
||||
<h1 className='font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap'>No Cards Found</h1>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,134 +1,17 @@
|
||||
import React from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import method1 from "../../../assets/images/payment-method-1.png";
|
||||
import method2 from "../../../assets/images/payment-method-2.png";
|
||||
import method3 from "../../../assets/images/payment-method-3.png";
|
||||
import method4 from "../../../assets/images/payment-method-4.png";
|
||||
import CardList from "./CardList";
|
||||
|
||||
|
||||
export default function PaymentMathodsTab() {
|
||||
return (
|
||||
<>
|
||||
<div className="payment-method-tab w-full">
|
||||
<div className="payment-item-wrapper w-full">
|
||||
<ul className="payment-items">
|
||||
<li className="sm:flex justify-between items-center w-full py-[30px] border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] ">
|
||||
<div className="flex space-x-5 mb-3 sm:mb-0">
|
||||
<div className="sm:w-[120px] sm:h-[120px] flex items-center justify-center rounded-full sm:bg-light-purple dark:bg-dark-light-purple ">
|
||||
<img src={method1} alt="payment" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="sm:text-xl text-lg tracking-wide text-dark-gray dark:text-white">
|
||||
Datch Bangla Bank Ltd
|
||||
</p>
|
||||
<p className="text-thin-light-gray sm:text-18 text-sm tracking-wide">
|
||||
Bank **********5535
|
||||
</p>
|
||||
<p className="sm:text-18 text-sm tracking-wide text-light-green">
|
||||
Verified
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
className="w-[95px] sm:h-[46px] h-[40px] rounded-full btn-gradient text-white sm:text-18 text-md tracking-wide"
|
||||
>
|
||||
Manage
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
<li className="sm:flex justify-between items-center w-full py-[30px] border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] ">
|
||||
<div className="flex space-x-5 mb-3 sm:mb-0">
|
||||
<div className="sm:w-[120px] sm:h-[120px] flex items-center justify-center rounded-full sm:bg-light-purple dark:bg-dark-light-purple ">
|
||||
<img src={method2} alt="payment" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="sm:text-xl text-lg tracking-wide text-dark-gray dark:text-white">
|
||||
Master Card
|
||||
</p>
|
||||
<p className="text-thin-light-gray sm:text-18 text-sm tracking-wide">
|
||||
Bank **********5535
|
||||
</p>
|
||||
<p className="sm:text-18 text-sm tracking-wide text-light-green">
|
||||
Verified
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
className="w-[95px] sm:h-[46px] h-[40px] rounded-full btn-gradient text-white sm:text-18 text-md tracking-wide"
|
||||
>
|
||||
Manage
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
<li className="sm:flex justify-between items-center w-full py-[30px] border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] ">
|
||||
<div className="flex space-x-5 mb-3 sm:mb-0">
|
||||
<div className="sm:w-[120px] sm:h-[120px] flex items-center justify-center rounded-full sm:bg-light-purple dark:bg-dark-light-purple ">
|
||||
<img src={method3} alt="payment" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="sm:text-xl text-lg tracking-wide text-dark-gray dark:text-white">
|
||||
Paypal Account
|
||||
</p>
|
||||
<p className="text-thin-light-gray sm:text-18 text-sm tracking-wide">
|
||||
Bank **********5535
|
||||
</p>
|
||||
<p className="sm:text-18 text-sm tracking-wide text-light-green">
|
||||
Verified
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
className="w-[95px] sm:h-[46px] h-[40px] rounded-full btn-gradient text-white sm:text-18 text-md tracking-wide"
|
||||
>
|
||||
Manage
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
<li className="sm:flex justify-between items-center w-full py-[30px] border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] ">
|
||||
<div className="flex space-x-5 mb-3 sm:mb-0">
|
||||
<div className="sm:w-[120px] sm:h-[120px] flex items-center justify-center rounded-full sm:bg-light-purple dark:bg-dark-light-purple ">
|
||||
<img src={method4} alt="payment" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="sm:text-xl text-lg tracking-wide text-dark-gray dark:text-white">
|
||||
Visa Card
|
||||
</p>
|
||||
<p className="text-thin-light-gray sm:text-18 text-sm tracking-wide">
|
||||
Bank **********5535
|
||||
</p>
|
||||
<p className="text-18 tracking-wide text-light-red">
|
||||
Unverified
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
className="w-[95px] sm:h-[46px] h-[40px] rounded-full btn-gradient text-white sm:text-18 text-md tracking-wide"
|
||||
>
|
||||
Manage
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<div className="py-7 flex space-x-4">
|
||||
<button
|
||||
type="button"
|
||||
className="btn-shine text-white text-18 bg-pink tracking-wide px-4 py-3 rounded-full"
|
||||
>
|
||||
Add Bank
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="text-white text-18 bg-light-green tracking-wide px-4 py-3 rounded-full"
|
||||
>
|
||||
Add Card
|
||||
</button>
|
||||
</div>
|
||||
<CardList />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
||||
@@ -58,7 +58,7 @@ export default function Settings({ faq }) {
|
||||
{
|
||||
id: 2,
|
||||
name: "payment",
|
||||
title: "Payment Method",
|
||||
title: "Payment Cards",
|
||||
iconName: "bank-card",
|
||||
},
|
||||
{
|
||||
|
||||
@@ -253,7 +253,7 @@ function JobListPopout({ details, onClose, situation }) {
|
||||
>
|
||||
{(props) => {
|
||||
return (
|
||||
<Form className="mb-4">
|
||||
<Form className="mb-4 hidden">
|
||||
{/* Assign to Family */}
|
||||
<JobFieldInput
|
||||
label="Assign to family"
|
||||
|
||||
@@ -11,6 +11,14 @@
|
||||
font-family: "Product Sans";
|
||||
src: url("./assets/fonts/Product Sans Bold.ttf");
|
||||
}
|
||||
.SENDER{
|
||||
margin-left: 60px !important;
|
||||
background-color: azure;
|
||||
}
|
||||
.RECIPIENT{
|
||||
margin-right: 60px !important;
|
||||
background-color: #add8e6 !important;
|
||||
}
|
||||
.wallet-box{
|
||||
background-color: aliceblue;
|
||||
border-radius: 20px;
|
||||
@@ -24,6 +32,13 @@
|
||||
.referral{
|
||||
margin-bottom: 20px
|
||||
}
|
||||
.task_action_panel{
|
||||
font-family: sans; color: white;
|
||||
font-weight: bolder;
|
||||
font-size: 14px;
|
||||
font-family: Circular, Helvetica Neue, Helvetica, Roboto, Arial, sans-serif;
|
||||
padding: 0px 10px 5px 10px
|
||||
}
|
||||
.heroSilderTitle{
|
||||
text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;
|
||||
font-family: sans; color: white;
|
||||
@@ -34,7 +49,7 @@
|
||||
min-width: 280px !important;
|
||||
}
|
||||
.job-action{
|
||||
background-color: aliceblue;
|
||||
background-color: #4687ba;
|
||||
height: 100px;
|
||||
border-radius: 15px;
|
||||
padding: 5px;
|
||||
@@ -47,9 +62,12 @@
|
||||
border-radius: 15px;
|
||||
}
|
||||
.msg_header{
|
||||
background-color: #1a3544;
|
||||
color: white;
|
||||
background-color: white;
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
border-radius: 9px;
|
||||
font-size: 14px;
|
||||
font-family: Circular, Helvetica Neue, Helvetica, Roboto, Arial, sans-serif;
|
||||
}
|
||||
.siderCardDescription{
|
||||
background-color: aliceblue;
|
||||
|
||||
@@ -39,12 +39,12 @@ class usersService {
|
||||
localStorage.setItem("session_token", ``);
|
||||
return this.postAuxEnd("/authstart", reqData);
|
||||
}
|
||||
|
||||
|
||||
authLogin(reqData) {
|
||||
localStorage.setItem("session_token", ``);
|
||||
return this.postAuxEnd("/authlogin", reqData);
|
||||
}
|
||||
|
||||
|
||||
marketJobData(reqData) {
|
||||
var postData = {
|
||||
uuid: localStorage.getItem("uuid"),
|
||||
@@ -216,6 +216,28 @@ class usersService {
|
||||
return this.postAuxEnd("/sendmoneyfee", postData);
|
||||
}
|
||||
|
||||
getStartCredit(value) {
|
||||
var postData = {
|
||||
uid: localStorage.getItem("uid"),
|
||||
member_id: localStorage.getItem("member_id"),
|
||||
sessionid: localStorage.getItem("session_token"),
|
||||
action: 11053,
|
||||
...value,
|
||||
};
|
||||
return this.postAuxEnd("/startcredit", postData);
|
||||
}
|
||||
|
||||
getPaidPrevCard(value) {
|
||||
var postData = {
|
||||
uid: localStorage.getItem("uid"),
|
||||
member_id: localStorage.getItem("member_id"),
|
||||
sessionid: localStorage.getItem("session_token"),
|
||||
action: 11056,
|
||||
...value,
|
||||
};
|
||||
return this.postAuxEnd("/payprevcard", postData);
|
||||
}
|
||||
|
||||
getFamilySampleTasks() {
|
||||
var postData = {
|
||||
uid: localStorage.getItem("uid"),
|
||||
@@ -899,6 +921,53 @@ class usersService {
|
||||
return this.postAuxEnd("/familysuggestlist", postData);
|
||||
}
|
||||
|
||||
// FUNCTION TO CHANGE PROFILE PASSWORD
|
||||
profilePassChange(reqData) {
|
||||
var postData = {
|
||||
uid: localStorage.getItem("uid"),
|
||||
member_id: localStorage.getItem("member_id"),
|
||||
sessionid: localStorage.getItem("session_token"),
|
||||
action: 11005,
|
||||
...reqData,
|
||||
};
|
||||
return this.postAuxEnd("/profilepasschange", postData);
|
||||
}
|
||||
|
||||
// FUNCTION TO GET ACCOUNT SETTINGS
|
||||
getAccSettings() {
|
||||
var postData = {
|
||||
uid: localStorage.getItem("uid"),
|
||||
member_id: localStorage.getItem("member_id"),
|
||||
sessionid: localStorage.getItem("session_token"),
|
||||
action: 11059,
|
||||
};
|
||||
return this.postAuxEnd("/getaccsettings", postData);
|
||||
}
|
||||
|
||||
// FUNCTION TO SET ACCOUNT SETTINGS
|
||||
setAccSettings(reqdata) {
|
||||
var postData = {
|
||||
uid: localStorage.getItem("uid"),
|
||||
member_id: localStorage.getItem("member_id"),
|
||||
sessionid: localStorage.getItem("session_token"),
|
||||
action: 11058,
|
||||
...reqdata,
|
||||
};
|
||||
return this.postAuxEnd("/setaccsettings", postData);
|
||||
}
|
||||
|
||||
// FUNCTION TO DELETE PAY CARD
|
||||
payRemCard(reqData) {
|
||||
var postData = {
|
||||
uid: localStorage.getItem("uid"),
|
||||
member_id: localStorage.getItem("member_id"),
|
||||
sessionid: localStorage.getItem("session_token"),
|
||||
action: 11057,
|
||||
...reqData,
|
||||
};
|
||||
return this.postAuxEnd("/payremcard", postData);
|
||||
}
|
||||
|
||||
/*
|
||||
- 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(username)
|
||||
- 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(password)
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import React from 'react'
|
||||
|
||||
import AppleRedirect from '../components/AuthPages/AuthRedirect/AppleRedirect'
|
||||
|
||||
function AppleRedirectPage() {
|
||||
return (
|
||||
<>
|
||||
<AppleRedirect />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default AppleRedirectPage
|
||||
@@ -0,0 +1,13 @@
|
||||
import React from 'react'
|
||||
|
||||
import FbookRedirect from '../components/AuthPages/AuthRedirect/FbookRedirect'
|
||||
|
||||
function FacebookRedirect() {
|
||||
return (
|
||||
<>
|
||||
<FbookRedirect />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default FacebookRedirect
|
||||
@@ -1,5 +1,3 @@
|
||||
import React from "react";
|
||||
// import MyWallet from "../components/MyWallet";
|
||||
import WalletRoutes from "../components/MyWallet/Wallet";
|
||||
|
||||
export default function MyWalletPage() {
|
||||
|
||||
@@ -20,6 +20,10 @@ module.exports = {
|
||||
'sky-blue': '#3a8fc3',
|
||||
'alice-blue': '#f0f8ff'
|
||||
},
|
||||
screens:{
|
||||
xxs: '400px',
|
||||
xxl:'1900px'
|
||||
}
|
||||
},
|
||||
},
|
||||
plugins: [require("@tailwindcss/line-clamp")],
|
||||
|
||||