Compare commits

...

21 Commits

Author SHA1 Message Date
Ebube 1f76dd0db8 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into faq-display 2023-06-26 19:01:49 +01:00
Ebube f772cf0a68 . 2023-06-26 18:57:41 +01:00
CHIEFSOFT\ameye c4c5c7967e Resource Starter 2023-06-26 13:36:43 -04:00
Ebube 45ecec24ac Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into faq-display 2023-06-26 17:48:25 +01:00
Ebube 16fd35df83 . 2023-06-26 17:48:00 +01:00
CHIEFSOFT\ameye 3f6a391d30 witing Jobs 2023-06-26 09:23:28 -04:00
CHIEFSOFT\ameye 5eb64f49c0 text style 2023-06-26 07:50:49 -04:00
CHIEFSOFT\ameye 1761150bd3 My wait jobs 2023-06-26 07:44:03 -04:00
ameye a4b15dd06e Merge branch 'faq-display' of WrenchBoard/Users-Wrench into master 2023-06-25 21:38:00 +00:00
Ebube 1a15410e4c . 2023-06-25 20:07:35 +01:00
Ebube da1133ed43 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into faq-display 2023-06-25 20:00:49 +01:00
Ebube 23605bc358 . 2023-06-25 19:58:54 +01:00
ameye 2092682be6 Merge branch 'faq-display' of WrenchBoard/Users-Wrench into master 2023-06-25 11:19:58 +00:00
Ebube 0e270d8efa . 2023-06-25 07:09:17 +01:00
CHIEFSOFT\ameye 3bb4fe6a02 banner waiting 2023-06-25 00:01:44 -04:00
CHIEFSOFT\ameye fa728d3879 Waiting Jobs 2023-06-24 15:43:59 -04:00
ameye a9ce76123b Merge branch 'privacy-policy' of WrenchBoard/Users-Wrench into master 2023-06-24 11:17:42 +00:00
ameye 3ac1be9b89 Merge branch 'AddJob-Link-Fix' of WrenchBoard/Users-Wrench into master 2023-06-24 11:17:37 +00:00
ameye e4be117c90 Merge branch 'offer-interest-msg-list' of WrenchBoard/Users-Wrench into master 2023-06-24 11:17:11 +00:00
Ebube 58834cd7ca privacy policy 2023-06-24 08:52:33 +01:00
victorAnumudu 0feaf42f49 offer interest message list API added 2023-06-23 23:47:46 +01:00
24 changed files with 744 additions and 326 deletions
+1 -1
View File
@@ -17,7 +17,7 @@ REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api
#"https://devapi.mermsemr.com/en/desktop/api/v2/myfituser"
REACT_APP_SESSION_EXPIRE_MINUTES=300000
REACT_APP_SESSION_EXPIRE_MINUTES=600000
REACT_APP_SESSION_EXPIRE_MINUTES_FAMILY=600000
REACT_APP_SESSION_EXPIRE_CHECKER=60000
+1 -1
View File
@@ -17,7 +17,7 @@ REACT_APP_USERS_ENDPOINT="https://apigate.lotus.g1.wrenchboard.com/en/wrench/api
#"https://devapi.mermsemr.com/en/desktop/api/v2/myfituser"
REACT_APP_SESSION_EXPIRE_MINUTES=300000
REACT_APP_SESSION_EXPIRE_MINUTES=600000
REACT_APP_SESSION_EXPIRE_MINUTES_FAMILY=600000
REACT_APP_SESSION_EXPIRE_CHECKER=60000
+1 -1
View File
@@ -17,7 +17,7 @@ REACT_APP_USERS_ENDPOINT="https://apigate.orion.g1.wrenchboard.com/en/wrench/api
#"https://devapi.mermsemr.com/en/desktop/api/v2/myfituser"
REACT_APP_SESSION_EXPIRE_MINUTES=300000
REACT_APP_SESSION_EXPIRE_MINUTES=600000
REACT_APP_SESSION_EXPIRE_MINUTES_FAMILY=600000
REACT_APP_SESSION_EXPIRE_CHECKER=60000
+2
View File
@@ -45,6 +45,7 @@ import BlogPage from "./views/BlogPage";
import MyReviewDueJobsPage from "./views/MyReviewDueJobsPage";
import OffersInterestPage from "./views/OffersInterestPage";
import ManageInterestOfferPage from './views/ManageInterestOfferPage'
import MyWaitingJobsPage from "./views/MyWaitingJobsPage";
export default function Routers() {
return (
@@ -93,6 +94,7 @@ export default function Routers() {
<Route exact path="/my-active-jobs" element={<MyActiveJobsPage />} />
<Route exact path="/my-pastdue-jobs" element={<MyPastDueJobsPage />} />
<Route exact path="/my-pending-jobs" element={<MyPendingJobsPage />} />
<Route exact path="/pend-interest" element={<MyWaitingJobsPage />} />
<Route exact path="/my-review-jobs" element={<MyReviewDueJobsPage />} />
<Route exact path="/acc-family" element={<FamilyAccPage />} />
<Route exact path="/manage-family" element={<FamilyManagePage />} />
Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

+44 -39
View File
@@ -14,8 +14,14 @@ const validationSchema = Yup.object().shape({
.max(25, "Maximum 25 characters")
.required("Country is required"),
price: Yup.number()
.typeError("you must specify a number")
.typeError("Invalid number")
.min(1, "Price must be greater than 0")
.test("no-e", "Invalid number", (value) => {
if (value && /\d+e/.test(value)) {
return false;
}
return true;
})
.required("Price is required"),
title: Yup.string()
.min(3, "Minimum 3 characters")
@@ -42,15 +48,16 @@ function AddJob({ popUpHandler, categories }) {
let { userDetails } = useSelector((state) => state.userDetails);
let [country, setCountry] = useState({
const [numberValue, setNumberValue] = useState("");
let [currency, setCurrency] = useState({
loading: true,
status: false,
data: [],
}); // To Hold the array of country getUserCountry returns
data: null,
}); // To Hold the array of currency getUserCurrency returns
let initialValues = {
// initial values for formik
country: userDetails.country,
currency: "",
price: "",
title: "",
description: "",
@@ -65,23 +72,25 @@ function AddJob({ popUpHandler, categories }) {
message: "",
}); // Holds state when submit button is pressed
// FUNCTION TO GET COUNTRY
const getUserCountry = () => {
setCountry((prev) => ({ ...prev, loading: true }));
ApiCall.getSignupCountryData()
// FUNCTION TO GET Currency
const getUserCurrency = () => {
setCurrency((prev) => ({ ...prev, loading: true }));
ApiCall.getUserWallets()
.then((res) => {
if (res.data.internal_return < 1) {
setCountry({ loading: false, status: true, data: [] });
if (res.data.internal_return < 0) {
setCurrency({ loading: false, status: true, data: [] });
return;
}
setCountry({
console.log("Res for currency >> ", res);
setCurrency({
loading: false,
status: true,
data: res.data.signup_country,
data: res.data.result_list,
});
})
.catch((err) => {
setCountry({ loading: false, status: false, data: [] });
setCurrency({ loading: false, status: false, data: [] });
});
};
@@ -113,7 +122,7 @@ function AddJob({ popUpHandler, categories }) {
setRequestStatus({
loading: false,
status: false,
message: "Opps! soemthing went wrong. Try Again",
message: "Opps! something went wrong. Try Again",
});
})
.finally(() => {
@@ -124,9 +133,11 @@ function AddJob({ popUpHandler, categories }) {
};
useEffect(() => {
getUserCountry();
getUserCurrency();
}, []);
console.log("Currency >> ", currency.data);
return (
<div className="add-job p-5 w-full bg-white rounded-md flex flex-col justify-between">
<Formik
@@ -140,46 +151,40 @@ function AddJob({ popUpHandler, categories }) {
<div className="flex flex-col-reverse sm:flex-row">
<div className="fields w-full">
{/* inputs starts here */}
{/* country */}
<div className="xl:flex xl:space-x-7 mb-[5px]">
<div className="field w-full mb-6 xl:mb-0">
<label
htmlFor="country"
htmlFor="currency"
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"
>
Country
Currency
</label>
<select
id="country"
name="country"
disabled
value={props.values.country}
id="currency"
name="currency"
value={props.values.currency}
className={`input-field p-2 mt-3 rounded-md placeholder:text-base text-dark-gray dark:text-white w-full h-10 bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none`}
onChange={props.handleChange}
onBlur={props.handleBlur}
>
{country.loading ? (
{currency.loading ? (
<option className="text-slate-500 text-lg" value="">
Loading...
</option>
) : country.data.length ? (
) : currency.data.length ? (
<>
<option className="text-slate-500 text-lg" value="">
Select...
Select a currency
</option>
{country.data.map((item, index) => {
if (item[0] == userDetails.country) {
return (
<option
key={index}
className="text-slate-500 text-lg"
value={item[0]}
>
{item[1]}
</option>
);
}
})}
{currency.data?.map((item, index) => (
<option
key={index}
className="text-slate-500 text-lg"
value={item?.country}
>
{item?.description}
</option>
))}
</>
) : (
<option className="text-slate-500 text-lg" value="">
-2
View File
@@ -152,8 +152,6 @@ export default function Login() {
);
}, []);
console.log("Looking for the cookies >>", selectedLoginType)
useEffect(() => {
setMail("");
setPassword("");
+2 -2
View File
@@ -80,7 +80,7 @@ export default function SignUp() {
if (res.status === 200) {
const { data } = res;
if (data.status === -1 && data.acc === "DULPICATE") {
if (data && data.acc === "DULPICATE") {
setMsgError("This account has been already created");
setSignUpLoading(false);
}
@@ -108,7 +108,7 @@ export default function SignUp() {
useEffect(() => {
getCountryList();
});
}, []);
return (
<>
@@ -0,0 +1,157 @@
import React, { useState } from "react";
import dataImage2 from "../../assets/images/data-table-user-2.png";
import { handlePagingFunc } from "../Pagination/HandlePagination";
import PaginatedList from "../Pagination/PaginatedList";
import PendingJobsPopout from "../jobPopout/PendingJobsPopout";
import { PriceFormatter } from "../Helpers/PriceFormatter";
export default function MyWaitingJobTable({ MyJobList, className }) {
let [jobPopout, setJobPopout] = useState({ show: false, data: {} }); // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW
const [currentPage, setCurrentPage] = useState(0);
const indexOfFirstItem = Number(currentPage);
const indexOfLastItem =
Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
const currentActiveJobList = MyJobList?.result_list?.slice(
indexOfFirstItem,
indexOfLastItem
);
const handlePagination = (e) => {
handlePagingFunc(e, setCurrentPage);
};
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 || ""
}`}
>
{MyJobList && MyJobList?.result_list && (
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between h-full">
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
<tbody>
{/*<tr className="text-base text-thin-light-gray border-b dark:border-[#5356fb29] default-border-b dark:border-[#5356fb29] ottom ">*/}
{/* <td className="py-4">All Product</td>*/}
{/* <td className="py-4 text-right">.</td>*/}
{/*</tr>*/}
{
<>
{MyJobList &&
MyJobList?.result_list &&
MyJobList.result_list.length > 0 ? (
currentActiveJobList.map((value, index) => {
let deliveryDate = value?.expire?.split(" ")[0];
let thePrice = PriceFormatter(
value?.price * 0.01,
value?.currency_code,
value?.currency
);
return (
<tr
key={index}
className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50"
>
<td className=" py-4">
<div className="flex space-x-2 items-center w-full">
<div className="w-full h-[60px] rounded-full overflow-hidden flex justify-center items-center flex-[0.1] max-w-[60px]">
<img
src={dataImage2}
alt="data"
className="w-full h-full"
/>
</div>
<div className="flex flex-col flex-[0.9]">
<h1 className="font-bold text-xl text-dark-gray dark:text-white">
{value.title}
</h1>
<div>{value.description}</div>
<span className="text-sm text-thin-light-gray flex items-start gap-1">
Price:{" "}
<span className="text-purple">
{thePrice}
</span>
</span>
<div className="flex items-center gap-4">
<span className="text-sm text-thin-light-gray">
Duration:{" "}
<span className="text-purple">
{" "}
{value.timeline_days} day(s)
</span>
</span>
<span className="text-sm text-thin-light-gray">
Expire:{" "}
<span className="text-purple">
{" "}
{deliveryDate}
</span>
</span>
<span className="text-sm text-thin-light-gray">
Sent :{" "}
<span className="text-purple">
{" "}
{value.sent}
</span>
</span>
</div>
</div>
</div>
</td>
<td className="text-right py-4 px-2">
<button
type="button"
onClick={() => {
setJobPopout({ show: true, data: value });
}}
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
View
</button>
</td>
</tr>
);
})
) : (
<tr className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
<td className="p-2">No Pending Task!</td>
</tr>
)}
</>
}
</tbody>
</table>
{/* PAGINATION BUTTON */}
<PaginatedList
onClick={handlePagination}
prev={currentPage == 0 ? true : false}
next={
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
MyJobList?.result_list.length
? true
: false
}
data={MyJobList?.result_list}
start={indexOfFirstItem}
stop={indexOfLastItem}
/>
{/* END OF PAGINATION BUTTON */}
</div>
)}
{/* Active Job Popout */}
{jobPopout.show && (
<PendingJobsPopout
details={jobPopout.data}
onClose={() => {
setJobPopout({ show: false, data: {} });
}}
situation={jobPopout.show}
/>
)}
{/* End of Active Job Popout */}
</div>
);
}
+43
View File
@@ -0,0 +1,43 @@
import React, { useState } from "react";
import { Link } from "react-router-dom";
import Layout from "../Partials/Layout";
import CommonHead from "../UserHeader/CommonHead";
import MyWaitingJobTable from "./MyWaitingJobTable";
export default function MyWaitingJobs(props) {
const [selectTab, setValue] = useState("today");
const filterHandler = (value) => {
setValue(value);
};
console.log("AMEYE LOC1", props.MyJobList);
return (
<Layout>
<CommonHead
commonHeadData={props.commonHeadData}
/>
<div className="notification-page w-full mb-10">
<div className="notification-wrapper w-full">
{/* heading */}
<div className="sm:flex justify-between items-center mb-6">
<div className="mb-5 sm:mb-0">
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
<span
className={`${selectTab === "today" ? "block" : "hidden"}`}
>
Waiting Job(s)
</span>
</h1>
</div>
<div className="slider-btns flex space-x-4">
<div
onClick={() => filterHandler("today")}
className="relative"
></div>
</div>
</div>
<MyWaitingJobTable MyJobList={props.MyJobList} />
</div>
</div>
</Layout>
);
}
@@ -4,8 +4,6 @@ import Layout from "../Partials/Layout";
import CommonHead from "../UserHeader/CommonHead";
import usersService from "../../services/UsersService";
// import { handlePagingFunc } from "../Pagination/HandlePagination";
// import PaginatedList from "../Pagination/PaginatedList";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import OthersInterestedTable from "./OthersInterestedTable";
@@ -23,15 +21,7 @@ export default function ManageInterestOffer(props) {
let [messageListReload, setMessageListReload] = useState(false) // STATE TO DETERMINE WHEN MESSAGE LIST WILL RELOAD
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
// 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 [messageList, setMessageList] = useState({loading: true, data: []}) // TO BE REMOVED AND REPLACE WITH REAL MESSAGE FROM API CALL
const [selectTab, setValue] = useState("today");
const filterHandler = (value) => {
@@ -112,14 +102,17 @@ export default function ManageInterestOffer(props) {
})
}
useEffect(()=>{
// 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]})
useEffect(()=>{ //API to get Offer Interest message list
let reqData = { // API PAYLOADS
msg_type: 'MRKTINT',
offer_uid: props.offerDetails.offer_uid,
interest_uid: props.offerDetails.interest_uid
}
setMessageList(prev => ({...prev, loading: true}))
apiCall.offerInterestListMsg(reqData).then(res=>{
setMessageList({loading: false, data:res?.data?.result_list})
}).catch(err => {
setMessageList({loading: false, data:[1,2,3,6,7,8,9]})
setMessageList(prev => ({...prev, loading: false}))
console.log('Failed', err)
})
},[messageListReload])
@@ -288,36 +281,14 @@ export default function ManageInterestOffer(props) {
<div className="my-1 min-h-[100px] max-h-[200px] border-t overflow-y-scroll">
{ messageList.loading ?
<LoadingSpinner color='sky-blue' size='16' />
: messageList.data.map((item, index)=>(
: 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>
<p className="text-base font-bold text-dark-gray dark:text-white tracking-wide">{item.added.split(' ')[0]}-from { }<span className="font-normal">{item.sender || 'Dummy name'}</span></p>
<p className="text-base font-bold text-dark-gray dark:text-white tracking-wide">{item.msg}</p>
</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>
{/* PAGINATION BUTTON */}
{/* <PaginatedList
onClick={handlePagination}
prev={currentPage == 0 ? true : false}
next={
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
messageList?.data?.length
? true
: false
}
data={messageList?.data}
start={indexOfFirstItem}
stop={indexOfLastItem}
/> */}
{/* END OF PAGINATION BUTTON */}
</div>
}
</div>
+1 -2
View File
@@ -1,7 +1,6 @@
import React, {useEffect, useState} from "react";
import React, { useState} from "react";
import { useDispatch, useSelector } from "react-redux";
import { useNavigate } from "react-router-dom";
import { toast } from "react-toastify";
import useToggle from "../../hooks/useToggle";
import { drawerToggle } from "../../store/drawer";
import ModalCom from "../Helpers/ModalCom";
@@ -0,0 +1,210 @@
import React from "react";
export default function PrivacyPolicyTab() {
return (
<div className="terms-conditon-tab w-full">
<div className="terms-condition-wrappr w-full">
<div className="mb-6">
<h1 className="text-3xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
Privacy Policy
</h1>
<p className="text-base text-thin-light-gray leading-[28px] ">
Wrenchboard issues this policy to inform users about the information
we collect, the use and disclosures in the course of interactions
with the WrenchBoard services by customers. We value the privacy of
our customers and such strive to employ best industry standards and
practices to protect their privacy. By signing up for this services,
using our products or technologies offered through the WrenchBoard
website, you expressly agree to the terms of this Privacy Policy.
</p>
</div>
<hr />
<div className="my-8">
<h1 className="text-2xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
Collection of Information
</h1>
<p className="text-base text-thin-light-gray leading-[28px] ">
When you sign up for WrenchBoard platform as a user, freelancer,
worker or client, you inadvertently provide certain personal
information such as name and email address. This information may be
used to identify or contact you as part of the service we provide.
Below is information we may collect from registered users of the
service.
</p>
<ul className="flex flex-col rounded-[0.25rem]">
{[
"We collect financial information which include bank account numbers, debit/credit account.",
"We collect financial information which include bank account numbers, debit/credit account.",
"We collect personal information (names email addresses) from you and your friends when you use our referral program. We may also receive information about you from third party sites during promotions and campaigns.",
].map((item, idx) => (
<li
className="border-opacity-10 block relative px-[1.25rem] py-[0.75rem] first:rounded-tl first:rounded-tr text-[#505056]"
key={idx}
>
{item}
</li>
))}
</ul>
</div>
<hr />
<div className="my-8">
<h1 className="text-2xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
Use of Personal Information
</h1>
<p className="text-base text-thin-light-gray leading-[28px] ">
The information we collect about you is mainly utilized to provide a
secure, efficient and smooth user experience as you interact with
the site. We may also utilize the information to contact you to
resolve issues with your account or resolve disputes between
freelancers and clients. We also use your personal information in
the following ways.
</p>
<ul className="flex flex-col rounded-[0.25rem]">
{[
"To comply with the regulatory requirement, whenever the need arises.",
"To improve business relationship between Wrenchboard and users.",
"To manage and protect our IT infrastructure.",
"To contact you as the need arises as part of the services we offer to users.",
"To provide some indication on the promotional offers and advertisement we direct to you.",
"To protect you and your information. We regularly send you notification based on activities as you use the service.",
].map((item, idx) => (
<li
className="border-opacity-10 block relative px-[1.25rem] py-[0.75rem] first:rounded-tl first:rounded-tr text-[#505056]"
key={idx}
>
{item}
</li>
))}
</ul>
</div>
<hr />
<div className="my-8">
<h1 className="text-2xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
How We Share Your Personal Information:
</h1>
<p className="text-base text-thin-light-gray leading-[28px] ">
When you sign up to the Service as a freelancer and create a
profile, we will share your limited personal information with
clients or project owners for whom you may perform a task or do work
for based on expression of interest. Such information will include
name, profile information with experience and your ranking based on
previous performance. This information will be available to the
public.
<br />
When you register as a client or project owner and post a job in the
market place or offer jobs to preselected freelancers or workers on
this service, information about you, your business will be shared.
This information will be based on the information provided in your
profile. <br />
In order to deliver a quality service on WrenchBoard, we require the
services of third parties and agents such as PayPal, Quickteller
Service or banks to facilitate and process transactions. <br />
We may also share your personal information when and if compelled or
mandated by government agencies, or court injunctions or regulatory
requirement. In order to settle disputes or claims, we may also be
compelled to share your information in order to deliver services to
you. <br />
Finally, we may share your information with companies that we plan
to to merge with or to be acquired by. We will take necessary
measure to ensure that all such new affiliations and corporate
entities comply with the Privacy Policies hereby stated failing
which you will be notified duly.
</p>
</div>
<hr />
<div className="my-8">
<h1 className="text-2xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
How We Use Cookies and Related Technologies:
</h1>
<p className="text-base text-thin-light-gray leading-[28px] ">
When you access the service or website, www.wrenchboard.com , we
store small files called Cookies in your browser. Cookies and
related technologies like beacons and tags are used to identify
customers uniquely. With Cookies, we can track and trend the pages
of interest within the website. Hence, these technologies help us
focus only relevant promotions or advertisement to each customer.
Through this technologies, we are able to improve the service based
on the feedback from the interaction with users. We also rely on
these technologies to mitigate fraudulent attempts on your
WrenchBoard account. You may elect to disable cookies to prevent
installation of cookies from the website to your browser. However,
your functional experience with the service or website may be
impacted. Note that you automatically disconnect from cookies when
you close your browser session or log out of the service.
</p>
</div>
<hr />
<div className="my-8">
<h1 className="text-2xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
Measures We Take to Secure Your Information
</h1>
<p className="text-base text-thin-light-gray leading-[28px] ">
Your data and privacy are important to us as such we take extreme
care on how we protect your information. We use a combination of
industry standard encryption technologies to protect your
information. Your password is not visible to our technical support
team or any one in WrenchBoard. Our IT infrastructures are located
in hosting facilities with strict access controls, and security
protocols with only pre checked and authorized persons have access.
</p>
</div>
<hr />
<div className="my-8">
<h1 className="text-2xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
Updating Your Information or Opting Out
</h1>
<p className="text-base text-thin-light-gray leading-[28px] ">
Users of this service may update the information posted in profiles
or their accounts at any time. The accuracy of information posted on
the profiles and accounts is entirely the responsibility of users.
You may also decide to opt out the service or close your account at
any time. We may also deactivate your account if you violate the
terms of use of the website. Whilst we will endeavor to delete your
core information in such instances, we will retain minimal records
for reasons including disputes, claims or administrative purposes.
Also, note that it may not be possible to delete any information you
had shared with other users on the website previously.
</p>
</div>
<hr />
<div className="my-8">
<h1 className="text-2xl tracking-wide font-bold text-dark-gray dark:text-white mb-4">
Deactivate/Delete your account
</h1>
<p className="text-base text-thin-light-gray leading-[28px] ">
If you no longer wish to use our Services, you can deactivate your
Services account. If you want to deactivate your account, that
setting is available to you in your account settings. Otherwise,
please get in touch with our support. While we close any associated
process, you will not be able to access your account. Note that this
process cannot be reversed since we will remove your data. If you
want to use our services in the future, it will be a new account
altogether.
</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>
</div>
</div>
</div>
);
}
+19
View File
@@ -0,0 +1,19 @@
import ChangePasswordTab from "./ChangePasswordTab";
import FaqTab from "./FaqTab";
import LoginActivityTab from "./LoginActivityTab";
import NotificationSettingTab from "./NotificationSettingTab";
import PaymentMathodsTab from "./PaymentMathodsTab";
import PersonalInfoTab from "./PersonalInfoTab";
import PrivacyPolicyTab from "./PrivacyPolicyTab";
import TermsConditionTab from "./TermsConditionTab";
export {
ChangePasswordTab,
FaqTab,
LoginActivityTab,
NotificationSettingTab,
PaymentMathodsTab,
PersonalInfoTab,
PrivacyPolicyTab,
TermsConditionTab,
};
+83 -170
View File
@@ -1,56 +1,20 @@
import React, { useRef, useState } from "react";
import cover from "../../assets/images/profile-info-cover.png";
import profile from "../../assets/images/profile-info-profile.png";
import Icons from "../Helpers/Icons";
import Layout from "../Partials/Layout";
import ChangePasswordTab from "./Tabs/ChangePasswordTab";
import FaqTab from "./Tabs/FaqTab";
import LoginActivityTab from "./Tabs/LoginActivityTab";
import NotificationSettingTab from "./Tabs/NotificationSettingTab";
import PaymentMathodsTab from "./Tabs/PaymentMathodsTab";
import PersonalInfoTab from "./Tabs/PersonalInfoTab";
import TermsConditionTab from "./Tabs/TermsConditionTab";
import {
ChangePasswordTab,
FaqTab,
LoginActivityTab,
NotificationSettingTab,
PaymentMathodsTab,
PersonalInfoTab,
PrivacyPolicyTab,
TermsConditionTab,
} from "./Tabs";
export default function Settings({faq}) {
const tabs = [
{
id: 1,
name: "personal",
},
{
id: 2,
name: "payment",
},
{
id: 3,
name: "notification",
},
{
id: 4,
name: "login_activity",
},
{
id: 5,
name: "password",
},
{
id: 6,
name: "faq",
},
{
id: 7,
name: "privacy",
},
{
id: 8,
name: "terms",
},
];
const [tab, setTab] = useState(tabs[0].name);
const tabHandler = (value) => {
setTab(value);
};
export default function Settings({ faq }) {
const [profileImg, setProfileImg] = useState(profile);
const [coverImg, setCoverImg] = useState(cover);
@@ -83,6 +47,62 @@ export default function Settings({faq}) {
}
};
// Tabs Handling
const tabs = [
{
id: 1,
name: "personal",
title: "Edit Profile",
iconName: "people-hover",
},
{
id: 2,
name: "payment",
title: "Payment Method",
iconName: "bank-card",
},
{
id: 3,
name: "notification",
title: "Notification Setting",
iconName: "notification-setting",
},
{
id: 4,
name: "login_activity",
title: "Login Activity",
iconName: "login-activity",
},
{
id: 5,
name: "password",
title: "Change Password",
iconName: "password-hover",
},
{
id: 6,
name: "faq",
title: "FAQ",
iconName: "block-question",
},
{
id: 7,
name: "privacy",
title: "Privacy Policy",
iconName: "page-right",
},
{
id: 8,
name: "terms",
title: "Terms and Conditions",
iconName: "page-right",
},
];
const [tab, setTab] = useState(tabs[0].name);
const tabHandler = (value) => {
setTab(value);
};
return (
<>
<Layout>
@@ -97,136 +117,28 @@ export default function Settings({faq}) {
<div className="content-container w-full pt-10 rounded-2xl bg-white dark:bg-dark-white ">
<div className="content-heading w-full mb-8 lg:px-10 px-4">
<h1 className="text-xl font-bold text-dark-gray dark:text-white antialiased">
Parsonal Informaiton
Personal Information
</h1>
</div>
<div className="content-body w-full lg:flex lg:px-10 px-4">
<div className="content-tab-items lg:w-[230px] w-full mr-2">
<ul className="overflow-hidden mb-10 lg:mb-0">
<li
onClick={() => tabHandler("personal")}
className={`flex lg:space-x-4 space-x-2 hover:text-purple transition-all duration-300 ease-in-out items-center cursor-pointer lg:mb-11 mb-2 mr-6 lg:mr-0 float-left lg:float-none overflow-hidden ${
tab === "personal"
? "text-purple"
: " text-thin-light-gray"
}`}
>
<div>
<Icons name="people-hover" />
</div>
<div>
<p className="text-18 tracking-wide">Edit Profile</p>
</div>
</li>
<li
onClick={() => tabHandler("payment")}
className={`flex lg:space-x-4 space-x-2 hover:text-purple transition-all duration-300 ease-in-out items-center cursor-pointer lg:mb-11 mb-2 mr-6 lg:mr-0 float-left lg:float-none overflow-hidden ${
tab === "payment"
? "text-purple"
: " text-thin-light-gray"
}`}
>
<div>
<Icons name="bank-card" />
</div>
<div>
<p className="text-18 tracking-wide">Payment Method</p>
</div>
</li>
<li
onClick={() => tabHandler("notification")}
className={`flex lg:space-x-4 space-x-2 hover:text-purple transition-all duration-300 ease-in-out items-center cursor-pointer lg:mb-11 mb-2 mr-6 lg:mr-0 float-left lg:float-none overflow-hidden ${
tab === "notification"
? "text-purple"
: " text-thin-light-gray"
}`}
>
<div>
<Icons name="notification-setting" />
</div>
<div>
<p className="text-18 tracking-wide">
Notifiction Setting
</p>
</div>
</li>
<li
onClick={() => tabHandler("login_activity")}
className={`flex lg:space-x-4 space-x-2 hover:text-purple transition-all duration-300 ease-in-out items-center cursor-pointer lg:mb-11 mb-2 mr-6 lg:mr-0 float-left lg:float-none overflow-hidden ${
tab === "login_activity"
? "text-purple"
: " text-thin-light-gray"
}`}
>
<div>
<Icons name="login-activity" />
</div>
<div>
<p className="text-18 tracking-wide">Login Activity</p>
</div>
</li>
<li
onClick={() => tabHandler("password")}
className={`flex lg:space-x-4 space-x-2 hover:text-purple transition-all duration-300 ease-in-out items-center cursor-pointer lg:mb-11 mb-2 mr-6 lg:mr-0 float-left lg:float-none overflow-hidden ${
tab === "password"
? "text-purple"
: " text-thin-light-gray"
}`}
>
<div>
<Icons name="password-hover" />
</div>
<div>
<p className="text-18 tracking-wide">Change Password</p>
</div>
</li>
<li
onClick={() => tabHandler("faq")}
className={`flex lg:space-x-4 space-x-2 hover:text-purple transition-all duration-300 ease-in-out items-center cursor-pointer lg:mb-11 mb-2 mr-6 lg:mr-0 float-left lg:float-none overflow-hidden ${
tab === "faq" ? "text-purple" : " text-thin-light-gray"
}`}
>
<div>
<Icons name="block-question" />
</div>
<div>
<p className="text-18 tracking-wide">FAQ</p>
</div>
</li>
<li
onClick={() => tabHandler("terms")}
{tabs.map(({ name, id, title, iconName }) => (
<li
onClick={() => tabHandler(name)}
key={id}
className={`flex lg:space-x-4 space-x-2 hover:text-purple transition-all duration-300 ease-in-out items-center cursor-pointer lg:mb-11 mb-2 mr-6 lg:mr-0 float-left lg:float-none overflow-hidden ${
tab === "privacy"
? "text-purple"
: " text-thin-light-gray"
tab === name ? "text-purple" : " text-thin-light-gray"
}`}
>
<div>
<Icons name="page-right" />
</div>
<div>
<p className="text-18 tracking-wide">
Privacy Policy
</p>
</div>
</li>
<li
onClick={() => tabHandler("terms")}
className={`flex lg:space-x-4 space-x-2 hover:text-purple transition-all duration-300 ease-in-out items-center cursor-pointer lg:mb-11 mb-2 mr-6 lg:mr-0 float-left lg:float-none overflow-hidden ${
tab === "terms"
? "text-purple"
: " text-thin-light-gray"
}`}
>
<div>
<Icons name="page-right" />
</div>
<div>
<p className="text-18 tracking-wide">
Terms and Conditions
</p>
</div>
</li>
>
<div>
<Icons name={iconName} />
</div>
<div>
<p className="text-18 tracking-wide">{title}</p>
</div>
</li>
))}
</ul>
</div>
<div className="w-[1px] bg-[#E3E4FE] dark:bg-[#a7a9b533] mr-10"></div>
@@ -258,6 +170,7 @@ export default function Settings({faq}) {
{tab === "login_activity" && <LoginActivityTab />}
{tab === "password" && <ChangePasswordTab />}
{tab === "faq" && <FaqTab datas={faq} />}
{tab === "privacy" && <PrivacyPolicyTab />}
{tab === "terms" && <TermsConditionTab />}
</div>
</div>
+7 -6
View File
@@ -53,7 +53,7 @@ const EditJobPopOut = ({
let initialValues = {
// initial values for formik
country: country,
currency: details.currency,
price: details?.price,
title: details?.title,
description: details?.description,
@@ -74,7 +74,7 @@ const EditJobPopOut = ({
job_uid: details.job_uid,
...values,
};
delete reqData?.country;
delete reqData?.currency;
try {
let res = await jobApi.jobManagerUpdateJob(reqData);
let { data } = await res;
@@ -93,6 +93,7 @@ const EditJobPopOut = ({
[jobApi, navigate, onClose, details]
);
console.log(details)
return (
<ModalCom action={onClose} situation={situation} className="edit-popup">
<div className="logout-modal-wrapper lg:w-[600px] h-full lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl">
@@ -140,13 +141,13 @@ const EditJobPopOut = ({
<div className="field w-full mb-6 xl:mb-0">
<InputCom
fieldClass="px-6 cursor-default"
label="Country"
label="Currency"
labelClass="tracking-wide"
inputBg="bg-slate-100"
inputClass="input-curve lg border border-light-purple"
type="text"
name="country"
value={props.values.country}
name="currency"
value={props.values.currency}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
disable={true}
@@ -163,7 +164,7 @@ const EditJobPopOut = ({
inputClass="input-curve lg border border-light-purple"
type="number"
name="price"
value={props.values.price * 0.01}
value={props.values.price}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
errorBorder={
+5 -1
View File
@@ -26,6 +26,7 @@
text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;
font-family: sans; color: white;
font-size: 42px;
font-family: Circular, Helvetica Neue, Helvetica, Roboto, Arial, sans-serif;
}
.job-action{
@@ -52,10 +53,13 @@
}
.siderCardDescription{
margin: 10px 45px 10px 45px;
font-size: 18px;
background-color: aliceblue;
padding: 5px;
border-radius: 5px;
font-family: Circular, Helvetica Neue, Helvetica, Roboto, Arial, sans-serif;
font-weight: 400;
font-size: 1.125rem;
line-height: 1.56;
}
.siderCardButton{
margin-top: 10px;
+97 -52
View File
@@ -47,9 +47,9 @@ class usersService {
};
return this.postAuxEnd("/mybanklist", postData);
}
getUserWallets(reqData) {
getUserWallets() {
var postData = {
uuid: localStorage.getItem("uuid"),
uid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
};
@@ -208,7 +208,7 @@ class usersService {
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
action: 22025,
...reqData
...reqData,
};
return this.postAuxEnd("/familymanage", postData);
}
@@ -223,7 +223,7 @@ class usersService {
limit: 30,
offset: 0,
action: 13008,
...reqData
...reqData,
};
return this.postAuxEnd("/jobmanageractive", postData);
}
@@ -289,6 +289,29 @@ class usersService {
};
return this.postAuxEnd("/jobmanageroffers", postData);
}
//
getResourceList() { // jobs you have shown inteterest in
var postData = {
uuid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
page: 0,
offset: 0,
limit: 100,
};
return this.postAuxEnd("/resources", postData);
}
getMyWiatingJobList() { // jobs you have shown inteterest in
var postData = {
uuid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
page: 0,
offset: 0,
limit: 100,
};
return this.postAuxEnd("/waitinginterest", postData);
}
getMyJobList() {
var postData = {
uuid: localStorage.getItem("uid"),
@@ -449,8 +472,8 @@ class usersService {
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
action: 11032,
...postData
}
...postData,
};
return this.postAuxEnd("/sendreferral", reqData);
}
@@ -468,7 +491,7 @@ class usersService {
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
action: 85020,
...reqData
...reqData,
};
return this.postAuxEnd("/couponredeem", postData);
}
@@ -485,7 +508,7 @@ class usersService {
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
action: 11183,
country: "NG",
// country: "NG",
};
return this.postAuxEnd("/countrybanks", postData);
}
@@ -507,9 +530,9 @@ class usersService {
uid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
msg_type: 'JOB',
msg_type: "JOB",
action: 13033,
...reqData
...reqData,
};
return this.postAuxEnd("/marketinterest", postData);
}
@@ -519,9 +542,9 @@ class usersService {
uid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
msg_type: 'JOB',
msg_type: "JOB",
action: 13036,
...reqData
...reqData,
};
return this.postAuxEnd("/marketmessage", postData);
}
@@ -623,7 +646,7 @@ class usersService {
for (let data in postData) {
formData.append(data, postData[data]);
}
// return this.postAuxEnd("/uploads", formData);
// return this.postAuxEnd("/uploads", formData);
return this.postAuxEnd("/uploads", postData);
}
@@ -668,25 +691,25 @@ class usersService {
sessionid: localStorage.getItem("session_token"),
action: 13024,
limit: 30,
offset: 0
offset: 0,
};
return this.postAuxEnd("/offersinterestlist", postData);
}
// END POINT FOR PROCESSING OFFER INTEREST
offersInterestProc(reqData) {
var postData = {
uid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
action: 13034,
...reqData
};
return this.postAuxEnd("/offersinterestproc", postData);
}
// END POINT FOR PROCESSING OFFER INTEREST
offersInterestProc(reqData) {
var postData = {
uid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
action: 13034,
...reqData,
};
return this.postAuxEnd("/offersinterestproc", postData);
}
// END POINT FOR WORKER TO MARK TASK AS COMPLETED
workerJobAction(reqData) {
// END POINT FOR WORKER TO MARK TASK AS COMPLETED
workerJobAction(reqData) {
var postData = {
uid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
@@ -697,50 +720,72 @@ class usersService {
return this.postAuxEnd("/activetaskstatus", postData);
}
// END POINT FOR OWNER JOB ACTION
ownerJobAction(reqData) {
var postData = {
uid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
action: 14015,
...reqData,
};
return this.postAuxEnd("/activejobstatus", postData);
}
// END POINT FOR OWNER JOB ACTION
ownerJobAction(reqData) {
var postData = {
uid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
action: 14015,
...reqData,
};
return this.postAuxEnd("/activejobstatus", postData);
}
// END POINT FOR OWNER JOB ACTION
getFaq() {
var postData = {
uid: localStorage.getItem("uid"),
// member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
};
return this.postAuxEnd("/faq", postData);
}
getMyNotifications() {
var postData = {
uid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
limit: 30,
offset: 0,
action: 11205,
};
return this.postAuxEnd("/mynotifications", 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
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);
}
// END POINT TO SEND 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);
}
// END POINT TO GET OFFER INTEREST MESSAGE
offerInterestListMsg(reqData) {
var postData = {
uid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
action: 13037,
...reqData,
};
return this.postAuxEnd("/offerinterestlistmsg", postData);
}
/*
- 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(username)
- 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(password)
+33
View File
@@ -0,0 +1,33 @@
import React, { useContext, useState, useEffect } from "react";
import usersService from "../services/UsersService";
import MyPendingJobs from "../components/MyPendingJobs";
import { useSelector } from "react-redux";
import MyWaitingJobs from "../components/MyWaitingJobs";
export default function MyWaitingJobsPage() {
let { commonHeadBanner } = useSelector((state) => state.commonHeadBanner);
const [MyJobList, setMyJobList] = useState([]);
const api = new usersService();
const getMyJobList = async () => {
try {
const res = await api.getMyWiatingJobList();
setMyJobList(res.data);
} catch (error) {
console.log("Error getting mode");
}
};
useEffect(() => {
getMyJobList();
}, []);
// debugger;
return (
<>
<MyWaitingJobs
MyJobList={MyJobList}
commonHeadData={commonHeadBanner.result_list}
/>
</>
);
}
+21 -4
View File
@@ -1,7 +1,24 @@
import React from "react";
//import UserProfile from "../components/AuthPages/UserProfile";
import React, { useContext, useState, useEffect } from "react";
import Resources from "../components/Resources";
import {useSelector} from "react-redux";
import usersService from "../services/UsersService";
export default function ResourcePage() {
return <Resources />;
const [MyResourceData, setMyResourceData] = useState([]);
const api = new usersService();
const getMyResourceData = async () => {
try {
const res = await api.getResourceList();
setMyResourceData(res.data);
} catch (error) {
console.log("Error getting mode");
}
};
useEffect(() => {
getMyResourceData();
}, []);
return <Resources
MyResourceData={MyResourceData} />;
}
+3 -2
View File
@@ -6,14 +6,14 @@ export default function SettingsPage() {
const apiCall = new usersService()
let [faq, setFaq] = useState({loading:true, data:[]}) // STATE TO HOLD FAQ DATA
let [faq, setFaq] = useState({loading:true, data:null}) // STATE TO HOLD FAQ DATA
//FUNCTION TO GET FAQ
const getFaq = () => {
apiCall.getFaq().then(res => {
setFaq({loading:false, data:res.data.result_list})
}).catch(err => {
setFaq({loading:false, data:[]})
setFaq({loading:false, data:null})
console.log('Error', err)
})
}
@@ -21,6 +21,7 @@ export default function SettingsPage() {
useEffect(()=>{
getFaq()
},[])
return (
<>
<Settings faq={faq} />