Compare commits

...

13 Commits

22 changed files with 375 additions and 300 deletions
+7 -33
View File
@@ -1,12 +1,12 @@
import React, { useState, useEffect } from "react";
import { Link, useNavigate } from "react-router-dom";
import { Link } from "react-router-dom";
import InputCom from "../Helpers/Inputs/InputCom";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import usersService from "../../services/UsersService";
import { useSelector, useDispatch } from "react-redux";
import { tableReload } from '../../store/TableReloads'
import { tableReload } from "../../store/TableReloads";
import { Field, Form, Formik } from "formik";
import * as Yup from "yup";
@@ -38,16 +38,12 @@ const validationSchema = Yup.object().shape({
.required("Timeline is required"),
});
function AddJob() {
function AddJob({ popUpHandler }) {
const ApiCall = new usersService();
const navigate = useNavigate();
let dispatch = useDispatch()
let dispatch = useDispatch();
let { userDetails } = useSelector((state) => state.userDetails);
let [pageLoading, setPageLoading] = useState(true); // State used for knowing when the page is mounting
let [country, setCountry] = useState({
loading: true,
status: false,
@@ -109,8 +105,8 @@ function AddJob() {
message: "Job Added Successfully",
});
setTimeout(() => {
dispatch(tableReload({type:'JOBTABLE'}))
navigate("/myjobs", { replace: true });
dispatch(tableReload({ type: "JOBTABLE" }));
popUpHandler()
}, 1000);
})
.catch((err) => {
@@ -129,16 +125,9 @@ function AddJob() {
useEffect(() => {
getUserCountry();
setPageLoading(false);
}, []);
return pageLoading.loading ? (
<div className="personal-info-tab w-full flex flex-col justify-between">
<div className="p-3">
<LoadingSpinner size="32" color="sky-blue" />
</div>
</div>
) : (
return (
<div className="add-job p-5 w-full bg-white rounded-md flex flex-col justify-between">
<Formik
initialValues={initialValues}
@@ -148,27 +137,12 @@ function AddJob() {
{(props) => {
return (
<Form>
<h1 className="py-2 my-4 text-lg md:text-xl font-bold tracking-wide">
Create New Job
</h1>
<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-6">
<div className="field w-full mb-6 xl:mb-0">
{/* <InputCom
fieldClass="px-6 cursor-not-allowed"
label="Country"
labelClass='tracking-wide'
inputBg = 'bg-slate-100'
type="text"
name="country"
disable={true}
value={country.loading ? 'loading' : country.data ? country.data : 'no country found!'}
inputHandler={(e)=> setCountry((prev) => ({...prev, data:e.target.value}))}
/> */}
<label
htmlFor="country"
className="input-label text-[#181c32] dark:text-white text-[13.975px] leading-[20.9625px] font-semibold block"
@@ -117,7 +117,7 @@ export default function FamilyManageTabs({
return (
<div
className={`update-table w-full bg-white dark:bg-dark-white overflow-y-auto rounded-2xl section-shadow min-h-[520px] max-h-[600px] ${
className={`w-full bg-white dark:bg-dark-white overflow-y-auto rounded-2xl section-shadow min-h-[520px] max-h-[600px] ${
className || ""
}`}
>
+35 -31
View File
@@ -5,16 +5,12 @@ import { handlePagingFunc } from "../../Pagination/HandlePagination";
import PaginatedList from "../../Pagination/PaginatedList";
import LoadingSpinner from "../../Spinners/LoadingSpinner";
import Icons from "../../Helpers/Icons";
import { PriceFormatter } from "../../Helpers/PriceFormatter";
export default function FamilyTasks({ familyData, className, loader }) {
const filterCategories = ["All Categories", "Explore", "Featured"];
const [selectedCategory, setCategory] = useState(filterCategories[0]);
let navigate = useNavigate();
let { pathname } = useLocation();
let data = ["1", "2", "3", "4", "5", "6"]; // to be replaced later by result from API CALL
const [currentPage, setCurrentPage] = useState(0);
const indexOfFirstItem = Number(currentPage);
const indexOfLastItem =
@@ -24,10 +20,7 @@ export default function FamilyTasks({ familyData, className, loader }) {
indexOfLastItem
);
const handlePagination = (e) => {
handlePagingFunc(e, setCurrentPage);
};
const handlePagination = (e) => handlePagingFunc(e, setCurrentPage);
return (
<div
@@ -52,8 +45,14 @@ export default function FamilyTasks({ familyData, className, loader }) {
familyData?.result_list &&
familyData.result_list.length > 0 &&
currentTask.map((value, index) => {
// find due date
const dueDate = value?.delivery_date.split(" ")[0]
// find due date
const dueDate = value?.delivery_date.split(" ")[0];
// the price
let thePrice = PriceFormatter(
value?.price * 0.01,
value?.currency_code,
value?.currency
);
return (
<tr
key={index}
@@ -73,37 +72,42 @@ export default function FamilyTasks({ familyData, className, loader }) {
{value.title}
</h1>
<div className="flex gap-4 items-center">
<span className="text-sm text-thin-light-gray">
Price:{" "}
<span className="text-purple">
{value.price * 0.01}
<span className="text-sm text-thin-light-gray">
Price:{" "}
<span className="text-purple">
{thePrice}
</span>
</span>
</span>
<span className="text-sm text-thin-light-gray">
Duration:{" "}
<span className="text-purple">
{" "}
{value.timeline_days} day(s)
<span className="text-sm text-thin-light-gray">
Duration:{" "}
<span className="text-purple">
{" "}
{value.timeline_days} day(s)
</span>
</span>
</span>
<span className="text-sm text-thin-light-gray">
Due Date:{" "}
<span className="text-purple">
{" "}
{dueDate}
<span className="text-sm text-thin-light-gray">
Due Date:{" "}
<span className="text-purple">
{" "}
{dueDate}
</span>
</span>
</span>
</div>
</div>
</div>
</td>
<td className="text-right py-4 px-2">
<button
type="button"
onClick={() => {
navigate("/manage-active-job", {
state: { ...value, pathname },
state: {
...value,
pathname,
dueDate,
thePrice,
},
});
}}
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
@@ -112,7 +116,7 @@ export default function FamilyTasks({ familyData, className, loader }) {
</button>
</td>
</tr>
)
);
})}
</>
}
+2 -2
View File
@@ -10,7 +10,7 @@ export default function Accordion({ datas }) {
<>
<div className="accordion-item overflow-hidden relative z-[1]">
<div
className="accordion-title-bar flex items-center space-x-3 py-5 border-b border-light-purple dark:border-[#5356fb29] "
className="accordion-title-bar flex items-center space-x-3 py-5 border-b border-light-purple dark:border-[#5356fb29] cursor-pointer"
onClick={accordionHandler}
>
<div className="accordion-title-icon relative">
@@ -36,7 +36,7 @@ export default function Accordion({ datas }) {
<div className="w-[3px] h-auto bg-purple rounded-[28px]"></div>
<div className="flex-1">
<p className="text-base text-thin-light-gray tracking-wide">
{datas.content}
{datas.msg}
</p>
</div>
</div>
@@ -68,13 +68,13 @@ export default function InputCom({
)}
</div>
<div
className={`input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-[0.475rem] 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 border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base ${inputClass}`}
>
<input
placeholder={placeholder}
value={value}
onChange={inputHandler}
className={`input-field placeholder:text-base text-dark-gray w-full h-full ${
className={`input-field placeholder:text-base text-dark-gray w-full h-full tracking-wide ${
inputBg ? inputBg : "bg-[#FAFAFA]"
} dark:bg-[#11131F] focus:ring-0 focus:outline-none ${fieldClass}`}
type={type}
+1 -1
View File
@@ -241,7 +241,7 @@ export default function History() {
</div>
{/* END OF RECENT ACTIVITY SECTION */}
</div>
<HistoryTable />
{/*<HistoryTable />*/}
</div>
</div>
</Layout>
+37 -19
View File
@@ -1,10 +1,17 @@
import { useMemo, useState } from "react";
import { toast } from "react-toastify";
import usersService from "../../services/UsersService";
import { useDispatch } from "react-redux";
import { tableReload } from "../../store/TableReloads";
const CouponPopup = ({ popUpHandler, data }) => {
const [loader, setLoader] = useState(false);
const apiCall = useMemo(() => new usersService(), []);
const [statusMsg, setStatusMsg] = useState({
success: "",
error: "",
});
const dispatch = useDispatch();
const redeemCouponHandler = async () => {
setLoader(true);
@@ -14,28 +21,34 @@ const CouponPopup = ({ popUpHandler, data }) => {
const reqData = { code_id: Number(coupon_id), code };
const res = await apiCall.getCouponRedeem(reqData);
if (res.statusText === "OK") {
toast.success("Great news! Your coupon has been redeemed.", {
autoClose: 3000,
hideProgressBar: true,
});
}
if (res.data?.internal_return < 0)
setStatusMsg({ error: "An error occurred" });
else setStatusMsg({ success: res.data?.status_text });
dispatch(tableReload({ type: "COUPONTABLE" }));
setTimeout(() => {
popUpHandler();
setLoader(false);
}, 3000);
throw new Response(res);
}, 10000);
} catch (error) {
// error &&
// toast.warn("An error occurred while processing your coupon.", {
// autoClose: 3000,
// hideProgressBar: true,
// });
setLoader(false);
console.log(error);
return;
// throw new Error(error);
if (error?.status !== 200)
setStatusMsg({
error: {
status: true,
msg:
error?.statusText !== ""
? error?.statusText
: "An error occurred",
},
});
throw new Error(error);
} finally {
setStatusMsg({
success: "",
error: "",
});
}
};
@@ -77,9 +90,8 @@ const CouponPopup = ({ popUpHandler, data }) => {
Amount:
</label>
</div>
<div className=" flex-[0.7] max-w-[150px]">{`${data?.amount} Naira`}</div>
<div className=" flex-[0.7] max-w-[150px]">{data?.thePrice}</div>
</div>
<div className="signin-area w-full">
<div className="flex justify-end">
<button
@@ -96,6 +108,12 @@ const CouponPopup = ({ popUpHandler, data }) => {
)}
</button>
</div>
{statusMsg.success && (
<p className="text-sm text-green-500 italic">{statusMsg.success}</p>
)}
{statusMsg.error && (
<p className="text-sm text-red-500 italic">{statusMsg.error}</p>
)}
</div>
</form>
<div className="signin-area w-full px-5 py-4">
+11 -4
View File
@@ -4,6 +4,7 @@ import { handlePagingFunc } from "../Pagination/HandlePagination";
import ModalCom from "../Helpers/ModalCom";
import CouponPopup from "./CouponPopup";
import { useNavigate } from "react-router-dom";
import { PriceFormatter } from "../Helpers/PriceFormatter";
function CouponTable({ coupon }) {
const [currentPage, setCurrentPage] = useState(0);
@@ -38,12 +39,18 @@ function CouponTable({ coupon }) {
</thead>
{coupon.data.length ? (
<tbody>
{currentCoupon.map((item, index) => (
{currentCoupon.map((item, index) => {
let thePrice = PriceFormatter(
item?.amount * 0.01,
item?.currency_code,
item?.currency
);
return(
<tr key={index} className="text-slate-500">
<td className="p-2 cursor-default">
{item.added} <br /> {item.code}
</td>
<td className="p-2 text-center cursor-default">{`${item.amount} Naira`}</td>
<td className="p-2 text-center cursor-default">{thePrice}</td>
<td className="p-2 h-20 flex items-center justify-end">
<button
type="button"
@@ -51,7 +58,7 @@ function CouponTable({ coupon }) {
onClick={() => {
setCouponPopup((prev) => ({
state: !prev.state,
data: item,
data: {...item, thePrice},
}));
}}
>
@@ -59,7 +66,7 @@ function CouponTable({ coupon }) {
</button>
</td>
</tr>
))}
)})}
</tbody>
) : coupon.error ? (
<tbody>
+8 -6
View File
@@ -1,11 +1,13 @@
import React, { useEffect, useState } from "react";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import Layout from "../Partials/Layout";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import CouponTable from "./CouponTable";
import usersService from "../../services/UsersService";
import { useSelector } from "react-redux";
export default function MyCoupons() {
const apiCall = new usersService();
const apiCall = useMemo(() => new usersService(), []);
const {couponTable} = useSelector(state => state.tableReload)
let [couponHistory, setCouponHistory] = useState({
// FOR COUPON HISTORY
loading: true,
@@ -14,7 +16,7 @@ export default function MyCoupons() {
});
//FUNCTION TO GET COUPON HISTORY
const getCouponHistory = () => {
const getCouponHistory = useCallback(() => {
apiCall
.getCouponPending()
.then((res) => {
@@ -32,11 +34,11 @@ export default function MyCoupons() {
.catch((error) => {
setCouponHistory((prev) => ({ ...prev, loading: false, error: true }));
});
};
}, [apiCall]);
useEffect(() => {
getCouponHistory();
}, []);
}, [couponTable]);
return (
<>
@@ -59,7 +61,7 @@ export default function MyCoupons() {
<LoadingSpinner size="16" color="sky-blue" />
</div>
) : (
<CouponTable coupon={couponHistory} />
<CouponTable coupon={couponHistory} />
)}
</div>
</div>
+15 -10
View File
@@ -11,6 +11,7 @@ import usersService from "../../services/UsersService";
import { handlePagingFunc } from "../Pagination/HandlePagination";
import PaginatedList from "../Pagination/PaginatedList";
import EditJobPopOut from "../jobPopout/EditJobPopout";
import { PriceFormatter } from "../Helpers/PriceFormatter";
export default function MyJobTable({ MyJobList, reloadJobList, className }) {
const [myCountry, setCountries] = useState("");
@@ -101,9 +102,15 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
{selectedCategory === "All Categories" ? (
<>
{MyJobList &&
MyJobList?.data?.result_list &&
MyJobList.data?.result_list.length > 0 ?
currentJobList.map((value, index) => (
MyJobList?.data?.result_list &&
MyJobList.data?.result_list.length > 0 ? (
currentJobList.map((value, index) => {
let thePrice = PriceFormatter(
value?.price * 0.01,
value?.currency_code,
value?.currency
);
return(
<tr
key={index}
className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50"
@@ -126,7 +133,7 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
<span className="text-sm text-thin-light-gray">
Price:{" "}
<span className="text-purple">
{value.price * 0.01}
{thePrice}
</span>
</span>
<span className="text-sm text-thin-light-gray">
@@ -181,14 +188,12 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
</button>
</td>
</tr>
))
:
)})
) : (
<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>
}
)}
</>
) : selectedCategory === "Explore" ? (
<></>
+17 -26
View File
@@ -3,50 +3,41 @@ import { Link } from "react-router-dom";
import Layout from "../Partials/Layout";
import MyJobTable from "./MyJobTable";
import CommonHead from "../UserHeader/CommonHead";
import AddJobPage from "../../views/AddJobPage";
export default function MyJobs(props) {
const [selectTab, setValue] = useState("today");
const filterHandler = (value) => {
setValue(value);
const [popUp, setPopUp] = useState(false);
const popUpHandler = () => {
setPopUp((prev) => !prev);
};
return (
<Layout>
<CommonHead
commonHeadData={props.commonHeadData}
/>
<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="sm:flex items-center mb-6">
<div className="mb-5 sm:mb-0">
<h1 className="text-26 font-bold flex items-center space-x-1 text-dark-gray dark:text-white gap-2">
<span
className={`${selectTab === "today" ? "block" : "hidden"}`}
>
My Jobs
</span>
<span>My Jobs</span>
<Link
to="/add-job"
<button
className="text-white btn-gradient text-lg tracking-wide px-5 py-2 rounded-full"
onClick={popUpHandler}
>
Add Job
</Link>
</button>
</h1>
</div>
<div className="slider-btns flex space-x-4">
<div
onClick={() => filterHandler("today")}
className="relative"
></div>
</div>
</div>
<MyJobTable
MyJobList={props.MyJobList}
/>
<MyJobTable MyJobList={props.MyJobList} />
</div>
</div>
{/* Add Job List Popout */}
{popUp && <AddJobPage action={popUpHandler} situation={popUp} />}
{/* End of Add Job List Popout */}
</Layout>
);
}
}
@@ -1,66 +1,85 @@
import React, {useState} from 'react'
import React, { useState } from "react";
import PaginatedList from '../../Pagination/PaginatedList'
import { handlePagingFunc } from '../../Pagination/HandlePagination';
import PaginatedList from "../../Pagination/PaginatedList";
import { handlePagingFunc } from "../../Pagination/HandlePagination";
import { PriceFormatter } from "../../Helpers/PriceFormatter";
function CouponTable({coupon}) {
function CouponTable({ coupon }) {
const [currentPage, setCurrentPage] = useState(0);
const indexOfFirstItem = Number(currentPage);
const indexOfLastItem =
Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
const currentCoupon = coupon?.data?.slice(indexOfFirstItem, indexOfLastItem);
const [currentPage, setCurrentPage] = useState(0);
const indexOfFirstItem = Number(currentPage);
const indexOfLastItem = Number(indexOfFirstItem)+Number(process.env.REACT_APP_ITEM_PER_PAGE);
const currentCoupon = coupon?.data?.slice(indexOfFirstItem, indexOfLastItem);
const handlePagination = (e) => {
handlePagingFunc(e,setCurrentPage)
}
const handlePagination = (e) => {
handlePagingFunc(e, setCurrentPage);
};
return (
<div className='flex flex-col justify-between h-full'>
<table className="wallet-activity w-full table-auto border-collapse text-left">
<thead className='border-b-2'>
<tr className='text-slate-600'>
<div className="flex flex-col justify-between h-full">
<table className="wallet-activity w-full table-auto border-collapse text-left">
<thead className="border-b-2">
<tr className="text-slate-600">
<th className="p-2">Date</th>
<th className="p-2">Description</th>
<th className="p-2">Amount</th>
<th className="p-2">Active</th>
</tr>
</tr>
</thead>
{coupon.data.length ?
(
<tbody>
{currentCoupon.map((item, index) => (
<tr key={index} className='text-slate-500'>
<td className="p-2">{item.added}</td>
<td className="p-2">{item.code}</td>
<td className="p-2">{item.amount}</td>
<td className="p-2">{item.status}</td>
{coupon.data.length ? (
<tbody>
{currentCoupon.map((item, index) => {
let thePrice = PriceFormatter(
item?.price * 0.01,
item?.currency_code,
item?.currency
);
return (
<tr key={index} className="text-slate-500">
<td className="p-2">{item.added}</td>
<td className="p-2">{item.code}</td>
<td className="p-2">{item.amount}</td>
<td className="p-2">{item.status}</td>
</tr>
);
})}
</tbody>
) : coupon.error ? (
<tbody>
<tr className="text-slate-500">
<td className="p-2" colSpan={4}>
Opps! an error occurred. Please try again!
</td>
</tr>
))}
</tbody>
)
:
coupon.error ?
(
<tbody>
<tr className='text-slate-500'>
<td className="p-2" colSpan={4}>Opps! an error occurred. Please try again!</td>
</tbody>
) : (
<tbody>
<tr className="text-slate-500">
<td className="p-2" colSpan={4}>
No Purchase History Found!
</td>
</tr>
</tbody>
)
:
<tbody>
<tr className='text-slate-500'>
<td className="p-2" colSpan={4}>No Purchase History Found!</td>
</tr>
</tbody>
}
</table>
</tbody>
)}
</table>
{/* PAGINATION BUTTON */}
<PaginatedList onClick={handlePagination} prev={currentPage == 0 ? true : false} next={currentPage+Number(process.env.REACT_APP_ITEM_PER_PAGE) >= coupon?.data?.length ? true : false} data={coupon?.data} start={indexOfFirstItem} stop={indexOfLastItem} />
{/* END OF PAGINATION BUTTON */}
{/* PAGINATION BUTTON */}
<PaginatedList
onClick={handlePagination}
prev={currentPage == 0 ? true : false}
next={
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
coupon?.data?.length
? true
: false
}
data={coupon?.data}
start={indexOfFirstItem}
stop={indexOfLastItem}
/>
{/* END OF PAGINATION BUTTON */}
</div>
)
);
}
export default CouponTable
export default CouponTable;
@@ -15,7 +15,7 @@ function ReferralTable({history}) {
}
return (
<div className='flex flex-col justify-between h-full'>
<div className='flex flex-col justify-between min-h-[420px] overflow-x-auto'>
<table className="referral-list w-full table-auto border-collapse text-left">
<thead className='border-b-2'>
<tr className='text-slate-600'>
+58 -46
View File
@@ -116,10 +116,21 @@ function ReferralDisplay() {
}, [refHistoryReload]);
return (
<div className="content-wrapper w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin">
<div className="lg:w-1/2 w-full mb-10 lg:mb-0">
<div className="referral w-full md:p-8 p-4 h-full bg-white dark:bg-dark-white rounded-2xl shadow">
<h2 className="text-slate-900 dark:text-white text-xl lg:text-2xl font-medium">
<div className="content-wrapper w-full lg:flex xl:space-x-8 bottomMargin">
<div className="lg:w-2/2 w-full mb-10 lg:mb-0">
<div className="sm:flex justify-between items-center mb-6">
<div className="mb-5 sm:mb-0">
<h1 className="text-26 font-bold inline-flex gap-3 text-dark-gray dark:text-white items-center">
<span>
Refer a Friend
</span>
</h1>
</div>
</div>
<div className="referral w-full md:p-8 p-4 bg-white dark:bg-dark-white rounded-2xl shadow">
<h2 className="mb-4 text-slate-900 dark:text-white text-xl lg:text-2xl font-medium">
Send Referral
</h2>
<Formik
@@ -129,42 +140,44 @@ function ReferralDisplay() {
>
{(props) => (
<Form className="referral-info">
{/* Firstname */}
<div className="field w-full mb-6">
<InputCom
fieldClass="px-6"
label="Firstname"
type="text"
name="firstname"
placeholder="Firstname"
value={props.values.firstname}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{props.errors.firstname && props.touched.firstname && (
<p className="text-sm text-red-500">
{props.errors.firstname}
</p>
)}
</div>
<div className="block md:mb-6 md:flex gap-10">
{/* Firstname */}
<div className="field w-full mb-6 md:mb-0">
<InputCom
fieldClass="px-6"
label="Firstname"
type="text"
name="firstname"
placeholder="Firstname"
value={props.values.firstname}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{props.errors.firstname && props.touched.firstname && (
<p className="text-sm text-red-500">
{props.errors.firstname}
</p>
)}
</div>
{/* Lastname */}
<div className="field w-full mb-6">
<InputCom
fieldClass="px-6"
label="Lastname"
type="text"
name="lastname"
placeholder="Lastname"
value={props.values.lastname}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{props.errors.lastname && props.touched.lastname && (
<p className="text-sm text-red-500">
{props.errors.lastname}
</p>
)}
{/* Lastname */}
<div className="field w-full mb-6 md:mb-0">
<InputCom
fieldClass="px-6"
label="Lastname"
type="text"
name="lastname"
placeholder="Lastname"
value={props.values.lastname}
inputHandler={props.handleChange}
blurHandler={props.handleBlur}
/>
{props.errors.lastname && props.touched.lastname && (
<p className="text-sm text-red-500">
{props.errors.lastname}
</p>
)}
</div>
</div>
<div className="field w-full mb-6">
@@ -193,8 +206,7 @@ function ReferralDisplay() {
) : (
<button
type="submit"
className="text-lg text-white bg-sky-blue p-2 hover:opacity-90 rounded-md"
>
className="px-2 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white" >
Send Message
</button>
)}
@@ -203,20 +215,20 @@ function ReferralDisplay() {
)}
</Formik>
</div>
</div>
<div className="lg:w-1/2 w-full mb-10 lg:mb-0">
<div className="referral 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="w-full md:p-8 p-4 bg-white dark:bg-dark-white rounded-2xl shadow">
<h2 className="mb-2 text-slate-900 dark:text-white text-xl lg:text-2xl font-medium">
Referral List
</h2>
{referralList.loading ? (
<LoadingSpinner size="32" color="sky-blue" />
<LoadingSpinner size="32" color="sky-blue" />
) : (
<ReferralTable history={referralList} />
<ReferralTable history={referralList} />
)}
</div>
</div>
</div>
);
}
+9 -5
View File
@@ -1,14 +1,18 @@
import React from "react";
import Accordion from "../../Helpers/Accordion";
import LoadingSpinner from "../../Spinners/LoadingSpinner";
export default function FaqTab({ datas = [] }) {
export default function FaqTab({ datas }) {
return (
<div className="faq-tab w-full">
<div className="accordion-items w-full">
{datas &&
datas.length > 0 &&
datas.map((value) => (
<Accordion key={value.id + Math.random()} datas={value} />
{datas.loading ?
<LoadingSpinner color='sky-blue' size={16} />
:
datas &&
datas?.data?.length > 0 &&
datas.data.map((value, index) => (
<Accordion key={index + Math.random()} datas={value} />
))}
</div>
</div>
+3 -5
View File
@@ -1,7 +1,7 @@
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 faq from "../../data/faq.json";
import Icons from "../Helpers/Icons";
import Layout from "../Partials/Layout";
import ChangePasswordTab from "./Tabs/ChangePasswordTab";
@@ -12,7 +12,7 @@ import PaymentMathodsTab from "./Tabs/PaymentMathodsTab";
import PersonalInfoTab from "./Tabs/PersonalInfoTab";
import TermsConditionTab from "./Tabs/TermsConditionTab";
export default function Settings() {
export default function Settings({faq}) {
const tabs = [
{
id: 1,
@@ -83,8 +83,6 @@ export default function Settings() {
}
};
// fab tab
const faqData = faq.datas;
return (
<>
<Layout>
@@ -259,7 +257,7 @@ export default function Settings() {
)}
{tab === "login_activity" && <LoginActivityTab />}
{tab === "password" && <ChangePasswordTab />}
{tab === "faq" && <FaqTab datas={faqData} />}
{tab === "faq" && <FaqTab datas={faq} />}
{tab === "terms" && <TermsConditionTab />}
</div>
</div>
+8
View File
@@ -10,6 +10,9 @@
src: url("./assets/fonts/Product Sans Bold.ttf");
}
.referral{
margin-bottom: 20px
}
.heroSilderTitle{
text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;
font-family: sans; color: white;
@@ -880,4 +883,9 @@ TODO: Responsive ===========================
.job-popup{
top: 55px;
}
.addJob-popup{
top: 30px;
height: 55rem !important;
}
+11 -1
View File
@@ -687,9 +687,19 @@ class usersService {
action: 14015,
...reqData,
};
return this.postAuxEnd("/activejobstatus ", postData);
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);
}
/*
- 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(username)
- 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(password)
+16 -12
View File
@@ -4,7 +4,8 @@ const initialState = {
jobListTable: false,
pendingListTable: false,
myTaskTable: false,
othersInterestedTable: false
othersInterestedTable: false,
couponTable: false
};
export const tableReloadSlice = createSlice({
@@ -12,21 +13,24 @@ export const tableReloadSlice = createSlice({
initialState,
reducers: {
tableReload: (state, action) => {
switch(action.payload.type){
case 'JOBTABLE':
switch (action.payload.type) {
case "JOBTABLE":
state.jobListTable = !state.jobListTable;
return
case 'PENDINGTABLE' :
return;
case "PENDINGTABLE":
state.pendingListTable = !state.pendingListTable;
return
case 'MYTASKTABLE' :
return;
case "MYTASKTABLE":
state.myTaskTable = !state.myTaskTable;
return
case 'OTHERSINTERESTEDTABLE' :
return;
case "OTHERSINTERESTEDTABLE":
state.othersInterestedTable = !state.othersInterestedTable;
return
return;
case "COUPONTABLE":
state.couponTable = !state.couponTable;
return;
default:
return state
return state;
}
},
},
@@ -34,4 +38,4 @@ export const tableReloadSlice = createSlice({
export const { tableReload } = tableReloadSlice.actions;
export default tableReloadSlice.reducer;
export default tableReloadSlice.reducer;
+36 -10
View File
@@ -1,14 +1,40 @@
import React from 'react'
import AddJob from '../components/AddJob/AddJob'
import Layout from '../components/Partials/Layout'
import React from "react";
import AddJob from "../components/AddJob/AddJob";
import ModalCom from "../components/Helpers/ModalCom";
function AddJobPage() {
function AddJobPage({ action, situation }) {
return (
<Layout>
<AddJob />
</Layout>
)
<ModalCom action={action} situation={situation} className="addJob-popup">
<div className="lg:w-[600px] w-full h-full lg:overflow-hidden lg:rounded-2xl bg-white dark:bg-dark-white ">
<div className="heading flex justify-between items-center py-6 md:px-[30px] px-[23px] border-b dark:border-[#5356fb29] border-light-purple dark:border-[#5356fb29] ">
<p className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
Create New Job
</p>
<button type="button" onClick={action}>
<svg
width="32"
height="32"
viewBox="0 0 32 32"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M32 14.3645C32 15.5022 32 16.6399 32 17.7779C31.8143 17.8408 31.8787 18.0048 31.8565 18.1334C30.6952 24.8402 26.8853 29.2664 20.4091 31.362C19.4672 31.6668 18.4669 31.7917 17.4935 31.9997C16.3558 31.9997 15.2181 31.9997 14.0801 31.9997C13.8574 31.741 13.5279 31.7984 13.2475 31.7416C6.90872 30.4552 2.74424 26.7311 0.684152 20.6107C0.386668 19.7268 0.396442 18.7733 0 17.9199C0 16.6399 0 15.3598 0 14.0798C0.259 13.884 0.190585 13.5694 0.240675 13.3162C1.52285 6.84244 5.35655 2.66392 11.5936 0.623067C12.4549 0.34116 13.3785 0.343909 14.2221 0C15.3125 0 16.4029 0 17.4932 0C17.525 0.110258 17.6111 0.120948 17.7089 0.130417C24.2666 0.77242 29.8064 5.52819 31.449 11.9351C31.6552 12.739 31.8174 13.5542 32 14.3645ZM29.3431 16.0699C29.3718 8.68538 23.4154 2.66942 16.0684 2.66178C8.69759 2.65445 2.66972 8.58489 2.65353 15.8601C2.63704 23.2563 8.52319 29.2979 15.7868 29.3404C23.2862 29.3846 29.3144 23.4832 29.3431 16.0699Z"
fill="#374557"
fillOpacity="0.6"
/>
<path
d="M14.1604 16.0221C12.3843 14.2567 10.6724 12.5534 8.95837 10.8525C8.53353 10.431 8.23421 9.97162 8.46175 9.34031C8.83956 8.29209 9.95101 8.07371 10.794 8.906C12.3611 10.4536 13.9344 11.9963 15.4529 13.5909C15.9202 14.0817 16.1447 14.0005 16.5662 13.5643C18.0961 11.9804 19.6617 10.4307 21.2282 8.88248C22.0596 8.06058 23.208 8.30064 23.5522 9.35008C23.7584 9.97865 23.459 10.4383 23.0336 10.8619C21.489 12.3991 19.9531 13.9443 18.4088 15.4815C18.2421 15.6476 18.0408 15.779 17.8188 15.9558C19.629 17.7563 21.366 19.4676 23.0831 21.1987C23.934 22.0567 23.6875 23.2106 22.6072 23.556C21.9658 23.761 21.5223 23.4186 21.1067 23.0023C19.5502 21.444 17.9757 19.9031 16.448 18.3171C16.0616 17.9157 15.8854 17.9811 15.5375 18.3378C13.9835 19.9318 12.399 21.4956 10.8242 23.0692C10.4015 23.4916 9.94887 23.7768 9.30961 23.516C8.27819 23.0948 8.06073 22.0814 8.87591 21.2418C10.0307 20.0528 11.2118 18.8891 12.3895 17.7221C12.9588 17.1577 13.5462 16.6106 14.1604 16.0221Z"
fill="#374557"
fillOpacity="0.6"
/>
</svg>
</button>
</div>
<AddJob popUpHandler={action} />
</div>
</ModalCom>
);
}
export default AddJobPage
export default AddJobPage;
+7 -33
View File
@@ -1,41 +1,15 @@
//import React from "react";
import React, { useContext, useState, useEffect } from "react";
// import MyTasks from "../components/MyTasks";
// import UsersService from "../services/UsersService";
import usersService from "../services/UsersService";
import MyJobs from "../components/MyJobs";
import { useSelector } from "react-redux";
export default function MyJobsPage() {
let {commonHeadBanner} = useSelector(state => state.commonHeadBanner)
const {userJobList} = useSelector((state) => state.userJobList)
// const { jobListTable } = useSelector((state) => state.tableReload);
// const userApi = new usersService();
// const activeJobList = userApi.getMyJobList();
// const [myJobList, setMyJobList] = useState({ loading: true, data: [] });
// const api = new usersService();
// const getMyJobList = async () => {
// setMyJobList({ loading: true, data: [] });
// try {
// const res = await api.getMyJobList();
// setMyJobList({ loading: false, data: res.data });
// // setMyJobList(res.data);
// } catch (error) {
// setMyJobList({ loading: false, data: [] });
// console.log("Error getting mode");
// }
// };
// useEffect(() => {
// getMyJobList();
// }, [jobListTable]);
// debugger;
let { commonHeadBanner } = useSelector((state) => state.commonHeadBanner);
const { userJobList } = useSelector((state) => state.userJobList);
return (
<>
<MyJobs MyJobList={userJobList} commonHeadData={commonHeadBanner.result_list} />
<MyJobs
MyJobList={userJobList}
commonHeadData={commonHeadBanner.result_list}
/>
</>
);
}
}
+21 -2
View File
@@ -1,10 +1,29 @@
import React from "react";
import React,{useState, useEffect} from "react";
import Settings from "../components/Settings";
import usersService from "../services/UsersService";
export default function SettingsPage() {
const apiCall = new usersService()
let [faq, setFaq] = useState({loading:true, data:[]}) // 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:[]})
console.log('Error', err)
})
}
useEffect(()=>{
getFaq()
},[])
return (
<>
<Settings />
<Settings faq={faq} />
</>
);
}