Compare commits

..

39 Commits

Author SHA1 Message Date
Ebube 5769332e74 . 2023-06-22 08:42:42 +01:00
ameye bab0296f4f Merge branch 'offer-interest-format' of WrenchBoard/Users-Wrench into master 2023-06-21 15:06:12 +00:00
victorAnumudu d457550d58 offer interest page formatted 2023-06-21 15:58:40 +01:00
ameye f106e17ce6 Merge branch 'market-toggle-position' of WrenchBoard/Users-Wrench into master 2023-06-21 10:52:13 +00:00
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
38 changed files with 1548 additions and 747 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_USERS_ENDPOINT="http://10.20.30.32:9083/svs/user"
REACT_APP_AUX_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/svs/user"
REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/svs/user"
#REACT_APP_AUX_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/svs/user"
#REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/svs/user"
#REACT_APP_AUX_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
#REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
REACT_APP_AUX_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
#"https://devapi.mermsemr.com/en/desktop/api/v2/myfituser"
+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_USERS_ENDPOINT="http://10.20.30.32:9083/svs/user"
REACT_APP_AUX_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/svs/user"
REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/svs/user"
# REACT_APP_AUX_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/svs/user"
# REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/svs/user"
#REACT_APP_AUX_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
#REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
REACT_APP_AUX_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
#"https://devapi.mermsemr.com/en/desktop/api/v2/myfituser"
+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_USERS_ENDPOINT="http://10.20.30.32:9083/svs/user"
REACT_APP_AUX_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/svs/user"
REACT_APP_USERS_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/svs/user"
#REACT_APP_AUX_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/svs/user"
#REACT_APP_USERS_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/svs/user"
#REACT_APP_AUX_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/en/wrench/api/v1"
#REACT_APP_USERS_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/en/wrench/api/v1"
REACT_APP_AUX_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/en/wrench/api/v1"
REACT_APP_USERS_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/en/wrench/api/v1"
#"https://devapi.mermsemr.com/en/desktop/api/v2/myfituser"
+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

+71 -61
View File
@@ -3,11 +3,8 @@ import { Link } from "react-router-dom";
import InputCom from "../Helpers/Inputs/InputCom";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import usersService from "../../services/UsersService";
import { useSelector, useDispatch } from "react-redux";
import { tableReload } from "../../store/TableReloads";
import { Field, Form, Formik } from "formik";
import * as Yup from "yup";
@@ -36,9 +33,10 @@ const validationSchema = Yup.object().shape({
.typeError("you must specify a number")
.min(1, "Price must be greater than 0")
.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();
let dispatch = useDispatch();
@@ -58,6 +56,7 @@ function AddJob({ popUpHandler }) {
description: "",
job_detail: "",
timeline_days: "",
category: [],
};
let [requestStatus, setRequestStatus] = useState({
@@ -88,6 +87,7 @@ function AddJob({ popUpHandler }) {
// FUNCTION TO HANDLE ADD JOB FORM
const handleAddJob = (values, helpers) => {
values.category = values.category?.join("@");
setRequestStatus({ loading: true, status: false, message: "" });
ApiCall.jobManagerCreateJob(values)
.then((res) => {
@@ -106,7 +106,7 @@ function AddJob({ popUpHandler }) {
});
setTimeout(() => {
dispatch(tableReload({ type: "JOBTABLE" }));
popUpHandler()
popUpHandler();
}, 1000);
})
.catch((err) => {
@@ -127,6 +127,7 @@ function AddJob({ popUpHandler }) {
getUserCountry();
}, []);
return (
<div className="add-job p-5 w-full bg-white rounded-md flex flex-col justify-between">
<Formik
@@ -141,7 +142,7 @@ function AddJob({ popUpHandler }) {
<div className="fields w-full">
{/* inputs starts here */}
{/* 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">
<label
htmlFor="country"
@@ -187,11 +188,6 @@ function AddJob({ popUpHandler }) {
</option>
)}
</select>
{props.errors.country && props.touched.country && (
<p className="text-sm text-red-500">
{props.errors.country}
</p>
)}
</div>
{/* Price */}
@@ -207,18 +203,14 @@ function AddJob({ popUpHandler }) {
value={props.values.price}
inputHandler={props.handleChange}
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>
{/* Title */}
<div className="field w-full mb-6">
<div className="field w-full mb-[5px]">
<InputCom
fieldClass="px-6"
label="Title"
@@ -226,20 +218,15 @@ function AddJob({ popUpHandler }) {
inputBg="bg-slate-100"
type="text"
name="title"
// placeholder="Enter Job Title"
value={props.values.title}
inputHandler={props.handleChange}
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>
{/* Description */}
<div className="field w-full mb-6">
<div className="field w-full mb-[5px]">
<InputCom
fieldClass="px-6"
label="Description"
@@ -247,44 +234,70 @@ function AddJob({ popUpHandler }) {
inputBg="bg-slate-100"
type="text"
name="description"
// placeholder="Enter a description"
value={props.values.description}
inputHandler={props.handleChange}
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>
{/* Details */}
<div className="field w-full mb-6">
<label
htmlFor="Job Delivery Details"
className='className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"'
>
Job Delivery Details
</label>
<textarea
id="Job Delivery Details"
rows="7"
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`}
style={{ resize: "none" }}
name="job_detail"
value={props.values.job_detail}
onChange={props.handleChange}
onBlur={props.handleBlur}
/>
{props.errors.job_detail && props.touched.job_detail && (
<p className="text-sm text-red-500">
{props.errors.job_detail}
</p>
)}
<div className="field flex flex-col sm:flex-row w-full mb-[5px] gap-2">
<div className="sm:w-[60%] w-full">
<label
htmlFor="Job Delivery Details"
className='className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"'
>
Job Delivery Details
</label>
<textarea
id="Job Delivery Details"
rows="5"
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" }}
name="job_detail"
value={props.values.job_detail}
onChange={props.handleChange}
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 && (
<p className="text-sm text-red-500">
{props.errors.job_detail}
</p>
)}
</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`}>
<label
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>
))}
</Field>
{props.errors.timeline_days &&
props.touched.timeline_days && (
<p className="text-sm text-red-500">
{props.errors.timeline_days}
</p>
)}
</div>
{/* inputs ends here */}
</div>
@@ -345,13 +352,16 @@ function AddJob({ popUpHandler }) {
))}
{/* 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">
<Link
to="/myjobs"
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
</span>
+105 -32
View File
@@ -1,57 +1,57 @@
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { Link, useNavigate, } from "react-router-dom";
import { toast } from "react-toastify";
import localImgLoad from "../../lib/localImgLoad";
import Icons from "../Helpers/Icons";
import { useCallback, useEffect, useMemo, useState } from "react";
import { Link, useNavigate } from "react-router-dom";
import MarketPopUp from "../MarketPlace/PopUp/MarketPopUp";
import usersService from "../../services/UsersService";
import { PriceFormatter } from "../Helpers/PriceFormatter";
import dataImage2 from "../../assets/images/data-table-user-2.png";
export default function AvailableJobsCard({
className,
datas,
hidden = false,
contentDisplay
}) {
//debugger;
const [addFavorite, setValue] = useState(datas.whishlisted);
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 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 reqData = { offer_code };
try {
const manageInt = await apiCall.MarketInterest(reqData);
const manageIntRes = await manageInt?.data;
setManageInt(manageIntRes)
setManageInt(manageIntRes);
} 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(() => {
if (!datas) {
navigate("/market", { replace: true });
}
marketInterestData()
}, [marketInterestData, datas])
marketInterestData();
}, []);
useEffect(() => {
const imagePath = require(`../../assets/images/${datas.thumbnil}`); // Replace with your directory path for local images
setImageUrl(imagePath);
}, []);
return (
<>
{contentDisplay == 'grid' ?
<div
className={`card-style-two w-full h-[426px] p-[20px] bg-white dark:bg-dark-white rounded-2xl section-shadow ${
className || ""
@@ -87,11 +87,9 @@ export default function AvailableJobsCard({
</div>
<div className="thumbnail-area w-full">
<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={{
background: `url(${localImgLoad(
`images/${datas.thumbnil}`
)}) 0% 0% / cover no-repeat`,
backgroundImage: `url('${imageUrl}')`,
}}
>
<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>
<p className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white">
{datas.price * 0.01}
{datas.currency} | {datas.timeline_days} day(s)
{/* {thePrice} | {datas.timeline_days} day(s) */}
{thePrice}
</p>
<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>
</div>
</div>
@@ -137,7 +138,7 @@ export default function AvailableJobsCard({
type="button"
className="px-4 py-2.5 text-white text-sm bg-pink rounded-full tracking-wide"
onClick={() => {
setMarketPopUp({show: true, data: datas})
setMarketPopUp({ show: true, data: datas });
}}
>
View
@@ -147,6 +148,78 @@ export default function AvailableJobsCard({
</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
details={datas}
@@ -9,7 +9,6 @@ export default function HomeBannerOffersCard(props) {
let { banner, banner_location } = props?.itemData;
if (banner_location === "LOCAL") {
const imagePath = require(`../../assets/images/${banner}`); // Replace with your directory path for local images
console.log("This is local");
setImageUrl(imagePath);
} else if (banner_location === "URL") setImageUrl(banner);
else return null;
@@ -30,7 +29,6 @@ export default function HomeBannerOffersCard(props) {
<span className="heroSilderTitle">{props.itemData.title}</span>
</h1>
</div>
{/*<SelectBox datas={filterDatas} action={dataSetHandler} />*/}
</div>
<div className="h-[233px]">
<div className="siderCardDescription">
+10
View File
@@ -1,5 +1,9 @@
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 }) {
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"
></path>
</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,
spanTag,
inputBg,
direction
direction,
errorBorder
}) {
const inputRef = useRef(null);
// Entry Validation
@@ -51,11 +52,16 @@ export default function InputCom({
htmlFor={name}
>
{label}
{spanTag && (
{spanTag &&
spanTag == '*' ?
<span className="text-red-700 text-sm tracking-wide">
{' '}{spanTag}
</span>
:
<span className="text-green-700 text-sm tracking-wide">
{spanTag}
</span>
)}
}
</label>
)}
{forgotPassword && (
@@ -68,7 +74,7 @@ export default function InputCom({
)}
</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
placeholder={placeholder}
@@ -89,8 +95,12 @@ export default function InputCom({
dir={direction}
/>
{iconName && (
<div className="absolute right-6 bottom-[10px] z-10">
<Icons name={iconName} />
<div className="absolute right-6 bottom-[10px] z-10 flex gap-2">
{
iconName.split(' ').map((item, index)=>(
<Icons key={index} name={item} />
))
}
</div>
)}
{passIcon && (
+2 -2
View File
@@ -1,7 +1,7 @@
import React, { useState } from "react";
import useToggle from "../../../hooks/useToggle";
function SelectBox({ datas = [], className, action, contentBodyClasses }) {
function SelectBox({ datas = [], className, action, contentBodyClasses, position }) {
const [item, setItem] = useState(datas[0]);
// custom hook
const [toggle, setToggle] = useToggle(false);
@@ -49,7 +49,7 @@ function SelectBox({ datas = [], className, action, contentBodyClasses }) {
<div
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" : ""
} ${contentBodyClasses || ""}`}
>
+52 -26
View File
@@ -13,7 +13,9 @@ import LoadingSpinner from "../Spinners/LoadingSpinner";
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
loading: true,
@@ -63,7 +65,7 @@ export default function History() {
<>
<Layout>
<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="mb-5 sm:mb-0">
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
@@ -213,33 +215,57 @@ export default function History() {
{/*</div>*/}
{/*<MarketHistorySection />*/}
{/* <TopHxBox className="mb-11" /> */}
<div className='w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin'>
{/* PURCHASE SECTION */}
<div className="lg:w-1/2 w-full mb-10 lg:mb-0">
<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">
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">Purchases</h1>
{purchaseHistory.loading ?
<LoadingSpinner size='16' color='sky-blue' />
:
<PurchasesTable purchase={purchaseHistory} />
}
</div>
<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 PURCHASE SECTION */}
{/* RECENT ACTIVITY SECTION */}
<div className="lg:w-1/2 w-full mb-10 lg:mb-0">
<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">
<h1 className="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> */}
{paymentHistory.loading ?
<LoadingSpinner size='16' color='sky-blue' />
:
<RecentActivityTable payment={paymentHistory} />
{/* END OF switch button */}
<div className="history-tables w-full">
{/* PURCHASE SECTION */}
{tab == 'purchases' &&
<div className="wallet w-full border-t">
<h1 className="p-2 text-xl font-bold text-dark-gray dark:text-white tracking-wide">Purchases</h1>
{purchaseHistory.loading ?
<LoadingSpinner size='16' color='sky-blue' />
:
<PurchasesTable purchase={purchaseHistory} />
}
</div>
}
</div>
{/* END OF PURCHASE SECTION */}
{/* RECENT ACTIVITY SECTION */}
{tab == 'recent' &&
<div className="wallet w-full border-t">
<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> */}
{paymentHistory.loading ?
<LoadingSpinner size='16' color='sky-blue' />
:
<RecentActivityTable payment={paymentHistory} />
}
</div>
}
{/* END OF RECENT ACTIVITY SECTION */}
</div>
{/* END OF RECENT ACTIVITY SECTION */}
</div>
{/*<HistoryTable />*/}
</div>
+81 -82
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 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 }) {
const [tab, setTab] = useState("all");
const [products, setProducts] = useState(marketPlaceProduct);
export default function MainSection({
className,
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) => {
setTab(value);
};
useEffect(() => {
if (tab === "artist") {
setProducts(marketPlaceProduct?.slice(0, 3));
} else if (tab === "market") {
setProducts(marketPlaceProduct?.slice(0, 6));
} else if (tab === "shop") {
setProducts(marketPlaceProduct?.slice(6, 9));
} else if (tab === "assets") {
setProducts(marketPlaceProduct?.slice(3, 6));
} else {
setProducts(marketPlaceProduct);
// Handles the category selection on mobile view
const handleSetCategory = (value) => {
for (let i in marketCategories) {
if (marketCategories[i] == value) {
setTab(i);
}
}
}, [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 (
<div className={`market-place-section w-full ${className || ""}`}>
<div className="market-place-wrapper w-full">
<div className="filter-navigate-area lg:flex justify-between mb-8 items-center">
<div className="tab-item lg:mb-0 mb-5">
<div className="md:flex md:space-x-8 space-x-2">
<span
onClick={() => tabHandler("all")}
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"
? "text-pink border-pink"
: " border-transparent"
}`}
>
All
</span>
<span
onClick={() => tabHandler("artist")}
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 === "artist"
? "text-pink border-pink"
: " border-transparent"
}`}
>
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 className="filter-navigate-area flex justify-between items-center mb-8">
<div className="tab-item w-full flex items-center">
<div className="hidden lg:flex md:space-x-8 space-x-2">
{mappedArray.map(({ key, value }) => (
<span
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 ${
tab === key
? "text-pink border-pink"
: " border-transparent"
}`}
>
{value}
</span>
))}
</div>
{/* market categories on screen smaller than large screen */}
<div className="w-[80%] lg:hidden">
<SelectBox
action={handleSetCategory}
datas={Object.values(marketCategories)}
className="Update-table-dropdown"
contentBodyClasses="w-auto min-w-max"
position='left'
/>
</div>
</div>
{/*<div className="search-item flex lg:flex-none justify-end">*/}
{/* <SearchCom*/}
{/* className="lg:bg-transparent"*/}
{/* inputClasses="lg:bg-transparent"*/}
{/* />*/}
{/*</div>*/}
{/* contentDisplay toggler */}
<div className="p-2 w-[35px] h-[35px] bg-white dark:bg-slate-200 rounded-lg">
<img
title={contentDisplay=='grid'? 'list view' : 'grid view'}
onClick={()=>setContentDisplay((prev)=>prev=='grid'? 'list' : 'grid')}
src={contentDisplay=='grid'? ListView : GridView}
className="w-full h-full cursor-pointer" alt="view"
/>
</div>
{/* end of contentDisplay toggler */}
</div>
<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
datas={products}
startLength={process.env.REACT_APP_ZERO_STATE}
endLength={products?.length}
>
{({ datas }) => (
<AvailableJobsCard key={datas.id} datas={datas} />
<AvailableJobsCard contentDisplay={contentDisplay} key={datas.id} datas={datas} />
)}
</DataIteration>
</div>
@@ -4,6 +4,7 @@ import { toast } from "react-toastify";
import { Form, Formik } from "formik";
import usersService from "../../../services/UsersService";
import LoadingSpinner from "../../Spinners/LoadingSpinner";
import { PriceFormatter } from "../../Helpers/PriceFormatter";
const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
const [marketMsg, setMarketMsg] = useState({
@@ -96,14 +97,18 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
[apiCall, details, onClose, textValue]
);
console.log('Checking my mangeInt',manageInt)
let thePrice = PriceFormatter(
details?.price * 0.01,
details?.currency_code,
details?.currency
);
// let addedIntDate = marketInt?.added?.split(" ")[0];
let expireIntDate = marketInt?.expire?.split(" ")[0];
return (
<ModalCom action={onClose} situation={situation} className="edit-popup">
<div className="logout-modal-wrapper md:w-[750px] md:h-[700px] h-full bg-white dark:bg-dark-white lg:rounded-2xl overflow-y-auto">
<div className="logout-modal-wrapper md:w-[750px] md:h-[660px] h-full bg-white dark:bg-dark-white lg:rounded-2xl overflow-y-auto">
<div className="logout-modal-header w-full flex items-center justify-between lg:p-6 px-[30px] py-[23px]">
<h1 className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
{details.offer_code}
@@ -112,8 +117,8 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
</div>
<div className="md:flex bg-white rounded-lg">
<div className="p-4 w-full md:w-3/4 md:border-r-1">
<div className="min-h-[290px]">
<div className="p-4 w-full md:w-[75%] md:border-r-1">
<div className="min-h-[263px]">
<h2 className="font-semibold text-slate-900 dark:text-black tracking-wide">
{details?.title}
</h2>
@@ -128,7 +133,7 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
name: "",
content: {
text: `Timeline: ${details.timeline_days} day(s) -- `,
bold: `Budget: ${details.price} naira`,
bold: `Budget: ${thePrice}`,
},
},
{
@@ -138,7 +143,7 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
},
].map(({ name, content, danger }, idx) => (
<div className={`my-3 md:flex items-center`} key={idx}>
<label className="w-full md:w-1/4 text-slate-900 tracking-wide font-semibold">
<label className="w-full md:w-[19%] text-slate-900 tracking-wide font-semibold whitespace-pre-wrap">
{name}
</label>
<div
@@ -156,15 +161,19 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
}}
/>
) : (
<p className={`w-full md:w-3/4 text-slate-900`}>
<p className={`w-full text-slate-900`}>
{name !== "Delivery Detail" ? (
<>
{typeof content !== "object" ? content : null}
{typeof content === "object" && (
<span className="flex items-center gap-2">
{content?.text}
<strong>{content?.bold}</strong>
</span>
<>
<hr className="mb-1" />
<span className="flex items-center gap-2">
{content?.text}
<strong>{content?.bold}</strong>
</span>
<hr className="mt-1" />
</>
)}
</>
) : (
@@ -207,15 +216,15 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
</div>
</div>
<div className="w-full md:w-1/4 h-full ">
<div className="w-[90%] mx-auto bg-[#f1f8ff] p-4 rounded-md md:min-h-[550px] flex flex-col justify-between">
<div className="w-full md:w-[23%] h-full ">
<div className="mx-auto bg-[#f1f8ff] p-4 rounded-md md:min-h-[498px] flex flex-col justify-between">
<div className="w-full flex flex-col justify-center py-4 gap-2">
<p className="w-full text-slate-900 tracking-wide my-1">
Interested in the task?
</p>
<hr />
<button
className="bg-[#57cd89] text-center text-lg font-semibold text-white py-2 px-4 rounded-md inline-flex flex-col items-center justify-center"
className="bg-[#57cd89] text-center text-lg font-semibold text-white py-2 px-4 rounded-md inline-flex sm:flex-col flex-row sm:gap-0 gap-1 items-center justify-center"
name="market-interest"
onClick={marketCalls}
>
@@ -251,6 +260,13 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
<p className="my-1">Expire: {expireIntDate}</p>
</div>
</div>
<button
className="self-end w-[150px] mt-2 h-[52px] rounded-md text-base bg-transparent border border-red-500 text-red-500 mx-auto"
name="cancel"
onClick={onClose}
>
Cancel
</button>
</div>
{/* END OF ACTION SECTION */}
</div>
+9 -8
View File
@@ -1,22 +1,23 @@
import React from "react";
// import products from "../../data/marketplace_data.json";
//import CreateNft from "../Home/CreateNft";
import Layout from "../Partials/Layout";
import MainSection from "./MainSection";
import CommonHead from "../UserHeader/CommonHead";
import { useSelector } from "react-redux";
export default function MarketPlace({commonHeadData}) {
export default function MarketPlace({ commonHeadData }) {
let { jobLists } = useSelector((state) => state.jobLists);
const marketData = jobLists?.result_list;
const categories = jobLists?.categories;
// const marketProduct = products.data;
return (
<>
<Layout>
<CommonHead commonHeadData={commonHeadData} />
<MainSection marketPlaceProduct={marketData} className="mb-10" />
<CommonHead commonHeadData={commonHeadData} />
<MainSection
marketPlaceProduct={marketData}
categories={categories}
className="mb-10"
/>
</Layout>
</>
);
}
}
+146 -122
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 SelectBox from "../Helpers/SelectBox";
import DeleteJobPopout from "../jobPopout/DeleteJobPopout";
import JobListPopout from "../jobPopout/JobListPopout";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import { useSelector } from "react-redux";
import usersService from "../../services/UsersService";
import { handlePagingFunc } from "../Pagination/HandlePagination";
@@ -14,6 +12,23 @@ import EditJobPopOut from "../jobPopout/EditJobPopout";
import { PriceFormatter } from "../Helpers/PriceFormatter";
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 {
userDetails: { country },
@@ -45,22 +60,25 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
getCountryList();
}, [getCountryList]);
const filterCategories = ["All Categories", "Explore", "Featured"];
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: {} });
// Handle Pagination
const [currentPage, setCurrentPage] = useState(0);
const indexOfFirstItem = Number(currentPage);
const indexOfLastItem =
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,
indexOfLastItem
);
@@ -69,6 +87,96 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
handlePagingFunc(e, setCurrentPage);
};
// Handles the category selection
const handleSetCategory = (value) => {
setCurrentPage(0);
for (let i in filterCategories) {
if (filterCategories[i] == value) {
setCategory(i);
}
}
};
const JobListItem = ({ value, index }) => {
let thePrice = PriceFormatter(
value?.price * 0.01,
value?.currency_code,
value?.currency
);
return (
<tr
key={index}
className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50"
>
<td className="py-9">
<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="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]">
<h1 className="font-bold text-xl text-dark-gray dark:text-white">
{value.title}
</h1>
<div>{value.description}</div>
<span className="text-sm text-thin-light-gray">
Price: <span className="text-purple">{thePrice}</span>
</span>
<span className="text-sm text-thin-light-gray">
Duration:{" "}
<span className="text-purple">
{" "}
{value.timeline_days} day(s)
</span>
</span>
</div>
</div>
<div className="min-w-[110px] max-w-[110px] bg-yellow-300 mx-2 rounded-md flex flex-nowrap space-x-2 justify-center items-center self-end">
<button
type="button"
className="p-2 w-[60px] h-11"
onClick={() => {
setDeleteJobPopout({
show: true,
data: { thePrice, ...value },
});
}}
>
[Delete]
</button>
<span>|</span>
<button
type="button"
className="p-2 w-[40px] h-11"
onClick={() => {
setEditJob({
show: true,
data: { thePrice, ...value },
});
}}
>
Edit
</button>
</div>
</div>
</td>
<td className="text-right py-9 px-2">
<button
type="button"
onClick={() => {
setJobPopout({ show: true, data: { thePrice, ...value } });
}}
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
Manage
</button>
</td>
</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] ${
@@ -82,8 +190,8 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
</h1>
</div>
<SelectBox
action={setCategory}
datas={filterCategories}
action={handleSetCategory}
datas={Object.values(filterCategories)}
className="Update-table-dropdown"
contentBodyClasses="w-auto min-w-max"
/>
@@ -94,112 +202,27 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
<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" ? (
<>
{MyJobList &&
MyJobList?.data?.result_list &&
MyJobList.data?.result_list.length > 0 ? (
currentJobList.map((value, index) => {
let thePrice = PriceFormatter(
value?.price * 0.01,
value?.currency_code,
value?.currency
);
return(
<tr
key={index}
className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50"
>
<td className="py-9">
<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="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]">
<h1 className="font-bold text-xl text-dark-gray dark:text-white">
{value.title}
</h1>
<div>{value.description}</div>
<span className="text-sm text-thin-light-gray">
Price:{" "}
<span className="text-purple">
{thePrice}
</span>
</span>
<span className="text-sm text-thin-light-gray">
Duration:{" "}
<span className="text-purple">
{" "}
{value.timeline_days} day(s)
</span>
</span>
</div>
</div>
<div className="min-w-[110px] max-w-[110px] bg-yellow-300 mx-2 rounded-md flex flex-nowrap space-x-2 justify-center items-center self-end">
<button
type="button"
className="p-2 w-[60px] h-11"
onClick={() => {
setDeleteJobPopout({
show: true,
data: value,
});
}}
>
[Delete]
</button>
<span>|</span>
<button
type="button"
className="p-2 w-[40px] h-11"
onClick={() => {
setEditJob({
show: true,
data: value,
});
}}
>
Edit
</button>
</div>
</div>
</td>
<td className="text-right py-9 px-2">
<button
type="button"
onClick={() => {
setJobPopout({ show: true, data: value });
}}
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
Manage
</button>
</td>
</tr>
)})
<>
{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 Avaliable!</td>
<td className="p-2">
No Jobs Available In This Category!
</td>
</tr>
)}
</>
) : selectedCategory === "Explore" ? (
<></>
) : (
<></>
)}
)
) : (
<tr className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
<td className="p-2">No Jobs Avaliable!</td>
</tr>
)}
</>
</tbody>
</table>
@@ -209,11 +232,11 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
prev={currentPage == 0 ? true : false}
next={
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
MyJobList?.data?.result_list?.length
currentJobList?.length
? true
: false
}
data={MyJobList?.data?.result_list}
data={currentJobList}
start={indexOfFirstItem}
stop={indexOfLastItem}
/>
@@ -257,6 +280,7 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
}}
situation={editJob.show}
country={myCountry}
categories={currentJobCart}
/>
)}
</div>
+10 -3
View File
@@ -1,5 +1,4 @@
import React, { useState } from "react";
import { Link } from "react-router-dom";
import Layout from "../Partials/Layout";
import MyJobTable from "./MyJobTable";
import CommonHead from "../UserHeader/CommonHead";
@@ -11,6 +10,8 @@ export default function MyJobs(props) {
setPopUp((prev) => !prev);
};
const categoryOptions = props.MyJobList?.data?.categories;
return (
<Layout>
<CommonHead commonHeadData={props.commonHeadData} />
@@ -36,8 +37,14 @@ export default function MyJobs(props) {
</div>
{/* Add Job List Popout */}
{popUp && <AddJobPage action={popUpHandler} situation={popUp} />}
{popUp && (
<AddJobPage
action={popUpHandler}
situation={popUp}
categories={categoryOptions}
/>
)}
{/* End of Add Job List Popout */}
</Layout>
);
}
}
+24 -8
View File
@@ -1,15 +1,18 @@
import React, {useState} from 'react'
import RecentActivityTable from './WalletComponent/RecentActivityTable'
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 AddFundDollars from './AddFundDollars'
function AddFund({payment}) {
const navigate = useNavigate()
const {currency} = useLocation()?.state //GETS THE USER CURRENCY FOR ADD FUND
//STATE FOR CONTROLLED INPUT
let [input, setInput] = useState('0')
let [input, setInput] = useState('')
let [inputError, setInputError] = useState('')
@@ -23,15 +26,15 @@ function AddFund({payment}) {
setInputError('')
if(!input || input == '0'){
setInputError('Please Enter Amount')
return
return setTimeout(()=>{setInputError('')}, 5000)
}
if(isNaN(input)){
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})
setInput('')
@@ -79,18 +82,27 @@ function AddFund({payment}) {
<div className="field w-full mb-6">
<InputCom
fieldClass="px-6"
label="Amount(Naira)"
label={currency == 'US Dollars' ? "Amount (USD)" : "Amount (Naira)"}
type="text"
name="amount"
placeholder="Amount"
placeholder="0"
value={input}
inputHandler={handleChange}
// blurHandler={props.handleBlur}
/>
{inputError && <p className='text-base text-red-500'>{inputError}</p>}
</div>
</form>
<hr />
{/* SHOWS THIS IF USER CURRENCY IS DOLLARS */}
{currency == 'US Dollars' &&
<div className='w-full md:p-8 p-4 bg-white dark:bg-dark-white rounded-2xl shadow'>
<AddFundDollars setInputError={setInputError} input={input} setInput={setInput} />
</div>
}
{/* HIDES THIS BUTTON IF CURENCY IS NAIRA */}
{currency != 'US Dollars' &&
<div className='md:p-8 p-4 add-fund-btn flex justify-end items-center py-4'>
<button
onClick={handleSubmit}
@@ -100,10 +112,13 @@ function AddFund({payment}) {
<span className="text-white">Continue</span>
</button>
</div>
}
</div>
</div>
</div>
{/* HIDES THIS SECTION IF CURENCY IS NAIRA */}
{currency != 'US Dollars' &&
<div className="content-wrapper w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin">
<div className="lg:w-2/2 w-full mb-10 lg:mb-0">
<div className="wallet w-full md:p-8 p-4 h-full min-h-[590px] bg-white dark:bg-dark-white rounded-2xl shadow">
@@ -117,6 +132,7 @@ function AddFund({payment}) {
</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' ?
<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="">
<svg xmlns="http://www.w3.org/2000/svg" width="38"
height="38" viewBox="0 0 42 42" fill="none"><path
+17 -8
View File
@@ -50,7 +50,6 @@ function ConfirmAddFund({ payment }) {
toast.success("Account Topup was sucessful");
setTimeout(() => {
navigate("/my-wallet", { replace: true });
window.location.reload(true);
}, 1000);
})
.catch((err) => {
@@ -102,11 +101,11 @@ function ConfirmAddFund({ payment }) {
}, []);
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 ? (
<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">
<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
@@ -116,7 +115,7 @@ function ConfirmAddFund({ payment }) {
<div className="field w-full mb-3">
<InputCom
fieldClass="px-6"
label="Amount (Naira):"
label={state.currency == 'naira' ? "Amount (Naira):" : "Amount (Dollars):"}
type="text"
name="amount"
value={state.amount || ""}
@@ -127,16 +126,26 @@ function ConfirmAddFund({ payment }) {
<hr />
<div className="md:p-8 p-4 add-fund-btn flex justify-end items-center py-4">
<FlutterWaveButton
{...fwConfig}
{
state.currency == 'naira' ?
<FlutterWaveButton
{...fwConfig}
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
/>
:
<button
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
/>
onClick={()=>console.log('WORKING')}
>
Continue
</button>
}
</div>
</div>
</div>
)}
<div className="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">
<h2 className="text-gray-900 dark:text-white text-xl lg:text-2xl font-medium">
Recent Activity
@@ -15,11 +15,11 @@ function PurchasesTable({purchase}) {
}
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">
<thead className='border-b-2'>
<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">Fee</th>
</tr>
@@ -29,7 +29,7 @@ function PurchasesTable({purchase}) {
<tbody>
{currentPurchase.map((item, index) => (
<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>
</td>
<td className="p-2">{item.amount}</td>
@@ -15,7 +15,7 @@ function RecentActivityTable({payment}) {
}
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">
<thead className='border-b-2'>
<tr className='text-slate-600'>
@@ -1,60 +1,73 @@
import React, {useState} from 'react'
import { useState } from "react";
import PaginatedList from "../../Pagination/PaginatedList";
import { handlePagingFunc } from "../../Pagination/HandlePagination";
import PaginatedList from '../../Pagination/PaginatedList';
import {handlePagingFunc} from '../../Pagination/HandlePagination';
function ReferralTable({ history }) {
const [currentPage, setCurrentPage] = useState(0);
const indexOfFirstItem = Number(currentPage);
const indexOfLastItem =
Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
const currentReferral = history?.data?.slice(
indexOfFirstItem,
indexOfLastItem
);
function ReferralTable({history}) {
const [currentPage, setCurrentPage] = useState(0);
const indexOfFirstItem = Number(currentPage);
const indexOfLastItem = Number(indexOfFirstItem)+Number(process.env.REACT_APP_ITEM_PER_PAGE);
const currentReferral = history?.data?.slice(indexOfFirstItem, indexOfLastItem);
const handlePagination = (e) => {
handlePagingFunc(e,setCurrentPage)
}
const handlePagination = (e) => {
handlePagingFunc(e, setCurrentPage);
};
return (
<div className='flex flex-col justify-between min-h-[420px] overflow-x-auto'>
<table className="referral-list w-full table-auto border-collapse text-left">
<thead className='border-b-2'>
<tr className='text-slate-600'>
<th className="p-3">Added/Name</th>
<th className="p-3">Email</th>
<th className="p-3">Status</th>
</tr>
</thead>
<tbody>
{history.data.length ?
currentReferral.map((item, index) => (
<tr key={index} className='text-slate-500'>
<td className="p-3">{item.added_date} / {item.firstname} {item.lastname}</td>
<td className="p-3">{item.email}</td>
<td className="p-3">{item.status}</td>
</tr>
))
:
(
history.error ?
<tr className='text-slate-500'>
<td colSpan={3}>Opps! couldn't get referral history. Try reloading the page</td>
</tr>
:
(
<tr className='text-slate-500'>
<td colSpan={3}>No Item Found on referral List</td>
</tr>
)
)
}
</tbody>
</table>
<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">
<thead className="border-b-2">
<tr className="text-slate-600">
<th className="p-3">Added/Name</th>
<th className="p-3">Email</th>
<th className="p-3">Status</th>
</tr>
</thead>
<tbody>
{history.data.length ? (
currentReferral.map((item, index) => (
<tr key={index} className="text-slate-500">
<td className="p-3">
{item.added_date} / {item.firstname} {item.lastname}
</td>
<td className="p-3">{item.email}</td>
<td className="p-3">{item.status}</td>
</tr>
))
) : history.error ? (
<tr className="text-slate-500">
<td colSpan={3}>
Opps! couldn't get referral history. Try reloading the page
</td>
</tr>
) : (
<tr className="text-slate-500">
<td colSpan={3}>No Item Found on referral List</td>
</tr>
)}
</tbody>
</table>
{/* 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} />
{/* END OF 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}
/>
{/* END OF PAGINATION BUTTON */}
</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: ''})
return
}
setInterval(() => { // SETS REDIRECT COUNT DOWN
let intervalTime = setInterval(() => { // SETS REDIRECT COUNT DOWN
setRedirectTime(prev => prev - 1)
}, 1000);
setRequestStatus({loading: false, status: true, message: `Offer ${name}ed`, processType: ''})
setTimeout(()=>{
navigate('/offer-interest', {replace: true})
clearInterval(intervalTime)
},5000)
}).catch(err => {
setRequestStatus({loading: false, status: false, message: 'Opps! something went wrong. Try again', processType: ''})
@@ -142,13 +143,15 @@ export default function ManageInterestOffer(props) {
{/* info tab */}
{tab == 'info' ?
<div className="info-details w-full border-t">
<div className="my-3 flex items-center gap-1">
<span className="w-[200px] text-lg font-bold text-dark-gray dark:text-white tracking-wide">Name</span>
<span className="min-w-[100px] text-sm font-bold text-dark-gray dark:text-white tracking-wide">{props.offerDetails?.client_name}</span>
</div>
<div className="my-3 flex items-center gap-1">
<span className="w-[200px] text-lg font-bold text-dark-gray dark:text-white tracking-wide">Member Since</span>
<span className="min-w-[100px] text-sm font-bold text-dark-gray dark:text-white tracking-wide">{props.offerDetails?.client_added}</span>
<div className="my-0 md:my-3 block md:flex items-center gap-10">
<div className="my-3 md:my-0 flex items-center gap-1">
<span className="w-[200px] text-lg font-bold text-dark-gray dark:text-white tracking-wide">Name</span>
<span className="min-w-[100px] text-sm font-bold text-dark-gray dark:text-white tracking-wide">{props.offerDetails?.client_name}</span>
</div>
<div className="my-3 md:my-0 flex items-center gap-1">
<span className="w-[200px] text-lg font-bold text-dark-gray dark:text-white tracking-wide">Member Since</span>
<span className="min-w-[100px] text-sm font-bold text-dark-gray dark:text-white tracking-wide">{props.offerDetails?.client_added}</span>
</div>
</div>
<div className="my-3 flex items-center gap-1">
<span className="w-[200px] text-lg font-bold text-dark-gray dark:text-white tracking-wide">Jobs completed</span>
@@ -225,7 +228,7 @@ export default function ManageInterestOffer(props) {
{/* BUTTON section */}
<div className="p-4 w-full min-h-full bg-sky-100 dark:bg-dark-gray col-span-1">
<div className="w-full h-full">
<div className="mt-0 sm:mt-10 flex sm:flex-col justify-center items-center gap-10">
<div className="h-full flex sm:flex-col justify-center items-center gap-10">
{requestStatus.loading && requestStatus.processType == 'accept' ?
<LoadingSpinner color='sky-blue' size='10' />
:
@@ -234,9 +237,10 @@ export default function ManageInterestOffer(props) {
name='accept'
disabled={requestStatus.loading}
onClick={interestOfferProcess}
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"
className='max-w-[150px] h-[100px] bg-[#57cd89] text-center text-lg font-semibold text-white py-2 px-4 rounded-md shadow-md'
>
Accept
Accept this Interest
</button>
}
@@ -248,9 +252,10 @@ export default function ManageInterestOffer(props) {
name='reject'
disabled={requestStatus.loading}
onClick={interestOfferProcess}
className="px-2 py-1 h-11 flex justify-center items-center border-gradient text-base rounded-full text-black"
// className="px-2 py-1 h-11 flex justify-center items-center border-gradient text-base rounded-full text-black"
className='max-w-[150px] h-[100px] bg-red-300 text-center text-lg font-semibold text-white py-2 px-4 rounded-md shadow-md'
>
Reject
Reject this Interest
</button>
}
</div>
+6 -6
View File
@@ -1,13 +1,13 @@
import React from 'react'
import Layout from '../Partials/Layout'
import ReferralDisplay from './ReferralDisplay'
import React from "react";
import Layout from "../Partials/Layout";
import ReferralDisplay from "./ReferralDisplay";
function Referral() {
return (
<Layout>
<ReferralDisplay />
<ReferralDisplay />
</Layout>
)
);
}
export default Referral
export default Referral;
+36 -47
View File
@@ -1,5 +1,4 @@
import React, { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { toast } from "react-toastify";
import usersService from "../../services/UsersService";
import InputCom from "../Helpers/Inputs/InputCom";
@@ -10,30 +9,29 @@ import * as Yup from "yup";
import ReferralTable from "../MyWallet/WalletComponent/ReferralTable";
const validationSchema = Yup.object().shape({
email: Yup.string()
ref_email: Yup.string()
.email("Wrong email format")
.min(3, "Minimum 3 characters")
.max(50, "Maximum 50 characters")
.required("Email is required"),
firstname: Yup.string()
ref_firstname: Yup.string()
.min(3, "Minimum 3 characters")
.max(25, "Maximum 25 characters")
.required("Firstname is required"),
lastname: Yup.string()
ref_lastname: Yup.string()
.min(3, "Minimum 3 characters")
.max(25, "Maximum 25 characters")
.required("Lastname is required"),
});
const initialValues = {
firstname: "",
lastname: "",
email: "",
ref_firstname: "",
ref_lastname: "",
ref_email: "",
};
function ReferralDisplay() {
const apiCall = new usersService(); // GET API CALL
const navigate = useNavigate();
let [refHistoryReload, setRefHistoryReload] = useState(false); // Determines when referral history reloads
@@ -76,13 +74,13 @@ function ReferralDisplay() {
.then((res) => {
if (res.data.internal_return < 0) {
setError({
message: "Email already referred",
message: res.data.status,
loading: false,
status: false,
});
return;
} else {
toast.success("Message Sent");
toast.success(res.data.status | "Message Sent!");
setError({ message: "", loading: false, status: true });
setRefHistoryReload((prev) => !prev);
}
@@ -99,16 +97,7 @@ function ReferralDisplay() {
//FUNCTION TO HANDLE SUBMIT
const handleSubmit = (values, helpers) => {
setError({ message: "", loading: true, status: false });
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
sendReferralMsg({...values}); // FUNCTION TO SEND REFERRAL MESSAGE
};
useEffect(() => {
@@ -121,12 +110,9 @@ function ReferralDisplay() {
<div className="sm:flex justify-between items-center mb-6">
<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">
<span>
Refer a Friend
</span>
<span>Refer a Friend</span>
</h1>
</div>
</div>
<div className="referral w-full md:p-8 p-4 bg-white dark:bg-dark-white rounded-2xl shadow">
@@ -147,17 +133,18 @@ function ReferralDisplay() {
fieldClass="px-6"
label="Firstname"
type="text"
name="firstname"
name="ref_firstname"
placeholder="Firstname"
value={props.values.firstname}
value={props.values.ref_firstname}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{props.errors.firstname && props.touched.firstname && (
<p className="text-sm text-red-500">
{props.errors.firstname}
</p>
)}
{props.errors.ref_firstname &&
props.touched.ref_firstname && (
<p className="text-sm text-red-500">
{props.errors.ref_firstname}
</p>
)}
</div>
{/* Lastname */}
@@ -166,17 +153,18 @@ function ReferralDisplay() {
fieldClass="px-6"
label="Lastname"
type="text"
name="lastname"
name="ref_lastname"
placeholder="Lastname"
value={props.values.lastname}
value={props.values.ref_lastname}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{props.errors.lastname && props.touched.lastname && (
<p className="text-sm text-red-500">
{props.errors.lastname}
</p>
)}
{props.errors.ref_lastname &&
props.touched.ref_lastname && (
<p className="text-sm text-red-500">
{props.errors.ref_lastname}
</p>
)}
</div>
</div>
@@ -185,14 +173,16 @@ function ReferralDisplay() {
fieldClass="px-6"
label="Email"
type="text"
name="email"
name="ref_email"
placeholder="Email"
value={props.values.email}
value={props.values.ref_email}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{props.errors.email && props.touched.email && (
<p className="text-sm text-red-500">{props.errors.email}</p>
{props.errors.ref_email && props.touched.ref_email && (
<p className="text-sm text-red-500">
{props.errors.ref_email}
</p>
)}
</div>
@@ -206,7 +196,8 @@ function ReferralDisplay() {
) : (
<button
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
</button>
)}
@@ -221,14 +212,12 @@ function ReferralDisplay() {
Referral List
</h2>
{referralList.loading ? (
<LoadingSpinner size="32" color="sky-blue" />
<LoadingSpinner size="32" color="sky-blue" />
) : (
<ReferralTable history={referralList} />
<ReferralTable history={referralList} />
)}
</div>
</div>
</div>
);
}
+159 -138
View File
@@ -1,152 +1,173 @@
import React, { useState } from 'react'
import ModalCom from '../Helpers/ModalCom'
import { useNavigate } from 'react-router-dom'
import usersService from '../../services/UsersService'
import LoadingSpinner from '../Spinners/LoadingSpinner'
import { useDispatch } from 'react-redux'
import { tableReload } from '../../store/TableReloads'
import React, { useState } from "react";
import ModalCom from "../Helpers/ModalCom";
import { useNavigate } from "react-router-dom";
import usersService from "../../services/UsersService";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import { useDispatch } from "react-redux";
import { tableReload } from "../../store/TableReloads";
function DeleteJobPopout({details, onClose, situation}) {
let dispatch = useDispatch()
const navigate = useNavigate()
const ApiCall = new usersService()
function DeleteJobPopout({ details, onClose, situation }) {
let dispatch = useDispatch();
const navigate = useNavigate();
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
const deleteJob = (details) => {
setRequestStatus({laoding: true, status:false, message: ''})
let reqData = {
job_id: details.job_id,
job_uid: details.job_uid
} // DATA NEEDED BY THE API
// API CALL TO DELETE A JOB
ApiCall.deleteJob(reqData).then(res => {
if(res.data.internal_return < 0){
setRequestStatus({laoding: false, status:false, message: 'Could not perform the request, try again!'})
return
}
setRequestStatus({laoding: false, status:true, message: 'Job deleted successfully'})
setTimeout(()=>{
dispatch(tableReload({type:'JOBTABLE'}))
navigate('/myjobs', {replace: true})
onClose()
}, 1000)
}).catch(error => {
setRequestStatus({laoding: false, status:false, message: 'Opps! something went wrong, try again'})
}).finally(()=>{
setTimeout(()=>{
setRequestStatus({laoding: false, status:false, message: ''})
}, 5000)
})
}
// FUNCTION CALLED ONCE USER CONFIRM DELETE JOB
const deleteJob = (details) => {
setRequestStatus({ laoding: true, status: false, message: "" });
let reqData = {
job_id: details.job_id,
job_uid: details.job_uid,
}; // DATA NEEDED BY THE API
// API CALL TO DELETE A JOB
ApiCall.deleteJob(reqData)
.then((res) => {
if (res.data.internal_return < 0) {
setRequestStatus({
laoding: false,
status: false,
message: "Could not perform the request, try again!",
});
return;
}
setRequestStatus({
laoding: false,
status: true,
message: "Job deleted successfully",
});
setTimeout(() => {
dispatch(tableReload({ type: "JOBTABLE" }));
navigate("/myjobs", { replace: true });
onClose();
}, 1000);
})
.catch((error) => {
setRequestStatus({
laoding: false,
status: false,
message: "Opps! something went wrong, try again",
});
})
.finally(() => {
setTimeout(() => {
setRequestStatus({ laoding: false, status: false, message: "" });
}, 5000);
});
};
return (
<ModalCom action={onClose} situation={situation}>
<div className="logout-modal-wrapper lg:w-[600px] h-full lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl">
<div className="logout-modal-header w-full flex items-center justify-between lg:px-10 lg:py-8 px-[30px] py-[23px] border-b border-light-purple dark:border-[#5356fb29] ">
<h1 className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
Delete Job
</h1>
<div className="logout-modal-wrapper lg:w-[600px] h-full lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl">
<div className="logout-modal-header w-full flex items-center justify-between lg:px-10 lg:py-8 px-[30px] py-[23px] border-b border-light-purple dark:border-[#5356fb29] ">
<h1 className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
Delete Job
</h1>
<button
type="button"
className="text-[#374557] dark:text-red-500"
onClick={onClose}
>
<svg
width="36"
height="36"
viewBox="0 0 36 36"
fill="none"
className="fill-current"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M36 16.16C36 17.4399 36 18.7199 36 20.0001C35.7911 20.0709 35.8636 20.2554 35.8385 20.4001C34.5321 27.9453 30.246 32.9248 22.9603 35.2822C21.9006 35.6251 20.7753 35.7657 19.6802 35.9997C18.4003 35.9997 17.1204 35.9997 15.8401 35.9997C15.5896 35.7086 15.2189 35.7732 14.9034 35.7093C7.77231 34.2621 3.08728 30.0725 0.769671 23.187C0.435002 22.1926 0.445997 21.1199 0 20.1599C0 18.7198 0 17.2798 0 15.8398C0.291376 15.6195 0.214408 15.2656 0.270759 14.9808C1.71321 7.69774 6.02611 2.99691 13.0428 0.700951C14.0118 0.383805 15.0509 0.386897 15.9999 0C17.2265 0 18.4532 0 19.6799 0C19.7156 0.124041 19.8125 0.136067 19.9225 0.146719C27.3 0.868973 33.5322 6.21922 35.3801 13.427C35.6121 14.3313 35.7945 15.2484 36 16.16ZM33.011 18.0787C33.0433 9.77105 26.3423 3.00309 18.077 2.9945C9.78479 2.98626 3.00344 9.658 2.98523 17.8426C2.96667 26.1633 9.58859 32.9601 17.7602 33.0079C26.197 33.0577 32.9787 26.4186 33.011 18.0787Z"
fill=""
fillOpacity="0.6"
/>
<path
d="M15.9309 18.023C13.9329 16.037 12.007 14.1207 10.0787 12.2072C9.60071 11.733 9.26398 11.2162 9.51996 10.506C9.945 9.32677 11.1954 9.0811 12.1437 10.0174C13.9067 11.7585 15.6766 13.494 17.385 15.2879C17.9108 15.8401 18.1633 15.7487 18.6375 15.258C20.3586 13.4761 22.1199 11.7327 23.8822 9.99096C24.8175 9.06632 26.1095 9.33639 26.4967 10.517C26.7286 11.2241 26.3919 11.7413 25.9133 12.2178C24.1757 13.9472 22.4477 15.6855 20.7104 17.4148C20.5228 17.6018 20.2964 17.7495 20.0466 17.9485C22.0831 19.974 24.0372 21.8992 25.9689 23.8468C26.9262 24.8119 26.6489 26.1101 25.4336 26.4987C24.712 26.7292 24.2131 26.3441 23.7455 25.8757C21.9945 24.1227 20.2232 22.3892 18.5045 20.6049C18.0698 20.1534 17.8716 20.2269 17.4802 20.6282C15.732 22.4215 13.9493 24.1807 12.1777 25.951C11.7022 26.4262 11.193 26.7471 10.4738 26.4537C9.31345 25.9798 9.06881 24.8398 9.98589 23.8952C11.285 22.5576 12.6138 21.2484 13.9387 19.9355C14.5792 19.3005 15.2399 18.6852 15.9309 18.023Z"
fill="#"
fillOpacity="0.6"
/>
</svg>
</button>
</div>
<div className="logout-modal-body w-full flex flex-col items-center px-10 py-8">
<div className="what-icon mb-6 cursor-pointer">
<svg
width="136"
height="136"
viewBox="0 0 136 136"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<circle cx="68" cy="68" r="68" fill="#5356FB" />
<path
d="M69.8844 35.7891C71.1588 36.0357 72.4569 36.1967 73.7044 36.5423C81.5447 38.7098 87.2705 45.5378 87.9574 53.6156C88.5113 60.1147 86.3075 65.6006 81.5043 70.0195C79.8359 71.5545 78.0497 72.9604 76.3408 74.4534C76.127 74.6397 75.9654 75.0037 75.9604 75.2872C75.9284 77.2752 75.9435 79.2649 75.9435 81.2965C70.8895 81.2965 65.8758 81.2965 60.7915 81.2965C60.7915 81.0616 60.7915 80.8385 60.7915 80.6137C60.7915 76.5454 60.7999 72.4772 60.7797 68.4106C60.778 67.9392 60.9312 67.649 61.2831 67.3537C64.5643 64.5957 67.8271 61.8175 71.1033 59.0545C72.2616 58.0781 72.9215 56.8702 72.9081 55.3419C72.8878 52.916 70.8608 50.9146 68.423 50.8911C65.9701 50.8693 63.9145 52.8053 63.832 55.2328C63.8084 55.8988 63.8286 56.5665 63.8286 57.2695C58.7745 57.2695 53.7744 57.2695 48.6917 57.2695C48.6917 56.3149 48.6462 55.3385 48.6984 54.3655C49.222 44.699 56.7442 36.8745 66.4331 35.8914C66.5762 35.8763 66.7142 35.8243 66.854 35.7891C67.8641 35.7891 68.8742 35.7891 69.8844 35.7891Z"
fill="white"
/>
<path
d="M67.485 100.21C66.1617 99.9268 64.9041 99.5091 63.803 98.6787C61.3804 96.8484 60.2877 93.7699 61.0386 90.7888C61.7726 87.8747 64.2138 85.6703 67.2089 85.2157C71.273 84.6 75.2024 87.3681 75.8135 91.277C76.4937 95.6153 73.8202 99.3782 69.544 100.103C69.4429 100.12 69.3487 100.172 69.2527 100.209C68.6635 100.21 68.0742 100.21 67.485 100.21Z"
fill="white"
/>
</svg>
</div>
<div className="mb-6">
<p className="text-xl tracking-wide text-dark-gray dark:text-white">
{details.title}
</p>
<p className="text-lg tracking-wide text-dark-gray dark:text-white">
Price: {details.thePrice}
</p>
<p className="text-lg tracking-wide text-dark-gray dark:text-white">
Duration: {details.timeline_days} day(s)
</p>
</div>
<div className="flex space-x-2.5">
<button
onClick={onClose}
type="button"
className=" border-gradient text-18 tracking-wide px-4 py-3 rounded-full"
>
<span className="text-gradient">Cancel</span>
</button>
{requestStatus.laoding ? (
<LoadingSpinner size="8" color="sky-blue" />
) : (
<button
onClick={() => deleteJob(details)}
type="button"
className="text-[#374557] dark:text-red-500"
onClick={onClose}
className="text-white primary-gradient text-18 tracking-wide px-4 py-3 rounded-full"
>
<svg
width="36"
height="36"
viewBox="0 0 36 36"
fill="none"
className="fill-current"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M36 16.16C36 17.4399 36 18.7199 36 20.0001C35.7911 20.0709 35.8636 20.2554 35.8385 20.4001C34.5321 27.9453 30.246 32.9248 22.9603 35.2822C21.9006 35.6251 20.7753 35.7657 19.6802 35.9997C18.4003 35.9997 17.1204 35.9997 15.8401 35.9997C15.5896 35.7086 15.2189 35.7732 14.9034 35.7093C7.77231 34.2621 3.08728 30.0725 0.769671 23.187C0.435002 22.1926 0.445997 21.1199 0 20.1599C0 18.7198 0 17.2798 0 15.8398C0.291376 15.6195 0.214408 15.2656 0.270759 14.9808C1.71321 7.69774 6.02611 2.99691 13.0428 0.700951C14.0118 0.383805 15.0509 0.386897 15.9999 0C17.2265 0 18.4532 0 19.6799 0C19.7156 0.124041 19.8125 0.136067 19.9225 0.146719C27.3 0.868973 33.5322 6.21922 35.3801 13.427C35.6121 14.3313 35.7945 15.2484 36 16.16ZM33.011 18.0787C33.0433 9.77105 26.3423 3.00309 18.077 2.9945C9.78479 2.98626 3.00344 9.658 2.98523 17.8426C2.96667 26.1633 9.58859 32.9601 17.7602 33.0079C26.197 33.0577 32.9787 26.4186 33.011 18.0787Z"
fill=""
fillOpacity="0.6"
/>
<path
d="M15.9309 18.023C13.9329 16.037 12.007 14.1207 10.0787 12.2072C9.60071 11.733 9.26398 11.2162 9.51996 10.506C9.945 9.32677 11.1954 9.0811 12.1437 10.0174C13.9067 11.7585 15.6766 13.494 17.385 15.2879C17.9108 15.8401 18.1633 15.7487 18.6375 15.258C20.3586 13.4761 22.1199 11.7327 23.8822 9.99096C24.8175 9.06632 26.1095 9.33639 26.4967 10.517C26.7286 11.2241 26.3919 11.7413 25.9133 12.2178C24.1757 13.9472 22.4477 15.6855 20.7104 17.4148C20.5228 17.6018 20.2964 17.7495 20.0466 17.9485C22.0831 19.974 24.0372 21.8992 25.9689 23.8468C26.9262 24.8119 26.6489 26.1101 25.4336 26.4987C24.712 26.7292 24.2131 26.3441 23.7455 25.8757C21.9945 24.1227 20.2232 22.3892 18.5045 20.6049C18.0698 20.1534 17.8716 20.2269 17.4802 20.6282C15.732 22.4215 13.9493 24.1807 12.1777 25.951C11.7022 26.4262 11.193 26.7471 10.4738 26.4537C9.31345 25.9798 9.06881 24.8398 9.98589 23.8952C11.285 22.5576 12.6138 21.2484 13.9387 19.9355C14.5792 19.3005 15.2399 18.6852 15.9309 18.023Z"
fill="#"
fillOpacity="0.6"
/>
</svg>
Confirm Delete
</button>
</div>
<div className="logout-modal-body w-full flex flex-col items-center px-10 py-8">
<div className="what-icon mb-6 cursor-pointer">
<svg
width="136"
height="136"
viewBox="0 0 136 136"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<circle cx="68" cy="68" r="68" fill="#5356FB" />
<path
d="M69.8844 35.7891C71.1588 36.0357 72.4569 36.1967 73.7044 36.5423C81.5447 38.7098 87.2705 45.5378 87.9574 53.6156C88.5113 60.1147 86.3075 65.6006 81.5043 70.0195C79.8359 71.5545 78.0497 72.9604 76.3408 74.4534C76.127 74.6397 75.9654 75.0037 75.9604 75.2872C75.9284 77.2752 75.9435 79.2649 75.9435 81.2965C70.8895 81.2965 65.8758 81.2965 60.7915 81.2965C60.7915 81.0616 60.7915 80.8385 60.7915 80.6137C60.7915 76.5454 60.7999 72.4772 60.7797 68.4106C60.778 67.9392 60.9312 67.649 61.2831 67.3537C64.5643 64.5957 67.8271 61.8175 71.1033 59.0545C72.2616 58.0781 72.9215 56.8702 72.9081 55.3419C72.8878 52.916 70.8608 50.9146 68.423 50.8911C65.9701 50.8693 63.9145 52.8053 63.832 55.2328C63.8084 55.8988 63.8286 56.5665 63.8286 57.2695C58.7745 57.2695 53.7744 57.2695 48.6917 57.2695C48.6917 56.3149 48.6462 55.3385 48.6984 54.3655C49.222 44.699 56.7442 36.8745 66.4331 35.8914C66.5762 35.8763 66.7142 35.8243 66.854 35.7891C67.8641 35.7891 68.8742 35.7891 69.8844 35.7891Z"
fill="white"
/>
<path
d="M67.485 100.21C66.1617 99.9268 64.9041 99.5091 63.803 98.6787C61.3804 96.8484 60.2877 93.7699 61.0386 90.7888C61.7726 87.8747 64.2138 85.6703 67.2089 85.2157C71.273 84.6 75.2024 87.3681 75.8135 91.277C76.4937 95.6153 73.8202 99.3782 69.544 100.103C69.4429 100.12 69.3487 100.172 69.2527 100.209C68.6635 100.21 68.0742 100.21 67.485 100.21Z"
fill="white"
/>
</svg>
</div>
<div className="mb-6">
<p className="text-xl tracking-wide text-dark-gray dark:text-white">
{details.title}
</p>
<p className="text-lg tracking-wide text-dark-gray dark:text-white">
Price: {details.price * 0.01}
</p>
<p className="text-lg tracking-wide text-dark-gray dark:text-white">
Duration: {details.timeline_days} day(s)
</p>
</div>
<div className="flex space-x-2.5">
<button
onClick={onClose}
type="button"
className=" border-gradient text-18 tracking-wide px-4 py-3 rounded-full"
>
<span className="text-gradient">Cancel</span>
</button>
{requestStatus.laoding ?
<LoadingSpinner size='8' color='sky-blue' />
:
<button
onClick={() => deleteJob(details)}
type="button"
className="text-white primary-gradient text-18 tracking-wide px-4 py-3 rounded-full"
>
Confirm Delete
</button>
}
</div>
{/* ERROR DISPLAY AND SUBMIT BUTTON */}
{requestStatus.message != "" && (
!requestStatus.status ?
(<div className={`relative p-4 my-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}>
{requestStatus.message}
</div>)
:
requestStatus.status &&
(<div className={`relative p-4 my-4 text-green-700 bg-slate-200 border-slate-800 mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}>
{requestStatus.message}
</div>
)
)}
{/* End of error or success display */}
</div>
)}
</div>
</ModalCom>
)
{/* ERROR DISPLAY AND SUBMIT BUTTON */}
{requestStatus.message != "" &&
(!requestStatus.status ? (
<div
className={`relative p-4 my-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
>
{requestStatus.message}
</div>
) : (
requestStatus.status && (
<div
className={`relative p-4 my-4 text-green-700 bg-slate-200 border-slate-800 mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
>
{requestStatus.message}
</div>
)
))}
{/* End of error or success display */}
</div>
</div>
</ModalCom>
);
}
export default DeleteJobPopout
export default DeleteJobPopout;
+105 -84
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 { Field, Form, Formik } from "formik";
import * as Yup from "yup";
@@ -6,13 +6,17 @@ import InputCom from "../Helpers/Inputs/InputCom";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import usersService from "../../services/UsersService";
import { useNavigate } from "react-router-dom";
import { tableReload } from "../../store/TableReloads";
import { useDispatch } from "react-redux";
const EditJobPopOut = ({ details, onClose, situation, country }) => {
const dispatch = useDispatch()
const EditJobPopOut = ({
details,
onClose,
situation,
country,
categories,
}) => {
const dispatch = useDispatch();
let [requestStatus, setRequestStatus] = useState({
loading: false,
@@ -55,27 +59,31 @@ const EditJobPopOut = ({ details, onClose, situation, country }) => {
description: details?.description,
job_detail: details?.job_detail,
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 navigate = useNavigate();
const handleEditJob = useCallback(
async (values) => {
values.category = values.category?.join("@");
setRequestStatus({ loading: true, message: "" });
let reqData = {
job_id: details.job_id,
job_uid: details.job_uid,
...values,
};
delete reqData?.country
delete reqData?.country;
try {
let res = await jobApi.jobManagerUpdateJob(reqData);
let { data } = await res;
if (data?.internal_return < 0) return;
setRequestStatus({ loading: false, message: null });
setTimeout(() => {
dispatch(tableReload({type:'JOBTABLE'}))
dispatch(tableReload({ type: "JOBTABLE" }));
navigate("/myjobs", { replace: true });
onClose();
}, 1000);
@@ -130,7 +138,7 @@ const EditJobPopOut = ({ details, onClose, situation, country }) => {
<Form className="w-full">
<div className="flex flex-col-reverse sm:flex-row">
<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">
<InputCom
fieldClass="px-6 cursor-default"
@@ -145,11 +153,6 @@ const EditJobPopOut = ({ details, onClose, situation, country }) => {
blurHandler={props.handleBlur}
disable={true}
/>
{props.errors.country && props.touched.country && (
<p className="text-sm text-red-500">
{props.errors.country}
</p>
)}
</div>
{/* Price */}
@@ -162,20 +165,17 @@ const EditJobPopOut = ({ details, onClose, situation, country }) => {
inputClass="input-curve lg border border-light-purple"
type="number"
name="price"
// placeholder="Please Enter Amount"
value={props.values.price * 0.01}
inputHandler={props.handleChange}
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>
{/* Title */}
<div className="field w-full mb-6">
<div className="field w-full mb-[0.5rem]">
<InputCom
fieldClass="px-6"
label="Title"
@@ -184,20 +184,15 @@ const EditJobPopOut = ({ details, onClose, situation, country }) => {
inputClass=" input-curve lg border border-light-purple"
type="text"
name="title"
// placeholder="Enter Job Title"
value={props.values.title}
inputHandler={props.handleChange}
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>
{/* Description */}
<div className="field w-full mb-6">
<div className="field w-full mb-[0.5rem]">
<InputCom
fieldClass="px-6"
label="Description"
@@ -206,84 +201,110 @@ const EditJobPopOut = ({ details, onClose, situation, country }) => {
inputClass=" input-curve lg border border-light-purple"
type="text"
name="description"
// placeholder="Enter a description"
value={props.values.description}
inputHandler={props.handleChange}
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>
{/* Details */}
<div className="field w-full mb-6">
<label
htmlFor="Job Delivery Details"
className='className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block mb-3'
>
Job Delivery Details
</label>
<textarea
id="Job Delivery Details"
rows="5"
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" }}
name="job_detail"
value={props.values.job_detail}
onChange={props.handleChange}
onBlur={props.handleBlur}
/>
<div className="field flex flex-col sm:flex-row w-full mb-[5px] gap-2">
<div className="sm:w-[60%] w-full">
<label
htmlFor="Job Delivery Details"
className='className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"'
>
Job Delivery Details
</label>
<textarea
id="Job Delivery Details"
rows="5"
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" }}
name="job_detail"
value={props.values.job_detail}
onChange={props.handleChange}
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 && (
<p className="text-sm text-red-500">
{props.errors.job_detail}
</p>
)}
</div> */}
</div>
<div className="field w-full mb-6">
<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="timeline_days"
<div
className={`flex items-center justify-between mb-2.5`}
>
Timeline
<span className="text-green-700 text-sm tracking-wide">
- Expected duration of this task
</span>
</label>
</div>
<Field
component="select"
name="timeline_days"
className="input-field p-2 mt-3 rounded-md placeholder:text-base text-dark-gray dark:text-white w-full h-10 bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none"
value={props.values.timeline_days}
>
<option value="">Select Duration</option>
{publicArray.map(({ name, duration }, idx) => (
<option
className="text-slate-500 text-lg"
value={duration}
<label
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"
htmlFor="timeline_days"
>
{name}
</option>
))}
</Field>
{props.errors.timeline_days &&
props.touched.timeline_days && (
<p className="text-sm text-red-500">
{props.errors.timeline_days}
</p>
)}
Timeline
<span className="text-green-700 text-sm tracking-wide">
- Expected duration of this task
</span>
</label>
</div>
<Field
component="select"
name="timeline_days"
className="input-field p-2 mt-3 rounded-md placeholder:text-base text-dark-gray dark:text-white w-full h-10 bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none"
value={props.values.timeline_days}
>
<option value="">Select Duration</option>
{publicArray.map(({ name, duration }, idx) => (
<option
className="text-slate-500 text-lg"
value={duration}
>
{name}
</option>
))}
</Field>
</div>
{/* inputs ends here */}
</div>
</div>
{/* ERROR DISPLAY AND SUBMIT BUTTON */}
{/* ERROR DISPLAY AND SUBMIT BUTTON */}
<div className="content-footer w-full">
{/* error or success display */}
{requestStatus.message != "" &&
+2 -2
View File
@@ -3,7 +3,7 @@ import Detail from "./popoutcomponent/Detail";
import ModalCom from "../Helpers/ModalCom";
import InputCom from "../Helpers/Inputs/InputCom/index";
import SiteService from "../../services/SiteService";
import { Form, Formik, Field, ErrorMessage } from "formik";
import { Form, Formik, Field } from "formik";
import * as Yup from "yup";
import LoadingSpinner from "../Spinners/LoadingSpinner";
@@ -210,7 +210,7 @@ function JobListPopout({ details, onClose, situation }) {
</div>
<div className="my-3 md:flex">
<Detail label="Price" value={`${details.price * 0.01} Naira`} />
<Detail label="Price" value={details.thePrice} />
</div>
<div className="my-3 md:flex">
+28 -3
View File
@@ -51,8 +51,11 @@
font-weight: bolder;
}
.siderCardDescription{
margin: 20px 45px 10px 45px;
font-size: 20px;
margin: 10px 45px 10px 45px;
font-size: 18px;
background-color: aliceblue;
padding: 5px;
border-radius: 5px;
}
.siderCardButton{
margin-top: 10px;
@@ -897,4 +900,26 @@ TODO: Responsive ===========================
.addJob-popup{
top: 30px;
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
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) {
@@ -712,6 +719,16 @@ class usersService {
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(password)
+4 -4
View File
@@ -2,10 +2,10 @@ import React from "react";
import AddJob from "../components/AddJob/AddJob";
import ModalCom from "../components/Helpers/ModalCom";
function AddJobPage({ action, situation }) {
function AddJobPage({ action, situation, categories }) {
return (
<ModalCom action={action} situation={situation} className="addJob-popup">
<div className="lg:w-[600px] w-full h-full lg:overflow-hidden lg:rounded-2xl bg-white dark:bg-dark-white ">
<ModalCom action={action} situation={situation} className="edit-popup">
<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] ">
<p className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
Create New Job
@@ -31,7 +31,7 @@ function AddJobPage({ action, situation }) {
</svg>
</button>
</div>
<AddJob popUpHandler={action} />
<AddJob popUpHandler={action} categories={categories} />
</div>
</ModalCom>
);
+3 -1
View File
@@ -1,9 +1,11 @@
import MyJobs from "../components/MyJobs";
import MyJobs from "../components/MyJobs";
import { useSelector } from "react-redux";
export default function MyJobsPage() {
let { commonHeadBanner } = useSelector((state) => state.commonHeadBanner);
const { userJobList } = useSelector((state) => state.userJobList);
return (
<>
<MyJobs
+5 -5
View File
@@ -1,12 +1,12 @@
import React from 'react'
import Referral from '../components/Referral/Index'
import React from "react";
import Referral from "../components/Referral/Index";
function ReferralPage() {
return (
<>
<Referral />
<Referral />
</>
)
);
}
export default ReferralPage
export default ReferralPage;