Compare commits
56 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 59945c28e4 | |||
| 5a623dd147 | |||
| 9265fde343 | |||
| 452bb73bef | |||
| cfec230ce3 | |||
| 87430f530d | |||
| 52cb0cb2da | |||
| a19df45997 | |||
| 7868e7d689 | |||
| 08f1ae1a9f | |||
| c4cc27490b | |||
| 90b609d457 | |||
| a6c6c36fbc | |||
| 03b79f0e0c | |||
| 0af52df1d2 | |||
| 9e1a68f81a | |||
| 12e4b7824a | |||
| 5769332e74 | |||
| bab0296f4f | |||
| d457550d58 | |||
| f106e17ce6 | |||
| 8f1d2b6584 | |||
| 3a3503447a | |||
| e46d2bea8d | |||
| b05c519571 | |||
| 48ab2d80ad | |||
| 47876875cf | |||
| d78ad0b648 | |||
| d63690a43c | |||
| 3ce97a4b76 | |||
| 6e9af99d46 | |||
| 4ce8f813c4 | |||
| 9163c42d77 | |||
| 3b4ce9c99e | |||
| cfa6117a07 | |||
| 6f26e2e88f | |||
| b7927a9d6a | |||
| 2d366cd103 | |||
| 6eed7bf1f3 | |||
| 3c87a67581 | |||
| e31ee86299 | |||
| 4d3fe6a799 | |||
| 3e8c8e88ea | |||
| feca65eb80 | |||
| 9ea846bc56 | |||
| 8c31eb3145 | |||
| d049d1b2b0 | |||
| d34895c64c | |||
| 9a3fa2a4a4 | |||
| a9d982386c | |||
| 2341d2a17d | |||
| 076df9438d | |||
| bbf03b2b10 | |||
| afead464b0 | |||
| dcdf03e9c5 | |||
| 44e2402cb3 |
@@ -9,11 +9,11 @@ REACT_APP_APPSITE="https://myfitapp.mermsemr.com"
|
|||||||
|
|
||||||
# REACT_APP_AUX_ENDPOINT="http://10.20.30.32:9083/svs/user"
|
# REACT_APP_AUX_ENDPOINT="http://10.20.30.32:9083/svs/user"
|
||||||
# REACT_APP_USERS_ENDPOINT="http://10.20.30.32:9083/svs/user"
|
# REACT_APP_USERS_ENDPOINT="http://10.20.30.32:9083/svs/user"
|
||||||
REACT_APP_AUX_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/svs/user"
|
#REACT_APP_AUX_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/svs/user"
|
||||||
REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/svs/user"
|
#REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/svs/user"
|
||||||
|
|
||||||
#REACT_APP_AUX_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
|
REACT_APP_AUX_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
|
||||||
#REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
|
REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
|
||||||
|
|
||||||
#"https://devapi.mermsemr.com/en/desktop/api/v2/myfituser"
|
#"https://devapi.mermsemr.com/en/desktop/api/v2/myfituser"
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -9,11 +9,11 @@ REACT_APP_APPSITE="https://myfitapp.mermsemr.com"
|
|||||||
|
|
||||||
# REACT_APP_AUX_ENDPOINT="http://10.20.30.32:9083/svs/user"
|
# REACT_APP_AUX_ENDPOINT="http://10.20.30.32:9083/svs/user"
|
||||||
# REACT_APP_USERS_ENDPOINT="http://10.20.30.32:9083/svs/user"
|
# REACT_APP_USERS_ENDPOINT="http://10.20.30.32:9083/svs/user"
|
||||||
REACT_APP_AUX_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/svs/user"
|
# REACT_APP_AUX_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/svs/user"
|
||||||
REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/svs/user"
|
# REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/svs/user"
|
||||||
|
|
||||||
#REACT_APP_AUX_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
|
REACT_APP_AUX_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
|
||||||
#REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
|
REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api/v1"
|
||||||
|
|
||||||
#"https://devapi.mermsemr.com/en/desktop/api/v2/myfituser"
|
#"https://devapi.mermsemr.com/en/desktop/api/v2/myfituser"
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -9,11 +9,11 @@ REACT_APP_APPSITE="https://myfitapp.mermsemr.com"
|
|||||||
|
|
||||||
# REACT_APP_AUX_ENDPOINT="http://10.20.30.32:9083/svs/user"
|
# REACT_APP_AUX_ENDPOINT="http://10.20.30.32:9083/svs/user"
|
||||||
# REACT_APP_USERS_ENDPOINT="http://10.20.30.32:9083/svs/user"
|
# REACT_APP_USERS_ENDPOINT="http://10.20.30.32:9083/svs/user"
|
||||||
REACT_APP_AUX_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/svs/user"
|
#REACT_APP_AUX_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/svs/user"
|
||||||
REACT_APP_USERS_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/svs/user"
|
#REACT_APP_USERS_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/svs/user"
|
||||||
|
|
||||||
#REACT_APP_AUX_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/en/wrench/api/v1"
|
REACT_APP_AUX_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/en/wrench/api/v1"
|
||||||
#REACT_APP_USERS_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/en/wrench/api/v1"
|
REACT_APP_USERS_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/en/wrench/api/v1"
|
||||||
|
|
||||||
#"https://devapi.mermsemr.com/en/desktop/api/v2/myfituser"
|
#"https://devapi.mermsemr.com/en/desktop/api/v2/myfituser"
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -89,7 +89,7 @@ export default function Routers() {
|
|||||||
<Route exact path="/notification" element={<Notification />} />
|
<Route exact path="/notification" element={<Notification />} />
|
||||||
<Route exact path="/mytask" element={<MyTaskPage />} />
|
<Route exact path="/mytask" element={<MyTaskPage />} />
|
||||||
<Route exact path="/myjobs" element={<MyJobsPage />} />
|
<Route exact path="/myjobs" element={<MyJobsPage />} />
|
||||||
<Route exact path="/add-job" element={<AddJobPage />} />
|
{/* <Route exact path="/add-job" element={<AddJobPage />} /> */}
|
||||||
<Route exact path="/my-active-jobs" element={<MyActiveJobsPage />} />
|
<Route exact path="/my-active-jobs" element={<MyActiveJobsPage />} />
|
||||||
<Route exact path="/my-pastdue-jobs" element={<MyPastDueJobsPage />} />
|
<Route exact path="/my-pastdue-jobs" element={<MyPastDueJobsPage />} />
|
||||||
<Route exact path="/my-pending-jobs" element={<MyPendingJobsPage />} />
|
<Route exact path="/my-pending-jobs" element={<MyPendingJobsPage />} />
|
||||||
|
|||||||
@@ -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 |
@@ -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 |
@@ -3,11 +3,8 @@ import { Link } from "react-router-dom";
|
|||||||
import InputCom from "../Helpers/Inputs/InputCom";
|
import InputCom from "../Helpers/Inputs/InputCom";
|
||||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||||
import usersService from "../../services/UsersService";
|
import usersService from "../../services/UsersService";
|
||||||
|
|
||||||
import { useSelector, useDispatch } from "react-redux";
|
import { useSelector, useDispatch } from "react-redux";
|
||||||
|
|
||||||
import { tableReload } from "../../store/TableReloads";
|
import { tableReload } from "../../store/TableReloads";
|
||||||
|
|
||||||
import { Field, Form, Formik } from "formik";
|
import { Field, Form, Formik } from "formik";
|
||||||
import * as Yup from "yup";
|
import * as Yup from "yup";
|
||||||
|
|
||||||
@@ -36,9 +33,10 @@ const validationSchema = Yup.object().shape({
|
|||||||
.typeError("you must specify a number")
|
.typeError("you must specify a number")
|
||||||
.min(1, "Price must be greater than 0")
|
.min(1, "Price must be greater than 0")
|
||||||
.required("Timeline is required"),
|
.required("Timeline is required"),
|
||||||
|
category: Yup.array().min(1, "Select at least one checkbox"),
|
||||||
});
|
});
|
||||||
|
|
||||||
function AddJob({ popUpHandler }) {
|
function AddJob({ popUpHandler, categories }) {
|
||||||
const ApiCall = new usersService();
|
const ApiCall = new usersService();
|
||||||
let dispatch = useDispatch();
|
let dispatch = useDispatch();
|
||||||
|
|
||||||
@@ -58,6 +56,7 @@ function AddJob({ popUpHandler }) {
|
|||||||
description: "",
|
description: "",
|
||||||
job_detail: "",
|
job_detail: "",
|
||||||
timeline_days: "",
|
timeline_days: "",
|
||||||
|
category: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
let [requestStatus, setRequestStatus] = useState({
|
let [requestStatus, setRequestStatus] = useState({
|
||||||
@@ -88,6 +87,7 @@ function AddJob({ popUpHandler }) {
|
|||||||
|
|
||||||
// FUNCTION TO HANDLE ADD JOB FORM
|
// FUNCTION TO HANDLE ADD JOB FORM
|
||||||
const handleAddJob = (values, helpers) => {
|
const handleAddJob = (values, helpers) => {
|
||||||
|
values.category = values.category?.join("@");
|
||||||
setRequestStatus({ loading: true, status: false, message: "" });
|
setRequestStatus({ loading: true, status: false, message: "" });
|
||||||
ApiCall.jobManagerCreateJob(values)
|
ApiCall.jobManagerCreateJob(values)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
@@ -106,7 +106,7 @@ function AddJob({ popUpHandler }) {
|
|||||||
});
|
});
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
dispatch(tableReload({ type: "JOBTABLE" }));
|
dispatch(tableReload({ type: "JOBTABLE" }));
|
||||||
popUpHandler()
|
popUpHandler();
|
||||||
}, 1000);
|
}, 1000);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
@@ -141,7 +141,7 @@ function AddJob({ popUpHandler }) {
|
|||||||
<div className="fields w-full">
|
<div className="fields w-full">
|
||||||
{/* inputs starts here */}
|
{/* inputs starts here */}
|
||||||
{/* country */}
|
{/* country */}
|
||||||
<div className="xl:flex xl:space-x-7 mb-6">
|
<div className="xl:flex xl:space-x-7 mb-[5px]">
|
||||||
<div className="field w-full mb-6 xl:mb-0">
|
<div className="field w-full mb-6 xl:mb-0">
|
||||||
<label
|
<label
|
||||||
htmlFor="country"
|
htmlFor="country"
|
||||||
@@ -187,11 +187,6 @@ function AddJob({ popUpHandler }) {
|
|||||||
</option>
|
</option>
|
||||||
)}
|
)}
|
||||||
</select>
|
</select>
|
||||||
{props.errors.country && props.touched.country && (
|
|
||||||
<p className="text-sm text-red-500">
|
|
||||||
{props.errors.country}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Price */}
|
{/* Price */}
|
||||||
@@ -207,18 +202,14 @@ function AddJob({ popUpHandler }) {
|
|||||||
value={props.values.price}
|
value={props.values.price}
|
||||||
inputHandler={props.handleChange}
|
inputHandler={props.handleChange}
|
||||||
blurHandler={props.handleBlur}
|
blurHandler={props.handleBlur}
|
||||||
|
errorBorder={props.errors.price && props.touched.price}
|
||||||
/>
|
/>
|
||||||
{props.errors.price && props.touched.price && (
|
|
||||||
<p className="text-sm text-red-500">
|
|
||||||
{props.errors.price}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Title */}
|
{/* Title */}
|
||||||
|
|
||||||
<div className="field w-full mb-6">
|
<div className="field w-full mb-[5px]">
|
||||||
<InputCom
|
<InputCom
|
||||||
fieldClass="px-6"
|
fieldClass="px-6"
|
||||||
label="Title"
|
label="Title"
|
||||||
@@ -226,20 +217,15 @@ function AddJob({ popUpHandler }) {
|
|||||||
inputBg="bg-slate-100"
|
inputBg="bg-slate-100"
|
||||||
type="text"
|
type="text"
|
||||||
name="title"
|
name="title"
|
||||||
// placeholder="Enter Job Title"
|
|
||||||
value={props.values.title}
|
value={props.values.title}
|
||||||
inputHandler={props.handleChange}
|
inputHandler={props.handleChange}
|
||||||
blurHandler={props.handleBlur}
|
blurHandler={props.handleBlur}
|
||||||
|
errorBorder={props.errors.title && props.touched.title}
|
||||||
/>
|
/>
|
||||||
{props.errors.title && props.touched.title && (
|
|
||||||
<p className="text-sm text-red-500">
|
|
||||||
{props.errors.title}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Description */}
|
{/* Description */}
|
||||||
<div className="field w-full mb-6">
|
<div className="field w-full mb-[5px]">
|
||||||
<InputCom
|
<InputCom
|
||||||
fieldClass="px-6"
|
fieldClass="px-6"
|
||||||
label="Description"
|
label="Description"
|
||||||
@@ -247,20 +233,18 @@ function AddJob({ popUpHandler }) {
|
|||||||
inputBg="bg-slate-100"
|
inputBg="bg-slate-100"
|
||||||
type="text"
|
type="text"
|
||||||
name="description"
|
name="description"
|
||||||
// placeholder="Enter a description"
|
|
||||||
value={props.values.description}
|
value={props.values.description}
|
||||||
inputHandler={props.handleChange}
|
inputHandler={props.handleChange}
|
||||||
blurHandler={props.handleBlur}
|
blurHandler={props.handleBlur}
|
||||||
|
errorBorder={
|
||||||
|
props.errors.description && props.touched.description
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
{props.errors.description && props.touched.description && (
|
|
||||||
<p className="text-sm text-red-500">
|
|
||||||
{props.errors.description}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Details */}
|
{/* Details */}
|
||||||
<div className="field w-full mb-6">
|
<div className="field flex flex-col sm:flex-row w-full mb-[5px] gap-2">
|
||||||
|
<div className="sm:w-[60%] w-full">
|
||||||
<label
|
<label
|
||||||
htmlFor="Job Delivery Details"
|
htmlFor="Job Delivery Details"
|
||||||
className='className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"'
|
className='className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"'
|
||||||
@@ -269,22 +253,55 @@ function AddJob({ popUpHandler }) {
|
|||||||
</label>
|
</label>
|
||||||
<textarea
|
<textarea
|
||||||
id="Job Delivery Details"
|
id="Job Delivery Details"
|
||||||
rows="7"
|
rows="5"
|
||||||
className={`input-field p-6 mt-3 rounded-md placeholder:text-base text-dark-gray dark:text-white w-full h-full bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none`}
|
className={`input-field px-6 py-2 placeholder:text-base text-dark-gray dark:text-white w-full h-[100px] bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-[#dce4e9] border border-[#dce4e9] rounded-[10px]`}
|
||||||
style={{ resize: "none" }}
|
style={{ resize: "none" }}
|
||||||
name="job_detail"
|
name="job_detail"
|
||||||
value={props.values.job_detail}
|
value={props.values.job_detail}
|
||||||
onChange={props.handleChange}
|
onChange={props.handleChange}
|
||||||
onBlur={props.handleBlur}
|
onBlur={props.handleBlur}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="sm:w-[35%] w-full">
|
||||||
|
<div
|
||||||
|
htmlFor="Job Categories"
|
||||||
|
className='className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"'
|
||||||
|
id="checked-group"
|
||||||
|
>
|
||||||
|
Categories
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="sm:flex-col flex flex-wrap px-3 mt-3"
|
||||||
|
role="group"
|
||||||
|
aria-labelledby="checked-group"
|
||||||
|
>
|
||||||
|
{Object.entries(categories).map(([key, value]) => (
|
||||||
|
<label
|
||||||
|
key={key}
|
||||||
|
className="flex gap-1 w-full items-center"
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
type="checkbox"
|
||||||
|
name="category"
|
||||||
|
value={key}
|
||||||
|
/>
|
||||||
|
<span className="text-[13.975px]">{value}</span>
|
||||||
|
</label>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* <div className={`${!props.errors && "invisible"} h-5`}>
|
||||||
{props.errors.job_detail && props.touched.job_detail && (
|
{props.errors.job_detail && props.touched.job_detail && (
|
||||||
<p className="text-sm text-red-500">
|
<p className="text-sm text-red-500">
|
||||||
{props.errors.job_detail}
|
{props.errors.job_detail}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
|
</div> */}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="field w-full mb-6">
|
<div className="field w-full mb-[5px]">
|
||||||
<div className={`flex items-center justify-between mb-2.5`}>
|
<div className={`flex items-center justify-between mb-2.5`}>
|
||||||
<label
|
<label
|
||||||
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"
|
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"
|
||||||
@@ -313,12 +330,6 @@ function AddJob({ popUpHandler }) {
|
|||||||
</option>
|
</option>
|
||||||
))}
|
))}
|
||||||
</Field>
|
</Field>
|
||||||
{props.errors.timeline_days &&
|
|
||||||
props.touched.timeline_days && (
|
|
||||||
<p className="text-sm text-red-500">
|
|
||||||
{props.errors.timeline_days}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
{/* inputs ends here */}
|
{/* inputs ends here */}
|
||||||
</div>
|
</div>
|
||||||
@@ -345,17 +356,20 @@ function AddJob({ popUpHandler }) {
|
|||||||
))}
|
))}
|
||||||
{/* End of error or success display */}
|
{/* End of error or success display */}
|
||||||
|
|
||||||
<div className="w-full h-[120px] border-t border-light-purple dark:border-[#5356fb29] flex justify-end items-center">
|
<div className="w-full h-[70px] border-t border-light-purple dark:border-[#5356fb29] flex justify-end items-center">
|
||||||
<div className="flex items-center space-x-4 mr-9">
|
<div className="flex items-center space-x-4 mr-9">
|
||||||
<Link
|
<button
|
||||||
to="/myjobs"
|
type="button"
|
||||||
className="text-18 text-light-red tracking-wide "
|
className="text-18 text-light-red tracking-wide "
|
||||||
>
|
>
|
||||||
<span className="border-b dark:border-[#5356fb29] border-light-red">
|
<span
|
||||||
|
className="border-b dark:border-[#5356fb29] border-light-red"
|
||||||
|
onClick={popUpHandler}
|
||||||
|
>
|
||||||
{" "}
|
{" "}
|
||||||
Cancel
|
Cancel
|
||||||
</span>
|
</span>
|
||||||
</Link>
|
</button>
|
||||||
|
|
||||||
{requestStatus.loading ? (
|
{requestStatus.loading ? (
|
||||||
<LoadingSpinner size="8" color="sky-blue" />
|
<LoadingSpinner size="8" color="sky-blue" />
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ export default function Login() {
|
|||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
let [loginType, setLoginType] = useState({ full: true, family: false });
|
let [loginType, setLoginType] = useState({ full: true, family: false });
|
||||||
|
const [selectedLoginType, setSelectedLoginType] = useState(
|
||||||
|
document.cookie.includes("loginType=family") ? "loginfamily" : "loginfull"
|
||||||
|
);
|
||||||
|
|
||||||
const [checked, setValue] = useState(false);
|
const [checked, setValue] = useState(false);
|
||||||
const [loginLoading, setLoginLoading] = useState(false);
|
const [loginLoading, setLoginLoading] = useState(false);
|
||||||
@@ -77,6 +80,10 @@ export default function Login() {
|
|||||||
login_mode: 1100,
|
login_mode: 1100,
|
||||||
action: 11025,
|
action: 11025,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Clear the loginType cookie if the user switches to loginfull
|
||||||
|
document.cookie =
|
||||||
|
"loginType=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
|
||||||
} else if (name == "loginfamily") {
|
} else if (name == "loginfamily") {
|
||||||
// Post Data Info for family Login
|
// Post Data Info for family Login
|
||||||
postData = {
|
postData = {
|
||||||
@@ -86,6 +93,8 @@ export default function Login() {
|
|||||||
login_mode: 1105,
|
login_mode: 1105,
|
||||||
action: 11025,
|
action: 11025,
|
||||||
};
|
};
|
||||||
|
// Set the loginType cookie to remember the user's selection
|
||||||
|
document.cookie = "loginType=family; expires=Session; path=/;";
|
||||||
} else {
|
} else {
|
||||||
setLoginLoading(false);
|
setLoginLoading(false);
|
||||||
setMsgError("Invalid Login Type. Consider refreshing the page");
|
setMsgError("Invalid Login Type. Consider refreshing the page");
|
||||||
@@ -127,8 +136,8 @@ export default function Login() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const googleLogin = useGoogleLogin({
|
const googleLogin = useGoogleLogin({
|
||||||
flow: 'auth-code',
|
flow: "auth-code",
|
||||||
ux_mode:'redirect',
|
ux_mode: "redirect",
|
||||||
redirect_uri: process.env.REACT_APP_GOOGLE_REDIRECT_URL,
|
redirect_uri: process.env.REACT_APP_GOOGLE_REDIRECT_URL,
|
||||||
onSuccess: async (codeResponse) => {
|
onSuccess: async (codeResponse) => {
|
||||||
console.log("GOOGLE LOGIN GOOD --- ", codeResponse);
|
console.log("GOOGLE LOGIN GOOD --- ", codeResponse);
|
||||||
@@ -136,6 +145,15 @@ export default function Login() {
|
|||||||
onError: (errorResponse) => console.log(errorResponse),
|
onError: (errorResponse) => console.log(errorResponse),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// In order to update the selected login type whenever the component renders
|
||||||
|
useEffect(() => {
|
||||||
|
setSelectedLoginType(
|
||||||
|
document.cookie.includes("loginType=family") ? "loginfamily" : "loginfull"
|
||||||
|
);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
console.log("Looking for the cookies >>", selectedLoginType)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setMail("");
|
setMail("");
|
||||||
setPassword("");
|
setPassword("");
|
||||||
|
|||||||
@@ -1,35 +1,24 @@
|
|||||||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||||
import { Link, useNavigate, } from "react-router-dom";
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
import { toast } from "react-toastify";
|
|
||||||
import localImgLoad from "../../lib/localImgLoad";
|
|
||||||
import Icons from "../Helpers/Icons";
|
|
||||||
import MarketPopUp from "../MarketPlace/PopUp/MarketPopUp";
|
import MarketPopUp from "../MarketPlace/PopUp/MarketPopUp";
|
||||||
import usersService from "../../services/UsersService";
|
import usersService from "../../services/UsersService";
|
||||||
|
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
||||||
|
import dataImage2 from "../../assets/images/data-table-user-2.png";
|
||||||
|
|
||||||
export default function AvailableJobsCard({
|
export default function AvailableJobsCard({
|
||||||
className,
|
className,
|
||||||
datas,
|
datas,
|
||||||
hidden = false,
|
hidden = false,
|
||||||
|
contentDisplay
|
||||||
}) {
|
}) {
|
||||||
//debugger;
|
//debugger;
|
||||||
const [addFavorite, setValue] = useState(datas.whishlisted);
|
|
||||||
const [marketPopUp, setMarketPopUp] = useState({ show: false, data: {} });
|
const [marketPopUp, setMarketPopUp] = useState({ show: false, data: {} });
|
||||||
const [manageInt, setManageInt] = useState(null)
|
const [manageInt, setManageInt] = useState(null);
|
||||||
|
const [imageUrl, setImageUrl] = useState("");
|
||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const apiCall = useMemo(() => new usersService(), []);
|
const apiCall = useMemo(() => new usersService(), []);
|
||||||
|
|
||||||
|
|
||||||
const favoriteHandler = () => {
|
|
||||||
if (!addFavorite) {
|
|
||||||
setValue(true);
|
|
||||||
toast.success("Added to Favorite List");
|
|
||||||
} else {
|
|
||||||
setValue(false);
|
|
||||||
toast.warn("Remove to Favorite List");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const marketInterestData = useCallback(async () => {
|
const marketInterestData = useCallback(async () => {
|
||||||
let { offer_code } = datas;
|
let { offer_code } = datas;
|
||||||
let reqData = { offer_code };
|
let reqData = { offer_code };
|
||||||
@@ -37,21 +26,32 @@ export default function AvailableJobsCard({
|
|||||||
try {
|
try {
|
||||||
const manageInt = await apiCall.MarketInterest(reqData);
|
const manageInt = await apiCall.MarketInterest(reqData);
|
||||||
const manageIntRes = await manageInt?.data;
|
const manageIntRes = await manageInt?.data;
|
||||||
setManageInt(manageIntRes)
|
setManageInt(manageIntRes);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error(error)
|
throw new Error(error);
|
||||||
}
|
}
|
||||||
|
}, [apiCall, datas]);
|
||||||
|
|
||||||
}, [])
|
let thePrice = PriceFormatter(
|
||||||
|
datas?.price * 0.01,
|
||||||
|
datas?.currency_code,
|
||||||
|
datas?.currency
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!datas) {
|
if (!datas) {
|
||||||
navigate("/market", { replace: true });
|
navigate("/market", { replace: true });
|
||||||
}
|
}
|
||||||
marketInterestData()
|
marketInterestData();
|
||||||
}, [marketInterestData, datas])
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const imagePath = require(`../../assets/images/${datas.thumbnil}`); // Replace with your directory path for local images
|
||||||
|
setImageUrl(imagePath);
|
||||||
|
}, []);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
{contentDisplay == 'grid' ?
|
||||||
<div
|
<div
|
||||||
className={`card-style-two w-full h-[426px] p-[20px] bg-white dark:bg-dark-white rounded-2xl section-shadow ${
|
className={`card-style-two w-full h-[426px] p-[20px] bg-white dark:bg-dark-white rounded-2xl section-shadow ${
|
||||||
className || ""
|
className || ""
|
||||||
@@ -87,11 +87,9 @@ export default function AvailableJobsCard({
|
|||||||
</div>
|
</div>
|
||||||
<div className="thumbnail-area w-full">
|
<div className="thumbnail-area w-full">
|
||||||
<div
|
<div
|
||||||
className="w-full h-[236px] p-6 rounded-xl overflow-hidden"
|
className="w-full h-[236px] p-6 rounded-xl overflow-hidden bg-center bg-cover bg-no-repeat"
|
||||||
style={{
|
style={{
|
||||||
background: `url(${localImgLoad(
|
backgroundImage: `url('${imageUrl}')`,
|
||||||
`images/${datas.thumbnil}`
|
|
||||||
)}) 0% 0% / cover no-repeat`,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="flex justify-center">{datas.description}</div>
|
<div className="flex justify-center">{datas.description}</div>
|
||||||
@@ -124,11 +122,14 @@ export default function AvailableJobsCard({
|
|||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<div>
|
<div>
|
||||||
<p className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white">
|
<p className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white">
|
||||||
{datas.price * 0.01}
|
{/* {thePrice} | {datas.timeline_days} day(s) */}
|
||||||
{datas.currency} | {datas.timeline_days} day(s)
|
{thePrice}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-sm text-lighter-gray">
|
<p className="text-sm text-lighter-gray">
|
||||||
( {datas.offer_code})
|
( {datas.offer_code}) |
|
||||||
|
<span className="italic ml-1">
|
||||||
|
{datas.timeline_days} day(s)
|
||||||
|
</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -137,7 +138,7 @@ export default function AvailableJobsCard({
|
|||||||
type="button"
|
type="button"
|
||||||
className="px-4 py-2.5 text-white text-sm bg-pink rounded-full tracking-wide"
|
className="px-4 py-2.5 text-white text-sm bg-pink rounded-full tracking-wide"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setMarketPopUp({show: true, data: datas})
|
setMarketPopUp({ show: true, data: datas });
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
View
|
View
|
||||||
@@ -147,6 +148,78 @@ export default function AvailableJobsCard({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
:
|
||||||
|
<div className="card-style-two w-full p-8 my-2 flex items-center gap-4 bg-white dark:bg-dark-white rounded-2xl section-shadow">
|
||||||
|
<div className="flex gap-5 items-center w-full">
|
||||||
|
<div className="w-full h-[60px] rounded-full overflow-hidden flex justify-center items-center flex-[0.1] min-w-[60px] max-w-[60px]">
|
||||||
|
<img src={dataImage2} alt="data" className="w-full h-full" />
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col flex-[0.9]">
|
||||||
|
<Link to="/shop-details" className="">
|
||||||
|
<h1 className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
|
||||||
|
{datas?.title}
|
||||||
|
</h1>
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<div className="my-2">
|
||||||
|
<p className="text-dark-gray dark:text-white">{datas?.description}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* <div className="card-two-info flex gap-2 items-center">
|
||||||
|
<div className="owned-by flex space-x-2 items-center">
|
||||||
|
<div>
|
||||||
|
<p className="text-thin-light-gray text-sm leading-3">Added</p>
|
||||||
|
<p className="text-base text-dark-gray dark:text-white">
|
||||||
|
{datas.offer_added}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="w-[1px] bg-light-purple dark:bg-dark-light-purple h-7"></div>
|
||||||
|
<div className="created-by flex space-x-2 items-center flex-row-reverse">
|
||||||
|
<div>
|
||||||
|
<p className="text-thin-light-gray text-sm leading-3 text-right">
|
||||||
|
Expires
|
||||||
|
</p>
|
||||||
|
<p className="text-base text-dark-gray dark:text-white text-right">
|
||||||
|
{datas.expire}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div> */}
|
||||||
|
<div className="block sm:flex flex-wrap gap-4">
|
||||||
|
<p className="text-sm text-thin-light-gray flex flext-start gap-1">
|
||||||
|
Price: <span className="text-purple">{thePrice}</span>
|
||||||
|
</p>
|
||||||
|
<p className="text-sm text-thin-light-gray">
|
||||||
|
Duration:{" "}
|
||||||
|
<span className="text-purple italic">
|
||||||
|
{" "}
|
||||||
|
{datas?.timeline_days} day(s)
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<p className="text-sm text-thin-light-gray">
|
||||||
|
Code:{" "}
|
||||||
|
<span className="text-purple">
|
||||||
|
{" "}
|
||||||
|
{datas?.offer_code}
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="px-4 py-2.5 text-white text-sm bg-pink rounded-full tracking-wide"
|
||||||
|
onClick={() => {
|
||||||
|
setMarketPopUp({ show: true, data: datas });
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
View
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
{marketPopUp.show && (
|
{marketPopUp.show && (
|
||||||
<MarketPopUp
|
<MarketPopUp
|
||||||
details={datas}
|
details={datas}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ export default function HomeBannerOffersCard(props) {
|
|||||||
let { banner, banner_location } = props?.itemData;
|
let { banner, banner_location } = props?.itemData;
|
||||||
if (banner_location === "LOCAL") {
|
if (banner_location === "LOCAL") {
|
||||||
const imagePath = require(`../../assets/images/${banner}`); // Replace with your directory path for local images
|
const imagePath = require(`../../assets/images/${banner}`); // Replace with your directory path for local images
|
||||||
console.log("This is local");
|
|
||||||
setImageUrl(imagePath);
|
setImageUrl(imagePath);
|
||||||
} else if (banner_location === "URL") setImageUrl(banner);
|
} else if (banner_location === "URL") setImageUrl(banner);
|
||||||
else return null;
|
else return null;
|
||||||
@@ -30,7 +29,6 @@ export default function HomeBannerOffersCard(props) {
|
|||||||
<span className="heroSilderTitle">{props.itemData.title}</span>
|
<span className="heroSilderTitle">{props.itemData.title}</span>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
{/*<SelectBox datas={filterDatas} action={dataSetHandler} />*/}
|
|
||||||
</div>
|
</div>
|
||||||
<div className="h-[233px]">
|
<div className="h-[233px]">
|
||||||
<div className="siderCardDescription">
|
<div className="siderCardDescription">
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ export default function FamilyTasks({ familyData, className, loader }) {
|
|||||||
{value.title}
|
{value.title}
|
||||||
</h1>
|
</h1>
|
||||||
<div className="flex gap-4 items-center">
|
<div className="flex gap-4 items-center">
|
||||||
<span className="text-sm text-thin-light-gray">
|
<span className="text-sm text-thin-light-gray flex flex-start gap-1">
|
||||||
Price:{" "}
|
Price:{" "}
|
||||||
<span className="text-purple">
|
<span className="text-purple">
|
||||||
{thePrice}
|
{thePrice}
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
|
import ATMCard from '../../assets/images/card.svg'
|
||||||
|
import VisaCard from '../../assets/images/visa.svg'
|
||||||
|
import MasterCard from '../../assets/images/master.svg'
|
||||||
|
|
||||||
export default function Icons({ name }) {
|
export default function Icons({ name }) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -483,6 +487,12 @@ export default function Icons({ name }) {
|
|||||||
c0.3,0,0.5-0.1,0.7-0.3l5.7-5.7c0,0,0,0,0,0C15.9,12.3,15.9,11.7,15.5,11.3z"
|
c0.3,0,0.5-0.1,0.7-0.3l5.7-5.7c0,0,0,0,0,0C15.9,12.3,15.9,11.7,15.5,11.3z"
|
||||||
></path>
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
|
) : name === "atm-card" ? (
|
||||||
|
<img className="w-[20px]" src={ATMCard} alt="card" />
|
||||||
|
) : name === "visa-card" ? (
|
||||||
|
<img className="w-[20px]" src={VisaCard} alt="card" />
|
||||||
|
) : name === "master-card" ? (
|
||||||
|
<img className="w-[20px]" src={MasterCard} alt="card" />
|
||||||
) : (
|
) : (
|
||||||
""
|
""
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ export default function InputCom({
|
|||||||
blurHandler,
|
blurHandler,
|
||||||
spanTag,
|
spanTag,
|
||||||
inputBg,
|
inputBg,
|
||||||
direction
|
direction,
|
||||||
|
errorBorder
|
||||||
}) {
|
}) {
|
||||||
const inputRef = useRef(null);
|
const inputRef = useRef(null);
|
||||||
// Entry Validation
|
// Entry Validation
|
||||||
@@ -51,11 +52,16 @@ export default function InputCom({
|
|||||||
htmlFor={name}
|
htmlFor={name}
|
||||||
>
|
>
|
||||||
{label}
|
{label}
|
||||||
{spanTag && (
|
{spanTag &&
|
||||||
|
spanTag == '*' ?
|
||||||
|
<span className="text-red-700 text-sm tracking-wide">
|
||||||
|
{' '}{spanTag}
|
||||||
|
</span>
|
||||||
|
:
|
||||||
<span className="text-green-700 text-sm tracking-wide">
|
<span className="text-green-700 text-sm tracking-wide">
|
||||||
{spanTag}
|
{spanTag}
|
||||||
</span>
|
</span>
|
||||||
)}
|
}
|
||||||
</label>
|
</label>
|
||||||
)}
|
)}
|
||||||
{forgotPassword && (
|
{forgotPassword && (
|
||||||
@@ -68,7 +74,7 @@ export default function InputCom({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className={`input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base ${inputClass}`}
|
className={`input-wrapper border ${errorBorder ? "border-red-500 border-[0.5px] animate-shake" : "border border-[#f5f8fa] dark:border-[#5e6278]"} w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base ${inputClass}`}
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
@@ -89,8 +95,12 @@ export default function InputCom({
|
|||||||
dir={direction}
|
dir={direction}
|
||||||
/>
|
/>
|
||||||
{iconName && (
|
{iconName && (
|
||||||
<div className="absolute right-6 bottom-[10px] z-10">
|
<div className="absolute right-6 bottom-[10px] z-10 flex gap-2">
|
||||||
<Icons name={iconName} />
|
{
|
||||||
|
iconName.split(' ').map((item, index)=>(
|
||||||
|
<Icons key={index} name={item} />
|
||||||
|
))
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{passIcon && (
|
{passIcon && (
|
||||||
|
|||||||
@@ -1,16 +1,48 @@
|
|||||||
export const PriceFormatter = (price, currency, currencyName) => {
|
import React from 'react'
|
||||||
const supportedCurrencies = ["USD", "EUR", "GBP"];
|
|
||||||
const symbolFormatter = supportedCurrencies.includes(currency)
|
|
||||||
? currency
|
|
||||||
: undefined;
|
|
||||||
|
|
||||||
const formatter = new Intl.NumberFormat("en", {
|
// export const PriceFormatter = (price, currency, currencyName) => {
|
||||||
style: symbolFormatter,
|
// const supportedCurrencies = ["USD", "EUR", "GBP"];
|
||||||
currencyDisplay: "symbol",
|
// const symbolFormatter = supportedCurrencies.includes(currency)
|
||||||
minimumFractionDigits: 2,
|
// ? currency
|
||||||
});
|
// : undefined;
|
||||||
|
|
||||||
const displayCurrencyName = symbolFormatter ? "" : currencyName;
|
// const formatter = new Intl.NumberFormat("en", {
|
||||||
|
// style: symbolFormatter,
|
||||||
|
// currencyDisplay: "symbol",
|
||||||
|
// minimumFractionDigits: 2,
|
||||||
|
// });
|
||||||
|
|
||||||
return `${formatter.format(price)} ${displayCurrencyName}`;
|
// const displayCurrencyName = symbolFormatter ? "" : currencyName;
|
||||||
};
|
|
||||||
|
// return `${formatter.format(price)} ${displayCurrencyName}`;
|
||||||
|
// };
|
||||||
|
|
||||||
|
|
||||||
|
export const PriceFormatter = (price='00', currency='', currencyName='') => {
|
||||||
|
// Convert the number to a string
|
||||||
|
let numStr = String(price);
|
||||||
|
|
||||||
|
// Split the string into integer and decimal parts
|
||||||
|
let parts = numStr.split('.');
|
||||||
|
let integerPart = parts[0];
|
||||||
|
let decimalPart = parts[1] || '';
|
||||||
|
|
||||||
|
// Add thousands separators to the integer part
|
||||||
|
// let formattedInteger = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
||||||
|
let formattedInteger = integerPart;
|
||||||
|
|
||||||
|
// Truncate or pad the decimal part to two decimal points
|
||||||
|
let formattedDecimal = decimalPart.slice(0, 2).padEnd(2, '0');
|
||||||
|
|
||||||
|
// Combine the formatted integer and decimal parts
|
||||||
|
// let formattedNumber = formattedInteger + '.' + formattedDecimal;
|
||||||
|
|
||||||
|
// return formattedNumber;
|
||||||
|
return (
|
||||||
|
<span className='text-sm flex items-center'>
|
||||||
|
<sup>{currency || currencyName || ''}</sup>
|
||||||
|
<span className='px-1 font-bold text-lg'>{formattedInteger}</span>
|
||||||
|
<sup>{formattedDecimal}</sup>
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import useToggle from "../../../hooks/useToggle";
|
import useToggle from "../../../hooks/useToggle";
|
||||||
|
|
||||||
function SelectBox({ datas = [], className, action, contentBodyClasses }) {
|
function SelectBox({ datas = [], className, action, contentBodyClasses, position }) {
|
||||||
const [item, setItem] = useState(datas[0]);
|
const [item, setItem] = useState(datas[0]);
|
||||||
// custom hook
|
// custom hook
|
||||||
const [toggle, setToggle] = useToggle(false);
|
const [toggle, setToggle] = useToggle(false);
|
||||||
@@ -49,7 +49,7 @@ function SelectBox({ datas = [], className, action, contentBodyClasses }) {
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
style={{ boxShadow: "0px 4px 87px 0px #0000002B" }}
|
style={{ boxShadow: "0px 4px 87px 0px #0000002B" }}
|
||||||
className={`drop-down-content w-[120px] bg-white dark:bg-dark-white rounded-[4px] p-3 absolute right-0 top-[100%] z-20 ${
|
className={`drop-down-content w-[120px] bg-white dark:bg-dark-white rounded-[4px] p-3 absolute ${position =='left' ? 'left-0' : 'right-0'} top-[100%] z-20 ${
|
||||||
toggle ? "active" : ""
|
toggle ? "active" : ""
|
||||||
} ${contentBodyClasses || ""}`}
|
} ${contentBodyClasses || ""}`}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ export default function History() {
|
|||||||
|
|
||||||
const apiCall = new usersService()
|
const apiCall = new usersService()
|
||||||
|
|
||||||
|
let [tab, setTab] = useState("purchases"); //STATE FOR SWITCHING BETWEEN TABS
|
||||||
|
|
||||||
let [paymentHistory, setPaymentHistory] = useState({ // FOR PAYMENT HISTORY
|
let [paymentHistory, setPaymentHistory] = useState({ // FOR PAYMENT HISTORY
|
||||||
loading: true,
|
loading: true,
|
||||||
data: [],
|
data: [],
|
||||||
@@ -63,7 +65,7 @@ export default function History() {
|
|||||||
<>
|
<>
|
||||||
<Layout>
|
<Layout>
|
||||||
<div className="history-wrapper w-full mb-10">
|
<div className="history-wrapper w-full mb-10">
|
||||||
<div className="main-wrapper w-full">
|
<div className="w-full">
|
||||||
<div className="sm:flex justify-between items-center mb-6">
|
<div className="sm:flex justify-between items-center mb-6">
|
||||||
<div className="mb-5 sm:mb-0">
|
<div className="mb-5 sm:mb-0">
|
||||||
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
|
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
|
||||||
@@ -213,24 +215,47 @@ export default function History() {
|
|||||||
{/*</div>*/}
|
{/*</div>*/}
|
||||||
{/*<MarketHistorySection />*/}
|
{/*<MarketHistorySection />*/}
|
||||||
{/* <TopHxBox className="mb-11" /> */}
|
{/* <TopHxBox className="mb-11" /> */}
|
||||||
<div className='w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin'>
|
<div className='w-full p-4 md:p-8 bg-white dark:bg-dark-white rounded-2xl shadow bottomMargin'>
|
||||||
|
{/* switch button */}
|
||||||
|
<div className="my-1 flex items-center border-b border-slate-300">
|
||||||
|
<button
|
||||||
|
name="purchases"
|
||||||
|
onClick={(e) => setTab(e.target.name)}
|
||||||
|
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border ${
|
||||||
|
tab == "purchases" ? "border-sky-blue" : "border-slate-300"
|
||||||
|
} tracking-wide transition duration-200`}
|
||||||
|
>
|
||||||
|
Purchases
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
name="recent"
|
||||||
|
onClick={(e) => setTab(e.target.name)}
|
||||||
|
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border ${
|
||||||
|
tab == "recent" ? "border-sky-blue" : "border-slate-300"
|
||||||
|
} tracking-wide transition duration-200`}
|
||||||
|
>
|
||||||
|
Recent Activity
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{/* END OF switch button */}
|
||||||
|
<div className="history-tables w-full">
|
||||||
{/* PURCHASE SECTION */}
|
{/* PURCHASE SECTION */}
|
||||||
<div className="lg:w-1/2 w-full mb-10 lg:mb-0">
|
{tab == 'purchases' &&
|
||||||
<div className="wallet w-full md:p-8 p-4 h-full max-h-[700px] bg-white dark:bg-dark-white overflow-y-auto rounded-2xl shadow">
|
<div className="wallet w-full border-t">
|
||||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">Purchases</h1>
|
<h1 className="p-2 text-xl font-bold text-dark-gray dark:text-white tracking-wide">Purchases</h1>
|
||||||
{purchaseHistory.loading ?
|
{purchaseHistory.loading ?
|
||||||
<LoadingSpinner size='16' color='sky-blue' />
|
<LoadingSpinner size='16' color='sky-blue' />
|
||||||
:
|
:
|
||||||
<PurchasesTable purchase={purchaseHistory} />
|
<PurchasesTable purchase={purchaseHistory} />
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
}
|
||||||
{/* END OF PURCHASE SECTION */}
|
{/* END OF PURCHASE SECTION */}
|
||||||
|
|
||||||
{/* RECENT ACTIVITY SECTION */}
|
{/* RECENT ACTIVITY SECTION */}
|
||||||
<div className="lg:w-1/2 w-full mb-10 lg:mb-0">
|
{tab == 'recent' &&
|
||||||
<div className="wallet w-full md:p-8 p-4 h-full max-h-[700px] bg-white dark:bg-dark-white overflow-y-auto rounded-2xl shadow">
|
<div className="wallet w-full border-t">
|
||||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">Recent Activity</h1>
|
<h1 className="p-2 text-xl font-bold text-dark-gray dark:text-white tracking-wide">Recent Activity</h1>
|
||||||
{/* <p className='text-base text-slate-500 dark:text-white'>Activity Report</p> */}
|
{/* <p className='text-base text-slate-500 dark:text-white'>Activity Report</p> */}
|
||||||
{paymentHistory.loading ?
|
{paymentHistory.loading ?
|
||||||
<LoadingSpinner size='16' color='sky-blue' />
|
<LoadingSpinner size='16' color='sky-blue' />
|
||||||
@@ -238,9 +263,10 @@ export default function History() {
|
|||||||
<RecentActivityTable payment={paymentHistory} />
|
<RecentActivityTable payment={paymentHistory} />
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
}
|
||||||
{/* END OF RECENT ACTIVITY SECTION */}
|
{/* END OF RECENT ACTIVITY SECTION */}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
{/*<HistoryTable />*/}
|
{/*<HistoryTable />*/}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,106 +1,105 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useMemo, useState } from "react";
|
||||||
import DataIteration from "../Helpers/DataIteration";
|
import DataIteration from "../Helpers/DataIteration";
|
||||||
import AvailableJobsCard from "../Cards/AvailableJobsCard";
|
import AvailableJobsCard from "../Cards/AvailableJobsCard";
|
||||||
|
import ListView from '../../assets/images/list-view.png'
|
||||||
|
import GridView from '../../assets/images/grid-view.svg'
|
||||||
|
import SelectBox from "../Helpers/SelectBox";
|
||||||
|
|
||||||
export default function MainSection({ className, marketPlaceProduct }) {
|
export default function MainSection({
|
||||||
const [tab, setTab] = useState("all");
|
className,
|
||||||
const [products, setProducts] = useState(marketPlaceProduct);
|
marketPlaceProduct,
|
||||||
|
categories,
|
||||||
|
}) {
|
||||||
|
// Creating All cart..
|
||||||
|
let marketCategories = useMemo(
|
||||||
|
() => ({ All: "All Categories", ...categories }),
|
||||||
|
[categories]
|
||||||
|
);
|
||||||
|
const [tab, setTab] = useState(Object.keys(marketCategories)[0]);
|
||||||
|
|
||||||
|
let [contentDisplay, setContentDisplay] = useState('grid') // STATE TO HOLD LIST VIEW STYLE
|
||||||
|
|
||||||
|
// Convert to array in order to map
|
||||||
|
const mappedArray = Object.entries(marketCategories).map(([key, value]) => {
|
||||||
|
return { key, value };
|
||||||
|
});
|
||||||
|
|
||||||
|
const [products, setProducts] = useState([]);
|
||||||
const tabHandler = (value) => {
|
const tabHandler = (value) => {
|
||||||
setTab(value);
|
setTab(value);
|
||||||
};
|
};
|
||||||
useEffect(() => {
|
|
||||||
if (tab === "artist") {
|
// Handles the category selection on mobile view
|
||||||
setProducts(marketPlaceProduct?.slice(0, 3));
|
const handleSetCategory = (value) => {
|
||||||
} else if (tab === "market") {
|
for (let i in marketCategories) {
|
||||||
setProducts(marketPlaceProduct?.slice(0, 6));
|
if (marketCategories[i] == value) {
|
||||||
} else if (tab === "shop") {
|
setTab(i);
|
||||||
setProducts(marketPlaceProduct?.slice(6, 9));
|
|
||||||
} else if (tab === "assets") {
|
|
||||||
setProducts(marketPlaceProduct?.slice(3, 6));
|
|
||||||
} else {
|
|
||||||
setProducts(marketPlaceProduct);
|
|
||||||
}
|
}
|
||||||
}, [tab, marketPlaceProduct]);
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (tab === "All") {
|
||||||
|
setProducts(marketPlaceProduct);
|
||||||
|
} else {
|
||||||
|
const filteredProducts = marketPlaceProduct.filter((product) =>
|
||||||
|
product.category.includes(tab)
|
||||||
|
);
|
||||||
|
setProducts(filteredProducts);
|
||||||
|
}
|
||||||
|
}, [tab, marketPlaceProduct, categories, marketCategories]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`market-place-section w-full ${className || ""}`}>
|
<div className={`market-place-section w-full ${className || ""}`}>
|
||||||
<div className="market-place-wrapper w-full">
|
<div className="market-place-wrapper w-full">
|
||||||
<div className="filter-navigate-area lg:flex justify-between mb-8 items-center">
|
<div className="filter-navigate-area flex justify-between items-center mb-8">
|
||||||
<div className="tab-item lg:mb-0 mb-5">
|
<div className="tab-item w-full flex items-center">
|
||||||
<div className="md:flex md:space-x-8 space-x-2">
|
<div className="hidden lg:flex md:space-x-8 space-x-2">
|
||||||
|
{mappedArray.map(({ key, value }) => (
|
||||||
<span
|
<span
|
||||||
onClick={() => tabHandler("all")}
|
key={key}
|
||||||
|
onClick={() => tabHandler(key)}
|
||||||
className={`md:text-[18px] text-md text-dark-gray dark:text-white hover:text-pink border-b hover:border-pink font-medium cursor-pointer ${
|
className={`md:text-[18px] text-md text-dark-gray dark:text-white hover:text-pink border-b hover:border-pink font-medium cursor-pointer ${
|
||||||
tab === "all"
|
tab === key
|
||||||
? "text-pink border-pink"
|
? "text-pink border-pink"
|
||||||
: " border-transparent"
|
: " border-transparent"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
All
|
{value}
|
||||||
</span>
|
</span>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
<span
|
{/* market categories on screen smaller than large screen */}
|
||||||
onClick={() => tabHandler("artist")}
|
<div className="w-[80%] lg:hidden">
|
||||||
className={`md:text-[18px] text-md text-dark-gray dark:text-white hover:text-pink border-b hover:border-pink font-medium cursor-pointer ${
|
<SelectBox
|
||||||
tab === "artist"
|
action={handleSetCategory}
|
||||||
? "text-pink border-pink"
|
datas={Object.values(marketCategories)}
|
||||||
: " border-transparent"
|
className="Update-table-dropdown"
|
||||||
}`}
|
contentBodyClasses="w-auto min-w-max"
|
||||||
>
|
position='left'
|
||||||
Featured Artist
|
/>
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
onClick={() => tabHandler("market")}
|
|
||||||
className={`md:text-[18px] text-md text-dark-gray dark:text-white hover:text-pink border-b hover:border-pink font-medium cursor-pointer ${
|
|
||||||
tab === "market"
|
|
||||||
? "text-pink border-pink"
|
|
||||||
: " border-transparent"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
Open Market
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
onClick={() => tabHandler("shop")}
|
|
||||||
className={`md:text-[18px] text-md text-dark-gray dark:text-white hover:text-pink border-b hover:border-pink font-medium cursor-pointer ${
|
|
||||||
tab === "shop"
|
|
||||||
? "text-pink border-pink"
|
|
||||||
: " border-transparent"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
Partner Shops
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
onClick={() => tabHandler("assets")}
|
|
||||||
className={`md:text-[18px] text-md text-dark-gray dark:text-white hover:text-pink border-b hover:border-pink font-medium cursor-pointer ${
|
|
||||||
tab === "assets"
|
|
||||||
? "text-pink border-pink"
|
|
||||||
: " border-transparent"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
Game Assets
|
|
||||||
</span>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{/* contentDisplay toggler */}
|
||||||
{/*<div className="search-item flex lg:flex-none justify-end">*/}
|
<div className="p-2 w-[35px] h-[35px] bg-white dark:bg-slate-200 rounded-lg">
|
||||||
{/* <SearchCom*/}
|
<img
|
||||||
{/* className="lg:bg-transparent"*/}
|
title={contentDisplay=='grid'? 'list view' : 'grid view'}
|
||||||
{/* inputClasses="lg:bg-transparent"*/}
|
onClick={()=>setContentDisplay((prev)=>prev=='grid'? 'list' : 'grid')}
|
||||||
{/* />*/}
|
src={contentDisplay=='grid'? ListView : GridView}
|
||||||
{/*</div>*/}
|
className="w-full h-full cursor-pointer" alt="view"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/* end of contentDisplay toggler */}
|
||||||
</div>
|
</div>
|
||||||
<div className="filter-navigate-content w-full min-h-screen">
|
<div className="filter-navigate-content w-full min-h-screen">
|
||||||
<div className="grid lg:grid-cols-3 sm:grid-cols-2 gap-[30px]">
|
<div className={contentDisplay == 'grid' ? 'grid lg:grid-cols-3 sm:grid-cols-2 gap-[30px]' : 'w-full'}>
|
||||||
<DataIteration
|
<DataIteration
|
||||||
datas={products}
|
datas={products}
|
||||||
startLength={process.env.REACT_APP_ZERO_STATE}
|
startLength={process.env.REACT_APP_ZERO_STATE}
|
||||||
endLength={products?.length}
|
endLength={products?.length}
|
||||||
>
|
>
|
||||||
{({ datas }) => (
|
{({ datas }) => (
|
||||||
<AvailableJobsCard key={datas.id} datas={datas} />
|
<AvailableJobsCard contentDisplay={contentDisplay} key={datas.id} datas={datas} />
|
||||||
)}
|
)}
|
||||||
</DataIteration>
|
</DataIteration>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { toast } from "react-toastify";
|
|||||||
import { Form, Formik } from "formik";
|
import { Form, Formik } from "formik";
|
||||||
import usersService from "../../../services/UsersService";
|
import usersService from "../../../services/UsersService";
|
||||||
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
||||||
|
import { PriceFormatter } from "../../Helpers/PriceFormatter";
|
||||||
|
|
||||||
const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
||||||
const [marketMsg, setMarketMsg] = useState({
|
const [marketMsg, setMarketMsg] = useState({
|
||||||
@@ -96,14 +97,18 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
|||||||
[apiCall, details, onClose, textValue]
|
[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 addedIntDate = marketInt?.added?.split(" ")[0];
|
||||||
let expireIntDate = marketInt?.expire?.split(" ")[0];
|
let expireIntDate = marketInt?.expire?.split(" ")[0];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalCom action={onClose} situation={situation} className="edit-popup">
|
<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]">
|
<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">
|
<h1 className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
|
||||||
{details.offer_code}
|
{details.offer_code}
|
||||||
@@ -112,8 +117,8 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="md:flex bg-white rounded-lg">
|
<div className="md:flex bg-white rounded-lg">
|
||||||
<div className="p-4 w-full md:w-3/4 md:border-r-1">
|
<div className="p-4 w-full md:w-[75%] md:border-r-1">
|
||||||
<div className="min-h-[290px]">
|
<div className="min-h-[263px]">
|
||||||
<h2 className="font-semibold text-slate-900 dark:text-black tracking-wide">
|
<h2 className="font-semibold text-slate-900 dark:text-black tracking-wide">
|
||||||
{details?.title}
|
{details?.title}
|
||||||
</h2>
|
</h2>
|
||||||
@@ -128,7 +133,7 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
|||||||
name: "",
|
name: "",
|
||||||
content: {
|
content: {
|
||||||
text: `Timeline: ${details.timeline_days} day(s) -- `,
|
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) => (
|
].map(({ name, content, danger }, idx) => (
|
||||||
<div className={`my-3 md:flex items-center`} key={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}
|
{name}
|
||||||
</label>
|
</label>
|
||||||
<div
|
<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" ? (
|
{name !== "Delivery Detail" ? (
|
||||||
<>
|
<>
|
||||||
{typeof content !== "object" ? content : null}
|
{typeof content !== "object" ? content : null}
|
||||||
{typeof content === "object" && (
|
{typeof content === "object" && (
|
||||||
|
<>
|
||||||
|
<hr className="mb-1" />
|
||||||
<span className="flex items-center gap-2">
|
<span className="flex items-center gap-2">
|
||||||
{content?.text}
|
{content?.text}
|
||||||
<strong>{content?.bold}</strong>
|
<strong>{thePrice}</strong>
|
||||||
</span>
|
</span>
|
||||||
|
<hr className="mt-1" />
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
@@ -207,15 +216,15 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="w-full md:w-1/4 h-full ">
|
<div className="w-full md:w-[23%] 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="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">
|
<div className="w-full flex flex-col justify-center py-4 gap-2">
|
||||||
<p className="w-full text-slate-900 tracking-wide my-1">
|
<p className="w-full text-slate-900 tracking-wide my-1">
|
||||||
Interested in the task?
|
Interested in the task?
|
||||||
</p>
|
</p>
|
||||||
<hr />
|
<hr />
|
||||||
<button
|
<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"
|
name="market-interest"
|
||||||
onClick={marketCalls}
|
onClick={marketCalls}
|
||||||
>
|
>
|
||||||
@@ -251,6 +260,13 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
|||||||
<p className="my-1">Expire: {expireIntDate}</p>
|
<p className="my-1">Expire: {expireIntDate}</p>
|
||||||
</div>
|
</div>
|
||||||
</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>
|
</div>
|
||||||
{/* END OF ACTION SECTION */}
|
{/* END OF ACTION SECTION */}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
import React from "react";
|
|
||||||
// import products from "../../data/marketplace_data.json";
|
|
||||||
//import CreateNft from "../Home/CreateNft";
|
|
||||||
import Layout from "../Partials/Layout";
|
import Layout from "../Partials/Layout";
|
||||||
import MainSection from "./MainSection";
|
import MainSection from "./MainSection";
|
||||||
import CommonHead from "../UserHeader/CommonHead";
|
import CommonHead from "../UserHeader/CommonHead";
|
||||||
@@ -9,13 +6,17 @@ import { useSelector } from "react-redux";
|
|||||||
export default function MarketPlace({ commonHeadData }) {
|
export default function MarketPlace({ commonHeadData }) {
|
||||||
let { jobLists } = useSelector((state) => state.jobLists);
|
let { jobLists } = useSelector((state) => state.jobLists);
|
||||||
const marketData = jobLists?.result_list;
|
const marketData = jobLists?.result_list;
|
||||||
|
const categories = jobLists?.categories;
|
||||||
|
|
||||||
// const marketProduct = products.data;
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Layout>
|
<Layout>
|
||||||
<CommonHead commonHeadData={commonHeadData} />
|
<CommonHead commonHeadData={commonHeadData} />
|
||||||
<MainSection marketPlaceProduct={marketData} className="mb-10" />
|
<MainSection
|
||||||
|
marketPlaceProduct={marketData}
|
||||||
|
categories={categories}
|
||||||
|
className="mb-10"
|
||||||
|
/>
|
||||||
</Layout>
|
</Layout>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ export default function MyActiveJobTable({ MyJobList, className }) {
|
|||||||
{value.title}
|
{value.title}
|
||||||
</h1>
|
</h1>
|
||||||
<div>{value.description}</div>
|
<div>{value.description}</div>
|
||||||
<span className="text-sm text-thin-light-gray">
|
<span className="text-sm text-thin-light-gray flex flext-start gap-1">
|
||||||
Price:{" "}
|
Price:{" "}
|
||||||
<span className="text-purple">
|
<span className="text-purple">
|
||||||
{thePrice}
|
{thePrice}
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||||
import dataImage2 from "../../assets/images/data-table-user-2.png";
|
import dataImage2 from "../../assets/images/data-table-user-2.png";
|
||||||
import SelectBox from "../Helpers/SelectBox";
|
import SelectBox from "../Helpers/SelectBox";
|
||||||
import DeleteJobPopout from "../jobPopout/DeleteJobPopout";
|
import DeleteJobPopout from "../jobPopout/DeleteJobPopout";
|
||||||
import JobListPopout from "../jobPopout/JobListPopout";
|
import JobListPopout from "../jobPopout/JobListPopout";
|
||||||
|
|
||||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||||
|
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
import usersService from "../../services/UsersService";
|
import usersService from "../../services/UsersService";
|
||||||
import { handlePagingFunc } from "../Pagination/HandlePagination";
|
import { handlePagingFunc } from "../Pagination/HandlePagination";
|
||||||
@@ -14,6 +12,23 @@ import EditJobPopOut from "../jobPopout/EditJobPopout";
|
|||||||
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
||||||
|
|
||||||
export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
||||||
|
// Getting the categories
|
||||||
|
const currentJobCart = MyJobList?.data?.categories;
|
||||||
|
// DropDown Box
|
||||||
|
const filterCategories = { All: "All Categories", ...currentJobCart };
|
||||||
|
|
||||||
|
const [selectedCategory, setCategory] = useState(
|
||||||
|
Object.keys(filterCategories)[0]
|
||||||
|
);
|
||||||
|
|
||||||
|
let [jobPopout, setJobPopout] = useState({ show: false, data: {} }); // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW
|
||||||
|
|
||||||
|
let [deleteJobPopout, setDeleteJobPopout] = useState({
|
||||||
|
show: false,
|
||||||
|
data: {},
|
||||||
|
}); // STATE TO HOLD THE VALUE OF THE ITEM DETAILS TO DELETE AND DETERMINE WHEN TO SHOW
|
||||||
|
const [editJob, setEditJob] = useState({ show: false, data: {} });
|
||||||
|
|
||||||
const [myCountry, setCountries] = useState("");
|
const [myCountry, setCountries] = useState("");
|
||||||
const {
|
const {
|
||||||
userDetails: { country },
|
userDetails: { country },
|
||||||
@@ -45,22 +60,25 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
|||||||
getCountryList();
|
getCountryList();
|
||||||
}, [getCountryList]);
|
}, [getCountryList]);
|
||||||
|
|
||||||
const filterCategories = ["All Categories", "Explore", "Featured"];
|
// Handle Pagination
|
||||||
const [selectedCategory, setCategory] = useState(filterCategories[0]);
|
|
||||||
|
|
||||||
let [jobPopout, setJobPopout] = useState({ show: false, data: {} }); // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW
|
|
||||||
|
|
||||||
let [deleteJobPopout, setDeleteJobPopout] = useState({
|
|
||||||
show: false,
|
|
||||||
data: {},
|
|
||||||
}); // STATE TO HOLD THE VALUE OF THE ITEM DETAILS TO DELETE AND DETERMINE WHEN TO SHOW
|
|
||||||
const [editJob, setEditJob] = useState({ show: false, data: {} });
|
|
||||||
|
|
||||||
const [currentPage, setCurrentPage] = useState(0);
|
const [currentPage, setCurrentPage] = useState(0);
|
||||||
const indexOfFirstItem = Number(currentPage);
|
const indexOfFirstItem = Number(currentPage);
|
||||||
const indexOfLastItem =
|
const indexOfLastItem =
|
||||||
Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
||||||
const currentJobList = MyJobList?.data?.result_list?.slice(
|
|
||||||
|
// Handle Filter Job List
|
||||||
|
const filterJobList = () => {
|
||||||
|
if (selectedCategory === "All") return MyJobList?.data?.result_list;
|
||||||
|
else
|
||||||
|
return MyJobList?.data?.result_list?.filter((item) =>
|
||||||
|
item.category.includes(selectedCategory)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const currentJobList = filterJobList();
|
||||||
|
|
||||||
|
// Handling Filter Pagination
|
||||||
|
const filteredCurrentJobList = currentJobList?.slice(
|
||||||
indexOfFirstItem,
|
indexOfFirstItem,
|
||||||
indexOfLastItem
|
indexOfLastItem
|
||||||
);
|
);
|
||||||
@@ -69,42 +87,17 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
|||||||
handlePagingFunc(e, setCurrentPage);
|
handlePagingFunc(e, setCurrentPage);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
// Handles the category selection
|
||||||
<div
|
const handleSetCategory = (value) => {
|
||||||
className={`update-table w-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow min-h-[520px] ${
|
setCurrentPage(0);
|
||||||
className || ""
|
for (let i in filterCategories) {
|
||||||
}`}
|
if (filterCategories[i] == value) {
|
||||||
>
|
setCategory(i);
|
||||||
<div className="header w-full flex justify-between items-center mb-5">
|
}
|
||||||
<div className="flex space-x-2 items-center">
|
}
|
||||||
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">
|
};
|
||||||
All Jobs
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
<SelectBox
|
|
||||||
action={setCategory}
|
|
||||||
datas={filterCategories}
|
|
||||||
className="Update-table-dropdown"
|
|
||||||
contentBodyClasses="w-auto min-w-max"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{MyJobList.loading ? (
|
|
||||||
<LoadingSpinner size="16" color="sky-blue" />
|
|
||||||
) : (
|
|
||||||
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between h-full">
|
|
||||||
<table className="table-auto min-w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
|
||||||
<tbody>
|
|
||||||
<tr className="text-base text-thin-light-gray border-b default-border-b dark:border-[#5356fb29] ottom ">
|
|
||||||
<td className="py-1">.</td>
|
|
||||||
<td className="py-1 text-right">.</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
{selectedCategory === "All Categories" ? (
|
const JobListItem = ({ value, index }) => {
|
||||||
<>
|
|
||||||
{MyJobList &&
|
|
||||||
MyJobList?.data?.result_list &&
|
|
||||||
MyJobList.data?.result_list.length > 0 ? (
|
|
||||||
currentJobList.map((value, index) => {
|
|
||||||
let thePrice = PriceFormatter(
|
let thePrice = PriceFormatter(
|
||||||
value?.price * 0.01,
|
value?.price * 0.01,
|
||||||
value?.currency_code,
|
value?.currency_code,
|
||||||
@@ -119,22 +112,15 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
|||||||
<div className="sm:flex sm:space-x-2 sm:justify-between sm:items-center job-items">
|
<div className="sm:flex sm:space-x-2 sm:justify-between sm:items-center job-items">
|
||||||
<div className="flex space-x-2 items-center job-items w-full">
|
<div className="flex space-x-2 items-center job-items w-full">
|
||||||
<div className="w-full h-[60px] rounded-full overflow-hidden flex justify-center items-center flex-[0.1] min-w-[60px] max-w-[60px]">
|
<div className="w-full h-[60px] rounded-full overflow-hidden flex justify-center items-center flex-[0.1] min-w-[60px] max-w-[60px]">
|
||||||
<img
|
<img src={dataImage2} alt="data" className="w-full h-full" />
|
||||||
src={dataImage2}
|
|
||||||
alt="data"
|
|
||||||
className="w-full h-full"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col flex-[0.9]">
|
<div className="flex flex-col flex-[0.9]">
|
||||||
<h1 className="font-bold text-xl text-dark-gray dark:text-white">
|
<h1 className="font-bold text-xl text-dark-gray dark:text-white">
|
||||||
{value.title}
|
{value.title}
|
||||||
</h1>
|
</h1>
|
||||||
<div>{value.description}</div>
|
<div>{value.description}</div>
|
||||||
<span className="text-sm text-thin-light-gray">
|
<span className="text-sm text-thin-light-gray flex items-start gap-1">
|
||||||
Price:{" "}
|
Price: <span className="text-purple">{thePrice}</span>
|
||||||
<span className="text-purple">
|
|
||||||
{thePrice}
|
|
||||||
</span>
|
|
||||||
</span>
|
</span>
|
||||||
<span className="text-sm text-thin-light-gray">
|
<span className="text-sm text-thin-light-gray">
|
||||||
Duration:{" "}
|
Duration:{" "}
|
||||||
@@ -153,7 +139,7 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
setDeleteJobPopout({
|
setDeleteJobPopout({
|
||||||
show: true,
|
show: true,
|
||||||
data: value,
|
data: { thePrice, ...value },
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -166,7 +152,7 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
setEditJob({
|
setEditJob({
|
||||||
show: true,
|
show: true,
|
||||||
data: value,
|
data: { thePrice, ...value },
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -180,7 +166,7 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setJobPopout({ show: true, data: value });
|
setJobPopout({ show: true, data: { thePrice, ...value } });
|
||||||
}}
|
}}
|
||||||
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||||
>
|
>
|
||||||
@@ -188,18 +174,55 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
|||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
)})
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={`update-table w-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow min-h-[520px] ${
|
||||||
|
className || ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<div className="header w-full flex justify-between items-center mb-5">
|
||||||
|
<div className="flex space-x-2 items-center">
|
||||||
|
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">
|
||||||
|
{filterCategories[selectedCategory]} Jobs
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<SelectBox
|
||||||
|
action={handleSetCategory}
|
||||||
|
datas={Object.values(filterCategories)}
|
||||||
|
className="Update-table-dropdown"
|
||||||
|
contentBodyClasses="w-auto min-w-max"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{MyJobList.loading ? (
|
||||||
|
<LoadingSpinner size="16" color="sky-blue" />
|
||||||
|
) : (
|
||||||
|
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between h-full">
|
||||||
|
<table className="table-auto min-w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
||||||
|
<tbody>
|
||||||
|
<>
|
||||||
|
{MyJobList &&
|
||||||
|
MyJobList?.data?.result_list &&
|
||||||
|
MyJobList.data?.result_list.length > 0 ? (
|
||||||
|
filteredCurrentJobList?.length ? (
|
||||||
|
filteredCurrentJobList.map((value, index) => (
|
||||||
|
<JobListItem index={index} key={index} value={value} />
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<tr className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
|
||||||
|
<td className="p-2">
|
||||||
|
No Jobs Available In This Category!
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)
|
||||||
) : (
|
) : (
|
||||||
<tr className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
|
<tr className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
|
||||||
<td className="p-2">No Jobs Avaliable!</td>
|
<td className="p-2">No Jobs Avaliable!</td>
|
||||||
</tr>
|
</tr>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
) : selectedCategory === "Explore" ? (
|
|
||||||
<></>
|
|
||||||
) : (
|
|
||||||
<></>
|
|
||||||
)}
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
@@ -209,11 +232,11 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
|||||||
prev={currentPage == 0 ? true : false}
|
prev={currentPage == 0 ? true : false}
|
||||||
next={
|
next={
|
||||||
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
|
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
|
||||||
MyJobList?.data?.result_list?.length
|
currentJobList?.length
|
||||||
? true
|
? true
|
||||||
: false
|
: false
|
||||||
}
|
}
|
||||||
data={MyJobList?.data?.result_list}
|
data={currentJobList}
|
||||||
start={indexOfFirstItem}
|
start={indexOfFirstItem}
|
||||||
stop={indexOfLastItem}
|
stop={indexOfLastItem}
|
||||||
/>
|
/>
|
||||||
@@ -257,6 +280,7 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
|
|||||||
}}
|
}}
|
||||||
situation={editJob.show}
|
situation={editJob.show}
|
||||||
country={myCountry}
|
country={myCountry}
|
||||||
|
categories={currentJobCart}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,16 +1,32 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { Link } from "react-router-dom";
|
import { useLocation, useNavigate } from "react-router-dom";
|
||||||
import Layout from "../Partials/Layout";
|
import Layout from "../Partials/Layout";
|
||||||
import MyJobTable from "./MyJobTable";
|
import MyJobTable from "./MyJobTable";
|
||||||
import CommonHead from "../UserHeader/CommonHead";
|
import CommonHead from "../UserHeader/CommonHead";
|
||||||
import AddJobPage from "../../views/AddJobPage";
|
import AddJobPage from "../../views/AddJobPage";
|
||||||
|
|
||||||
export default function MyJobs(props) {
|
export default function MyJobs(props) {
|
||||||
|
let { state } = useLocation();
|
||||||
|
const navigate = useNavigate();
|
||||||
const [popUp, setPopUp] = useState(false);
|
const [popUp, setPopUp] = useState(false);
|
||||||
|
|
||||||
|
console.log(state)
|
||||||
const popUpHandler = () => {
|
const popUpHandler = () => {
|
||||||
setPopUp((prev) => !prev);
|
setPopUp((prev) => !prev);
|
||||||
|
|
||||||
|
if (state?.popup) navigate("/", { replace: true });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const categoryOptions = props.MyJobList?.data?.categories;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!state?.popup) {
|
||||||
|
setPopUp(false);
|
||||||
|
} else {
|
||||||
|
setPopUp(true);
|
||||||
|
}
|
||||||
|
}, [state?.popup]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
<CommonHead commonHeadData={props.commonHeadData} />
|
<CommonHead commonHeadData={props.commonHeadData} />
|
||||||
@@ -36,7 +52,13 @@ export default function MyJobs(props) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Add Job List Popout */}
|
{/* Add Job List Popout */}
|
||||||
{popUp && <AddJobPage action={popUpHandler} situation={popUp} />}
|
{popUp && (
|
||||||
|
<AddJobPage
|
||||||
|
action={popUpHandler}
|
||||||
|
situation={popUp}
|
||||||
|
categories={categoryOptions}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
{/* End of Add Job List Popout */}
|
{/* End of Add Job List Popout */}
|
||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ export default function MyPendingJobTable({ MyJobList, className }) {
|
|||||||
{value.title}
|
{value.title}
|
||||||
</h1>
|
</h1>
|
||||||
<div>{value.description}</div>
|
<div>{value.description}</div>
|
||||||
<span className="text-sm text-thin-light-gray">
|
<span className="text-sm text-thin-light-gray flex items-start gap-1">
|
||||||
Price:{" "}
|
Price:{" "}
|
||||||
<span className="text-purple">
|
<span className="text-purple">
|
||||||
{thePrice}
|
{thePrice}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ export default function MyJobTable({ className, ActiveJobList }) {
|
|||||||
<span className="text-base text-gray-600">
|
<span className="text-base text-gray-600">
|
||||||
{task?.description}
|
{task?.description}
|
||||||
</span>
|
</span>
|
||||||
<span className="text-sm text-thin-light-gray">
|
<span className="text-sm text-thin-light-gray flex flext-start gap-1">
|
||||||
Price:
|
Price:
|
||||||
<span className="text-purple ml-1">{thePrice}</span>
|
<span className="text-purple ml-1">{thePrice}</span>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
import React, {useState} from 'react'
|
import React, {useState} from 'react'
|
||||||
import RecentActivityTable from './WalletComponent/RecentActivityTable'
|
import RecentActivityTable from './WalletComponent/RecentActivityTable'
|
||||||
import LoadingSpinner from '../Spinners/LoadingSpinner'
|
import LoadingSpinner from '../Spinners/LoadingSpinner'
|
||||||
import { useNavigate } from 'react-router-dom'
|
import { useNavigate, useLocation } from 'react-router-dom'
|
||||||
import InputCom from '../Helpers/Inputs/InputCom'
|
import InputCom from '../Helpers/Inputs/InputCom'
|
||||||
|
|
||||||
|
import AddFundDollars from './AddFundDollars'
|
||||||
|
|
||||||
function AddFund({payment}) {
|
function AddFund({payment}) {
|
||||||
|
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
|
const {currency} = useLocation()?.state //GETS THE USER CURRENCY FOR ADD FUND
|
||||||
|
|
||||||
//STATE FOR CONTROLLED INPUT
|
//STATE FOR CONTROLLED INPUT
|
||||||
let [input, setInput] = useState('0')
|
let [input, setInput] = useState('')
|
||||||
|
|
||||||
let [inputError, setInputError] = useState('')
|
let [inputError, setInputError] = useState('')
|
||||||
|
|
||||||
@@ -23,15 +26,15 @@ function AddFund({payment}) {
|
|||||||
setInputError('')
|
setInputError('')
|
||||||
if(!input || input == '0'){
|
if(!input || input == '0'){
|
||||||
setInputError('Please Enter Amount')
|
setInputError('Please Enter Amount')
|
||||||
return
|
return setTimeout(()=>{setInputError('')}, 5000)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isNaN(input)){
|
if(isNaN(input)){
|
||||||
setInputError('Amount must be a Number')
|
setInputError('Amount must be a Number')
|
||||||
return
|
return setTimeout(()=>{setInputError('')}, 5000)
|
||||||
}
|
}
|
||||||
|
|
||||||
const stateData = {amount: Number(input)}
|
const stateData = {amount: Number(input), currency: 'naira'}
|
||||||
navigate('confirm-add-fund', {state: stateData})
|
navigate('confirm-add-fund', {state: stateData})
|
||||||
|
|
||||||
setInput('')
|
setInput('')
|
||||||
@@ -79,18 +82,27 @@ function AddFund({payment}) {
|
|||||||
<div className="field w-full mb-6">
|
<div className="field w-full mb-6">
|
||||||
<InputCom
|
<InputCom
|
||||||
fieldClass="px-6"
|
fieldClass="px-6"
|
||||||
label="Amount(Naira)"
|
label={currency == 'US Dollars' ? "Amount (USD)" : "Amount (Naira)"}
|
||||||
type="text"
|
type="text"
|
||||||
name="amount"
|
name="amount"
|
||||||
placeholder="Amount"
|
placeholder="0"
|
||||||
value={input}
|
value={input}
|
||||||
inputHandler={handleChange}
|
inputHandler={handleChange}
|
||||||
// blurHandler={props.handleBlur}
|
|
||||||
/>
|
/>
|
||||||
{inputError && <p className='text-base text-red-500'>{inputError}</p>}
|
{inputError && <p className='text-base text-red-500'>{inputError}</p>}
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
|
{/* SHOWS THIS IF USER CURRENCY IS DOLLARS */}
|
||||||
|
{currency == 'US Dollars' &&
|
||||||
|
<div className='w-full md:p-8 p-4 bg-white dark:bg-dark-white rounded-2xl shadow'>
|
||||||
|
<AddFundDollars setInputError={setInputError} input={input} setInput={setInput} />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
{/* HIDES THIS BUTTON IF CURENCY IS NAIRA */}
|
||||||
|
{currency != 'US Dollars' &&
|
||||||
<div className='md:p-8 p-4 add-fund-btn flex justify-end items-center py-4'>
|
<div className='md:p-8 p-4 add-fund-btn flex justify-end items-center py-4'>
|
||||||
<button
|
<button
|
||||||
onClick={handleSubmit}
|
onClick={handleSubmit}
|
||||||
@@ -100,10 +112,13 @@ function AddFund({payment}) {
|
|||||||
<span className="text-white">Continue</span>
|
<span className="text-white">Continue</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* HIDES THIS SECTION IF CURENCY IS NAIRA */}
|
||||||
|
{currency != 'US Dollars' &&
|
||||||
<div className="content-wrapper w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin">
|
<div className="content-wrapper w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin">
|
||||||
<div className="lg:w-2/2 w-full mb-10 lg:mb-0">
|
<div className="lg:w-2/2 w-full mb-10 lg:mb-0">
|
||||||
<div className="wallet w-full md:p-8 p-4 h-full min-h-[590px] bg-white dark:bg-dark-white rounded-2xl shadow">
|
<div className="wallet w-full md:p-8 p-4 h-full min-h-[590px] bg-white dark:bg-dark-white rounded-2xl shadow">
|
||||||
@@ -117,6 +132,7 @@ function AddFund({payment}) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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})
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ import RecentActivityTable from './WalletComponent/RecentActivityTable'
|
|||||||
import PurchasesTable from './WalletComponent/PurchasesTable'
|
import PurchasesTable from './WalletComponent/PurchasesTable'
|
||||||
import CouponTable from './WalletComponent/CouponTable'
|
import CouponTable from './WalletComponent/CouponTable'
|
||||||
import LoadingSpinner from '../Spinners/LoadingSpinner'
|
import LoadingSpinner from '../Spinners/LoadingSpinner'
|
||||||
|
import { PriceFormatter } from '../Helpers/PriceFormatter'
|
||||||
|
|
||||||
function Balance({wallet, coupon}) {
|
function Balance({wallet, coupon}) {
|
||||||
return (
|
return (
|
||||||
@@ -42,11 +43,11 @@ function Balance({wallet, coupon}) {
|
|||||||
</div>
|
</div>
|
||||||
<div className='balance-info'>
|
<div className='balance-info'>
|
||||||
<p className='py-2'>Balance</p>
|
<p className='py-2'>Balance</p>
|
||||||
<span className='py-1 px-2 bg-green-100 text-green-500 rounded-lg'>{item.symbol}{(item.amount*0.01).toFixed(2)}</span>
|
<span className='py-1 px-2 bg-green-100 text-green-500 rounded-lg flex flex-start gap-1'>{PriceFormatter(item.amount * 0.01, item.code)}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className='balance-info'>
|
<div className='balance-info'>
|
||||||
<p className='py-2'>Escrow</p>
|
<p className='py-2'>Escrow</p>
|
||||||
<span className='py-1 px-2 bg-red-100 text-red-500 rounded-lg'>{item.symbol}{(item.escrow*0.01).toFixed(2)}</span>
|
<span className='py-1 px-2 bg-red-100 text-red-500 rounded-lg flex flex-start gap-1'>{PriceFormatter(item.escrow * 0.01, item.code)}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -55,7 +56,7 @@ function Balance({wallet, coupon}) {
|
|||||||
item.action_type != 'AC_AD_FD_ONLY' ?
|
item.action_type != 'AC_AD_FD_ONLY' ?
|
||||||
<Link to='transfer-fund' className='px-2 py-1 flex items-center gap-2 user-balance cursor-pointer h-[48px] rounded-full relative bg-purple lg:text-xl text-lg font-bold text-white'>Transfer</Link>:''
|
<Link to='transfer-fund' className='px-2 py-1 flex items-center gap-2 user-balance cursor-pointer h-[48px] rounded-full relative bg-purple lg:text-xl text-lg font-bold text-white'>Transfer</Link>:''
|
||||||
}
|
}
|
||||||
<Link to='add-fund' className='px-2 py-1 flex items-center gap-2 user-balance cursor-pointer h-[48px] rounded-full relative bg-green lg:text-xl text-lg font-bold text-white'>
|
<Link to='add-fund' state={{currency:item.description}} className='px-2 py-1 flex items-center gap-2 user-balance cursor-pointer h-[48px] rounded-full relative bg-green lg:text-xl text-lg font-bold text-white'>
|
||||||
<span className="">
|
<span className="">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="38"
|
<svg xmlns="http://www.w3.org/2000/svg" width="38"
|
||||||
height="38" viewBox="0 0 42 42" fill="none"><path
|
height="38" viewBox="0 0 42 42" fill="none"><path
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ function ConfirmAddFund({ payment }) {
|
|||||||
toast.success("Account Topup was sucessful");
|
toast.success("Account Topup was sucessful");
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
navigate("/my-wallet", { replace: true });
|
navigate("/my-wallet", { replace: true });
|
||||||
window.location.reload(true);
|
|
||||||
}, 1000);
|
}, 1000);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
@@ -102,11 +101,11 @@ function ConfirmAddFund({ payment }) {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="content-wrapper w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin">
|
<div className="content-wrapper w-full">
|
||||||
{pageLoading ? (
|
{pageLoading ? (
|
||||||
<LoadingSpinner size="8" color="sky-blue" />
|
<LoadingSpinner size="8" color="sky-blue" />
|
||||||
) : (
|
) : (
|
||||||
<div className="lg:w-1/2 w-full mb-10 lg:mb-0">
|
<div className="w-full mb-10">
|
||||||
<div className="add-fund w-full bg-white dark:bg-dark-white rounded-2xl shadow">
|
<div className="add-fund w-full bg-white dark:bg-dark-white rounded-2xl shadow">
|
||||||
<h2 className="md:p-8 p-4 text-slate-900 dark:text-white text-xl lg:text-2xl font-medium">
|
<h2 className="md:p-8 p-4 text-slate-900 dark:text-white text-xl lg:text-2xl font-medium">
|
||||||
Confirm Add Fund To Account
|
Confirm Add Fund To Account
|
||||||
@@ -116,7 +115,7 @@ function ConfirmAddFund({ payment }) {
|
|||||||
<div className="field w-full mb-3">
|
<div className="field w-full mb-3">
|
||||||
<InputCom
|
<InputCom
|
||||||
fieldClass="px-6"
|
fieldClass="px-6"
|
||||||
label="Amount (Naira):"
|
label={state.currency == 'naira' ? "Amount (Naira):" : "Amount (Dollars):"}
|
||||||
type="text"
|
type="text"
|
||||||
name="amount"
|
name="amount"
|
||||||
value={state.amount || ""}
|
value={state.amount || ""}
|
||||||
@@ -127,16 +126,26 @@ function ConfirmAddFund({ payment }) {
|
|||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
<div className="md:p-8 p-4 add-fund-btn flex justify-end items-center py-4">
|
<div className="md:p-8 p-4 add-fund-btn flex justify-end items-center py-4">
|
||||||
|
{
|
||||||
|
state.currency == 'naira' ?
|
||||||
<FlutterWaveButton
|
<FlutterWaveButton
|
||||||
{...fwConfig}
|
{...fwConfig}
|
||||||
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||||
/>
|
/>
|
||||||
|
:
|
||||||
|
<button
|
||||||
|
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||||
|
onClick={()=>console.log('WORKING')}
|
||||||
|
>
|
||||||
|
Continue
|
||||||
|
</button>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="lg:w-1/2 w-full mb-10 lg:mb-0">
|
<div className="w-full mb-10">
|
||||||
<div className="wallet w-full md:p-8 p-4 h-full min-h-[600px] bg-white dark:bg-dark-white rounded-2xl shadow">
|
<div className="wallet w-full md:p-8 p-4 h-full min-h-[600px] bg-white dark:bg-dark-white rounded-2xl shadow">
|
||||||
<h2 className="text-gray-900 dark:text-white text-xl lg:text-2xl font-medium">
|
<h2 className="text-gray-900 dark:text-white text-xl lg:text-2xl font-medium">
|
||||||
Recent Activity
|
Recent Activity
|
||||||
|
|||||||
@@ -15,11 +15,11 @@ function PurchasesTable({purchase}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='flex flex-col justify-between h-full'>
|
<div className='flex flex-col justify-between min-h-[500px]'>
|
||||||
<table className="wallet-activity w-full table-auto border-collapse text-left">
|
<table className="wallet-activity w-full table-auto border-collapse text-left">
|
||||||
<thead className='border-b-2'>
|
<thead className='border-b-2'>
|
||||||
<tr className='text-slate-600'>
|
<tr className='text-slate-600'>
|
||||||
<th className="p-4">Trx.</th>
|
<th className="p-2">Trx.</th>
|
||||||
<th className="p-2">Amount</th>
|
<th className="p-2">Amount</th>
|
||||||
<th className="p-2">Fee</th>
|
<th className="p-2">Fee</th>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -29,7 +29,7 @@ function PurchasesTable({purchase}) {
|
|||||||
<tbody>
|
<tbody>
|
||||||
{currentPurchase.map((item, index) => (
|
{currentPurchase.map((item, index) => (
|
||||||
<tr key={index} className='text-slate-500'>
|
<tr key={index} className='text-slate-500'>
|
||||||
<td className="p-4">{item.added_date}<br />
|
<td className="p-2">{item.added_date}<br />
|
||||||
<b>{item.confirmation} </b>
|
<b>{item.confirmation} </b>
|
||||||
</td>
|
</td>
|
||||||
<td className="p-2">{item.amount}</td>
|
<td className="p-2">{item.amount}</td>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ function RecentActivityTable({payment}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='flex flex-col justify-between h-full'>
|
<div className='flex flex-col justify-between min-h-[500px]'>
|
||||||
<table className="wallet-activity w-full table-auto border-collapse text-left">
|
<table className="wallet-activity w-full table-auto border-collapse text-left">
|
||||||
<thead className='border-b-2'>
|
<thead className='border-b-2'>
|
||||||
<tr className='text-slate-600'>
|
<tr className='text-slate-600'>
|
||||||
|
|||||||
@@ -1,60 +1,73 @@
|
|||||||
import React, {useState} from 'react'
|
import { useState } from "react";
|
||||||
|
import PaginatedList from "../../Pagination/PaginatedList";
|
||||||
import PaginatedList from '../../Pagination/PaginatedList';
|
import { handlePagingFunc } from "../../Pagination/HandlePagination";
|
||||||
import {handlePagingFunc} from '../../Pagination/HandlePagination';
|
|
||||||
|
|
||||||
function ReferralTable({ history }) {
|
function ReferralTable({ history }) {
|
||||||
|
|
||||||
const [currentPage, setCurrentPage] = useState(0);
|
const [currentPage, setCurrentPage] = useState(0);
|
||||||
const indexOfFirstItem = Number(currentPage);
|
const indexOfFirstItem = Number(currentPage);
|
||||||
const indexOfLastItem = Number(indexOfFirstItem)+Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
const indexOfLastItem =
|
||||||
const currentReferral = history?.data?.slice(indexOfFirstItem, indexOfLastItem);
|
Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
||||||
|
const currentReferral = history?.data?.slice(
|
||||||
|
indexOfFirstItem,
|
||||||
|
indexOfLastItem
|
||||||
|
);
|
||||||
|
|
||||||
const handlePagination = (e) => {
|
const handlePagination = (e) => {
|
||||||
handlePagingFunc(e,setCurrentPage)
|
handlePagingFunc(e, setCurrentPage);
|
||||||
}
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='flex flex-col justify-between min-h-[420px] overflow-x-auto'>
|
<div className="flex flex-col justify-between min-h-[420px] overflow-x-auto">
|
||||||
<table className="referral-list w-full table-auto border-collapse text-left">
|
<table className="referral-list w-full table-auto border-collapse text-left">
|
||||||
<thead className='border-b-2'>
|
<thead className="border-b-2">
|
||||||
<tr className='text-slate-600'>
|
<tr className="text-slate-600">
|
||||||
<th className="p-3">Added/Name</th>
|
<th className="p-3">Added/Name</th>
|
||||||
<th className="p-3">Email</th>
|
<th className="p-3">Email</th>
|
||||||
<th className="p-3">Status</th>
|
<th className="p-3">Status</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{history.data.length ?
|
{history.data.length ? (
|
||||||
currentReferral.map((item, index) => (
|
currentReferral.map((item, index) => (
|
||||||
<tr key={index} className='text-slate-500'>
|
<tr key={index} className="text-slate-500">
|
||||||
<td className="p-3">{item.added_date} / {item.firstname} {item.lastname}</td>
|
<td className="p-3">
|
||||||
|
{item.added_date} / {item.firstname} {item.lastname}
|
||||||
|
</td>
|
||||||
<td className="p-3">{item.email}</td>
|
<td className="p-3">{item.email}</td>
|
||||||
<td className="p-3">{item.status}</td>
|
<td className="p-3">{item.status}</td>
|
||||||
</tr>
|
</tr>
|
||||||
))
|
))
|
||||||
:
|
) : history.error ? (
|
||||||
(
|
<tr className="text-slate-500">
|
||||||
history.error ?
|
<td colSpan={3}>
|
||||||
<tr className='text-slate-500'>
|
Opps! couldn't get referral history. Try reloading the page
|
||||||
<td colSpan={3}>Opps! couldn't get referral history. Try reloading the page</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
:
|
) : (
|
||||||
(
|
<tr className="text-slate-500">
|
||||||
<tr className='text-slate-500'>
|
|
||||||
<td colSpan={3}>No Item Found on referral List</td>
|
<td colSpan={3}>No Item Found on referral List</td>
|
||||||
</tr>
|
</tr>
|
||||||
)
|
)}
|
||||||
)
|
|
||||||
}
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
{/* PAGINATION BUTTON */}
|
{/* PAGINATION BUTTON */}
|
||||||
<PaginatedList onClick={handlePagination} prev={currentPage == 0 ? true : false} next={currentPage+Number(process.env.REACT_APP_ITEM_PER_PAGE) >= history?.data?.length ? true : false} data={history?.data} start={indexOfFirstItem} stop={indexOfLastItem} />
|
<PaginatedList
|
||||||
|
onClick={handlePagination}
|
||||||
|
prev={currentPage == 0 ? true : false}
|
||||||
|
next={
|
||||||
|
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
|
||||||
|
history?.data?.length
|
||||||
|
? true
|
||||||
|
: false
|
||||||
|
}
|
||||||
|
data={history?.data}
|
||||||
|
start={indexOfFirstItem}
|
||||||
|
stop={indexOfLastItem}
|
||||||
|
/>
|
||||||
{/* END OF PAGINATION BUTTON */}
|
{/* END OF PAGINATION BUTTON */}
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ReferralTable
|
export default ReferralTable;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import bank2 from "../../assets/images/bank-2.png";
|
|||||||
import bank3 from "../../assets/images/bank-3.png";
|
import bank3 from "../../assets/images/bank-3.png";
|
||||||
import bank4 from "../../assets/images/bank-4.png";
|
import bank4 from "../../assets/images/bank-4.png";
|
||||||
import Accordion from "../Helpers/Accordion";
|
import Accordion from "../Helpers/Accordion";
|
||||||
|
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
||||||
|
|
||||||
export default function WalletHeader(props) {
|
export default function WalletHeader(props) {
|
||||||
// debugger;
|
// debugger;
|
||||||
@@ -58,10 +59,7 @@ export default function WalletHeader(props) {
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="eth text-xl font-bold text-purple">
|
<p className="eth text-xl font-bold text-purple">
|
||||||
{(value.amount * 0.01).toFixed(2)} {value.code}
|
{PriceFormatter(value.amount * 0.01, value.code)}
|
||||||
</p>
|
|
||||||
<p className="usd text-base text-thin-light-gray text-right">
|
|
||||||
{/*(773.69 USD)*/}
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import Layout from "../Partials/Layout";
|
|||||||
import CommonHead from "../UserHeader/CommonHead";
|
import CommonHead from "../UserHeader/CommonHead";
|
||||||
|
|
||||||
import usersService from "../../services/UsersService";
|
import usersService from "../../services/UsersService";
|
||||||
import { handlePagingFunc } from "../Pagination/HandlePagination";
|
// import { handlePagingFunc } from "../Pagination/HandlePagination";
|
||||||
import PaginatedList from "../Pagination/PaginatedList";
|
// import PaginatedList from "../Pagination/PaginatedList";
|
||||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||||
import OthersInterestedTable from "./OthersInterestedTable";
|
import OthersInterestedTable from "./OthersInterestedTable";
|
||||||
|
|
||||||
@@ -15,25 +15,72 @@ export default function ManageInterestOffer(props) {
|
|||||||
|
|
||||||
let [redirectTime, setRedirectTime] = useState(5)
|
let [redirectTime, setRedirectTime] = useState(5)
|
||||||
|
|
||||||
|
let [messageToSend, setMessageToSend] = useState('')
|
||||||
|
|
||||||
let [tab, setTab] = useState("info"); //message STATE FOR SWITCHING BETWEEN TABS
|
let [tab, setTab] = useState("info"); //message STATE FOR SWITCHING BETWEEN TABS
|
||||||
|
|
||||||
let [requestStatus, setRequestStatus] = useState({loading: false, status: false, message: '', processType: ''})
|
let [requestStatus, setRequestStatus] = useState({loading: false, status: false, message: '', processType: ''})
|
||||||
|
|
||||||
const messageList = {data: [1,2,3,4,5,6]} // TO BE REMOVED AND REPLACE WITH REAL MESSAGE FROM API CALL
|
let [messageListReload, setMessageListReload] = useState(false) // STATE TO DETERMINE WHEN MESSAGE LIST WILL RELOAD
|
||||||
const [currentPage, setCurrentPage] = useState(0);
|
|
||||||
const indexOfFirstItem = Number(currentPage);
|
|
||||||
const indexOfLastItem = Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
|
||||||
const currentMessageList = messageList?.data?.slice(indexOfFirstItem, indexOfLastItem);
|
|
||||||
|
|
||||||
const handlePagination = (e) => {
|
const [messageList, setMessageList] = useState({loading: true, data: [1,2,3,4,5,6,7,8,95,6,7,8,9]}) // TO BE REMOVED AND REPLACE WITH REAL MESSAGE FROM API CALL
|
||||||
handlePagingFunc(e, setCurrentPage);
|
// const [currentPage, setCurrentPage] = useState(0);
|
||||||
};
|
// const indexOfFirstItem = Number(currentPage);
|
||||||
|
// const indexOfLastItem = Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
||||||
|
// const currentMessageList = messageList?.data?.slice(indexOfFirstItem, indexOfLastItem);
|
||||||
|
|
||||||
|
// const handlePagination = (e) => {
|
||||||
|
// handlePagingFunc(e, setCurrentPage);
|
||||||
|
// };
|
||||||
|
|
||||||
const [selectTab, setValue] = useState("today");
|
const [selectTab, setValue] = useState("today");
|
||||||
const filterHandler = (value) => {
|
const filterHandler = (value) => {
|
||||||
setValue(value);
|
setValue(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//FUNCTION TO HANDLE ON CHANGE MESSAGE IN TEXTAREA
|
||||||
|
const onMessageChange = ({target:{value}}) => {
|
||||||
|
if(messageToSend.length > 149){
|
||||||
|
setRequestStatus({loading: false, status: false, message: 'max of 150 characters', processType: 'sendmessage'})
|
||||||
|
}else{
|
||||||
|
setRequestStatus({loading: false, status: false, message: '', processType: 'sendmessage'})
|
||||||
|
}
|
||||||
|
setMessageToSend(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
//FUNCTION TO SEND MESSAGE TO CLIENT
|
||||||
|
const sendMessage = () => {
|
||||||
|
let reqData = { // API PAYLOADS
|
||||||
|
msg_type: 'MRKTINT',
|
||||||
|
yourmessage: messageToSend,
|
||||||
|
offer_uid: props.offerDetails.offer_uid,
|
||||||
|
interest_uid: props.offerDetails.interest_uid
|
||||||
|
}
|
||||||
|
setRequestStatus(prev => ({...prev, loading: true, processType: 'sendmessage'}))
|
||||||
|
if(!messageToSend){
|
||||||
|
setRequestStatus({loading: false, status: false, message: 'Please enter message to send', processType: 'sendmessage'})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(messageToSend.length > 149){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
apiCall.offerInterestMsg(reqData).then(res=>{
|
||||||
|
if(res.status != 200 || res.data.internal_return < 0){
|
||||||
|
setRequestStatus({loading: false, status: false, message: 'message not sent, try again', processType: 'sendmessage'})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setRequestStatus({loading: false, status: true, message: 'message sent', processType: 'sendmessage'})
|
||||||
|
setMessageToSend('') // sets message to empty strings
|
||||||
|
setMessageListReload(prev => !prev) //A FUNCTION TO MAKE MESSAGE LIST RELOAD
|
||||||
|
}).catch(error => {
|
||||||
|
setRequestStatus({loading: false, status: false, message: 'Opps, an error occured', processType: 'sendmessage'})
|
||||||
|
}).finally(()=>{
|
||||||
|
setTimeout(() => {
|
||||||
|
setRequestStatus({loading: false, status: false, message: '', processType: ''})
|
||||||
|
}, 5000);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
//FUNCTION TO ACCEPT/REJECT OFFER INTEREST
|
//FUNCTION TO ACCEPT/REJECT OFFER INTEREST
|
||||||
const interestOfferProcess = ({target:{name}}) => {
|
const interestOfferProcess = ({target:{name}}) => {
|
||||||
setRequestStatus(prev => ({...prev, loading: true, processType: name}))
|
setRequestStatus(prev => ({...prev, loading: true, processType: name}))
|
||||||
@@ -48,12 +95,13 @@ export default function ManageInterestOffer(props) {
|
|||||||
setRequestStatus({loading: false, status: false, message: 'Unable to complete request', processType: ''})
|
setRequestStatus({loading: false, status: false, message: 'Unable to complete request', processType: ''})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
setInterval(() => { // SETS REDIRECT COUNT DOWN
|
let intervalTime = setInterval(() => { // SETS REDIRECT COUNT DOWN
|
||||||
setRedirectTime(prev => prev - 1)
|
setRedirectTime(prev => prev - 1)
|
||||||
}, 1000);
|
}, 1000);
|
||||||
setRequestStatus({loading: false, status: true, message: `Offer ${name}ed`, processType: ''})
|
setRequestStatus({loading: false, status: true, message: `Offer ${name}ed`, processType: ''})
|
||||||
setTimeout(()=>{
|
setTimeout(()=>{
|
||||||
navigate('/offer-interest', {replace: true})
|
navigate('/offer-interest', {replace: true})
|
||||||
|
clearInterval(intervalTime)
|
||||||
},5000)
|
},5000)
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
setRequestStatus({loading: false, status: false, message: 'Opps! something went wrong. Try again', processType: ''})
|
setRequestStatus({loading: false, status: false, message: 'Opps! something went wrong. Try again', processType: ''})
|
||||||
@@ -65,8 +113,16 @@ export default function ManageInterestOffer(props) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
// run API to get message to replace message array above, add reload variable as dependence array
|
// run API to get message to replace message array above, add reload variable as dependence array. CODE IS DUMMY FOR NOW
|
||||||
},[])
|
setMessageList({loading: true, data: []})
|
||||||
|
apiCall.offerInterestMsg().then(res=>{
|
||||||
|
console.log('Data', res.data)
|
||||||
|
setMessageList({loading: false, data:[1,2,3,6,7,8,9]})
|
||||||
|
}).catch(err => {
|
||||||
|
setMessageList({loading: false, data:[1,2,3,6,7,8,9]})
|
||||||
|
console.log('Failed', err)
|
||||||
|
})
|
||||||
|
},[messageListReload])
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
<CommonHead
|
<CommonHead
|
||||||
@@ -142,14 +198,16 @@ export default function ManageInterestOffer(props) {
|
|||||||
{/* info tab */}
|
{/* info tab */}
|
||||||
{tab == 'info' ?
|
{tab == 'info' ?
|
||||||
<div className="info-details w-full border-t">
|
<div className="info-details w-full border-t">
|
||||||
<div className="my-3 flex items-center gap-1">
|
<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="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>
|
<span className="min-w-[100px] text-sm font-bold text-dark-gray dark:text-white tracking-wide">{props.offerDetails?.client_name}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="my-3 flex items-center gap-1">
|
<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="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>
|
<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>
|
||||||
<div className="my-3 flex items-center gap-1">
|
<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>
|
<span className="w-[200px] text-lg font-bold text-dark-gray dark:text-white tracking-wide">Jobs completed</span>
|
||||||
<span className="min-w-[100px] text-sm font-bold text-dark-gray dark:text-white tracking-wide">{props.offerDetails?.client_jobs_completed ? props.offerDetails?.client_jobs_completed :0}</span>
|
<span className="min-w-[100px] text-sm font-bold text-dark-gray dark:text-white tracking-wide">{props.offerDetails?.client_jobs_completed ? props.offerDetails?.client_jobs_completed :0}</span>
|
||||||
@@ -177,32 +235,76 @@ export default function ManageInterestOffer(props) {
|
|||||||
</div>
|
</div>
|
||||||
:
|
:
|
||||||
<div className="message-details w-full border-t">
|
<div className="message-details w-full border-t">
|
||||||
<div className="my-0 w-full flex items-center gap-5">
|
<p className="my-1 text-base text-dark-gray dark:text-white tracking-wide">To: <span className="font-bold">{props.offerDetails?.client_name}</span></p>
|
||||||
<div className="w-3/4">
|
<div className="w-full flex items-center gap-5">
|
||||||
<p className="text-base font-bold text-dark-gray dark:text-white tracking-wide">Message to dummy name</p>
|
<div className="w-full">
|
||||||
<textarea rows={2} autoFocus={true} className="p-2 text-base font-bold text-dark-gray dark:text-white dark:bg-dark-gray border tracking-wide w-full resize-none rounded-md outline-none" />
|
<textarea
|
||||||
|
value={messageToSend}
|
||||||
|
onChange={onMessageChange}
|
||||||
|
rows={2} autoFocus={true}
|
||||||
|
className="p-2 text-base font-bold text-dark-gray dark:text-white dark:bg-dark-gray border tracking-wide w-full resize-none rounded-md outline-none"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-1/4 flex flex-col justify-center items-center">
|
<div className="flex justify-end items-center">
|
||||||
|
{requestStatus.loading && requestStatus.processType == 'sendmessage' ?
|
||||||
|
<LoadingSpinner color='sky-blue' size='10' />
|
||||||
|
:
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
onClick={sendMessage}
|
||||||
|
disabled={requestStatus.loading}
|
||||||
|
// className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||||
|
className="w-[100px] h-[50px] bg-sky-blue text-center text-lg font-semibold text-white rounded-md shadow-md flex justify-center items-center"
|
||||||
>
|
>
|
||||||
<span className="text-white">Send</span>
|
Send
|
||||||
</button>
|
</button>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* ERROR DISPLAY FOR MESSAGE SENDING */}
|
||||||
|
<div className="w-full">
|
||||||
|
{/* error or success display */}
|
||||||
|
{requestStatus.message != "" && requestStatus.processType == 'sendmessage' &&
|
||||||
|
(!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>
|
||||||
|
)
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
{/* END OF ERROR DISPLAY FOR MESSAGE SENDING */}
|
||||||
|
|
||||||
{/* message list */}
|
{/* message list */}
|
||||||
<div className="min-h-[100px] max-h-[200px] overflow-y-auto">
|
<div className="my-1 min-h-[100px] max-h-[200px] border-t overflow-y-scroll">
|
||||||
{currentMessageList.map((item, index)=>(
|
{ messageList.loading ?
|
||||||
|
<LoadingSpinner color='sky-blue' size='16' />
|
||||||
|
: messageList.data.map((item, index)=>(
|
||||||
<div key={index} className="my-2 w-full flex items-center gap-1">
|
<div key={index} className="my-2 w-full flex items-center gap-1">
|
||||||
<p className="text-base font-bold text-dark-gray dark:text-white tracking-wide">2023-04-06-from { }<span className="font-normal">Dummy name</span></p>
|
<p className="text-base font-bold text-dark-gray dark:text-white tracking-wide">2023-04-06-from { }<span className="font-normal">Dummy name</span></p>
|
||||||
<p className="text-base font-bold text-dark-gray dark:text-white tracking-wide">I am testing message</p>
|
<p className="text-base font-bold text-dark-gray dark:text-white tracking-wide">I am testing message</p>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))
|
||||||
|
}
|
||||||
|
{/* {messageList.data.map((item, index)=>(
|
||||||
|
<div key={index} className="my-2 w-full flex items-center gap-1">
|
||||||
|
<p className="text-base font-bold text-dark-gray dark:text-white tracking-wide">2023-04-06-from { }<span className="font-normal">Dummy name</span></p>
|
||||||
|
<p className="text-base font-bold text-dark-gray dark:text-white tracking-wide">I am testing message</p>
|
||||||
|
</div>
|
||||||
|
))} */}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* PAGINATION BUTTON */}
|
{/* PAGINATION BUTTON */}
|
||||||
<PaginatedList
|
{/* <PaginatedList
|
||||||
onClick={handlePagination}
|
onClick={handlePagination}
|
||||||
prev={currentPage == 0 ? true : false}
|
prev={currentPage == 0 ? true : false}
|
||||||
next={
|
next={
|
||||||
@@ -214,7 +316,7 @@ export default function ManageInterestOffer(props) {
|
|||||||
data={messageList?.data}
|
data={messageList?.data}
|
||||||
start={indexOfFirstItem}
|
start={indexOfFirstItem}
|
||||||
stop={indexOfLastItem}
|
stop={indexOfLastItem}
|
||||||
/>
|
/> */}
|
||||||
{/* END OF PAGINATION BUTTON */}
|
{/* END OF PAGINATION BUTTON */}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@@ -225,7 +327,7 @@ export default function ManageInterestOffer(props) {
|
|||||||
{/* BUTTON section */}
|
{/* BUTTON section */}
|
||||||
<div className="p-4 w-full min-h-full bg-sky-100 dark:bg-dark-gray col-span-1">
|
<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="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' ?
|
{requestStatus.loading && requestStatus.processType == 'accept' ?
|
||||||
<LoadingSpinner color='sky-blue' size='10' />
|
<LoadingSpinner color='sky-blue' size='10' />
|
||||||
:
|
:
|
||||||
@@ -234,9 +336,10 @@ export default function ManageInterestOffer(props) {
|
|||||||
name='accept'
|
name='accept'
|
||||||
disabled={requestStatus.loading}
|
disabled={requestStatus.loading}
|
||||||
onClick={interestOfferProcess}
|
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>
|
</button>
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,9 +351,10 @@ export default function ManageInterestOffer(props) {
|
|||||||
name='reject'
|
name='reject'
|
||||||
disabled={requestStatus.loading}
|
disabled={requestStatus.loading}
|
||||||
onClick={interestOfferProcess}
|
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>
|
</button>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@@ -258,7 +362,7 @@ export default function ManageInterestOffer(props) {
|
|||||||
{/* ERROR DISPLAY */}
|
{/* ERROR DISPLAY */}
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
{/* error or success display */}
|
{/* error or success display */}
|
||||||
{requestStatus.message != "" && requestStatus.processType != 'sendmeassge' &&
|
{requestStatus.message != "" && requestStatus.processType != 'sendmessage' &&
|
||||||
(!requestStatus.status ? (
|
(!requestStatus.status ? (
|
||||||
<div
|
<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]`}
|
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]`}
|
||||||
|
|||||||
@@ -225,9 +225,10 @@ export default function MobileSidebar({ sidebar, action, logoutModalHandler, myJ
|
|||||||
<ul className="flex flex-col space-y-6">
|
<ul className="flex flex-col space-y-6">
|
||||||
<ListItem
|
<ListItem
|
||||||
title="Add Job"
|
title="Add Job"
|
||||||
route="/add-job"
|
route="/myjobs"
|
||||||
iconName="people-two"
|
iconName="people-two"
|
||||||
sidebar={sidebar}
|
sidebar={sidebar}
|
||||||
|
state={true}
|
||||||
/>
|
/>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -301,11 +302,12 @@ export default function MobileSidebar({ sidebar, action, logoutModalHandler, myJ
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ListItem = ({ sidebar, route, title, bubble }) => {
|
const ListItem = ({ sidebar, route, title, bubble, popup }) => {
|
||||||
return (
|
return (
|
||||||
<li className="item group">
|
<li className="item group">
|
||||||
<NavLink
|
<NavLink
|
||||||
to={route}
|
to={route}
|
||||||
|
state={popup ? { popup: true } : { popup: false }}
|
||||||
className={`nav-item flex items-center ${
|
className={`nav-item flex items-center ${
|
||||||
((navData) => (navData.isActive ? "active" : ""),
|
((navData) => (navData.isActive ? "active" : ""),
|
||||||
sidebar ? "justify-start space-x-3.5" : "justify-center")
|
sidebar ? "justify-start space-x-3.5" : "justify-center")
|
||||||
|
|||||||
@@ -8,7 +8,12 @@ import {
|
|||||||
import DarkModeContext from "../Contexts/DarkModeContext";
|
import DarkModeContext from "../Contexts/DarkModeContext";
|
||||||
import Icons from "../Helpers/Icons";
|
import Icons from "../Helpers/Icons";
|
||||||
|
|
||||||
export default function Sidebar({ sidebar, action, logoutModalHandler, myJobList }) {
|
export default function Sidebar({
|
||||||
|
sidebar,
|
||||||
|
action,
|
||||||
|
logoutModalHandler,
|
||||||
|
myJobList,
|
||||||
|
}) {
|
||||||
const darkMode = useContext(DarkModeContext);
|
const darkMode = useContext(DarkModeContext);
|
||||||
|
|
||||||
let { userDetails } = useSelector((state) => state.userDetails);
|
let { userDetails } = useSelector((state) => state.userDetails);
|
||||||
@@ -137,9 +142,7 @@ export default function Sidebar({ sidebar, action, logoutModalHandler, myJobList
|
|||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="heading mb-5">
|
<div className="heading mb-5">
|
||||||
<h1 className="title text-xl font-bold text-purple">
|
<h1 className="title text-xl font-bold text-purple">Family</h1>
|
||||||
Family
|
|
||||||
</h1>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="items">
|
<div className="items">
|
||||||
<ul className="flex flex-col space-y-6">
|
<ul className="flex flex-col space-y-6">
|
||||||
@@ -249,9 +252,10 @@ export default function Sidebar({ sidebar, action, logoutModalHandler, myJobList
|
|||||||
<ul className="flex flex-col space-y-6">
|
<ul className="flex flex-col space-y-6">
|
||||||
<ListItem
|
<ListItem
|
||||||
title="Add Job"
|
title="Add Job"
|
||||||
route="/add-job"
|
route="/myjobs"
|
||||||
iconName="people-two"
|
iconName="people-two"
|
||||||
sidebar={sidebar}
|
sidebar={sidebar}
|
||||||
|
popup={true}
|
||||||
/>
|
/>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -325,11 +329,12 @@ export default function Sidebar({ sidebar, action, logoutModalHandler, myJobList
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ListItem = ({ sidebar, route, title, bubble, iconName }) => {
|
const ListItem = ({ sidebar, route, title, bubble, iconName, popup }) => {
|
||||||
return (
|
return (
|
||||||
<li className={`item group`}>
|
<li className={`item group`}>
|
||||||
<NavLink
|
<NavLink
|
||||||
to={route}
|
to={route}
|
||||||
|
state={popup ? { popup: true } : { popup: false }}
|
||||||
className={`nav-item flex items-center ${
|
className={`nav-item flex items-center ${
|
||||||
((navData) => (navData.isActive ? "active" : ""),
|
((navData) => (navData.isActive ? "active" : ""),
|
||||||
sidebar ? "justify-start space-x-3.5" : "justify-center")
|
sidebar ? "justify-start space-x-3.5" : "justify-center")
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import React from 'react'
|
import React from "react";
|
||||||
import Layout from '../Partials/Layout'
|
import Layout from "../Partials/Layout";
|
||||||
import ReferralDisplay from './ReferralDisplay'
|
import ReferralDisplay from "./ReferralDisplay";
|
||||||
|
|
||||||
function Referral() {
|
function Referral() {
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
<ReferralDisplay />
|
<ReferralDisplay />
|
||||||
</Layout>
|
</Layout>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Referral
|
export default Referral;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
import usersService from "../../services/UsersService";
|
import usersService from "../../services/UsersService";
|
||||||
import InputCom from "../Helpers/Inputs/InputCom";
|
import InputCom from "../Helpers/Inputs/InputCom";
|
||||||
@@ -10,30 +9,29 @@ import * as Yup from "yup";
|
|||||||
import ReferralTable from "../MyWallet/WalletComponent/ReferralTable";
|
import ReferralTable from "../MyWallet/WalletComponent/ReferralTable";
|
||||||
|
|
||||||
const validationSchema = Yup.object().shape({
|
const validationSchema = Yup.object().shape({
|
||||||
email: Yup.string()
|
ref_email: Yup.string()
|
||||||
.email("Wrong email format")
|
.email("Wrong email format")
|
||||||
.min(3, "Minimum 3 characters")
|
.min(3, "Minimum 3 characters")
|
||||||
.max(50, "Maximum 50 characters")
|
.max(50, "Maximum 50 characters")
|
||||||
.required("Email is required"),
|
.required("Email is required"),
|
||||||
firstname: Yup.string()
|
ref_firstname: Yup.string()
|
||||||
.min(3, "Minimum 3 characters")
|
.min(3, "Minimum 3 characters")
|
||||||
.max(25, "Maximum 25 characters")
|
.max(25, "Maximum 25 characters")
|
||||||
.required("Firstname is required"),
|
.required("Firstname is required"),
|
||||||
lastname: Yup.string()
|
ref_lastname: Yup.string()
|
||||||
.min(3, "Minimum 3 characters")
|
.min(3, "Minimum 3 characters")
|
||||||
.max(25, "Maximum 25 characters")
|
.max(25, "Maximum 25 characters")
|
||||||
.required("Lastname is required"),
|
.required("Lastname is required"),
|
||||||
});
|
});
|
||||||
|
|
||||||
const initialValues = {
|
const initialValues = {
|
||||||
firstname: "",
|
ref_firstname: "",
|
||||||
lastname: "",
|
ref_lastname: "",
|
||||||
email: "",
|
ref_email: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
function ReferralDisplay() {
|
function ReferralDisplay() {
|
||||||
const apiCall = new usersService(); // GET API CALL
|
const apiCall = new usersService(); // GET API CALL
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
let [refHistoryReload, setRefHistoryReload] = useState(false); // Determines when referral history reloads
|
let [refHistoryReload, setRefHistoryReload] = useState(false); // Determines when referral history reloads
|
||||||
|
|
||||||
@@ -76,13 +74,13 @@ function ReferralDisplay() {
|
|||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.data.internal_return < 0) {
|
if (res.data.internal_return < 0) {
|
||||||
setError({
|
setError({
|
||||||
message: "Email already referred",
|
message: res.data.status,
|
||||||
loading: false,
|
loading: false,
|
||||||
status: false,
|
status: false,
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
toast.success("Message Sent");
|
toast.success(res.data.status | "Message Sent!");
|
||||||
setError({ message: "", loading: false, status: true });
|
setError({ message: "", loading: false, status: true });
|
||||||
setRefHistoryReload((prev) => !prev);
|
setRefHistoryReload((prev) => !prev);
|
||||||
}
|
}
|
||||||
@@ -99,16 +97,7 @@ function ReferralDisplay() {
|
|||||||
//FUNCTION TO HANDLE SUBMIT
|
//FUNCTION TO HANDLE SUBMIT
|
||||||
const handleSubmit = (values, helpers) => {
|
const handleSubmit = (values, helpers) => {
|
||||||
setError({ message: "", loading: true, status: false });
|
setError({ message: "", loading: true, status: false });
|
||||||
|
sendReferralMsg({...values}); // FUNCTION TO SEND REFERRAL MESSAGE
|
||||||
var postData = {
|
|
||||||
uid: localStorage.getItem("uid"),
|
|
||||||
member_id: localStorage.getItem("member_id"),
|
|
||||||
sessionid: localStorage.getItem("session_token"),
|
|
||||||
action: 11032,
|
|
||||||
...values,
|
|
||||||
};
|
|
||||||
|
|
||||||
sendReferralMsg(postData); // FUNCTION TO SEND REFERRAL MESSAGE
|
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -121,12 +110,9 @@ function ReferralDisplay() {
|
|||||||
<div className="sm:flex justify-between items-center mb-6">
|
<div className="sm:flex justify-between items-center mb-6">
|
||||||
<div className="mb-5 sm:mb-0">
|
<div className="mb-5 sm:mb-0">
|
||||||
<h1 className="text-26 font-bold inline-flex gap-3 text-dark-gray dark:text-white items-center">
|
<h1 className="text-26 font-bold inline-flex gap-3 text-dark-gray dark:text-white items-center">
|
||||||
<span>
|
<span>Refer a Friend</span>
|
||||||
Refer a Friend
|
|
||||||
</span>
|
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="referral w-full md:p-8 p-4 bg-white dark:bg-dark-white rounded-2xl shadow">
|
<div className="referral w-full md:p-8 p-4 bg-white dark:bg-dark-white rounded-2xl shadow">
|
||||||
@@ -147,15 +133,16 @@ function ReferralDisplay() {
|
|||||||
fieldClass="px-6"
|
fieldClass="px-6"
|
||||||
label="Firstname"
|
label="Firstname"
|
||||||
type="text"
|
type="text"
|
||||||
name="firstname"
|
name="ref_firstname"
|
||||||
placeholder="Firstname"
|
placeholder="Firstname"
|
||||||
value={props.values.firstname}
|
value={props.values.ref_firstname}
|
||||||
inputHandler={props.handleChange}
|
inputHandler={props.handleChange}
|
||||||
blurHandler={props.handleBlur}
|
blurHandler={props.handleBlur}
|
||||||
/>
|
/>
|
||||||
{props.errors.firstname && props.touched.firstname && (
|
{props.errors.ref_firstname &&
|
||||||
|
props.touched.ref_firstname && (
|
||||||
<p className="text-sm text-red-500">
|
<p className="text-sm text-red-500">
|
||||||
{props.errors.firstname}
|
{props.errors.ref_firstname}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -166,15 +153,16 @@ function ReferralDisplay() {
|
|||||||
fieldClass="px-6"
|
fieldClass="px-6"
|
||||||
label="Lastname"
|
label="Lastname"
|
||||||
type="text"
|
type="text"
|
||||||
name="lastname"
|
name="ref_lastname"
|
||||||
placeholder="Lastname"
|
placeholder="Lastname"
|
||||||
value={props.values.lastname}
|
value={props.values.ref_lastname}
|
||||||
inputHandler={props.handleChange}
|
inputHandler={props.handleChange}
|
||||||
blurHandler={props.handleBlur}
|
blurHandler={props.handleBlur}
|
||||||
/>
|
/>
|
||||||
{props.errors.lastname && props.touched.lastname && (
|
{props.errors.ref_lastname &&
|
||||||
|
props.touched.ref_lastname && (
|
||||||
<p className="text-sm text-red-500">
|
<p className="text-sm text-red-500">
|
||||||
{props.errors.lastname}
|
{props.errors.ref_lastname}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -185,14 +173,16 @@ function ReferralDisplay() {
|
|||||||
fieldClass="px-6"
|
fieldClass="px-6"
|
||||||
label="Email"
|
label="Email"
|
||||||
type="text"
|
type="text"
|
||||||
name="email"
|
name="ref_email"
|
||||||
placeholder="Email"
|
placeholder="Email"
|
||||||
value={props.values.email}
|
value={props.values.ref_email}
|
||||||
inputHandler={props.handleChange}
|
inputHandler={props.handleChange}
|
||||||
blurHandler={props.handleBlur}
|
blurHandler={props.handleBlur}
|
||||||
/>
|
/>
|
||||||
{props.errors.email && props.touched.email && (
|
{props.errors.ref_email && props.touched.ref_email && (
|
||||||
<p className="text-sm text-red-500">{props.errors.email}</p>
|
<p className="text-sm text-red-500">
|
||||||
|
{props.errors.ref_email}
|
||||||
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -206,7 +196,8 @@ function ReferralDisplay() {
|
|||||||
) : (
|
) : (
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
className="px-2 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white" >
|
className="px-2 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||||
|
>
|
||||||
Send Message
|
Send Message
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
@@ -227,8 +218,6 @@ function ReferralDisplay() {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,77 +4,231 @@ export default function TermsConditionTab() {
|
|||||||
return (
|
return (
|
||||||
<div className="terms-conditon-tab w-full">
|
<div className="terms-conditon-tab w-full">
|
||||||
<div className="terms-condition-wrappr w-full">
|
<div className="terms-condition-wrappr w-full">
|
||||||
<div className="mb-8">
|
<div className="mb-6">
|
||||||
<h1 className="text-xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
<h1 className="text-3xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
||||||
1. Definitions
|
Terms of use
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-base text-thin-light-gray leading-[28px] ">
|
<p className="text-base text-thin-light-gray leading-[28px] ">
|
||||||
What you do own when you buy an NFT are the keys to a non-fungible –
|
These Website Terms & Conditions (“T&Cs”) apply to your access and
|
||||||
perhaps unique – token. That token is yours to trade or hold or
|
use of www.wrenchboard.com,dashboard.wrenchboard.com (the “Site”),
|
||||||
display in Decentraland. But the digital file associated with an NFT
|
including all software, data, reports, text, images, sounds, video,
|
||||||
is just as easy to copy and paste and download as any other – the
|
and all contents made available through any portion of the Site
|
||||||
Finally, players lose their NFTs sometimes according to the rules
|
(collectively, the “Content”). Content includes all such elements as
|
||||||
and regulations of the NFT game.
|
a whole, as well as individual elements and portions thereof.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-8">
|
<hr />
|
||||||
<h1 className="text-xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
<div className="my-8">
|
||||||
2. Acceptance
|
<h1 className="text-2xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
||||||
|
Acceptance of Terms
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-base text-thin-light-gray leading-[28px] ">
|
<p className="text-base text-thin-light-gray leading-[28px] ">
|
||||||
Amet minim mollit non deserunt ullamco est sit aliqua dolor do amet
|
WRENCHBOARD permits you (“User” or “you” or “your”) to access and
|
||||||
sint. Velit officia consequat duis enim velit mollit. Exercitation
|
use the Site and Content, subject to these T&Cs. By accessing or
|
||||||
veniam consequat sunt nostrud amet.Capacity. You confirm that you
|
using any portion of the Site, you acknowledge that you have read,
|
||||||
have the legal capacity to receive and hold and make use of the NFT
|
understood, and agree to be bound by these T&Cs. If you do not agree
|
||||||
under French jurisdiction and any other relevant
|
with these T&Cs, you must not accept these T&Cs or access or use the
|
||||||
jurisdiction.Acceptance. By participating in the Sale, You accept
|
site or content.
|
||||||
and agree to these Terms and Conditions without any condition or
|
|
||||||
restriction. If You do not agree to this Contract, You shall not
|
|
||||||
participate in the Sale made by the Company Exercitation veniam
|
|
||||||
consequat sunt nostrud amet.Capacity. You confirm that you have the
|
|
||||||
legal capacity to receive and hold find to end.Contract, You shall
|
|
||||||
not participate in the Sale made by the Company Exercitation venia
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-8 bg-purple p-[23px] text-white rounded-lg">
|
<hr />
|
||||||
<p className="text-[18px]">
|
|
||||||
These Terms and Conditions are related to the sale of NFTs by the
|
<div className="my-8">
|
||||||
Company (the “Company”) on its Website. It solely governs the
|
<h1 className="text-2xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
||||||
contractual relationship between You and the Company regarding the
|
General Conditions of Use
|
||||||
Sale and any related contract.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div className="mb-8">
|
|
||||||
<h1 className="text-xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
|
||||||
3. The Sale
|
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-base text-thin-light-gray leading-[28px] ">
|
<p className="text-base text-thin-light-gray leading-[28px] ">
|
||||||
The Company offers NFTs featuring the Betonyou universe. The holders
|
<b> Authorization to Access and Use Site and Content.</b> Subject to
|
||||||
of one or more NFTs will be able to win cryptos while playing video
|
your compliance with these T&Cs and the provisions hereof, you may
|
||||||
games. In the future, the Company plans to develop its own games and
|
access or use the Site and Content solely for the purpose of your
|
||||||
Metaverse around the Betonyou universe (“Project”). <br />
|
evaluation of WRENCHBOARD and WRENCHBOARD’s products and services.
|
||||||
|
You may only link to the Site or Content, or any portion thereof, as
|
||||||
|
expressly permitted by WRENCHBOARD.
|
||||||
<br />
|
<br />
|
||||||
To release the NFTs and fund the project, the Company offers NFTs
|
<b> Ownership and Restrictions.</b> All rights, title, and interest
|
||||||
from a dedicated website("Sale"). The web address of this website
|
in and to the Site and Content will remain with and belong
|
||||||
will be given at the time of the mint. The NFT acquisition does not
|
exclusively to WRENCHBOARD. You will not (a) sublicense, resell,
|
||||||
confer any rights on the Company or in the future development.
|
rent, lease, transfer, assign, time share or otherwise commercially
|
||||||
|
exploit or make the Site and any Content available to any third
|
||||||
|
party, (b) use the Site and Content in any unlawful manner
|
||||||
|
(including without limitation in violation of any data, privacy or
|
||||||
|
export control laws) or in any manner that interferes with or
|
||||||
|
disrupts the integrity or performance of the Site and Content or
|
||||||
|
their related components, or (c) modify, adapt or hack the Site and
|
||||||
|
Content to, or try to, gain unauthorized access to the restricted
|
||||||
|
portions of the Site and Content or related systems or networks
|
||||||
|
(i.e., circumvent any encryption or other security measures, gain
|
||||||
|
access to any source code or any other underlying form of technology
|
||||||
|
or information, and gain access to any part of the Site and Content,
|
||||||
|
or any other products or services of WRENCHBOARD that are not
|
||||||
|
readily made available to the general public). You are not permitted
|
||||||
|
to copy, modify, frame, repost, publicly perform or display, sell,
|
||||||
|
reproduce, distribute, or create derivative works of the Site and
|
||||||
|
Content, except that you may download, display, and print one copy
|
||||||
|
of the publicly available materials (i.e., the Content that does not
|
||||||
|
require an Account name or password to access) on any single
|
||||||
|
computer solely for your personal, non-commercial use, provided that
|
||||||
|
you do not modify the material in any way and you keep intact all
|
||||||
|
copyright, trademark, and other proprietary notices. You agree not
|
||||||
|
to access the Site or Content by any means other than through the
|
||||||
|
interface that is provided by WRENCHBOARD to access the same. You
|
||||||
|
may not use any “page-scrape,” “deep-link,” “spider,” or “robot or
|
||||||
|
other automatic program, device, algorithm or methodology, or any
|
||||||
|
similar manual process, to access, copy, acquire, or monitor any
|
||||||
|
portion of the Site or any Content, or in any way reproduce or
|
||||||
|
circumvent the presentation or navigational structure of the Site or
|
||||||
|
any Content, to obtain or attempt to obtain any Content or other
|
||||||
|
information through any means not made generally available through
|
||||||
|
the Site by WRENCHBOARD. WRENCHBOARD reserves the right to take any
|
||||||
|
lawful measures to prevent any such activity. You may not forge
|
||||||
|
headers or otherwise manipulate identifiers in order to disguise the
|
||||||
|
origin of any message or transmittal you send to WRENCHBOARD on or
|
||||||
|
through the Site or any service offered on or through the Site. You
|
||||||
|
may not pretend that you are, or that you represent, someone else,
|
||||||
|
or impersonate any other individual or entity.
|
||||||
|
<b> Responsibility for Your Data.</b> You are solely responsible for
|
||||||
|
all data, information, and other content, that you upload, post, or
|
||||||
|
otherwise provide or store (hereafter “post(ing)”) in connection
|
||||||
|
with or relating to the Site.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-8">
|
<hr />
|
||||||
<h1 className="text-xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
|
||||||
4. Purchaser’s obligations
|
<div className="my-8">
|
||||||
|
<h1 className="text-2xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
||||||
|
Use of Intellectual Property.
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-base text-thin-light-gray leading-[28px] ">
|
<p className="text-base text-thin-light-gray leading-[28px] ">
|
||||||
To the fullest extent permitted by applicable law, You undertake to
|
<b> Rights in User Content.</b> By posting your information and
|
||||||
indemnify, defend and hold harmless the Company from and against all
|
other content (“User Content”) on or through the Site and Content,
|
||||||
claims, demands, actions, damages, losses, costs and expenses
|
you grant WRENCHBOARD a worldwide, non-exclusive, perpetual,
|
||||||
(including attorneys’ fees) that arise from or relate to (i) your
|
irrevocable, royalty-free, fully paid, sublicensable and
|
||||||
Subscription or use of the NFTs; (ii) your responsibilities or
|
transferable license to use, modify, reproduce, distribute, display,
|
||||||
obligations under this Contract; and (iii) your breach of this
|
publish and perform User Content in connection with the Site and
|
||||||
Contract. <br /> <br /> Company undertakes to act with the care
|
Content. WRENCHBOARD has the right, but not the obligation, to
|
||||||
normally expected from a professional in his field and to comply
|
monitor the Site and Content and User Content. WRENCHBOARD may
|
||||||
with the best practice in force. The best endeavor obligation only
|
remove or disable any User Content at any time for any reason, or
|
||||||
binds the Company.
|
for no reason at all. You, the user, acknowledge that you bear sole
|
||||||
|
responsibility for adequate security, protection, and backup of User
|
||||||
|
Content. WRENCHBOARD will have no liability to you for any
|
||||||
|
unauthorized access or use of any of User Content, or any
|
||||||
|
corruption, deletion, destruction, or loss of any of User Content.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<div className="my-8">
|
||||||
|
<h1 className="text-2xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
||||||
|
Feedback
|
||||||
|
</h1>
|
||||||
|
<p className="text-base text-thin-light-gray leading-[28px] ">
|
||||||
|
You may submit ideas, suggestions, or comments (“Feedback”)
|
||||||
|
regarding the Site and Content or WRENCHBOARD’s business, products,
|
||||||
|
or services. By submitting any Feedback, you acknowledge and agree
|
||||||
|
that (a) your Feedback is provided by you voluntarily and
|
||||||
|
WRENCHBOARD may, without any obligations or limitation, use and
|
||||||
|
exploit such Feedback in any manner and for any purpose, (b) you
|
||||||
|
will not seek and are not entitled to any money or other form of
|
||||||
|
compensation, consideration, or attribution with respect to your
|
||||||
|
Feedback regardless of whether WRENCHBOARD considered or used your
|
||||||
|
Feedback in any manner, and (c) your Feedback is not the
|
||||||
|
confidential or proprietary information of you or any third party.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<div className="my-8">
|
||||||
|
<h1 className="text-2xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
||||||
|
Termination of Access Due to Violations
|
||||||
|
</h1>
|
||||||
|
<p className="text-base text-thin-light-gray leading-[28px] ">
|
||||||
|
WRENCHBOARD may, in its sole discretion and without prior notice,
|
||||||
|
terminate your access to the Site and/or block your future access to
|
||||||
|
the Site if we determine that you have violated these T&Cs or other
|
||||||
|
agreements or guidelines which may be associated with your use of
|
||||||
|
the Site. You also agree that any violation by you of these T&Cs
|
||||||
|
will cause irreparable harm to WRENCHBOARD, for which monetary
|
||||||
|
damages would be inadequate, and you consent to WRENCHBOARD
|
||||||
|
obtaining any injunctive or equitable relief that WRENCHBOARD deems
|
||||||
|
necessary or appropriate in such circumstances, without limiting
|
||||||
|
WRENCHBOARD’s other available remedies. Further, WRENCHBOARD may, in
|
||||||
|
its sole discretion and without prior notice, terminate your access
|
||||||
|
to the Site, for cause, which includes (but is not limited to) (1)
|
||||||
|
requests by law enforcement or other government agencies, (2)
|
||||||
|
discontinuance or material modification of the Site or any service
|
||||||
|
offered on or through the Site, or (3) unexpected technical issues
|
||||||
|
or problems.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<div className="my-8">
|
||||||
|
<h1 className="text-2xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
||||||
|
T&Cs Updates
|
||||||
|
</h1>
|
||||||
|
<p className="text-base text-thin-light-gray leading-[28px] ">
|
||||||
|
WRENCHBOARD reserves the right, at its sole discretion, to change or
|
||||||
|
modify portions of these T&Cs at any time. WRENCHBOARD will post the
|
||||||
|
changes to these T&Cs on the Site and will indicate at the top of
|
||||||
|
this page the date these terms were last revised. It is your
|
||||||
|
responsibility to check the T&Cs periodically for changes. Your
|
||||||
|
continued use of the Site and Content after the date any such
|
||||||
|
changes become effective constitutes your acceptance of the new or
|
||||||
|
revised T&Cs.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<div className="my-8">
|
||||||
|
<h1 className="text-2xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
||||||
|
NO WARRANTIES AND DISCLAIMER BY WRENCHBOARD
|
||||||
|
</h1>
|
||||||
|
<p className="text-base text-thin-light-gray leading-[28px] ">
|
||||||
|
THE SITE AND CONTENT, AND ALL SERVER AND NETWORK COMPONENTS, ARE
|
||||||
|
PROVIDED ON AN “AS IS” AND “AS AVAILABLE” BASIS WITH ALL ERRORS AND
|
||||||
|
DEFECTS AND WITHOUT ANY WARRANTIES OF ANY KIND, AND WRENCHBOARD
|
||||||
|
EXPRESSLY DISCLAIMS ALL REPRESENTATIONS AND WARRANTIES, INCLUDING
|
||||||
|
ANY IMPLIED WARRANTIES OF ACCURACY, COMPLETENESS, MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, AND ANY
|
||||||
|
REPRESENTATIONS OR WARRANTIES ARISING FROM COURSE OF DEALING, COURSE
|
||||||
|
OF PERFORMANCE OR USAGE OF TRADE. YOU ACKNOWLEDGE THAT WRENCHBOARD
|
||||||
|
DOES NOT WARRANT THAT YOUR ACCESS OR USE OR BOTH OF THE SITE AND
|
||||||
|
CONTENT WILL BE UNINTERRUPTED, TIMELY, SECURE, ERROR-FREE OR
|
||||||
|
VIRUS-FREE, AND WRENCHBOARD DOES NOT MAKE ANY WARRANTY AS TO THE
|
||||||
|
RESULTS THAT MAY BE OBTAINED FROM USE OF THE SITE AND CONTENT. NO
|
||||||
|
INFORMATION, ADVICE OR SERVICES OBTAINED BY YOU FROM WRENCHBOARD OR
|
||||||
|
THROUGH THE SITE WILL CREATE ANY WARRANTY NOT EXPRESSLY STATED IN
|
||||||
|
THESE TERMS and CONDITIONS AND YOU SHOULD NOT RELY ON THE SITE AND
|
||||||
|
THE GENERAL CONTENT ALONE AS THE BASIS FOR YOUR BUSINESS DECISIONS.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<div className="my-8">
|
||||||
|
<p className="text-base text-thin-light-gray leading-[28px] ">
|
||||||
|
WRENCHBOARD reserves the right to do any of the following, at any
|
||||||
|
time, without notice: (1) to modify, suspend or terminate operation
|
||||||
|
of or access to the Site, or any portion of the Site, for any
|
||||||
|
reason; (2) to modify or change the Site, or any portion of the
|
||||||
|
Site, for any reason; and (3) to interrupt the operation of the
|
||||||
|
Site, or any portion of the Site, as necessary to perform routine or
|
||||||
|
non-routine maintenance, error correction, or other changes..
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<div className="mt-8">
|
||||||
|
<h1 className="text-2xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
|
||||||
|
Changes To the Policy
|
||||||
|
</h1>
|
||||||
|
<p className="text-base text-thin-light-gray leading-[28px] ">
|
||||||
|
We reserve the rights to update and make changes to this Privacy
|
||||||
|
policy at anytime. Changes will become effective once posted.
|
||||||
|
However, we will notify you by email or when you log on to the
|
||||||
|
service or website about any changes that fundamentally affect how
|
||||||
|
we manage your personal information. Contacting Us: You may contact
|
||||||
|
us about this policy through our email address anytime :
|
||||||
|
support@wrenchboard.com
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,46 +1,65 @@
|
|||||||
import React, { useState } from 'react'
|
import React, { useState } from "react";
|
||||||
import ModalCom from '../Helpers/ModalCom'
|
import ModalCom from "../Helpers/ModalCom";
|
||||||
import { useNavigate } from 'react-router-dom'
|
import { useNavigate } from "react-router-dom";
|
||||||
import usersService from '../../services/UsersService'
|
import usersService from "../../services/UsersService";
|
||||||
import LoadingSpinner from '../Spinners/LoadingSpinner'
|
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||||
import { useDispatch } from 'react-redux'
|
import { useDispatch } from "react-redux";
|
||||||
import { tableReload } from '../../store/TableReloads'
|
import { tableReload } from "../../store/TableReloads";
|
||||||
|
|
||||||
function DeleteJobPopout({ details, onClose, situation }) {
|
function DeleteJobPopout({ details, onClose, situation }) {
|
||||||
let dispatch = useDispatch()
|
let dispatch = useDispatch();
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate();
|
||||||
const ApiCall = new usersService()
|
const ApiCall = new usersService();
|
||||||
|
|
||||||
let [requestStatus, setRequestStatus] = useState({laoding: false, status:false, message: ''}) // STATE FOR KNOWING WHEN A REQUEST IS MADE TO THE SERVER
|
let [requestStatus, setRequestStatus] = useState({
|
||||||
|
laoding: false,
|
||||||
|
status: false,
|
||||||
|
message: "",
|
||||||
|
}); // STATE FOR KNOWING WHEN A REQUEST IS MADE TO THE SERVER
|
||||||
|
|
||||||
// FUNCTION CALLED ONCE USER CONFIRM DELETE JOB
|
// FUNCTION CALLED ONCE USER CONFIRM DELETE JOB
|
||||||
const deleteJob = (details) => {
|
const deleteJob = (details) => {
|
||||||
setRequestStatus({laoding: true, status:false, message: ''})
|
setRequestStatus({ laoding: true, status: false, message: "" });
|
||||||
let reqData = {
|
let reqData = {
|
||||||
job_id: details.job_id,
|
job_id: details.job_id,
|
||||||
job_uid: details.job_uid
|
job_uid: details.job_uid,
|
||||||
} // DATA NEEDED BY THE API
|
}; // DATA NEEDED BY THE API
|
||||||
|
|
||||||
// API CALL TO DELETE A JOB
|
// API CALL TO DELETE A JOB
|
||||||
ApiCall.deleteJob(reqData).then(res => {
|
ApiCall.deleteJob(reqData)
|
||||||
|
.then((res) => {
|
||||||
if (res.data.internal_return < 0) {
|
if (res.data.internal_return < 0) {
|
||||||
setRequestStatus({laoding: false, status:false, message: 'Could not perform the request, try again!'})
|
setRequestStatus({
|
||||||
return
|
laoding: false,
|
||||||
|
status: false,
|
||||||
|
message: "Could not perform the request, try again!",
|
||||||
|
});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
setRequestStatus({laoding: false, status:true, message: 'Job deleted successfully'})
|
setRequestStatus({
|
||||||
|
laoding: false,
|
||||||
|
status: true,
|
||||||
|
message: "Job deleted successfully",
|
||||||
|
});
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
dispatch(tableReload({type:'JOBTABLE'}))
|
dispatch(tableReload({ type: "JOBTABLE" }));
|
||||||
navigate('/myjobs', {replace: true})
|
navigate("/myjobs", { replace: true });
|
||||||
onClose()
|
onClose();
|
||||||
}, 1000)
|
}, 1000);
|
||||||
}).catch(error => {
|
|
||||||
setRequestStatus({laoding: false, status:false, message: 'Opps! something went wrong, try again'})
|
|
||||||
}).finally(()=>{
|
|
||||||
setTimeout(()=>{
|
|
||||||
setRequestStatus({laoding: false, status:false, message: ''})
|
|
||||||
}, 5000)
|
|
||||||
})
|
})
|
||||||
}
|
.catch((error) => {
|
||||||
|
setRequestStatus({
|
||||||
|
laoding: false,
|
||||||
|
status: false,
|
||||||
|
message: "Opps! something went wrong, try again",
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
setRequestStatus({ laoding: false, status: false, message: "" });
|
||||||
|
}, 5000);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalCom action={onClose} situation={situation}>
|
<ModalCom action={onClose} situation={situation}>
|
||||||
@@ -99,8 +118,8 @@ function DeleteJobPopout({details, onClose, situation}) {
|
|||||||
<p className="text-xl tracking-wide text-dark-gray dark:text-white">
|
<p className="text-xl tracking-wide text-dark-gray dark:text-white">
|
||||||
{details.title}
|
{details.title}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-lg tracking-wide text-dark-gray dark:text-white">
|
<p className="text-lg tracking-wide text-dark-gray dark:text-white flex items-start gap-1">
|
||||||
Price: {details.price * 0.01}
|
Price: {details.thePrice}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-lg tracking-wide text-dark-gray dark:text-white">
|
<p className="text-lg tracking-wide text-dark-gray dark:text-white">
|
||||||
Duration: {details.timeline_days} day(s)
|
Duration: {details.timeline_days} day(s)
|
||||||
@@ -114,9 +133,9 @@ function DeleteJobPopout({details, onClose, situation}) {
|
|||||||
>
|
>
|
||||||
<span className="text-gradient">Cancel</span>
|
<span className="text-gradient">Cancel</span>
|
||||||
</button>
|
</button>
|
||||||
{requestStatus.laoding ?
|
{requestStatus.laoding ? (
|
||||||
<LoadingSpinner size='8' color='sky-blue' />
|
<LoadingSpinner size="8" color="sky-blue" />
|
||||||
:
|
) : (
|
||||||
<button
|
<button
|
||||||
onClick={() => deleteJob(details)}
|
onClick={() => deleteJob(details)}
|
||||||
type="button"
|
type="button"
|
||||||
@@ -124,29 +143,31 @@ function DeleteJobPopout({details, onClose, situation}) {
|
|||||||
>
|
>
|
||||||
Confirm Delete
|
Confirm Delete
|
||||||
</button>
|
</button>
|
||||||
}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* ERROR DISPLAY AND SUBMIT BUTTON */}
|
{/* ERROR DISPLAY AND SUBMIT BUTTON */}
|
||||||
{requestStatus.message != "" && (
|
{requestStatus.message != "" &&
|
||||||
!requestStatus.status ?
|
(!requestStatus.status ? (
|
||||||
(<div className={`relative p-4 my-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}>
|
<div
|
||||||
|
className={`relative p-4 my-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
|
||||||
|
>
|
||||||
{requestStatus.message}
|
{requestStatus.message}
|
||||||
</div>)
|
</div>
|
||||||
:
|
) : (
|
||||||
requestStatus.status &&
|
requestStatus.status && (
|
||||||
(<div className={`relative p-4 my-4 text-green-700 bg-slate-200 border-slate-800 mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}>
|
<div
|
||||||
|
className={`relative p-4 my-4 text-green-700 bg-slate-200 border-slate-800 mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
|
||||||
|
>
|
||||||
{requestStatus.message}
|
{requestStatus.message}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
)}
|
))}
|
||||||
{/* End of error or success display */}
|
{/* End of error or success display */}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</ModalCom>
|
</ModalCom>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default DeleteJobPopout
|
export default DeleteJobPopout;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
import React, { useCallback, useMemo, useState } from "react";
|
||||||
import ModalCom from "../Helpers/ModalCom";
|
import ModalCom from "../Helpers/ModalCom";
|
||||||
import { Field, Form, Formik } from "formik";
|
import { Field, Form, Formik } from "formik";
|
||||||
import * as Yup from "yup";
|
import * as Yup from "yup";
|
||||||
@@ -6,13 +6,17 @@ import InputCom from "../Helpers/Inputs/InputCom";
|
|||||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||||
import usersService from "../../services/UsersService";
|
import usersService from "../../services/UsersService";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
import { tableReload } from "../../store/TableReloads";
|
import { tableReload } from "../../store/TableReloads";
|
||||||
import { useDispatch } from "react-redux";
|
import { useDispatch } from "react-redux";
|
||||||
|
|
||||||
const EditJobPopOut = ({ details, onClose, situation, country }) => {
|
const EditJobPopOut = ({
|
||||||
|
details,
|
||||||
const dispatch = useDispatch()
|
onClose,
|
||||||
|
situation,
|
||||||
|
country,
|
||||||
|
categories,
|
||||||
|
}) => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
let [requestStatus, setRequestStatus] = useState({
|
let [requestStatus, setRequestStatus] = useState({
|
||||||
loading: false,
|
loading: false,
|
||||||
@@ -55,6 +59,7 @@ const EditJobPopOut = ({ details, onClose, situation, country }) => {
|
|||||||
description: details?.description,
|
description: details?.description,
|
||||||
job_detail: details?.job_detail,
|
job_detail: details?.job_detail,
|
||||||
timeline_days: details?.timeline_days,
|
timeline_days: details?.timeline_days,
|
||||||
|
category: details?.category,
|
||||||
};
|
};
|
||||||
|
|
||||||
const jobApi = useMemo(() => new usersService(), []);
|
const jobApi = useMemo(() => new usersService(), []);
|
||||||
@@ -62,20 +67,21 @@ const EditJobPopOut = ({ details, onClose, situation, country }) => {
|
|||||||
|
|
||||||
const handleEditJob = useCallback(
|
const handleEditJob = useCallback(
|
||||||
async (values) => {
|
async (values) => {
|
||||||
|
values.category = values.category?.join("@");
|
||||||
setRequestStatus({ loading: true, message: "" });
|
setRequestStatus({ loading: true, message: "" });
|
||||||
let reqData = {
|
let reqData = {
|
||||||
job_id: details.job_id,
|
job_id: details.job_id,
|
||||||
job_uid: details.job_uid,
|
job_uid: details.job_uid,
|
||||||
...values,
|
...values,
|
||||||
};
|
};
|
||||||
delete reqData?.country
|
delete reqData?.country;
|
||||||
try {
|
try {
|
||||||
let res = await jobApi.jobManagerUpdateJob(reqData);
|
let res = await jobApi.jobManagerUpdateJob(reqData);
|
||||||
let { data } = await res;
|
let { data } = await res;
|
||||||
if (data?.internal_return < 0) return;
|
if (data?.internal_return < 0) return;
|
||||||
setRequestStatus({ loading: false, message: null });
|
setRequestStatus({ loading: false, message: null });
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
dispatch(tableReload({type:'JOBTABLE'}))
|
dispatch(tableReload({ type: "JOBTABLE" }));
|
||||||
navigate("/myjobs", { replace: true });
|
navigate("/myjobs", { replace: true });
|
||||||
onClose();
|
onClose();
|
||||||
}, 1000);
|
}, 1000);
|
||||||
@@ -130,7 +136,7 @@ const EditJobPopOut = ({ details, onClose, situation, country }) => {
|
|||||||
<Form className="w-full">
|
<Form className="w-full">
|
||||||
<div className="flex flex-col-reverse sm:flex-row">
|
<div className="flex flex-col-reverse sm:flex-row">
|
||||||
<div className="fields w-full">
|
<div className="fields w-full">
|
||||||
<div className="xl:flex xl:space-x-7 mb-6">
|
<div className="xl:flex xl:space-x-7 mb-[0.5rem]">
|
||||||
<div className="field w-full mb-6 xl:mb-0">
|
<div className="field w-full mb-6 xl:mb-0">
|
||||||
<InputCom
|
<InputCom
|
||||||
fieldClass="px-6 cursor-default"
|
fieldClass="px-6 cursor-default"
|
||||||
@@ -145,11 +151,6 @@ const EditJobPopOut = ({ details, onClose, situation, country }) => {
|
|||||||
blurHandler={props.handleBlur}
|
blurHandler={props.handleBlur}
|
||||||
disable={true}
|
disable={true}
|
||||||
/>
|
/>
|
||||||
{props.errors.country && props.touched.country && (
|
|
||||||
<p className="text-sm text-red-500">
|
|
||||||
{props.errors.country}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Price */}
|
{/* Price */}
|
||||||
@@ -162,20 +163,17 @@ const EditJobPopOut = ({ details, onClose, situation, country }) => {
|
|||||||
inputClass="input-curve lg border border-light-purple"
|
inputClass="input-curve lg border border-light-purple"
|
||||||
type="number"
|
type="number"
|
||||||
name="price"
|
name="price"
|
||||||
// placeholder="Please Enter Amount"
|
|
||||||
value={props.values.price * 0.01}
|
value={props.values.price * 0.01}
|
||||||
inputHandler={props.handleChange}
|
inputHandler={props.handleChange}
|
||||||
blurHandler={props.handleBlur}
|
blurHandler={props.handleBlur}
|
||||||
|
errorBorder={
|
||||||
|
props.errors.price && props.touched.price
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
{props.errors.price && props.touched.price && (
|
|
||||||
<p className="text-sm text-red-500">
|
|
||||||
{props.errors.price}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/* Title */}
|
{/* Title */}
|
||||||
<div className="field w-full mb-6">
|
<div className="field w-full mb-[0.5rem]">
|
||||||
<InputCom
|
<InputCom
|
||||||
fieldClass="px-6"
|
fieldClass="px-6"
|
||||||
label="Title"
|
label="Title"
|
||||||
@@ -184,20 +182,15 @@ const EditJobPopOut = ({ details, onClose, situation, country }) => {
|
|||||||
inputClass=" input-curve lg border border-light-purple"
|
inputClass=" input-curve lg border border-light-purple"
|
||||||
type="text"
|
type="text"
|
||||||
name="title"
|
name="title"
|
||||||
// placeholder="Enter Job Title"
|
|
||||||
value={props.values.title}
|
value={props.values.title}
|
||||||
inputHandler={props.handleChange}
|
inputHandler={props.handleChange}
|
||||||
blurHandler={props.handleBlur}
|
blurHandler={props.handleBlur}
|
||||||
|
errorBorder={props.errors.title && props.touched.title}
|
||||||
/>
|
/>
|
||||||
{props.errors.title && props.touched.title && (
|
|
||||||
<p className="text-sm text-red-500">
|
|
||||||
{props.errors.title}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Description */}
|
{/* Description */}
|
||||||
<div className="field w-full mb-6">
|
<div className="field w-full mb-[0.5rem]">
|
||||||
<InputCom
|
<InputCom
|
||||||
fieldClass="px-6"
|
fieldClass="px-6"
|
||||||
label="Description"
|
label="Description"
|
||||||
@@ -206,24 +199,21 @@ const EditJobPopOut = ({ details, onClose, situation, country }) => {
|
|||||||
inputClass=" input-curve lg border border-light-purple"
|
inputClass=" input-curve lg border border-light-purple"
|
||||||
type="text"
|
type="text"
|
||||||
name="description"
|
name="description"
|
||||||
// placeholder="Enter a description"
|
|
||||||
value={props.values.description}
|
value={props.values.description}
|
||||||
inputHandler={props.handleChange}
|
inputHandler={props.handleChange}
|
||||||
blurHandler={props.handleBlur}
|
blurHandler={props.handleBlur}
|
||||||
|
errorBorder={
|
||||||
|
props.errors.description && props.touched.description
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
{props.errors.description &&
|
|
||||||
props.touched.description && (
|
|
||||||
<p className="text-sm text-red-500">
|
|
||||||
{props.errors.description}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Details */}
|
{/* Details */}
|
||||||
<div className="field w-full mb-6">
|
<div className="field flex flex-col sm:flex-row w-full mb-[5px] gap-2">
|
||||||
|
<div className="sm:w-[60%] w-full">
|
||||||
<label
|
<label
|
||||||
htmlFor="Job Delivery Details"
|
htmlFor="Job Delivery Details"
|
||||||
className='className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block mb-3'
|
className='className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"'
|
||||||
>
|
>
|
||||||
Job Delivery Details
|
Job Delivery Details
|
||||||
</label>
|
</label>
|
||||||
@@ -237,15 +227,50 @@ const EditJobPopOut = ({ details, onClose, situation, country }) => {
|
|||||||
onChange={props.handleChange}
|
onChange={props.handleChange}
|
||||||
onBlur={props.handleBlur}
|
onBlur={props.handleBlur}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="sm:w-[35%] w-full">
|
||||||
|
<div
|
||||||
|
htmlFor="Job Categories"
|
||||||
|
className='className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"'
|
||||||
|
id="checked-group"
|
||||||
|
>
|
||||||
|
Categories
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="sm:flex-col flex flex-wrap px-3 mt-3"
|
||||||
|
role="group"
|
||||||
|
aria-labelledby="checked-group"
|
||||||
|
>
|
||||||
|
{Object.entries(categories).map(([key, value]) => (
|
||||||
|
<label
|
||||||
|
key={key}
|
||||||
|
className="flex gap-1 w-full items-center"
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
type="checkbox"
|
||||||
|
name="category"
|
||||||
|
value={key}
|
||||||
|
/>
|
||||||
|
<span className="text-[13.975px]">{value}</span>
|
||||||
|
</label>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* <div className={`${!props.errors && "invisible"} h-5`}>
|
||||||
{props.errors.job_detail && props.touched.job_detail && (
|
{props.errors.job_detail && props.touched.job_detail && (
|
||||||
<p className="text-sm text-red-500">
|
<p className="text-sm text-red-500">
|
||||||
{props.errors.job_detail}
|
{props.errors.job_detail}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
|
</div> */}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="field w-full mb-6">
|
<div className="field w-full mb-6">
|
||||||
<div className={`flex items-center justify-between mb-2.5`}>
|
<div
|
||||||
|
className={`flex items-center justify-between mb-2.5`}
|
||||||
|
>
|
||||||
<label
|
<label
|
||||||
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"
|
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"
|
||||||
htmlFor="timeline_days"
|
htmlFor="timeline_days"
|
||||||
@@ -273,12 +298,6 @@ const EditJobPopOut = ({ details, onClose, situation, country }) => {
|
|||||||
</option>
|
</option>
|
||||||
))}
|
))}
|
||||||
</Field>
|
</Field>
|
||||||
{props.errors.timeline_days &&
|
|
||||||
props.touched.timeline_days && (
|
|
||||||
<p className="text-sm text-red-500">
|
|
||||||
{props.errors.timeline_days}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
{/* inputs ends here */}
|
{/* inputs ends here */}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import Detail from "./popoutcomponent/Detail";
|
|||||||
import ModalCom from "../Helpers/ModalCom";
|
import ModalCom from "../Helpers/ModalCom";
|
||||||
import InputCom from "../Helpers/Inputs/InputCom/index";
|
import InputCom from "../Helpers/Inputs/InputCom/index";
|
||||||
import SiteService from "../../services/SiteService";
|
import SiteService from "../../services/SiteService";
|
||||||
import { Form, Formik, Field, ErrorMessage } from "formik";
|
import { Form, Formik, Field } from "formik";
|
||||||
import * as Yup from "yup";
|
import * as Yup from "yup";
|
||||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||||
|
|
||||||
@@ -167,6 +167,8 @@ function JobListPopout({ details, onClose, situation }) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// console.log("Job List P >> ", details)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalCom action={onClose} situation={situation} className="job-popup">
|
<ModalCom action={onClose} situation={situation} className="job-popup">
|
||||||
<div className="logout-modal-wrapper lw-[90%] md:w-[768px] h-full lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl overflow-y-auto">
|
<div className="logout-modal-wrapper lw-[90%] md:w-[768px] h-full lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl overflow-y-auto">
|
||||||
@@ -210,7 +212,7 @@ function JobListPopout({ details, onClose, situation }) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="my-3 md:flex">
|
<div className="my-3 md:flex">
|
||||||
<Detail label="Price" value={`${details.price * 0.01} Naira`} />
|
<Detail label="Price" value={details.thePrice} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="my-3 md:flex">
|
<div className="my-3 md:flex">
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import ModalCom from "../Helpers/ModalCom";
|
|||||||
import usersService from "../../services/UsersService";
|
import usersService from "../../services/UsersService";
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||||
|
import { PriceFormatter } from "../Helpers/PriceFormatter";
|
||||||
|
|
||||||
const showSuccessToast = (message) => {
|
const showSuccessToast = (message) => {
|
||||||
toast.success(message, {
|
toast.success(message, {
|
||||||
@@ -133,7 +134,8 @@ function PendingJobsPopout({ details, onClose, situation }) {
|
|||||||
<div className="my-2 md:flex">
|
<div className="my-2 md:flex">
|
||||||
<Detail
|
<Detail
|
||||||
label="Price"
|
label="Price"
|
||||||
value={`${details.price * 0.01} ${details.currency}`}
|
// value={`${details.price * 0.01} ${details.currency}`}
|
||||||
|
value={PriceFormatter(details.price * 0.01, details?.currency_code, details.currency)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
+27
-2
@@ -51,8 +51,11 @@
|
|||||||
font-weight: bolder;
|
font-weight: bolder;
|
||||||
}
|
}
|
||||||
.siderCardDescription{
|
.siderCardDescription{
|
||||||
margin: 20px 45px 10px 45px;
|
margin: 10px 45px 10px 45px;
|
||||||
font-size: 20px;
|
font-size: 18px;
|
||||||
|
background-color: aliceblue;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
.siderCardButton{
|
.siderCardButton{
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
@@ -898,3 +901,25 @@ TODO: Responsive ===========================
|
|||||||
top: 30px;
|
top: 30px;
|
||||||
height: 55rem !important;
|
height: 55rem !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes shake {
|
||||||
|
0% {
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
25% {
|
||||||
|
transform: translateX(-5px);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: translateX(5px);
|
||||||
|
}
|
||||||
|
75% {
|
||||||
|
transform: translateX(-5px);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ebu-animate-shake {
|
||||||
|
animation: shake 0.3s linear 3;
|
||||||
|
}
|
||||||
|
|||||||
@@ -444,7 +444,14 @@ class usersService {
|
|||||||
|
|
||||||
//END POINT CALL FOR SENDING REFERRAL MESSAGE
|
//END POINT CALL FOR SENDING REFERRAL MESSAGE
|
||||||
sendReferralMsg(postData) {
|
sendReferralMsg(postData) {
|
||||||
return this.postAuxEnd("/sendreferral", postData);
|
var reqData = {
|
||||||
|
uid: localStorage.getItem("uid"),
|
||||||
|
member_id: localStorage.getItem("member_id"),
|
||||||
|
sessionid: localStorage.getItem("session_token"),
|
||||||
|
action: 11032,
|
||||||
|
...postData
|
||||||
|
}
|
||||||
|
return this.postAuxEnd("/sendreferral", reqData);
|
||||||
}
|
}
|
||||||
|
|
||||||
StartResetPassword(reqData) {
|
StartResetPassword(reqData) {
|
||||||
@@ -712,6 +719,28 @@ class usersService {
|
|||||||
return this.postAuxEnd("/faq", postData);
|
return this.postAuxEnd("/faq", postData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// END POINT TO GET LIST OF USER PREVIOUS CARDS
|
||||||
|
payListCard() {
|
||||||
|
var postData = {
|
||||||
|
uid: localStorage.getItem("uid"),
|
||||||
|
member_id: localStorage.getItem("member_id"),
|
||||||
|
sessionid: localStorage.getItem("session_token"),
|
||||||
|
action: 11055
|
||||||
|
};
|
||||||
|
return this.postAuxEnd("/paylistcard", postData);
|
||||||
|
}
|
||||||
|
|
||||||
|
// END POINT TO SEND AND GET OFFER INTEREST MESSAGE
|
||||||
|
offerInterestMsg(reqData) {
|
||||||
|
var postData = {
|
||||||
|
uid: localStorage.getItem("uid"),
|
||||||
|
member_id: localStorage.getItem("member_id"),
|
||||||
|
sessionid: localStorage.getItem("session_token"),
|
||||||
|
action: 13037,
|
||||||
|
...reqData
|
||||||
|
};
|
||||||
|
return this.postAuxEnd("/offerinterestmsg", postData);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
- 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(username)
|
- 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(username)
|
||||||
- 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(password)
|
- 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(password)
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ import React from "react";
|
|||||||
import AddJob from "../components/AddJob/AddJob";
|
import AddJob from "../components/AddJob/AddJob";
|
||||||
import ModalCom from "../components/Helpers/ModalCom";
|
import ModalCom from "../components/Helpers/ModalCom";
|
||||||
|
|
||||||
function AddJobPage({ action, situation }) {
|
function AddJobPage({ action, situation, categories }) {
|
||||||
return (
|
return (
|
||||||
<ModalCom action={action} situation={situation} className="addJob-popup">
|
<ModalCom action={action} situation={situation} className="edit-popup">
|
||||||
<div className="lg:w-[600px] w-full h-full lg:overflow-hidden lg:rounded-2xl bg-white dark:bg-dark-white ">
|
<div className="lg:w-[600px] w-full lg:overflow-hidden lg:rounded-2xl bg-white dark:bg-dark-white ">
|
||||||
<div className="heading flex justify-between items-center py-6 md:px-[30px] px-[23px] border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] ">
|
<div className="heading flex justify-between items-center py-6 md:px-[30px] px-[23px] border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] ">
|
||||||
<p className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
|
<p className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
|
||||||
Create New Job
|
Create New Job
|
||||||
@@ -31,7 +31,7 @@ function AddJobPage({ action, situation }) {
|
|||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<AddJob popUpHandler={action} />
|
<AddJob popUpHandler={action} categories={categories} />
|
||||||
</div>
|
</div>
|
||||||
</ModalCom>
|
</ModalCom>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import { useSelector } from "react-redux";
|
|||||||
export default function MyJobsPage() {
|
export default function MyJobsPage() {
|
||||||
let { commonHeadBanner } = useSelector((state) => state.commonHeadBanner);
|
let { commonHeadBanner } = useSelector((state) => state.commonHeadBanner);
|
||||||
const { userJobList } = useSelector((state) => state.userJobList);
|
const { userJobList } = useSelector((state) => state.userJobList);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<MyJobs
|
<MyJobs
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import React from 'react'
|
import React from "react";
|
||||||
import Referral from '../components/Referral/Index'
|
import Referral from "../components/Referral/Index";
|
||||||
|
|
||||||
function ReferralPage() {
|
function ReferralPage() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Referral />
|
<Referral />
|
||||||
</>
|
</>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ReferralPage
|
export default ReferralPage;
|
||||||
|
|||||||
Reference in New Issue
Block a user