Compare commits

..

33 Commits

Author SHA1 Message Date
victorAnumudu 39b3218545 merged master to branch 2023-04-27 13:52:21 +01:00
victorAnumudu e26330af9a handling adding recipient done 2023-04-27 13:49:19 +01:00
ameye ccc43bb55d Merge branch 'verify-signup' of WrenchBoard/Users-Wrench into master 2023-04-27 12:29:37 +00:00
Ebube 2b0d344dfa lest touch b4 pr 2023-04-27 13:11:56 +01:00
ameye 53b9db85a5 Merge branch 'recipient_account_num__match' of WrenchBoard/Users-Wrench into master 2023-04-27 10:10:38 +00:00
victorAnumudu ecdd8f9180 validates that account number is a number 2023-04-27 11:08:11 +01:00
victorAnumudu 25dcfecfaf made validates that account number matches retype account number 2023-04-27 10:47:05 +01:00
DESKTOP-GBA0BK8\Admin ed638f5c0f Honeofferc card 2023-04-27 05:24:18 -04:00
DESKTOP-GBA0BK8\Admin 033d87fdf6 My Jobs listimg 2023-04-27 05:09:35 -04:00
Ebube babed484b2 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into verify-signup 2023-04-27 10:07:52 +01:00
Ebube e2b4aaa105 added the rest 2023-04-27 10:07:10 +01:00
ameye ce01b2637b Merge branch 'add_recipient_validation' of WrenchBoard/Users-Wrench into master 2023-04-27 09:01:07 +00:00
Ebube d91241dad9 added verify emali endpoint 2023-04-27 08:34:07 +01:00
Ebube 1ad3b74610 added checkers 2023-04-27 08:31:25 +01:00
victorAnumudu d94ff616a9 added validation to add recipient page 2023-04-27 04:26:11 +01:00
DESKTOP-GBA0BK8\Admin f87dbcbe5e Jobs format 2023-04-26 22:40:15 -04:00
DESKTOP-GBA0BK8\Admin 4df1589222 my jobs list 2023-04-26 22:13:41 -04:00
Ebube 886b73ffa3 fixing signup 2023-04-27 02:44:09 +01:00
Ebube 6cb0871d34 added html validation 2023-04-27 02:37:04 +01:00
Ebube 3ed764e8f4 Added a check up email v 2023-04-27 02:28:59 +01:00
Ebube c87fc4f32d Added verify link 2023-04-27 02:25:03 +01:00
ameye 75015e84d2 Merge branch 'add_recipient_country' of WrenchBoard/Users-Wrench into master 2023-04-26 11:57:49 +00:00
tokslaw7 24a5b8e785 Attempt fix 2023-04-26 11:40:51 +00:00
tolik 03ca576e16 Fix build 2023-04-26 19:25:47 +08:00
victorAnumudu 8886544024 Merge branch 'master' into add_recipient_country 2023-04-26 12:06:39 +01:00
victorAnumudu cadd2aa4c4 added recipient country, bank name and account types from API 2023-04-26 12:03:33 +01:00
tolik 104cd15f64 Attempt to fix 2023-04-26 18:49:58 +08:00
tolik 3acdbfb6e0 Remove volume maps for node_modules & vendors 2023-04-26 18:29:41 +08:00
tolik f30600816b Map node_modules 2023-04-26 18:11:32 +08:00
tolik 627774c910 Dev/prod env support 2023-04-26 17:25:58 +08:00
DESKTOP-GBA0BK8\Admin ee59990d85 sntx error 2023-04-25 20:56:41 -04:00
DESKTOP-GBA0BK8\Admin 7f4d8f3ff0 Hero Top data parts 2023-04-25 20:45:25 -04:00
ameye b888e9f5df Merge branch 'profile_validation' of WrenchBoard/Users-Wrench into master 2023-04-25 19:08:01 +00:00
29 changed files with 15989 additions and 12695 deletions
+30
View File
@@ -0,0 +1,30 @@
SKIP_PREFLIGHT_CHECK=true
REACT_APP_FACEBOOK="https://www.facebook.com/profile.php?id=100066498622246"
REACT_APP_TWITTER="https://twitter.com/fluxtra"
REACT_APP_APPSITE="https://myfitapp.mermsemr.com"
#REACT_APP_APPSITE="http://localhost:7012"
# REACT_APP_AUX_ENDPOINT="http://10.20.30.32:9083/svs/user"
# REACT_APP_USERS_ENDPOINT="http://10.20.30.32:9083/svs/user"
REACT_APP_AUX_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/svs/user"
REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/svs/user"
#REACT_APP_AUX_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
#REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
#"https://devapi.mermsemr.com/en/desktop/api/v2/myfituser"
REACT_APP_SESSION_EXPIRE_MINUTES=300000
REACT_APP_SESSION_EXPIRE_CHECKER=60000
REACT_APP_LOGIN_ERROR_TIMEOUT=7000
REACT_APP_SIGNUP_ERROR_TIMEOUT=7000
# Had to change the error time to 3sec cause it took too long
REACT_APP_RESET_START_ERROR_TIMEOUT=3000
#apigate.lotus.g1.wrenchboard.com:76.209.103.227
#apigate.orion.g1.wrenchboard.com:76.209.103.227
+30
View File
@@ -0,0 +1,30 @@
SKIP_PREFLIGHT_CHECK=true
REACT_APP_FACEBOOK="https://www.facebook.com/profile.php?id=100066498622246"
REACT_APP_TWITTER="https://twitter.com/fluxtra"
REACT_APP_APPSITE="https://myfitapp.mermsemr.com"
#REACT_APP_APPSITE="http://localhost:7012"
# REACT_APP_AUX_ENDPOINT="http://10.20.30.32:9083/svs/user"
# REACT_APP_USERS_ENDPOINT="http://10.20.30.32:9083/svs/user"
REACT_APP_AUX_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/svs/user"
REACT_APP_USERS_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/svs/user"
#REACT_APP_AUX_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/en/wrench/api/v1"
#REACT_APP_USERS_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/en/wrench/api/v1"
#"https://devapi.mermsemr.com/en/desktop/api/v2/myfituser"
REACT_APP_SESSION_EXPIRE_MINUTES=300000
REACT_APP_SESSION_EXPIRE_CHECKER=60000
REACT_APP_LOGIN_ERROR_TIMEOUT=7000
REACT_APP_SIGNUP_ERROR_TIMEOUT=7000
# Had to change the error time to 3sec cause it took too long
REACT_APP_RESET_START_ERROR_TIMEOUT=3000
#apigate.orion.g1.wrenchboard.com:76.209.103.227
#apigate.orion.g1.wrenchboard.com:76.209.103.227
-59
View File
@@ -1,59 +0,0 @@
{
"extends": [
"airbnb",
"airbnb/hooks",
"eslint:recommended",
"prettier",
"plugin:jsx-a11y/recommended"
],
"parser": "babel-eslint",
"parserOptions": {
"ecmaVersion": 8
},
"env": {
"browser": true,
"node": true,
"es6": true,
"jest": true
},
"rules": {
"no-plusplus": 0,
"import/no-dynamic-require": 0,
"global-require": 0,
"no-nested-ternary": 0,
"react/self-closing-comp": 0,
"react/no-unescaped-entities": 0,
"jsx-a11y/anchor-is-valid": 0,
"react/jsx-props-no-spreading": 0,
"jsx-eslint/eslint-plugin-jsx-a11y": 0,
"jsx-a11y/no-static-element-interactions": 0,
"jsx-a11y/label-has-associated-control": 0,
"jsx-a11y/no-noninteractive-element-interactions": 0,
"react/react-in-jsx-scope": 0,
"react-hooks/rules-of-hooks": "error",
"no-console": 0,
"react/state-in-constructor": 0,
"indent": 0,
"linebreak-style": 0,
"react/prop-types": 0,
"jsx-a11y/click-events-have-key-events": 0,
"react/jsx-filename-extension": [
1,
{
"extensions": [".js", ".jsx"]
}
]
// "prettier/prettier": [
// "error",
// {
// "trailingComma": "es5",
// "singleQuote": true,
// "printWidth": 100,
// "tabWidth": 4,
// "semi": true,
// "endOfLine": "auto"
// }
// ]
},
"plugins": ["prettier", "react", "react-hooks"]
}
+36
View File
@@ -0,0 +1,36 @@
# pull the base image
FROM node:alpine
# Build args
ARG NODE_ENV
# set the working direction
#WORKDIR /app
WORKDIR /usr/src/app
# add `/app/node_modules/.bin` to $PATH
# ENV PATH /app/node_modules/.bin:$PATH
ENV PATH /usr/src/app/node_modules/.bin:$PATH
ENV NODE_ENV=$NODE_ENV
# install nginx
RUN apk update
RUN apk add nginx
# install app dependencies
COPY package.json ./
COPY package-lock.json ./
COPY nginx.conf ./
COPY run.sh ./
RUN npm install --legacy-peer-deps
# add app
COPY . ./
# start app
CMD /bin/sh ./run.sh
+6 -3
View File
@@ -4,7 +4,9 @@ services:
image: registry.chiefsoft.net/wrenchboard-users-wrench:latest
build:
context: .
dockerfile: docker/Dockerfile
dockerfile: Dockerfile
args:
- NODE_ENV=production
restart: unless-stopped
ports:
- 9082:3000
@@ -13,19 +15,20 @@ services:
working_dir: /usr/src/app
volumes:
- ./:/usr/src/app
- /usr/src/app/node_modules
- ./src/:/usr/src/app/src
- ./vendors/:/usr/src/app/vendors
- ./run.sh:/usr/src/app/run.sh
extra_hosts:
- backend.wrenchboard.api.live:10.10.33.15
- backend.wrenchboard.api.test:10.10.33.15
- apigate.lotus.g1.wrenchboard.com:10.10.33.15
- apigate.orion.g1.wrenchboard.com:10.10.33.15
# #- backend.wrenchboard.api.live:172.31.4.27
# #- backend.wrenchboard.api.test:10.20.30.27
- apigateway.wrenchboard.app.dev.fluxtra.net:10.20.30.19
- apigateway.wrenchboard.app.lotus.fluxtra.net:172.31.4.19
environment:
- CHOKIDAR_USEPOLLING=true
- NODE_ENV=${NODE_ENV:-production}
# volumes:
# - ./:/app
# - /app/node_modules
+15 -1
View File
@@ -3,7 +3,15 @@
FROM alpine:3.15
# Build args
ARG NODE_ENV
ENV NODE_VERSION 14.19.0
ENV NODE_ENV=$NODE_ENV
# install nginx
RUN apk update
RUN apk add nginx
RUN addgroup -g 1000 node \
&& adduser -u 1000 -G node -s /bin/sh -D node \
@@ -103,6 +111,10 @@ WORKDIR /usr/src/app
# ENV PATH /app/node_modules/.bin:$PATH
ENV PATH /usr/src/app/node_modules/.bin:$PATH
COPY nginx.conf ./
COPY run.sh ./
# install app dependencies
COPY package.json ./
RUN npm install
@@ -114,7 +126,9 @@ RUN npm install
COPY . ./
# start app
CMD ["npm","run", "start"]
# CMD ["npm","run", "start"]
# CMD ["yarn", "start"]
# start app
CMD /bin/sh ./run.sh
+29
View File
@@ -0,0 +1,29 @@
worker_processes 1;
events {
worker_connections 1024;
}
http {
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
server {
gzip on;
listen 3000;
server_name localhost;
root /usr/src/app/build;
include /etc/nginx/mime.types;
location /nginx_status {
stub_status on;
access_log off;
}
location / {
try_files $uri $uri/ /index.html;
}
}
}
+10992 -6604
View File
File diff suppressed because it is too large Load Diff
+3 -19
View File
@@ -30,11 +30,10 @@
"yup": "^1.1.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"start": "react-scripts start -e .env.development",
"build": "react-scripts build -e .env.production",
"test": "react-scripts test",
"eject": "react-scripts eject",
"lint": "yarn add -D prettier@2.4.1 && yarn add -D eslint@7.11.0 && yarn add -D babel-eslint@10.1.0 && npx install-peerdeps --dev eslint-config-airbnb@18.2.1 && yarn add -D eslint-config-prettier@8.3.0 eslint-plugin-prettier@4.0.0"
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
@@ -53,20 +52,5 @@
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"autoprefixer": "^10.4.5",
"babel-eslint": "10.1.0",
"eslint": "7.2.0",
"eslint-config-airbnb": "18.2.1",
"eslint-config-prettier": "8.3.0",
"eslint-plugin-import": "2.22.1",
"eslint-plugin-jsx-a11y": "6.4.1",
"eslint-plugin-prettier": "4.0.0",
"eslint-plugin-react": "^7.29.4",
"eslint-plugin-react-hooks": "1.7.0",
"postcss": "^8.4.12",
"prettier": "2.4.1",
"tailwindcss": "^3.0.24"
}
}
Executable
+17
View File
@@ -0,0 +1,17 @@
#!/usr/bin/env sh
set -e
set -x
export NODE_ENV="${NODE_ENV:-development}"
if [ $NODE_ENV == "development" ]; then
# this runs webpack-dev-server with hot reloading
npm install --legacy-peer-deps
npm start
else
# build the app and serve it via nginx
npm install --legacy-peer-deps
npm run build
nginx -g 'daemon off;' -c /usr/src/app/nginx.conf
nginx -c /usr/src/app/nginx.conf
fi
+2
View File
@@ -30,6 +30,7 @@ import ResourcePage from "./views/ResourcePage";
import MyTaskPage from "./views/MyTaskPage";
import MyJobsPage from "./views/MyJobsPage";
import ReferralPage from "./views/ReferralPage";
import VerifyLinkPages from "./views/VerifyLinkPages";
export default function Routers() {
return (
@@ -48,6 +49,7 @@ export default function Routers() {
path="/update-password"
element={<UpdatePasswordPages />}
/>
<Route path="/vemail" element={<VerifyLinkPages />} />
<Route exact path="/verify-you" element={<VerifyYouPages />} />
{/* private route */}
+2 -1
View File
@@ -67,7 +67,6 @@ export default function Login() {
setLoginLoading(true);
// userApi.getUserReminders(); //testing
setTimeout(() => {
toast.success("Login Successfully");
navigate("/", { replace: true });
setLoginLoading(false);
}, 2000);
@@ -119,6 +118,8 @@ export default function Login() {
iconName="message"
/>
</div>
<input type="text" placeholder="boyce" />
<div className="input-item mb-5">
<InputCom
value={password}
+19 -18
View File
@@ -37,7 +37,7 @@ export default function SignUp() {
const navigate = useNavigate();
const userApi = new usersService();
// Get Country Api
const getCountryList = async () => {
const res = await userApi.getSignupCountryData()
@@ -46,7 +46,7 @@ export default function SignUp() {
if (res.status === 200) {
const { signup_country } = await res.data
setCountries(signup_country)
} else if (res.data.result != 100) {
} else if (res.data.result !== 100) {
setCountries('Nothing see here!')
}
} catch (error) {
@@ -57,12 +57,13 @@ export default function SignUp() {
const handleSignUp = async () => {
let { country, first_name, last_name, email, password } = formData
if (email == '' && password == '' && first_name == '') {
if (email === '' && password === '' && first_name === '') {
setMsgError('Please fill in fields')
}
try {
if (email !== '' && password !== '' && first_name !== '' && last_name !== '') {
setSignUpLoading(true)
const reqData = {
country: country,
firstname: first_name,
@@ -75,46 +76,46 @@ export default function SignUp() {
}
const res = await userApi.CreateUser(reqData)
setSignUpLoading(true)
if (res.status === 200) {
const { data } = res
if (data.status == -1 && data.acc == 'DULPICATE') {
if (data.status === -1 && data.acc === 'DULPICATE') {
setMsgError('This account has been already created')
setSignUpLoading(false)
}
if (data.status > 0 && data.internal_return == 100 && data.session != '') {
localStorage.setItem("email", `${data.email}`);
localStorage.setItem("country", `${data.country}`);
localStorage.setItem("firstname", `${data.firstname}`);
localStorage.setItem("lastname", `${data.lastname}`);
if (data && data.status === '1') {
setTimeout(() => {
navigate("/", { replace: true });
navigate("/verify-you", { replace: true });
setSignUpLoading(false)
}, 2000)
} else {
setMsgError(data.status)
setSignUpLoading(false)
setMsgError('This account does not exist')
}
} else {
setSignUpLoading(false)
setMsgError('An error occurred')
}
} else {
setMsgError('This account does not exist')
setSignUpLoading(false)
}
} catch (error) {
throw new Error(error)
setMsgError('An error occurred')
} finally {
setTimeout(() => {
setMsgError(null)
}, process.env.REACT_APP_SIGNUP_ERROR_TIMEOUT)
setFormData({
first_name: '',
last_name: '',
email: '',
country: '',
password: ''
})
}
}
useEffect(() => {
getCountryList()
}, [])
})
return (
<>
@@ -0,0 +1,143 @@
import { useState, useLayoutEffect, useCallback } from "react";
import { useLocation, Link, useNavigate } from "react-router-dom";
import AuthLayout from "../AuthLayout";
import InputCom from "../../Helpers/Inputs/InputCom";
import usersService from "../../../services/UsersService";
import WrenchBoard from "../../../assets/images/wrenchboard.png"
export default function VerifyLink() {
const [pageLoader, setPageLoader] = useState(true)
const [linkSuccess, setLinkSuccess] = useState(false)
const [linkError, setLinkError] = useState(false)
const navigate = useNavigate()
const location = useLocation();
const queryParams = new URLSearchParams(location?.search)
const token = queryParams.get('vlink')
const verifyEmail = useCallback(
async (code) => {
const userApi = new usersService()
try {
const verifyRes = await userApi.verifyEmail(code)
if (verifyRes.status === 200) {
let { data } = verifyRes
if (data && data.internal_return === 0 && data.status_text === 'Link Verfied') {
setPageLoader(false)
setLinkSuccess(true)
} else {
setPageLoader(false)
setLinkError(true)
}
console.log(data)
}
} catch (error) {
setPageLoader(false)
setLinkError(true)
throw new Error(error)
}
}, []
)
useLayoutEffect(() => {
verifyEmail(token)
})
console.log(token)
return (
<>
<AuthLayout
slogan="Welcome to WrenchBoard"
>
{pageLoader ? (
<img src={WrenchBoard} alt="wrenchboard" className="h-10 mx-auto" />
) : (
<div className="w-full">
<div className='mb-12'>
<Link to='#'>
<img src={WrenchBoard} alt="wrenchboard" className="h-10 mx-auto" />
</Link>
</div>
<div className="content-wrapper login shadow-md w-full lg:max-w-[500px] mx-auto flex justify-center items-center dark:bg-dark-white 2xl:w-[828px] rounded-[0.475rem] sm:p-7 p-5">
<div className="w-full">
<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" style={{
fontSize: 'calc(1rem + .6vw)'
}}>
{linkError && 'Invalid verification link'}
{linkSuccess && 'Sign In to WrenchBoard'}
</h1>
</div>
{/* If the verification was a success */}
{linkSuccess && <SuccessfulComponent />}
{/* If the verification was unsuccessful */}
{linkError && <ErrorComponent onClick={() => navigate('/login')} />}
</div>
</div>
</div>
)}
</AuthLayout>
</>
)
}
const SuccessfulComponent = ({ onClick }) => (
<div className="input-area">
{/* INPUT */}
<div className="mb-5">
<InputCom
// value={password}
// inputHandler={handlePassword}
placeholder="support@mermsemr.com"
label="Email"
name="email"
type="email"
iconName="message"
/>
</div>
<div className="mb-5">
<InputCom
// value={password}
// inputHandler={handlePassword}
placeholder="● ● ● ● ● ●"
label="Password"
name="password"
type="password"
iconName="password"
/>
</div>
<div className="signin-area mb-3.5">
<button
onClick={onClick}
type="button"
className={`btn-login rounded-[0.475rem] mb-6 text-xl text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center $`}
>
<span>Continue</span>
</button>
</div>
</div>
)
const ErrorComponent = ({ onClick }) => (
<div className="input-area">
<div className="my-5">
<p className="text-[14px] leading-[19px] text-center text-[#181c32]">
This error occurs because you have already verified this link or the link has expired. Try login or reset password. If none worked, try to create the account from the start.
</p>
</div>
<div className="signin-area flex justify-center mb-3.5">
<button
onClick={onClick}
type="button"
className={`rounded-[0.475rem] mb-6 text-[1.15rem] font-semibold text-[#009ef7] hover:text-white flex justify-center bg-[#f1faff] hover:bg-[#009ef7] transition-all duration-300 items-center py-[0.8875rem] px-[1.81rem]`}
>
<span>Return Home</span>
</button>
</div>
</div>
)
+14 -25
View File
@@ -1,7 +1,4 @@
import React from "react";
import titleShape from "../../../assets/images/shape/text-shape-three.svg";
import AuthLayout from "../AuthLayout";
import Otp from "./Otp";
export default function VerifyYou() {
return (
@@ -9,32 +6,24 @@ export default function VerifyYou() {
<AuthLayout
slogan="Welcome to WrenchBoard"
>
<div className="content-wrapper xl:bg-white dark:bg-dark-white w-full sm:w-auto px-5 xl:px-[70px] 2xl:px-[100px] h-[818px] rounded-xl flex flex-col justify-center">
<div>
<div className="title-area flex flex-col justify-center items-center relative text-center mb-8">
<h1 className="sm:text-5xl text-4xl font-bold leading-[74px] text-dark-gray dark:text-white">
Verification Code
<div className="content-wrapper login dark:bg-dark-white w-full lg:max-w-[500px] 2xl:w-[828px] rounded-xl flex flex-col justify-center sm:p-7 p-5">
<div className="w-full">
<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" style={{
fontSize: 'calc(1rem + .6vw)'
}}>
Verification Sent
</h1>
<div className="shape sm:w-[377px] w-[270px] -mt-5 ml-5">
<img src={titleShape} alt="shape" />
</div>
</div>
<div className="input-area">
<Otp />
<div className="signin-area mb-3.5">
<a
href="/update-password"
className="w-full rounded-[50px] h-[58px] mb-6 text-xl text-white font-bold flex justify-center bg-purple items-center"
>
Continue
</a>
<div className="mb-5">
<p className="text-[14px] leading-[19px] text-center text-[#181c32]">
To complete the verification process, you should check your email inbox and look for the verification email. It may take a few minutes for the email to arrive, so be patient. Once you receive the email, open it and click on the verification link provided.
</p>
</div>
<div className="resend-code flex justify-center">
<p className="text-lg text-thin-light-gray font-normal">
Dontt have an aceount ?
<a href="#" className="ml-2 text-dark-gray dark:text-white font-bold">
Please resend
</a>
<div className="mb-5">
<p className="text-[14px] leading-[19px] text-center text-[#181c32]">
If you haven't received the verification email after a reasonable amount of time, make sure to check your spam or junk mail folder. It's also possible that the email was sent to the wrong email address, so double-check that you entered your email address correctly.
</p>
</div>
</div>
@@ -0,0 +1,26 @@
import React from "react";
import { Link } from "react-router-dom";
import localImgLoad from "../../lib/localImgLoad";
export default function HomeBannerOffersCard(props) {
return (
<Link
to="/my-collection/collection-item"
className="item w-full block group banner-630-340"
>
<div className="flex flex-col justify-between h-full">
<div className="content flex justify-between items-center mb-5">
<div>
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">
<>Ab hshsh jsjsj hshdhhdjjd</>
</h1>
</div>
{/*<SelectBox datas={filterDatas} action={dataSetHandler} />*/}
</div>
<div className="h-[233px]">
BEST IMAGE IN THE WORLLD
</div>
</div>
</Link>
);
}
@@ -1,4 +1,4 @@
import React from "react";
import React, { useRef } from "react";
import Icons from "../../Icons";
import { Link } from "react-router-dom";
@@ -15,7 +15,56 @@ export default function InputCom({
onClick,
disable,
blurHandler,
onMouseEnter,
onMouseLeave
}) {
const inputRef = useRef(null)
// Entry Validation
// for Min Length:
const minLengthValidation = () => {
if (inputRef && inputRef?.current && inputRef?.current?.name === 'email') {
return 7
} else if (inputRef && inputRef?.current && inputRef?.current?.name === 'first_name') {
return 3
} else if (inputRef && inputRef?.current && inputRef?.current?.name === 'last_name') {
return 3
} else if (inputRef && inputRef?.current && inputRef?.current?.name === 'address') {
return 5
} else if (inputRef && inputRef?.current && inputRef?.current?.name === 'password') {
return 8
} else if (inputRef && inputRef?.current && inputRef?.current?.name === 'state') {
return 3
} else if (inputRef && inputRef?.current && inputRef?.current?.name === 'province') {
return 3
} else if (inputRef && inputRef?.current && inputRef?.current?.name === 'city') {
return 3
} else if (inputRef && inputRef?.current && inputRef?.current?.name === 'amount') {
return 1
}
}
// for MaxLength
const maxLengthValidation = () => {
if (inputRef && inputRef?.current && inputRef?.current?.name === 'email') {
return 35
} else if (inputRef && inputRef?.current && inputRef?.current?.name === 'first_name') {
return 25
} else if (inputRef && inputRef?.current && inputRef?.current?.name === 'last_name') {
return 25
} else if (inputRef && inputRef?.current && inputRef?.current?.name === 'address') {
return 49
} else if (inputRef && inputRef?.current && inputRef?.current?.name === 'password') {
return 15
} else if (inputRef && inputRef?.current && inputRef?.current?.name === 'state') {
return 25
} else if (inputRef && inputRef?.current && inputRef?.current?.name === 'province') {
return 25
} else if (inputRef && inputRef?.current && inputRef?.current?.name === 'city') {
return 25
} else if (inputRef && inputRef?.current && inputRef?.current?.name === 'amount') {
return 9
}
}
return (
<div className="input-com">
<div className="flex items-center justify-between">
@@ -38,8 +87,13 @@ export default function InputCom({
type={type}
id={name}
name={name}
minLength={minLengthValidation()}
maxLength={maxLengthValidation()}
ref={inputRef}
readOnly={disable}
onBlur={blurHandler}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
/>
{iconName && (
<div className="absolute right-6 bottom-[10px] z-10">
+2 -1
View File
@@ -18,6 +18,7 @@ export default function Hero({ className }) {
infinite: true,
swipe: true,
};
const sildeData =null;
const [addFavorite, setValue] = useState(false);
const favoriteHandler = () => {
if (!addFavorite) {
@@ -96,7 +97,7 @@ export default function Hero({ className }) {
</Link>
</div>
</div>
<HomeSliders settings={settings} />
<HomeSliders settings={settings} sideData={sildeData}/>
</div>
);
}
+4
View File
@@ -2,6 +2,7 @@ import SliderCom from "../Helpers/SliderCom";
import slider1 from "../../assets/images/slider-1.jpg";
import slider2 from "../../assets/images/slider-2.jpg";
import slider3 from "../../assets/images/slider-3.jpg";
import HomeBannerOffersCard from "../Cards/HomeBannerOffersCard";
export default function HomeSliders(props) {
@@ -20,6 +21,9 @@ export default function HomeSliders(props) {
<div className="item w-full h-full bg-white dark:bg-dark-white rounded-2xl overflow-hidden">
<img src={slider3} alt="slider" className="w-full h-full" />
</div>
<div className="item w-full h-full bg-white dark:bg-dark-white rounded-2xl overflow-hidden">
<HomeBannerOffersCard />
</div>
</SliderCom>
</div>
</div>
File diff suppressed because it is too large Load Diff
+3 -2
View File
@@ -4,11 +4,12 @@ import Layout from "../Partials/Layout";
import MyJobTable from "./MyJobTable";
import CommonHead from "../UserHeader/CommonHead";
export default function MyJobs() {
export default function MyJobs(props) {
const [selectTab, setValue] = useState("today");
const filterHandler = (value) => {
setValue(value);
};
console.log("AMEYE LOC1", props.MyJobList);
return (
<Layout>
<CommonHead />
@@ -32,7 +33,7 @@ export default function MyJobs() {
</div>
</div>
</div>
<MyJobTable />
<MyJobTable MyJobList={props.MyJobList} />
</div>
</div>
</Layout>
+339 -135
View File
@@ -1,161 +1,365 @@
import React, {useState} from 'react'
import { Link } from 'react-router-dom'
import React, {useEffect, useState} from 'react'
import { Link, useNavigate } from 'react-router-dom'
import Icons from '../Helpers/Icons'
import usersService from '../../services/UsersService'
import InputCom from '../Helpers/Inputs/InputCom'
import LoadingSpinner from '../Spinners/LoadingSpinner'
import {toast} from 'react-toastify'
import {Formik, Form} from 'formik'
import * as Yup from 'yup'
const validationSchema = Yup.object().shape({
firstname: Yup.string()
.min(3, 'Minimum 3 characters')
.max(25, 'Maximum 25 characters')
.required('Firstname is required'),
lastname: Yup.string()
.min(3, 'Minimum 3 characters')
.max(25, 'Maximum 25 characters')
.required('Lastname is required'),
country: Yup.string()
.min(1, 'Minimum 3 characters')
.max(25, 'Maximum 25 characters')
.required('Country is required'),
bank: Yup.string()
.min(3, 'Minimum 3 characters')
.max(25, 'Maximum 25 characters')
.required('Bank name is required'),
accountNumber: Yup.string()
.matches(/\d/, "must be a number")
.min(3, 'Minimum 3 characters')
.max(25, 'Maximum 25 characters')
.required('Account Number is required'),
repeatAccountNumber: Yup.string()
.required('Repeat Account Number is required')
.oneOf([Yup.ref('accountNumber'), null], 'Must match Account Number'),
accountType: Yup.string()
.min(1, 'Minimum 3 characters')
.max(25, 'Maximum 25 characters')
.required('Account Type is required'),
city: Yup.string()
.min(3, 'Minimum 3 characters')
.max(25, 'Maximum 25 characters')
.required('City is required'),
state: Yup.string()
.min(3, 'Minimum 3 characters')
.max(25, 'Maximum 25 characters')
.required('State is required'),
})
const initialValues = {
firstname: '',
lastname: '',
country: '',
bank: '',
accountNumber: '',
repeatAccountNumber: '',
accountType: '',
state: '',
city: ''
}
function AddRecipient() {
//STATE FOR CONTROLLED INPUTS
let [inputs, setInputs] = useState({
firstname: '',
lastname: '',
country: '',
'bank-name': '',
'account-number': '',
'repeat-account-number': '',
'account-type': '',
state: '',
city: ''
const apiURL = new usersService()
const navigate = useNavigate()
let [requestStatus, setRequestStatus] = useState({message: '', loading: false, status: false})
let [allCountries, setAllCountries] = useState({ // STATE TO HOLD LIST OF COUNTRIES
loading: true,
data: []
})
// FUNCTION TO HANDLE INPUT CHANGE
const handleChange = ({target:{name, value}}) => {
setInputs(prev => ({...prev, [name]:value}))
let [bankName, setBankName] = useState({ // STATE TO HOLD LIST OF BANK NAME
loading: true,
data: []
})
let [accType, setAccType] = useState({ // STATE TO HOLD LIST ACCOUNT TYPE
loading: true,
data: []
})
//FUNCTION TO HANDLE ADD RECIPIENT SUBMIT
const handleSubmit = (values, helpers) => {
setRequestStatus({message: '', loading: true, status: false})
let reqData = { //REQUEST DATA FOR API CALL
firstname: values.firstname,
lastname: values.lastname,
bank_code: values.bank,
account_no: values.accountNumber,
account_type: values.accountType,
country: values.country,
state: values.state,
city: values.city
}
//CALL TO ADD RECIPIENT API
apiURL.addRecipient(reqData).then((res)=>{
if(res.data.internal_return < 0){
setRequestStatus({message: 'could not add recipient, try again!', loading: false, status: true})
return
}
// setRequestStatus({message: 'Recipient Added Successfully!', loading: false, status: true})
toast.success("Recipient Added Successfully!");
setTimeout(()=>{navigate('../transfer-fund',{replace:true})},1000)
}).catch((error)=>{
setRequestStatus({message: 'Opps! an error occured! Try again later', loading: false, status: false})
})
}
//FUNCTION TO HANDLE SUBMIT
const handleSubmit = (e) => {
e.preventDefault();
//valid inputs before submitting. Just for texting remove later
// setInputs((prev)=>{
// for(let input in prev){
// prev[input] = ''
// }
// })
// RETURN INPUTS TO EMPTY STRING
setInputs({
firstname: '',
lastname: '',
country: '',
'bank-name': '',
'account-number': '',
'repeat-account-number': '',
'account-type': '',
state: '',
city: ''
// FUNCTION TO GET COUNTRIES
const getCountry = ()=> {
apiURL.getSignupCountryData().then((res)=>{
if(res.data.internal_return < 0){
setAllCountries(prev => ({loading: false, data: []}))
return
}
setAllCountries(prev => ({loading: false, data:res.data.signup_country}))
}).catch((error)=>{
setAllCountries(prev => ({loading: false, data: []}))
})
}
// END OF FUNCTION TO GET COUNTRIES
// FUNCTION TO GET COUNTRY BANK
const getCountryBank = ()=> {
apiURL.getCountryBank().then((res)=>{
if(res.data.internal_return < 0){
setBankName(prev => ({loading: false, data: []}))
return
}
setBankName(prev => ({loading: false, data:res.data.result_list}))
}).catch((error)=>{
setBankName(prev => ({loading: false, data: []}))
})
}
// END OF FUNCTION TO GET COUNTRY BANK
// FUNCTION TO GET ACCOUNT TYPES
const getAccountTypes = ()=> {
apiURL.getAccountTypes().then((res)=>{
if(res.data.internal_return < 0){
setAccType(prev => ({loading: false, data: []}))
return
}
setAccType(prev => ({loading: false, data:res.data.result_list}))
}).catch((error)=>{
setAccType(prev => ({loading: false, data: []}))
})
}
// END OF FUNCTION TO GET ACCOUNT TYPES
useEffect(()=>{
getCountry() // TO LOAD LIST COUNTRY
getCountryBank() // TO LOAD LIST COUNTRY BANK
getAccountTypes() // TO LOAD LIST ACCOUNT TYPES
},[])
return (
<div className="content-wrapper w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin">
<div className="w-full mb-10 lg:mb-0">
<div className="w-full md:p-8 p-4 bg-white dark:bg-dark-white rounded-2xl shadow">
<h2 className='my-4 text-slate-900 dark:text-white text-xl lg:text-2xl font-semibold'>ADD BANK ACCOUNT</h2>
<form className='add-recipient-info px-1 md:px-[50px] lg:px-[100px]' onSubmit={handleSubmit}>
{/* inputs starts here */}
<div className='add-recipient my-3 md:flex items-center justify-between'>
<label className='w-full md:w-1/4 text-slate-600 text-lg'>First Name <span className='text-red-500'>*</span></label>
<input className='w-full md:w-3/4 p-3 text-lg bg-slate-100 rounded-md outline-0 placeholder:text-slate-500 placeholder:text-lg'
value={inputs.firstname}
name='firstname'
type="text"
placeholder='Account Firstname'
required
onChange={handleChange}
/>
</div>
<h2 className='my-4 text-slate-900 dark:text-white text-xl lg:text-2xl font-semibold'>ADD BANK ACCOUNT</h2>
<Formik initialValues={initialValues} validationSchema={validationSchema} onSubmit={handleSubmit}>
{(props)=>(
<Form className='add-recipient-info px-1 md:px-[50px] lg:px-[100px]'>
{/* inputs starts here */}
{/* firstname */}
<div className="xl:flex xl:space-x-7 mb-6">
<div className="field w-full mb-6 xl:mb-0">
<InputCom
label="Firstname"
type="text"
name="firstname"
placeholder="Account Firstname"
value={props.values.firstname}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{(props.errors.firstname && props.touched.firstname) && <p className="text-sm text-red-500">{props.errors.firstname}</p>}
</div>
<div className='add-recipient my-3 md:flex items-center justify-between'>
<label className='w-full md:w-1/4 text-slate-600 text-lg'>Last Name <span className='text-red-500'>*</span></label>
<input className='w-full md:w-3/4 p-3 text-lg bg-slate-100 rounded-md outline-0 placeholder:text-slate-500 placeholder:text-lg'
value={inputs.lastname}
name='lastname'
type="text"
placeholder='Account Lastname'
required
onChange={handleChange}
/>
</div>
{/* lastname */}
<div className="field w-full">
<InputCom
label="Lastname"
type="text"
name="lastname"
placeholder="Account Lastname"
value={props.values.lastname}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{(props.errors.lastname && props.touched.lastname) && <p className="text-sm text-red-500">{props.errors.lastname}</p>}
</div>
</div>
<div className='add-recipient my-3 md:flex items-center justify-between'>
<label className='w-full md:w-1/4 text-slate-600 text-lg'>Country <span className='text-red-500'>*</span></label>
<select className='mt-2 w-full md:w-3/4 p-3 text-lg bg-white rounded-md border border-slate-300 outline-0' name='country' onChange={handleChange}>
<option className='text-slate-500 text-lg' value="">Select...</option>
</select>
</div>
<div className="xl:flex xl:space-x-7 mb-6">
{/* country */}
<div className='add-recipient w-full mb-6 xl:mb-0'>
<label className='input-label text-[#181c32] dark:text-white text-base font-semibold block mb-2.5'>Country <span className='text-red-500'>*</span></label>
<select className='w-full text-base p-2 text-dark-gray dark:text-white rounded-md border border-slate-300 outline-0' name='country'
value={props.values.country}
onChange={props.handleChange}
onBlur={props.handleBlur}
>
{allCountries.loading ?
<option className='text-slate-500 text-lg' value="">Loading...</option>
:
allCountries.data.length ?
<>
<option className='text-slate-500 text-lg' value="">Select...</option>
{allCountries.data.map((item, index)=>(
<option key={index} className='text-slate-500 text-lg' value={item[0]}>{item[1]}</option>
))}
</>
:
<option className='text-slate-500 text-lg' value="">No Options Found! Try Again</option>
}
</select>
{(props.errors.country && props.touched.country) && <p className="text-sm text-red-500">{props.errors.country}</p>}
</div>
{/* bank name */}
<div className='add-recipient w-full'>
<label className='input-label text-[#181c32] dark:text-white text-base font-semibold block mb-2.5'>Bank Name <span className='text-red-500'>*</span></label>
<select className='w-full text-base p-2 text-dark-gray dark:text-white rounded-md border border-slate-300 outline-0' name='bank'
value={props.values.bank}
onChange={props.handleChange}
onBlur={props.handleBlur}
>
{bankName.loading ?
<option className='text-slate-500 text-lg' value="">Loading...</option>
:
bankName.data.length ?
<>
<option className='text-slate-500 text-lg' value="">Select...</option>
{bankName.data.map((item, index)=>(
<option key={index} className='text-slate-500 text-lg' value={item.code}>{item.name}</option>
))}
</>
:
<option className='text-slate-500 text-lg' value="">No Options Found! Try Again</option>
}
</select>
{(props.errors.bank && props.touched.bank) && <p className="text-sm text-red-500">{props.errors.bank}</p>}
</div>
</div>
<div className='add-recipient my-3 md:flex items-center justify-between'>
<label className='w-full md:w-1/4 text-slate-600 text-lg'>Bank Name <span className='text-red-500'>*</span></label>
<select className='mt-2 w-full md:w-3/4 p-3 text-lg bg-white rounded-md border border-slate-300 outline-0' name='bank-name' onChange={handleChange}>
<option className='text-slate-500 text-lg' value="">Select...</option>
</select>
</div>
{/* ACCOUNT NUMBER */}
<div className="xl:flex xl:space-x-7 mb-6">
<div className="field w-full mb-6 xl:mb-0">
<InputCom
label="Account Number"
type="text"
name="accountNumber"
placeholder="Account No"
value={props.values.accountNumber}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{(props.errors.accountNumber && props.touched.accountNumber) && <p className="text-sm text-red-500">{props.errors.accountNumber}</p>}
</div>
<div className='add-recipient my-3 md:flex items-center justify-between'>
<label className='w-full md:w-1/4 text-slate-600 text-lg'>Account Number <span className='text-red-500'>*</span></label>
<input className='w-full md:w-3/4 p-3 text-lg bg-slate-100 rounded-md outline-0 placeholder:text-slate-500 placeholder:text-lg'
value={inputs['account-number']}
name='account-number'
type="text"
placeholder='Account No'
required
onChange={handleChange}
/>
</div>
{/* REPEAT ACCT. NUMBER */}
<div className="field w-full">
<InputCom
label="Repeat Account Number"
type="text"
name="repeatAccountNumber"
placeholder="Repeat Account Number"
value={props.values.repeatAccountNumber}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{(props.errors.repeatAccountNumber && props.touched.repeatAccountNumber) && <p className="text-sm text-red-500">{props.errors.repeatAccountNumber}</p>}
</div>
</div>
<div className='add-recipient my-3 md:flex items-center justify-between'>
<label className='w-full md:w-1/4 text-slate-600 text-lg'>Repeat Account Number <span className='text-red-500'>*</span></label>
<input className='w-full md:w-3/4 p-3 text-lg bg-slate-100 rounded-md outline-0 placeholder:text-slate-500 placeholder:text-lg'
value={inputs['repeat-account-number']}
name='repeat-account-number'
type="text"
placeholder='Repeat Account No'
required
onChange={handleChange}
/>
</div>
<div className="xl:flex xl:space-x-7 mb-6">
{/* Account Type */}
<div className='add-recipient w-full'>
<label className='input-label text-[#181c32] dark:text-white text-base font-semibold block mb-2.5'>Account Type <span className='text-red-500'>*</span></label>
<select className='w-full text-base p-2 text-dark-gray dark:text-white rounded-md border border-slate-300 outline-0' name='accountType'
value={props.values.accountType}
onChange={props.handleChange}
onBlur={props.handleBlur}
>
{accType.loading ?
<option className='text-slate-500 text-lg' value="">Loading...</option>
:
accType.data.length ?
<>
<option className='text-slate-500 text-lg' value="">Select...</option>
{accType.data.map((item, index)=>(
<option key={index} className='text-slate-500 text-lg' value={item.value}>{item.name}</option>
))}
</>
:
<option className='text-slate-500 text-lg' value="">No Options Found! Try Again</option>
}
</select>
{(props.errors.accountType && props.touched.accountType) && <p className="text-sm text-red-500">{props.errors.accountType}</p>}
</div>
</div>
<div className='add-recipient my-3 md:flex items-center justify-between'>
<label className='w-full md:w-1/4 text-slate-600 text-lg'>Account type <span className='text-red-500'>*</span></label>
<select className='mt-2 w-full md:w-3/4 p-3 text-lg bg-white rounded-md border border-slate-300 outline-0' name='account-type' onChange={handleChange}>
<option className='text-slate-500 text-lg' value="">Select...</option>
</select>
</div>
{/* state */}
<div className="xl:flex xl:space-x-7 mb-6">
<div className="field w-full mb-6 xl:mb-0">
<InputCom
label="State"
type="text"
name="state"
placeholder="State/Province"
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 className='add-recipient my-3 md:flex items-center justify-between'>
<label className='w-full md:w-1/4 text-slate-600 text-lg'>State/Province <span className='text-red-500'>*</span></label>
<input className='w-full md:w-3/4 p-3 text-lg bg-slate-100 rounded-md outline-0 placeholder:text-slate-500 placeholder:text-lg'
value={inputs.state}
name='state'
type="text"
placeholder='State'
required
onChange={handleChange}
/>
</div>
{/* city */}
<div className="field w-full">
<InputCom
label="City"
type="text"
name="city"
placeholder="City"
value={props.values.city}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{(props.errors.city && props.touched.city) && <p className="text-sm text-red-500">{props.errors.city}</p>}
</div>
</div>
{/* end of inputs starts here */}
<div className='add-recipient my-3 md:flex items-center justify-between'>
<label className='w-full md:w-1/4 text-slate-600 text-lg'>City <span className='text-red-500'>*</span></label>
<input className='w-full md:w-3/4 p-3 text-lg bg-slate-100 rounded-md outline-0 placeholder:text-slate-500 placeholder:text-lg'
value={inputs.city}
name='city'
type="text"
placeholder='City'
required
onChange={handleChange}
/>
</div>
{/* REQUEST ERROR DISPLAY */}
{requestStatus.message && <p className='text-sm text-red-500'>{requestStatus.message}</p>}
{/* end of inputs starts here */}
<div className='add-recipient-btn flex justify-end items-center py-4'>
<button className='text-lg text-white bg-sky-blue px-4 py-2 hover:opacity-90 rounded-md flex items-center space-x-1'>
<span className='pr-2'>ADD RECIPIENT</span>
<Icons name="arrows" />
</button>
</div>
</form>
<div className='add-recipient-btn flex justify-end items-center py-4'>
{requestStatus.loading ?
<LoadingSpinner size={6} color='sky-blue' />
:
<button type='submit' className='text-lg text-white bg-sky-blue px-4 py-2 hover:opacity-90 rounded-md flex items-center space-x-1'>
<span className='pr-2'>ADD RECIPIENT</span>
<Icons name="arrows" />
</button>
}
</div>
</Form>
)}
</Formik>
</div>
</div>
+50 -48
View File
@@ -2,6 +2,7 @@ import React, {useEffect, useState} from 'react'
import { Link } from 'react-router-dom'
import RecentActivityTable from './WalletComponent/RecentActivityTable'
import LoadingSpinner from '../Spinners/LoadingSpinner'
import InputCom from '../Helpers/Inputs/InputCom'
import usersService from '../../services/UsersService'
@@ -97,57 +98,53 @@ function TransferFund({payment, wallet}) {
:
<h2 className='my-4 py-2 text-slate-900 dark:text-white text-xl lg:text-2xl font-medium'>No Wallet Information Found!</h2>
}
<div className='my-3 md:flex items-center justify-between space-x-2'>
<div className='transfer-input w-full md:w-1/2'>
<label className='w-full text-slate-600 text-lg'>Amount <span className='text-red-500'>*</span></label>
<input className='w-full p-3 text-lg text-right bg-slate-100 rounded-md outline-0 placeholder:text-slate-500 placeholder:text-lg'
value={inputs.amount}
name='amount'
type="text"
placeholder='Amount'
required
onChange={handleChange}
<div className="xl:flex xl:space-x-7 mb-6">
<div className="field w-full mb-6 xl:mb-0">
<InputCom
label="Amount"
type="text"
name="amount"
value={inputs.amount}
inputHandler={handleChange}
onMouseEnter={()=>{setNewFee(false)}}
onMouseLeave={()=>{setNewFee(true)}}
/>
/>
</div>
<div className='transfer-input w-full md:w-1/2'>
<label className='w-full text-slate-600 text-lg'>Fee <span className='text-red-500'>*</span></label>
<input className='w-full p-3 text-lg text-right bg-slate-100 opacity-50 rounded-md outline-0 placeholder:text-slate-500 placeholder:text-lg'
value={sendMoneyFee.fee}
name='fee'
type="text"
placeholder='Fee'
required
disabled
/>
<div className="field w-full">
<InputCom
label="Fee"
type="text"
name="fee"
value={sendMoneyFee.fee}
disable={true}
/>
</div>
</div>
<div className='my-3 md:flex items-center justify-end space-x-2'>
<div className='transfer-input w-full md:w-1/2'>
<label className='w-full text-slate-600 text-lg'>Total <span className='text-red-500'>*</span></label>
<input className='w-full p-3 text-lg text-right bg-slate-100 opacity-50 rounded-md outline-0 placeholder:text-slate-500 placeholder:text-lg'
value={sendMoneyFee.total}
name='total'
type="text"
placeholder='Total'
required
disabled
/>
<div className='md:flex items-center justify-end'>
<div className="field w-full lg:w-1/2 mb-6">
<InputCom
label="Total"
type="text"
name="total"
value={sendMoneyFee.total}
disable={true}
/>
</div>
</div>
<div className='relative my-3 md:flex items-center'>
<div className='transfer-input w-full'>
<div className='flex items-center justify-start'>
<label className='text-slate-600 text-lg'>Recipient
<div className='flex items-center justify-start py-2'>
<label className='text-[#181c32] dark:text-white text-base font-semibold block mb-2.5'>Recipient
<span className='text-red-500 mx-2'>*</span>
<span title='Transfer Recipient' className={`text-white text-sm bg-slate-500 w-1 h-1 rounded-full px-3 py-1 cursor-pointer`}>!</span>
</label>
<Link to='add-recipient' className='mx-1 text-base text-white p-3 bg-[orange] rounded-md hover:opacity-80'>Add New</Link>
<Link to='add-recipient' className='mx-1 text-base text-white p-2 bg-[orange] rounded-md hover:opacity-80'>Add New</Link>
</div>
<select className='mt-2 w-full p-3 text-lg bg-white rounded-md border border-slate-300 outline-0' value={inputs.recipient} name='recipient' onChange={handleChange}>
<select className='w-full text-base p-2 text-dark-gray dark:text-white rounded-md border border-slate-300 outline-0' value={inputs.recipient} name='recipient' onChange={handleChange}>
{recepients.loading ?
<option className='text-slate-500 text-lg' value="">Loading...</option>
:
@@ -168,18 +165,23 @@ function TransferFund({payment, wallet}) {
</div>
</div>
<div className='my-3 md:flex items-center'>
<div className='transfer-input w-full'>
<label className='w-full text-slate-600 text-lg'>Comment <span className='text-red-500'>*</span></label>
<input className='w-full p-3 text-lg bg-slate-100 rounded-md outline-0 placeholder:text-slate-500 placeholder:text-lg'
value={inputs.comment}
name='comment'
type="text"
placeholder='Comment'
required
onChange={handleChange}
/>
</div>
<div className="field w-full mb-6">
{/* <InputCom
label="Comment"
type="text"
name="comment"
value={inputs.comment}
inputHandler={handleChange}
/> */}
<label className='text-[#181c32] dark:text-white text-base font-semibold block mb-2.5'>Comment</label>
<textarea style={{resize: 'none'}}
className='text-base px-6 text-dark-gray dark:text-white w-full bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none'
name="comment"
value={inputs.comment}
onChange={handleChange}
cols="30"
rows="2"
/>
</div>
<div className='transfer-fund-btn flex justify-end items-center py-4'>
+6
View File
@@ -10,6 +10,12 @@
src: url("./assets/fonts/Product Sans Bold.ttf");
}
.banner-630-340{
width: 630px;
height: 340px;
background-color: aliceblue;
}
/* Bold italic Weight */
@font-face {
font-family: "Product Sans";
+56 -2
View File
@@ -96,7 +96,7 @@ class usersService {
return this.postAuxEnd("/getjobsdata", postData);
}
getMyJobList(){
getHeroJBanners(){
var postData = {
uuid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
@@ -104,7 +104,19 @@ class usersService {
page:0,
limit :100
};
return this.postAuxEnd("/myjobs", postData);
return this.postAuxEnd("/homebanners", postData);
}
getMyJobList(){
var postData = {
uuid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
page:0,
offset:0,
limit :100
};
return this.postAuxEnd("/jobmanagerlist", postData);
}
getGetPendingJobs(){
@@ -153,6 +165,17 @@ class usersService {
return this.postAuxEnd("/recipients", postData);
}
//END POINT CALL FOR UPDATE PROFILE
addRecipient(data){
var postData = {
uid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
...data
};
return this.postAuxEnd("/addrecipient", postData);
}
// API FUNCTION TO GET SEND MONEY FEE
getSendMoneyFee(amount){
var postData = {
@@ -263,6 +286,37 @@ class usersService {
return this.postAuxEnd("/signupcountry", null);
}
// END POINT TO GET BANK NAME
getCountryBank() {
var postData = {
uid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
action: 11183,
country: 'NG'
};
return this.postAuxEnd("/countrybanks", postData);
}
// END POINT TO GET ACCOUNT TYPE
getAccountTypes() {
var postData = {
uid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
action: 11177
};
return this.postAuxEnd("/accounttypes", postData);
}
verifyEmail(code) {
const reqData = {
verify_link: code,
action: 11015
}
return this.postAuxEnd("/verifysignuplink", reqData);
}
/*
- 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(username)
- 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(password)
+18 -2
View File
@@ -1,7 +1,23 @@
import React from "react";
import React, {useState, useEffect} from 'react'
import Home from "../components/Home";
import usersService from "../services/UsersService";
export default function HomePages() {
const [marketActiveJobList, setMarketActiveJobList] = useState([]);
const api = new usersService();
const getMarketActiveJobList = async () => {
try {
const res = await api.getHeroJBanners();
setMarketActiveJobList(res.data);
} catch (error) {
console.log("Error getting mode");
}
};
useEffect(() => {
getMarketActiveJobList();
}, []);
return (
<>
<Home />
+2 -2
View File
@@ -24,10 +24,10 @@ export default function MyJobsPage() {
getMyJobList();
}, []);
debugger;
// debugger;
return (
<>
<MyJobs />
<MyJobs MyJobList={MyJobList} />
</>
);
}
+5
View File
@@ -0,0 +1,5 @@
import VerifyLink from "../components/AuthPages/VerifyLink";
export default function VerifyLinkPages() {
return <VerifyLink />;
}
+4042 -4758
View File
File diff suppressed because it is too large Load Diff