Compare commits
91 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 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 | |||
| 8b01139b93 | |||
| 8511db6961 | |||
| 99c81fd4ee | |||
| ef545c9714 | |||
| 029a7327a8 | |||
| 5a5d933b24 | |||
| 9f19c930b7 | |||
| 84d7fabae7 | |||
| b245f87556 | |||
| bed5303fa4 | |||
| a5af8ed722 | |||
| ec97d118b2 | |||
| 85213c31a1 | |||
| f9b6c68f99 | |||
| 2a4b77c9a0 | |||
| 97aa5dba21 | |||
| 58a10ca6be | |||
| f3edf1d90b | |||
| 1f7b310b6f | |||
| aecb06ca96 | |||
| d89194f18e | |||
| 03866d666b | |||
| 4224be46bc | |||
| 5dad00096a | |||
| 72da5c707a | |||
| 625928e34b | |||
| 6fd92600b4 | |||
| 133f500849 | |||
| b1f1b34924 | |||
| e80c3528db | |||
| 3eb6960cc7 | |||
| eb01e35c75 | |||
| 0cc70d66b3 | |||
| 7111e81f11 | |||
| 1c64771dcd | |||
| ac1a4f895a | |||
| 22f5bd01d2 | |||
| 467528835a |
@@ -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_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_GOOGLE_REDIRECT_URL=http://localhost:9082/login/auth/
|
||||||
|
|
||||||
REACT_APP_FACEBOOK_CLIENT_ID=390204307987009
|
#Real Account
|
||||||
REACT_APP_FACEBOOK_CLIENT_SECRET=19f778e312f2ab96d147bacb612910c2
|
REACT_APP_FACEBOOK_CLIENT_ID2=390204307987009
|
||||||
REACT_APP_FACEBOOK_CLIENT_SCOPE="email, public_profile"
|
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_MAX_FILE_SIZE=1000000
|
||||||
REACT_APP_TOTAL_NUM_FILE=4
|
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_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_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
|
DISABLE_ESLINT_PLUGIN=true
|
||||||
|
|
||||||
REACT_APP_MAX_FILE_SIZE=1000000
|
REACT_APP_MAX_FILE_SIZE=1000000
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
"flutterwave-react-v3": "^1.3.0",
|
"flutterwave-react-v3": "^1.3.0",
|
||||||
"formik": "^2.2.9",
|
"formik": "^2.2.9",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
|
"react-apple-login": "^1.1.6",
|
||||||
"react-chartjs-2": "^4.1.0",
|
"react-chartjs-2": "^4.1.0",
|
||||||
"react-countup": "^6.2.0",
|
"react-countup": "^6.2.0",
|
||||||
"react-dom": "^18.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 ManageInterestOfferPage from './views/ManageInterestOfferPage'
|
||||||
import MyWaitingJobsPage from "./views/MyWaitingJobsPage";
|
import MyWaitingJobsPage from "./views/MyWaitingJobsPage";
|
||||||
import FamilyMarketPage from "./views/FamilyMarketPage";
|
import FamilyMarketPage from "./views/FamilyMarketPage";
|
||||||
|
import FacebookRedirect from "./views/FacebookRedirect";
|
||||||
|
import AppleRedirectPage from "./views/AppleRedirectPage";
|
||||||
|
|
||||||
export default function Routers() {
|
export default function Routers() {
|
||||||
return (
|
return (
|
||||||
@@ -56,6 +58,8 @@ export default function Routers() {
|
|||||||
<Route exact path="/login" element={<LoginPage />} />
|
<Route exact path="/login" element={<LoginPage />} />
|
||||||
<Route exact path="/signup" element={<SignupPage />} />
|
<Route exact path="/signup" element={<SignupPage />} />
|
||||||
<Route exact path="/login/auth" element={<AuthRedirect />} />
|
<Route exact path="/login/auth" element={<AuthRedirect />} />
|
||||||
|
<Route exact path="/login/auth/flogin" element={<FacebookRedirect />} />
|
||||||
|
<Route exact path="/login/auth/apple" element={<AppleRedirectPage />} />
|
||||||
<Route
|
<Route
|
||||||
exact
|
exact
|
||||||
path="/forgot-password"
|
path="/forgot-password"
|
||||||
|
|||||||
|
After Width: | Height: | Size: 6.2 KiB |
|
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 |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="identificationcard"><path fill="#4687ba" d="M0 6v13c0 1.103.897 2 2 2h20c1.103 0 2-.897 2-2V6" class="color2d98d4 svgShape"></path><path fill="#ff6699" d="M22 3H2a2 2 0 0 0-2 2v2h24V5a2 2 0 0 0-2-2z" class="color0377be svgShape"></path><path fill="#e6e7f9" d="M22 3H2C.897 3 0 3.897 0 5v.25c0-1.103.897-2 2-2h20c1.103 0 2 .897 2 2V5c0-1.103-.897-2-2-2z" opacity=".2" class="colorffffff svgShape"></path><path fill="#4687ba" d="M22 20.75H2c-1.103 0-2-.897-2-2V19c0 1.103.897 2 2 2h20c1.103 0 2-.897 2-2v-.25c0 1.103-.897 2-2 2z" opacity=".1" class="color010101 svgShape"></path><path fill="#e6e7f9" d="M13 17h8v1h-8zM13 14h8v1h-8zM13 11h8v1h-8z" class="colorffffff svgShape"></path><circle cx="7" cy="12" r="2" fill="#e6e7f9" class="colorffffff svgShape"></circle><path fill="#e6e7f9" d="M9.987 15.237C9.288 14.9 8.203 14.5 7 14.5s-2.288.4-2.987.737c-.625.3-1.013.9-1.013 1.566V18h8v-1.197c0-.665-.388-1.265-1.013-1.566z" class="colorffffff svgShape"></path><circle cx="17" cy="5" r="1" fill="#ff6699" class="color0a70b9 svgShape"></circle><path fill="#4687ba" d="M17 4.25a.99.99 0 0 1 .975.875C17.98 5.082 18 5.045 18 5a1 1 0 0 0-2 0c0 .044.02.082.025.125A.99.99 0 0 1 17 4.25z" opacity=".1" class="color010101 svgShape"></path><linearGradient id="a" x1="6.973" x2="21.55" y1="1.973" y2="16.55" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#010101" stop-opacity=".1" class="stopColor010101 svgShape"></stop><stop offset="1" stop-color="#010101" stop-opacity="0" class="stopColor010101 svgShape"></stop></linearGradient><path fill="url(#a)" d="M22 21c1.103 0 2-.897 2-2V7H0l14 14h8z"></path><circle cx="7" cy="5" r="1" fill="#ff6699" class="color0a70b9 svgShape"></circle><path fill="#4687ba" d="M7 4.25a.99.99 0 0 1 .975.875C7.98 5.082 8 5.045 8 5a1 1 0 0 0-2 0c0 .044.02.082.025.125A.99.99 0 0 1 7 4.25z" opacity=".1" class="color010101 svgShape"></path><linearGradient id="b" x1="-.708" x2="24.708" y1="6.074" y2="17.925" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ffffff" stop-opacity=".2" class="stopColorffffff svgShape"></stop><stop offset="1" stop-color="#ffffff" stop-opacity="0" class="stopColorffffff svgShape"></stop></linearGradient><path fill="url(#b)" d="M22 3H2a2 2 0 0 0-2 2v14c0 1.103.897 2 2 2h20c1.103 0 2-.897 2-2V5a2 2 0 0 0-2-2z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -0,0 +1,3 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 128 128" viewBox="0 0 128 128" id="Pin"><path fill="#4687ba" d="M106,13.8L91.7,4.6C86.2,1,78.9,2,74.5,7L41.9,46.9c-9.1,0.4-17.9,3.3-25.4,8.7c-0.7,0.5-0.7,1.6,0.1,2.1
|
||||||
|
l10.2,6.6l0,0L46.4,77l-24,41.4c-1.2,2.1-0.7,4.9,1.4,6.3c2.2,1.6,5.2,1.1,6.7-1.1l28-38.8L78,97.5l0,0l10.2,6.6
|
||||||
|
c0.7,0.5,1.7,0.1,1.9-0.8c1.8-9,0.9-18.3-2.5-26.8l23.1-46C113.6,24.5,111.5,17.4,106,13.8z" class="color2d3e50 svgShape"></path></svg>
|
||||||
|
After Width: | Height: | Size: 482 B |
|
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
|
||||||
@@ -1,22 +1,63 @@
|
|||||||
import React, {useState, useEffect} from 'react'
|
import React, { useEffect } from 'react';
|
||||||
import { useLocation, useNavigate } from 'react-router-dom'
|
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 Redirect() {
|
function Redirect() {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const userApi = new usersService();
|
||||||
|
const dispatch = useDispatch()
|
||||||
|
|
||||||
const queryParams = new URLSearchParams(location?.search);
|
const queryParams = new URLSearchParams(location?.search);
|
||||||
const codeResponse = queryParams.get("code");
|
const codeResponse = queryParams.get("code");
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
if(!codeResponse){
|
if(!codeResponse){
|
||||||
navigate('/login', {replace: true})
|
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: "GOOGLE",
|
||||||
|
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
|
return
|
||||||
}
|
}
|
||||||
console.log(codeResponse)
|
navigate('/login', {state: {error: true}})
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
navigate('/login', {state: {error: true}})
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
},[])
|
},[])
|
||||||
return (
|
return (
|
||||||
<div>Redirecting ... </div>
|
<AuthLayout>
|
||||||
|
<div className='min-h-[70vh]'>Redirecting ... </div>
|
||||||
|
</AuthLayout>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { useEffect, useLayoutEffect, useState } from "react";
|
import React, { useEffect, useLayoutEffect, useState } from "react";
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
import { Link, useNavigate, useLocation } from "react-router-dom";
|
||||||
import linkedInLogo from "../../../assets/images/Linkedin.png";
|
import linkedInLogo from "../../../assets/images/Linkedin.png";
|
||||||
import appleLogo from "../../../assets/images/apple-black.svg";
|
import appleLogo from "../../../assets/images/apple-black.svg";
|
||||||
import facebookLogo from "../../../assets/images/facebook-4.svg";
|
import facebookLogo from "../../../assets/images/facebook-4.svg";
|
||||||
@@ -16,12 +16,15 @@ import { updateUserDetails } from "../../../store/UserDetails";
|
|||||||
|
|
||||||
export default function Login() {
|
export default function Login() {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
const {state} = useLocation()
|
||||||
|
|
||||||
let [loginType, setLoginType] = useState('');
|
let [loginType, setLoginType] = useState('');
|
||||||
|
|
||||||
const [checked, setValue] = useState(false);
|
const [checked, setValue] = useState(false);
|
||||||
const [loginLoading, setLoginLoading] = useState(false);
|
const [loginLoading, setLoginLoading] = useState(false);
|
||||||
|
|
||||||
|
const [showPassword, setShowPassword] = useState(false);
|
||||||
|
|
||||||
//login error state
|
//login error state
|
||||||
const [loginError, setLoginError] = useState(false);
|
const [loginError, setLoginError] = useState(false);
|
||||||
// for the catch error
|
// for the catch error
|
||||||
@@ -31,6 +34,11 @@ export default function Login() {
|
|||||||
setValue(!checked);
|
setValue(!checked);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// To Show and Hide Password
|
||||||
|
const togglePasswordVisibility = () => {
|
||||||
|
setShowPassword(!showPassword);
|
||||||
|
};
|
||||||
|
|
||||||
//FUNCTION TO DETERMINE/CHANGE LOGIN COMPONENT
|
//FUNCTION TO DETERMINE/CHANGE LOGIN COMPONENT
|
||||||
const handleLoginType = ({ target: { name } }) => {
|
const handleLoginType = ({ target: { name } }) => {
|
||||||
setLoginType(name);
|
setLoginType(name);
|
||||||
@@ -70,6 +78,13 @@ export default function Login() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (name == "full") {
|
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
|
// Post Data Info for normal Login
|
||||||
postData = {
|
postData = {
|
||||||
username: email,
|
username: email,
|
||||||
@@ -98,7 +113,7 @@ export default function Login() {
|
|||||||
userApi
|
userApi
|
||||||
.logInUser(postData)
|
.logInUser(postData)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.status != 200 || res.data.internal_return < 0) {
|
if (res.status != 200 || res.data.internal_return < 0 || !res.data.member_id || !res.data.uid || !res.data.session) {
|
||||||
// setMsgError("Wrong, email/password");
|
// setMsgError("Wrong, email/password");
|
||||||
setLoginError(true);
|
setLoginError(true);
|
||||||
setLoginLoading(false);
|
setLoginLoading(false);
|
||||||
@@ -108,7 +123,7 @@ export default function Login() {
|
|||||||
localStorage.setItem("uid", `${res.data.uid}`);
|
localStorage.setItem("uid", `${res.data.uid}`);
|
||||||
localStorage.setItem("session_token", `${res.data.session}`);
|
localStorage.setItem("session_token", `${res.data.session}`);
|
||||||
// localStorage.setItem("session", `${res.data.session}`);
|
// localStorage.setItem("session", `${res.data.session}`);
|
||||||
dispatch(updateUserDetails({...res.data, loggedIn:true}));
|
dispatch(updateUserDetails({...res.data}));
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
navigate("/", { replace: true });
|
navigate("/", { replace: true });
|
||||||
setLoginLoading(false);
|
setLoginLoading(false);
|
||||||
@@ -168,6 +183,14 @@ export default function Login() {
|
|||||||
}
|
}
|
||||||
let loginValue = readCookie('loginType')
|
let loginValue = readCookie('loginType')
|
||||||
setLoginType(loginValue)
|
setLoginType(loginValue)
|
||||||
|
|
||||||
|
if(state?.error){ //check if the login path has an error state indicating any social handle login with error
|
||||||
|
setMsgError("Unexpected Error, Please try again soon.");
|
||||||
|
setTimeout(()=>{
|
||||||
|
setMsgError("");
|
||||||
|
navigate('/login', {replace: true})
|
||||||
|
},4000)
|
||||||
|
}
|
||||||
},[])
|
},[])
|
||||||
|
|
||||||
|
|
||||||
@@ -189,7 +212,7 @@ export default function Login() {
|
|||||||
/>
|
/>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className="content-wrapper login shadow-md w-full lg:max-w-[500px] mx-auto flex justify-center items-center xl:bg-white dark:bg-dark-white 2xl:w-[828px] rounded-[0.475rem] sm:p-7 p-5">
|
<div className="content-wrapper login shadow-md w-full lg:max-w-[530px] mx-auto flex justify-center items-center xl:bg-white dark:bg-dark-white 2xl:w-[828px] rounded-[0.475rem] sm:p-7 p-5">
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
|
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
|
||||||
{/* <h1 className="text-[#181c32] font-semibold dark:text-white mb-3 leading-[27.3px] text-[22.75px]">
|
{/* <h1 className="text-[#181c32] font-semibold dark:text-white mb-3 leading-[27.3px] text-[22.75px]">
|
||||||
@@ -211,7 +234,7 @@ export default function Login() {
|
|||||||
<button
|
<button
|
||||||
name="full"
|
name="full"
|
||||||
className={`login-type-btn px-4 py-1 rounded-t-2xl ${
|
className={`login-type-btn px-4 py-1 rounded-t-2xl ${
|
||||||
loginType=='full' ? "bg-white text-[#000] border-t-[2px]" : "bg-[#4687ba] border-[2px] border-[#4687ba] text-white"
|
loginType=='full' ? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white" : "bg-white text-[#000] border-t-[2px]"
|
||||||
}`}
|
}`}
|
||||||
onClick={handleLoginType}
|
onClick={handleLoginType}
|
||||||
>
|
>
|
||||||
@@ -220,7 +243,7 @@ export default function Login() {
|
|||||||
<button
|
<button
|
||||||
name="family"
|
name="family"
|
||||||
className={`login-type-btn px-4 py-1 rounded-t-2xl ${
|
className={`login-type-btn px-4 py-1 rounded-t-2xl ${
|
||||||
loginType=='family' ? "bg-white text-[#000] border-t-[2px]" : "bg-[#4687ba] border-[2px] border-[#4687ba] text-white"
|
loginType=='family' ? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white" : "bg-white text-[#000] border-t-[2px]"
|
||||||
}`}
|
}`}
|
||||||
onClick={handleLoginType}
|
onClick={handleLoginType}
|
||||||
>
|
>
|
||||||
@@ -234,7 +257,7 @@ export default function Login() {
|
|||||||
{
|
{
|
||||||
loginType == 'full' ? (
|
loginType == 'full' ? (
|
||||||
//user login component
|
//user login component
|
||||||
<div className="p-2 input-area login-area border-2 border-[#4687ba] rounded-2xl">
|
<div className="p-6 input-area login-area border-2 border-[#4687ba] rounded-2xl">
|
||||||
<div className="input-item mb-5">
|
<div className="input-item mb-5">
|
||||||
<InputCom
|
<InputCom
|
||||||
labelClass="tracking-wider"
|
labelClass="tracking-wider"
|
||||||
@@ -258,8 +281,9 @@ export default function Login() {
|
|||||||
placeholder="● ● ● ● ● ●"
|
placeholder="● ● ● ● ● ●"
|
||||||
label="Password"
|
label="Password"
|
||||||
name="password"
|
name="password"
|
||||||
type="password"
|
type={showPassword ? "text" : "password"}
|
||||||
iconName="password"
|
onClick={togglePasswordVisibility}
|
||||||
|
passIcon={showPassword ? "password" : "password"}
|
||||||
forgotPassword
|
forgotPassword
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -297,32 +321,40 @@ export default function Login() {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="sm:flex sm:justify-between sm:items-center sm:space-x-2">
|
<div className="sm:flex sm:justify-between sm:items-center sm:space-x-2">
|
||||||
<BrandBtn
|
<BrandBtn
|
||||||
link="#"
|
link="#"
|
||||||
imgSrc={googleLogo}
|
imgSrc={googleLogo}
|
||||||
brand="Google"
|
brand="Google"
|
||||||
onClick={googleLogin}
|
onClick={googleLogin}
|
||||||
/>
|
/>
|
||||||
<BrandBtn link="#" imgSrc={appleLogo} brand="Apple" />
|
<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>
|
||||||
<div className="sm:flex sm:justify-between sm:items-center sm:space-x-2">
|
<div className="sm:flex sm:justify-between sm:items-center sm:space-x-2">
|
||||||
<BrandBtn
|
<BrandBtn
|
||||||
link="#"
|
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}
|
imgSrc={facebookLogo}
|
||||||
brand="Facebook"
|
brand="Facebook"
|
||||||
/>
|
isAnchor={true}
|
||||||
<BrandBtn
|
/>
|
||||||
link="#"
|
<BrandBtn
|
||||||
imgSrc={linkedInLogo}
|
// 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"
|
||||||
brand="LinkedIn"
|
imgSrc={linkedInLogo}
|
||||||
/>
|
brand="LinkedIn"
|
||||||
|
isAnchor={true}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
// END of user login compoenent
|
// END of user login compoenent
|
||||||
// family login compoenent
|
// family login compoenent
|
||||||
<div className="p-2 input-area login-area border-2 border-[#4687ba] rounded-2xl">
|
<div className="p-6 input-area login-area border-2 border-[#4687ba] rounded-2xl">
|
||||||
<div className="input-item mb-5">
|
<div className="input-item mb-5">
|
||||||
<InputCom
|
<InputCom
|
||||||
labelClass="tracking-wider"
|
labelClass="tracking-wider"
|
||||||
@@ -333,7 +365,7 @@ export default function Login() {
|
|||||||
label="Username"
|
label="Username"
|
||||||
name="email"
|
name="email"
|
||||||
type="email"
|
type="email"
|
||||||
iconName="message"
|
iconName="family-id"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -346,9 +378,9 @@ export default function Login() {
|
|||||||
placeholder="● ● ● ● ● ●"
|
placeholder="● ● ● ● ● ●"
|
||||||
label="Pin"
|
label="Pin"
|
||||||
name="password"
|
name="password"
|
||||||
type="password"
|
type={showPassword ? "text" : "password"}
|
||||||
iconName="password"
|
onClick={togglePasswordVisibility}
|
||||||
// forgotPassword
|
passIcon={showPassword ? "family-pin" : "family-pin"}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{loginError && (
|
{loginError && (
|
||||||
@@ -403,7 +435,7 @@ export default function Login() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const BrandBtn = ({ link, imgSrc, brand, onClick }) => {
|
const BrandBtn = ({ link, imgSrc, brand, onClick, isAnchor=false }) => {
|
||||||
// const doGoogle = async () => {
|
// const doGoogle = async () => {
|
||||||
// alert("start google");
|
// alert("start google");
|
||||||
// };
|
// };
|
||||||
@@ -422,10 +454,23 @@ const BrandBtn = ({ link, imgSrc, brand, onClick }) => {
|
|||||||
// const doFacebook = async () => {
|
// const doFacebook = async () => {
|
||||||
// alert("start facebook");
|
// alert("start facebook");
|
||||||
// };
|
// };
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full sm:w-1/2 flex justify-center bottomMargin">
|
<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}
|
onClick={onClick}
|
||||||
// href="#dd"
|
// 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"
|
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"
|
||||||
@@ -435,6 +480,9 @@ const BrandBtn = ({ link, imgSrc, brand, onClick }) => {
|
|||||||
Continue with {brand}
|
Continue with {brand}
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
|
)
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
);
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -72,6 +72,12 @@ export default function SignUp() {
|
|||||||
return setTimeout(()=>{setMsgError("");},3000)
|
return setTimeout(()=>{setMsgError("");},3000)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//checks if terms and condition is checked
|
||||||
|
if (!checked) {
|
||||||
|
setMsgError("Terms and condition required");
|
||||||
|
return setTimeout(()=>{setMsgError("");},3000)
|
||||||
|
}
|
||||||
|
|
||||||
setSignUpLoading(true);
|
setSignUpLoading(true);
|
||||||
const reqData = {
|
const reqData = {
|
||||||
country: country,
|
country: country,
|
||||||
@@ -89,7 +95,7 @@ export default function SignUp() {
|
|||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
const { data } = res;
|
const { data } = res;
|
||||||
if (data && data.acc === "DULPICATE") {
|
if (data && data.acc === "DULPICATE") {
|
||||||
setMsgError("This account has been already created");
|
setMsgError("Unable to use this username. Please try another username.");
|
||||||
setSignUpLoading(false);
|
setSignUpLoading(false);
|
||||||
}
|
}
|
||||||
if (data && data.status === "1") {
|
if (data && data.status === "1") {
|
||||||
@@ -131,7 +137,7 @@ export default function SignUp() {
|
|||||||
/>
|
/>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className="content-wrapper login shadow-md w-full lg:max-w-[500px] mx-auto flex justify-center items-center xl:bg-white dark:bg-dark-white 2xl:w-[828px] rounded-[0.475rem] sm:p-7 p-5 mb-0">
|
<div className="content-wrapper login relative shadow-md w-full lg:max-w-[530px] mx-auto flex justify-center items-center xl:bg-white dark:bg-dark-white 2xl:w-[828px] rounded-[0.475rem] sm:p-7 p-5 mb-0">
|
||||||
<div>
|
<div>
|
||||||
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
|
<div className="title-area flex flex-col justify-center items-center relative text-center mb-7">
|
||||||
<h1 className="text-[#181c32] font-semibold dark:text-white mb-3 leading-[27.3px] text-[22.75px]">
|
<h1 className="text-[#181c32] font-semibold dark:text-white mb-3 leading-[27.3px] text-[22.75px]">
|
||||||
@@ -213,7 +219,7 @@ export default function SignUp() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{msgError && (
|
{msgError && (
|
||||||
<div className="relative p-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px]">
|
<div className="p-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px]">
|
||||||
{msgError}
|
{msgError}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -298,7 +304,7 @@ const SelectOption = ({
|
|||||||
<select
|
<select
|
||||||
name={name}
|
name={name}
|
||||||
id={name}
|
id={name}
|
||||||
className="input-wrapper border border-[#f5f8fa]] dark:border-[#5e6278] w-full rounded-[0.475rem] 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 focus-visible:border-transparent focus-visible:outline-0 focus-visible:ring-transparent "
|
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 focus-visible:border-transparent focus-visible:outline-0 focus-visible:ring-transparent "
|
||||||
onChange={inputHandler}
|
onChange={inputHandler}
|
||||||
value={value}
|
value={value}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -86,10 +86,14 @@ export default function VerifyLink() {
|
|||||||
const verifyRes = await userApi.verifyEmail(code);
|
const verifyRes = await userApi.verifyEmail(code);
|
||||||
if (verifyRes.status === 200) {
|
if (verifyRes.status === 200) {
|
||||||
let { data } = verifyRes;
|
let { data } = verifyRes;
|
||||||
|
console.log('TESTING VERIFY',data)
|
||||||
if (
|
if (
|
||||||
data &&
|
data &&
|
||||||
data.internal_return >= 0 &&
|
data.internal_return >= 0 &&
|
||||||
|
data.status == 0 &&
|
||||||
|
data.pending_id != '' &&
|
||||||
|
data.pending_uid != '' &&
|
||||||
|
data.username != '' &&
|
||||||
data.status_text === "Link Verified"
|
data.status_text === "Link Verified"
|
||||||
) {
|
) {
|
||||||
setPageLoader(false);
|
setPageLoader(false);
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ export default function FamilyActiveJobsCard({ datas, hidden = false }) {
|
|||||||
toast.warn("Remove to Favorite List");
|
toast.warn("Remove to Favorite List");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
//debugger;
|
||||||
|
const bannerName = datas.banner == null ?'default.jpg':datas.banner;
|
||||||
return (
|
return (
|
||||||
<div className="card-style-one flex flex-col justify-between w-full h-[387px] bg-white dark:bg-dark-white p-3 pb rounded-2xl">
|
<div className="card-style-one flex flex-col justify-between w-full h-[387px] bg-white dark:bg-dark-white p-3 pb rounded-2xl">
|
||||||
<div className="content">
|
<div className="content">
|
||||||
@@ -32,7 +33,7 @@ export default function FamilyActiveJobsCard({ datas, hidden = false }) {
|
|||||||
className="thumbnail w-full h-full rounded-xl overflow-hidden px-4 pt-4"
|
className="thumbnail w-full h-full rounded-xl overflow-hidden px-4 pt-4"
|
||||||
style={{
|
style={{
|
||||||
background: `url(${localImgLoad(
|
background: `url(${localImgLoad(
|
||||||
`images/taskbanners/${datas.banner}`
|
`images/taskbanners/${bannerName}`
|
||||||
)}) center / contain no-repeat`,
|
)}) center / contain no-repeat`,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -17,21 +17,21 @@ export default function HomeBannerOffersCard(props) {
|
|||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
to={link_result}
|
to={link_result}
|
||||||
className="item w-full block group banner-630-340 bg-cover bg-center"
|
className="item p-2 w-full flex items-center min-h-[340px] bg-alice-blue bg-cover bg-center"
|
||||||
style={{
|
style={{
|
||||||
backgroundImage: `url('${imageUrl}')`,
|
backgroundImage: `url('${imageUrl}')`,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="flex flex-col justify-between h-full">
|
<div className="w-[80%] h-full mx-auto flex flex-col justify-between">
|
||||||
<div className="content flex justify-between items-center">
|
<div className="content flex justify-between items-center">
|
||||||
<div className="siderCardHeader">
|
<div className="mb-2">
|
||||||
<h1 className="text-2xl font-bold text-dark-gray dark:text-white tracking-wide">
|
<h1 className="text-2xl lg:text-4xl font-bold text-dark-gray dark:text-white tracking-wide">
|
||||||
<span className="heroSilderTitle">{props.itemData.title}</span>
|
<span className="heroSilderTitle">{props.itemData.title}</span>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col justify-around items-center flex-1">
|
<div className="flex flex-col justify-around items-center flex-1">
|
||||||
<div className="siderCardDescription">
|
<div className="siderCardDescription mb-2">
|
||||||
{props.itemData.description}
|
{props.itemData.description}
|
||||||
</div>
|
</div>
|
||||||
<button className="w-[150px] h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white">
|
<button className="w-[150px] h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white">
|
||||||
|
|||||||
@@ -1,26 +1,28 @@
|
|||||||
import React, {
|
import React, {
|
||||||
Suspense,
|
Suspense,
|
||||||
|
lazy,
|
||||||
useCallback,
|
useCallback,
|
||||||
useEffect,
|
useEffect,
|
||||||
useMemo,
|
useMemo,
|
||||||
useRef,
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
|
useTransition,
|
||||||
} from "react";
|
} from "react";
|
||||||
import { useReactToPrint } from "react-to-print";
|
import { useReactToPrint } from "react-to-print";
|
||||||
import profile from "../../assets/images/profile-info-profile.png";
|
import profile from "../../assets/images/profile-info-profile.png";
|
||||||
import usersService from "../../services/UsersService";
|
import usersService from "../../services/UsersService";
|
||||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||||
import AssignTaskPopout from "./FamilyPopout/AssignTaskPopout";
|
import AssignTaskPopout from "./FamilyPopout/AssignTaskPopout";
|
||||||
import {
|
|
||||||
FamilyWaitlist,
|
|
||||||
FamilyAccount,
|
|
||||||
FamilyProfile,
|
|
||||||
FamilyTasks,
|
|
||||||
ProfileInfo,
|
|
||||||
FamilyPending,
|
|
||||||
} from "./Tabs";
|
|
||||||
import localImgLoad from "../../lib/localImgLoad";
|
import localImgLoad from "../../lib/localImgLoad";
|
||||||
|
|
||||||
|
// Lazy Imports for components
|
||||||
|
const FamilyWaitlist = lazy(() => import("./Tabs/FamilyWaitlist"));
|
||||||
|
const FamilyAccount = lazy(() => import("./Tabs/FamilyAccount"));
|
||||||
|
const FamilyProfile = lazy(() => import("./Tabs/FamilyProfile"));
|
||||||
|
const FamilyTasks = lazy(() => import("./Tabs/FamilyTasks"));
|
||||||
|
const ProfileInfo = lazy(() => import("./Tabs/ProfileInfo"));
|
||||||
|
const FamilyPending = lazy(() => import("./Tabs/FamilyPending"));
|
||||||
|
|
||||||
export default function FamilyManageTabs({
|
export default function FamilyManageTabs({
|
||||||
className,
|
className,
|
||||||
accountDetails,
|
accountDetails,
|
||||||
@@ -35,14 +37,15 @@ export default function FamilyManageTabs({
|
|||||||
});
|
});
|
||||||
const [errMsg, setErrMsg] = useState("");
|
const [errMsg, setErrMsg] = useState("");
|
||||||
const [familyTaskPopout, setFamilyTaskPopout] = useState(false);
|
const [familyTaskPopout, setFamilyTaskPopout] = useState(false);
|
||||||
|
const [profileImg, setProfileImg] = useState(profile);
|
||||||
|
const profileImgInput = useRef(null);
|
||||||
|
const [isPending, startTransition] = useTransition();
|
||||||
|
const apiCall = useMemo(() => new usersService(), []);
|
||||||
|
|
||||||
const familyPopUpHandler = () => {
|
const familyPopUpHandler = () => {
|
||||||
setFamilyTaskPopout((prev) => !prev);
|
setFamilyTaskPopout((prev) => !prev);
|
||||||
};
|
};
|
||||||
|
|
||||||
const [profileImg, setProfileImg] = useState(profile);
|
|
||||||
const profileImgInput = useRef(null);
|
|
||||||
|
|
||||||
const browseProfileImg = () => {
|
const browseProfileImg = () => {
|
||||||
profileImgInput.current.click();
|
profileImgInput.current.click();
|
||||||
};
|
};
|
||||||
@@ -57,16 +60,15 @@ export default function FamilyManageTabs({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const apiCall = useMemo(() => new usersService(), []);
|
|
||||||
|
|
||||||
const manageFamily = useCallback(async () => {
|
const manageFamily = useCallback(async () => {
|
||||||
try {
|
try {
|
||||||
setDetails({
|
setDetails((prevDetails) => ({
|
||||||
|
...prevDetails,
|
||||||
familyDetails: { loading: true },
|
familyDetails: { loading: true },
|
||||||
familyTasks: { loading: true },
|
familyTasks: { loading: true },
|
||||||
familyWaitList: { loading: true },
|
familyWaitList: { loading: true },
|
||||||
familyPending: { loading: true },
|
familyPending: { loading: true },
|
||||||
});
|
}));
|
||||||
|
|
||||||
const { family_uid } = accountDetails;
|
const { family_uid } = accountDetails;
|
||||||
const reqData = { family_uid };
|
const reqData = { family_uid };
|
||||||
@@ -89,22 +91,26 @@ export default function FamilyManageTabs({
|
|||||||
tasksData?.internal_return < 0 ||
|
tasksData?.internal_return < 0 ||
|
||||||
familyWaitData?.internal_return < 0 ||
|
familyWaitData?.internal_return < 0 ||
|
||||||
familyPendingData?.internal_return < 0
|
familyPendingData?.internal_return < 0
|
||||||
)
|
) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setDetails({
|
startTransition(() => {
|
||||||
familyDetails: { loading: false, data: familyData },
|
setDetails({
|
||||||
familyTasks: { loading: false, data: tasksData },
|
familyDetails: { loading: false, data: familyData },
|
||||||
familyWaitList: { loading: false, data: familyWaitData },
|
familyTasks: { loading: false, data: tasksData },
|
||||||
familyPending: { loading: false, data: familyPendingData },
|
familyWaitList: { loading: false, data: familyWaitData },
|
||||||
|
familyPending: { loading: false, data: familyPendingData },
|
||||||
|
});
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setDetails({
|
setDetails((prevDetails) => ({
|
||||||
|
...prevDetails,
|
||||||
familyDetails: { loading: false },
|
familyDetails: { loading: false },
|
||||||
familyTasks: { loading: false },
|
familyTasks: { loading: false },
|
||||||
familyWaitList: { loading: false },
|
familyWaitList: { loading: false },
|
||||||
familyPending: { loading: false },
|
familyPending: { loading: false },
|
||||||
});
|
}));
|
||||||
setErrMsg("An error occurred");
|
setErrMsg("An error occurred");
|
||||||
throw new Error(error);
|
throw new Error(error);
|
||||||
}
|
}
|
||||||
@@ -119,13 +125,15 @@ export default function FamilyManageTabs({
|
|||||||
const tabs = [
|
const tabs = [
|
||||||
{ id: 1, name: "Tasks" },
|
{ id: 1, name: "Tasks" },
|
||||||
{ id: 2, name: "Waiting" },
|
{ id: 2, name: "Waiting" },
|
||||||
{ id: 3, name: "Pending" }
|
{ id: 3, name: "Pending" },
|
||||||
];
|
];
|
||||||
|
|
||||||
const [tab, setTab] = useState(tabs[0].name);
|
const [tab, setTab] = useState(tabs[0].name);
|
||||||
|
|
||||||
const tabHandler = (value) => {
|
const tabHandler = (value) => {
|
||||||
setTab(value);
|
startTransition(() => {
|
||||||
|
setTab(value);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const tabComponents = {
|
const tabComponents = {
|
||||||
@@ -174,7 +182,13 @@ export default function FamilyManageTabs({
|
|||||||
const selectedTabComponent = tabComponents[tab] || defaultTabComponent;
|
const selectedTabComponent = tabComponents[tab] || defaultTabComponent;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
manageFamily();
|
let __manageFamily = true;
|
||||||
|
if (__manageFamily) {
|
||||||
|
manageFamily();
|
||||||
|
}
|
||||||
|
return () => {
|
||||||
|
__manageFamily = false;
|
||||||
|
};
|
||||||
}, [tab, manageFamily]);
|
}, [tab, manageFamily]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -200,18 +214,28 @@ export default function FamilyManageTabs({
|
|||||||
browseProfileImg={browseProfileImg}
|
browseProfileImg={browseProfileImg}
|
||||||
accountDetails={accountDetails}
|
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
|
<button
|
||||||
onClick={() => tabHandler('Account')}
|
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]" alt='Settings-Icon' />
|
>
|
||||||
<p className="mt-2 text-lg text-sky-blue">Account</p>
|
<img
|
||||||
|
src={localImgLoad("images/icons/account.svg")}
|
||||||
|
className="max-w-[30px] w-full"
|
||||||
|
alt="Settings-Icon"
|
||||||
|
/>
|
||||||
|
<p className="text-lg text-sky-blue">Acc.</p>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => tabHandler('Profile')}
|
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]" alt='Settings-Icon' />
|
>
|
||||||
<p className="mt-2 text-lg text-sky-blue">Profile</p>
|
<img
|
||||||
|
src={localImgLoad("images/icons/profile.svg")}
|
||||||
|
className="max-w-[30px] w-full"
|
||||||
|
alt="Settings-Icon"
|
||||||
|
/>
|
||||||
|
<p className="text-lg text-sky-blue">Profile</p>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -243,7 +267,11 @@ export default function FamilyManageTabs({
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex-[0.9] lg:min-h-[450px] h-full">
|
<div className="flex-[0.9] lg:min-h-[450px] h-full">
|
||||||
<div className="h-full p-4 border border-[#dbd9d9] relative overflow-y-auto">
|
<div className="h-full p-4 border border-[#dbd9d9] relative overflow-y-auto">
|
||||||
{selectedTabComponent}
|
<Suspense
|
||||||
|
fallback={<LoadingSpinner size="16" color="sky-blue" />}
|
||||||
|
>
|
||||||
|
{selectedTabComponent}
|
||||||
|
</Suspense>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect, useTransition } from "react";
|
||||||
import ModalCom from "../../Helpers/ModalCom";
|
import ModalCom from "../../Helpers/ModalCom";
|
||||||
import Detail from "../../jobPopout/popoutcomponent/Detail";
|
import Detail from "../../jobPopout/popoutcomponent/Detail";
|
||||||
import usersService from "../../../services/UsersService";
|
import usersService from "../../../services/UsersService";
|
||||||
@@ -6,7 +6,7 @@ import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
|||||||
import { PriceFormatter } from "../../Helpers/PriceFormatter";
|
import { PriceFormatter } from "../../Helpers/PriceFormatter";
|
||||||
import { NewTasks } from "./forms";
|
import { NewTasks } from "./forms";
|
||||||
|
|
||||||
function AssignTaskPopout({ action, situation, familyDetails }) {
|
const AssignTaskPopout = React.memo(({ action, details, situation, familyDetails }) => {
|
||||||
const apiCall = new usersService();
|
const apiCall = new usersService();
|
||||||
|
|
||||||
let [requestStatus, setRequestStatus] = useState({
|
let [requestStatus, setRequestStatus] = useState({
|
||||||
@@ -15,9 +15,9 @@ function AssignTaskPopout({ action, situation, familyDetails }) {
|
|||||||
message: "",
|
message: "",
|
||||||
}); // HOLDS RESPONSE FOR SENDING API REQUEST
|
}); // HOLDS RESPONSE FOR SENDING API REQUEST
|
||||||
|
|
||||||
let [familyTask, setFamilyTask] = useState({ loading: true, data: [] });
|
let [familyTask, setFamilyTask] = useState({ loading: false, data: [] });
|
||||||
|
|
||||||
let [taskType, setTaskType] = useState("select"); // SWITCHES BTW SELECT TASK AND NEW TASK
|
let [taskType, setTaskType] = useState(details ? "new" : "select"); // SWITCHES BTW SELECT TASK AND NEW TASK
|
||||||
|
|
||||||
let [activeTask, setActiveTask] = useState({ id: 0, data: {} }); // HOLDS SELECTED TASK
|
let [activeTask, setActiveTask] = useState({ id: 0, data: {} }); // HOLDS SELECTED TASK
|
||||||
|
|
||||||
@@ -34,14 +34,14 @@ function AssignTaskPopout({ action, situation, familyDetails }) {
|
|||||||
// New Task
|
// New Task
|
||||||
const [formState, setFormState] = useState({
|
const [formState, setFormState] = useState({
|
||||||
// Initialize form state with desired fields
|
// Initialize form state with desired fields
|
||||||
banner: "" || "default.jpg",
|
banner: details?.banner || "default.jpg",
|
||||||
country: "" || "",
|
country: details?.country || "",
|
||||||
price: "" || "",
|
price: details?.price || "",
|
||||||
title: "" || "",
|
title: details?.title || "",
|
||||||
description: "" || "",
|
description: details?.description || "",
|
||||||
job_detail: "" || "",
|
job_detail: details?.job_detail || "",
|
||||||
timeline_days: "" || "",
|
timeline_days: details?.timeline_days || "",
|
||||||
category: [] || "",
|
category: details?.category || "",
|
||||||
});
|
});
|
||||||
|
|
||||||
const assignFamilyTask = () => {
|
const assignFamilyTask = () => {
|
||||||
@@ -81,30 +81,29 @@ function AssignTaskPopout({ action, situation, familyDetails }) {
|
|||||||
title,
|
title,
|
||||||
} = formState;
|
} = formState;
|
||||||
|
|
||||||
const requiredFields = [
|
const requiredFields = {
|
||||||
banner,
|
banner,
|
||||||
category,
|
// category,
|
||||||
country,
|
country,
|
||||||
description,
|
description,
|
||||||
job_detail,
|
job_detail,
|
||||||
price,
|
price,
|
||||||
timeline_days,
|
timeline_days,
|
||||||
title,
|
title,
|
||||||
];
|
};
|
||||||
|
|
||||||
if (requiredFields.some((field) => !field)) {
|
for (let field in requiredFields) {
|
||||||
const emptyField = requiredFields.find((field) => !field);
|
if (requiredFields[field] == "") {
|
||||||
setRequestStatus({
|
// let currencyErrMsg = field == "country" && "currency"
|
||||||
loading: false,
|
setRequestStatus({
|
||||||
status: false,
|
loading: false,
|
||||||
message: `${emptyField} Empty`,
|
status: false,
|
||||||
});
|
message: `${field} is empty`,
|
||||||
|
});
|
||||||
setTimeout(() => {
|
return setTimeout(() => {
|
||||||
setRequestStatus({ loading: false, status: false, message: "" });
|
setRequestStatus({ loading: false, status: false, message: "" });
|
||||||
}, 3000);
|
}, 3000);
|
||||||
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
reqData = {
|
reqData = {
|
||||||
@@ -117,7 +116,7 @@ function AssignTaskPopout({ action, situation, familyDetails }) {
|
|||||||
timeline_days,
|
timeline_days,
|
||||||
title,
|
title,
|
||||||
assign_mode: 110055,
|
assign_mode: 110055,
|
||||||
family_uid: familyDetails.uid,
|
family_uid: details?.family_uid || familyDetails?.uid,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,37 +156,48 @@ function AssignTaskPopout({ action, situation, familyDetails }) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
let checkFamilyTask = true;
|
||||||
const reqData = {
|
const reqData = {
|
||||||
limit: 30,
|
limit: 30,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
job_type: "FAMILY",
|
job_type: "FAMILY",
|
||||||
action: 13005,
|
action: 13005,
|
||||||
};
|
};
|
||||||
|
|
||||||
apiCall
|
apiCall
|
||||||
.getMyJobList(reqData)
|
.getMyJobList(reqData)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
setFamilyTask({ loading: false, data: res?.data?.result_list });
|
if (checkFamilyTask) {
|
||||||
if (res?.data?.result_list?.length) {
|
setFamilyTask({ loading: false, data: res?.data?.result_list });
|
||||||
setActiveTask((prev) => ({
|
if (res?.data?.result_list?.length) {
|
||||||
...prev,
|
setActiveTask((prev) => ({
|
||||||
data: res?.data?.result_list[0],
|
...prev,
|
||||||
}));
|
data: res?.data?.result_list[0],
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
setFamilyTask({ loading: false, data: [] });
|
setFamilyTask({ loading: false, data: [] });
|
||||||
console.log("Error", err);
|
console.log("Error", err);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
checkFamilyTask = false;
|
||||||
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
console.log("Trying to see form data >>", formState);
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ModalCom action={action} situation={situation} className="assign-task-popup">
|
<ModalCom
|
||||||
|
action={action}
|
||||||
|
situation={situation}
|
||||||
|
className="assign-task-popup"
|
||||||
|
>
|
||||||
<div className="w-full h-full lg:w-[700px] lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl">
|
<div className="w-full h-full lg:w-[700px] lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl">
|
||||||
<div className="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">
|
<div className="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-dark-gray dark:text-white tracking-wide">
|
<h1 className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
|
||||||
Assign task to {familyDetails?.firstname}
|
Assign task to {familyDetails?.firstname || details.firstName}
|
||||||
</h1>
|
</h1>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -362,55 +372,62 @@ function AssignTaskPopout({ action, situation, familyDetails }) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* BTN */}
|
{/* BTN */}
|
||||||
<div className="p-2 border-t-2 flex justify-end items-center gap-3">
|
<div className="py-2 px-4 border-t-2 flex justify-between items-center">
|
||||||
{/* error or success display */}
|
{/* error or success display */}
|
||||||
{requestStatus.message != "" &&
|
<div className="w-auto h-auto flex items-center">
|
||||||
(!requestStatus.status ? (
|
{requestStatus.message != "" &&
|
||||||
<div
|
(!requestStatus.status ? (
|
||||||
className={`relative p-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
|
<div
|
||||||
className={`relative p-2 text-green-700 bg-slate-200 border-slate-800 mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
|
className={`relative p-2 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px] self-start`}
|
||||||
>
|
>
|
||||||
{requestStatus.message}
|
{requestStatus.message}
|
||||||
</div>
|
</div>
|
||||||
)
|
) : (
|
||||||
))}
|
requestStatus.status && (
|
||||||
|
<div
|
||||||
|
className={`relative p-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>
|
||||||
|
)
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* End of error or success display */}
|
{/* End of error or success display */}
|
||||||
<button
|
<div className="w-auto h-auto flex items-center gap-3">
|
||||||
disabled={requestStatus.loading}
|
<button
|
||||||
onClick={action}
|
disabled={requestStatus.loading}
|
||||||
type="button"
|
onClick={action}
|
||||||
className="w-20 h-11 flex justify-center items-center border-gradient text-base rounded-full text-white cursor-pointer"
|
type="button"
|
||||||
>
|
className="w-20 h-11 flex justify-center items-center border-gradient text-base rounded-full text-white cursor-pointer"
|
||||||
<span className="text-gradient">Close</span>
|
>
|
||||||
</button>
|
<span className="text-gradient">Close</span>
|
||||||
<div className="">
|
</button>
|
||||||
{requestStatus.loading ? (
|
<div className="">
|
||||||
<LoadingSpinner color="sky-blue" size="8" />
|
{requestStatus.loading ? (
|
||||||
) : taskType == "select" ? (
|
<LoadingSpinner color="sky-blue" size="8" />
|
||||||
<button
|
) : taskType == "select" ? (
|
||||||
type="button"
|
<button
|
||||||
disabled={requestStatus.loading}
|
type="button"
|
||||||
onClick={assignFamilyTask}
|
disabled={requestStatus.loading}
|
||||||
className="px-1 w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white cursor-pointer"
|
onClick={assignFamilyTask}
|
||||||
>
|
className="px-1 w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white cursor-pointer"
|
||||||
Assign
|
>
|
||||||
</button>
|
Assign
|
||||||
) : (
|
</button>
|
||||||
<button
|
) : (
|
||||||
type="button"
|
<button
|
||||||
disabled={requestStatus.loading}
|
type="button"
|
||||||
onClick={assignFamilyTask}
|
disabled={requestStatus.loading}
|
||||||
className="px-1 w-40 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white cursor-pointer"
|
onClick={assignFamilyTask}
|
||||||
>
|
className="px-1 w-40 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white cursor-pointer"
|
||||||
{`Assign to ${familyDetails?.firstname}`}
|
>
|
||||||
</button>
|
{`Assign to ${
|
||||||
)}
|
familyDetails?.firstname || details?.firstName
|
||||||
|
}`}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
@@ -419,6 +436,6 @@ function AssignTaskPopout({ action, situation, familyDetails }) {
|
|||||||
</ModalCom>
|
</ModalCom>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
})
|
||||||
|
|
||||||
export default AssignTaskPopout;
|
export default AssignTaskPopout;
|
||||||
@@ -1,9 +1,7 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import usersService from "../../../../services/UsersService";
|
import usersService from "../../../../services/UsersService";
|
||||||
import InputCom from "../../../Helpers/Inputs/InputCom";
|
import InputCom from "../../../Helpers/Inputs/InputCom";
|
||||||
import debounce from "../../../../hooks/debounce";
|
|
||||||
|
|
||||||
const DEFAULT_IMAGE = require("../../../../assets/images/taskbanners/default.jpg");
|
|
||||||
export default function NewTasks({ formState, setFormState }) {
|
export default function NewTasks({ formState, setFormState }) {
|
||||||
let [currency, setCurrency] = useState({
|
let [currency, setCurrency] = useState({
|
||||||
loading: true,
|
loading: true,
|
||||||
@@ -11,6 +9,9 @@ export default function NewTasks({ formState, setFormState }) {
|
|||||||
data: null,
|
data: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const selectImage = require(`../../../../assets/images/taskbanners/${
|
||||||
|
formState.banner || "default.jpg"
|
||||||
|
}`);
|
||||||
const ApiCall = new usersService();
|
const ApiCall = new usersService();
|
||||||
|
|
||||||
// FUNCTION TO GET Currency
|
// FUNCTION TO GET Currency
|
||||||
@@ -47,7 +48,7 @@ export default function NewTasks({ formState, setFormState }) {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form className="w-full flex justify-between items-center">
|
<form className="w-full flex justify-between items-start">
|
||||||
<div className="flex flex-col gap-3 max-w-[77%]">
|
<div className="flex flex-col gap-3 max-w-[77%]">
|
||||||
{/* inputs starts here */}
|
{/* inputs starts here */}
|
||||||
<div className="grid md:grid-cols-3 grid-cols-1 gap-6 mb-[5px]">
|
<div className="grid md:grid-cols-3 grid-cols-1 gap-6 mb-[5px]">
|
||||||
@@ -207,7 +208,7 @@ export default function NewTasks({ formState, setFormState }) {
|
|||||||
<div className="max-w-[20%] w-full">
|
<div className="max-w-[20%] w-full">
|
||||||
<div className="h-32 w-full">
|
<div className="h-32 w-full">
|
||||||
<img
|
<img
|
||||||
src={DEFAULT_IMAGE}
|
src={selectImage}
|
||||||
alt="task_banner_img"
|
alt="task_banner_img"
|
||||||
className="w-full h-full object-contain"
|
className="w-full h-full object-contain"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,17 +1,14 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import dataImage1 from "../../assets/images/data-table-user-1.png";
|
import dataImage1 from "../../assets/images/data-table-user-1.png";
|
||||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
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 { handlePagingFunc } from "../Pagination/HandlePagination";
|
||||||
import PaginatedList from "../Pagination/PaginatedList";
|
import PaginatedList from "../Pagination/PaginatedList";
|
||||||
|
|
||||||
import familyImage from '../../assets/images/no-family-side.png'
|
import familyImage from '../../assets/images/no-family-side.png'
|
||||||
|
|
||||||
export default function FamilyTable({ className, familyList, loader, popUpHandler }) {
|
export default function FamilyTable({ className, familyList, loader, popUpHandler }) {
|
||||||
const filterCategories = ["All Categories", "Explore", "Featured"];
|
|
||||||
const [selectedCategory, setCategory] = useState(filterCategories[0]);
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
// let location = useLocation();
|
|
||||||
|
|
||||||
const [currentPage, setCurrentPage] = useState(0);
|
const [currentPage, setCurrentPage] = useState(0);
|
||||||
const indexOfFirstItem = Number(currentPage);
|
const indexOfFirstItem = Number(currentPage);
|
||||||
|
|||||||
@@ -1,56 +1,56 @@
|
|||||||
import { forwardRef } from 'react'
|
import { forwardRef } from "react";
|
||||||
import QRCode from 'react-qr-code';
|
import QRCode from "react-qr-code";
|
||||||
|
|
||||||
const FamilyAccount = forwardRef(({ familyData, myRef, handlePrint }, ref) => {
|
const FamilyAccount = forwardRef(({ familyData, myRef, handlePrint }, ref) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="w-full lg:min-h-[500px] h-full flex flex-col items-center justify-center"
|
className="w-full lg:min-h-[500px] h-full flex flex-col items-center justify-center"
|
||||||
ref={myRef}
|
ref={myRef}
|
||||||
>
|
>
|
||||||
<div className="update-table w-full lg:min-h-[450px] h-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow ">
|
<div className="update-table w-full lg:min-h-[450px] h-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow ">
|
||||||
<div className="flex items-center justify-around h-[380px]">
|
<div className="flex items-center justify-around h-[380px]">
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<h2 className="font-bold text-lg tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
|
<h2 className="font-bold text-lg tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
|
||||||
Username:{" "}
|
Username:{" "}
|
||||||
<span className="ml-2 normal-case">
|
<span className="ml-2 normal-case">
|
||||||
{familyData?.username ? familyData?.username : "please wait..."}
|
{familyData?.username ? familyData?.username : "please wait..."}
|
||||||
</span>
|
</span>
|
||||||
</h2>
|
</h2>
|
||||||
<h2 className="font-bold text-lg tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
|
<h2 className="font-bold text-lg tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
|
||||||
Pin:{" "}
|
Pin:{" "}
|
||||||
<span className="ml-2 normal-case">
|
<span className="ml-2 normal-case">
|
||||||
{familyData?.pin ? familyData?.pin : "please wait..."}
|
{familyData?.pin ? familyData?.pin : "please wait..."}
|
||||||
</span>
|
</span>
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
|
||||||
|
|
||||||
<span className="text-5xl text-gray-400 opacity-20 font-bold">
|
|
||||||
or
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<div className="max-w-[200px]">
|
|
||||||
<p className="text-xl tracking-wide mb-[15px] text-center font-bold text-dark-gray dark:text-white">
|
|
||||||
Scan the code from mobile app
|
|
||||||
</p>
|
|
||||||
<QRCode
|
|
||||||
size={256}
|
|
||||||
style={{ height: "auto", maxWidth: "100%", width: "100%" }}
|
|
||||||
value={`https://www.google.com`}
|
|
||||||
viewBox={`0 0 256 256`}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="h-[50px] w-full flex justify-center items-center">
|
|
||||||
<button
|
<span className="text-5xl text-gray-400 opacity-20 font-bold">
|
||||||
className="btn-shine w-[116px] h-[46px] text-white rounded-full text-base bg-pink flex justify-center items-center"
|
or
|
||||||
onClick={handlePrint}
|
</span>
|
||||||
>
|
|
||||||
Print
|
<div className="max-w-[200px]">
|
||||||
</button>
|
<p className="text-xl tracking-wide mb-[15px] text-center font-bold text-dark-gray dark:text-white">
|
||||||
|
Scan the code from mobile app
|
||||||
|
</p>
|
||||||
|
<QRCode
|
||||||
|
size={256}
|
||||||
|
style={{ height: "auto", maxWidth: "100%", width: "100%" }}
|
||||||
|
value={`https://www.google.com`}
|
||||||
|
viewBox={`0 0 256 256`}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="h-[50px] w-full flex justify-center items-center">
|
||||||
|
<button
|
||||||
|
className="btn-shine w-[116px] h-[46px] text-white rounded-full text-base bg-pink flex justify-center items-center"
|
||||||
|
onClick={handlePrint}
|
||||||
|
>
|
||||||
|
Print
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
</div>
|
||||||
});
|
);
|
||||||
|
});
|
||||||
|
|
||||||
export default FamilyAccount
|
export default FamilyAccount;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useState } from "react";
|
import { useMemo, useState } from "react";
|
||||||
import { PaginatedList, handlePagingFunc } from "../../Pagination";
|
import { PaginatedList, handlePagingFunc } from "../../Pagination";
|
||||||
import { PriceFormatter } from "../../Helpers/PriceFormatter";
|
import { PriceFormatter } from "../../Helpers/PriceFormatter";
|
||||||
import dataImage2 from "../../../assets/images/data-table-user-2.png";
|
import dataImage2 from "../../../assets/images/data-table-user-2.png";
|
||||||
@@ -13,8 +13,12 @@ export default function FamilyPending({
|
|||||||
}) {
|
}) {
|
||||||
let [jobPopout, setJobPopout] = useState({ show: false, data: {} }); // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW
|
let [jobPopout, setJobPopout] = useState({ show: false, data: {} }); // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW
|
||||||
|
|
||||||
let filteredFamilyData = familyData?.result_list?.filter(
|
let filteredFamilyData = useMemo(
|
||||||
(data) => data?.family_uid === accountDetails?.family_uid
|
() =>
|
||||||
|
familyData?.result_list?.filter(
|
||||||
|
(data) => data?.family_uid === accountDetails?.family_uid
|
||||||
|
),
|
||||||
|
[accountDetails?.family_uid, familyData?.result_list]
|
||||||
);
|
);
|
||||||
|
|
||||||
const [currentPage, setCurrentPage] = useState(0);
|
const [currentPage, setCurrentPage] = useState(0);
|
||||||
@@ -51,7 +55,7 @@ export default function FamilyPending({
|
|||||||
value?.currency_code,
|
value?.currency_code,
|
||||||
value?.currency
|
value?.currency
|
||||||
);
|
);
|
||||||
let image = value.banner ? value.banner : 'default.jpg'
|
let image = value.banner ? value.banner : "default.jpg";
|
||||||
return (
|
return (
|
||||||
<tr
|
<tr
|
||||||
key={index}
|
key={index}
|
||||||
@@ -61,7 +65,9 @@ export default function FamilyPending({
|
|||||||
<div className="flex space-x-2 items-center w-full">
|
<div className="flex space-x-2 items-center w-full">
|
||||||
<div className="w-[60px] h-[60px] p-2 bg-alice-blue rounded-full overflow-hidden flex justify-center items-center">
|
<div className="w-[60px] h-[60px] p-2 bg-alice-blue rounded-full overflow-hidden flex justify-center items-center">
|
||||||
<img
|
<img
|
||||||
src={localImgLoad(`images/taskbanners/${image}`)}
|
src={localImgLoad(
|
||||||
|
`images/taskbanners/${image}`
|
||||||
|
)}
|
||||||
alt="data"
|
alt="data"
|
||||||
className="w-full h-full rounded-full"
|
className="w-full h-full rounded-full"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,122 +1,152 @@
|
|||||||
import { useState } from "react";
|
import { memo, useMemo, useState } from "react";
|
||||||
import { handlePagingFunc, PaginatedList } from "../../Pagination";
|
|
||||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
|
||||||
import SuggestTask from "../../FamilyPopup/SuggestTask";
|
import SuggestTask from "../../FamilyPopup/SuggestTask";
|
||||||
|
import { PaginatedList, handlePagingFunc } from "../../Pagination";
|
||||||
|
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||||
|
import AssignTaskPopout from "../FamilyPopout/AssignTaskPopout";
|
||||||
|
|
||||||
const FamilyWaitlist = ({ familyData, className, accountDetails, loader }) => {
|
const FamilyWaitlist = memo(
|
||||||
const [popUp, setPopUp] = useState({ show: false, data: {} });
|
({ 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]
|
||||||
|
);
|
||||||
|
|
||||||
let filteredFamilyData = familyData?.result_list?.filter(
|
const [currentPage, setCurrentPage] = useState(0);
|
||||||
(data) => data?.family_uid === accountDetails?.family_uid
|
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 handlePagination = (e) => handlePagingFunc(e, setCurrentPage);
|
||||||
const itemsPerPage = Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
|
||||||
const indexOfFirstItem = currentPage;
|
|
||||||
const indexOfLastItem = currentPage + itemsPerPage;
|
|
||||||
const currentTask = filteredFamilyData?.slice(
|
|
||||||
indexOfFirstItem,
|
|
||||||
indexOfLastItem
|
|
||||||
);
|
|
||||||
|
|
||||||
const handlePagination = (e) => handlePagingFunc(e, setCurrentPage);
|
const openPopUp = (value) => {
|
||||||
|
setPopUp({ show: true, data: { ...value } });
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
const closePopUp = () => {
|
||||||
<div
|
setPopUp({ show: false, data: {} });
|
||||||
className={`update-table w-full bg-white dark:bg-dark-white h-full lg:min-h-[450px] overflow-hidden rounded-2xl section-shadow ${
|
};
|
||||||
className || ""
|
|
||||||
}`}
|
const openContinueTaskPopup = (value) => {
|
||||||
>
|
setContinueTaskPopup({ show: true, data: { ...value } });
|
||||||
{loader ? (
|
};
|
||||||
<div className="w-full h-full flex justify-center items-center lg:min-h-[470px]">
|
|
||||||
<LoadingSpinner size={16} color="sky-blue" />
|
const closeContinueTaskPopup = () => {
|
||||||
</div>
|
setContinueTaskPopup({ show: false, data: {} });
|
||||||
) : (
|
};
|
||||||
<>
|
|
||||||
{filteredFamilyData && (
|
return (
|
||||||
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between h-full">
|
<div
|
||||||
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
className={`update-table w-full bg-white dark:bg-dark-white h-full lg:min-h-[450px] overflow-hidden rounded-2xl section-shadow ${
|
||||||
<tbody>
|
className || ""
|
||||||
{currentTask.map((value) => {
|
}`}
|
||||||
const addedDate = value?.added.split(" ")[0];
|
>
|
||||||
const selectedImage = require(`../../../assets/images/family/${
|
{loader ? (
|
||||||
value?.banner || "default.jpg"
|
<div className="w-full h-full flex justify-center items-center lg:min-h-[470px]">
|
||||||
}`);
|
<LoadingSpinner size={16} color="sky-blue" />
|
||||||
return (
|
</div>
|
||||||
<tr
|
) : (
|
||||||
className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50"
|
<>
|
||||||
key={value.uid}
|
{filteredFamilyData && (
|
||||||
>
|
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between h-full">
|
||||||
<td className="py-4">
|
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
||||||
<div className="w-full flex justify-between items-center">
|
<tbody>
|
||||||
<div className="account-name flex space-x-4 items-center">
|
{currentTask.map((value) => {
|
||||||
<div className="icon w-14 h-14 flex justify-center items-center">
|
const addedDate = value?.added.split(" ")[0];
|
||||||
<img
|
const selectedImage = require(`../../../assets/images/family/${
|
||||||
src={selectedImage}
|
value?.banner || "default.jpg"
|
||||||
alt="task_img"
|
}`);
|
||||||
className="w-full object-cover"
|
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>
|
||||||
<div className="">
|
<div className="px-2 flex flex-col items-center justify-center">
|
||||||
<p className="text-xl font-bold text-dark-gray dark:text-white mb-2 capitalize line-clamp-1">
|
<p className="text-sm font-bold text-dark-gray dark:text-white">
|
||||||
{value.title}
|
{addedDate}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-sm text-thin-light-gray font-medium">
|
<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.description}
|
{value.status_text}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="px-2 flex flex-col items-center justify-center">
|
</td>
|
||||||
<p className="text-sm font-bold text-dark-gray dark:text-white">
|
<td className="text-right py-4 px-2">
|
||||||
{addedDate}
|
<button
|
||||||
</p>
|
onClick={() => openPopUp(value)}
|
||||||
<p className="text-xs py-1.5 w-[70px] cursor-default tracking-wide rounded-full bg-gold text-white flex justify-center items-center">
|
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||||
{value.status_text}
|
>
|
||||||
</p>
|
View
|
||||||
</div>
|
</button>
|
||||||
</div>
|
</td>
|
||||||
</td>
|
</tr>
|
||||||
<td className="text-right py-4 px-2">
|
);
|
||||||
<button
|
})}
|
||||||
onClick={() =>
|
</tbody>
|
||||||
setPopUp({
|
</table>
|
||||||
show: true,
|
<PaginatedList
|
||||||
data: { ...value, selectedImage },
|
onClick={handlePagination}
|
||||||
})
|
prev={currentPage === 0}
|
||||||
}
|
next={
|
||||||
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
currentPage + itemsPerPage >= filteredFamilyData?.length
|
||||||
>
|
}
|
||||||
View
|
data={filteredFamilyData}
|
||||||
</button>
|
start={indexOfFirstItem}
|
||||||
</td>
|
stop={indexOfLastItem}
|
||||||
</tr>
|
/>
|
||||||
);
|
</div>
|
||||||
})}
|
)}
|
||||||
</tbody>
|
</>
|
||||||
</table>
|
)}
|
||||||
<PaginatedList
|
{popUp.show && (
|
||||||
onClick={handlePagination}
|
<SuggestTask
|
||||||
prev={currentPage === 0}
|
details={popUp.data}
|
||||||
next={currentPage + itemsPerPage >= filteredFamilyData?.length}
|
onClose={closePopUp}
|
||||||
data={filteredFamilyData}
|
continuePopupData={openContinueTaskPopup}
|
||||||
start={indexOfFirstItem}
|
situation={popUp.show}
|
||||||
stop={indexOfLastItem}
|
/>
|
||||||
/>
|
)}
|
||||||
</div>
|
|
||||||
)}
|
{continueTaskPopup.show && (
|
||||||
</>
|
<AssignTaskPopout
|
||||||
)}
|
details={continueTaskPopup.data}
|
||||||
{popUp.show && (
|
action={closeContinueTaskPopup}
|
||||||
<SuggestTask
|
situation={continueTaskPopup.show}
|
||||||
details={popUp.data}
|
/>
|
||||||
onClose={() => {
|
)}
|
||||||
setPopUp({ show: false, data: {} });
|
</div>
|
||||||
}}
|
);
|
||||||
situation={popUp.show}
|
}
|
||||||
/>
|
);
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default FamilyWaitlist;
|
export default FamilyWaitlist;
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ export default function ProfileInfo({
|
|||||||
accountDetails,
|
accountDetails,
|
||||||
}) {
|
}) {
|
||||||
return (
|
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="flex justify-center">
|
||||||
<div className="w-full relative">
|
<div className="w-full relative">
|
||||||
<img
|
<img
|
||||||
src={profileImg}
|
src={profileImg}
|
||||||
alt=""
|
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
|
<input
|
||||||
ref={profileImgInput}
|
ref={profileImgInput}
|
||||||
|
|||||||
@@ -1,9 +1,16 @@
|
|||||||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
import React, {
|
||||||
|
Suspense,
|
||||||
|
useCallback,
|
||||||
|
useEffect,
|
||||||
|
useMemo,
|
||||||
|
useState,
|
||||||
|
} from "react";
|
||||||
import InputCom from "../Helpers/Inputs/InputCom";
|
import InputCom from "../Helpers/Inputs/InputCom";
|
||||||
import Layout from "../Partials/Layout";
|
import Layout from "../Partials/Layout";
|
||||||
import FamilyTable from "./FamilyTable";
|
import FamilyTable from "./FamilyTable";
|
||||||
import SiteService from "../../services/SiteService";
|
import SiteService from "../../services/SiteService";
|
||||||
import ModalCom from "../Helpers/ModalCom";
|
import ModalCom from "../Helpers/ModalCom";
|
||||||
|
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||||
|
|
||||||
export default function FamilyAcc() {
|
export default function FamilyAcc() {
|
||||||
const [selectTab, setValue] = useState("today");
|
const [selectTab, setValue] = useState("today");
|
||||||
@@ -20,60 +27,50 @@ export default function FamilyAcc() {
|
|||||||
|
|
||||||
const apiCall = useMemo(() => new SiteService(), []);
|
const apiCall = useMemo(() => new SiteService(), []);
|
||||||
|
|
||||||
// This is to make sure it's called once and used everywhere
|
|
||||||
let memberId = localStorage.getItem("member_id");
|
|
||||||
let uid = localStorage.getItem("uid");
|
|
||||||
let sessionId = localStorage.getItem("session_token");
|
|
||||||
|
|
||||||
const popUpHandler = () => {
|
const popUpHandler = () => {
|
||||||
setPopUp((prev) => !prev);
|
setPopUp((prev) => !prev);
|
||||||
};
|
};
|
||||||
|
|
||||||
// tab handler
|
|
||||||
const filterHandler = (value) => {
|
const filterHandler = (value) => {
|
||||||
setValue(value);
|
setValue(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
// For the age drop down
|
const ageRange = useMemo(() => {
|
||||||
let startAge = 5;
|
const startAge = 5;
|
||||||
let endAge = 16;
|
const endAge = 16;
|
||||||
// creates an array of age values ranging from 16 to 70
|
return Array.from(
|
||||||
const ageRange = Array.from(
|
{ length: endAge - startAge + 1 },
|
||||||
{ length: endAge - startAge + 1 },
|
(_, index) => startAge + index
|
||||||
(_, index) => startAge + index
|
);
|
||||||
);
|
}, []);
|
||||||
// age handler
|
|
||||||
const handleAgeSelect = (event) => {
|
const handleAgeSelect = (event) => {
|
||||||
setSelectedAge(parseInt(event.target.value));
|
setSelectedAge(parseInt(event.target.value));
|
||||||
};
|
};
|
||||||
// Input handler
|
|
||||||
const handleInputChange = (event) => {
|
const handleInputChange = (event) => {
|
||||||
const { name, value } = event?.target;
|
const { name, value } = event?.target;
|
||||||
setFormData({ ...formData, [name]: value });
|
setFormData((prevFormData) => ({ ...prevFormData, [name]: value }));
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add member
|
|
||||||
const addMember = async () => {
|
const addMember = async () => {
|
||||||
const { first_name, last_name } = formData;
|
const { first_name, last_name } = formData;
|
||||||
setLoader(true);
|
setLoader(true);
|
||||||
try {
|
try {
|
||||||
if (first_name !== "" && last_name !== "") {
|
if (first_name !== "" && last_name !== "") {
|
||||||
let reqData = {
|
const reqData = {
|
||||||
member_id: memberId,
|
|
||||||
uid: uid,
|
|
||||||
session_id: sessionId,
|
|
||||||
firstname: first_name,
|
firstname: first_name,
|
||||||
lastname: last_name,
|
lastname: last_name,
|
||||||
age: selectedAge,
|
age: selectedAge,
|
||||||
};
|
};
|
||||||
|
|
||||||
let res = await apiCall.addFamily(reqData);
|
const res = await apiCall.addFamily(reqData);
|
||||||
const { data } = res;
|
const { data } = res;
|
||||||
|
|
||||||
if (data?.internal_return > 0 && data?.status == "OK") {
|
if (data?.internal_return > 0 && data?.status === "OK") {
|
||||||
setLoader(false);
|
setLoader(false);
|
||||||
setListReload((prev) => !prev);
|
setListReload((prev) => !prev);
|
||||||
popUpHandler()
|
popUpHandler();
|
||||||
} else {
|
} else {
|
||||||
setLoader(false);
|
setLoader(false);
|
||||||
setMsgErr("Sorry, something went wrong");
|
setMsgErr("Sorry, something went wrong");
|
||||||
@@ -94,38 +91,42 @@ export default function FamilyAcc() {
|
|||||||
first_name: "",
|
first_name: "",
|
||||||
last_name: "",
|
last_name: "",
|
||||||
});
|
});
|
||||||
setSelectedAge("")
|
setSelectedAge("");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// member listing
|
|
||||||
const memberList = useCallback(async () => {
|
const memberList = useCallback(async () => {
|
||||||
setLoader(true);
|
setLoader(true);
|
||||||
try {
|
try {
|
||||||
let reqData = {
|
const reqData = {
|
||||||
member_id: memberId,
|
|
||||||
uid: uid,
|
|
||||||
session_id: sessionId,
|
|
||||||
limit: 20,
|
limit: 20,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
action: 22010,
|
action: 22010,
|
||||||
};
|
};
|
||||||
|
|
||||||
let res = await apiCall.familyListings(reqData);
|
const res = await apiCall.familyListings(reqData);
|
||||||
const { data } = res;
|
const { data } = res;
|
||||||
if (data?.internal_return >= 0 && data?.status == "OK") {
|
if (data?.internal_return >= 0 && data?.status === "OK") {
|
||||||
let { result_list } = data;
|
const { result_list } = data;
|
||||||
setFamilyList(result_list);
|
setFamilyList(result_list);
|
||||||
setLoader(false);
|
setLoader(false);
|
||||||
} else return;
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setLoader(false);
|
setLoader(false);
|
||||||
throw new Error(error);
|
throw new Error(error);
|
||||||
}
|
}
|
||||||
}, [apiCall, memberId, sessionId, uid]);
|
}, [apiCall]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
memberList();
|
let checkMemberList = true;
|
||||||
|
if (checkMemberList) {
|
||||||
|
memberList();
|
||||||
|
}
|
||||||
|
return () => {
|
||||||
|
checkMemberList = false;
|
||||||
|
};
|
||||||
}, [listReload, memberList]);
|
}, [listReload, memberList]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -158,7 +159,13 @@ export default function FamilyAcc() {
|
|||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<FamilyTable familyList={familyList} loader={loader} popUpHandler={popUpHandler} />
|
<Suspense fallback={<LoadingSpinner color="sky-blue" size="16" />}>
|
||||||
|
<FamilyTable
|
||||||
|
familyList={familyList}
|
||||||
|
loader={loader}
|
||||||
|
popUpHandler={popUpHandler}
|
||||||
|
/>
|
||||||
|
</Suspense>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{popUp && (
|
{popUp && (
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import usersService from "../../services/UsersService";
|
|||||||
import Icons from "../Helpers/Icons";
|
import Icons from "../Helpers/Icons";
|
||||||
|
|
||||||
const DEFAULT_IMAGE = require("../../assets/images/family/default.jpg");
|
const DEFAULT_IMAGE = require("../../assets/images/family/default.jpg");
|
||||||
const SuggestTask = ({ details, onClose, situation }) => {
|
const SuggestTask = ({ details, onClose, situation, continuePopupData }) => {
|
||||||
const { pathname, state } = useLocation();
|
const { pathname, state } = useLocation();
|
||||||
const [submitTask, setSubmitTask] = useState({
|
const [submitTask, setSubmitTask] = useState({
|
||||||
loading: false,
|
loading: false,
|
||||||
@@ -16,7 +16,7 @@ const SuggestTask = ({ details, onClose, situation }) => {
|
|||||||
});
|
});
|
||||||
const [suggestedNextStep, setSuggestedNextStep] = useState("Send Task");
|
const [suggestedNextStep, setSuggestedNextStep] = useState("Send Task");
|
||||||
|
|
||||||
const switchNextStep = (value) => {
|
const switchNextStep = ({ target: value }) => {
|
||||||
setSuggestedNextStep(value);
|
setSuggestedNextStep(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -29,8 +29,9 @@ const SuggestTask = ({ details, onClose, situation }) => {
|
|||||||
|
|
||||||
const apiCall = new usersService();
|
const apiCall = new usersService();
|
||||||
|
|
||||||
const handleSubmit = async (values) => {
|
const handleSuggestedTask = async (values) => {
|
||||||
if (!values.title && !values.description) return;
|
if (!values.title && !values.description) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setSubmitTask({ loading: true });
|
setSubmitTask({ loading: true });
|
||||||
const reqData = { ...values };
|
const reqData = { ...values };
|
||||||
@@ -49,7 +50,15 @@ const SuggestTask = ({ details, onClose, situation }) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// console.log("state >-->>", state);
|
const handleParentSuggestion = (values) => {
|
||||||
|
if (suggestedNextStep == "Send Task") {
|
||||||
|
let firstName = state?.firstname;
|
||||||
|
let family_uid = state?.family_uid;
|
||||||
|
continuePopupData({ ...details, firstName, family_uid });
|
||||||
|
}
|
||||||
|
onClose();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalCom action={onClose} situation={situation}>
|
<ModalCom action={onClose} situation={situation}>
|
||||||
<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-wrapper lw-[90%] md:w-[768px] h-full lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl overflow-y-auto">
|
||||||
@@ -87,7 +96,11 @@ const SuggestTask = ({ details, onClose, situation }) => {
|
|||||||
</div>
|
</div>
|
||||||
<Formik
|
<Formik
|
||||||
initialValues={initialValues}
|
initialValues={initialValues}
|
||||||
onSubmit={pathname !== "/manage-family" && handleSubmit}
|
onSubmit={
|
||||||
|
pathname !== "/manage-family"
|
||||||
|
? handleSuggestedTask
|
||||||
|
: handleParentSuggestion
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{(props) => {
|
{(props) => {
|
||||||
return (
|
return (
|
||||||
@@ -164,7 +177,7 @@ const SuggestTask = ({ details, onClose, situation }) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Radio buttons for family */}
|
{/* Radio buttons for family */}
|
||||||
{pathname === "/manage-family" && (
|
{pathname === "/manage-family" ? (
|
||||||
<div className="h-[20px] w-full border-t dark:border-[#5356fb29] border-light-purple relative">
|
<div className="h-[20px] w-full border-t dark:border-[#5356fb29] border-light-purple relative">
|
||||||
<div id="my-radio-group" className="sr-only">
|
<div id="my-radio-group" className="sr-only">
|
||||||
Parent suggested next step
|
Parent suggested next step
|
||||||
@@ -182,18 +195,22 @@ const SuggestTask = ({ details, onClose, situation }) => {
|
|||||||
<label
|
<label
|
||||||
role="group"
|
role="group"
|
||||||
key={idx}
|
key={idx}
|
||||||
htmlFor="parent-suggested"
|
htmlFor={`parent-suggested-${idx}`}
|
||||||
|
className={`transition duration-150 ease-in-out parent-suggest group cursor-pointer`}
|
||||||
|
onClick={() => setSuggestedNextStep(title)}
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
name="parent-suggested"
|
name="parent-suggested"
|
||||||
value={title}
|
value={title}
|
||||||
checked={title == suggestedNextStep}
|
checked={suggestedNextStep === title}
|
||||||
onChange={switchNextStep}
|
onChange={switchNextStep}
|
||||||
className={`transition duration-150 ease-in-out parent-suggest`}
|
className={`transition duration-150 ease-in-out parent-suggest pointer-events-none`}
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
onClick={switchNextStep}
|
onClick={() => setSuggestedNextStep(title)}
|
||||||
|
id={`parent-suggested-${idx}`}
|
||||||
|
name="parent-suggested"
|
||||||
className={`ml-1 ${
|
className={`ml-1 ${
|
||||||
title == "Not Now"
|
title == "Not Now"
|
||||||
? "text-red-500"
|
? "text-red-500"
|
||||||
@@ -208,9 +225,10 @@ const SuggestTask = ({ details, onClose, situation }) => {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="w-full h-[70px] border-t border-light-purple dark:border-[#5356fb29] flex justify-end items-center">
|
<div className="w-full h-[70px] border-t border-light-purple dark:border-[#5356fb29] flex justify-end items-center">
|
||||||
<div className="flex items-center space-x-4 mr-9">
|
<div className="flex items-center space-x-4 mr-9">
|
||||||
<button
|
<button
|
||||||
@@ -220,31 +238,33 @@ const SuggestTask = ({ details, onClose, situation }) => {
|
|||||||
>
|
>
|
||||||
<span className="text-gradient"> Cancel</span>
|
<span className="text-gradient"> Cancel</span>
|
||||||
</button>
|
</button>
|
||||||
{pathname !== "/manage-family" ? (
|
<button
|
||||||
<button
|
type="submit"
|
||||||
type="submit"
|
disabled={props.isSubmitting}
|
||||||
disabled={props.isSubmitting}
|
className="text-white primary-gradient text-18 tracking-wide px-4 py-3 rounded-full transition duration-150 ease-in-out flex items-center"
|
||||||
className="text-white primary-gradient text-18 tracking-wide px-4 py-3 rounded-full transition duration-150 ease-in-out"
|
>
|
||||||
>
|
{pathname !== "/manage-family" ? (
|
||||||
{submitTask.loading
|
<>
|
||||||
? "Submitting Task"
|
{submitTask.loading
|
||||||
: submitTask.state == "success"
|
? "Submitting Task"
|
||||||
? "Task Submitted"
|
: submitTask.state == "success"
|
||||||
: submitTask.state == "bad"
|
? "Task Submitted"
|
||||||
? "An Error Occurred"
|
: submitTask.state == "bad"
|
||||||
: "Send to Parents"}
|
? "An Error Occurred"
|
||||||
</button>
|
: "Send to Parents"}
|
||||||
) : (
|
</>
|
||||||
<button className="text-white primary-gradient text-18 tracking-wide px-4 py-3 rounded-full flex items-center transition duration-150 ease-in-out">
|
) : (
|
||||||
{suggestedNextStep == "Send Task" ? (
|
<>
|
||||||
<>
|
{suggestedNextStep == "Send Task" ? (
|
||||||
Continue <Icons name="chevron-right" />
|
<>
|
||||||
</>
|
Continue <Icons name="chevron-right" />
|
||||||
) : (
|
</>
|
||||||
"Complete"
|
) : (
|
||||||
)}
|
"Complete"
|
||||||
</button>
|
)}
|
||||||
)}
|
</>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Form>
|
</Form>
|
||||||
|
|||||||
@@ -519,7 +519,11 @@ export default function Icons({ name }) {
|
|||||||
<img className="w-[17px] h-[17px]" src={localImgLoad('images/icons/market.svg')} alt="market" />
|
<img className="w-[17px] h-[17px]" src={localImgLoad('images/icons/market.svg')} alt="market" />
|
||||||
) : name === "new-mytask" ? (
|
) : name === "new-mytask" ? (
|
||||||
<img className="w-[17px] h-[17px]" src={localImgLoad('images/icons/my-task.svg')} alt="task" />
|
<img className="w-[17px] h-[17px]" src={localImgLoad('images/icons/my-task.svg')} alt="task" />
|
||||||
) : (
|
) : name === "family-id" ? (
|
||||||
|
<img className="w-[20px] h-[20px]" src={localImgLoad('images/icons/family-id.svg')} alt="family-id" />
|
||||||
|
) : name === "family-pin" ? (
|
||||||
|
<img className="w-[20px] h-[20px]" src={localImgLoad('images/icons/family-pin.svg')} alt="family-pin" />
|
||||||
|
): (
|
||||||
""
|
""
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ export default function InputCom({
|
|||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{/* displays error is any */}
|
{/* 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>
|
</label>
|
||||||
)}
|
)}
|
||||||
{forgotPassword && (
|
{forgotPassword && (
|
||||||
@@ -97,7 +97,7 @@ export default function InputCom({
|
|||||||
dir={direction}
|
dir={direction}
|
||||||
/>
|
/>
|
||||||
{iconName && (
|
{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) => (
|
{iconName.split(" ").map((item, index) => (
|
||||||
<Icons key={index} name={item} />
|
<Icons key={index} name={item} />
|
||||||
))}
|
))}
|
||||||
@@ -105,7 +105,7 @@ export default function InputCom({
|
|||||||
)}
|
)}
|
||||||
{passIcon && (
|
{passIcon && (
|
||||||
<div
|
<div
|
||||||
className="absolute right-6 bottom-[10px] z-10"
|
className="absolute right-6 bottom-3 z-10"
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
>
|
>
|
||||||
<Icons name={passIcon} />
|
<Icons name={passIcon} />
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ import React from "react";
|
|||||||
export const PriceFormatter = (
|
export const PriceFormatter = (
|
||||||
price = "00",
|
price = "00",
|
||||||
currency = "",
|
currency = "",
|
||||||
currencyName = ""
|
currencyName = "",
|
||||||
|
priceClass
|
||||||
) => {
|
) => {
|
||||||
// Convert the number to a string
|
// Convert the number to a string
|
||||||
let numStr = String(price);
|
let numStr = String(price);
|
||||||
@@ -44,7 +45,7 @@ export const PriceFormatter = (
|
|||||||
return (
|
return (
|
||||||
<span className="text-sm flex items-center">
|
<span className="text-sm flex items-center">
|
||||||
<sup>{currency || currencyName || ""}</sup>
|
<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>
|
<sup>{formattedDecimal || ""}</sup>
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -11,12 +11,6 @@ import HomeActivities from "./HomeActivities";
|
|||||||
|
|
||||||
export default function FullAccountDash(props) {
|
export default function FullAccountDash(props) {
|
||||||
console.log("PROPS IN HOME->", 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);
|
const { userDetails } = useSelector((state) => state?.userDetails);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
import heroBg from "../../assets/images/hero-bg.svg";
|
import heroBg from "../../assets/images/bg-sky-blue.jpg"; //hero-bg.svg";
|
||||||
import heroUser from "../../assets/images/hero-user.png";
|
import heroUser from "../../assets/images/hero-user.png";
|
||||||
import CountDown from "../Helpers/CountDown";
|
import CountDown from "../Helpers/CountDown";
|
||||||
import HomeSliders from "./HomeSliders";
|
import HomeSliders from "./HomeSliders";
|
||||||
@@ -24,7 +24,7 @@ export default function Hero({ className, bannerList, nextDueTask }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`w-full lg:h-[444px] h-full lg:flex lg:p-8 p-4 justify-between items-center lg:space-x-28 rounded-2xl overflow-hidden ${
|
className={`w-full min-h-[400px] md:grid grid-cols-2 lg:p-8 p-4 justify-between items-center gap-2 rounded-2xl overflow-hidden ${
|
||||||
className || ""
|
className || ""
|
||||||
}`}
|
}`}
|
||||||
style={{
|
style={{
|
||||||
@@ -33,7 +33,7 @@ export default function Hero({ className, bannerList, nextDueTask }) {
|
|||||||
backgroundSize: "cover",
|
backgroundSize: "cover",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="flex-1 h-[330px] lg:h-full flex flex-col justify-between mb-5 lg:mb-0">
|
<div className="h-full flex flex-col justify-between mb-5 lg:mb-0">
|
||||||
{/* heading */}
|
{/* heading */}
|
||||||
<div>
|
<div>
|
||||||
<h1 className="lg:text-2xl text-xl font-medium text-white tracking-wide">
|
<h1 className="lg:text-2xl text-xl font-medium text-white tracking-wide">
|
||||||
@@ -57,7 +57,7 @@ export default function Hero({ className, bannerList, nextDueTask }) {
|
|||||||
</div>
|
</div>
|
||||||
{/* countdown */}
|
{/* countdown */}
|
||||||
{nextDueTask?.next_due && Object.keys(nextDueTask.next_due)?.length != 0 && (
|
{nextDueTask?.next_due && Object.keys(nextDueTask.next_due)?.length != 0 && (
|
||||||
<div className="w-full h-32 flex justify-evenly items-center sm:p-6 p-1 rounded-2xl border border-white-opacity">
|
<div className="w-full h-32 flex justify-evenly items-center sm:p-6 p-1 rounded-2xl border back-dark1 border-white-opacity">
|
||||||
<div className="flex flex-col justify-between">
|
<div className="flex flex-col justify-between">
|
||||||
<p className="text-base text-white tracking-wide">Current Task</p>
|
<p className="text-base text-white tracking-wide">Current Task</p>
|
||||||
<p className="lg:text-2xl text-lg font-bold tracking-wide text-white">
|
<p className="lg:text-2xl text-lg font-bold tracking-wide text-white">
|
||||||
@@ -84,7 +84,7 @@ export default function Hero({ className, bannerList, nextDueTask }) {
|
|||||||
)}
|
)}
|
||||||
{/* action */}
|
{/* action */}
|
||||||
<div className="flex lg:space-x-3 space-x-1 items-center">
|
<div className="flex lg:space-x-3 space-x-1 items-center">
|
||||||
<Link to="/mytask" className="text-white text-base sm:block hidden">
|
<Link to="/mytask" className="text-white text-base">
|
||||||
<span className=" border-b dark:border-[#5356fb29] border-white">
|
<span className=" border-b dark:border-[#5356fb29] border-white">
|
||||||
{" "}
|
{" "}
|
||||||
View All Task(s)
|
View All Task(s)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ export default function HomeSliders(props) {
|
|||||||
// debugger;
|
// debugger;
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="hero-slider relative 2xl:w-[600px] xl:w-[400px] lg:w-[420px] w-full mb-2 lg:mb-0 ">
|
<div className="hero-slider relative h-full w-full mb-2 lg:mb-0">
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<SliderCom settings={props.settings}>
|
<SliderCom settings={props.settings}>
|
||||||
{props.bannerList?.length <= 0 && (
|
{props.bannerList?.length <= 0 && (
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import React from 'react'
|
|||||||
|
|
||||||
function CurrentJobAction() {
|
function CurrentJobAction() {
|
||||||
return (
|
return (
|
||||||
<div className='job-action bg-white dark:bg-black'>
|
<div className='job-action dark:bg-black'>
|
||||||
<p className="my-3 py-1 text-base active-owner">
|
<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>
|
<tbody>
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ function CurrentTaskAction({jobDetails}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='job-action bg-white dark:bg-black'>
|
<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>
|
<tbody>
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ function PastDueJobAction({jobDetails}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='job-action bg-white dark:bg-black'>
|
<div className='job-action dark:bg-black'>
|
||||||
|
|
||||||
<table className="w-full text-sm text-left text-gray-500 owner-pastdue">
|
<table className="w-full text-sm text-left text-gray-500 owner-pastdue">
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import React from 'react'
|
|||||||
|
|
||||||
function PastDueTaskAction() {
|
function PastDueTaskAction() {
|
||||||
return (
|
return (
|
||||||
<div className='job-action bg-white dark:bg-black'>
|
<div className='job-action dark:bg-black'>
|
||||||
|
|
||||||
<table className="w-full text-sm text-left text-gray-500 worker-pastdue">
|
<table className="w-full text-sm text-left text-gray-500 worker-pastdue">
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ function ReviewJobAction({jobDetails}) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div className='job-action bg-white dark:bg-black'>
|
<div className='job-action dark:bg-black'>
|
||||||
<div className="my-3 py-1 text-base">
|
<div className="my-3 py-1 text-base">
|
||||||
<table className="w-full text-sm text-left text-gray-500 review-owner">
|
<table className="w-full text-sm text-left text-gray-500 review-owner">
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import React from 'react'
|
|||||||
|
|
||||||
function ReviewTaskAction() {
|
function ReviewTaskAction() {
|
||||||
return (
|
return (
|
||||||
<div className='job-action bg-white dark:bg-black'>
|
<div className='job-action dark:bg-black'>
|
||||||
<p className="my-3 py-1 text-base text-dark-gray dark:text-white">
|
<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
|
Waiting for the completion message from the client before you can approve. Worker True & Review Job
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ function AddFund({payment}) {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{/* heading */}
|
{/* heading */}
|
||||||
<div className="sm:flex justify-between items-center mb-6">
|
{/* <div className="sm:flex justify-between items-center mb-6">
|
||||||
<div className="w-full flex justify-start space-x-3 items-center">
|
<div className="w-full flex justify-start space-x-3 items-center">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -71,7 +71,7 @@ function AddFund({payment}) {
|
|||||||
className="relative"
|
className="relative"
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> */}
|
||||||
|
|
||||||
<div className="content-wrapper w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin">
|
<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="lg:w-2/2 w-full mb-10 lg:mb-0">
|
||||||
|
|||||||
@@ -1,480 +1,520 @@
|
|||||||
import React,{useEffect, useState} from 'react'
|
import React, { useEffect, useState } from "react";
|
||||||
import { useNavigate } from 'react-router-dom'
|
import { useNavigate } from "react-router-dom";
|
||||||
import InputCom from '../Helpers/Inputs/InputCom';
|
import usersService from "../../services/UsersService";
|
||||||
import PaginatedList from '../Pagination/PaginatedList';
|
import InputCom from "../Helpers/Inputs/InputCom";
|
||||||
import { handlePagingFunc } from '../Pagination/HandlePagination';
|
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||||
import LoadingSpinner from '../Spinners/LoadingSpinner';
|
|
||||||
import usersService from '../../services/UsersService';
|
|
||||||
|
|
||||||
import { Form, Formik } from "formik";
|
import { Form, Formik } from "formik";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
import * as Yup from "yup";
|
import * as Yup from "yup";
|
||||||
|
import Icons from "../Helpers/Icons";
|
||||||
|
|
||||||
const validationSchema = Yup.object().shape({
|
const validationSchema = Yup.object().shape({
|
||||||
name: Yup.string()
|
name: Yup.string()
|
||||||
.min(3, "Minimum 3 characters")
|
.min(3, "3 chars min.")
|
||||||
.max(50, "Maximum 50 characters")
|
.max(50, "50 chars max.")
|
||||||
.required("Name is required"),
|
.required("required"),
|
||||||
cardNum: Yup.string()
|
cardNum: Yup.string()
|
||||||
.min(3, "Minimum 3 characters")
|
.min(3, "3 chars min.")
|
||||||
.max(25, "Maximum 25 characters")
|
.max(25, "25 chars max.")
|
||||||
.required("Card Number is required"),
|
.required("required"),
|
||||||
code: Yup.string()
|
code: Yup.string()
|
||||||
.min(3, "Minimum 3 characters")
|
.min(3, "3 chars min.")
|
||||||
.max(25, "Maximum 25 characters")
|
.max(25, "25 chars max.")
|
||||||
.required("Postal Code is required"),
|
.required("required"),
|
||||||
state: Yup.string()
|
state: Yup.string()
|
||||||
.min(3, "Minimum 3 characters")
|
.min(3, "3 chars min.")
|
||||||
.max(25, "Maximum 25 characters")
|
.max(25, "25 chars max.")
|
||||||
.required("State is required"),
|
.required("required"),
|
||||||
address: Yup.string()
|
address: Yup.string()
|
||||||
.min(3, "Minimum 3 characters")
|
.min(3, "3 chars min.")
|
||||||
.max(50, "Maximum 50 characters")
|
.max(50, "50 chars max.")
|
||||||
.required("Address is required"),
|
.required("required"),
|
||||||
expirationYear: Yup.string()
|
expirationYear: Yup.string()
|
||||||
.min(4, "Minimum 4 characters")
|
.min(4, "4 chars min.")
|
||||||
.max(4, "Maximum 4 characters")
|
.max(4, "4 chars max.")
|
||||||
.required("Expiration Year is required"),
|
.required("required"),
|
||||||
expirationMonth: Yup.string()
|
expirationMonth: Yup.string()
|
||||||
.min(1, "Minimum 1 characters")
|
.min(1, "1 chars min.")
|
||||||
.max(2, "Maximum 2 characters")
|
.max(2, "2 chars max.")
|
||||||
.required("Expiration Month is required"),
|
.required("required"),
|
||||||
cvv: Yup.string()
|
cvv: Yup.string()
|
||||||
.min(3, "Minimum 3 characters")
|
.min(3, "3 chars min.")
|
||||||
.max(4, "Maximum 4 characters")
|
.max(4, "4 chars max.")
|
||||||
.required("CVV Year is required"),
|
.required("required"),
|
||||||
});
|
});
|
||||||
|
|
||||||
const initialValues = {
|
const initialValues = {
|
||||||
name: '',
|
name: "",
|
||||||
cardNum: '',
|
cardNum: "",
|
||||||
code: '',
|
code: "",
|
||||||
state: '',
|
state: "",
|
||||||
address: '',
|
address: "",
|
||||||
expirationYear: '',
|
expirationYear: "",
|
||||||
expirationMonth: '',
|
expirationMonth: "",
|
||||||
cvv: ''
|
cvv: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
function AddFundDollars(props) {
|
function AddFundDollars(props) {
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate();
|
||||||
let apiCall = new usersService()
|
const apiCall = new usersService();
|
||||||
|
|
||||||
let [tab, setTab] = useState("previous"); //STATE FOR SWITCHING BETWEEN TABS
|
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 [prevCardDetails, setPrevCardDetails] = useState(null) // STATE TO HOLD PREVIOUS CARD SELECTED
|
const handleInputChange = (event) => {
|
||||||
|
const { name, value } = event.target;
|
||||||
|
setPrevCardDetails((prevState) => ({
|
||||||
|
...prevState,
|
||||||
|
[name]: value,
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
let [payListCard, setPayListCard] = useState({loading: true, data:[]}) //USER PREVIOUS CARDS
|
const indexOfFirstItem = 0;
|
||||||
|
const indexOfLastItem =
|
||||||
|
indexOfFirstItem + Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
||||||
|
const currentPreviousCards = payListCards?.data?.slice(
|
||||||
|
indexOfFirstItem,
|
||||||
|
indexOfLastItem
|
||||||
|
);
|
||||||
|
|
||||||
const [currentPage, setCurrentPage] = useState(0);
|
const handleSubmit = (values, helpers) => {
|
||||||
const indexOfFirstItem = Number(currentPage);
|
props.setInputError("");
|
||||||
const indexOfLastItem = Number(indexOfFirstItem)+Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
if (!props.input || props.input === "0") {
|
||||||
const currentPreviousCards = payListCard?.data?.slice(indexOfFirstItem, indexOfLastItem);
|
props.setInputError("Please Enter Amount");
|
||||||
|
return;
|
||||||
const handlePagination = (e) => {
|
|
||||||
handlePagingFunc(e,setCurrentPage)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FUNCTION TO SUBMIT
|
if (isNaN(props.input)) {
|
||||||
const handleSubmit = (values, helpers) => {
|
props.setInputError("Amount must be a Number");
|
||||||
props.setInputError('')
|
return;
|
||||||
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(()=>{
|
if (tab === "previous") {
|
||||||
apiCall.payListCard().then(res => {
|
if (!prevCardDetails) {
|
||||||
setPayListCard({loading: false, data: res.data.result_list})
|
return;
|
||||||
}).catch(err => {
|
}
|
||||||
console.log('PAYCARDLIST ERROR', err)
|
setLoader(true);
|
||||||
setPayListCard({loading: false, data: []})
|
const stateData = {
|
||||||
})
|
amount: Number(props.input),
|
||||||
}, [])
|
currency: props.currency,
|
||||||
|
card: prevCardDetails["payment-card"],
|
||||||
|
};
|
||||||
|
|
||||||
|
return setTimeout(() => {
|
||||||
|
props.setConfirmCredit({ show: true, data: stateData });
|
||||||
|
setLoader(false);
|
||||||
|
}, 1500);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tab === "new") {
|
||||||
|
const stateData = {
|
||||||
|
amount: Number(props.input),
|
||||||
|
currency: props.currency,
|
||||||
|
...values,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
apiCall
|
||||||
|
.payListCard()
|
||||||
|
.then((res) => {
|
||||||
|
setPayListCards({ loading: false, data: res.data.result_list });
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log("PAYCARDLIST ERROR", err);
|
||||||
|
setPayListCards({ loading: false, data: [] });
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
console.log(props)
|
||||||
|
|
||||||
|
const handleClose = props.onClose
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h1 className='mb-2 text-xl font-bold text-dark-gray dark:text-white'>Payment Method</h1>
|
<div className="w-full">
|
||||||
<div className="w-full">
|
{/* switch button */}
|
||||||
{/* switch button */}
|
<div className="flex">
|
||||||
<div className="my-1 flex items-center border-b border-slate-300">
|
<form className="add-fund-info flex items-center gap-3">
|
||||||
<button
|
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||||
name="previous"
|
{props.currency == "US Dollars" && "Payment Method"}
|
||||||
onClick={(e) => setTab(e.target.name)}
|
</h1>
|
||||||
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border ${
|
<div className="my-1 flex items-center gap-2">
|
||||||
tab == "previous" ? "border-sky-blue" : "border-slate-300"
|
<label
|
||||||
} tracking-wide transition duration-200`}
|
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
|
Previous Cards
|
||||||
</button>
|
</label>
|
||||||
<button
|
<label
|
||||||
name="new"
|
onClick={() => setTab("new")}
|
||||||
onClick={(e) => setTab(e.target.name)}
|
htmlFor="new"
|
||||||
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border ${
|
className="cursor-pointer flex items-center gap-1"
|
||||||
tab == "new" ? "border-sky-blue" : "border-slate-300"
|
>
|
||||||
} tracking-wide transition duration-200`}
|
<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
|
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>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{/* END OF switch button */}
|
)}
|
||||||
|
</div>
|
||||||
{/* previous tab */}
|
) : (
|
||||||
{tab == 'previous' ?
|
<div className="new-details w-full max-h-[23rem]">
|
||||||
<div className="p-4 previous-details w-full border min-h-[300px] flex flex-col justify-between items-center">
|
<div className="w-full flex flex-col justify-between">
|
||||||
{ payListCard.loading ?
|
<Formik
|
||||||
<LoadingSpinner size='10' color='sky-blue' />
|
initialValues={initialValues}
|
||||||
:
|
validationSchema={validationSchema}
|
||||||
payListCard?.data?.length ?
|
onSubmit={handleSubmit}
|
||||||
<table className="my-3 w-full">
|
>
|
||||||
<tbody>
|
{(props) => {
|
||||||
{currentPreviousCards.map((item, index)=>(
|
return (
|
||||||
<tr key={index} className={index != 0 && 'border-t-2'}>
|
<Form className="md:pl-8">
|
||||||
<td>
|
<div className="flex flex-col-reverse sm:flex-row">
|
||||||
<div className='my-2 flex items-center gap-5'>
|
<div className="flex-1 sm:mr-10">
|
||||||
<input type="radio" className='w-8 h-8' name='card' value='value' />
|
<div className="fields w-full">
|
||||||
<div className='card-details'>
|
{/* Inputs */}
|
||||||
<h1 className='text-lg font-bold text-dark-gray dark:text-white tracking-wide'>{item.description} Card</h1>
|
{/* Name */}
|
||||||
<p className='text-base font-bold text-dark-gray dark:text-white tracking-wide'>Bank **************{item.digits}</p>
|
<div className="flex items-center field w-full my-2 flex-[0.4] gap-3">
|
||||||
<div className='w-full sm:flex items-center gap-5'>
|
<label className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold flex items-center gap-1">
|
||||||
<p className='text-base font-bold text-dark-gray dark:text-white tracking-wide'>{item.added}</p>
|
Name:
|
||||||
<p className='text-sm font-bold text-green-700 dark:text-white tracking-wide'>Verified</p>
|
</label>
|
||||||
</div>
|
<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>
|
|
||||||
</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>
|
||||||
|
|
||||||
{/* <div className="w-full">
|
<div className="flex items-center flex-1 gap-3 my-2">
|
||||||
{requestStatus.message != "" && (
|
{/* Card Number */}
|
||||||
<p
|
<div className="field w-full flex-[0.6]">
|
||||||
className={`text-center text-base ${
|
<InputCom
|
||||||
requestStatus.status ? "text-green-800" : "text-red-600"
|
fieldClass="px-6"
|
||||||
}`}
|
spanTag="*"
|
||||||
>
|
iconName="master-card visa-card atm-card"
|
||||||
{requestStatus.message}
|
label="Card Number"
|
||||||
</p>
|
type="text"
|
||||||
)}
|
name="cardNum"
|
||||||
<div className="w-full h-[120px] border-t border-light-purple dark:border-[#5356fb29] flex justify-end items-center">
|
placeholder="Enter Card Number"
|
||||||
<div className="flex items-center space-x-4 mr-9">
|
value={props.values.cardNum}
|
||||||
<Link
|
inputHandler={props.handleChange}
|
||||||
to="/"
|
blurHandler={props.handleBlur}
|
||||||
className="text-18 text-light-red tracking-wide "
|
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`}
|
||||||
>
|
>
|
||||||
<span className="border-b dark:border-[#5356fb29] border-light-red">
|
<label
|
||||||
{" "}
|
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold line-clamp-3 flex items-center"
|
||||||
Cancel
|
htmlFor="expiration"
|
||||||
</span>
|
>
|
||||||
</Link>
|
Exp Month{" "}
|
||||||
|
<span className="text-red-700 text-sm italic">
|
||||||
{requestStatus.loading ? (
|
*
|
||||||
<LoadingSpinner size="8" color="sky-blue" />
|
</span>
|
||||||
) : (
|
<span className="text-[12px] text-red-500 ml-1">
|
||||||
<button
|
{props.errors.expirationMonth && "**"}
|
||||||
type="submit"
|
</span>
|
||||||
className="w-[152px] h-[46px] flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
</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`}
|
||||||
>
|
>
|
||||||
Update Profile
|
<select
|
||||||
</button>
|
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>
|
||||||
|
<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>
|
||||||
<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>
|
</div>
|
||||||
</Form>
|
|
||||||
);
|
<div className="flex items-center flex-1 gap-3 my-2">
|
||||||
}}
|
{/* Address and CVV */}
|
||||||
</Formik>
|
<div className="field w-full col-span-1 flex-[0.4]">
|
||||||
</div>
|
<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>
|
||||||
|
)}
|
||||||
|
</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"
|
||||||
|
>
|
||||||
|
{loader ? (
|
||||||
|
<LoadingSpinner size="6" color="sky-blue" />
|
||||||
|
) : (
|
||||||
|
<span className="text-white">Continue</span>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
</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
|
export default AddFundDollars;
|
||||||
|
|
||||||
|
|
||||||
// FORMS ARRAY OF EXPIRATION YEAR FOR CARD
|
// FORMS ARRAY OF EXPIRATION YEAR FOR CARD
|
||||||
const expireYear = []
|
const expireYear = [];
|
||||||
let currentYear = new Date().getFullYear()
|
let currentYear = new Date().getFullYear();
|
||||||
for(let i=0; i<=6; i++){
|
for (let i = 0; i <= 6; i++) {
|
||||||
expireYear.push(currentYear + i)
|
expireYear.push(currentYear + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FORMS ARRAY OF EXPIRATION MONTH FOR CARD
|
// FORMS ARRAY OF EXPIRATION MONTH FOR CARD
|
||||||
let month = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
|
let month = [
|
||||||
const expireMonth = []
|
"January",
|
||||||
for(let i=0; i<month.length; i++){
|
"February",
|
||||||
expireMonth.push({name:month[i], value:i+1})
|
"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,138 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import InputCom from "../Helpers/Inputs/InputCom";
|
||||||
|
|
||||||
|
import AddFundDollars from "./AddFundDollars";
|
||||||
|
|
||||||
|
function AddFundPop({ _payment, input, setInput, onClose, setConfirmCredit }) {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
// const { currency } = useLocation()?.state; //GETS THE USER CURRENCY FOR ADD FUND
|
||||||
|
|
||||||
|
let { payment, currency } = _payment;
|
||||||
|
|
||||||
|
//STATE FOR CONTROLLED INPUT
|
||||||
|
let [inputError, setInputError] = useState("");
|
||||||
|
|
||||||
|
// FUNCTION TO HANDLE INPUT CHANGE
|
||||||
|
const handleChange = ({ target: { name, value } }) => {
|
||||||
|
setInput(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
//FUNCTION TO HANDLE SUBMIT
|
||||||
|
const handleSubmit = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
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: currency,
|
||||||
|
};
|
||||||
|
|
||||||
|
return setTimeout(
|
||||||
|
() =>
|
||||||
|
setConfirmCredit({
|
||||||
|
show: true,
|
||||||
|
data: stateData,
|
||||||
|
}),
|
||||||
|
1500
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
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">
|
||||||
|
{/*<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: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>
|
||||||
|
|
||||||
|
{/* SHOWS THIS IF USER CURRENCY IS DOLLARS */}
|
||||||
|
{currency == "US Dollars" && (
|
||||||
|
<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}
|
||||||
|
input={input}
|
||||||
|
setInput={setInput}
|
||||||
|
currency={currency}
|
||||||
|
onClose={onClose}
|
||||||
|
setConfirmCredit={setConfirmCredit}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{currency != "US Dollars" && <div className="h-[18rem]"></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 gap-4">
|
||||||
|
<button
|
||||||
|
className="px-2 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-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>
|
||||||
|
null}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AddFundPop;
|
||||||
@@ -1,16 +1,14 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
import { useLocation, useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
import InputCom from "../Helpers/Inputs/InputCom";
|
import InputCom from "../Helpers/Inputs/InputCom";
|
||||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
|
||||||
import RecentActivityTable from "./WalletComponent/RecentActivityTable";
|
|
||||||
|
|
||||||
import usersService from "../../services/UsersService";
|
import usersService from "../../services/UsersService";
|
||||||
|
|
||||||
import { FlutterWaveButton, closePaymentModal } from "flutterwave-react-v3";
|
import { FlutterWaveButton, closePaymentModal } from "flutterwave-react-v3";
|
||||||
|
|
||||||
function ConfirmAddFund({ payment }) {
|
function ConfirmAddFund({ confirmCredit, onClose, walletItem }) {
|
||||||
let { userDetails } = useSelector((state) => state.userDetails); // TO GET LOGGEDIN USER DETAILS
|
let { userDetails } = useSelector((state) => state.userDetails); // TO GET LOGGEDIN USER DETAILS
|
||||||
|
|
||||||
let [pageLoading, setPageLoading] = useState(true);
|
let [pageLoading, setPageLoading] = useState(true);
|
||||||
@@ -24,12 +22,10 @@ function ConfirmAddFund({ payment }) {
|
|||||||
const apiURL = new usersService();
|
const apiURL = new usersService();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
let { state } = useLocation();
|
|
||||||
|
|
||||||
//FUNCTION TO HANDLE SUBMIT
|
//FUNCTION TO HANDLE SUBMIT
|
||||||
const onSuccessPayment = () => {
|
const onSuccessPayment = () => {
|
||||||
setRequestStatus({ message: "", loading: true, status: false });
|
setRequestStatus({ message: "", loading: true, status: false });
|
||||||
let reqData = { amount: state?.account, currency: "NGN" };
|
let reqData = { amount: confirmCredit?.data?.account, currency: "NGN" };
|
||||||
apiURL
|
apiURL
|
||||||
.startTopUp(reqData)
|
.startTopUp(reqData)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
@@ -66,7 +62,7 @@ function ConfirmAddFund({ payment }) {
|
|||||||
const config = {
|
const config = {
|
||||||
public_key: process.env.REACT_APP_FLUTTERWAVE_APIKEY,
|
public_key: process.env.REACT_APP_FLUTTERWAVE_APIKEY,
|
||||||
tx_ref: Date.now(),
|
tx_ref: Date.now(),
|
||||||
amount: state?.amount,
|
amount: confirmCredit?.data?.amount,
|
||||||
currency: "NGN",
|
currency: "NGN",
|
||||||
payment_options: "card,mobilemoney,ussd",
|
payment_options: "card,mobilemoney,ussd",
|
||||||
customer: {
|
customer: {
|
||||||
@@ -91,73 +87,118 @@ function ConfirmAddFund({ payment }) {
|
|||||||
onClose: () => {},
|
onClose: () => {},
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
// what happens if not state redirect user
|
// // what happens if not data redirect user
|
||||||
if (!state) {
|
// if (!data) {
|
||||||
navigate("/my-wallet/add-fund", { replace: true });
|
// navigate("/my-wallet/add-fund", { replace: true });
|
||||||
} else {
|
// } else {
|
||||||
setPageLoading(false);
|
// setPageLoading(false);
|
||||||
}
|
// }
|
||||||
}, []);
|
// }, []);
|
||||||
|
|
||||||
|
const __confirmCard = confirmCredit?.data.card
|
||||||
|
? JSON.parse(confirmCredit?.data.card)
|
||||||
|
: "";
|
||||||
|
|
||||||
|
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 (
|
return (
|
||||||
<div className="content-wrapper w-full">
|
<div className="content-wrapper w-full h-[32rem]">
|
||||||
{pageLoading ? (
|
<div className="w-full mb-10">
|
||||||
<LoadingSpinner size="8" color="sky-blue" />
|
<div className="add-fund w-full bg-white dark:bg-dark-white rounded-2xl">
|
||||||
) : (
|
{/* <h2 className="md:p-8 p-4 text-slate-900 dark:text-white text-xl lg:text-2xl font-medium">
|
||||||
<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
|
Confirm Add Fund To Account
|
||||||
</h2>
|
</h2>
|
||||||
<hr />
|
<hr /> */}
|
||||||
<div className="px-4 md:px-8 py-4 add-fund-info">
|
<div className="px-4 md:p-8 py-4 add-fund-info">
|
||||||
<div className="field w-full mb-3">
|
<div className="field w-full mb-3 min-h-[45px]">
|
||||||
|
{confirmCredit?.show ? (
|
||||||
|
<div className="flex flex-col gap-4">
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||||
|
Amount({confirmCredit?.data?.currency})
|
||||||
|
</h1>
|
||||||
|
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
||||||
|
{`${walletItem?.symbol} ${
|
||||||
|
Number(confirmCredit?.data?.amount).toLocaleString() ||
|
||||||
|
""
|
||||||
|
}`}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
{/* <h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1"> */}
|
||||||
|
<label
|
||||||
|
htmlFor="payment"
|
||||||
|
className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1"
|
||||||
|
>
|
||||||
|
{confirmCredit?.data?.currency && "Payment Method:"}
|
||||||
|
</label>
|
||||||
|
<span className="text-[#181c32] dark:text-white ">
|
||||||
|
{__confirmCard ? (
|
||||||
|
<ThePaymentText value={__confirmCard} />
|
||||||
|
) : null}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
<InputCom
|
<InputCom
|
||||||
fieldClass="px-6"
|
fieldClass="px-6"
|
||||||
label={state.currency == 'naira' ? "Amount (Naira):" : "Amount (Dollars):"}
|
label={` Amount${confirmCredit?.data?.currency}`}
|
||||||
type="text"
|
type="text"
|
||||||
name="amount"
|
name="amount"
|
||||||
value={state.amount || ""}
|
value={confirmCredit?.data?.amount || ""}
|
||||||
disable={true}
|
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>
|
||||||
</div>
|
{/* <h1 className="mb-2 text-xl font-bold text-dark-gray dark:text-white px-4 h-5">
|
||||||
)}
|
{confirmCredit?.data?.currency && "Payment Method"}
|
||||||
|
</h1> */}
|
||||||
|
{/* <hr /> */}
|
||||||
|
<div className="min-h-[220px]"></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 border-gradient text-base rounded-full"
|
||||||
|
onClick={onClose}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
|
||||||
<div className="w-full mb-10">
|
{confirmCredit?.data?.currency == "Naira" && (
|
||||||
<div className="wallet w-full md:p-8 p-4 h-full min-h-[600px] bg-white dark:bg-dark-white rounded-2xl shadow">
|
<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 className="w-full mb-10">
|
||||||
|
<div className="wallet w-full md:p-8 p-4 h-full bg-white dark:bg-dark-white rounded-2xl shadow">
|
||||||
<h2 className="text-gray-900 dark:text-white text-xl lg:text-2xl font-medium">
|
<h2 className="text-gray-900 dark:text-white text-xl lg:text-2xl font-medium">
|
||||||
Recent Activity
|
Recent Activity
|
||||||
</h2>
|
</h2>
|
||||||
{/* <p className='text-base text-gray-600 dark:text-white'>Activity Report</p> */}
|
<p className='text-base text-gray-600 dark:text-white'>Activity Report</p>
|
||||||
{payment.loading ? (
|
{payment.loading ? (
|
||||||
<LoadingSpinner size="16" color="sky-blue" />
|
<LoadingSpinner size="16" color="sky-blue" />
|
||||||
) : (
|
) : (
|
||||||
<RecentActivityTable payment={payment} />
|
<RecentActivityTable payment={payment} />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> */}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,110 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import { useLocation } from "react-router-dom";
|
||||||
|
import usersService from "../../../services/UsersService";
|
||||||
|
import ModalCom from "../../Helpers/ModalCom";
|
||||||
|
import AddFundPop from "../AddFundPop";
|
||||||
|
import ConfirmAddFund from "../ConfirmAddFund";
|
||||||
|
|
||||||
|
const CreditPopup = ({ details, onClose, situation, walletItem }) => {
|
||||||
|
const { pathname, state } = useLocation();
|
||||||
|
const [submitTask, setSubmitTask] = useState({
|
||||||
|
loading: false,
|
||||||
|
msg: "",
|
||||||
|
state: "",
|
||||||
|
});
|
||||||
|
const [suggestedNextStep, setSuggestedNextStep] = useState("Send Task");
|
||||||
|
let [input, setInput] = useState("");
|
||||||
|
const [confirmCredit, setConfirmCredit] = useState({
|
||||||
|
show: false,
|
||||||
|
data: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
// const openConfirmCredit = (value) => {
|
||||||
|
// setConfirmCredit({ show: true, data: { ...value } });
|
||||||
|
// };
|
||||||
|
|
||||||
|
// const closeConfirmCredit = () => {
|
||||||
|
// setConfirmCredit({ show: false, data: {} });
|
||||||
|
// };
|
||||||
|
// const handleConfirmCredit = useMemo((input) => {
|
||||||
|
// if (input) {
|
||||||
|
// setConfirmCredit(true);
|
||||||
|
// } else setConfirmCredit(false);
|
||||||
|
// }, []);
|
||||||
|
|
||||||
|
const switchNextStep = ({ target: value }) => {
|
||||||
|
setSuggestedNextStep(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const apiCall = new usersService();
|
||||||
|
|
||||||
|
const handleParentSuggestion = (values) => {
|
||||||
|
if (suggestedNextStep == "Send Task") {
|
||||||
|
let firstName = state?.firstname;
|
||||||
|
let family_uid = state?.family_uid;
|
||||||
|
// continuePopupData({ ...details, firstName, family_uid });
|
||||||
|
}
|
||||||
|
onClose();
|
||||||
|
};
|
||||||
|
|
||||||
|
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 ? "Add Credit" : "Confirm Credit Add"}
|
||||||
|
</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 ? (
|
||||||
|
<ConfirmAddFund
|
||||||
|
confirmCredit={confirmCredit}
|
||||||
|
walletItem={walletItem}
|
||||||
|
onClose={onClose}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<AddFundPop
|
||||||
|
_payment={details}
|
||||||
|
input={input}
|
||||||
|
setInput={setInput}
|
||||||
|
onClose={onClose}
|
||||||
|
confirmCredit={confirmCredit}
|
||||||
|
setConfirmCredit={setConfirmCredit}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ModalCom>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CreditPopup;
|
||||||
@@ -91,6 +91,7 @@ function TransferFund({ payment, wallet }) {
|
|||||||
|
|
||||||
//FUNCTION TO HANDLE SUBMIT
|
//FUNCTION TO HANDLE SUBMIT
|
||||||
const handleSubmit = (values, helpers) => {
|
const handleSubmit = (values, helpers) => {
|
||||||
|
if(!values?.amount && !values.recipientID) return
|
||||||
setRequestStatus(true);
|
setRequestStatus(true);
|
||||||
let recipientDetails = recipients.data?.filter(
|
let recipientDetails = recipients.data?.filter(
|
||||||
(item) => item.recipient_id == values.recipientID
|
(item) => item.recipient_id == values.recipientID
|
||||||
@@ -302,6 +303,7 @@ function TransferFund({ payment, wallet }) {
|
|||||||
) : (
|
) : (
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
|
disabled={props.isSubmitting}
|
||||||
className="text-lg text-white bg-sky-blue px-4 py-2 hover:opacity-90 rounded-md"
|
className="text-lg text-white bg-sky-blue px-4 py-2 hover:opacity-90 rounded-md"
|
||||||
>
|
>
|
||||||
Continue
|
Continue
|
||||||
|
|||||||
@@ -1,83 +1,177 @@
|
|||||||
import React, { useEffect, useState } from 'react'
|
import React, {
|
||||||
import {Routes, Route, Outlet, Navigate} from 'react-router-dom'
|
Suspense,
|
||||||
import usersService from '../../services/UsersService'
|
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'
|
const AddFund = lazy(() => import("./AddFund"));
|
||||||
|
const ConfirmAddFund = lazy(() => import("./ConfirmAddFund"));
|
||||||
import Balance from './Balance'
|
const TransferFund = lazy(() => import("./TransferFund"));
|
||||||
import TransferFund from './TransferFund'
|
const WalletBox = lazy(() => import("./WalletBox"));
|
||||||
import AddFund from './AddFund'
|
const AddRecipient = lazy(() => import("./AddRecipient"));
|
||||||
import AddRecipient from './AddRecipient'
|
const ConfirmTransfer = lazy(() => import("./ConfirmTransfer"));
|
||||||
import ConfirmTransfer from './ConfirmTransfer'
|
|
||||||
import ConfirmAddFund from './ConfirmAddFund'
|
|
||||||
|
|
||||||
function Wallet() {
|
function Wallet() {
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
<Outlet />
|
<Outlet />
|
||||||
</Layout>
|
</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 WalletRoutes = () => {
|
||||||
const apiCall = new usersService()
|
const apiCall = useMemo(() => new usersService(), []);
|
||||||
|
|
||||||
let [walletList, setWalletList] = useState({ // FOR WALLET LIST
|
const [walletList, dispatchWalletList] = useReducer(reducer, initialState);
|
||||||
loading: true,
|
const [paymentHistory, dispatchPaymentHistory] = useReducer(
|
||||||
data: [],
|
reducer,
|
||||||
error: false
|
initialState
|
||||||
})
|
);
|
||||||
|
|
||||||
let [paymentHistory, setPaymentHistory] = useState({ // FOR PAYMENT HISTORY
|
const getWalletList = useCallback(() => {
|
||||||
loading: true,
|
apiCall
|
||||||
data: [],
|
.getUserWallets(null)
|
||||||
error: false
|
.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 getPaymentHistory = useCallback(() => {
|
||||||
const getWalletList = ()=>{
|
apiCall
|
||||||
apiCall.getUserWallets(null).then((res)=>{
|
.getPaymentHx()
|
||||||
if(res.data.internal_return < 0){ // success but no data
|
.then((res) => {
|
||||||
setWalletList(prev => ({...prev, loading: false}))
|
if (res.data.internal_return < 0) {
|
||||||
return
|
dispatchPaymentHistory({ type: "FETCH_SUCCESS", payload: [] });
|
||||||
}
|
} else {
|
||||||
setWalletList(prev => ({...prev, loading: false, data: res.data.result_list}))
|
dispatchPaymentHistory({
|
||||||
}).catch((error)=>{
|
type: "FETCH_SUCCESS",
|
||||||
setWalletList(prev => ({...prev, loading: false, error: true}))
|
payload: res.data.result_list,
|
||||||
})
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
dispatchPaymentHistory({ type: "FETCH_ERROR" });
|
||||||
|
});
|
||||||
|
}, [apiCall]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let isMounted = true;
|
||||||
|
|
||||||
|
if (isMounted) {
|
||||||
|
getWalletList();
|
||||||
|
getPaymentHistory();
|
||||||
}
|
}
|
||||||
|
|
||||||
//FUNCTION TO GET PAYMENT HISTORY
|
return () => {
|
||||||
const getPaymentHistory = ()=>{
|
isMounted = false;
|
||||||
apiCall.getPaymentHx().then((res)=>{
|
};
|
||||||
if(res.data.internal_return < 0){ // success but no data
|
}, [getWalletList, getPaymentHistory]);
|
||||||
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}))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(()=>{
|
return (
|
||||||
getWalletList()
|
<Routes>
|
||||||
getPaymentHistory()
|
<Route
|
||||||
}, [])
|
element={
|
||||||
return (
|
<Suspense fallback={<LoadingSpinner size="16" color="sky-blue" />}>
|
||||||
<Routes>
|
<Wallet />
|
||||||
<Route element={<Wallet />}>
|
</Suspense>
|
||||||
<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
|
||||||
<Route index element={<Balance wallet={walletList} />} />
|
path="add-fund"
|
||||||
<Route path='transfer-fund/add-recipient' element={<AddRecipient />} />
|
element={
|
||||||
<Route path='transfer-fund/confirm-transfer' element={<ConfirmTransfer payment={paymentHistory} wallet={walletList} />} />
|
<Suspense fallback={<LoadingSpinner size="16" color="sky-blue" />}>
|
||||||
<Route path='*' element={<Navigate to='/' />} />
|
<AddFund payment={paymentHistory} />
|
||||||
</Route>
|
</Suspense>
|
||||||
</Routes>
|
}
|
||||||
)
|
/>
|
||||||
}
|
<Route
|
||||||
|
path="add-fund/confirm-add-fund"
|
||||||
|
element={
|
||||||
|
<Suspense fallback={<LoadingSpinner size="16" color="sky-blue" />}>
|
||||||
|
<ConfirmAddFund payment={paymentHistory} />
|
||||||
|
</Suspense>
|
||||||
|
}
|
||||||
|
/> */}
|
||||||
|
<Route
|
||||||
|
path="transfer-fund"
|
||||||
|
element={
|
||||||
|
<Suspense fallback={<LoadingSpinner size="16" color="sky-blue" />}>
|
||||||
|
<TransferFund payment={paymentHistory} wallet={walletList} />
|
||||||
|
</Suspense>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
{/*<Route index element={<Balance wallet={walletList} />} />*/}
|
||||||
|
<Route
|
||||||
|
index
|
||||||
|
element={
|
||||||
|
<Suspense fallback={<LoadingSpinner size="16" color="sky-blue" />}>
|
||||||
|
<WalletBox wallet={walletList} payment={paymentHistory} />
|
||||||
|
</Suspense>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="transfer-fund/add-recipient"
|
||||||
|
element={
|
||||||
|
<Suspense fallback={<LoadingSpinner size="16" color="sky-blue" />}>
|
||||||
|
<AddRecipient />
|
||||||
|
</Suspense>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="transfer-fund/confirm-transfer"
|
||||||
|
element={
|
||||||
|
<Suspense fallback={<LoadingSpinner size="16" color="sky-blue" />}>
|
||||||
|
<ConfirmTransfer payment={paymentHistory} wallet={walletList} />
|
||||||
|
</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 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
|
||||||
@@ -0,0 +1,266 @@
|
|||||||
|
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, payment }) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="my-wallet-wrapper w-full mb-10">
|
||||||
|
<div className="main-wrapper w-full">
|
||||||
|
<div className="balance-inquery w-full flex flex-wrap justify-center gap-2">
|
||||||
|
{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="w-[350px] h-full flex justify-center">
|
||||||
|
<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 PaginatedList from "../../Pagination/PaginatedList";
|
||||||
import {handlePagingFunc} from '../../Pagination/HandlePagination';
|
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 handlePagination = (e) => {
|
||||||
const indexOfFirstItem = Number(currentPage);
|
handlePagingFunc(e, setCurrentPage);
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='flex flex-col justify-between min-h-[500px]'>
|
<div className="flex flex-col justify-between overflow-y-auto">
|
||||||
<table className="wallet-activity w-full table-auto border-collapse text-left">
|
<table className="wallet-activity w-full table-auto border-collapse text-left">
|
||||||
<thead className='border-b-2'>
|
<thead className="border-b-2">
|
||||||
<tr className='text-slate-600'>
|
<tr className="text-slate-600">
|
||||||
<th className="p-2">Date</th>
|
<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">Amnt./Fee</th>
|
||||||
<th className="p-2">Status</th>
|
<th className="p-2">Status</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
{payment.data.length ?
|
{payment?.data?.length > 0 ? (
|
||||||
(
|
<tbody>
|
||||||
<tbody>
|
|
||||||
{currentActivity.map((item, index) => (
|
{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-2">{item.trx_date}</td>
|
||||||
<td className="p-4" dangerouslySetInnerHTML={{__html:item.recipient}}></td>
|
<td
|
||||||
<td className="p-2">{item.amount}<br />{item.fee}</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>
|
<td className="p-2">{item.status}</td>
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
)
|
) : payment?.error ? (
|
||||||
:
|
<tbody>
|
||||||
payment.error ?
|
<tr className="text-slate-500">
|
||||||
(
|
<td className="p-2" colSpan={4}>
|
||||||
<tbody>
|
Opps! an error occurred. Please try again!
|
||||||
<tr className='text-slate-500'>
|
</td>
|
||||||
<td className="p-2" colSpan={4}>Opps! an error occurred. Please try again!</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
)
|
) : (
|
||||||
:
|
<tbody>
|
||||||
<tbody>
|
<tr className="text-slate-500">
|
||||||
<tr className='text-slate-500'>
|
<td className="p-2" colSpan={4}>
|
||||||
<td className="p-2" colSpan={4}>No Payment History Found!</td>
|
No Payment History Found!
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
}
|
)}
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
{/* 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} />
|
<PaginatedList
|
||||||
{/* END OF PAGINATION BUTTON */}
|
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>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default RecentActivityTable
|
export default RecentActivityTable;
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import { Link, useLocation, useNavigate } from "react-router-dom";
|
import { Link, useLocation, useNavigate } from "react-router-dom";
|
||||||
import Icons from "../Helpers/Icons";
|
import Icons from "../Helpers/Icons";
|
||||||
import bank1 from "../../assets/images/bank-1.png";
|
// import bank1 from "../../assets/images/bank-1.png";
|
||||||
import bank2 from "../../assets/images/bank-2.png";
|
// import bank2 from "../../assets/images/bank-2.png";
|
||||||
import bank3 from "../../assets/images/bank-3.png";
|
// import bank3 from "../../assets/images/bank-3.png";
|
||||||
import bank4 from "../../assets/images/bank-4.png";
|
// import bank4 from "../../assets/images/bank-4.png";
|
||||||
import Accordion from "../Helpers/Accordion";
|
import Accordion from "../Helpers/Accordion";
|
||||||
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
||||||
|
import localImgLoad from "../../lib/localImgLoad";
|
||||||
|
|
||||||
export default function WalletHeader(props) {
|
export default function WalletHeader(props) {
|
||||||
// debugger;
|
// debugger;
|
||||||
@@ -41,30 +42,35 @@ export default function WalletHeader(props) {
|
|||||||
<ul>
|
<ul>
|
||||||
{props.myWalletList &&
|
{props.myWalletList &&
|
||||||
props.myWalletList?.result_list?.length > 0 &&
|
props.myWalletList?.result_list?.length > 0 &&
|
||||||
props.myWalletList.result_list.map((value, index) => (
|
props.myWalletList.result_list.map((value, index) =>
|
||||||
<li
|
{
|
||||||
key={index}
|
let image = value.code ? `${value.code.toLocaleLowerCase()}.svg` : 'default.png'
|
||||||
className="content-item py-4 border-b dark:border-[#5356fb29] border-light-purple hover:border-purple dark:hover:border-purple"
|
return(
|
||||||
>
|
<li
|
||||||
<div className="sm:flex justify-between items-center">
|
key={index}
|
||||||
<div className="account-name flex space-x-4 items-center mb-2 sm:mb-0">
|
className="content-item py-4 border-b dark:border-[#5356fb29] border-light-purple hover:border-purple dark:hover:border-purple"
|
||||||
<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 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>
|
||||||
<div className="name">
|
<div>
|
||||||
<p className="text-base text-dark-gray dark:text-white font-medium">
|
<p className="eth text-xl font-bold text-purple">
|
||||||
{value.description}
|
{PriceFormatter(value.amount * 0.01, value.code)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
</li>
|
||||||
<p className="eth text-xl font-bold text-purple">
|
)
|
||||||
{PriceFormatter(value.amount * 0.01, value.code)}
|
}
|
||||||
</p>
|
)}
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
|
|
||||||
{/*<li className="content-item py-4 border-b dark:border-[#5356fb29] border-light-purple hover:border-purple dark:hover:border-purple">*/}
|
{/*<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">*/}
|
{/* <div className="sm:flex justify-between items-center">*/}
|
||||||
|
|||||||
@@ -0,0 +1,120 @@
|
|||||||
|
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 CreditPopup from "./Popup/CreditPopup";
|
||||||
|
import localImgLoad from "../../lib/localImgLoad";
|
||||||
|
import WalletAction from "./WalletAction";
|
||||||
|
|
||||||
|
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: {} });
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log("walletItem >>", walletItem, payment);
|
||||||
|
|
||||||
|
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-[350px] h-full rounded-2xl overflow-hidden flex flex-col gap-2 px-8 pt-9 pb-20`}
|
||||||
|
style={{
|
||||||
|
background: `url(${background}) 0% 0% / cover no-repeat`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="wallet xxs: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 mt-2">
|
||||||
|
<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>
|
||||||
|
<p className="xxs:-ml-5 mt-10 mb-5 text-lg text-white tracking-wide flex justify-start items-center gap-2">
|
||||||
|
HOLDINGS :{" "}
|
||||||
|
<span className="mt-1">
|
||||||
|
{PriceFormatter(
|
||||||
|
walletItem.escrow * 0.01,
|
||||||
|
walletItem.code,
|
||||||
|
undefined,
|
||||||
|
"text-[2rem]"
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* <div className="flex justify-center items-center">
|
||||||
|
<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">
|
||||||
|
{PriceFormatter(
|
||||||
|
walletItem.amount * 0.01,
|
||||||
|
walletItem.code,
|
||||||
|
undefined,
|
||||||
|
"text-[2rem]"
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
<p className="text-lg text-white tracking-wide">
|
||||||
|
HOLDINGS :{" "}
|
||||||
|
<span className="mt-1">
|
||||||
|
{PriceFormatter(
|
||||||
|
walletItem.escrow * 0.01,
|
||||||
|
walletItem.code,
|
||||||
|
undefined,
|
||||||
|
"text-[2rem]"
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div> */}
|
||||||
|
|
||||||
|
{/* for white underline */}
|
||||||
|
<div className="my-2 w-full h-[1px] bg-white"></div>
|
||||||
|
|
||||||
|
{!accountType ? (
|
||||||
|
<WalletAction walletItem={walletItem} payment={payment} openPopUp={openPopUp} />
|
||||||
|
)
|
||||||
|
:
|
||||||
|
null
|
||||||
|
}
|
||||||
|
</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 }) => {
|
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 (
|
return (
|
||||||
<div className="p-3 flex justify-center items-center min-h-[70px] space-x-2 border-t-2">
|
<div className="p-3 flex justify-center items-center min-h-[70px] space-x-2 border-t-2">
|
||||||
{/* Render pagination buttons */}
|
{/* Render pagination buttons */}
|
||||||
{!prev && (
|
{!prev && (
|
||||||
<button
|
<button
|
||||||
className={`p-2 border ${
|
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`}
|
} btn-shine rounded-full h-11 w-11`}
|
||||||
name="prev"
|
name="prev"
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
@@ -15,7 +17,7 @@ const PaginatedList = ({ onClick, prev, next, data, start, stop }) => {
|
|||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{data.map((item, index) => {
|
{data?.map((item, index) => {
|
||||||
if (
|
if (
|
||||||
index % process.env.REACT_APP_ITEM_PER_PAGE == 0 &&
|
index % process.env.REACT_APP_ITEM_PER_PAGE == 0 &&
|
||||||
index >= start &&
|
index >= start &&
|
||||||
@@ -26,7 +28,9 @@ const PaginatedList = ({ onClick, prev, next, data, start, stop }) => {
|
|||||||
key={index}
|
key={index}
|
||||||
value={index}
|
value={index}
|
||||||
className={`p-2 border ${
|
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`}
|
} btn-shine rounded-full h-11 w-11`}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
name="page_num"
|
name="page_num"
|
||||||
@@ -43,7 +47,9 @@ const PaginatedList = ({ onClick, prev, next, data, start, stop }) => {
|
|||||||
{!next && (
|
{!next && (
|
||||||
<button
|
<button
|
||||||
className={`p-2 border ${
|
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`}
|
} btn-shine rounded-full h-11 w-11`}
|
||||||
name="next"
|
name="next"
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ import ReferralTable from "../MyWallet/WalletComponent/ReferralTable";
|
|||||||
const validationSchema = Yup.object().shape({
|
const validationSchema = Yup.object().shape({
|
||||||
ref_email: Yup.string()
|
ref_email: Yup.string()
|
||||||
.email("Wrong email format")
|
.email("Wrong email format")
|
||||||
|
.matches(
|
||||||
|
// /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/,
|
||||||
|
/^[^0-9][a-zA-Z0-9._%+-]+@[a-zA-Z]+(\.[a-zA-Z]+)+$/,
|
||||||
|
"Invalid email format"
|
||||||
|
)
|
||||||
.min(3, "Minimum 3 characters")
|
.min(3, "Minimum 3 characters")
|
||||||
.max(50, "Maximum 50 characters")
|
.max(50, "Maximum 50 characters")
|
||||||
.required("Email is required"),
|
.required("Email is required"),
|
||||||
|
|||||||
@@ -14,6 +14,11 @@ import * as Yup from "yup";
|
|||||||
const validationSchema = Yup.object().shape({
|
const validationSchema = Yup.object().shape({
|
||||||
email: Yup.string()
|
email: Yup.string()
|
||||||
.email("Wrong email format")
|
.email("Wrong email format")
|
||||||
|
.matches(
|
||||||
|
// /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/,
|
||||||
|
/^[^0-9][a-zA-Z0-9._%+-]+@[a-zA-Z]+(\.[a-zA-Z]+)+$/,
|
||||||
|
"Invalid email format"
|
||||||
|
)
|
||||||
.min(3, "Minimum 3 characters")
|
.min(3, "Minimum 3 characters")
|
||||||
.max(50, "Maximum 50 characters")
|
.max(50, "Maximum 50 characters")
|
||||||
.required("Email is required"),
|
.required("Email is required"),
|
||||||
@@ -96,7 +101,7 @@ export default function PersonalInfoTab({
|
|||||||
// setRequestState({message: 'Profile update successfully', loading: false, status: true})
|
// setRequestState({message: 'Profile update successfully', loading: false, status: true})
|
||||||
toast.success("Update Successful");
|
toast.success("Update Successful");
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
navigate("/", { replace: true });
|
// navigate("/", { replace: true });
|
||||||
window.location.reload(true);
|
window.location.reload(true);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -3,7 +3,9 @@
|
|||||||
font-family: "Product Sans";
|
font-family: "Product Sans";
|
||||||
src: url("./assets/fonts/Product Sans Regular.ttf");
|
src: url("./assets/fonts/Product Sans Regular.ttf");
|
||||||
}
|
}
|
||||||
|
.nft-main-container{
|
||||||
|
max-width: 1200px;
|
||||||
|
}
|
||||||
/* Bold Weight */
|
/* Bold Weight */
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Product Sans";
|
font-family: "Product Sans";
|
||||||
@@ -25,14 +27,17 @@
|
|||||||
.heroSilderTitle{
|
.heroSilderTitle{
|
||||||
text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;
|
text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;
|
||||||
font-family: sans; color: white;
|
font-family: sans; color: white;
|
||||||
font-size: 42px;
|
|
||||||
font-family: Circular, Helvetica Neue, Helvetica, Roboto, Arial, sans-serif;
|
font-family: Circular, Helvetica Neue, Helvetica, Roboto, Arial, sans-serif;
|
||||||
}
|
}
|
||||||
|
.back-dark1{
|
||||||
|
background-color: #193F5F;
|
||||||
|
min-width: 280px !important;
|
||||||
|
}
|
||||||
.job-action{
|
.job-action{
|
||||||
background-color: lightgoldenrodyellow;
|
background-color: aliceblue;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
border-radius: 15px;
|
border-radius: 15px;
|
||||||
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.msg_box{
|
.msg_box{
|
||||||
@@ -46,13 +51,7 @@
|
|||||||
color: white;
|
color: white;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
.siderCardHeader{
|
|
||||||
margin: 40px 40px 10px 40px;
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: bolder;
|
|
||||||
}
|
|
||||||
.siderCardDescription{
|
.siderCardDescription{
|
||||||
margin: 10px 45px 10px 45px;
|
|
||||||
background-color: aliceblue;
|
background-color: aliceblue;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
|
|||||||
@@ -18,7 +18,9 @@ const AuthRoute = ({ redirectPath = "/login", children }) => {
|
|||||||
|
|
||||||
const { jobListTable } = useSelector((state) => state.tableReload);
|
const { jobListTable } = useSelector((state) => state.tableReload);
|
||||||
|
|
||||||
const { userDetails:{loggedIn} } = useSelector((state) => state?.userDetails); // CHECKS IF LOGGEDIN IS TRUE
|
const { userDetails:{username, uid} } = useSelector((state) => state?.userDetails); // CHECKS IF USER Details are avaliable, to determine if user is active
|
||||||
|
|
||||||
|
let loggedIn = username && uid ? true : false // variable to determine if user is logged in
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
//Removing Data stored at localStorage after session expires
|
//Removing Data stored at localStorage after session expires
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import React from "react";
|
|
||||||
import Axios from "axios";
|
import Axios from "axios";
|
||||||
|
|
||||||
class usersService {
|
class usersService {
|
||||||
@@ -11,6 +10,10 @@ class usersService {
|
|||||||
return this.postAuxEnd("/createuser", reqData);
|
return this.postAuxEnd("/createuser", reqData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CompleteOauthLogin(reqData) {
|
||||||
|
localStorage.setItem("session_token", ``);
|
||||||
|
return this.postAuxEnd("/authlogin", reqData);
|
||||||
|
}
|
||||||
CompleteSignUp(reqData) {
|
CompleteSignUp(reqData) {
|
||||||
localStorage.setItem("session_token", ``);
|
localStorage.setItem("session_token", ``);
|
||||||
return this.postAuxEnd("/completesignuplink", reqData);
|
return this.postAuxEnd("/completesignuplink", reqData);
|
||||||
@@ -26,10 +29,22 @@ class usersService {
|
|||||||
};
|
};
|
||||||
return this.postAuxEnd("/dashdata", postData);
|
return this.postAuxEnd("/dashdata", postData);
|
||||||
}
|
}
|
||||||
|
|
||||||
logInUser(reqData) {
|
logInUser(reqData) {
|
||||||
localStorage.setItem("session_token", ``);
|
localStorage.setItem("session_token", ``);
|
||||||
return this.postAuxEnd("/userlogin", reqData);
|
return this.postAuxEnd("/userlogin", reqData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
authStart(reqData) {
|
||||||
|
localStorage.setItem("session_token", ``);
|
||||||
|
return this.postAuxEnd("/authstart", reqData);
|
||||||
|
}
|
||||||
|
|
||||||
|
authLogin(reqData) {
|
||||||
|
localStorage.setItem("session_token", ``);
|
||||||
|
return this.postAuxEnd("/authlogin", reqData);
|
||||||
|
}
|
||||||
|
|
||||||
marketJobData(reqData) {
|
marketJobData(reqData) {
|
||||||
var postData = {
|
var postData = {
|
||||||
uuid: localStorage.getItem("uuid"),
|
uuid: localStorage.getItem("uuid"),
|
||||||
@@ -838,6 +853,27 @@ class usersService {
|
|||||||
return this.postAuxEnd("/offerinterestlistmsg", postData);
|
return this.postAuxEnd("/offerinterestlistmsg", postData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TO ADD FAMILY
|
||||||
|
addFamily(reqData) {
|
||||||
|
var postData = {
|
||||||
|
uid: localStorage.getItem("uid"),
|
||||||
|
member_id: localStorage.getItem("member_id"),
|
||||||
|
sessionid: localStorage.getItem("session_token"),
|
||||||
|
...reqData,
|
||||||
|
};
|
||||||
|
return this.postAuxEnd("/familyadd", postData);
|
||||||
|
}
|
||||||
|
|
||||||
|
familyListings(reqData) {
|
||||||
|
var postData = {
|
||||||
|
uid: localStorage.getItem("uid"),
|
||||||
|
member_id: localStorage.getItem("member_id"),
|
||||||
|
sessionid: localStorage.getItem("session_token"),
|
||||||
|
...reqData,
|
||||||
|
};
|
||||||
|
return this.postAuxEnd("/familylist", postData);
|
||||||
|
}
|
||||||
|
|
||||||
// FUNCTION TO ASSIGN TASK TO FAMILY MEMBER
|
// FUNCTION TO ASSIGN TASK TO FAMILY MEMBER
|
||||||
assignFamilyTask(reqData) {
|
assignFamilyTask(reqData) {
|
||||||
var postData = {
|
var postData = {
|
||||||
|
|||||||
@@ -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,9 +1,9 @@
|
|||||||
import FamilyAcc from "../components/FamilyAcc";
|
import FamilyAcc from "../components/FamilyAcc";
|
||||||
|
|
||||||
export default function FamilyAccPage() {
|
export default function FamilyAccPage() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<FamilyAcc />
|
<FamilyAcc />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import React from "react";
|
|
||||||
// import MyWallet from "../components/MyWallet";
|
|
||||||
import WalletRoutes from "../components/MyWallet/Wallet";
|
import WalletRoutes from "../components/MyWallet/Wallet";
|
||||||
|
|
||||||
export default function MyWalletPage() {
|
export default function MyWalletPage() {
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ module.exports = {
|
|||||||
'sky-blue': '#3a8fc3',
|
'sky-blue': '#3a8fc3',
|
||||||
'alice-blue': '#f0f8ff'
|
'alice-blue': '#f0f8ff'
|
||||||
},
|
},
|
||||||
|
screens:{
|
||||||
|
xxs: '400px'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: [require("@tailwindcss/line-clamp")],
|
plugins: [require("@tailwindcss/line-clamp")],
|
||||||
|
|||||||