Compare commits

...

35 Commits

Author SHA1 Message Date
victorAnumudu 8f1d2b6584 market category toggle position changed 2023-06-21 10:02:47 +01:00
ameye 3a3503447a Merge branch 'market-list-toggle' of WrenchBoard/Users-Wrench into master 2023-06-20 22:34:26 +00:00
ameye e46d2bea8d Merge branch 'JobList-Categories' of WrenchBoard/Users-Wrench into master 2023-06-20 22:34:15 +00:00
victorAnumudu b05c519571 adjusted market toggle position 2023-06-20 22:48:55 +01:00
victorAnumudu 48ab2d80ad market list toggle added, thumbnail images added in add pay card page 2023-06-20 22:37:18 +01:00
Ebube 47876875cf done 2023-06-20 21:33:18 +01:00
ameye d78ad0b648 Merge branch 'JobList-Categories' of WrenchBoard/Users-Wrench into master 2023-06-20 19:52:15 +00:00
Ebube d63690a43c Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into JobList-Categories 2023-06-20 20:47:36 +01:00
Ebube 3ce97a4b76 . 2023-06-20 20:46:51 +01:00
ameye 6e9af99d46 Merge branch 'paycard-listing' of WrenchBoard/Users-Wrench into master 2023-06-20 19:44:35 +00:00
victorAnumudu 4ce8f813c4 added svg images 2023-06-20 20:22:08 +01:00
victorAnumudu 9163c42d77 API for paycard listing added 2023-06-20 20:15:05 +01:00
CHIEFSOFT\ameye 3b4ce9c99e Production to orion 2023-06-20 12:00:57 -04:00
ameye cfa6117a07 Merge branch 'history-new-layout' of WrenchBoard/Users-Wrench into master 2023-06-20 15:01:40 +00:00
victorAnumudu 6f26e2e88f history layout changed 2023-06-20 15:50:47 +01:00
ameye b7927a9d6a Merge branch 'JobList-Categories' of WrenchBoard/Users-Wrench into master 2023-06-19 22:43:57 +00:00
Ebube 2d366cd103 . 2023-06-19 22:32:18 +01:00
Ebube 6eed7bf1f3 Added Price Formatter to this files 2023-06-19 22:27:01 +01:00
Ebube 3c87a67581 Changed the status and moved the payload to the users-services 2023-06-19 21:47:40 +01:00
Ebube e31ee86299 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into JobList-Categories 2023-06-19 21:25:18 +01:00
Ebube 4d3fe6a799 Joblist cart 2023-06-19 21:24:57 +01:00
CHIEFSOFT\ameye 3e8c8e88ea Correct endpoint settings 2023-06-19 08:24:19 -04:00
ameye feca65eb80 Merge branch 'add-dollar-fund' of WrenchBoard/Users-Wrench into master 2023-06-19 11:45:43 +00:00
victorAnumudu 9ea846bc56 add dollar fund component added 2023-06-19 10:21:50 +01:00
CHIEFSOFT\ameye 8c31eb3145 banner description 2023-06-18 20:05:11 -04:00
ameye d049d1b2b0 Merge branch 'referral_page_payload_fix' of WrenchBoard/Users-Wrench into master 2023-06-18 22:17:02 +00:00
Ebube d34895c64c . 2023-06-18 23:09:18 +01:00
Ebube 9a3fa2a4a4 added fix 2023-06-18 23:06:16 +01:00
Ebube a9d982386c . 2023-06-18 22:46:42 +01:00
ameye 2341d2a17d Merge branch 'offer-interval-cleanup' of WrenchBoard/Users-Wrench into master 2023-06-18 16:45:26 +00:00
ameye 076df9438d Merge branch 'Market-Categories' of WrenchBoard/Users-Wrench into master 2023-06-18 16:45:21 +00:00
Ebube bbf03b2b10 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into Market-Categories 2023-06-18 15:52:19 +01:00
Ebube afead464b0 Done! 2023-06-18 15:51:59 +01:00
victorAnumudu dcdf03e9c5 redirect interval cleared from memory once the page redirects 2023-06-18 13:41:43 +01:00
ameye 44e2402cb3 Merge branch 'offer-interest-process' of WrenchBoard/Users-Wrench into master 2023-06-18 11:58:58 +00:00
37 changed files with 1502 additions and 721 deletions
+4 -4
View File
@@ -9,11 +9,11 @@ REACT_APP_APPSITE="https://myfitapp.mermsemr.com"
# REACT_APP_AUX_ENDPOINT="http://10.20.30.32:9083/svs/user" # 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_USERS_ENDPOINT="http://10.20.30.32:9083/svs/user"
REACT_APP_AUX_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/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_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_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" REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
#"https://devapi.mermsemr.com/en/desktop/api/v2/myfituser" #"https://devapi.mermsemr.com/en/desktop/api/v2/myfituser"
+4 -4
View File
@@ -9,11 +9,11 @@ REACT_APP_APPSITE="https://myfitapp.mermsemr.com"
# REACT_APP_AUX_ENDPOINT="http://10.20.30.32:9083/svs/user" # 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_USERS_ENDPOINT="http://10.20.30.32:9083/svs/user"
REACT_APP_AUX_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/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_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_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" REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
#"https://devapi.mermsemr.com/en/desktop/api/v2/myfituser" #"https://devapi.mermsemr.com/en/desktop/api/v2/myfituser"
+4 -4
View File
@@ -9,11 +9,11 @@ REACT_APP_APPSITE="https://myfitapp.mermsemr.com"
# REACT_APP_AUX_ENDPOINT="http://10.20.30.32:9083/svs/user" # 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_USERS_ENDPOINT="http://10.20.30.32:9083/svs/user"
REACT_APP_AUX_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/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_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_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" REACT_APP_USERS_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/en/wrench/api/v1"
#"https://devapi.mermsemr.com/en/desktop/api/v2/myfituser" #"https://devapi.mermsemr.com/en/desktop/api/v2/myfituser"
+9
View File
@@ -0,0 +1,9 @@
<svg width="905" height="575" viewBox="0 0 905 575" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<rect width="905" height="575" fill="url(#pattern0)"/>
<defs>
<pattern id="pattern0" patternContentUnits="objectBoundingBox" width="1" height="1">
<use xlink:href="#image0_201_3" transform="matrix(0.00849979 0 0 0.0131639 -0.0662984 -0.354783)"/>
</pattern>
<image id="image0_201_3" width="130" height="130" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIIAAACCCAMAAAC93eDPAAAApVBMVEX///82OzgAAAAuMi81OjdVXVfqpQCzs7NCSUSwsbAaIBslKyjk5OQuNDAhJiLZ2tpJT0opNTkvNzloVy31rAC1hRtPV1HNzc34+PgaLztBQUHLkg9UVFTw8PDGxsaioqKampp/f39sbGyIiIgaGho9Qj5MTExeXl5fUi+9vb03Nzd2dnYjIyORkZFjZWMNFQ9CQTWYcyLAjBSsfx12XytSSjEQEBBeBsYmAAAEiklEQVR4nO3a7XaqOBQG4BjoQXRraKc1GUoSPgQaETszZ473f2kTqm0VsKLLYs80b3+UhQgPOwlBESETExMTExMTExMTExMTk/9HQDk9xHUdcgiwmk7HPWQ0Gj0HrQiaWvagh9iWztSiTQH3rD4AW4I19nmDUI77EWwJ1ihpENJeWuGdYE0afXHSN2EMdUI/fXGHMK0Piv6rcJhg39VyadpRwt3g6Y+9PNl3/RLsvx7va3kcXLYOxwh/Ptz/qOX+79t+CY91wY8fD4ZgCIbwvQn/NAT3P/sl3P3bENz/uuwkcXSaun162M/PX5ctQofJ+u62lgtPlL/HLYshGIIhfDGC3chZ65ur7c6EYSN2+/r0wPYvn4/ttH19B4Lt3TRSGexZc316YP3LgZrrZ9sqTK5PsK7fEMcJn90d7eOEz84XIEyuT7CuTrCvT5hcn2BdnWBfnbAj+CaEtyvizrXROpfQOu0fAwyGnucN9X89XeiltPrebnIuwU5nO+n2dbmdbqfH1B6+Le02w4mEvYnX60J4PW61/fukb51PGO4SulWheRehMecTTu8LbTc+NzMvPZ9wctrupW505+yR0NYOelR41yVUgq5VaLnjOvmy0GyIStC5L6RH0okwbBN4g06ExpubFe00JPbKMNsIOl4XWofT6YTB4HU/3mDWLjjpc8RevE4APSF4VSFmQ31VTl8AqdWZcInuuEFUHWczLdgDuw7o637BnjSP/AHh8o9KPwR8fhXslsrXCfUHxpd8bH7k9LdpPDZHyajL+y6XUdQggD/uUzAeNNoBIWpN+xNMJy0/JNF1mD2Pespz0FKDDcJxe4k6BDAxMTExMTH5kunjZ8cfB+Gr53sTluE7YQ0gBSGrBEgEROIcCA0oVnEEkFfbCp44ZUYDAhLjiGAKCiugmASlXAGMa/teEBCLHCCSYZmEofBlqUIcACQ44r4PoJbVZnOk3ghzFPlMujyEbIViH8es4C6LSAKuAP16gaqlAlwomY9DVrCElSjhCVfSAYe6NYLPSq6oCFmohFIhl64kLqYkZEuFogzlqMSZEPo2nr4TijVLQk1YBihYa0IGigMNeZRF+vUcFTiGkiqxTpa45BIWUjIfQs4dh8KiXmGfBZQSqc9EACExsBcCuDHyKXd8hLmu9GY8wvKVADHnKJZIBIis8AoByTnoc4k2Z6hPeYlUKIRUfkXgcxxpQskBqTlhywYh3xB8DkRvByysCE6McghptiGwjYG+EgLMSigkwQHS5xTzAGdQIk2QVUP4q5BlnOVC5PqVqgq+cF+qkCCV64odICCMqEBLvadwW4UYCcj3quC/E1BElS5wjlaLqiFwwHUPAf2ho1jhGCUso2jh8IgFVV9ACSpRxBO2Ig4oShuEgju6ZJrgKraEgEmilrovaHKk/wKUbPsCmb+OCJphEReioDTRG+JAl9tXa7mKiZLSxWtJEpyo+ZwKx8eFwEoPG71XLLKo9Cmtd4aFomrp616gB1Xhrp0sSiQlmSBx4uLqKHK+GRHibUR8mCQ4tsW5mUrcjfD5+QKE/wC0yMO17JCUyAAAAABJRU5ErkJggg=="/>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

+2
View File
@@ -0,0 +1,2 @@
<?xml version="1.0" ?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg fill="#000000" width="800px" height="800px" viewBox="0 0 52 52" data-name="Layer 1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"><path d="M14,16H2a2,2,0,0,1-2-2V2A2,2,0,0,1,2,0H14a2,2,0,0,1,2,2V14A2,2,0,0,1,14,16ZM4,12h8V4H4Z"/><path d="M14,34H2a2,2,0,0,1-2-2V20a2,2,0,0,1,2-2H14a2,2,0,0,1,2,2V32A2,2,0,0,1,14,34ZM4,30h8V22H4Z"/><path d="M14,52H2a2,2,0,0,1-2-2V38a2,2,0,0,1,2-2H14a2,2,0,0,1,2,2V50A2,2,0,0,1,14,52ZM4,48h8V40H4Z"/><path d="M32,16H20a2,2,0,0,1-2-2V2a2,2,0,0,1,2-2H32a2,2,0,0,1,2,2V14A2,2,0,0,1,32,16ZM22,12h8V4H22Z"/><path d="M32,34H20a2,2,0,0,1-2-2V20a2,2,0,0,1,2-2H32a2,2,0,0,1,2,2V32A2,2,0,0,1,32,34ZM22,30h8V22H22Z"/><path d="M32,52H20a2,2,0,0,1-2-2V38a2,2,0,0,1,2-2H32a2,2,0,0,1,2,2V50A2,2,0,0,1,32,52ZM22,48h8V40H22Z"/><path d="M50,16H38a2,2,0,0,1-2-2V2a2,2,0,0,1,2-2H50a2,2,0,0,1,2,2V14A2,2,0,0,1,50,16ZM40,12h8V4H40Z"/><path d="M50,34H38a2,2,0,0,1-2-2V20a2,2,0,0,1,2-2H50a2,2,0,0,1,2,2V32A2,2,0,0,1,50,34ZM40,30h8V22H40Z"/><path d="M50,52H38a2,2,0,0,1-2-2V38a2,2,0,0,1,2-2H50a2,2,0,0,1,2,2V50A2,2,0,0,1,50,52ZM40,48h8V40H40Z"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 236 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.6 KiB

+52 -42
View File
@@ -3,11 +3,8 @@ import { Link } from "react-router-dom";
import InputCom from "../Helpers/Inputs/InputCom"; import InputCom from "../Helpers/Inputs/InputCom";
import LoadingSpinner from "../Spinners/LoadingSpinner"; import LoadingSpinner from "../Spinners/LoadingSpinner";
import usersService from "../../services/UsersService"; import usersService from "../../services/UsersService";
import { useSelector, useDispatch } from "react-redux"; import { useSelector, useDispatch } from "react-redux";
import { tableReload } from "../../store/TableReloads"; import { tableReload } from "../../store/TableReloads";
import { Field, Form, Formik } from "formik"; import { Field, Form, Formik } from "formik";
import * as Yup from "yup"; import * as Yup from "yup";
@@ -36,9 +33,10 @@ const validationSchema = Yup.object().shape({
.typeError("you must specify a number") .typeError("you must specify a number")
.min(1, "Price must be greater than 0") .min(1, "Price must be greater than 0")
.required("Timeline is required"), .required("Timeline is required"),
category: Yup.array().min(1, "Select at least one checkbox"),
}); });
function AddJob({ popUpHandler }) { function AddJob({ popUpHandler, categories }) {
const ApiCall = new usersService(); const ApiCall = new usersService();
let dispatch = useDispatch(); let dispatch = useDispatch();
@@ -58,6 +56,7 @@ function AddJob({ popUpHandler }) {
description: "", description: "",
job_detail: "", job_detail: "",
timeline_days: "", timeline_days: "",
category: [],
}; };
let [requestStatus, setRequestStatus] = useState({ let [requestStatus, setRequestStatus] = useState({
@@ -88,6 +87,7 @@ function AddJob({ popUpHandler }) {
// FUNCTION TO HANDLE ADD JOB FORM // FUNCTION TO HANDLE ADD JOB FORM
const handleAddJob = (values, helpers) => { const handleAddJob = (values, helpers) => {
values.category = values.category?.join("@");
setRequestStatus({ loading: true, status: false, message: "" }); setRequestStatus({ loading: true, status: false, message: "" });
ApiCall.jobManagerCreateJob(values) ApiCall.jobManagerCreateJob(values)
.then((res) => { .then((res) => {
@@ -106,7 +106,7 @@ function AddJob({ popUpHandler }) {
}); });
setTimeout(() => { setTimeout(() => {
dispatch(tableReload({ type: "JOBTABLE" })); dispatch(tableReload({ type: "JOBTABLE" }));
popUpHandler() popUpHandler();
}, 1000); }, 1000);
}) })
.catch((err) => { .catch((err) => {
@@ -127,6 +127,7 @@ function AddJob({ popUpHandler }) {
getUserCountry(); getUserCountry();
}, []); }, []);
return ( return (
<div className="add-job p-5 w-full bg-white rounded-md flex flex-col justify-between"> <div className="add-job p-5 w-full bg-white rounded-md flex flex-col justify-between">
<Formik <Formik
@@ -141,7 +142,7 @@ function AddJob({ popUpHandler }) {
<div className="fields w-full"> <div className="fields w-full">
{/* inputs starts here */} {/* inputs starts here */}
{/* country */} {/* country */}
<div className="xl:flex xl:space-x-7 mb-6"> <div className="xl:flex xl:space-x-7 mb-[5px]">
<div className="field w-full mb-6 xl:mb-0"> <div className="field w-full mb-6 xl:mb-0">
<label <label
htmlFor="country" htmlFor="country"
@@ -187,11 +188,6 @@ function AddJob({ popUpHandler }) {
</option> </option>
)} )}
</select> </select>
{props.errors.country && props.touched.country && (
<p className="text-sm text-red-500">
{props.errors.country}
</p>
)}
</div> </div>
{/* Price */} {/* Price */}
@@ -207,18 +203,14 @@ function AddJob({ popUpHandler }) {
value={props.values.price} value={props.values.price}
inputHandler={props.handleChange} inputHandler={props.handleChange}
blurHandler={props.handleBlur} blurHandler={props.handleBlur}
errorBorder={props.errors.price && props.touched.price}
/> />
{props.errors.price && props.touched.price && (
<p className="text-sm text-red-500">
{props.errors.price}
</p>
)}
</div> </div>
</div> </div>
{/* Title */} {/* Title */}
<div className="field w-full mb-6"> <div className="field w-full mb-[5px]">
<InputCom <InputCom
fieldClass="px-6" fieldClass="px-6"
label="Title" label="Title"
@@ -226,20 +218,15 @@ function AddJob({ popUpHandler }) {
inputBg="bg-slate-100" inputBg="bg-slate-100"
type="text" type="text"
name="title" name="title"
// placeholder="Enter Job Title"
value={props.values.title} value={props.values.title}
inputHandler={props.handleChange} inputHandler={props.handleChange}
blurHandler={props.handleBlur} blurHandler={props.handleBlur}
errorBorder={props.errors.title && props.touched.title}
/> />
{props.errors.title && props.touched.title && (
<p className="text-sm text-red-500">
{props.errors.title}
</p>
)}
</div> </div>
{/* Description */} {/* Description */}
<div className="field w-full mb-6"> <div className="field w-full mb-[5px]">
<InputCom <InputCom
fieldClass="px-6" fieldClass="px-6"
label="Description" label="Description"
@@ -247,20 +234,16 @@ function AddJob({ popUpHandler }) {
inputBg="bg-slate-100" inputBg="bg-slate-100"
type="text" type="text"
name="description" name="description"
// placeholder="Enter a description"
value={props.values.description} value={props.values.description}
inputHandler={props.handleChange} inputHandler={props.handleChange}
blurHandler={props.handleBlur} blurHandler={props.handleBlur}
errorBorder={props.errors.description && props.touched.description}
/> />
{props.errors.description && props.touched.description && (
<p className="text-sm text-red-500">
{props.errors.description}
</p>
)}
</div> </div>
{/* Details */} {/* Details */}
<div className="field w-full mb-6"> <div className="field flex flex-col sm:flex-row w-full mb-[5px] gap-2">
<div className="sm:w-[60%] w-full">
<label <label
htmlFor="Job Delivery Details" htmlFor="Job Delivery Details"
className='className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"' className='className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"'
@@ -269,22 +252,52 @@ function AddJob({ popUpHandler }) {
</label> </label>
<textarea <textarea
id="Job Delivery Details" id="Job Delivery Details"
rows="7" rows="5"
className={`input-field p-6 mt-3 rounded-md placeholder:text-base text-dark-gray dark:text-white w-full h-full bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none`} className={`input-field px-6 py-2 placeholder:text-base text-dark-gray dark:text-white w-full h-[100px] bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-[#dce4e9] border border-[#dce4e9] rounded-[10px]`}
style={{ resize: "none" }} style={{ resize: "none" }}
name="job_detail" name="job_detail"
value={props.values.job_detail} value={props.values.job_detail}
onChange={props.handleChange} onChange={props.handleChange}
onBlur={props.handleBlur} onBlur={props.handleBlur}
/> />
</div>
<div className="sm:w-[35%] w-full">
<div
htmlFor="Job Categories"
className='className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"'
id="checked-group"
>
Categories
</div>
<div
className="sm:flex-col flex flex-wrap px-3 mt-3"
role="group"
aria-labelledby="checked-group"
>
{Object.entries(categories).map(([key, value]) => (
<label key={key} className="flex gap-1 w-full items-center">
<Field
type="checkbox"
name="category"
value={key}
/>
<span className="text-[13.975px]">{value}</span>
</label>
))}
</div>
</div>
{/* <div className={`${!props.errors && "invisible"} h-5`}>
{props.errors.job_detail && props.touched.job_detail && ( {props.errors.job_detail && props.touched.job_detail && (
<p className="text-sm text-red-500"> <p className="text-sm text-red-500">
{props.errors.job_detail} {props.errors.job_detail}
</p> </p>
)} )}
</div> */}
</div> </div>
<div className="field w-full mb-6"> <div className="field w-full mb-[5px]">
<div className={`flex items-center justify-between mb-2.5`}> <div className={`flex items-center justify-between mb-2.5`}>
<label <label
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block" className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"
@@ -313,12 +326,6 @@ function AddJob({ popUpHandler }) {
</option> </option>
))} ))}
</Field> </Field>
{props.errors.timeline_days &&
props.touched.timeline_days && (
<p className="text-sm text-red-500">
{props.errors.timeline_days}
</p>
)}
</div> </div>
{/* inputs ends here */} {/* inputs ends here */}
</div> </div>
@@ -345,13 +352,16 @@ function AddJob({ popUpHandler }) {
))} ))}
{/* End of error or success display */} {/* End of error or success display */}
<div className="w-full h-[120px] 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">
<Link <Link
to="/myjobs" to="/myjobs"
className="text-18 text-light-red tracking-wide " className="text-18 text-light-red tracking-wide "
> >
<span className="border-b dark:border-[#5356fb29] border-light-red"> <span
className="border-b dark:border-[#5356fb29] border-light-red"
onClick={popUpHandler}
>
{" "} {" "}
Cancel Cancel
</span> </span>
+104 -31
View File
@@ -1,35 +1,24 @@
import React, { useCallback, useEffect, useMemo, useState } from "react"; import { useCallback, useEffect, useMemo, useState } from "react";
import { Link, useNavigate, } from "react-router-dom"; import { Link, useNavigate } from "react-router-dom";
import { toast } from "react-toastify";
import localImgLoad from "../../lib/localImgLoad";
import Icons from "../Helpers/Icons";
import MarketPopUp from "../MarketPlace/PopUp/MarketPopUp"; import MarketPopUp from "../MarketPlace/PopUp/MarketPopUp";
import usersService from "../../services/UsersService"; import usersService from "../../services/UsersService";
import { PriceFormatter } from "../Helpers/PriceFormatter";
import dataImage2 from "../../assets/images/data-table-user-2.png";
export default function AvailableJobsCard({ export default function AvailableJobsCard({
className, className,
datas, datas,
hidden = false, hidden = false,
contentDisplay
}) { }) {
//debugger; //debugger;
const [addFavorite, setValue] = useState(datas.whishlisted);
const [marketPopUp, setMarketPopUp] = useState({ show: false, data: {} }); const [marketPopUp, setMarketPopUp] = useState({ show: false, data: {} });
const [manageInt, setManageInt] = useState(null) const [manageInt, setManageInt] = useState(null);
const [imageUrl, setImageUrl] = useState("");
const navigate = useNavigate(); const navigate = useNavigate();
const apiCall = useMemo(() => new usersService(), []); const apiCall = useMemo(() => new usersService(), []);
const favoriteHandler = () => {
if (!addFavorite) {
setValue(true);
toast.success("Added to Favorite List");
} else {
setValue(false);
toast.warn("Remove to Favorite List");
}
};
const marketInterestData = useCallback(async () => { const marketInterestData = useCallback(async () => {
let { offer_code } = datas; let { offer_code } = datas;
let reqData = { offer_code }; let reqData = { offer_code };
@@ -37,21 +26,32 @@ export default function AvailableJobsCard({
try { try {
const manageInt = await apiCall.MarketInterest(reqData); const manageInt = await apiCall.MarketInterest(reqData);
const manageIntRes = await manageInt?.data; const manageIntRes = await manageInt?.data;
setManageInt(manageIntRes) setManageInt(manageIntRes);
} catch (error) { } catch (error) {
throw new Error(error) throw new Error(error);
} }
}, [apiCall, datas]);
}, []) let thePrice = PriceFormatter(
datas?.price * 0.01,
datas?.currency_code,
datas?.currency
);
useEffect(() => { useEffect(() => {
if (!datas) { if (!datas) {
navigate("/market", { replace: true }); navigate("/market", { replace: true });
} }
marketInterestData() marketInterestData();
}, [marketInterestData, datas]) }, []);
useEffect(() => {
const imagePath = require(`../../assets/images/${datas.thumbnil}`); // Replace with your directory path for local images
setImageUrl(imagePath);
}, []);
return ( return (
<> <>
{contentDisplay == 'grid' ?
<div <div
className={`card-style-two w-full h-[426px] p-[20px] bg-white dark:bg-dark-white rounded-2xl section-shadow ${ className={`card-style-two w-full h-[426px] p-[20px] bg-white dark:bg-dark-white rounded-2xl section-shadow ${
className || "" className || ""
@@ -87,11 +87,9 @@ export default function AvailableJobsCard({
</div> </div>
<div className="thumbnail-area w-full"> <div className="thumbnail-area w-full">
<div <div
className="w-full h-[236px] p-6 rounded-xl overflow-hidden" className="w-full h-[236px] p-6 rounded-xl overflow-hidden bg-center bg-cover bg-no-repeat"
style={{ style={{
background: `url(${localImgLoad( backgroundImage: `url('${imageUrl}')`,
`images/${datas.thumbnil}`
)}) 0% 0% / cover no-repeat`,
}} }}
> >
<div className="flex justify-center">{datas.description}</div> <div className="flex justify-center">{datas.description}</div>
@@ -124,11 +122,14 @@ export default function AvailableJobsCard({
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">
<div> <div>
<p className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white"> <p className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white">
{datas.price * 0.01} {/* {thePrice} | {datas.timeline_days} day(s) */}
{datas.currency} | {datas.timeline_days} day(s) {thePrice}
</p> </p>
<p className="text-sm text-lighter-gray"> <p className="text-sm text-lighter-gray">
( {datas.offer_code}) ( {datas.offer_code}) |
<span className="italic ml-1">
{datas.timeline_days} day(s)
</span>
</p> </p>
</div> </div>
</div> </div>
@@ -137,7 +138,7 @@ export default function AvailableJobsCard({
type="button" type="button"
className="px-4 py-2.5 text-white text-sm bg-pink rounded-full tracking-wide" className="px-4 py-2.5 text-white text-sm bg-pink rounded-full tracking-wide"
onClick={() => { onClick={() => {
setMarketPopUp({show: true, data: datas}) setMarketPopUp({ show: true, data: datas });
}} }}
> >
View View
@@ -147,6 +148,78 @@ export default function AvailableJobsCard({
</div> </div>
</div> </div>
</div> </div>
:
<div className="card-style-two w-full p-8 my-2 flex items-center gap-4 bg-white dark:bg-dark-white rounded-2xl section-shadow">
<div className="flex gap-5 items-center w-full">
<div className="w-full h-[60px] rounded-full overflow-hidden flex justify-center items-center flex-[0.1] min-w-[60px] max-w-[60px]">
<img src={dataImage2} alt="data" className="w-full h-full" />
</div>
<div className="flex flex-col flex-[0.9]">
<Link to="/shop-details" className="">
<h1 className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
{datas?.title}
</h1>
</Link>
<div className="my-2">
<p className="text-dark-gray dark:text-white">{datas?.description}</p>
</div>
{/* <div className="card-two-info flex gap-2 items-center">
<div className="owned-by flex space-x-2 items-center">
<div>
<p className="text-thin-light-gray text-sm leading-3">Added</p>
<p className="text-base text-dark-gray dark:text-white">
{datas.offer_added}
</p>
</div>
</div>
<div className="w-[1px] bg-light-purple dark:bg-dark-light-purple h-7"></div>
<div className="created-by flex space-x-2 items-center flex-row-reverse">
<div>
<p className="text-thin-light-gray text-sm leading-3 text-right">
Expires
</p>
<p className="text-base text-dark-gray dark:text-white text-right">
{datas.expire}
</p>
</div>
</div>
</div> */}
<div className="block sm:flex flex-wrap gap-4">
<p className="text-sm text-thin-light-gray">
Price: <span className="text-purple">{thePrice}</span>
</p>
<p className="text-sm text-thin-light-gray">
Duration:{" "}
<span className="text-purple italic">
{" "}
{datas?.timeline_days} day(s)
</span>
</p>
<p className="text-sm text-thin-light-gray">
Code:{" "}
<span className="text-purple">
{" "}
{datas?.offer_code}
</span>
</p>
</div>
</div>
</div>
<div className="">
<button
type="button"
className="px-4 py-2.5 text-white text-sm bg-pink rounded-full tracking-wide"
onClick={() => {
setMarketPopUp({ show: true, data: datas });
}}
>
View
</button>
</div>
</div>
}
{marketPopUp.show && ( {marketPopUp.show && (
<MarketPopUp <MarketPopUp
details={datas} details={datas}
@@ -9,7 +9,6 @@ export default function HomeBannerOffersCard(props) {
let { banner, banner_location } = props?.itemData; let { banner, banner_location } = props?.itemData;
if (banner_location === "LOCAL") { if (banner_location === "LOCAL") {
const imagePath = require(`../../assets/images/${banner}`); // Replace with your directory path for local images const imagePath = require(`../../assets/images/${banner}`); // Replace with your directory path for local images
console.log("This is local");
setImageUrl(imagePath); setImageUrl(imagePath);
} else if (banner_location === "URL") setImageUrl(banner); } else if (banner_location === "URL") setImageUrl(banner);
else return null; else return null;
@@ -30,7 +29,6 @@ export default function HomeBannerOffersCard(props) {
<span className="heroSilderTitle">{props.itemData.title}</span> <span className="heroSilderTitle">{props.itemData.title}</span>
</h1> </h1>
</div> </div>
{/*<SelectBox datas={filterDatas} action={dataSetHandler} />*/}
</div> </div>
<div className="h-[233px]"> <div className="h-[233px]">
<div className="siderCardDescription"> <div className="siderCardDescription">
+10
View File
@@ -1,5 +1,9 @@
import React from "react"; import React from "react";
import ATMCard from '../../assets/images/card.svg'
import VisaCard from '../../assets/images/visa.svg'
import MasterCard from '../../assets/images/master.svg'
export default function Icons({ name }) { export default function Icons({ name }) {
return ( return (
<> <>
@@ -483,6 +487,12 @@ export default function Icons({ name }) {
c0.3,0,0.5-0.1,0.7-0.3l5.7-5.7c0,0,0,0,0,0C15.9,12.3,15.9,11.7,15.5,11.3z" c0.3,0,0.5-0.1,0.7-0.3l5.7-5.7c0,0,0,0,0,0C15.9,12.3,15.9,11.7,15.5,11.3z"
></path> ></path>
</svg> </svg>
) : name === "atm-card" ? (
<img className="w-[20px]" src={ATMCard} alt="card" />
) : name === "visa-card" ? (
<img className="w-[20px]" src={VisaCard} alt="card" />
) : name === "master-card" ? (
<img className="w-[20px]" src={MasterCard} alt="card" />
) : ( ) : (
"" ""
)} )}
@@ -21,7 +21,8 @@ export default function InputCom({
blurHandler, blurHandler,
spanTag, spanTag,
inputBg, inputBg,
direction direction,
errorBorder
}) { }) {
const inputRef = useRef(null); const inputRef = useRef(null);
// Entry Validation // Entry Validation
@@ -51,11 +52,16 @@ export default function InputCom({
htmlFor={name} htmlFor={name}
> >
{label} {label}
{spanTag && ( {spanTag &&
spanTag == '*' ?
<span className="text-red-700 text-sm tracking-wide">
{' '}{spanTag}
</span>
:
<span className="text-green-700 text-sm tracking-wide"> <span className="text-green-700 text-sm tracking-wide">
{spanTag} {spanTag}
</span> </span>
)} }
</label> </label>
)} )}
{forgotPassword && ( {forgotPassword && (
@@ -68,7 +74,7 @@ export default function InputCom({
)} )}
</div> </div>
<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 ${inputClass}`} className={`input-wrapper border ${errorBorder ? "border-red-500 border-[0.5px] animate-shake" : "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 ${inputClass}`}
> >
<input <input
placeholder={placeholder} placeholder={placeholder}
@@ -89,8 +95,12 @@ export default function InputCom({
dir={direction} dir={direction}
/> />
{iconName && ( {iconName && (
<div className="absolute right-6 bottom-[10px] z-10"> <div className="absolute right-6 bottom-[10px] z-10 flex gap-2">
<Icons name={iconName} /> {
iconName.split(' ').map((item, index)=>(
<Icons key={index} name={item} />
))
}
</div> </div>
)} )}
{passIcon && ( {passIcon && (
+2 -2
View File
@@ -1,7 +1,7 @@
import React, { useState } from "react"; import React, { useState } from "react";
import useToggle from "../../../hooks/useToggle"; import useToggle from "../../../hooks/useToggle";
function SelectBox({ datas = [], className, action, contentBodyClasses }) { function SelectBox({ datas = [], className, action, contentBodyClasses, position }) {
const [item, setItem] = useState(datas[0]); const [item, setItem] = useState(datas[0]);
// custom hook // custom hook
const [toggle, setToggle] = useToggle(false); const [toggle, setToggle] = useToggle(false);
@@ -49,7 +49,7 @@ function SelectBox({ datas = [], className, action, contentBodyClasses }) {
<div <div
style={{ boxShadow: "0px 4px 87px 0px #0000002B" }} style={{ boxShadow: "0px 4px 87px 0px #0000002B" }}
className={`drop-down-content w-[120px] bg-white dark:bg-dark-white rounded-[4px] p-3 absolute right-0 top-[100%] z-20 ${ className={`drop-down-content w-[120px] bg-white dark:bg-dark-white rounded-[4px] p-3 absolute ${position =='left' ? 'left-0' : 'right-0'} top-[100%] z-20 ${
toggle ? "active" : "" toggle ? "active" : ""
} ${contentBodyClasses || ""}`} } ${contentBodyClasses || ""}`}
> >
+36 -10
View File
@@ -15,6 +15,8 @@ export default function History() {
const apiCall = new usersService() const apiCall = new usersService()
let [tab, setTab] = useState("purchases"); //STATE FOR SWITCHING BETWEEN TABS
let [paymentHistory, setPaymentHistory] = useState({ // FOR PAYMENT HISTORY let [paymentHistory, setPaymentHistory] = useState({ // FOR PAYMENT HISTORY
loading: true, loading: true,
data: [], data: [],
@@ -63,7 +65,7 @@ export default function History() {
<> <>
<Layout> <Layout>
<div className="history-wrapper w-full mb-10"> <div className="history-wrapper w-full mb-10">
<div className="main-wrapper w-full"> <div className="w-full">
<div className="sm:flex justify-between items-center mb-6"> <div className="sm:flex justify-between items-center mb-6">
<div className="mb-5 sm:mb-0"> <div className="mb-5 sm:mb-0">
<h1 className="text-26 font-bold text-dark-gray dark:text-white"> <h1 className="text-26 font-bold text-dark-gray dark:text-white">
@@ -213,24 +215,47 @@ export default function History() {
{/*</div>*/} {/*</div>*/}
{/*<MarketHistorySection />*/} {/*<MarketHistorySection />*/}
{/* <TopHxBox className="mb-11" /> */} {/* <TopHxBox className="mb-11" /> */}
<div className='w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin'> <div className='w-full p-4 md:p-8 bg-white dark:bg-dark-white rounded-2xl shadow bottomMargin'>
{/* switch button */}
<div className="my-1 flex items-center border-b border-slate-300">
<button
name="purchases"
onClick={(e) => setTab(e.target.name)}
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border ${
tab == "purchases" ? "border-sky-blue" : "border-slate-300"
} tracking-wide transition duration-200`}
>
Purchases
</button>
<button
name="recent"
onClick={(e) => setTab(e.target.name)}
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border ${
tab == "recent" ? "border-sky-blue" : "border-slate-300"
} tracking-wide transition duration-200`}
>
Recent Activity
</button>
</div>
{/* END OF switch button */}
<div className="history-tables w-full">
{/* PURCHASE SECTION */} {/* PURCHASE SECTION */}
<div className="lg:w-1/2 w-full mb-10 lg:mb-0"> {tab == 'purchases' &&
<div className="wallet w-full md:p-8 p-4 h-full max-h-[700px] bg-white dark:bg-dark-white overflow-y-auto rounded-2xl shadow"> <div className="wallet w-full border-t">
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">Purchases</h1> <h1 className="p-2 text-xl font-bold text-dark-gray dark:text-white tracking-wide">Purchases</h1>
{purchaseHistory.loading ? {purchaseHistory.loading ?
<LoadingSpinner size='16' color='sky-blue' /> <LoadingSpinner size='16' color='sky-blue' />
: :
<PurchasesTable purchase={purchaseHistory} /> <PurchasesTable purchase={purchaseHistory} />
} }
</div> </div>
</div> }
{/* END OF PURCHASE SECTION */} {/* END OF PURCHASE SECTION */}
{/* RECENT ACTIVITY SECTION */} {/* RECENT ACTIVITY SECTION */}
<div className="lg:w-1/2 w-full mb-10 lg:mb-0"> {tab == 'recent' &&
<div className="wallet w-full md:p-8 p-4 h-full max-h-[700px] bg-white dark:bg-dark-white overflow-y-auto rounded-2xl shadow"> <div className="wallet w-full border-t">
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">Recent Activity</h1> <h1 className="p-2 text-xl font-bold text-dark-gray dark:text-white tracking-wide">Recent Activity</h1>
{/* <p className='text-base text-slate-500 dark:text-white'>Activity Report</p> */} {/* <p className='text-base text-slate-500 dark:text-white'>Activity Report</p> */}
{paymentHistory.loading ? {paymentHistory.loading ?
<LoadingSpinner size='16' color='sky-blue' /> <LoadingSpinner size='16' color='sky-blue' />
@@ -238,9 +263,10 @@ export default function History() {
<RecentActivityTable payment={paymentHistory} /> <RecentActivityTable payment={paymentHistory} />
} }
</div> </div>
</div> }
{/* END OF RECENT ACTIVITY SECTION */} {/* END OF RECENT ACTIVITY SECTION */}
</div> </div>
</div>
{/*<HistoryTable />*/} {/*<HistoryTable />*/}
</div> </div>
</div> </div>
+74 -75
View File
@@ -1,106 +1,105 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useMemo, useState } from "react";
import DataIteration from "../Helpers/DataIteration"; import DataIteration from "../Helpers/DataIteration";
import AvailableJobsCard from "../Cards/AvailableJobsCard"; import AvailableJobsCard from "../Cards/AvailableJobsCard";
import ListView from '../../assets/images/list-view.png'
import GridView from '../../assets/images/grid-view.svg'
import SelectBox from "../Helpers/SelectBox";
export default function MainSection({ className, marketPlaceProduct }) { export default function MainSection({
const [tab, setTab] = useState("all"); className,
const [products, setProducts] = useState(marketPlaceProduct); marketPlaceProduct,
categories,
}) {
// Creating All cart..
let marketCategories = useMemo(
() => ({ All: "All Categories", ...categories }),
[categories]
);
const [tab, setTab] = useState(Object.keys(marketCategories)[0]);
let [contentDisplay, setContentDisplay] = useState('grid') // STATE TO HOLD LIST VIEW STYLE
// Convert to array in order to map
const mappedArray = Object.entries(marketCategories).map(([key, value]) => {
return { key, value };
});
const [products, setProducts] = useState([]);
const tabHandler = (value) => { const tabHandler = (value) => {
setTab(value); setTab(value);
}; };
useEffect(() => {
if (tab === "artist") { // Handles the category selection on mobile view
setProducts(marketPlaceProduct?.slice(0, 3)); const handleSetCategory = (value) => {
} else if (tab === "market") { for (let i in marketCategories) {
setProducts(marketPlaceProduct?.slice(0, 6)); if (marketCategories[i] == value) {
} else if (tab === "shop") { setTab(i);
setProducts(marketPlaceProduct?.slice(6, 9));
} else if (tab === "assets") {
setProducts(marketPlaceProduct?.slice(3, 6));
} else {
setProducts(marketPlaceProduct);
} }
}, [tab, marketPlaceProduct]); }
};
useEffect(() => {
if (tab === "All") {
setProducts(marketPlaceProduct);
} else {
const filteredProducts = marketPlaceProduct.filter((product) =>
product.category.includes(tab)
);
setProducts(filteredProducts);
}
}, [tab, marketPlaceProduct, categories, marketCategories]);
return ( return (
<div className={`market-place-section w-full ${className || ""}`}> <div className={`market-place-section w-full ${className || ""}`}>
<div className="market-place-wrapper w-full"> <div className="market-place-wrapper w-full">
<div className="filter-navigate-area lg:flex justify-between mb-8 items-center"> <div className="filter-navigate-area flex justify-between items-center mb-8">
<div className="tab-item lg:mb-0 mb-5"> <div className="tab-item w-full flex items-center">
<div className="md:flex md:space-x-8 space-x-2"> <div className="hidden lg:flex md:space-x-8 space-x-2">
{mappedArray.map(({ key, value }) => (
<span <span
onClick={() => tabHandler("all")} key={key}
onClick={() => tabHandler(key)}
className={`md:text-[18px] text-md text-dark-gray dark:text-white hover:text-pink border-b hover:border-pink font-medium cursor-pointer ${ className={`md:text-[18px] text-md text-dark-gray dark:text-white hover:text-pink border-b hover:border-pink font-medium cursor-pointer ${
tab === "all" tab === key
? "text-pink border-pink" ? "text-pink border-pink"
: " border-transparent" : " border-transparent"
}`} }`}
> >
All {value}
</span> </span>
))}
</div>
<span {/* market categories on screen smaller than large screen */}
onClick={() => tabHandler("artist")} <div className="w-[80%] lg:hidden">
className={`md:text-[18px] text-md text-dark-gray dark:text-white hover:text-pink border-b hover:border-pink font-medium cursor-pointer ${ <SelectBox
tab === "artist" action={handleSetCategory}
? "text-pink border-pink" datas={Object.values(marketCategories)}
: " border-transparent" className="Update-table-dropdown"
}`} contentBodyClasses="w-auto min-w-max"
> position='left'
Featured Artist />
</span>
<span
onClick={() => tabHandler("market")}
className={`md:text-[18px] text-md text-dark-gray dark:text-white hover:text-pink border-b hover:border-pink font-medium cursor-pointer ${
tab === "market"
? "text-pink border-pink"
: " border-transparent"
}`}
>
Open Market
</span>
<span
onClick={() => tabHandler("shop")}
className={`md:text-[18px] text-md text-dark-gray dark:text-white hover:text-pink border-b hover:border-pink font-medium cursor-pointer ${
tab === "shop"
? "text-pink border-pink"
: " border-transparent"
}`}
>
Partner Shops
</span>
<span
onClick={() => tabHandler("assets")}
className={`md:text-[18px] text-md text-dark-gray dark:text-white hover:text-pink border-b hover:border-pink font-medium cursor-pointer ${
tab === "assets"
? "text-pink border-pink"
: " border-transparent"
}`}
>
Game Assets
</span>
</div> </div>
</div> </div>
{/* contentDisplay toggler */}
{/*<div className="search-item flex lg:flex-none justify-end">*/} <div className="p-2 w-[35px] h-[35px] bg-white dark:bg-slate-200 rounded-lg">
{/* <SearchCom*/} <img
{/* className="lg:bg-transparent"*/} title={contentDisplay=='grid'? 'list view' : 'grid view'}
{/* inputClasses="lg:bg-transparent"*/} onClick={()=>setContentDisplay((prev)=>prev=='grid'? 'list' : 'grid')}
{/* />*/} src={contentDisplay=='grid'? ListView : GridView}
{/*</div>*/} className="w-full h-full cursor-pointer" alt="view"
/>
</div>
{/* end of contentDisplay toggler */}
</div> </div>
<div className="filter-navigate-content w-full min-h-screen"> <div className="filter-navigate-content w-full min-h-screen">
<div className="grid lg:grid-cols-3 sm:grid-cols-2 gap-[30px]"> <div className={contentDisplay == 'grid' ? 'grid lg:grid-cols-3 sm:grid-cols-2 gap-[30px]' : 'w-full'}>
<DataIteration <DataIteration
datas={products} datas={products}
startLength={process.env.REACT_APP_ZERO_STATE} startLength={process.env.REACT_APP_ZERO_STATE}
endLength={products?.length} endLength={products?.length}
> >
{({ datas }) => ( {({ datas }) => (
<AvailableJobsCard key={datas.id} datas={datas} /> <AvailableJobsCard contentDisplay={contentDisplay} key={datas.id} datas={datas} />
)} )}
</DataIteration> </DataIteration>
</div> </div>
+6 -5
View File
@@ -1,6 +1,3 @@
import React from "react";
// import products from "../../data/marketplace_data.json";
//import CreateNft from "../Home/CreateNft";
import Layout from "../Partials/Layout"; import Layout from "../Partials/Layout";
import MainSection from "./MainSection"; import MainSection from "./MainSection";
import CommonHead from "../UserHeader/CommonHead"; import CommonHead from "../UserHeader/CommonHead";
@@ -9,13 +6,17 @@ import { useSelector } from "react-redux";
export default function MarketPlace({ commonHeadData }) { export default function MarketPlace({ commonHeadData }) {
let { jobLists } = useSelector((state) => state.jobLists); let { jobLists } = useSelector((state) => state.jobLists);
const marketData = jobLists?.result_list; const marketData = jobLists?.result_list;
const categories = jobLists?.categories;
// const marketProduct = products.data;
return ( return (
<> <>
<Layout> <Layout>
<CommonHead commonHeadData={commonHeadData} /> <CommonHead commonHeadData={commonHeadData} />
<MainSection marketPlaceProduct={marketData} className="mb-10" /> <MainSection
marketPlaceProduct={marketData}
categories={categories}
className="mb-10"
/>
</Layout> </Layout>
</> </>
); );
+94 -70
View File
@@ -1,11 +1,9 @@
import React, { useCallback, useEffect, useMemo, useState } from "react"; import { useCallback, useEffect, useMemo, useState } from "react";
import dataImage2 from "../../assets/images/data-table-user-2.png"; import dataImage2 from "../../assets/images/data-table-user-2.png";
import SelectBox from "../Helpers/SelectBox"; import SelectBox from "../Helpers/SelectBox";
import DeleteJobPopout from "../jobPopout/DeleteJobPopout"; import DeleteJobPopout from "../jobPopout/DeleteJobPopout";
import JobListPopout from "../jobPopout/JobListPopout"; import JobListPopout from "../jobPopout/JobListPopout";
import LoadingSpinner from "../Spinners/LoadingSpinner"; import LoadingSpinner from "../Spinners/LoadingSpinner";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
import usersService from "../../services/UsersService"; import usersService from "../../services/UsersService";
import { handlePagingFunc } from "../Pagination/HandlePagination"; import { handlePagingFunc } from "../Pagination/HandlePagination";
@@ -14,6 +12,23 @@ import EditJobPopOut from "../jobPopout/EditJobPopout";
import { PriceFormatter } from "../Helpers/PriceFormatter"; import { PriceFormatter } from "../Helpers/PriceFormatter";
export default function MyJobTable({ MyJobList, reloadJobList, className }) { export default function MyJobTable({ MyJobList, reloadJobList, className }) {
// Getting the categories
const currentJobCart = MyJobList?.data?.categories;
// DropDown Box
const filterCategories = { All: "All Categories", ...currentJobCart };
const [selectedCategory, setCategory] = useState(
Object.keys(filterCategories)[0]
);
let [jobPopout, setJobPopout] = useState({ show: false, data: {} }); // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW
let [deleteJobPopout, setDeleteJobPopout] = useState({
show: false,
data: {},
}); // STATE TO HOLD THE VALUE OF THE ITEM DETAILS TO DELETE AND DETERMINE WHEN TO SHOW
const [editJob, setEditJob] = useState({ show: false, data: {} });
const [myCountry, setCountries] = useState(""); const [myCountry, setCountries] = useState("");
const { const {
userDetails: { country }, userDetails: { country },
@@ -45,22 +60,25 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
getCountryList(); getCountryList();
}, [getCountryList]); }, [getCountryList]);
const filterCategories = ["All Categories", "Explore", "Featured"]; // Handle Pagination
const [selectedCategory, setCategory] = useState(filterCategories[0]);
let [jobPopout, setJobPopout] = useState({ show: false, data: {} }); // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW
let [deleteJobPopout, setDeleteJobPopout] = useState({
show: false,
data: {},
}); // STATE TO HOLD THE VALUE OF THE ITEM DETAILS TO DELETE AND DETERMINE WHEN TO SHOW
const [editJob, setEditJob] = useState({ show: false, data: {} });
const [currentPage, setCurrentPage] = useState(0); const [currentPage, setCurrentPage] = useState(0);
const indexOfFirstItem = Number(currentPage); const indexOfFirstItem = Number(currentPage);
const indexOfLastItem = const indexOfLastItem =
Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE); Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
const currentJobList = MyJobList?.data?.result_list?.slice(
// Handle Filter Job List
const filterJobList = () => {
if (selectedCategory === "All") return MyJobList?.data?.result_list;
else
return MyJobList?.data?.result_list?.filter((item) =>
item.category.includes(selectedCategory)
);
};
const currentJobList = filterJobList();
// Handling Filter Pagination
const filteredCurrentJobList = currentJobList?.slice(
indexOfFirstItem, indexOfFirstItem,
indexOfLastItem indexOfLastItem
); );
@@ -69,42 +87,17 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
handlePagingFunc(e, setCurrentPage); handlePagingFunc(e, setCurrentPage);
}; };
return ( // Handles the category selection
<div const handleSetCategory = (value) => {
className={`update-table w-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow min-h-[520px] ${ setCurrentPage(0);
className || "" for (let i in filterCategories) {
}`} if (filterCategories[i] == value) {
> setCategory(i);
<div className="header w-full flex justify-between items-center mb-5"> }
<div className="flex space-x-2 items-center"> }
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-wide"> };
All Jobs
</h1>
</div>
<SelectBox
action={setCategory}
datas={filterCategories}
className="Update-table-dropdown"
contentBodyClasses="w-auto min-w-max"
/>
</div>
{MyJobList.loading ? (
<LoadingSpinner size="16" color="sky-blue" />
) : (
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between h-full">
<table className="table-auto min-w-full text-sm text-left text-gray-500 dark:text-gray-400">
<tbody>
<tr className="text-base text-thin-light-gray border-b default-border-b dark:border-[#5356fb29] ottom ">
<td className="py-1">.</td>
<td className="py-1 text-right">.</td>
</tr>
{selectedCategory === "All Categories" ? ( const JobListItem = ({ value, index }) => {
<>
{MyJobList &&
MyJobList?.data?.result_list &&
MyJobList.data?.result_list.length > 0 ? (
currentJobList.map((value, index) => {
let thePrice = PriceFormatter( let thePrice = PriceFormatter(
value?.price * 0.01, value?.price * 0.01,
value?.currency_code, value?.currency_code,
@@ -119,11 +112,7 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
<div className="sm:flex sm:space-x-2 sm:justify-between sm:items-center job-items"> <div className="sm:flex sm:space-x-2 sm:justify-between sm:items-center job-items">
<div className="flex space-x-2 items-center job-items w-full"> <div className="flex space-x-2 items-center job-items w-full">
<div className="w-full h-[60px] rounded-full overflow-hidden flex justify-center items-center flex-[0.1] min-w-[60px] max-w-[60px]"> <div className="w-full h-[60px] rounded-full overflow-hidden flex justify-center items-center flex-[0.1] min-w-[60px] max-w-[60px]">
<img <img src={dataImage2} alt="data" className="w-full h-full" />
src={dataImage2}
alt="data"
className="w-full h-full"
/>
</div> </div>
<div className="flex flex-col flex-[0.9]"> <div className="flex flex-col flex-[0.9]">
<h1 className="font-bold text-xl text-dark-gray dark:text-white"> <h1 className="font-bold text-xl text-dark-gray dark:text-white">
@@ -131,10 +120,7 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
</h1> </h1>
<div>{value.description}</div> <div>{value.description}</div>
<span className="text-sm text-thin-light-gray"> <span className="text-sm text-thin-light-gray">
Price:{" "} Price: <span className="text-purple">{thePrice}</span>
<span className="text-purple">
{thePrice}
</span>
</span> </span>
<span className="text-sm text-thin-light-gray"> <span className="text-sm text-thin-light-gray">
Duration:{" "} Duration:{" "}
@@ -153,7 +139,7 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
onClick={() => { onClick={() => {
setDeleteJobPopout({ setDeleteJobPopout({
show: true, show: true,
data: value, data: { thePrice, ...value },
}); });
}} }}
> >
@@ -166,7 +152,7 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
onClick={() => { onClick={() => {
setEditJob({ setEditJob({
show: true, show: true,
data: value, data: { thePrice, ...value },
}); });
}} }}
> >
@@ -180,7 +166,7 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
<button <button
type="button" type="button"
onClick={() => { onClick={() => {
setJobPopout({ show: true, data: value }); setJobPopout({ show: true, data: { thePrice, ...value } });
}} }}
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white" className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
> >
@@ -188,18 +174,55 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
</button> </button>
</td> </td>
</tr> </tr>
)}) );
};
return (
<div
className={`update-table w-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow min-h-[520px] ${
className || ""
}`}
>
<div className="header w-full flex justify-between items-center mb-5">
<div className="flex space-x-2 items-center">
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">
All Jobs
</h1>
</div>
<SelectBox
action={handleSetCategory}
datas={Object.values(filterCategories)}
className="Update-table-dropdown"
contentBodyClasses="w-auto min-w-max"
/>
</div>
{MyJobList.loading ? (
<LoadingSpinner size="16" color="sky-blue" />
) : (
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between h-full">
<table className="table-auto min-w-full text-sm text-left text-gray-500 dark:text-gray-400">
<tbody>
<>
{MyJobList &&
MyJobList?.data?.result_list &&
MyJobList.data?.result_list.length > 0 ? (
filteredCurrentJobList?.length ? (
filteredCurrentJobList.map((value, index) => (
<JobListItem index={index} key={index} value={value} />
))
) : (
<tr className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
<td className="p-2">
No Jobs Available In This Category!
</td>
</tr>
)
) : ( ) : (
<tr className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap"> <tr className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
<td className="p-2">No Jobs Avaliable!</td> <td className="p-2">No Jobs Avaliable!</td>
</tr> </tr>
)} )}
</> </>
) : selectedCategory === "Explore" ? (
<></>
) : (
<></>
)}
</tbody> </tbody>
</table> </table>
@@ -209,11 +232,11 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
prev={currentPage == 0 ? true : false} prev={currentPage == 0 ? true : false}
next={ next={
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >= currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
MyJobList?.data?.result_list?.length currentJobList?.length
? true ? true
: false : false
} }
data={MyJobList?.data?.result_list} data={currentJobList}
start={indexOfFirstItem} start={indexOfFirstItem}
stop={indexOfLastItem} stop={indexOfLastItem}
/> />
@@ -257,6 +280,7 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
}} }}
situation={editJob.show} situation={editJob.show}
country={myCountry} country={myCountry}
categories={currentJobCart}
/> />
)} )}
</div> </div>
+9 -2
View File
@@ -1,5 +1,4 @@
import React, { useState } from "react"; import React, { useState } from "react";
import { Link } from "react-router-dom";
import Layout from "../Partials/Layout"; import Layout from "../Partials/Layout";
import MyJobTable from "./MyJobTable"; import MyJobTable from "./MyJobTable";
import CommonHead from "../UserHeader/CommonHead"; import CommonHead from "../UserHeader/CommonHead";
@@ -11,6 +10,8 @@ export default function MyJobs(props) {
setPopUp((prev) => !prev); setPopUp((prev) => !prev);
}; };
const categoryOptions = props.MyJobList?.data?.categories;
return ( return (
<Layout> <Layout>
<CommonHead commonHeadData={props.commonHeadData} /> <CommonHead commonHeadData={props.commonHeadData} />
@@ -36,7 +37,13 @@ export default function MyJobs(props) {
</div> </div>
{/* Add Job List Popout */} {/* Add Job List Popout */}
{popUp && <AddJobPage action={popUpHandler} situation={popUp} />} {popUp && (
<AddJobPage
action={popUpHandler}
situation={popUp}
categories={categoryOptions}
/>
)}
{/* End of Add Job List Popout */} {/* End of Add Job List Popout */}
</Layout> </Layout>
); );
+24 -8
View File
@@ -1,15 +1,18 @@
import React, {useState} from 'react' import React, {useState} from 'react'
import RecentActivityTable from './WalletComponent/RecentActivityTable' import RecentActivityTable from './WalletComponent/RecentActivityTable'
import LoadingSpinner from '../Spinners/LoadingSpinner' import LoadingSpinner from '../Spinners/LoadingSpinner'
import { useNavigate } from 'react-router-dom' import { useNavigate, useLocation } from 'react-router-dom'
import InputCom from '../Helpers/Inputs/InputCom' import InputCom from '../Helpers/Inputs/InputCom'
import AddFundDollars from './AddFundDollars'
function AddFund({payment}) { function AddFund({payment}) {
const navigate = useNavigate() const navigate = useNavigate()
const {currency} = useLocation()?.state //GETS THE USER CURRENCY FOR ADD FUND
//STATE FOR CONTROLLED INPUT //STATE FOR CONTROLLED INPUT
let [input, setInput] = useState('0') let [input, setInput] = useState('')
let [inputError, setInputError] = useState('') let [inputError, setInputError] = useState('')
@@ -23,15 +26,15 @@ function AddFund({payment}) {
setInputError('') setInputError('')
if(!input || input == '0'){ if(!input || input == '0'){
setInputError('Please Enter Amount') setInputError('Please Enter Amount')
return return setTimeout(()=>{setInputError('')}, 5000)
} }
if(isNaN(input)){ if(isNaN(input)){
setInputError('Amount must be a Number') setInputError('Amount must be a Number')
return return setTimeout(()=>{setInputError('')}, 5000)
} }
const stateData = {amount: Number(input)} const stateData = {amount: Number(input), currency: 'naira'}
navigate('confirm-add-fund', {state: stateData}) navigate('confirm-add-fund', {state: stateData})
setInput('') setInput('')
@@ -79,18 +82,27 @@ function AddFund({payment}) {
<div className="field w-full mb-6"> <div className="field w-full mb-6">
<InputCom <InputCom
fieldClass="px-6" fieldClass="px-6"
label="Amount(Naira)" label={currency == 'US Dollars' ? "Amount (USD)" : "Amount (Naira)"}
type="text" type="text"
name="amount" name="amount"
placeholder="Amount" placeholder="0"
value={input} value={input}
inputHandler={handleChange} inputHandler={handleChange}
// blurHandler={props.handleBlur}
/> />
{inputError && <p className='text-base text-red-500'>{inputError}</p>} {inputError && <p className='text-base text-red-500'>{inputError}</p>}
</div> </div>
</form> </form>
<hr /> <hr />
{/* SHOWS THIS IF USER CURRENCY IS DOLLARS */}
{currency == 'US Dollars' &&
<div className='w-full md:p-8 p-4 bg-white dark:bg-dark-white rounded-2xl shadow'>
<AddFundDollars setInputError={setInputError} input={input} setInput={setInput} />
</div>
}
{/* HIDES THIS BUTTON IF CURENCY IS NAIRA */}
{currency != 'US Dollars' &&
<div className='md:p-8 p-4 add-fund-btn flex justify-end items-center py-4'> <div className='md:p-8 p-4 add-fund-btn flex justify-end items-center py-4'>
<button <button
onClick={handleSubmit} onClick={handleSubmit}
@@ -100,10 +112,13 @@ function AddFund({payment}) {
<span className="text-white">Continue</span> <span className="text-white">Continue</span>
</button> </button>
</div> </div>
}
</div> </div>
</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="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">
<div className="wallet w-full md:p-8 p-4 h-full min-h-[590px] bg-white dark:bg-dark-white rounded-2xl shadow"> <div className="wallet w-full md:p-8 p-4 h-full min-h-[590px] bg-white dark:bg-dark-white rounded-2xl shadow">
@@ -117,6 +132,7 @@ function AddFund({payment}) {
</div> </div>
</div> </div>
</div> </div>
}
</div> </div>
) )
} }
+480
View File
@@ -0,0 +1,480 @@
import React,{useEffect, useState} from 'react'
import { useNavigate } from 'react-router-dom'
import InputCom from '../Helpers/Inputs/InputCom';
import PaginatedList from '../Pagination/PaginatedList';
import { handlePagingFunc } from '../Pagination/HandlePagination';
import LoadingSpinner from '../Spinners/LoadingSpinner';
import usersService from '../../services/UsersService';
import { Form, Formik } from "formik";
import * as Yup from "yup";
const validationSchema = Yup.object().shape({
name: Yup.string()
.min(3, "Minimum 3 characters")
.max(50, "Maximum 50 characters")
.required("Name is required"),
cardNum: Yup.string()
.min(3, "Minimum 3 characters")
.max(25, "Maximum 25 characters")
.required("Card Number is required"),
code: Yup.string()
.min(3, "Minimum 3 characters")
.max(25, "Maximum 25 characters")
.required("Postal Code is required"),
state: Yup.string()
.min(3, "Minimum 3 characters")
.max(25, "Maximum 25 characters")
.required("State is required"),
address: Yup.string()
.min(3, "Minimum 3 characters")
.max(50, "Maximum 50 characters")
.required("Address is required"),
expirationYear: Yup.string()
.min(4, "Minimum 4 characters")
.max(4, "Maximum 4 characters")
.required("Expiration Year is required"),
expirationMonth: Yup.string()
.min(1, "Minimum 1 characters")
.max(2, "Maximum 2 characters")
.required("Expiration Month is required"),
cvv: Yup.string()
.min(3, "Minimum 3 characters")
.max(4, "Maximum 4 characters")
.required("CVV Year is required"),
});
const initialValues = {
name: '',
cardNum: '',
code: '',
state: '',
address: '',
expirationYear: '',
expirationMonth: '',
cvv: ''
};
function AddFundDollars(props) {
const navigate = useNavigate()
let apiCall = new usersService()
let [tab, setTab] = useState("previous"); //STATE FOR SWITCHING BETWEEN TABS
let [prevCardDetails, setPrevCardDetails] = useState(null) // STATE TO HOLD PREVIOUS CARD SELECTED
let [payListCard, setPayListCard] = useState({loading: true, data:[]}) //USER PREVIOUS CARDS
const [currentPage, setCurrentPage] = useState(0);
const indexOfFirstItem = Number(currentPage);
const indexOfLastItem = Number(indexOfFirstItem)+Number(process.env.REACT_APP_ITEM_PER_PAGE);
const currentPreviousCards = payListCard?.data?.slice(indexOfFirstItem, indexOfLastItem);
const handlePagination = (e) => {
handlePagingFunc(e,setCurrentPage)
}
// FUNCTION TO SUBMIT
const handleSubmit = (values, helpers) => {
props.setInputError('')
if(!props.input || props.input == '0'){
props.setInputError('Please Enter Amount')
return setTimeout(()=>{props.setInputError('')}, 5000)
}
if(isNaN(props.input)){
props.setInputError('Amount must be a Number')
return setTimeout(()=>{props.setInputError('')}, 5000)
}
if(tab == 'previous'){
const stateData = {amount: Number(props.input), currency: 'dollars'}
navigate('confirm-add-fund', {state: stateData}) // State will change later dummy for now
}
if(tab == 'new'){
const stateData = {amount: Number(props.input), currency: 'dollars', ...values}
navigate('confirm-add-fund', {state: stateData}) // State will change later dummy for now
}
props.setInput('')
}
useEffect(()=>{
apiCall.payListCard().then(res => {
setPayListCard({loading: false, data: res.data.result_list})
}).catch(err => {
console.log('PAYCARDLIST ERROR', err)
setPayListCard({loading: false, data: []})
})
}, [])
return (
<>
<h1 className='mb-2 text-xl font-bold text-dark-gray dark:text-white'>Payment Method</h1>
<div className="w-full">
{/* switch button */}
<div className="my-1 flex items-center border-b border-slate-300">
<button
name="previous"
onClick={(e) => setTab(e.target.name)}
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border ${
tab == "previous" ? "border-sky-blue" : "border-slate-300"
} tracking-wide transition duration-200`}
>
Previous Cards
</button>
<button
name="new"
onClick={(e) => setTab(e.target.name)}
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border ${
tab == "new" ? "border-sky-blue" : "border-slate-300"
} tracking-wide transition duration-200`}
>
Add New Card
</button>
</div>
{/* END OF switch button */}
{/* previous tab */}
{tab == 'previous' ?
<div className="p-4 previous-details w-full border min-h-[300px] flex flex-col justify-between items-center">
{ payListCard.loading ?
<LoadingSpinner size='10' color='sky-blue' />
:
payListCard?.data?.length ?
<table className="my-3 w-full">
<tbody>
{currentPreviousCards.map((item, index)=>(
<tr key={index} className={index != 0 && 'border-t-2'}>
<td>
<div className='my-2 flex items-center gap-5'>
<input type="radio" className='w-8 h-8' name='card' value='value' />
<div className='card-details'>
<h1 className='text-lg font-bold text-dark-gray dark:text-white tracking-wide'>{item.description} Card</h1>
<p className='text-base font-bold text-dark-gray dark:text-white tracking-wide'>Bank **************{item.digits}</p>
<div className='w-full sm:flex items-center gap-5'>
<p className='text-base font-bold text-dark-gray dark:text-white tracking-wide'>{item.added}</p>
<p className='text-sm font-bold text-green-700 dark:text-white tracking-wide'>Verified</p>
</div>
</div>
</div>
</td>
<td>
<button
// onClick={handleSubmit}
type="button"
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
<span className="text-white">Manage</span>
</button>
</td>
</tr>
))
}
</tbody>
</table>
:
<div className='w-full flex flex-col items-center'>
<p className='my-5 text-base font-bold text-dark-gray dark:text-white tracking-wide'>No Previous Card Found!</p>
<button
onClick={()=> setTab('new')}
type="button"
className="my-5 px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
<span className="text-white">Add Card</span>
</button>
</div>
}
{/* PAGINATION BUTTON */}
<div className='w-full'>
<PaginatedList onClick={handlePagination} prev={currentPage == 0 ? true : false} next={currentPage+Number(process.env.REACT_APP_ITEM_PER_PAGE) >= payListCard?.data?.length ? true : false} data={payListCard?.data} start={indexOfFirstItem} stop={indexOfLastItem} />
</div>
{/* END OF PAGINATION BUTTON */}
</div>
:
<div className="new-details w-full min-h-[300px] border-t">
<div className="w-full flex flex-col justify-between">
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={handleSubmit}
>
{(props) => {
return (
<Form>
<div className="flex flex-col-reverse sm:flex-row">
<div className="flex-1 sm:mr-10">
<div className="fields w-full">
{/* inputs starts here */}
{/* Name */}
<div className="field w-full my-6">
<InputCom
fieldClass="px-6"
spanTag='*'
label="Name on Card"
type="text"
name="name"
placeholder="DUMMY NAME"
value={props.values.name}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{props.errors.name && props.touched.name && (
<p className="text-sm text-red-500">
{props.errors.name}
</p>
)}
</div>
{/* CARD NUMBER */}
<div className="field w-full mb-6">
<InputCom
fieldClass="px-6"
spanTag='*'
iconName='master-card visa-card atm-card'
label="Card Number"
type="text"
name="cardNum"
placeholder="Enter Card Number"
value={props.values.cardNum}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{props.errors.cardNum && props.touched.cardNum && (
<p className="text-sm text-red-500">
{props.errors.cardNum}
</p>
)}
</div>
{/* EXPIRE YEAR, YEAR AND CVV */}
<div className="sm:grid gap-5 grid-cols-3 mb-6">
<div className="field w-full mb-6 xl:mb-0 col-span-1">
<div className="select-option">
<div className={`flex items-center justify-between mb-2.5`}>
<label
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"
htmlFor='expiration'
>Expiration Month <span className="text-red-700 text-sm tracking-wide">*</span></label>
</div>
<div
className={`input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base`}
>
<select
className={`input-field placeholder:text-base text-dark-gray w-full h-full tracking-wide dark:bg-[#11131F] bg-[#f5f8fa] focus:ring-0 focus:outline-none`}
value={props.values.expirationMonth}
onChange={props.handleChange}
onBlur={props.handleBlur}
name='expirationMonth'
>
<option value=''>Select...</option>
{expireMonth?.length &&
expireMonth.map((item, index) => (
<option key={index} value={item.value}>{item.name}</option>
))
}
</select>
</div>
</div>
{props.errors.expirationMonth && props.touched.expirationMonth && (
<p className="text-sm text-red-500">
{props.errors.expirationMonth}
</p>
)}
</div>
<div className="field w-full mb-6 xl:mb-0 col-span-1">
<div className="select-option">
<div className={`flex items-center justify-between mb-2.5`}>
<label
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"
htmlFor='expiration'
>Expiration Year <span className="text-red-700 text-sm tracking-wide">*</span>
</label>
</div>
<div
className={`input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base`}
>
<select
className={`input-field placeholder:text-base text-dark-gray w-full h-full tracking-wide dark:bg-[#11131F] bg-[#f5f8fa] focus:ring-0 focus:outline-none`}
value={props.values.expirationYear}
onChange={props.handleChange}
onBlur={props.handleBlur}
name='expirationYear'
>
<option value=''>Select...</option>
{expireYear?.length &&
expireYear.map((item, index) => (
<option key={index} value={item}>{item}</option>
))
}
</select>
</div>
</div>
{props.errors.expirationYear && props.touched.expirationYear && (
<p className="text-sm text-red-500">
{props.errors.expirationYear}
</p>
)}
</div>
<div className="field w-full col-span-1">
<InputCom
fieldClass="px-6"
spanTag='*'
iconName='atm-card'
label="CVV"
type="text"
name="cvv"
placeholder="CVV"
value={props.values.cvv}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{props.errors.cvv && props.touched.cvv && (
<p className="text-sm text-red-500">
{props.errors.cvv}
</p>
)}
</div>
</div>
{/* Address */}
<div className="field w-full my-6">
<InputCom
fieldClass="px-6"
spanTag='*'
label="Billing Address"
type="text"
name="address"
placeholder="Billing Address"
value={props.values.Address}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{props.errors.address && props.touched.address && (
<p className="text-sm text-red-500">
{props.errors.address}
</p>
)}
</div>
{/* postal code and state */}
<div className="sm:grid gap-5 grid-cols-3 mb-6">
<div className="field w-full mb-6 xl:mb-0 col-span-1">
<InputCom
fieldClass="px-6"
spanTag='*'
label="Postal Code"
type="text"
name="code"
placeholder="Postal Code"
value={props.values.code}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{props.errors.code && props.touched.code && (
<p className="text-sm text-red-500">
{props.errors.code}
</p>
)}
</div>
<div className="field w-full col-span-1">
<InputCom
fieldClass="px-6"
spanTag='*'
label="State"
type="text"
name="state"
placeholder="State"
value={props.values.state}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{props.errors.state && props.touched.state && (
<p className="text-sm text-red-500">
{props.errors.state}
</p>
)}
</div>
</div>
</div>
</div>
</div>
{/* <div className="w-full">
{requestStatus.message != "" && (
<p
className={`text-center text-base ${
requestStatus.status ? "text-green-800" : "text-red-600"
}`}
>
{requestStatus.message}
</p>
)}
<div className="w-full h-[120px] border-t border-light-purple dark:border-[#5356fb29] flex justify-end items-center">
<div className="flex items-center space-x-4 mr-9">
<Link
to="/"
className="text-18 text-light-red tracking-wide "
>
<span className="border-b dark:border-[#5356fb29] border-light-red">
{" "}
Cancel
</span>
</Link>
{requestStatus.loading ? (
<LoadingSpinner size="8" color="sky-blue" />
) : (
<button
type="submit"
className="w-[152px] h-[46px] flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
Update Profile
</button>
)}
</div>
</div>
</div> */}
<div className='md:p-8 p-4 add-fund-btn flex justify-end items-center py-4'>
<button
type="submit"
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
<span className="text-white">Continue</span>
</button>
</div>
</Form>
);
}}
</Formik>
</div>
</div>
}
</div>
{ tab == 'previous' &&
<div className='md:p-8 p-4 add-fund-btn flex justify-end items-center py-4'>
<button
onClick={handleSubmit}
type="button"
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
<span className="text-white">Continue</span>
</button>
</div>
}
</>
)
}
export default AddFundDollars
// FORMS ARRAY OF EXPIRATION YEAR FOR CARD
const expireYear = []
let currentYear = new Date().getFullYear()
for(let i=0; i<=6; i++){
expireYear.push(currentYear + i)
}
// FORMS ARRAY OF EXPIRATION MONTH FOR CARD
let month = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
const expireMonth = []
for(let i=0; i<month.length; i++){
expireMonth.push({name:month[i], value:i+1})
}
+1 -1
View File
@@ -55,7 +55,7 @@ function Balance({wallet, coupon}) {
item.action_type != 'AC_AD_FD_ONLY' ? item.action_type != 'AC_AD_FD_ONLY' ?
<Link to='transfer-fund' className='px-2 py-1 flex items-center gap-2 user-balance cursor-pointer h-[48px] rounded-full relative bg-purple lg:text-xl text-lg font-bold text-white'>Transfer</Link>:'' <Link to='transfer-fund' className='px-2 py-1 flex items-center gap-2 user-balance cursor-pointer h-[48px] rounded-full relative bg-purple lg:text-xl text-lg font-bold text-white'>Transfer</Link>:''
} }
<Link to='add-fund' className='px-2 py-1 flex items-center gap-2 user-balance cursor-pointer h-[48px] rounded-full relative bg-green lg:text-xl text-lg font-bold text-white'> <Link to='add-fund' state={{currency:item.description}} className='px-2 py-1 flex items-center gap-2 user-balance cursor-pointer h-[48px] rounded-full relative bg-green lg:text-xl text-lg font-bold text-white'>
<span className=""> <span className="">
<svg xmlns="http://www.w3.org/2000/svg" width="38" <svg xmlns="http://www.w3.org/2000/svg" width="38"
height="38" viewBox="0 0 42 42" fill="none"><path height="38" viewBox="0 0 42 42" fill="none"><path
+14 -5
View File
@@ -50,7 +50,6 @@ function ConfirmAddFund({ payment }) {
toast.success("Account Topup was sucessful"); toast.success("Account Topup was sucessful");
setTimeout(() => { setTimeout(() => {
navigate("/my-wallet", { replace: true }); navigate("/my-wallet", { replace: true });
window.location.reload(true);
}, 1000); }, 1000);
}) })
.catch((err) => { .catch((err) => {
@@ -102,11 +101,11 @@ function ConfirmAddFund({ payment }) {
}, []); }, []);
return ( return (
<div className="content-wrapper w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin"> <div className="content-wrapper w-full">
{pageLoading ? ( {pageLoading ? (
<LoadingSpinner size="8" color="sky-blue" /> <LoadingSpinner size="8" color="sky-blue" />
) : ( ) : (
<div className="lg:w-1/2 w-full mb-10 lg:mb-0"> <div className="w-full mb-10">
<div className="add-fund w-full bg-white dark:bg-dark-white rounded-2xl shadow"> <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"> <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
@@ -116,7 +115,7 @@ function ConfirmAddFund({ payment }) {
<div className="field w-full mb-3"> <div className="field w-full mb-3">
<InputCom <InputCom
fieldClass="px-6" fieldClass="px-6"
label="Amount (Naira):" label={state.currency == 'naira' ? "Amount (Naira):" : "Amount (Dollars):"}
type="text" type="text"
name="amount" name="amount"
value={state.amount || ""} value={state.amount || ""}
@@ -127,16 +126,26 @@ function ConfirmAddFund({ payment }) {
<hr /> <hr />
<div className="md:p-8 p-4 add-fund-btn flex justify-end items-center py-4"> <div className="md:p-8 p-4 add-fund-btn flex justify-end items-center py-4">
{
state.currency == 'naira' ?
<FlutterWaveButton <FlutterWaveButton
{...fwConfig} {...fwConfig}
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white" 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> </div>
)} )}
<div className="lg:w-1/2 w-full mb-10 lg:mb-0"> <div className="w-full mb-10">
<div className="wallet w-full md:p-8 p-4 h-full min-h-[600px] bg-white dark:bg-dark-white rounded-2xl shadow"> <div className="wallet w-full md:p-8 p-4 h-full min-h-[600px] bg-white dark:bg-dark-white rounded-2xl shadow">
<h2 className="text-gray-900 dark:text-white text-xl lg:text-2xl font-medium"> <h2 className="text-gray-900 dark:text-white text-xl lg:text-2xl font-medium">
Recent Activity Recent Activity
@@ -15,11 +15,11 @@ function PurchasesTable({purchase}) {
} }
return ( return (
<div className='flex flex-col justify-between h-full'> <div className='flex flex-col justify-between min-h-[500px]'>
<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-4">Trx.</th> <th className="p-2">Trx.</th>
<th className="p-2">Amount</th> <th className="p-2">Amount</th>
<th className="p-2">Fee</th> <th className="p-2">Fee</th>
</tr> </tr>
@@ -29,7 +29,7 @@ function PurchasesTable({purchase}) {
<tbody> <tbody>
{currentPurchase.map((item, index) => ( {currentPurchase.map((item, index) => (
<tr key={index} className='text-slate-500'> <tr key={index} className='text-slate-500'>
<td className="p-4">{item.added_date}<br /> <td className="p-2">{item.added_date}<br />
<b>{item.confirmation} </b> <b>{item.confirmation} </b>
</td> </td>
<td className="p-2">{item.amount}</td> <td className="p-2">{item.amount}</td>
@@ -15,7 +15,7 @@ function RecentActivityTable({payment}) {
} }
return ( return (
<div className='flex flex-col justify-between h-full'> <div className='flex flex-col justify-between min-h-[500px]'>
<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'>
@@ -1,60 +1,73 @@
import React, {useState} from 'react' import { useState } from "react";
import PaginatedList from "../../Pagination/PaginatedList";
import PaginatedList from '../../Pagination/PaginatedList'; import { handlePagingFunc } from "../../Pagination/HandlePagination";
import {handlePagingFunc} from '../../Pagination/HandlePagination';
function ReferralTable({ history }) { function ReferralTable({ history }) {
const [currentPage, setCurrentPage] = useState(0); const [currentPage, setCurrentPage] = useState(0);
const indexOfFirstItem = Number(currentPage); const indexOfFirstItem = Number(currentPage);
const indexOfLastItem = Number(indexOfFirstItem)+Number(process.env.REACT_APP_ITEM_PER_PAGE); const indexOfLastItem =
const currentReferral = history?.data?.slice(indexOfFirstItem, indexOfLastItem); Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
const currentReferral = history?.data?.slice(
indexOfFirstItem,
indexOfLastItem
);
const handlePagination = (e) => { const handlePagination = (e) => {
handlePagingFunc(e,setCurrentPage) handlePagingFunc(e, setCurrentPage);
} };
return ( return (
<div className='flex flex-col justify-between min-h-[420px] overflow-x-auto'> <div className="flex flex-col justify-between min-h-[420px] overflow-x-auto">
<table className="referral-list w-full table-auto border-collapse text-left"> <table className="referral-list 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-3">Added/Name</th> <th className="p-3">Added/Name</th>
<th className="p-3">Email</th> <th className="p-3">Email</th>
<th className="p-3">Status</th> <th className="p-3">Status</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{history.data.length ? {history.data.length ? (
currentReferral.map((item, index) => ( currentReferral.map((item, index) => (
<tr key={index} className='text-slate-500'> <tr key={index} className="text-slate-500">
<td className="p-3">{item.added_date} / {item.firstname} {item.lastname}</td> <td className="p-3">
{item.added_date} / {item.firstname} {item.lastname}
</td>
<td className="p-3">{item.email}</td> <td className="p-3">{item.email}</td>
<td className="p-3">{item.status}</td> <td className="p-3">{item.status}</td>
</tr> </tr>
)) ))
: ) : history.error ? (
( <tr className="text-slate-500">
history.error ? <td colSpan={3}>
<tr className='text-slate-500'> Opps! couldn't get referral history. Try reloading the page
<td colSpan={3}>Opps! couldn't get referral history. Try reloading the page</td> </td>
</tr> </tr>
: ) : (
( <tr className="text-slate-500">
<tr className='text-slate-500'>
<td colSpan={3}>No Item Found on referral List</td> <td colSpan={3}>No Item Found on referral List</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) >= history?.data?.length ? true : false} data={history?.data} start={indexOfFirstItem} stop={indexOfLastItem} /> <PaginatedList
onClick={handlePagination}
prev={currentPage == 0 ? true : false}
next={
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
history?.data?.length
? true
: false
}
data={history?.data}
start={indexOfFirstItem}
stop={indexOfLastItem}
/>
{/* END OF PAGINATION BUTTON */} {/* END OF PAGINATION BUTTON */}
</div> </div>
) );
} }
export default ReferralTable export default ReferralTable;
@@ -48,12 +48,13 @@ export default function ManageInterestOffer(props) {
setRequestStatus({loading: false, status: false, message: 'Unable to complete request', processType: ''}) setRequestStatus({loading: false, status: false, message: 'Unable to complete request', processType: ''})
return return
} }
setInterval(() => { // SETS REDIRECT COUNT DOWN let intervalTime = setInterval(() => { // SETS REDIRECT COUNT DOWN
setRedirectTime(prev => prev - 1) setRedirectTime(prev => prev - 1)
}, 1000); }, 1000);
setRequestStatus({loading: false, status: true, message: `Offer ${name}ed`, processType: ''}) setRequestStatus({loading: false, status: true, message: `Offer ${name}ed`, processType: ''})
setTimeout(()=>{ setTimeout(()=>{
navigate('/offer-interest', {replace: true}) navigate('/offer-interest', {replace: true})
clearInterval(intervalTime)
},5000) },5000)
}).catch(err => { }).catch(err => {
setRequestStatus({loading: false, status: false, message: 'Opps! something went wrong. Try again', processType: ''}) setRequestStatus({loading: false, status: false, message: 'Opps! something went wrong. Try again', processType: ''})
+5 -5
View File
@@ -1,13 +1,13 @@
import React from 'react' import React from "react";
import Layout from '../Partials/Layout' import Layout from "../Partials/Layout";
import ReferralDisplay from './ReferralDisplay' import ReferralDisplay from "./ReferralDisplay";
function Referral() { function Referral() {
return ( return (
<Layout> <Layout>
<ReferralDisplay /> <ReferralDisplay />
</Layout> </Layout>
) );
} }
export default Referral export default Referral;
+28 -39
View File
@@ -1,5 +1,4 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { toast } from "react-toastify"; import { toast } from "react-toastify";
import usersService from "../../services/UsersService"; import usersService from "../../services/UsersService";
import InputCom from "../Helpers/Inputs/InputCom"; import InputCom from "../Helpers/Inputs/InputCom";
@@ -10,30 +9,29 @@ import * as Yup from "yup";
import ReferralTable from "../MyWallet/WalletComponent/ReferralTable"; import ReferralTable from "../MyWallet/WalletComponent/ReferralTable";
const validationSchema = Yup.object().shape({ const validationSchema = Yup.object().shape({
email: Yup.string() ref_email: Yup.string()
.email("Wrong email format") .email("Wrong 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"),
firstname: Yup.string() ref_firstname: Yup.string()
.min(3, "Minimum 3 characters") .min(3, "Minimum 3 characters")
.max(25, "Maximum 25 characters") .max(25, "Maximum 25 characters")
.required("Firstname is required"), .required("Firstname is required"),
lastname: Yup.string() ref_lastname: Yup.string()
.min(3, "Minimum 3 characters") .min(3, "Minimum 3 characters")
.max(25, "Maximum 25 characters") .max(25, "Maximum 25 characters")
.required("Lastname is required"), .required("Lastname is required"),
}); });
const initialValues = { const initialValues = {
firstname: "", ref_firstname: "",
lastname: "", ref_lastname: "",
email: "", ref_email: "",
}; };
function ReferralDisplay() { function ReferralDisplay() {
const apiCall = new usersService(); // GET API CALL const apiCall = new usersService(); // GET API CALL
const navigate = useNavigate();
let [refHistoryReload, setRefHistoryReload] = useState(false); // Determines when referral history reloads let [refHistoryReload, setRefHistoryReload] = useState(false); // Determines when referral history reloads
@@ -76,13 +74,13 @@ function ReferralDisplay() {
.then((res) => { .then((res) => {
if (res.data.internal_return < 0) { if (res.data.internal_return < 0) {
setError({ setError({
message: "Email already referred", message: res.data.status,
loading: false, loading: false,
status: false, status: false,
}); });
return; return;
} else { } else {
toast.success("Message Sent"); toast.success(res.data.status | "Message Sent!");
setError({ message: "", loading: false, status: true }); setError({ message: "", loading: false, status: true });
setRefHistoryReload((prev) => !prev); setRefHistoryReload((prev) => !prev);
} }
@@ -99,16 +97,7 @@ function ReferralDisplay() {
//FUNCTION TO HANDLE SUBMIT //FUNCTION TO HANDLE SUBMIT
const handleSubmit = (values, helpers) => { const handleSubmit = (values, helpers) => {
setError({ message: "", loading: true, status: false }); setError({ message: "", loading: true, status: false });
sendReferralMsg({...values}); // FUNCTION TO SEND REFERRAL MESSAGE
var postData = {
uid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
action: 11032,
...values,
};
sendReferralMsg(postData); // FUNCTION TO SEND REFERRAL MESSAGE
}; };
useEffect(() => { useEffect(() => {
@@ -121,12 +110,9 @@ function ReferralDisplay() {
<div className="sm:flex justify-between items-center mb-6"> <div className="sm:flex justify-between items-center mb-6">
<div className="mb-5 sm:mb-0"> <div className="mb-5 sm:mb-0">
<h1 className="text-26 font-bold inline-flex gap-3 text-dark-gray dark:text-white items-center"> <h1 className="text-26 font-bold inline-flex gap-3 text-dark-gray dark:text-white items-center">
<span> <span>Refer a Friend</span>
Refer a Friend
</span>
</h1> </h1>
</div> </div>
</div> </div>
<div className="referral w-full md:p-8 p-4 bg-white dark:bg-dark-white rounded-2xl shadow"> <div className="referral w-full md:p-8 p-4 bg-white dark:bg-dark-white rounded-2xl shadow">
@@ -147,15 +133,16 @@ function ReferralDisplay() {
fieldClass="px-6" fieldClass="px-6"
label="Firstname" label="Firstname"
type="text" type="text"
name="firstname" name="ref_firstname"
placeholder="Firstname" placeholder="Firstname"
value={props.values.firstname} value={props.values.ref_firstname}
inputHandler={props.handleChange} inputHandler={props.handleChange}
blurHandler={props.handleBlur} blurHandler={props.handleBlur}
/> />
{props.errors.firstname && props.touched.firstname && ( {props.errors.ref_firstname &&
props.touched.ref_firstname && (
<p className="text-sm text-red-500"> <p className="text-sm text-red-500">
{props.errors.firstname} {props.errors.ref_firstname}
</p> </p>
)} )}
</div> </div>
@@ -166,15 +153,16 @@ function ReferralDisplay() {
fieldClass="px-6" fieldClass="px-6"
label="Lastname" label="Lastname"
type="text" type="text"
name="lastname" name="ref_lastname"
placeholder="Lastname" placeholder="Lastname"
value={props.values.lastname} value={props.values.ref_lastname}
inputHandler={props.handleChange} inputHandler={props.handleChange}
blurHandler={props.handleBlur} blurHandler={props.handleBlur}
/> />
{props.errors.lastname && props.touched.lastname && ( {props.errors.ref_lastname &&
props.touched.ref_lastname && (
<p className="text-sm text-red-500"> <p className="text-sm text-red-500">
{props.errors.lastname} {props.errors.ref_lastname}
</p> </p>
)} )}
</div> </div>
@@ -185,14 +173,16 @@ function ReferralDisplay() {
fieldClass="px-6" fieldClass="px-6"
label="Email" label="Email"
type="text" type="text"
name="email" name="ref_email"
placeholder="Email" placeholder="Email"
value={props.values.email} value={props.values.ref_email}
inputHandler={props.handleChange} inputHandler={props.handleChange}
blurHandler={props.handleBlur} blurHandler={props.handleBlur}
/> />
{props.errors.email && props.touched.email && ( {props.errors.ref_email && props.touched.ref_email && (
<p className="text-sm text-red-500">{props.errors.email}</p> <p className="text-sm text-red-500">
{props.errors.ref_email}
</p>
)} )}
</div> </div>
@@ -206,7 +196,8 @@ function ReferralDisplay() {
) : ( ) : (
<button <button
type="submit" type="submit"
className="px-2 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white" > className="px-2 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
Send Message Send Message
</button> </button>
)} )}
@@ -227,8 +218,6 @@ function ReferralDisplay() {
)} )}
</div> </div>
</div> </div>
</div> </div>
); );
} }
+67 -46
View File
@@ -1,46 +1,65 @@
import React, { useState } from 'react' import React, { useState } from "react";
import ModalCom from '../Helpers/ModalCom' import ModalCom from "../Helpers/ModalCom";
import { useNavigate } from 'react-router-dom' import { useNavigate } from "react-router-dom";
import usersService from '../../services/UsersService' import usersService from "../../services/UsersService";
import LoadingSpinner from '../Spinners/LoadingSpinner' import LoadingSpinner from "../Spinners/LoadingSpinner";
import { useDispatch } from 'react-redux' import { useDispatch } from "react-redux";
import { tableReload } from '../../store/TableReloads' import { tableReload } from "../../store/TableReloads";
function DeleteJobPopout({ details, onClose, situation }) { function DeleteJobPopout({ details, onClose, situation }) {
let dispatch = useDispatch() let dispatch = useDispatch();
const navigate = useNavigate() const navigate = useNavigate();
const ApiCall = new usersService() const ApiCall = new usersService();
let [requestStatus, setRequestStatus] = useState({laoding: false, status:false, message: ''}) // STATE FOR KNOWING WHEN A REQUEST IS MADE TO THE SERVER let [requestStatus, setRequestStatus] = useState({
laoding: false,
status: false,
message: "",
}); // STATE FOR KNOWING WHEN A REQUEST IS MADE TO THE SERVER
// FUNCTION CALLED ONCE USER CONFIRM DELETE JOB // FUNCTION CALLED ONCE USER CONFIRM DELETE JOB
const deleteJob = (details) => { const deleteJob = (details) => {
setRequestStatus({laoding: true, status:false, message: ''}) setRequestStatus({ laoding: true, status: false, message: "" });
let reqData = { let reqData = {
job_id: details.job_id, job_id: details.job_id,
job_uid: details.job_uid job_uid: details.job_uid,
} // DATA NEEDED BY THE API }; // DATA NEEDED BY THE API
// API CALL TO DELETE A JOB // API CALL TO DELETE A JOB
ApiCall.deleteJob(reqData).then(res => { ApiCall.deleteJob(reqData)
.then((res) => {
if (res.data.internal_return < 0) { if (res.data.internal_return < 0) {
setRequestStatus({laoding: false, status:false, message: 'Could not perform the request, try again!'}) setRequestStatus({
return laoding: false,
status: false,
message: "Could not perform the request, try again!",
});
return;
} }
setRequestStatus({laoding: false, status:true, message: 'Job deleted successfully'}) setRequestStatus({
laoding: false,
status: true,
message: "Job deleted successfully",
});
setTimeout(() => { setTimeout(() => {
dispatch(tableReload({type:'JOBTABLE'})) dispatch(tableReload({ type: "JOBTABLE" }));
navigate('/myjobs', {replace: true}) navigate("/myjobs", { replace: true });
onClose() onClose();
}, 1000) }, 1000);
}).catch(error => {
setRequestStatus({laoding: false, status:false, message: 'Opps! something went wrong, try again'})
}).finally(()=>{
setTimeout(()=>{
setRequestStatus({laoding: false, status:false, message: ''})
}, 5000)
}) })
} .catch((error) => {
setRequestStatus({
laoding: false,
status: false,
message: "Opps! something went wrong, try again",
});
})
.finally(() => {
setTimeout(() => {
setRequestStatus({ laoding: false, status: false, message: "" });
}, 5000);
});
};
return ( return (
<ModalCom action={onClose} situation={situation}> <ModalCom action={onClose} situation={situation}>
@@ -100,7 +119,7 @@ function DeleteJobPopout({details, onClose, situation}) {
{details.title} {details.title}
</p> </p>
<p className="text-lg tracking-wide text-dark-gray dark:text-white"> <p className="text-lg tracking-wide text-dark-gray dark:text-white">
Price: {details.price * 0.01} Price: {details.thePrice}
</p> </p>
<p className="text-lg tracking-wide text-dark-gray dark:text-white"> <p className="text-lg tracking-wide text-dark-gray dark:text-white">
Duration: {details.timeline_days} day(s) Duration: {details.timeline_days} day(s)
@@ -114,9 +133,9 @@ function DeleteJobPopout({details, onClose, situation}) {
> >
<span className="text-gradient">Cancel</span> <span className="text-gradient">Cancel</span>
</button> </button>
{requestStatus.laoding ? {requestStatus.laoding ? (
<LoadingSpinner size='8' color='sky-blue' /> <LoadingSpinner size="8" color="sky-blue" />
: ) : (
<button <button
onClick={() => deleteJob(details)} onClick={() => deleteJob(details)}
type="button" type="button"
@@ -124,29 +143,31 @@ function DeleteJobPopout({details, onClose, situation}) {
> >
Confirm Delete Confirm Delete
</button> </button>
} )}
</div> </div>
{/* ERROR DISPLAY AND SUBMIT BUTTON */} {/* ERROR DISPLAY AND SUBMIT BUTTON */}
{requestStatus.message != "" && ( {requestStatus.message != "" &&
!requestStatus.status ? (!requestStatus.status ? (
(<div className={`relative p-4 my-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}> <div
className={`relative p-4 my-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
>
{requestStatus.message} {requestStatus.message}
</div>) </div>
: ) : (
requestStatus.status && requestStatus.status && (
(<div className={`relative p-4 my-4 text-green-700 bg-slate-200 border-slate-800 mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}> <div
className={`relative p-4 my-4 text-green-700 bg-slate-200 border-slate-800 mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
>
{requestStatus.message} {requestStatus.message}
</div> </div>
) )
)} ))}
{/* End of error or success display */} {/* End of error or success display */}
</div> </div>
</div> </div>
</ModalCom> </ModalCom>
) );
} }
export default DeleteJobPopout export default DeleteJobPopout;
+64 -43
View File
@@ -1,4 +1,4 @@
import React, { useCallback, useEffect, useMemo, useState } from "react"; import React, { useCallback, useMemo, useState } from "react";
import ModalCom from "../Helpers/ModalCom"; import ModalCom from "../Helpers/ModalCom";
import { Field, Form, Formik } from "formik"; import { Field, Form, Formik } from "formik";
import * as Yup from "yup"; import * as Yup from "yup";
@@ -6,13 +6,17 @@ import InputCom from "../Helpers/Inputs/InputCom";
import LoadingSpinner from "../Spinners/LoadingSpinner"; import LoadingSpinner from "../Spinners/LoadingSpinner";
import usersService from "../../services/UsersService"; import usersService from "../../services/UsersService";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { tableReload } from "../../store/TableReloads"; import { tableReload } from "../../store/TableReloads";
import { useDispatch } from "react-redux"; import { useDispatch } from "react-redux";
const EditJobPopOut = ({ details, onClose, situation, country }) => { const EditJobPopOut = ({
details,
const dispatch = useDispatch() onClose,
situation,
country,
categories,
}) => {
const dispatch = useDispatch();
let [requestStatus, setRequestStatus] = useState({ let [requestStatus, setRequestStatus] = useState({
loading: false, loading: false,
@@ -55,27 +59,31 @@ const EditJobPopOut = ({ details, onClose, situation, country }) => {
description: details?.description, description: details?.description,
job_detail: details?.job_detail, job_detail: details?.job_detail,
timeline_days: details?.timeline_days, timeline_days: details?.timeline_days,
category: details?.category
}; };
console.log("This is the init values for edit job",initialValues)
const jobApi = useMemo(() => new usersService(), []); const jobApi = useMemo(() => new usersService(), []);
const navigate = useNavigate(); const navigate = useNavigate();
const handleEditJob = useCallback( const handleEditJob = useCallback(
async (values) => { async (values) => {
values.category = values.category?.join("@");
setRequestStatus({ loading: true, message: "" }); setRequestStatus({ loading: true, message: "" });
let reqData = { let reqData = {
job_id: details.job_id, job_id: details.job_id,
job_uid: details.job_uid, job_uid: details.job_uid,
...values, ...values,
}; };
delete reqData?.country delete reqData?.country;
try { try {
let res = await jobApi.jobManagerUpdateJob(reqData); let res = await jobApi.jobManagerUpdateJob(reqData);
let { data } = await res; let { data } = await res;
if (data?.internal_return < 0) return; if (data?.internal_return < 0) return;
setRequestStatus({ loading: false, message: null }); setRequestStatus({ loading: false, message: null });
setTimeout(() => { setTimeout(() => {
dispatch(tableReload({type:'JOBTABLE'})) dispatch(tableReload({ type: "JOBTABLE" }));
navigate("/myjobs", { replace: true }); navigate("/myjobs", { replace: true });
onClose(); onClose();
}, 1000); }, 1000);
@@ -130,7 +138,7 @@ const EditJobPopOut = ({ details, onClose, situation, country }) => {
<Form className="w-full"> <Form className="w-full">
<div className="flex flex-col-reverse sm:flex-row"> <div className="flex flex-col-reverse sm:flex-row">
<div className="fields w-full"> <div className="fields w-full">
<div className="xl:flex xl:space-x-7 mb-6"> <div className="xl:flex xl:space-x-7 mb-[0.5rem]">
<div className="field w-full mb-6 xl:mb-0"> <div className="field w-full mb-6 xl:mb-0">
<InputCom <InputCom
fieldClass="px-6 cursor-default" fieldClass="px-6 cursor-default"
@@ -145,11 +153,6 @@ const EditJobPopOut = ({ details, onClose, situation, country }) => {
blurHandler={props.handleBlur} blurHandler={props.handleBlur}
disable={true} disable={true}
/> />
{props.errors.country && props.touched.country && (
<p className="text-sm text-red-500">
{props.errors.country}
</p>
)}
</div> </div>
{/* Price */} {/* Price */}
@@ -162,20 +165,17 @@ const EditJobPopOut = ({ details, onClose, situation, country }) => {
inputClass="input-curve lg border border-light-purple" inputClass="input-curve lg border border-light-purple"
type="number" type="number"
name="price" name="price"
// placeholder="Please Enter Amount"
value={props.values.price * 0.01} value={props.values.price * 0.01}
inputHandler={props.handleChange} inputHandler={props.handleChange}
blurHandler={props.handleBlur} blurHandler={props.handleBlur}
errorBorder={
props.errors.price && props.touched.price
}
/> />
{props.errors.price && props.touched.price && (
<p className="text-sm text-red-500">
{props.errors.price}
</p>
)}
</div> </div>
</div> </div>
{/* Title */} {/* Title */}
<div className="field w-full mb-6"> <div className="field w-full mb-[0.5rem]">
<InputCom <InputCom
fieldClass="px-6" fieldClass="px-6"
label="Title" label="Title"
@@ -184,20 +184,15 @@ const EditJobPopOut = ({ details, onClose, situation, country }) => {
inputClass=" input-curve lg border border-light-purple" inputClass=" input-curve lg border border-light-purple"
type="text" type="text"
name="title" name="title"
// placeholder="Enter Job Title"
value={props.values.title} value={props.values.title}
inputHandler={props.handleChange} inputHandler={props.handleChange}
blurHandler={props.handleBlur} blurHandler={props.handleBlur}
errorBorder={props.errors.title && props.touched.title}
/> />
{props.errors.title && props.touched.title && (
<p className="text-sm text-red-500">
{props.errors.title}
</p>
)}
</div> </div>
{/* Description */} {/* Description */}
<div className="field w-full mb-6"> <div className="field w-full mb-[0.5rem]">
<InputCom <InputCom
fieldClass="px-6" fieldClass="px-6"
label="Description" label="Description"
@@ -206,24 +201,21 @@ const EditJobPopOut = ({ details, onClose, situation, country }) => {
inputClass=" input-curve lg border border-light-purple" inputClass=" input-curve lg border border-light-purple"
type="text" type="text"
name="description" name="description"
// placeholder="Enter a description"
value={props.values.description} value={props.values.description}
inputHandler={props.handleChange} inputHandler={props.handleChange}
blurHandler={props.handleBlur} blurHandler={props.handleBlur}
errorBorder={
props.errors.description && props.touched.description
}
/> />
{props.errors.description &&
props.touched.description && (
<p className="text-sm text-red-500">
{props.errors.description}
</p>
)}
</div> </div>
{/* Details */} {/* Details */}
<div className="field w-full mb-6"> <div className="field flex flex-col sm:flex-row w-full mb-[5px] gap-2">
<div className="sm:w-[60%] w-full">
<label <label
htmlFor="Job Delivery Details" htmlFor="Job Delivery Details"
className='className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block mb-3' className='className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"'
> >
Job Delivery Details Job Delivery Details
</label> </label>
@@ -237,15 +229,50 @@ const EditJobPopOut = ({ details, onClose, situation, country }) => {
onChange={props.handleChange} onChange={props.handleChange}
onBlur={props.handleBlur} onBlur={props.handleBlur}
/> />
</div>
<div className="sm:w-[35%] w-full">
<div
htmlFor="Job Categories"
className='className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"'
id="checked-group"
>
Categories
</div>
<div
className="sm:flex-col flex flex-wrap px-3 mt-3"
role="group"
aria-labelledby="checked-group"
>
{Object.entries(categories).map(([key, value]) => (
<label
key={key}
className="flex gap-1 w-full items-center"
>
<Field
type="checkbox"
name="category"
value={key}
/>
<span className="text-[13.975px]">{value}</span>
</label>
))}
</div>
</div>
{/* <div className={`${!props.errors && "invisible"} h-5`}>
{props.errors.job_detail && props.touched.job_detail && ( {props.errors.job_detail && props.touched.job_detail && (
<p className="text-sm text-red-500"> <p className="text-sm text-red-500">
{props.errors.job_detail} {props.errors.job_detail}
</p> </p>
)} )}
</div> */}
</div> </div>
<div className="field w-full mb-6"> <div className="field w-full mb-6">
<div className={`flex items-center justify-between mb-2.5`}> <div
className={`flex items-center justify-between mb-2.5`}
>
<label <label
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block" className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"
htmlFor="timeline_days" htmlFor="timeline_days"
@@ -273,12 +300,6 @@ const EditJobPopOut = ({ details, onClose, situation, country }) => {
</option> </option>
))} ))}
</Field> </Field>
{props.errors.timeline_days &&
props.touched.timeline_days && (
<p className="text-sm text-red-500">
{props.errors.timeline_days}
</p>
)}
</div> </div>
{/* inputs ends here */} {/* inputs ends here */}
</div> </div>
+2 -2
View File
@@ -3,7 +3,7 @@ import Detail from "./popoutcomponent/Detail";
import ModalCom from "../Helpers/ModalCom"; import ModalCom from "../Helpers/ModalCom";
import InputCom from "../Helpers/Inputs/InputCom/index"; import InputCom from "../Helpers/Inputs/InputCom/index";
import SiteService from "../../services/SiteService"; import SiteService from "../../services/SiteService";
import { Form, Formik, Field, ErrorMessage } from "formik"; import { Form, Formik, Field } from "formik";
import * as Yup from "yup"; import * as Yup from "yup";
import LoadingSpinner from "../Spinners/LoadingSpinner"; import LoadingSpinner from "../Spinners/LoadingSpinner";
@@ -210,7 +210,7 @@ function JobListPopout({ details, onClose, situation }) {
</div> </div>
<div className="my-3 md:flex"> <div className="my-3 md:flex">
<Detail label="Price" value={`${details.price * 0.01} Naira`} /> <Detail label="Price" value={details.thePrice} />
</div> </div>
<div className="my-3 md:flex"> <div className="my-3 md:flex">
+27 -2
View File
@@ -51,8 +51,11 @@
font-weight: bolder; font-weight: bolder;
} }
.siderCardDescription{ .siderCardDescription{
margin: 20px 45px 10px 45px; margin: 10px 45px 10px 45px;
font-size: 20px; font-size: 18px;
background-color: aliceblue;
padding: 5px;
border-radius: 5px;
} }
.siderCardButton{ .siderCardButton{
margin-top: 10px; margin-top: 10px;
@@ -898,3 +901,25 @@ TODO: Responsive ===========================
top: 30px; top: 30px;
height: 55rem !important; height: 55rem !important;
} }
@keyframes shake {
0% {
transform: translateX(0);
}
25% {
transform: translateX(-5px);
}
50% {
transform: translateX(5px);
}
75% {
transform: translateX(-5px);
}
100% {
transform: translateX(0);
}
}
.ebu-animate-shake {
animation: shake 0.3s linear 3;
}
+18 -1
View File
@@ -444,7 +444,14 @@ class usersService {
//END POINT CALL FOR SENDING REFERRAL MESSAGE //END POINT CALL FOR SENDING REFERRAL MESSAGE
sendReferralMsg(postData) { sendReferralMsg(postData) {
return this.postAuxEnd("/sendreferral", postData); var reqData = {
uid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
action: 11032,
...postData
}
return this.postAuxEnd("/sendreferral", reqData);
} }
StartResetPassword(reqData) { StartResetPassword(reqData) {
@@ -712,6 +719,16 @@ class usersService {
return this.postAuxEnd("/faq", postData); return this.postAuxEnd("/faq", postData);
} }
// END POINT TO GET LIST OF USER PREVIOUS CARDS
payListCard() {
var postData = {
uid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
action: 11055
};
return this.postAuxEnd("/paylistcard", postData);
}
/* /*
- 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(username) - 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(username)
- 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(password) - 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(password)
+4 -4
View File
@@ -2,10 +2,10 @@ import React from "react";
import AddJob from "../components/AddJob/AddJob"; import AddJob from "../components/AddJob/AddJob";
import ModalCom from "../components/Helpers/ModalCom"; import ModalCom from "../components/Helpers/ModalCom";
function AddJobPage({ action, situation }) { function AddJobPage({ action, situation, categories }) {
return ( return (
<ModalCom action={action} situation={situation} className="addJob-popup"> <ModalCom action={action} situation={situation} className="edit-popup">
<div className="lg:w-[600px] w-full h-full lg:overflow-hidden lg:rounded-2xl bg-white dark:bg-dark-white "> <div className="lg:w-[600px] w-full lg:overflow-hidden lg:rounded-2xl bg-white dark:bg-dark-white ">
<div className="heading flex justify-between items-center py-6 md:px-[30px] px-[23px] border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] "> <div className="heading flex justify-between items-center py-6 md:px-[30px] px-[23px] border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] ">
<p className="text-26 font-bold text-dark-gray dark:text-white tracking-wide"> <p className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
Create New Job Create New Job
@@ -31,7 +31,7 @@ function AddJobPage({ action, situation }) {
</svg> </svg>
</button> </button>
</div> </div>
<AddJob popUpHandler={action} /> <AddJob popUpHandler={action} categories={categories} />
</div> </div>
</ModalCom> </ModalCom>
); );
+2
View File
@@ -4,6 +4,8 @@ import { useSelector } from "react-redux";
export default function MyJobsPage() { export default function MyJobsPage() {
let { commonHeadBanner } = useSelector((state) => state.commonHeadBanner); let { commonHeadBanner } = useSelector((state) => state.commonHeadBanner);
const { userJobList } = useSelector((state) => state.userJobList); const { userJobList } = useSelector((state) => state.userJobList);
return ( return (
<> <>
<MyJobs <MyJobs
+4 -4
View File
@@ -1,12 +1,12 @@
import React from 'react' import React from "react";
import Referral from '../components/Referral/Index' import Referral from "../components/Referral/Index";
function ReferralPage() { function ReferralPage() {
return ( return (
<> <>
<Referral /> <Referral />
</> </>
) );
} }
export default ReferralPage export default ReferralPage;