Compare commits

...

15 Commits

27 changed files with 522 additions and 299 deletions
View File
+2 -2
View File
@@ -25,7 +25,7 @@ export default function HistoryTable({ className }) {
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={`update-table w-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow ${
className || ""
}`}
>
@@ -43,7 +43,7 @@ export default function HistoryTable({ className }) {
/>
</div>
{data.length &&
<div className="relative w-full overflow-x-auto sm:rounded-lg">
<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 whitespace-nowrap border-b dark:border-[#5356fb29] default-border-b dark:border-[#5356fb29] ottom ">
+3 -3
View File
@@ -204,7 +204,7 @@ export default function History() {
<div className='w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin'>
{/* PURCHASE SECTION */}
<div className="lg:w-1/2 w-full mb-10 lg:mb-0">
<div className="wallet w-full md:p-8 p-4 h-full max-h-[500px] bg-white dark:bg-dark-white overflow-y-auto rounded-2xl shadow">
<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">
<h2 className='text-slate-900 dark:text-white text-xl lg:text-2xl font-medium'>Purchases</h2>
{purchaseHistory.loading ?
<LoadingSpinner size='16' color='sky-blue' />
@@ -217,9 +217,9 @@ export default function History() {
{/* RECENT ACTIVITY SECTION */}
<div className="lg:w-1/2 w-full mb-10 lg:mb-0">
<div className="wallet w-full md:p-8 p-4 h-full max-h-[500px] bg-white dark:bg-dark-white overflow-y-auto rounded-2xl shadow">
<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">
<h2 className='text-slate-900 dark:text-white text-xl lg:text-2xl font-medium'>Recent Activity</h2>
<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 ?
<LoadingSpinner size='16' color='sky-blue' />
:
+8 -6
View File
@@ -1,19 +1,21 @@
import React from "react";
import products from "../../data/marketplace_data.json";
// import products from "../../data/marketplace_data.json";
//import CreateNft from "../Home/CreateNft";
import Layout from "../Partials/Layout";
import MainSection from "./MainSection";
import CommonHead from "../UserHeader/CommonHead";
import { useSelector } from "react-redux";
export default function MarketPlace(props) {
const JobList = props.activeJobList?.result_list;
console.log("activeJobList->",props.activeJobList.result_list);
const marketProduct = products.data;
export default function MarketPlace() {
let { jobLists } = useSelector((state) => state.jobLists);
const marketData = jobLists?.result_list;
// const marketProduct = products.data;
return (
<>
<Layout>
<CommonHead />
<MainSection marketPlaceProduct={JobList} className="mb-10" />
<MainSection marketPlaceProduct={marketData} className="mb-10" />
</Layout>
</>
);
@@ -4,6 +4,7 @@ import dataImage2 from "../../assets/images/data-table-user-2.png";
import dataImage3 from "../../assets/images/data-table-user-3.png";
import dataImage4 from "../../assets/images/data-table-user-4.png";
import SelectBox from "../Helpers/SelectBox";
import ActiveJobsPopout from "../jobPopout/ActiveJobsPopout";
import PaginatedList from "../Pagination/PaginatedList";
import { handlePagingFunc } from "../Pagination/HandlePagination";
@@ -12,6 +13,8 @@ export default function MyActiveJobTable({MyJobList, className }) {
const filterCategories = ["All Categories", "Explore", "Featured"];
const [selectedCategory, setCategory] = useState(filterCategories[0]);
let [jobPopout,setJobPopout] = useState({show:false, data:{}}) // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW
const [currentPage, setCurrentPage] = useState(0);
const indexOfFirstItem = Number(currentPage);
const indexOfLastItem = Number(indexOfFirstItem)+Number(process.env.REACT_APP_ITEM_PER_PAGE);
@@ -23,12 +26,12 @@ export default function MyActiveJobTable({MyJobList, className }) {
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={`update-table w-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow ${
className || ""
}`}
>
{MyJobList && MyJobList?.result_list &&
<div className="relative w-full overflow-x-auto sm:rounded-lg">
<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 whitespace-nowrap border-b dark:border-[#5356fb29] default-border-b dark:border-[#5356fb29] ottom ">*/}
@@ -79,6 +82,7 @@ export default function MyActiveJobTable({MyJobList, className }) {
<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
@@ -97,6 +101,9 @@ export default function MyActiveJobTable({MyJobList, className }) {
{/* END OF PAGINATION BUTTON */}
</div>
}
{jobPopout.show &&
<ActiveJobsPopout details={jobPopout.data} onClose={()=>{setJobPopout({show:false, data:{}})}} />
}
</div>
);
}
+2 -2
View File
@@ -23,7 +23,7 @@ export default function MyJobTable({MyJobList, className }) {
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={`update-table w-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow ${
className || ""
}`}
>
@@ -41,7 +41,7 @@ export default function MyJobTable({MyJobList, className }) {
/>
</div>
{MyJobList && MyJobList?.result_list &&
<div className="relative w-full overflow-x-auto sm:rounded-lg">
<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 whitespace-nowrap border-b dark:border-[#5356fb29] default-border-b dark:border-[#5356fb29] ottom ">
+1 -1
View File
@@ -73,7 +73,7 @@ function AddFund({payment}) {
<div className="lg:w-1/2 w-full mb-10 lg:mb-0">
<div className="wallet w-full md:p-8 p-4 h-full max-h-[590px] bg-white dark:bg-dark-white overflow-y-auto rounded-2xl shadow">
<h2 className='text-gray-900 dark:text-white text-xl lg:text-2xl font-medium'>Recent Activity</h2>
<p className='text-base text-gray-600 dark:text-white'>Activity Report</p>
{/* <p className='text-base text-gray-600 dark:text-white'>Activity Report</p> */}
{payment.loading ?
<LoadingSpinner size='16' color='sky-blue' />
:
+1 -1
View File
@@ -117,7 +117,7 @@ function ConfirmAddFund({payment}) {
<div className="lg:w-1/2 w-full mb-10 lg:mb-0">
<div className="wallet w-full md:p-8 p-4 h-full max-h-[600px] bg-white dark:bg-dark-white overflow-y-auto rounded-2xl shadow">
<h2 className='text-gray-900 dark:text-white text-xl lg:text-2xl font-medium'>Recent Activity</h2>
<p className='text-base text-gray-600 dark:text-white'>Activity Report</p>
{/* <p className='text-base text-gray-600 dark:text-white'>Activity Report</p> */}
{payment.loading ?
<LoadingSpinner size='16' color='sky-blue' />
:
+2 -2
View File
@@ -151,9 +151,9 @@ function ConfirmTransfer({payment, wallet}) {
}
<div className="lg:w-1/2 w-full mb-10 lg:mb-0">
<div className="wallet w-full px-4 md:px-8 py-4 h-full max-h-[600px] bg-white dark:bg-dark-white overflow-y-auto rounded-2xl shadow">
<div className="wallet w-full px-4 md:px-8 py-4 h-full max-h-[700px] bg-white dark:bg-dark-white overflow-y-auto rounded-2xl shadow">
<h2 className='text-gray-900 dark:text-white text-xl lg:text-2xl font-medium'>Recent Activity</h2>
<p className='text-base text-gray-600 dark:text-white'>Activity Report</p>
{/* <p className='text-base text-gray-600 dark:text-white'>Activity Report</p> */}
{payment.loading ?
<LoadingSpinner size='16' color='sky-blue' />
:
+2 -2
View File
@@ -223,9 +223,9 @@ function TransferFund({payment, wallet}) {
</div>
<div className="lg:w-1/2 w-full mb-10 lg:mb-0">
<div className="wallet w-full md:p-8 p-4 h-full max-h-[600px] bg-white dark:bg-dark-white overflow-y-auto rounded-2xl shadow">
<div className="wallet w-full md:p-8 p-4 h-full max-h-[650px] bg-white dark:bg-dark-white overflow-y-auto rounded-2xl shadow">
<h2 className='text-slate-900 dark:text-white text-xl lg:text-2xl font-medium'>Recent Activity</h2>
<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> */}
{payment.loading ?
<LoadingSpinner size='16' color='sky-blue' />
:
@@ -15,7 +15,7 @@ function CouponTable({coupon}) {
}
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'>
@@ -59,7 +59,7 @@ function CouponTable({coupon}) {
{/* 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>
)
}
@@ -15,7 +15,7 @@ function PurchasesTable({purchase}) {
}
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'>
@@ -59,7 +59,7 @@ function PurchasesTable({purchase}) {
{/* PAGINATION BUTTON */}
<PaginatedList onClick={handlePagination} prev={currentPage == 0 ? true : false} next={currentPage+Number(process.env.REACT_APP_ITEM_PER_PAGE) >= purchase?.data?.length ? true : false} data={purchase?.data} start={indexOfFirstItem} stop={indexOfLastItem} />
{/* END OF PAGINATION BUTTON */}
</>
</div>
)
}
@@ -15,7 +15,7 @@ function RecentActivityTable({payment}) {
}
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'>
@@ -59,7 +59,7 @@ function RecentActivityTable({payment}) {
{/* PAGINATION BUTTON */}
<PaginatedList onClick={handlePagination} prev={currentPage == 0 ? true : false} next={currentPage+Number(process.env.REACT_APP_ITEM_PER_PAGE) >= payment?.data?.length ? true : false} data={payment?.data} start={indexOfFirstItem} stop={indexOfLastItem} />
{/* END OF PAGINATION BUTTON */}
</>
</div>
)
}
@@ -15,7 +15,7 @@ function ReferralTable({history}) {
}
return (
<>
<div className='flex flex-col justify-between h-full'>
<table className="referral-list w-full table-auto border-collapse text-left">
<thead className='border-b-2'>
<tr className='text-slate-600'>
@@ -53,7 +53,7 @@ function ReferralTable({history}) {
{/* PAGINATION BUTTON */}
<PaginatedList onClick={handlePagination} prev={currentPage == 0 ? true : false} next={currentPage+Number(process.env.REACT_APP_ITEM_PER_PAGE) >= history?.data?.length ? true : false} data={history?.data} start={indexOfFirstItem} stop={indexOfLastItem} />
{/* END OF PAGINATION BUTTON */}
</>
</div>
)
}
+1 -1
View File
@@ -5,7 +5,7 @@ const PaginatedList = ({ onClick, prev, next, data, start, stop }) => {
if(data.length){
return (
<div className='p-3 flex justify-center items-center space-x-2'>
<div className='p-3 flex justify-center items-center space-x-2 border-t-2'>
{/* Render pagination buttons */}
{!prev &&
<button
+110 -76
View File
@@ -4,9 +4,16 @@ import logo from "../../assets/images/wrenchboard.png"; //logo-2.svg";
import logo3 from "../../assets/images/wrenchboard.png"; //logo-3.svg";
import DarkModeContext from "../Contexts/DarkModeContext";
import Icons from "../Helpers/Icons";
import { useSelector } from "react-redux";
export default function MobileSidebar({ sidebar, action, logoutModalHandler }) {
let { userDetails } = useSelector((state) => state.userDetails);
const darkMode = useContext(DarkModeContext);
let { jobLists } = useSelector((state) => state.jobLists);
const marketData = jobLists?.result_list;
let noOfJobs = marketData?.length;
return (
<div className="w-full h-full">
{/* logo-area */}
@@ -73,49 +80,20 @@ export default function MobileSidebar({ sidebar, action, logoutModalHandler }) {
</div>
<div className="items">
<ul className="flex flex-col space-y-6">
<li className="item group">
<NavLink
className="nav-item flex items-center justify-start space-x-3.5"
to="/"
>
<span className="item-icon group-hover:bg-purple group-hover:text-white w-8 h-8 flex justify-center items-center transition-all duration-300 ease-in-out bg-light-purple dark:bg-dark-light-purple rounded-full text-dark-gray dark:text-white">
<Icons name="dashboard" />
</span>
<span className="item-content group-hover:text-purple text-[18px] transition-all duration-300 ease-in-out text-lighter-gray relative font-medium active flex-1">
Dashboard
</span>
</NavLink>
</li>
<li className="item group">
<NavLink
to="/market"
className="nav-item flex items-center justify-start space-x-3.5"
>
<span className="item-icon group-hover:bg-purple group-hover:text-white w-8 h-8 flex justify-center items-center transition-all duration-300 ease-in-out bg-light-purple dark:bg-dark-light-purple rounded-full text-dark-gray dark:text-white">
<Icons name="active-bids" />
</span>
<span className="item-content relative group-hover:text-purple text-[18px] transition-all duration-300 ease-in-out text-lighter-gray font-medium active flex-1">
Market
<span className="absolute left-24 -top-1 text-sm flex justify-center items-center w-5 h-5 primary-gradient rounded-full text-white">
0
</span>
</span>
</NavLink>
</li>
<li className="item group">
<NavLink
to="/mytask"
className="nav-item flex items-center justify-start space-x-3.5"
>
<span className="item-icon group-hover:bg-purple group-hover:text-white w-8 h-8 flex justify-center items-center transition-all duration-300 ease-in-out bg-light-purple dark:bg-dark-light-purple rounded-full text-dark-gray dark:text-white">
<Icons name="market" />
</span>
<span className="item-content group-hover:text-purple text-[18px] transition-all duration-300 ease-in-out text-lighter-gray relative font-medium active flex-1">
My Task(s)
</span>
</NavLink>
</li>
{/* Using mini component reduces the bulk amount of html */}
{[
{ name: "Dashboard", path: "/" },
{ name: "Market", path: "/market", bubble: noOfJobs },
{ name: "My Task(s)", path: "/mytask" },
].map(({ name, path, bubble }, idx) => (
<ListItem
key={idx}
title={name}
route={path}
bubble={bubble}
sidebar
/>
))}
{/*<li className="item group">*/}
{/* <NavLink*/}
{/* to="/notification"*/}
@@ -184,41 +162,67 @@ export default function MobileSidebar({ sidebar, action, logoutModalHandler }) {
</ul>
</div>
</div>
<div className="setting-item">
<div className="heading mb-5">
<h1 className="title text-xl font-bold text-purple">My Jobs</h1>
</div>
<div className="items">
<ul className="flex flex-col space-y-6">
<li className="item group">
<NavLink
to="/myjobs"
className="nav-item flex items-center justify-start space-x-3.5"
>
<span className="item-icon group-hover:bg-purple group-hover:text-white w-8 h-8 flex justify-center items-center transition-all duration-300 ease-in-out bg-light-purple dark:bg-dark-light-purple rounded-full text-dark-gray dark:text-white">
<Icons name="people-two" />
</span>
<span className="item-content group-hover:text-purple text-[18px] transition-all duration-300 ease-in-out text-lighter-gray relative font-medium active flex-1">
My Jobs
</span>
</NavLink>
</li>
<li className="item group">
<NavLink
to="/market"
className="nav-item flex items-center justify-start space-x-3.5"
>
<span className="item-icon group-hover:bg-purple group-hover:text-white w-8 h-8 flex justify-center items-center transition-all duration-300 ease-in-out bg-light-purple dark:bg-dark-light-purple rounded-full text-dark-gray dark:text-white">
<Icons name="setting" />
</span>
<span className="item-content group-hover:text-purple text-[18px] transition-all duration-300 ease-in-out text-lighter-gray relative font-medium active flex-1">
Active Job(s)
</span>
</NavLink>
</li>
</ul>
{!userDetails.post_jobs ?
<div className="setting-item">
<div className="top-platform bg-pink dark:bg-dark-white rounded-2xl p-16 2xl:w-[180px] w-full 2xl:mb-10 2xl:border-none border ">
<NavLink to="/start-job" className="nav-item flex items-center justify-start space-x-3.5">
<span className="item-content relative group-hover:text-purple text-xl transition-all duration-300 ease-in-out text-lighter-gray font-medium active flex-1">
Enable Job Post
</span>
</NavLink>
</div>
</div>
:
<div className="setting-item">
<div className="heading mb-5">
<h1 className="title text-xl font-bold text-purple">My Jobs</h1>
</div>
<div className="items">
<ul className="flex flex-col space-y-6">
<li className="item group">
<NavLink
to="/myjobs"
className="nav-item flex items-center justify-start space-x-3.5"
>
<span className="item-icon group-hover:bg-purple group-hover:text-white w-8 h-8 flex justify-center items-center transition-all duration-300 ease-in-out bg-light-purple dark:bg-dark-light-purple rounded-full text-dark-gray dark:text-white">
<Icons name="people-two" />
</span>
<span className="item-content group-hover:text-purple text-[18px] transition-all duration-300 ease-in-out text-lighter-gray relative font-medium active flex-1">
My Jobs
</span>
</NavLink>
</li>
<li className="item group">
<NavLink
to="/my-active-jobs"
className="nav-item flex items-center justify-start space-x-3.5"
>
<span className="item-icon group-hover:bg-purple group-hover:text-white w-8 h-8 flex justify-center items-center transition-all duration-300 ease-in-out bg-light-purple dark:bg-dark-light-purple rounded-full text-dark-gray dark:text-white">
<Icons name="setting" />
</span>
<span className="item-content group-hover:text-purple text-[18px] transition-all duration-300 ease-in-out text-lighter-gray relative font-medium active flex-1">
Pending
</span>
</NavLink>
</li>
<li className="item group">
<NavLink
to="/my-active-jobs"
className="nav-item flex items-center justify-start space-x-3.5"
>
<span className="item-icon group-hover:bg-purple group-hover:text-white w-8 h-8 flex justify-center items-center transition-all duration-300 ease-in-out bg-light-purple dark:bg-dark-light-purple rounded-full text-dark-gray dark:text-white">
<Icons name="setting" />
</span>
<span className="item-content group-hover:text-purple text-[18px] transition-all duration-300 ease-in-out text-lighter-gray relative font-medium active flex-1">
Active Job(s)
</span>
</NavLink>
</li>
</ul>
</div>
</div>
}
</div>
{/* signout area */}
{sidebar ? (
@@ -284,3 +288,33 @@ export default function MobileSidebar({ sidebar, action, logoutModalHandler }) {
</div>
);
}
const ListItem = ({ sidebar, route, title, bubble }) => {
return (
<li className="item group">
<NavLink
to={route}
className={`nav-item flex items-center ${
((navData) => (navData.isActive ? "active" : ""),
sidebar ? "justify-start space-x-3.5" : "justify-center")
}`}
>
<span className="item-icon group-hover:bg-purple group-hover:text-white w-8 h-8 flex justify-center items-center transition-all duration-300 ease-in-out bg-light-purple dark:bg-dark-light-purple rounded-full text-dark-gray dark:text-white dark:text-lighter-gray">
<Icons name="market" />
</span>
<span
className={`item-content relative group-hover:text-purple text-[18px] transition-all duration-300 ease-in-out text-lighter-gray font-medium ${
sidebar ? "active flex-1" : "w-0"
}`}
>
{title && title}
{bubble && (
<span className="absolute left-24 -top-1 text-sm flex justify-center items-center w-5 h-5 primary-gradient rounded-full text-white">
{bubble}
</span>
)}
</span>
</NavLink>
</li>
);
};
+96 -102
View File
@@ -4,9 +4,17 @@ import logo from "../../assets/images/wrenchboard.png"; //logo-2.svg";
import logo3 from "../../assets/images/wrenchboard.png"; //logo-3.svg";
import DarkModeContext from "../Contexts/DarkModeContext";
import Icons from "../Helpers/Icons";
import { useSelector } from "react-redux";
export default function Sidebar({ sidebar, action, logoutModalHandler }) {
const darkMode = useContext(DarkModeContext);
let { userDetails } = useSelector((state) => state.userDetails);
let { jobLists } = useSelector((state) => state.jobLists);
const marketData = jobLists?.result_list;
let noOfJobs = marketData?.length;
useEffect(() => {
const title = document.querySelectorAll(".menu-setting-items .heading");
if (sidebar) {
@@ -93,69 +101,20 @@ export default function Sidebar({ sidebar, action, logoutModalHandler }) {
</div>
<div className="items">
<ul className="flex flex-col space-y-6">
<li className="item group">
<NavLink
className={`nav-item flex items-center ${
((navData) => (navData.isActive ? "active" : ""),
sidebar ? "justify-start space-x-3.5" : "justify-center")
} `}
to="/"
>
<span className="item-icon group-hover:bg-purple group-hover:text-white w-8 h-8 flex justify-center items-center transition-all duration-300 ease-in-out bg-light-purple dark:bg-dark-light-purple rounded-full text-dark-gray dark:text-white dark:text-lighter-gray">
<Icons name="dashboard" />
</span>
<span
className={`item-content group-hover:text-purple text-[18px] transition-all duration-300 ease-in-out text-lighter-gray relative font-medium ${
sidebar ? "active flex-1" : "w-0"
}`}
>
Dashboard
</span>
</NavLink>
</li>
<li className="item group">
<NavLink
to="/market"
className={`nav-item flex items-center ${
((navData) => (navData.isActive ? "active" : ""),
sidebar ? "justify-start space-x-3.5" : "justify-center")
}`}
>
<span className="item-icon group-hover:bg-purple group-hover:text-white w-8 h-8 flex justify-center items-center transition-all duration-300 ease-in-out bg-light-purple dark:bg-dark-light-purple rounded-full text-dark-gray dark:text-white dark:text-lighter-gray">
<Icons name="market" />
</span>
<span
className={`item-content relative group-hover:text-purple text-[18px] transition-all duration-300 ease-in-out text-lighter-gray font-medium ${
sidebar ? "active flex-1" : "w-0"
}`}
>
Market
<span className="absolute left-24 -top-1 text-sm flex justify-center items-center w-5 h-5 primary-gradient rounded-full text-white">
0
</span>
</span>
</NavLink>
</li>
<li className="item group">
<NavLink
to="/mytask"
className={`nav-item flex items-center ${
((navData) => (navData.isActive ? "active" : ""),
sidebar ? "justify-start space-x-3.5" : "justify-center")
}`}
>
<span className="item-icon group-hover:bg-purple group-hover:text-white w-8 h-8 flex justify-center items-center transition-all duration-300 ease-in-out bg-light-purple dark:bg-dark-light-purple rounded-full text-dark-gray dark:text-white dark:text-lighter-gray">
<Icons name="active-bids" />
</span>
<span
className={`item-content relative group-hover:text-purple text-[18px] transition-all duration-300 ease-in-out text-lighter-gray font-medium ${
sidebar ? "active flex-1" : "w-0"
}`}
>
My Task(s)
</span>
</NavLink>
</li>
{/* Using mini component reduces the bulk amount of html */}
{[
{ name: "Dashboard", path: "/" },
{ name: "Market", path: "/market", bubble: noOfJobs },
{ name: "My Task(s)", path: "/mytask" },
].map(({ name, path, bubble }, idx) => (
<ListItem
key={idx}
title={name}
route={path}
bubble={bubble}
sidebar
/>
))}
{/*<li className="item group">*/}
{/* <NavLink*/}
{/* to="/notification"*/}
@@ -216,7 +175,7 @@ export default function Sidebar({ sidebar, action, logoutModalHandler }) {
{/* </span>*/}
{/* </NavLink>*/}
{/*</li>*/}
{/*<li className="item group">*/}
{/* <NavLink*/}
{/* to="/history"*/}
@@ -262,23 +221,26 @@ export default function Sidebar({ sidebar, action, logoutModalHandler }) {
</div>
</div>
<div className="setting-item">
<div class="top-platform bg-pink dark:bg-dark-white rounded-2xl p-6 2xl:w-[180px] w-full 2xl:mb-10 2xl:border-none border ">
<NavLink
to="/acc-family" >
<span className="item-content relative group-hover:text-purple text-[18px] transition-all duration-300 ease-in-out text-lighter-gray font-medium active flex-1">Family Account</span>
<div class="top-platform bg-pink dark:bg-dark-white rounded-2xl p-6 2xl:w-[180px] w-full 2xl:mb-10 2xl:border-none border ">
<NavLink to="/acc-family">
<span className="item-content relative group-hover:text-purple text-[18px] transition-all duration-300 ease-in-out text-lighter-gray font-medium active flex-1">
Family Account
</span>
</NavLink>
</div>
</div>
<div className="setting-item">
<div
className="top-platform bg-pink dark:bg-dark-white rounded-2xl p-16 2xl:w-[180px] w-full 2xl:mb-10 2xl:border-none border ">
<NavLink
to="/start-job" >
<span className="item-content relative group-hover:text-purple text-[18px] transition-all duration-300 ease-in-out text-lighter-gray font-medium active flex-1">Enable Job Post</span>
</NavLink>
</div>
{!userDetails.post_jobs ?
<div className="setting-item">
<div className="top-platform bg-pink dark:bg-dark-white rounded-2xl p-16 2xl:w-[180px] w-full 2xl:mb-10 2xl:border-none border ">
<NavLink to="/start-job">
<span className="item-content relative group-hover:text-purple text-[18px] transition-all duration-300 ease-in-out text-lighter-gray font-medium active flex-1">
Enable Job Post
</span>
</NavLink>
</div>
</div>
:
<div className="setting-item">
<div className="heading mb-5">
<h1 className="title text-xl font-bold text-purple">My Jobs</h1>
@@ -287,19 +249,19 @@ export default function Sidebar({ sidebar, action, logoutModalHandler }) {
<ul className="flex flex-col space-y-6">
<li className="item group">
<NavLink
to="/myjobs"
className={`nav-item flex items-center ${
((navData) => (navData.isActive ? "active" : ""),
sidebar ? "justify-start space-x-3.5" : "justify-center")
}`}
to="/myjobs"
className={`nav-item flex items-center ${
((navData) => (navData.isActive ? "active" : ""),
sidebar ? "justify-start space-x-3.5" : "justify-center")
}`}
>
<span className="item-icon group-hover:bg-purple group-hover:text-white w-8 h-8 flex justify-center items-center transition-all duration-300 ease-in-out bg-light-purple dark:bg-dark-light-purple rounded-full text-dark-gray dark:text-white dark:text-lighter-gray">
<Icons name="people-two" />
</span>
<span
className={`item-content group-hover:text-purple text-[18px] transition-all duration-300 ease-in-out text-lighter-gray relative font-medium ${
sidebar ? "active flex-1" : "w-0"
}`}
className={`item-content group-hover:text-purple text-[18px] transition-all duration-300 ease-in-out text-lighter-gray relative font-medium ${
sidebar ? "active flex-1" : "w-0"
}`}
>
List
</span>
@@ -307,41 +269,41 @@ export default function Sidebar({ sidebar, action, logoutModalHandler }) {
</li>
<li className="item group">
<NavLink
to="/my-active-jobs"
className={`nav-item flex items-center ${
((navData) => (navData.isActive ? "active" : ""),
sidebar ? "justify-start space-x-3.5" : "justify-center")
}`}
to="/my-active-jobs"
className={`nav-item flex items-center ${
((navData) => (navData.isActive ? "active" : ""),
sidebar ? "justify-start space-x-3.5" : "justify-center")
}`}
>
<span className="item-icon group-hover:bg-purple group-hover:text-white w-8 h-8 flex justify-center items-center transition-all duration-300 ease-in-out bg-light-purple dark:bg-dark-light-purple rounded-full text-dark-gray dark:text-white dark:text-lighter-gray">
<Icons name="people-two" />
</span>
<span
className={`item-content group-hover:text-purple text-[18px] transition-all duration-300 ease-in-out text-lighter-gray relative font-medium ${
sidebar ? "active flex-1" : "w-0"
}`}
className={`item-content group-hover:text-purple text-[18px] transition-all duration-300 ease-in-out text-lighter-gray relative font-medium ${
sidebar ? "active flex-1" : "w-0"
}`}
>
Pending
Pending
</span>
</NavLink>
</li>
<li className="item group">
<NavLink
to="/my-active-jobs"
className={`nav-item flex items-center ${
((navData) => (navData.isActive ? "active" : ""),
sidebar ? "justify-start space-x-3.5" : "justify-center")
}`}
to="/my-active-jobs"
className={`nav-item flex items-center ${
((navData) => (navData.isActive ? "active" : ""),
sidebar ? "justify-start space-x-3.5" : "justify-center")
}`}
>
<span className="item-icon group-hover:bg-purple group-hover:text-white w-8 h-8 flex justify-center items-center transition-all duration-300 ease-in-out bg-light-purple dark:bg-dark-light-purple rounded-full text-dark-gray dark:text-white dark:text-lighter-gray">
<Icons name="people-two" />
</span>
<span
className={`item-content group-hover:text-purple text-[18px] transition-all duration-300 ease-in-out text-lighter-gray relative font-medium ${
sidebar ? "active flex-1" : "w-0"
}`}
className={`item-content group-hover:text-purple text-[18px] transition-all duration-300 ease-in-out text-lighter-gray relative font-medium ${
sidebar ? "active flex-1" : "w-0"
}`}
>
Active
Active
</span>
</NavLink>
</li>
@@ -388,6 +350,8 @@ export default function Sidebar({ sidebar, action, logoutModalHandler }) {
</ul>
</div>
</div>
}
</div>
{/* signout area */}
{sidebar ? (
@@ -453,3 +417,33 @@ export default function Sidebar({ sidebar, action, logoutModalHandler }) {
</div>
);
}
const ListItem = ({ sidebar, route, title, bubble }) => {
return (
<li className="item group">
<NavLink
to={route}
className={`nav-item flex items-center ${
((navData) => (navData.isActive ? "active" : ""),
sidebar ? "justify-start space-x-3.5" : "justify-center")
}`}
>
<span className="item-icon group-hover:bg-purple group-hover:text-white w-8 h-8 flex justify-center items-center transition-all duration-300 ease-in-out bg-light-purple dark:bg-dark-light-purple rounded-full text-dark-gray dark:text-white dark:text-lighter-gray">
<Icons name="market" />
</span>
<span
className={`item-content relative group-hover:text-purple text-[18px] transition-all duration-300 ease-in-out text-lighter-gray font-medium ${
sidebar ? "active flex-1" : "w-0"
}`}
>
{title && title}
{bubble && (
<span className="absolute left-24 -top-1 text-sm flex justify-center items-center w-5 h-5 primary-gradient rounded-full text-white">
{bubble}
</span>
)}
</span>
</NavLink>
</li>
);
};
+1 -1
View File
@@ -162,7 +162,7 @@ function ReferralDisplay() {
</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-[500px] bg-white dark:bg-dark-white overflow-y-auto rounded-2xl shadow">
<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">
<h2 className='mb-2 text-slate-900 dark:text-white text-xl lg:text-2xl font-medium'>Referral List</h2>
{referralList.loading ?
(
+1 -1
View File
@@ -4,7 +4,7 @@ function LoadingSpinner({size, color, height}) {
return (
<div className={`flex items-center justify-center ${height ? height : ''}`}>
<div role="status">
<svg aria-hidden="true" className={`w-${size} h-${size} text-gray-200 animate-spin dark:text-gray-600 fill-${color}`} viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg aria-hidden="true" className={`w-${size} h-${size} text-gray-200 animate-spin dark:text-gray-600 fill-sky-blue`} viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z" fill="currentColor"/>
<path d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z" fill="currentFill"/>
</svg>
@@ -0,0 +1,97 @@
import React from 'react'
import Detail from './popoutcomponent/Detail'
function ActiveJobsPopout({details, onClose}) {
console.log(details)
return (
<div className='fixed top-0 left-0 z-[1000] p-3 w-full h-screen overflow-y-auto bg-[rgba(0,0,0,0.2)] flex justify-center items-center'>
<div className='alert-box w-[90%] md:w-[768px] md:flex bg-white rounded-lg shadow-lg'>
<div className='p-4 w-full md:w-3/4 md:border-r-2'>
<p>{details.title}</p>
<div className='my-2 p-2 flex justify-start items-center space-x-2 bg-red-100 border-2 border-red-300'>
<span className='w-8 h-8 text-center text-sm rounded-full flex justify-center items-center text-red-300 bg-yellow-100'>!</span>
<div className=''>
<p className='text-sm'>This Job have been sent to public view</p>
<p className='text-sm text-slate-600'>This Job will expire</p>
</div>
</div>
{/* INPUT SECTION */}
<div className='my-2 md:flex'>
<Detail
label='Date Added'
value={details.offer_added || 'default'}
/>
</div>
<div className='my-2 md:flex'>
<Detail
label='Description'
value={details.description}
/>
</div>
<div className='my-2 md:flex'>
<Detail
label='Offer Expire'
value={`${details.expire.split(' ')[0]} ${details.expire.split(' ')[1].split('.')[0]}`}
/>
</div>
<div className='my-2 md:flex'>
<Detail
label='Price'
value={`${details.price*0.01} ${details.currency}`}
/>
</div>
<div className='my-2 md:flex'>
<Detail
label='Duration'
value={`${details.timeline_days} day(s)`}
/>
</div>
<div className='my-2 md:flex'>
<Detail
label='Detail'
value={details.job_description || details.description}
/>
</div>
<div className='my-2 md:flex'>
<Detail
label='Public Link'
value='https://work.wrenchboard.com/plb/viewjob/218B4BWB83'
bg='bg-slate-200'
/>
</div>
</div>
{/* ACTION SECTION */}
<div className='p-4 w-full md:w-1/4 h-full'>
<p className='mb-6 text-sm'>Actions</p>
<div className='mb-3'>
<p className='py-2 text-sm bg-slate-100'>Job sent to public view</p>
</div>
<div className='my-3'>
<button className='px-2 py-1 text-sm text-white bg-blue-900 rounded-md'>Extend by a week</button>
</div>
<div className='my-3'>
<button className='px-2 py-1 text-sm text-white bg-blue-900 rounded-md'>Send to me</button>
</div>
<div className='mt-10 md:mt-32 md:flex md:justify-center'>
<button className='px-2 py-1 text-sm text-white bg-red-500 rounded-md' onClick={onClose}>Cancel Offer</button>
</div>
</div>
</div>
</div>
)
}
export default ActiveJobsPopout
@@ -0,0 +1,12 @@
import React from 'react'
function Detail({label, value, bg}) {
return (
<>
<label className='w-full md:w-1/4 text-slate-600'>{label}</label>
<p className={`p-1 w-full md:w-3/4 text-sm ${bg ? bg : null}`}>{value}</p>
</>
)
}
export default Detail
+15 -1
View File
@@ -732,4 +732,18 @@ TODO: Responsive ===========================
/* For IE10 */
.content-wrapper select::-ms-expand {
display: none;
}
}
/* JOBS DETAILS ALERT */
.alert-box{
animation-name: scale;
animation-duration: .5s;
animation-timing-function: linear;
}
@keyframes scale {
0%{transform: scale(0)}
50%{transform: scale(1.1)}
100%{transform: scale(1)}
}
/* END OF JOBS DETAILS ALERT */
+85 -67
View File
@@ -1,84 +1,102 @@
import { useEffect, useState, useCallback } from "react";
import { useEffect, useState, useCallback, useMemo } from "react";
import { Navigate, Outlet, useLocation, useNavigate } from "react-router-dom";
import usersService from '../services/UsersService'
import LoadingSpinner from '../components/Spinners/LoadingSpinner'
import WrenchBoard from "../assets/images/wrenchboard.png"
import usersService from "../services/UsersService";
import LoadingSpinner from "../components/Spinners/LoadingSpinner";
import { useDispatch, useSelector } from "react-redux";
import {updateUserDetails} from '../store/UserDetails'
import { updateUserDetails } from "../store/UserDetails";
import { updateJobs } from "../store/jobLists";
const AuthRoute = ({ redirectPath = "/login", children }) => {
const apiCall = new usersService()
const dispatch = useDispatch()
const apiCall = useMemo(() => new usersService(), []);
const dispatch = useDispatch();
const [lastActivityTime, setLastActivityTime] = useState(Date.now());
let [isLogin, setIsLogin] = useState({loading: true, status: false})
const [isLogin, setIsLogin] = useState({ loading: true, status: false });
const navigate = useNavigate();
//Removing Data stored at localStorage after session expires
const expireSession = () => {
localStorage.removeItem('session_token');
localStorage.removeItem('member_id');
localStorage.removeItem('uid');
localStorage.removeItem('session');
navigate("/login", { replace: true }); // redirects user to login page after session expires
};
// Reset last activity time on user input
const resetTime = () => {
setLastActivityTime(Date.now());
}
window.addEventListener('mousemove', resetTime)
window.addEventListener('keydown', resetTime)
const loadProfile = ()=>{ // function to load user profile
setIsLogin({loading: true, status: false})
apiCall.loadProfile().then((res)=>{
if(res.data.internal_return < 0){
setIsLogin({loading: false, status: false})
return
}
dispatch(updateUserDetails(res.data))
setIsLogin({loading: false, status: true})
}).catch(error =>{
setIsLogin({loading: false, status: false})
})
}
useEffect(() => {
if(!isLogin.status){
loadProfile() // LOADS USER PROFILE DETAILS AND CALLS DISPATCH UPDATEUSERDETAILS TO UPDATE USERDETAILS SLICE IN STORE
}
//Removing Data stored at localStorage after session expires
const expireSession = () => {
localStorage.clear();
navigate("/login", { replace: true }); // redirects user to login page after session expires
};
const checkInactivity = setInterval(() => {
if (Date.now() - lastActivityTime > process.env.REACT_APP_SESSION_EXPIRE_MINUTES) {
expireSession()
if (
Date.now() - lastActivityTime >
process.env.REACT_APP_SESSION_EXPIRE_MINUTES
) {
expireSession();
}
}, process.env.REACT_APP_SESSION_EXPIRE_CHECKER) // Checks for inactivity every minute
}, process.env.REACT_APP_SESSION_EXPIRE_CHECKER); // Checks for inactivity every minute
// cleaning up listeners
return () => {
clearInterval(checkInactivity)
window.removeEventListener('mousemove', resetTime)
window.removeEventListener('keydown', resetTime)
}
}, [lastActivityTime])
clearInterval(checkInactivity);
};
}, [lastActivityTime, navigate]);
return (
isLogin.loading ?
<LoadingSpinner size='32' color='sky-blue' height='h-screen' />
// Stills needs fixing
// <div className="h-screen m-auto">
// <img src={WrenchBoard} alt="wrenchboard" className="h-10" />
// </div>
:
!isLogin.status ?
<Navigate to={redirectPath} replace />
:
(children || <Outlet />)
)
// Reset last activity time on user input
const resetTime = useCallback(() => {
setLastActivityTime(Date.now());
}, []);
useEffect(() => {
window.addEventListener("mousemove", resetTime);
window.addEventListener("keydown", resetTime);
return () => {
window.removeEventListener("mousemove", resetTime);
window.removeEventListener("keydown", resetTime);
};
}, [resetTime]);
useEffect(() => {
if (!isLogin.status) {
const loadProfile = () => {
// function to load user profile
setIsLogin({ loading: true, status: false });
apiCall
.loadProfile()
.then((res) => {
if (res.data.internal_return < 0) {
setIsLogin({ loading: false, status: false });
return;
}
dispatch(updateUserDetails(res.data));
setIsLogin({ loading: false, status: true });
})
.catch((error) => {
setIsLogin({ loading: false, status: false });
});
};
loadProfile();
}
}, []);
useEffect(() => {
// Getting market data
const getMarketActiveJobList = async () => {
try {
const res = await apiCall.getActiveJobList();
dispatch(updateJobs(res.data));
} catch (error) {
console.log("Error getting mode");
}
};
getMarketActiveJobList();
}, [apiCall, dispatch]);
return isLogin.loading ? (
<LoadingSpinner size="32" color="sky-blue" height="h-screen" />
) : // Stills needs fixing
// <div className="h-screen m-auto">
// <img src={WrenchBoard} alt="wrenchboard" className="h-10" />
// </div>
!isLogin.status ? (
<Navigate to={redirectPath} replace />
) : (
children || <Outlet />
);
};
export default AuthRoute;
export default AuthRoute;
+44
View File
@@ -307,6 +307,50 @@ class usersService {
return this.postAuxEnd("/loadprofile", postData);
}
getFamilyList(){
var postData = {
uuid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
page:0,
limit :100
};
return this.postAuxEnd("/familylist", postData);
}
getFamilyAdd(){
var postData = {
uuid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
page:0,
limit :100
};
return this.postAuxEnd("/familyadd", postData);
}
getFamilyUpdate(){
var postData = {
uuid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
page:0,
limit :100
};
return this.postAuxEnd("/familyupdate", postData);
}
getFamilyManage(){
var postData = {
uuid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
page:0,
limit :100
};
return this.postAuxEnd("/familymanage", postData);
}
//END POINT CALL FOR ACCOUNT TOP
startTopUp(post){
var postData = {
+19
View File
@@ -0,0 +1,19 @@
import { createSlice } from "@reduxjs/toolkit";
const initialState = {
jobLists: {}
};
export const jobSlice = createSlice({
name: "jobLists",
initialState,
reducers: {
updateJobs: (state, payload) => {
state.jobLists = { ...payload.payload };
},
},
});
export const { updateJobs } = jobSlice.actions;
export default jobSlice.reducer;
+2
View File
@@ -2,10 +2,12 @@ import { configureStore } from "@reduxjs/toolkit";
import drawerReducer from "./drawer";
import userDetailReducer from "./UserDetails";
import jobReducer from "./jobLists";
export default configureStore({
reducer: {
drawer: drawerReducer,
userDetails: userDetailReducer,
jobLists: jobReducer
},
});
+1 -21
View File
@@ -1,29 +1,9 @@
import React, {useState, useEffect} from 'react'
import MarketPlace from "../components/MarketPlace";
import usersService from "../services/UsersService";
export default function MarketPlacePage() {
// const userApi = new usersService();
// const activeJobList = userApi.getActiveJobList();
// console.log("activeJobList->",activeJobList);
const [marketActiveJobList, setMarketActiveJobList] = useState([]);
const api = new usersService();
const getMarketActiveJobList = async () => {
try {
const res = await api.getActiveJobList();
setMarketActiveJobList(res.data);
} catch (error) {
console.log("Error getting mode");
}
};
useEffect(() => {
getMarketActiveJobList();
}, []);
return (
<>
<MarketPlace activeJobList={marketActiveJobList} />
<MarketPlace />
</>
);
}