Compare commits

...

59 Commits

Author SHA1 Message Date
victorAnumudu a9cf3c9d22 added breadcrumb to some pages in full account type 2024-03-07 16:51:24 +01:00
ameye 01bf8a4c52 Merge branch 'login-page-width' of WrenchBoard/Users-Wrench into master 2024-03-07 12:50:47 +00:00
victorAnumudu 68ab094bf6 reduced login page width 2024-03-07 13:42:16 +01:00
ameye d938202f7a Merge branch 'home-banners-dashboard' of WrenchBoard/Users-Wrench into master 2024-03-07 12:25:12 +00:00
Ebube c9f66bdacb Completed layout for family activities 2024-03-07 10:01:43 +01:00
Ebube 5854ad194a Added layout for activities page 2024-03-07 09:23:14 +01:00
ameye 0f25a92b88 Merge branch 'home-banners-dashboard' of WrenchBoard/Users-Wrench into master 2024-03-06 22:01:34 +00:00
Ebube 9d7bcd91f4 . 2024-03-06 20:48:54 +01:00
Ebube 68115e79fa Added the following changes 2024-03-06 18:52:07 +01:00
ameye de379c2bbc Merge branch 'manage-job-padding' of WrenchBoard/Users-Wrench into master 2024-03-06 17:42:38 +00:00
victorAnumudu 2c11a0755d manage job page padding reduction 2024-03-06 18:21:58 +01:00
ameye f4ed892c5c Merge branch 'family-wallet-page' of WrenchBoard/Users-Wrench into master 2024-03-06 16:24:49 +00:00
ameye 30403f27c5 Merge branch 'home-banners-dashboard' of WrenchBoard/Users-Wrench into master 2024-03-06 16:24:44 +00:00
victorAnumudu cf2df7529d added family wallet page 2024-03-06 16:12:55 +01:00
Ebube b3695324b3 Removed next due task countdown and modified my page format 2024-03-06 15:21:55 +01:00
ameye cf8f32ed64 Merge branch 'past-due-task' of WrenchBoard/Users-Wrench into master 2024-03-06 11:00:07 +00:00
victorAnumudu bd59f26146 added past due task page 2024-03-06 00:00:27 +01:00
ameye 3a397aad86 Merge branch 'family-home-active-task' of WrenchBoard/Users-Wrench into master 2024-03-05 14:51:16 +00:00
victorAnumudu 0f548e216d removed active task display from family home page 2024-03-05 15:49:04 +01:00
ameye 50fd9711e0 Merge branch 'breadcrumb-addition' of WrenchBoard/Users-Wrench into master 2024-03-04 17:46:41 +00:00
victorAnumudu f4d9eb65c6 added breadcrumb component to other family account pages 2024-03-04 18:12:02 +01:00
ameye 774224ba6d Merge branch 'home-banners-dashboard' of WrenchBoard/Users-Wrench into master 2024-03-04 16:46:09 +00:00
Ebube 9eae733755 changed to square brackets and reduced font 2024-03-04 17:34:11 +01:00
ameye 0aee3b9d6f Merge branch 'home-banners-dashboard' of WrenchBoard/Users-Wrench into master 2024-03-04 15:29:11 +00:00
Ebube b676a2a4f3 username replacement and Active task window feedback 2024-03-04 15:16:41 +01:00
ameye 0baacb3057 Merge branch 'family-blog-population' of WrenchBoard/Users-Wrench into master 2024-03-04 14:14:58 +00:00
victorAnumudu 9737c02d45 added family blog api resources 2024-03-04 15:05:31 +01:00
ameye 1048e51ddf Merge branch 'family-commonheader' of WrenchBoard/Users-Wrench into master 2024-03-04 10:52:33 +00:00
victorAnumudu 6545c32326 removed common header in family single blog post page 2024-03-04 01:29:22 +01:00
ameye 6ea9078848 Merge branch 'family-file-resource' of WrenchBoard/Users-Wrench into master 2024-03-01 20:55:47 +00:00
victorAnumudu 735cc0b296 corrected text error 2024-03-01 21:36:28 +01:00
ameye 29e058828b Merge branch 'family-resource-pages' of WrenchBoard/Users-Wrench into master 2024-03-01 20:13:32 +00:00
victorAnumudu 5d5542c221 merged master to branch 2024-03-01 21:05:03 +01:00
ameye b59f92c89f Merge branch 'bug-fixing' of WrenchBoard/Users-Wrench into master 2024-03-01 19:58:07 +00:00
victorAnumudu e01bfa369b created pages for family resources 2024-03-01 18:49:23 +01:00
victorAnumudu 3d150f7a6b array length bug fixed 2024-03-01 15:18:20 +01:00
tokslaw bbd100d04e Merge branch 'resources-linking' of WrenchBoard/Users-Wrench into master 2024-03-01 00:35:21 +00:00
victorAnumudu fcb340007c linked family resources 2024-02-29 21:52:11 +01:00
ameye 95a10cf795 Merge branch 'home-banners-dashboard' of WrenchBoard/Users-Wrench into master 2024-02-29 19:48:34 +00:00
Ebube 5b5a083987 Added Home Img on Home btn 2024-02-29 20:06:18 +01:00
ameye 1564f29a4c Merge branch 'family-home-offerlist' of WrenchBoard/Users-Wrench into master 2024-02-29 17:35:02 +00:00
ameye 2b73191741 Merge branch 'parent-waiting-page' of WrenchBoard/Users-Wrench into master 2024-02-29 17:34:57 +00:00
victorAnumudu fee5c20fe2 removed offerlist from family home page 2024-02-29 17:09:47 +01:00
victorAnumudu 2d2b184291 parent waiting page top brought to top 2024-02-29 16:40:13 +01:00
ameye 5abd3665d1 Merge branch 'home-banners-dashboard' of WrenchBoard/Users-Wrench into master 2024-02-29 15:01:45 +00:00
Ebube a603a9eaff Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into home-banners-dashboard 2024-02-29 15:54:35 +01:00
Ebube 5bd74b3ca4 Added new stuff 2024-02-29 15:54:11 +01:00
Ebube 60cc290004 reduced component 2024-02-29 13:05:44 +01:00
ameye 12f30ec1e8 Merge branch 'banner-pages' of WrenchBoard/Users-Wrench into master 2024-02-29 11:46:56 +00:00
victorAnumudu 2521fbc1d8 more pages created for family banner links 2024-02-29 12:38:35 +01:00
ameye 29812e9265 Merge branch 'family-banner-linking' of WrenchBoard/Users-Wrench into master 2024-02-29 09:35:47 +00:00
victorAnumudu 271180932c linked banner to page 2024-02-29 10:32:27 +01:00
ameye 0a2e291013 Merge branch 'home-banners-dashboard' of WrenchBoard/Users-Wrench into master 2024-02-28 18:00:00 +00:00
ameye 8be09a9f9f Merge branch 'parent-waiting' of WrenchBoard/Users-Wrench into master 2024-02-28 17:59:53 +00:00
Ebube 78aa4fe58b Added padding 2024-02-28 18:38:52 +01:00
victorAnumudu 154ea29504 added parent waiting page 2024-02-28 18:38:19 +01:00
ameye 4f670fa3ba Merge branch 'resources-banner-fix' of WrenchBoard/Users-Wrench into master 2024-02-28 16:49:51 +00:00
victorAnumudu 8d48435705 reduced family resources banner 2024-02-28 17:40:32 +01:00
ameye 76109dc458 Merge branch 'implemented-breadcrumb' of WrenchBoard/Users-Wrench into master 2024-02-28 16:00:09 +00:00
78 changed files with 2141 additions and 738 deletions
+4 -1
View File
@@ -108,4 +108,7 @@ REACT_APP_APPLE_APP='https://itunes.apple.com/us/app/wrenchboard/id1435718367?ls
REACT_APP_SHOW_NEW_FAMILY_DASH=1 REACT_APP_SHOW_NEW_FAMILY_DASH=1
# Displays the account dashboard # Displays the account dashboard
REACT_APP_SHOW_ACCOUNT_DASH=1 REACT_APP_SHOW_ACCOUNT_DASH=1
# Displays the slider banners
REACT_APP_SHOW_SLIDER_BANNERS=0
+4 -1
View File
@@ -76,4 +76,7 @@ REACT_APP_APPLE_APP='https://itunes.apple.com/us/app/wrenchboard/id1435718367?ls
REACT_APP_SHOW_NEW_FAMILY_DASH=1 REACT_APP_SHOW_NEW_FAMILY_DASH=1
# Displays the account dashboard # Displays the account dashboard
REACT_APP_SHOW_ACCOUNT_DASH=1 REACT_APP_SHOW_ACCOUNT_DASH=1
# Displays the slider banners
REACT_APP_SHOW_SLIDER_BANNERS=0
+4 -1
View File
@@ -82,4 +82,7 @@ REACT_APP_APPLE_APP='https://itunes.apple.com/us/app/wrenchboard/id1435718367?ls
REACT_APP_SHOW_NEW_FAMILY_DASH=1 REACT_APP_SHOW_NEW_FAMILY_DASH=1
# Displays the account dashboard # Displays the account dashboard
REACT_APP_SHOW_ACCOUNT_DASH=1 REACT_APP_SHOW_ACCOUNT_DASH=1
# Displays the slider banners
REACT_APP_SHOW_SLIDER_BANNERS=0
+20 -2
View File
@@ -57,6 +57,15 @@ import VerifyPasswordPagesTwo from "./views/VerifyPasswordPagesTwo";
import VerifyYouPages from "./views/VerifyYouPages"; import VerifyYouPages from "./views/VerifyYouPages";
import VerifyYouPagesTwo from "./views/VerifyYouPagesTwo"; import VerifyYouPagesTwo from "./views/VerifyYouPagesTwo";
import YourPages from "./views/YourPage_"; import YourPages from "./views/YourPage_";
import ParentWaitingPage from "./views/ParentWaitingPage";
import FamilyPendingOfferPage from "./views/FamilyPendingOfferPage";
import FamBlogPage from "./views/FamBlogPage"
import FamAIQuestionPage from "./views/FamAIQuestionPage"
import FamMyFilesPage from "./views/FamMyFilesPage"
import FamWorkInProgressPage from "./views/FamWorkInProgressPage";
import MyPastDueTasksPage from "./views/MyPastDueTasksPage";
import FamilyWalletPage from "./views/FamilyWalletPage";
import FamilyActivitiesPage from "./views/FamilyActivitiesPage";
export default function Routers() { export default function Routers() {
return ( return (
@@ -117,23 +126,31 @@ export default function Routers() {
<Route exact path="/notification" element={<Notification />} /> <Route exact path="/notification" element={<Notification />} />
<Route exact path="/market-place" element={<MarketPlacePage />} /> <Route exact path="/market-place" element={<MarketPlacePage />} />
<Route exact path="/shop-details" element={<ShopDetailsPage />} /> <Route exact path="/shop-details" element={<ShopDetailsPage />} />
<Route exact path="/my-wallet" element={<MyWalletPage />} /> <Route exact path="/my-collection" element={<MyCollection />} />*/}
<Route exact path="/my-collection" element={<MyCollection />} />*/}
<Route exact path="/reminders" element={<RemindersPage />} /> <Route exact path="/reminders" element={<RemindersPage />} />
<Route exact path="/tracking" element={<TrackingPage />} /> <Route exact path="/tracking" element={<TrackingPage />} />
<Route exact path="/calendar" element={<CalendarPage />} /> <Route exact path="/calendar" element={<CalendarPage />} />
<Route exact path="/resources" element={<ResourcePage />} /> <Route exact path="/resources" element={<ResourcePage />} />
<Route exact path="/my-wallet/*" element={<MyWalletPage />} /> <Route exact path="/my-wallet/*" element={<MyWalletPage />} />
<Route exact path="/family-wallet" element={<FamilyWalletPage />} />
<Route exact path="/my-coupon" element={<MyCouponPage />} /> <Route exact path="/my-coupon" element={<MyCouponPage />} />
<Route exact path="/notification" element={<Notification />} /> <Route exact path="/notification" element={<Notification />} />
<Route exact path="/market-place" element={<MarketPlacePage />} /> <Route exact path="/market-place" element={<MarketPlacePage />} />
<Route exact path="/market" element={<MarketPlacePage />} /> <Route exact path="/market" element={<MarketPlacePage />} />
<Route exact path="/familymarket" element={<FamilyMarketPage />} /> <Route exact path="/familymarket" element={<FamilyMarketPage />} />
<Route exact path="/suggested" element={<ParentWaitingPage />} />
<Route exact path="/pending" element={<FamilyPendingOfferPage />} />
<Route exact path="/fam-blog" element={<FamBlogPage />} />
<Route exact path="/ai-question" element={<FamAIQuestionPage />} />
<Route exact path="/myfiles" element={<FamMyFilesPage />} />
<Route exact path="/ai-lab" element={<FamAIQuestionPage />} />
<Route exact path="/work-in-progress" element={<FamWorkInProgressPage />} />
<Route <Route
exact exact
path="/familysettings" path="/familysettings"
element={<FamilySettingsPage />} element={<FamilySettingsPage />}
/> />
<Route exact path="/pastdue" element={<MyPastDueTasksPage />} />
<Route exact path="/notification" element={<Notification />} /> <Route exact path="/notification" element={<Notification />} />
<Route exact path="/mytask" element={<MyTaskPage />} /> <Route exact path="/mytask" element={<MyTaskPage />} />
<Route exact path="/myjobs" element={<MyJobsPage />} /> <Route exact path="/myjobs" element={<MyJobsPage />} />
@@ -152,6 +169,7 @@ export default function Routers() {
element={<MyReviewDueJobsPage />} element={<MyReviewDueJobsPage />}
/> />
<Route exact path="/acc-family" element={<FamilyAccPage />} /> <Route exact path="/acc-family" element={<FamilyAccPage />} />
<Route exact path="/acc-family/activities" element={<FamilyActivitiesPage />} />
<Route exact path="/manage-family" element={<FamilyManagePage />} /> <Route exact path="/manage-family" element={<FamilyManagePage />} />
<Route exact path="/start-job" element={<StartJob />} /> <Route exact path="/start-job" element={<StartJob />} />
<Route exact path="/yourpage" element={<YourPages />} /> <Route exact path="/yourpage" element={<YourPages />} />
+1 -1
View File
@@ -25,7 +25,7 @@ export default function LoginLayout({ slogan, children }) {
> >
</div> */} </div> */}
<div className="p-5 sm:p-7 flex place-content-center lg:col-start-2"> <div className="p-5 sm:p-7 flex place-content-center lg:col-start-2">
<div className="py-5 w-full sm:w-11/12 max-w-2xl shadow-md bg-slate-50 rounded-[0.475rem]"> <div className="py-5 w-full sm:w-11/12 max-w-[550px] shadow-md bg-slate-50 rounded-[0.475rem]">
<div className="w-full flex justify-center items-center"> <div className="w-full flex justify-center items-center">
{children && children} {children && children}
</div> </div>
+32 -11
View File
@@ -4,9 +4,15 @@ import usersService from "../../services/UsersService";
import Layout from "../Partials/Layout"; import Layout from "../Partials/Layout";
import LoadingSpinner from "../Spinners/LoadingSpinner"; import LoadingSpinner from "../Spinners/LoadingSpinner";
import CommonHead from "../UserHeader/CommonHead"; import CommonHead from "../UserHeader/CommonHead";
import { useSelector } from "react-redux";
import CustomBreadcrumb from "../Breadcrumb/CustomBreadcrumb";
export default function BlogItem(props) { export default function BlogItem(props) {
const {
userDetails: { account_type },
} = useSelector((state) => state?.userDetails); // CHECKS IF USER Details account type
const apiCall = new usersService() const apiCall = new usersService()
const navigate = useNavigate() const navigate = useNavigate()
@@ -33,11 +39,26 @@ export default function BlogItem(props) {
},[blog_id]) },[blog_id])
return ( return (
<Layout> <Layout>
<CommonHead {account_type == 'FULL' &&
commonHeadData={props.commonHeadData} <CommonHead
/> commonHeadData={props.commonHeadData}
/>
}
{ account_type == 'FAMILY' &&
<div className="mb-5">
<CustomBreadcrumb
title = {blogdata?.data?.blogdata?.length > 0 ? blogdata?.data?.blogdata[0]?.post_title : 'Blog'}
breadcrumb={
[
{ link: "/", title: "Home" },
{ link: "/fam-blog", title: "Blogs", active: true},
]
}
/>
</div>
}
<div className="notification-page w-full mb-10"> <div className="notification-page w-full mb-10">
<div className="mb-5"> {/* <div className="mb-5">
<h1 className="text-26 font-bold text-dark-gray dark:text-white"> <h1 className="text-26 font-bold text-dark-gray dark:text-white">
<span <span
className={`${selectTab === "today" ? "block" : "hidden"}`} className={`${selectTab === "today" ? "block" : "hidden"}`}
@@ -45,7 +66,7 @@ export default function BlogItem(props) {
{blogdata.data?.blogdata?.[0]?.post_title} {blogdata.data?.blogdata?.[0]?.post_title}
</span> </span>
</h1> </h1>
</div> </div> */}
<div className="notification-wrapper w-full bg-white p-8 rounded-2xl"> <div className="notification-wrapper w-full bg-white p-8 rounded-2xl">
{blogdata?.loading ? {blogdata?.loading ?
<LoadingSpinner size='8' color='sky-blue' height='h-[100px]' /> <LoadingSpinner size='8' color='sky-blue' height='h-[100px]' />
@@ -53,8 +74,8 @@ export default function BlogItem(props) {
blogdata?.data?.blogdata && blogdata.data?.blogdata.length ? blogdata?.data?.blogdata && blogdata.data?.blogdata.length ?
<div className="w-full"> <div className="w-full">
{/* heading */} {/* heading */}
<div className="sm:flex justify-between items-center mb-6"> {/* <div className="sm:flex justify-between items-center mb-6">
{/* <div className="mb-5"> <div className="mb-5">
<h1 className="text-26 font-bold text-dark-gray dark:text-white"> <h1 className="text-26 font-bold text-dark-gray dark:text-white">
<span <span
className={`${selectTab === "today" ? "block" : "hidden"}`} className={`${selectTab === "today" ? "block" : "hidden"}`}
@@ -62,10 +83,10 @@ export default function BlogItem(props) {
{blogdata.data?.blogdata?.[0]?.post_title} {blogdata.data?.blogdata?.[0]?.post_title}
</span> </span>
</h1> </h1>
</div> */} </div>
{/* <div className="slider-btns flex space-x-4"> <div className="slider-btns flex space-x-4">
</div> */} </div>
</div> </div> */}
<div dangerouslySetInnerHTML={{__html: blogdata.data?.blogdata?.[0]?.post_content}}> <div dangerouslySetInnerHTML={{__html: blogdata.data?.blogdata?.[0]?.post_content}}>
</div> </div>
</div> </div>
+1 -1
View File
@@ -117,7 +117,7 @@ export default function AvailableJobsCard({
</div> </div>
</div> </div>
) : ( ) : (
<div className="card-style-two w-full p-8 my-2 flex items-center gap-4 bg-white dark:bg-dark-white rounded-2xl section-shadow"> <div className="card-style-two w-full px-4 py-[0.4rem] my-2 flex items-center gap-4 bg-white dark:bg-dark-white rounded-2xl section-shadow">
<div className="flex gap-5 items-center w-full"> <div className="flex gap-5 items-center w-full">
<div className="w-full h-[60px] rounded-full overflow-hidden flex justify-center items-center flex-[0.1] min-w-[60px] max-w-[60px]"> <div className="w-full h-[60px] rounded-full overflow-hidden flex justify-center items-center flex-[0.1] min-w-[60px] max-w-[60px]">
<img src={image} alt="data" className="w-full h-full" /> <img src={image} alt="data" className="w-full h-full" />
@@ -67,11 +67,12 @@ export default AccountDashboard;
const TopBanner = ({ image, title = "", desc = "", btn, link_path, key }) => { const TopBanner = ({ image, title = "", desc = "", btn, link_path, key }) => {
return ( return (
<div className="flex flex-col shadow-md rounded-xl dark:border-[#5356fb29]"> <div className="flex flex-col shadow-md rounded-xl dark:border-[#5356fb29]" key={key}>
<Link to={link_path} key={key} className="h-[12rem] rounded-t-xl"> <Link to={link_path} className="h-[12rem] rounded-t-xl">
<img <img
src={image} src={image}
alt="banner-img" alt="banner-img"
loading="lazy"
className="w-full h-full rounded-t-xl object-cover" className="w-full h-full rounded-t-xl object-cover"
/> />
</Link> </Link>
@@ -120,6 +121,7 @@ const LowerBanner = ({ image, title = "", desc = "", btn, link_path, key }) => {
<img <img
src={image} src={image}
alt="banner-img" alt="banner-img"
loading="lazy"
className="w-full h-full rounded-xl" className="w-full h-full rounded-xl"
/> />
</Link> </Link>
@@ -1,9 +1,8 @@
import React from "react"; import React from "react";
import CountDown from "../Helpers/CountDown";
// import HomeSliders from "./HomeSliders"; // import HomeSliders from "./HomeSliders";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
export default function JobOwnerDashboard({ export default function FamilyParentDashboard({
className, className,
bannerList, bannerList,
nextDueTask, nextDueTask,
@@ -16,7 +15,7 @@ export default function JobOwnerDashboard({
return ( return (
<div <div
className={`w-full md:h-[47px] xxs:h-[74px] flex p-1 flex-wrap justify-between items-center gap-2 rounded-2xl overflow-hidden bg-sky-blue ${ className={`w-full md:h-[47px] xxs:h-[74px] flex px-[1.05rem] py-[0.35rem] flex-wrap justify-between items-center gap-2 rounded-2xl overflow-hidden bg-sky-blue ${
className || "" className || ""
}`} }`}
style={{ style={{
@@ -28,50 +27,19 @@ export default function JobOwnerDashboard({
<div className="h-full flex flex-wrap w-full justify-between mb-5 lg:mb-0"> <div className="h-full flex flex-wrap w-full justify-between mb-5 lg:mb-0">
{/* heading */} {/* heading */}
<div className="flex gap-8"> <div className="flex gap-8">
<h1 className="text-base ng font-medium text-white tracking-wide"> <h1 className="text-base font-medium text-white tracking-wide">
Welcome Welcome
</h1> </h1>
{/* user */} {/* user */}
<div> <div className="flex flex-col gap-1">
<p className="text-base tracking-wide font-bold antise text-white"> <p className="text-base tracking-wide font-bold antise text-white leading-[1]">
{`${firstname} ${lastname}`} {`${firstname} ${lastname}`}
</p> </p>
<p className="text-sm tracking-wide text-white">@{userEmail}</p> <p className="text-sm tracking-wide text-white leading-[1]">
@{userEmail}
</p>
</div> </div>
</div> </div>
{/* countdown */}
{nextDueTask?.next_due &&
Object.keys(nextDueTask.next_due)?.length != 0 && (
<div className="w-full h-32 flex justify-evenly items-center sm:p-6 p-1 rounded-2xl border back-dark1 border-white-opacity">
<div className="flex flex-col justify-between">
<p className="text-base text-white tracking-wide">
Current Task
</p>
<p className="lg:text-2xl text-lg font-bold tracking-wide text-white">
{nextDueTask.next_due.item_code.substr(0, 4) + "..."}
</p>
<p className="text-base text-white tracking-wide">
{nextDueTask.next_due.price * 0.01} Naira
</p>
</div>
<div className="w-[1px] h-full bg-white-opacity"></div>
<div className="flex flex-col justify-between">
<p className="text-base text-white tracking-wide">
Next due in
</p>
<p className="lg:text-2xl text-lg font-bold tracking-wide text-white">
{/* <CountDown lastDate="2023-04-26 4:00:00" /> */}
<CountDown lastDate={nextDueTask.next_due.due_date} />
</p>
<div className="text-base text-white tracking-wide flex gap-[23px]">
<span>Hrs</span>
<span>Min</span>
<span>Sec</span>
</div>
</div>
</div>
)}
<span className="text-base font-thin tracking-wide text-white flex items-end"> <span className="text-base font-thin tracking-wide text-white flex items-end">
Last Login : {loginDate} Last Login : {loginDate}
</span> </span>
+8 -43
View File
@@ -1,13 +1,8 @@
import React from "react"; import React from "react";
import CountDown from "../Helpers/CountDown";
// import HomeSliders from "./HomeSliders"; // import HomeSliders from "./HomeSliders";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
export default function JobOwnerDashboard({ export default function HomeDashboard({ className, bannerList, nextDueTask }) {
className,
bannerList,
nextDueTask,
}) {
const { userDetails } = useSelector((state) => state?.userDetails); const { userDetails } = useSelector((state) => state?.userDetails);
let loginDate = userDetails?.last_login.split(" ")[0]; let loginDate = userDetails?.last_login.split(" ")[0];
@@ -16,7 +11,7 @@ export default function JobOwnerDashboard({
return ( return (
<div <div
className={`w-full md:h-[47px] xxs:h-[74px] flex p-1 flex-wrap justify-between items-center gap-2 rounded-2xl overflow-hidden bg-sky-blue ${ className={`w-full md:h-[47px] xxs:h-[74px] flex px-[1.05rem] py-[0.35rem] flex-wrap justify-between items-center gap-2 rounded-2xl overflow-hidden bg-sky-blue ${
className || "" className || ""
}`} }`}
style={{ style={{
@@ -28,50 +23,20 @@ export default function JobOwnerDashboard({
<div className="h-full flex flex-wrap w-full justify-between mb-5 lg:mb-0"> <div className="h-full flex flex-wrap w-full justify-between mb-5 lg:mb-0">
{/* heading */} {/* heading */}
<div className="flex gap-8"> <div className="flex gap-8">
<h1 className="text-base ng font-medium text-white tracking-wide"> <h1 className="text-base font-medium text-white tracking-wide">
Welcome Welcome
</h1> </h1>
{/* user */} {/* user */}
<div> <div className="flex flex-col gap-1">
<p className="text-base tracking-wide font-bold antise text-white"> <p className="text-base tracking-wide font-bold antise text-white leading-[1]">
{`${firstname} ${lastname}`} {`${firstname} ${lastname}`}
</p> </p>
<p className="text-sm tracking-wide text-white">@{userEmail}</p> <p className="text-sm tracking-wide text-white leading-[1]">
@{userEmail}
</p>
</div> </div>
</div> </div>
{/* countdown */}
{nextDueTask?.next_due &&
Object.keys(nextDueTask.next_due)?.length != 0 && (
<div className="w-full h-32 flex justify-evenly items-center sm:p-6 p-1 rounded-2xl border back-dark1 border-white-opacity">
<div className="flex flex-col justify-between">
<p className="text-base text-white tracking-wide">
Current Task
</p>
<p className="lg:text-2xl text-lg font-bold tracking-wide text-white">
{nextDueTask.next_due.item_code.substr(0, 4) + "..."}
</p>
<p className="text-base text-white tracking-wide">
{nextDueTask.next_due.price * 0.01} Naira
</p>
</div>
<div className="w-[1px] h-full bg-white-opacity"></div>
<div className="flex flex-col justify-between">
<p className="text-base text-white tracking-wide">
Next due in
</p>
<p className="lg:text-2xl text-lg font-bold tracking-wide text-white">
{/* <CountDown lastDate="2023-04-26 4:00:00" /> */}
<CountDown lastDate={nextDueTask.next_due.due_date} />
</p>
<div className="text-base text-white tracking-wide flex gap-[23px]">
<span>Hrs</span>
<span>Min</span>
<span>Sec</span>
</div>
</div>
</div>
)}
<span className="text-base font-thin tracking-wide text-white flex items-end"> <span className="text-base font-thin tracking-wide text-white flex items-end">
Last Login : {loginDate} Last Login : {loginDate}
</span> </span>
@@ -1,5 +1,4 @@
import React from "react"; import React from "react";
import CountDown from "../Helpers/CountDown";
// import HomeSliders from "./HomeSliders"; // import HomeSliders from "./HomeSliders";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
@@ -16,7 +15,7 @@ export default function JobOwnerDashboard({
return ( return (
<div <div
className={`w-full md:h-[47px] xxs:h-[74px] flex p-1 flex-wrap justify-between items-center gap-2 rounded-2xl overflow-hidden bg-sky-blue ${ className={`w-full md:h-[47px] xxs:h-[74px] flex px-[1.05rem] py-[0.35rem] flex-wrap justify-between items-center gap-2 rounded-2xl overflow-hidden bg-sky-blue ${
className || "" className || ""
}`} }`}
style={{ style={{
@@ -32,46 +31,16 @@ export default function JobOwnerDashboard({
Welcome Welcome
</h1> </h1>
{/* user */} {/* user */}
<div> <div className="flex flex-col gap-1">
<p className="text-base tracking-wide font-bold antise text-white"> <p className="text-base tracking-wide font-bold antise text-white leading-[1]">
{`${firstname} ${lastname}`} {`${firstname} ${lastname}`}
</p> </p>
<p className="text-sm tracking-wide text-white">@{userEmail}</p> <p className="text-sm tracking-wide text-white leading-[1]">
@{userEmail}
</p>
</div> </div>
</div> </div>
{/* countdown */}
{nextDueTask?.next_due &&
Object.keys(nextDueTask.next_due)?.length != 0 && (
<div className="w-full h-32 flex justify-evenly items-center sm:p-6 p-1 rounded-2xl border back-dark1 border-white-opacity">
<div className="flex flex-col justify-between">
<p className="text-base text-white tracking-wide">
Current Task
</p>
<p className="lg:text-2xl text-lg font-bold tracking-wide text-white">
{nextDueTask.next_due.item_code.substr(0, 4) + "..."}
</p>
<p className="text-base text-white tracking-wide">
{nextDueTask.next_due.price * 0.01} Naira
</p>
</div>
<div className="w-[1px] h-full bg-white-opacity"></div>
<div className="flex flex-col justify-between">
<p className="text-base text-white tracking-wide">
Next due in
</p>
<p className="lg:text-2xl text-lg font-bold tracking-wide text-white">
{/* <CountDown lastDate="2023-04-26 4:00:00" /> */}
<CountDown lastDate={nextDueTask.next_due.due_date} />
</p>
<div className="text-base text-white tracking-wide flex gap-[23px]">
<span>Hrs</span>
<span>Min</span>
<span>Sec</span>
</div>
</div>
</div>
)}
<span className="text-base font-thin tracking-wide text-white flex items-end"> <span className="text-base font-thin tracking-wide text-white flex items-end">
Last Login : {loginDate} Last Login : {loginDate}
</span> </span>
+35 -28
View File
@@ -1,14 +1,16 @@
import React, { useState } from "react"; import React from "react";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { toast } from "react-toastify";
import heroBg from "../../assets/images/bg-sky-blue.jpg"; //hero-bg.svg";
import heroUser from "../../assets/images/hero-user.png"; import heroUser from "../../assets/images/hero-user.png";
import CountDown from "../Helpers/CountDown"; import CountDown from "../Helpers/CountDown";
// import HomeSliders from "./HomeSliders"; // import HomeSliders from "./HomeSliders";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
import HomeSliders from "../Home/HomeSliders"; import HomeSliders from "../Home/HomeSliders";
export default function WorkerDashboard({ className, bannerList, nextDueTask }) { export default function WorkerDashboard({
className,
bannerList,
nextDueTask,
}) {
const settings = { const settings = {
autoplay: true, autoplay: true,
dots: true, dots: true,
@@ -57,32 +59,37 @@ export default function WorkerDashboard({ className, bannerList, nextDueTask })
</div> </div>
</div> </div>
{/* countdown */} {/* countdown */}
{nextDueTask?.next_due && Object.keys(nextDueTask.next_due)?.length != 0 && ( {nextDueTask?.next_due &&
<div className="w-full h-32 flex justify-evenly items-center sm:p-6 p-1 rounded-2xl border back-dark1 border-white-opacity"> Object.keys(nextDueTask.next_due)?.length != 0 && (
<div className="flex flex-col justify-between"> <div className="w-full h-32 flex justify-evenly items-center sm:p-6 p-1 rounded-2xl border back-dark1 border-white-opacity">
<p className="text-base text-white tracking-wide">Current Task</p> <div className="flex flex-col justify-between">
<p className="lg:text-2xl text-lg font-bold tracking-wide text-white"> <p className="text-base text-white tracking-wide">
{(nextDueTask.next_due.item_code).substr(0,4)+'...'} Current Task
</p> </p>
<p className="text-base text-white tracking-wide"> <p className="lg:text-2xl text-lg font-bold tracking-wide text-white">
{nextDueTask.next_due.price * 0.01} Naira {nextDueTask.next_due.item_code.substr(0, 4) + "..."}
</p> </p>
</div> <p className="text-base text-white tracking-wide">
<div className="w-[1px] h-full bg-white-opacity"></div> {nextDueTask.next_due.price * 0.01} Naira
<div className="flex flex-col justify-between"> </p>
<p className="text-base text-white tracking-wide">Next due in</p> </div>
<p className="lg:text-2xl text-lg font-bold tracking-wide text-white"> <div className="w-[1px] h-full bg-white-opacity"></div>
{/* <CountDown lastDate="2023-04-26 4:00:00" /> */} <div className="flex flex-col justify-between">
<CountDown lastDate={nextDueTask.next_due.due_date} /> <p className="text-base text-white tracking-wide">
</p> Next due in
<div className="text-base text-white tracking-wide flex gap-[23px]"> </p>
<span>Hrs</span> <p className="lg:text-2xl text-lg font-bold tracking-wide text-white">
<span>Min</span> {/* <CountDown lastDate="2023-04-26 4:00:00" /> */}
<span>Sec</span> <CountDown lastDate={nextDueTask.next_due.due_date} />
</p>
<div className="text-base text-white tracking-wide flex gap-[23px]">
<span>Hrs</span>
<span>Min</span>
<span>Sec</span>
</div>
</div> </div>
</div> </div>
</div> )}
)}
{/* action */} {/* action */}
<div className="flex lg:space-x-3 space-x-1 items-center"> <div className="flex lg:space-x-3 space-x-1 items-center">
<Link to="/mytask" className="text-white text-base"> <Link to="/mytask" className="text-white text-base">
+8 -40
View File
@@ -1,9 +1,8 @@
import React from "react"; import React from "react";
import CountDown from "../Helpers/CountDown";
// import HomeSliders from "./HomeSliders"; // import HomeSliders from "./HomeSliders";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
export default function JobOwnerDashboard({ export default function WorkerDashboard({
className, className,
bannerList, bannerList,
nextDueTask, nextDueTask,
@@ -16,7 +15,7 @@ export default function JobOwnerDashboard({
return ( return (
<div <div
className={`w-full md:h-[47px] xxs:h-[74px] flex p-1 flex-wrap justify-between items-center gap-2 rounded-2xl overflow-hidden bg-sky-blue ${ className={`w-full md:h-[47px] xxs:h-[74px] flex px-[1.05rem] py-[0.35rem] flex-wrap justify-between items-center gap-2 rounded-2xl overflow-hidden bg-sky-blue ${
className || "" className || ""
}`} }`}
style={{ style={{
@@ -28,50 +27,19 @@ export default function JobOwnerDashboard({
<div className="h-full flex flex-wrap w-full justify-between mb-5 lg:mb-0"> <div className="h-full flex flex-wrap w-full justify-between mb-5 lg:mb-0">
{/* heading */} {/* heading */}
<div className="flex gap-8"> <div className="flex gap-8">
<h1 className="text-base ng font-medium text-white tracking-wide"> <h1 className="text-base font-medium text-white tracking-wide">
Welcome Welcome
</h1> </h1>
{/* user */} {/* user */}
<div> <div className="flex flex-col gap-1">
<p className="text-base tracking-wide font-bold antise text-white"> <p className="text-base tracking-wide font-bold antise text-white leading-[1]">
{`${firstname} ${lastname}`} {`${firstname} ${lastname}`}
</p> </p>
<p className="text-sm tracking-wide text-white">@{userEmail}</p> <p className="text-sm tracking-wide text-white leading-[1]">
@{userEmail}
</p>
</div> </div>
</div> </div>
{/* countdown */}
{nextDueTask?.next_due &&
Object.keys(nextDueTask.next_due)?.length != 0 && (
<div className="w-full h-32 flex justify-evenly items-center sm:p-6 p-1 rounded-2xl border back-dark1 border-white-opacity">
<div className="flex flex-col justify-between">
<p className="text-base text-white tracking-wide">
Current Task
</p>
<p className="lg:text-2xl text-lg font-bold tracking-wide text-white">
{nextDueTask.next_due.item_code.substr(0, 4) + "..."}
</p>
<p className="text-base text-white tracking-wide">
{nextDueTask.next_due.price * 0.01} Naira
</p>
</div>
<div className="w-[1px] h-full bg-white-opacity"></div>
<div className="flex flex-col justify-between">
<p className="text-base text-white tracking-wide">
Next due in
</p>
<p className="lg:text-2xl text-lg font-bold tracking-wide text-white">
{/* <CountDown lastDate="2023-04-26 4:00:00" /> */}
<CountDown lastDate={nextDueTask.next_due.due_date} />
</p>
<div className="text-base text-white tracking-wide flex gap-[23px]">
<span>Hrs</span>
<span>Min</span>
<span>Sec</span>
</div>
</div>
</div>
)}
<span className="text-base font-thin tracking-wide text-white flex items-end"> <span className="text-base font-thin tracking-wide text-white flex items-end">
Last Login : {loginDate} Last Login : {loginDate}
</span> </span>
@@ -0,0 +1,78 @@
import React, { Suspense, useMemo, useState } from "react";
import { Link } from "react-router-dom";
import usersService from "../../services/UsersService";
import Layout from "../Partials/Layout";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import FamilyTableNew from "./FamilyTableNew";
export default function FamilyActivities() {
const [familyList, setFamilyList] = useState({});
const [loader, setLoader] = useState(false);
const apiCall = useMemo(() => new usersService(), []);
return (
<Layout>
{/*<CommonHead />*/}
<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 inline-flex gap-3 text-dark-gray dark:text-white items-center">
<span className={``}>Tasks & Chores</span>
</h1>
</div>
<Link className="flex items-center gap-2" to="/acc-family">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth={1.5}
stroke="currentColor"
className="w-4 h-4"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M10.5 19.5 3 12m0 0 7.5-7.5M3 12h18"
/>
</svg>
<span>Family</span>
</Link>
</div>
<Suspense fallback={<LoadingSpinner color="sky-blue" size="16" />}>
<FamilyTableNew
familyList={familyList?.result_list}
loader={loader}
imageServer={familyList?.session_image_server}
/>
</Suspense>
</div>
</div>
</Layout>
);
}
const CloseIcon = () => (
<svg
width="36"
height="36"
viewBox="0 0 36 36"
fill="none"
className="fill-current"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M36 16.16C36 17.4399 36 18.7199 36 20.0001C35.7911 20.0709 35.8636 20.2554 35.8385 20.4001C34.5321 27.9453 30.246 32.9248 22.9603 35.2822C21.9006 35.6251 20.7753 35.7657 19.6802 35.9997C18.4003 35.9997 17.1204 35.9997 15.8401 35.9997C15.5896 35.7086 15.2189 35.7732 14.9034 35.7093C7.77231 34.2621 3.08728 30.0725 0.769671 23.187C0.435002 22.1926 0.445997 21.1199 0 20.1599C0 18.7198 0 17.2798 0 15.8398C0.291376 15.6195 0.214408 15.2656 0.270759 14.9808C1.71321 7.69774 6.02611 2.99691 13.0428 0.700951C14.0118 0.383805 15.0509 0.386897 15.9999 0C17.2265 0 18.4532 0 19.6799 0C19.7156 0.124041 19.8125 0.136067 19.9225 0.146719C27.3 0.868973 33.5322 6.21922 35.3801 13.427C35.6121 14.3313 35.7945 15.2484 36 16.16ZM33.011 18.0787C33.0433 9.77105 26.3423 3.00309 18.077 2.9945C9.78479 2.98626 3.00344 9.658 2.98523 17.8426C2.96667 26.1633 9.58859 32.9601 17.7602 33.0079C26.197 33.0577 32.9787 26.4186 33.011 18.0787Z"
fill=""
fillOpacity="0.6"
/>
<path
d="M15.9309 18.023C13.9329 16.037 12.007 14.1207 10.0787 12.2072C9.60071 11.733 9.26398 11.2162 9.51996 10.506C9.945 9.32677 11.1954 9.0811 12.1437 10.0174C13.9067 11.7585 15.6766 13.494 17.385 15.2879C17.9108 15.8401 18.1633 15.7487 18.6375 15.258C20.3586 13.4761 22.1199 11.7327 23.8822 9.99096C24.8175 9.06632 26.1095 9.33639 26.4967 10.517C26.7286 11.2241 26.3919 11.7413 25.9133 12.2178C24.1757 13.9472 22.4477 15.6855 20.7104 17.4148C20.5228 17.6018 20.2964 17.7495 20.0466 17.9485C22.0831 19.974 24.0372 21.8992 25.9689 23.8468C26.9262 24.8119 26.6489 26.1101 25.4336 26.4987C24.712 26.7292 24.2131 26.3441 23.7455 25.8757C21.9945 24.1227 20.2232 22.3892 18.5045 20.6049C18.0698 20.1534 17.8716 20.2269 17.4802 20.6282C15.732 22.4215 13.9493 24.1807 12.1777 25.951C11.7022 26.4262 11.193 26.7471 10.4738 26.4537C9.31345 25.9798 9.06881 24.8398 9.98589 23.8952C11.285 22.5576 12.6138 21.2484 13.9387 19.9355C14.5792 19.3005 15.2399 18.6852 15.9309 18.023Z"
fill="#"
fillOpacity="0.6"
/>
</svg>
);
+13 -1
View File
@@ -4,6 +4,7 @@ import SearchCom from "../Helpers/SearchCom";
import FamilyMarketCard from "../Cards/FamilyMarketCard"; import FamilyMarketCard from "../Cards/FamilyMarketCard";
import usersService from "../../services/UsersService"; import usersService from "../../services/UsersService";
import SuggestTask from "../FamilyPopup/SuggestTask"; import SuggestTask from "../FamilyPopup/SuggestTask";
import CustomBreadcrumb from "../Breadcrumb/CustomBreadcrumb";
export default function FamilyMarket() { export default function FamilyMarket() {
const [popUp, setPopUp] = useState(false); const [popUp, setPopUp] = useState(false);
@@ -53,12 +54,23 @@ export default function FamilyMarket() {
<div className="notification-page w-full mb-10"> <div className="notification-page w-full mb-10">
<div className="notification-wrapper w-full"> <div className="notification-wrapper w-full">
{/* heading */} {/* heading */}
<div className="sm:flex justify-between items-center mb-6"> {/* <div className="sm:flex justify-between items-center mb-6">
<div className="mb-5 sm:mb-0"> <div className="mb-5 sm:mb-0">
<h1 className="text-26 font-bold inline-flex gap-3 text-dark-gray dark:text-white items-center"> <h1 className="text-26 font-bold inline-flex gap-3 text-dark-gray dark:text-white items-center">
<span>Suggest Task to the Parents</span> <span>Suggest Task to the Parents</span>
</h1> </h1>
</div> </div>
</div> */}
<div className="mb-5">
<CustomBreadcrumb
title = {'Suggest Task to the Parents'}
breadcrumb={
[
{ link: "/", title: "Home" },
{ link: "/familymarket", title: "Family Market", active: true},
]
}
/>
</div> </div>
{/* Body */} {/* Body */}
<div className="filter-section w-full items-center sm:flex justify-between mb-6"> <div className="filter-section w-full items-center sm:flex justify-between mb-6">
@@ -0,0 +1,58 @@
import React, { useEffect, useState } from 'react'
import Layout from '../Partials/Layout'
import MyOffersFamilyTable from '../MyTasks/MyOffersFamilyTable'
import LoadingSpinner from '../Spinners/LoadingSpinner';
import usersService from '../../services/UsersService';
import CustomBreadcrumb from '../Breadcrumb/CustomBreadcrumb';
export default function FamilyPendingOffer() {
const userApi = new usersService();
const [myOffersList, setMyOffersList] = useState({loading: true, data: []});
const getMyOffersList = async () => {
try {
const res = await userApi.getOffersList();
setMyOffersList({loading:false, data:res.data});
console.log('SAME', res.data)
} catch (error) {
setMyOffersList({loading:false, data:[]});
console.log("Error getting offers", error);
}
};
useEffect(()=>{
getMyOffersList()
},[])
return (
<Layout>
<div className="mb-5">
<CustomBreadcrumb
title = {'Ready to Start'}
breadcrumb={
[
{ link: "/", title: "Home" },
{ link: "/pending", title: "Pending", active: true},
]
}
/>
</div>
{myOffersList.loading ?
<div className='w-full flex justify-center items-center rounded-2xl bg-white'>
<LoadingSpinner size='10' color='sky-blue' height='h-[20rem]' />
</div>
:
myOffersList?.data?.result_list && myOffersList?.data?.result_list.length > 0 ?
<MyOffersFamilyTable
familyOffers={myOffersList?.data?.result_list}
image_server={myOffersList?.data?.session_image_server}
className="mb-10"
/>
:
<div className='w-full h-[30rem] bg-white dark:bg-dark-white flex justify-center items-center rounded-2xl'>
<p className='text-black dark:text-white'>No Record Found!</p>
</div>
}
</Layout>
)
}
+25 -9
View File
@@ -19,7 +19,7 @@ export default function FamilyTable({
familyList, familyList,
loader, loader,
popUpHandler, popUpHandler,
imageServer imageServer,
}) { }) {
const navigate = useNavigate(); const navigate = useNavigate();
const [currentPage, setCurrentPage] = useState(0); const [currentPage, setCurrentPage] = useState(0);
@@ -55,14 +55,19 @@ export default function FamilyTable({
banner, banner,
enable_traking, enable_traking,
profile_picture, profile_picture,
imageServer imageServer,
username,
}) => { }) => {
// Check for valid dates // Check for valid dates
const addedDate = added ? added.split(" ")[0] : "N/A"; const addedDate = added ? added.split(" ")[0] : "N/A";
const loginDate = last_login ? formatDateString(last_login) : "N/A"; const loginDate = last_login ? formatDateString(last_login) : "N/A";
const key = `family-${family_uid}`; // Assign a unique key const key = `family-${family_uid}`; // Assign a unique key
const image = localStorage.getItem('session_token') ? `${imageServer}${localStorage.getItem('session_token')}/family/${family_uid}` : '' const image = localStorage.getItem("session_token")
? `${imageServer}${localStorage.getItem(
"session_token"
)}/family/${family_uid}`
: "";
const trackingStatus = const trackingStatus =
enable_traking === "0" enable_traking === "0"
? "Stopped" ? "Stopped"
@@ -80,14 +85,19 @@ export default function FamilyTable({
<div className="w-[60px] h-[60px] rounded-full overflow-hidden flex justify-center items-center"> <div className="w-[60px] h-[60px] rounded-full overflow-hidden flex justify-center items-center">
<img <img
// src={profile_picture} // src={profile_picture}
src={image || profile_picture || localImgLoad(`images/icons/${banner}`)} src={
image ||
profile_picture ||
localImgLoad(`images/icons/${banner}`)
}
alt={`Avatar of ${firstname} ${lastname}`} alt={`Avatar of ${firstname} ${lastname}`}
className="w-full h-full" className="w-full h-full"
/> />
</div> </div>
<div className="flex flex-col flex-[0.9]"> <div className="flex flex-col flex-[0.9]">
<h1 className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap"> <h1 className="font-bold text-lg text-dark-gray dark:text-white whitespace-nowrap">
{`${firstname} ${lastname} (${age < 10 ? `0${age}` : age})`} {`${firstname} ${lastname}`}{" "}
<span className="ml-1 text-sm">{`[${username}]`}</span>
</h1> </h1>
<span className="text-sm text-thin-light-gray"> <span className="text-sm text-thin-light-gray">
Added: <span className="text-purple ml-1">{addedDate}</span> Added: <span className="text-purple ml-1">{addedDate}</span>
@@ -136,7 +146,7 @@ export default function FamilyTable({
task_count, task_count,
family_uid, family_uid,
banner, banner,
image image,
}) })
} }
type="button" type="button"
@@ -186,7 +196,13 @@ export default function FamilyTable({
</thead> </thead>
<tbody className="h-full"> <tbody className="h-full">
{currentFamilyList?.map((familyMember, index) => { {currentFamilyList?.map((familyMember, index) => {
return <FamilyRow key={index} {...familyMember} imageServer={imageServer} />; return (
<FamilyRow
key={index}
{...familyMember}
imageServer={imageServer}
/>
);
})} })}
</tbody> </tbody>
</table> </table>
+314
View File
@@ -0,0 +1,314 @@
import React, {
Suspense,
lazy,
useEffect,
useMemo,
useRef,
useState,
} from "react";
import { useReactToPrint } from "react-to-print";
import localImgLoad from "../../lib/localImgLoad";
import usersService from "../../services/UsersService";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import AssignTaskPopout from "./FamilyPopout/AssignTaskPopout";
import FamilyWallet from "./Tabs/FamilyWallet";
import { apiConst } from "../../lib/apiConst";
// Lazy Imports for components
const FamilyWaitlist = lazy(() => import("./Tabs/FamilyWaitlist"));
const FamilyAccount = lazy(() => import("./Tabs/FamilyAccount"));
const FamilyProfile = lazy(() => import("./Tabs/FamilyProfile"));
const FamilyTasks = lazy(() => import("./Tabs/FamilyTasks"));
const FamilyPending = lazy(() => import("./Tabs/FamilyPending"));
export default function FamilyTableNew({
className,
accountDetails,
listReload,
loader,
}) {
// Initial state for family details
const initialDetailState = {
loading: false,
data: null,
};
// console.log('accountDetails',accountDetails)
// State for family details, tasks, waitlist, and pending
const [details, setDetails] = useState({
familyDetails: { ...initialDetailState },
familyTasks: { ...initialDetailState },
familyWaitList: { ...initialDetailState },
familyPending: { ...initialDetailState },
});
// Function to reset family details, tasks, waitlist, and pending
const resetDetails = () => {
setDetails({
familyDetails: { ...initialDetailState },
familyTasks: { ...initialDetailState },
familyWaitList: { ...initialDetailState },
familyPending: { ...initialDetailState },
});
};
const [updatePage, setUpdatePage] = useState(false) // State to determine when to update the page
// State for family task data
const [familyTask, setFamilyTask] = useState({ loading: false, data: [] });
// State for active task
const [activeTask, setActiveTask] = useState({ id: 0, data: {} });
// State for error messages
const [errMsg, setErrMsg] = useState("");
// State for family task popout
const [familyTaskPopout, setFamilyTaskPopout] = useState(false);
// Create an instance of the usersService class
const apiCall = useMemo(() => new usersService(), []);
// Function to handle toggling the family task popout
const familyPopUpHandler = () => {
setFamilyTaskPopout((prev) => !prev);
};
// Ref for the account section
const accountRef = useRef();
// React-to-Print hook for handling printing
const useHandlePrint = useReactToPrint({
content: () => accountRef.current,
});
// Array of tab names
const tabs = [
{ id: 1, name: "Tasks" },
{ id: 2, name: "Waiting" },
{ id: 3, name: "Pending" },
];
// State for the currently selected tab
const [tab, setTab] = useState(tabs[0].name);
// Function to handle tab changes
const tabHandler = (value) => {
setTab(value);
};
// Object that maps tab names to their corresponding components
const tabComponents = {
Tasks: (
<FamilyTasks
className={className}
loader={details.familyTasks.loading}
familyData={details.familyTasks.data}
accountDetails={accountDetails}
/>
),
Waiting: (
<FamilyWaitlist
familyData={details.familyWaitList.data}
accountDetails={accountDetails}
loader={details.familyWaitList.loading}
/>
),
Pending: (
<FamilyPending
familyData={details.familyPending.data}
accountDetails={accountDetails}
loader={details.familyPending.loading}
/>
),
Account: (
<FamilyAccount
familyData={details.familyDetails.data}
myRef={accountRef}
loader={details.familyDetails.loading}
handlePrint={useHandlePrint}
/>
),
Profile: <FamilyProfile familyData={details.familyDetails.data} />,
wallet: <FamilyWallet familyData={details.familyDetails.data} />,
};
// Default tab component
const defaultTabComponent = (
<FamilyTasks
className={className}
loader={details.familyTasks.loading}
familyData={details.familyTasks.data}
accountDetails={accountDetails}
/>
);
// Selected tab component based on the current 'tab'
const selectedTabComponent = tabComponents[tab] || defaultTabComponent;
// Effect to manage family details and related data
useEffect(() => {
const manageFamily = async () => {
try {
resetDetails();
setDetails({
familyDetails: { loading: true },
familyTasks: { loading: true },
familyWaitList: { loading: true },
familyPending: { loading: true },
});
const { family_uid } = accountDetails;
const reqData = { family_uid };
const [familyRes, tasksRes, familyWaitRes, familyPending] =
await Promise.all([
apiCall.ManageFamily(reqData),
apiCall.ManageTasks(reqData),
apiCall.ManageFamilyWaitlist(),
apiCall.ManageFamilyPending(),
]);
const familyData = familyRes.data;
const tasksData = tasksRes.data;
const familyWaitData = familyWaitRes.data;
const familyPendingData = familyPending.data;
// Function to check for errors in data
const checkDataError = (data) => data?.internal_return < 0;
if (
checkDataError(familyData) ||
checkDataError(tasksData) ||
checkDataError(familyWaitData) ||
checkDataError(familyPendingData)
) {
return;
}
setDetails({
familyDetails: { loading: false, data: familyData },
familyTasks: { loading: false, data: tasksData },
familyWaitList: { loading: false, data: familyWaitData },
familyPending: { loading: false, data: familyPendingData },
});
} catch (error) {
resetDetails();
setErrMsg("An error occurred");
throw new Error(error);
}
};
// Invoke the manageFamily function when the component mounts
manageFamily();
}, [updatePage]);
// Effect to manage family tasks
useEffect(() => {
let checkFamilyTask = true;
const reqData = {
limit: 30,
offset: 0,
job_type: "FAMILY",
action: apiConst.WRENCHBOARD_PICTURE_FAMMEMBER,
};
if (checkFamilyTask) {
setFamilyTask({ loading: true });
apiCall
.getMyJobList(reqData)
.then((res) => {
setFamilyTask({ loading: false, data: res?.data?.result_list });
if (res?.data?.result_list?.length) {
setActiveTask((prev) => ({
...prev,
data: res?.data?.result_list[0],
}));
}
})
.catch((err) => {
setFamilyTask({ loading: false, data: [] });
console.log("Error", err);
});
}
// Cleanup function to prevent memory leaks
return () => {
checkFamilyTask = false;
};
}, []);
return (
<div
className={`w-full bg-white dark:bg-dark-white overflow-y-auto rounded-2xl section-shadow h-full ${
className || ""
}`}
>
<div className="relative w-full sm:rounded-lg overflow-x-auto">
<Suspense
fallback={
<div className="h-full min-h-[609px] w-full overflow-hidden flex justify-center items-center">
<LoadingSpinner size="16" color="sky-blue" />
</div>
}
>
<div className="w-full h-full text-sm text-left text-gray-500 dark:text-gray-400 relative grid grid-cols-3 min-h-[575px]">
<div className="col-span-3 h-full w-full">
<div className="flex flex-col w-full">
<div className="w-full pr-8 flex items-center gap-1 border-b border-b-[#FAFAF]">
<ul className="flex gap-2 items-center w-full">
{tabs.map(({ name, id }) => (
<li
onClick={() => tabHandler(name)}
className={`p-4 flex hover:text-purple transition-all ease-in-out items-center cursor-pointer overflow-hidden text-xl relative top-[2px] ${
tab === name
? "text-purple border-r"
: "text-thin-light-gray"
}`}
key={id}
>
<h1>{name}</h1>
</li>
))}
</ul>
<button
type="button"
onClick={familyPopUpHandler}
className="p-1 my-1 w-[100px] flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
Add task
</button>
</div>
<div className="flex-[0.9] h-full">
<div className="h-full relative overflow-y-auto">
<Suspense
fallback={<LoadingSpinner size="16" color="sky-blue" />}
>
{selectedTabComponent}
</Suspense>
</div>
</div>
</div>
</div>
</div>
</Suspense>
</div>
{familyTaskPopout && (
<AssignTaskPopout
action={familyPopUpHandler}
situation={familyTaskPopout}
familyTask={familyTask}
setFamilyTask={setFamilyTask}
setActiveTask={setActiveTask}
activeTask={activeTask}
familyDetailsData={details.familyDetails.data}
setUpdatePage={setUpdatePage}
/>
)}
</div>
);
}
@@ -0,0 +1,12 @@
import React from 'react'
import Layout from '../Partials/Layout'
import ParentWaiting from '../MyOffers/ParentWaiting'
export default function ParentWaitingLayout() {
return (
<Layout>
<ParentWaiting />
</Layout>
)
}
+51 -25
View File
@@ -7,11 +7,13 @@ import React, {
} from "react"; } from "react";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import usersService from "../../services/UsersService"; import usersService from "../../services/UsersService";
import Icons from "../Helpers/Icons";
import InputCom from "../Helpers/Inputs/InputCom"; import InputCom from "../Helpers/Inputs/InputCom";
import ModalCom from "../Helpers/ModalCom"; import ModalCom from "../Helpers/ModalCom";
import Layout from "../Partials/Layout"; import Layout from "../Partials/Layout";
import LoadingSpinner from "../Spinners/LoadingSpinner"; import LoadingSpinner from "../Spinners/LoadingSpinner";
import FamilyTable from "./FamilyTable"; import FamilyTable from "./FamilyTable";
import CustomBreadcrumb from "../Breadcrumb/CustomBreadcrumb";
export default function FamilyAcc() { export default function FamilyAcc() {
// State to store the selected year and month // State to store the selected year and month
@@ -136,7 +138,18 @@ export default function FamilyAcc() {
<div className="sm:flex justify-between items-center mb-6"> <div className="sm:flex justify-between items-center mb-6">
<div className="mb-5 sm:mb-0"> <div className="mb-5 sm:mb-0">
<h1 className="text-26 font-bold inline-flex gap-3 text-dark-gray dark:text-white items-center"> <h1 className="text-26 font-bold inline-flex gap-3 text-dark-gray dark:text-white items-center">
<span className={``}>Family Accounts</span> {/* <span className={``}>Family Accounts</span> */}
<div className="mb-5">
<CustomBreadcrumb
title = {'Family Account'}
breadcrumb={
[
{ link: "/", title: "Home" },
{ link: "/acc-family", title: "Family-acc", active: true},
]
}
/>
</div>
{familyList?.result_list?.length < {familyList?.result_list?.length <
process.env.REACT_APP_MAX_FAMILY_MEMBERS && process.env.REACT_APP_MAX_FAMILY_MEMBERS &&
!loader && ( !loader && (
@@ -150,31 +163,44 @@ export default function FamilyAcc() {
)} )}
</h1> </h1>
</div> </div>
<Link
to={`/familysettings`} <div className="flex gap-2 items-center">
state={{ imageServer: familyList?.session_image_server }} <Link to="/acc-family/activities" className={`nav-item flex items-center `}>
className="slider-btns flex space-x-4 w-12 h-12 rounded-md shadow-sm justify-center items-center cursor-pointer dark:bg-[linear-gradient(134.38deg,#f539f8_0%,#c342f9_43.55%,#5356fb_104.51%)]" <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="pending-job" />
<svg </span>
xmlns="http://www.w3.org/2000/svg" <span
fill="none" className={`item-content relative group-hover:text-purple text-[18px] transition-all duration-300 ease-in-out text-lighter-gray font-medium`}
viewBox="0 0 24 24" >
strokeWidth={1.5} Activities
stroke="currentColor" </span>
className="w-6 h-6 dark:stroke-white" </Link>
<Link
to={`/familysettings`}
state={{ imageServer: familyList?.session_image_server }}
className="slider-btns flex space-x-4 w-12 h-12 rounded-md shadow-sm justify-center items-center cursor-pointer dark:bg-[linear-gradient(134.38deg,#f539f8_0%,#c342f9_43.55%,#5356fb_104.51%)]"
> >
<path <svg
strokeLinecap="round" xmlns="http://www.w3.org/2000/svg"
strokeLinejoin="round" fill="none"
d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 011.37.49l1.296 2.247a1.125 1.125 0 01-.26 1.431l-1.003.827c-.293.24-.438.613-.431.992a6.759 6.759 0 010 .255c-.007.378.138.75.43.99l1.005.828c.424.35.534.954.26 1.43l-1.298 2.247a1.125 1.125 0 01-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.57 6.57 0 01-.22.128c-.331.183-.581.495-.644.869l-.213 1.28c-.09.543-.56.941-1.11.941h-2.594c-.55 0-1.02-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 01-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 01-1.369-.49l-1.297-2.247a1.125 1.125 0 01.26-1.431l1.004-.827c.292-.24.437-.613.43-.992a6.932 6.932 0 010-.255c.007-.378-.138-.75-.43-.99l-1.004-.828a1.125 1.125 0 01-.26-1.43l1.297-2.247a1.125 1.125 0 011.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.087.22-.128.332-.183.582-.495.644-.869l.214-1.281z" viewBox="0 0 24 24"
/> strokeWidth={1.5}
<path stroke="currentColor"
strokeLinecap="round" className="w-6 h-6 dark:stroke-white"
strokeLinejoin="round" >
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" <path
/> strokeLinecap="round"
</svg> strokeLinejoin="round"
</Link> d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 011.37.49l1.296 2.247a1.125 1.125 0 01-.26 1.431l-1.003.827c-.293.24-.438.613-.431.992a6.759 6.759 0 010 .255c-.007.378.138.75.43.99l1.005.828c.424.35.534.954.26 1.43l-1.298 2.247a1.125 1.125 0 01-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.57 6.57 0 01-.22.128c-.331.183-.581.495-.644.869l-.213 1.28c-.09.543-.56.941-1.11.941h-2.594c-.55 0-1.02-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 01-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 01-1.369-.49l-1.297-2.247a1.125 1.125 0 01.26-1.431l1.004-.827c.292-.24.437-.613.43-.992a6.932 6.932 0 010-.255c.007-.378-.138-.75-.43-.99l-1.004-.828a1.125 1.125 0 01-.26-1.43l1.297-2.247a1.125 1.125 0 011.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.087.22-.128.332-.183.582-.495.644-.869l.214-1.281z"
/>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
/>
</svg>
</Link>
</div>
</div> </div>
<Suspense fallback={<LoadingSpinner color="sky-blue" size="16" />}> <Suspense fallback={<LoadingSpinner color="sky-blue" size="16" />}>
<FamilyTable <FamilyTable
@@ -14,6 +14,7 @@ export default function InputCom({
forgotPassword, forgotPassword,
parentClass, parentClass,
labelClass, labelClass,
labalClass,
inputClass, inputClass,
fieldClass, fieldClass,
onClick, onClick,
@@ -53,7 +54,7 @@ export default function InputCom({
<div className={`flex items-center justify-between mb-2.5 ${labelClass}`}> <div className={`flex items-center justify-between mb-2.5 ${labelClass}`}>
{label && ( {label && (
<label <label
className="input-label text-[#181c32] text-[13.975px] leading-[20.9625px] font-semibold flex items-center gap-1" className={`input-label text-[#181c32] text-[13.975px] leading-[20.9625px] font-semibold flex items-center gap-1 ${labalClass}`}
htmlFor={name} htmlFor={name}
> >
{label} {label}
+37 -62
View File
@@ -1,20 +1,20 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import usersService from "../../services/UsersService"; import usersService from "../../services/UsersService";
import ParentWaiting from "../MyOffers/ParentWaiting";
import MyOffersFamilyTable from "../MyTasks/MyOffersFamilyTable"; import MyOffersFamilyTable from "../MyTasks/MyOffersFamilyTable";
import FamilyActiveLSlde from "./FamilyActiveLSlde"; import FamilyActiveLSlde from "./FamilyActiveLSlde";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { tableReload } from "../../store/TableReloads"; import { tableReload } from "../../store/TableReloads";
import LoadingSpinner from "../Spinners/LoadingSpinner";
export default function FamilyDash({ familyOffers, MyActiveJobList }) { export default function FamilyDash({ MyActiveJobList=[], serverImg }) {
// console.log("PROPS IN FAMILY DASH->", familyOffers?.result_list); // console.log("PROPS IN FAMILY DASH->", familyOffers?.result_list);
const dispatch = useDispatch(); const dispatch = useDispatch();
const userApi = new usersService(); const userApi = new usersService();
const trending = MyActiveJobList; // const trending = MyActiveJobList;
const { familyBannersList } = useSelector((state) => state.familyBannersList); const { familyBannersList } = useSelector((state) => state.familyBannersList);
@@ -24,25 +24,6 @@ export default function FamilyDash({ familyOffers, MyActiveJobList }) {
let [reloadBanner, setReloadBanner] = useState(0) let [reloadBanner, setReloadBanner] = useState(0)
// DO NOT UNCOMMENT THE CODE BELOW
// let [familyBannersList, setFamilyBannersList] = useState({loading:false, result:{}})
// const getFamilyBanners = async () => { // FUNCTION TO GET FAMILY BANNERS
// setFamilyBannersList({loading:true, result:[]});
// try {
// const res = await userApi.getFamilyBannersList();
// setFamilyBannersList({loading:false, result:res.data});
// console.log('TEST RESPONSE', res.data)
// } catch (error) {
// setFamilyBannersList({loading:false, result:[]});
// console.log("Error getting tasks");
// }
// };
// useEffect(()=>{
// getFamilyBanners()
// },[])
useEffect(()=>{ useEffect(()=>{
if(reloadBanner >= 2){ if(reloadBanner >= 2){
dispatch(tableReload({ type: "FAMILYBANNERSLIST" })); // RELOAD FAMILY BANNERS LIST EVERY 10 MINS dispatch(tableReload({ type: "FAMILYBANNERSLIST" })); // RELOAD FAMILY BANNERS LIST EVERY 10 MINS
@@ -60,53 +41,51 @@ export default function FamilyDash({ familyOffers, MyActiveJobList }) {
return ( return (
<div> <div>
<div className="home-page-wrapper"> <div className="home-page-wrapper">
{/* <CommonHead commonHeadData={props.commonHeadData} /> */}
{/* Header */} {/* Header */}
<div className="text-white mb-4 p-2 w-full rounded-xl bg-sky-blue place-content-center"> <div className="text-white mb-4 min-h-[3rem] px-2 w-full flex justify-between items-center rounded-xl bg-family-header-bg">
<div className="w-full flex flex-wrap gap-x-4"> <div className="w-full">
<p className="text-lg font-normal">Welcome</p> <div className="w-full flex flex-wrap gap-x-4 ">
<div className=""> <p className="text-lg font-normal leading-5">Welcome</p>
<h1 className="text-lg font-normal">{`${userDetails?.firstname} ${userDetails?.lastname}`}</h1> <div className="">
<h1 className="text-lg font-normal leading-5">{`${userDetails?.firstname} ${userDetails?.lastname}`}</h1>
</div>
</div> </div>
</div> </div>
<div className="w-full text-sm flex justify-end items-end"> <div className="py-1 w-full text-sm text-right self-end">
<p>Last Login: {`${userDetails?.last_login.split(' ')[0]}`}</p> <p className="leading-4">Last Login: {`${userDetails?.last_login.split(' ')[0]}`}</p>
</div> </div>
</div> </div>
{process.env.REACT_APP_SHOW_NEW_FAMILY_DASH == '1' && {process.env.REACT_APP_SHOW_NEW_FAMILY_DASH == '1' &&
<> <>
{familyBannersList?.result_list && Object.keys(familyBannersList?.result_list).length > 0 && {familyBannersList?.loading ?
<div className="w-full bg-white rounded-2xl">
<LoadingSpinner size='10' color='sky-blue' height='h-[20rem]' />
</div>
:
familyBannersList?.result_list && Object.keys(familyBannersList?.result_list).length > 0 ?
// Loop for Family Banners // Loop for Family Banners
<div className="w-full mb-4 grid grid-cols-2 md:grid-cols-3 gap-2 md:gap-4"> <div className="w-full mb-4 grid grid-cols-2 md:grid-cols-3 gap-2 md:gap-4">
{Object.keys(familyBannersList?.result_list).map((item, index) => { {Object.keys(familyBannersList?.result_list).map((item, index) => {
let content = familyBannersList?.result_list[item] let content = familyBannersList?.result_list[item]
let action = item == 'recommend' ? 'familymarket' : 'mytask' // let action = item == 'recommend' ? 'familymarket' : 'mytask'
return ( return (
<Link key={item} to={`/${action}`} className={`rounded-xl bg-white dark:bg-dark-white shadow-md flex justify-center items-center transition-all duration-300 hover:shadow-sm`}> <Link key={item} to={`/${content.banner.action}`} className={`rounded-xl bg-white dark:bg-dark-white shadow-md flex justify-center items-center transition-all duration-300 hover:shadow-sm`}>
<div className="h-full w-full"> <div className="h-full w-full">
<img className="w-full h-[10rem] object-cover object-left rounded-t-xl" src={content.banner.image} alt='banner image' /> <img className="w-full h-[10rem] object-cover rounded-t-xl" src={content.banner.image} alt='banner image' />
<div className="flex flex-col justify-between"> <div className="flex flex-col justify-between">
<div className="px-2 py-2 border-b border-transparent min-h-[4rem] flex flex-col gap-1"> <div className="px-2 py-2 border-b border-transparent min-h-[4rem] flex flex-col gap-1">
<h1 className="text-lg text-[#083e21] dark:text-white font-bold tracking-wide">{content.banner.text}</h1> <h1 className="text-lg text-[#083e21] dark:text-white font-bold tracking-wide">{content.banner.text}</h1>
<p className="text-sm text-black dark:text-white">{content.banner.description}</p> <p className="text-sm text-black dark:text-white">{content.banner.description}</p>
</div> </div>
{/* <div className="px-2 py-1 flex justify-between items-center">
<span className="text-slate-400 dark:text-slate-200 text-sm">6w ago</span>
<div className="flex justify-center gap-1">
<div className="w-1 h-1 bg-slate-400 rounded-full"></div>
<div className="w-1 h-1 bg-slate-400 rounded-full"></div>
<div className="w-1 h-1 bg-slate-400 rounded-full"></div>
</div>
</div> */}
</div> </div>
</div> </div>
</Link> </Link>
) )
})} })}
</div> </div>
:
null
} }
{tab_categories?.data && {tab_categories?.data &&
@@ -114,19 +93,17 @@ export default function FamilyDash({ familyOffers, MyActiveJobList }) {
<h1 className="my-4 text-26 font-bold text-dark-gray dark:text-white tracking-wide">Resources</h1> <h1 className="my-4 text-26 font-bold text-dark-gray dark:text-white tracking-wide">Resources</h1>
<div className="w-full grid grid-cols-2 md:grid-cols-4 gap-2 md:gap-4"> <div className="w-full grid grid-cols-2 md:grid-cols-4 gap-2 md:gap-4">
{tab_categories.data.map((item) => { {tab_categories.data.map((item) => {
if(item.enabled){ // if(item.enabled){
// }
return ( return (
<Link key={item.uid} to={item?.action} className={`rounded-xl bg-white dark:bg-dark-white shadow-md flex justify-center items-center transition-all duration-300 hover:shadow-sm`}> <Link key={item.uid} to={`/${item?.action}`} className={`group rounded-xl bg-white dark:bg-dark-white shadow-md flex justify-center items-center transition-all duration-300 hover:shadow-sm`}>
<div className="h-full w-full"> <div className="h-full w-full">
<img className="w-full h-[12rem] object-cover rounded-t-xl" src={item?.banner} alt='banner image' /> <div className="w-full h-[8rem] rounded-t-xl overflow-hidden">
<img className="w-full h-full group-hover:scale-110 object-cover transition-all duration-300" src={item?.banner} alt='banner image' />
</div>
<div className="flex flex-col justify-between"> <div className="flex flex-col justify-between">
<div className="px-2 py-1 border-b border-slate-300 min-h-[5rem] flex flex-col gap-1"> <div className="px-2 py-1 border-b border-transparent min-h-[2rem] flex justify-between items-center gap-1">
<h1 className="text-lg text-[#083e21] dark:text-white font-bold tracking-wide">{item?.content}</h1> <h1 className="text-lg text-[#083e21] dark:text-white font-bold tracking-wide">{item?.content}</h1>
{/* <p className="text-sm text-black dark:text-white">{'Description'}</p> */}
</div>
<div className="px-2 py-1 flex justify-between items-center">
<span className="text-slate-400 dark:text-slate-200 text-sm">6w ago</span>
<div className="flex justify-center gap-1"> <div className="flex justify-center gap-1">
<div className="w-1 h-1 bg-slate-400 rounded-full"></div> <div className="w-1 h-1 bg-slate-400 rounded-full"></div>
<div className="w-1 h-1 bg-slate-400 rounded-full"></div> <div className="w-1 h-1 bg-slate-400 rounded-full"></div>
@@ -136,7 +113,7 @@ export default function FamilyDash({ familyOffers, MyActiveJobList }) {
</div> </div>
</div> </div>
</Link> </Link>
)} )
})} })}
</div> </div>
</div> </div>
@@ -144,23 +121,21 @@ export default function FamilyDash({ familyOffers, MyActiveJobList }) {
</> </>
} }
{familyOffers?.result_list && familyOffers?.result_list.length > 0 && ( {/* {familyOffers?.result_list && familyOffers?.result_list.length > 0 && (
<MyOffersFamilyTable <MyOffersFamilyTable
familyOffers={familyOffers?.result_list} familyOffers={familyOffers?.result_list}
image_server={familyOffers?.session_image_server} image_server={familyOffers?.session_image_server}
className="mb-10" className="mb-10"
/> />
)} )} */}
{trending && trending.length > 0 && (
{/* {trending && trending.length > 0 && (
<FamilyActiveLSlde <FamilyActiveLSlde
trending={trending} trending={trending}
className="mb-10" className="mb-10"
image_server={familyOffers?.session_image_server} image_server={serverImg}
/> />
)} )} */}
{/*<TopSellerTopBuyerSliderSection className="mb-10" />*/}
<ParentWaiting className="mb-10" />
</div> </div>
</div> </div>
); );
+10 -19
View File
@@ -8,8 +8,6 @@ import {
} from "../Dashboards"; } from "../Dashboards";
import MyJobTable from "../MyTasks/MyJobTable"; import MyJobTable from "../MyTasks/MyJobTable";
import MyOffersTable from "../MyTasks/MyOffersTable"; import MyOffersTable from "../MyTasks/MyOffersTable";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import HomeActivities from "./HomeActivities";
export default function FullAccountDash(props) { export default function FullAccountDash(props) {
// console.log("PROPS IN HOME->", props); // console.log("PROPS IN HOME->", props);
@@ -86,24 +84,17 @@ export default function FullAccountDash(props) {
imageServer={props.offersList?.data?.session_image_server} imageServer={props.offersList?.data?.session_image_server}
/> />
</> </>
) : !props.offersList?.loading && !props.MyActiveJobList?.loading ? ( ) : null}
<HomeActivities className="mb-10" />
) : (
<div className="w-full h-[220px] flex items-center justify-center">
<LoadingSpinner size="16" color="sky-blue" />
</div>
)}
{/*<UpdateTable className="mb-10"/>*/}
{/*<SellHistoryMarketVisitorAnalytic className="mb-10"/>*/}
{/*<TopSellerTopBuyerSliderSection className="mb-10" />*/}
{/*<HomeTaskDisplay*/}
{/* jobData={jobData}*/}
{/* className="mb-10"*/}
{/* bannerList={props.bannerList}*/}
{/*/>*/}
</div> </div>
</> </>
); );
} }
// : !props.offersList?.loading && !props.MyActiveJobList?.loading ? (
// <HomeActivities className="mb-10" />
// )
// : (
// <div className="w-full h-[220px] flex items-center justify-center">
// <LoadingSpinner size="16" color="sky-blue" />
// </div>
// )
+1 -1
View File
@@ -53,7 +53,7 @@ export default function HomeActivities({ className }) {
return ( return (
<div <div
className={`update-table w-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow relative min-h-[520px] ${ className={`update-table w-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl relative min-h-[520px] ${
className || "" className || ""
}`} }`}
> >
+7 -27
View File
@@ -58,14 +58,11 @@ export default function Home(props) {
useEffect(() => { useEffect(() => {
const fetchData = async () => { const fetchData = async () => {
await Promise.all([getHomeDate(), getMyOffersList()]); await Promise.all([getHomeDate(), getMyOffersList(), getMyActiveJobList()]);
}; };
if(userDetails?.account_type == 'FULL'){
fetchData(); fetchData();
}, []); }
useEffect(() => {
getMyActiveJobList();
}, []); }, []);
return ( return (
@@ -75,8 +72,9 @@ export default function Home(props) {
<FamilyDash <FamilyDash
account={userDetails} account={userDetails}
commonHeadData={props.bannerList} commonHeadData={props.bannerList}
familyOffers={MyOffersList?.data} // familyOffers={MyOffersList?.data}
MyActiveJobList={MyActiveJobList?.data} serverImg = {userDetails?.session_image_server}
// MyActiveJobList={MyActiveJobList?.data}
/> />
) : userDetails && userDetails?.account_type == "FULL" ? ( ) : userDetails && userDetails?.account_type == "FULL" ? (
<FullAccountDash <FullAccountDash
@@ -95,21 +93,3 @@ export default function Home(props) {
</Layout> </Layout>
); );
} }
// /*
// <Layout>
// <div className="home-page-wrapper">
// <Hero className="mb-10" data={userDetails} />
// {/* <CreateNft />
// <TrendingSection trending={trending} className="mb-10" />*/}
// <HomeTaskDisplay
// jobData={jobData}
// className="mb-10"
// bannerList={props.bannerList}
// />
{
/* <SellHistoryMarketVisitorAnalytic className="mb-10"/>
<TopSellerTopBuyerSliderSection className="mb-10" />
<UpdateTable className="mb-10"/>*/
}
// </div>
// </Layout>
+2 -1
View File
@@ -229,12 +229,13 @@ export default function MemberList({
// iconName="message" // iconName="message"
/> />
</div> </div>
<div className="input-item w-full sm:w-[150%]"> <div className="input-item w-full">
<InputCom <InputCom
labelClass="tracking-wider" labelClass="tracking-wider"
fieldClass="sm:px-6 px-2" fieldClass="sm:px-6 px-2"
value={fields.email} value={fields.email}
inputHandler={handleFieldsChange} inputHandler={handleFieldsChange}
inputClass="xl:w-[16rem] 2xl:w-full"
placeholder="Email" placeholder="Email"
// label="Email" // label="Email"
name="email" name="email"
+1 -1
View File
@@ -18,7 +18,7 @@ export default function MainSection({
); );
const [tab, setTab] = useState(Object.keys(marketCategories)[0]); const [tab, setTab] = useState(Object.keys(marketCategories)[0]);
let [contentDisplay, setContentDisplay] = useState("grid"); // STATE TO HOLD LIST VIEW STYLE let [contentDisplay, setContentDisplay] = useState("list"); // STATE TO HOLD LIST VIEW STYLE
// Convert to array in order to map // Convert to array in order to map
const mappedArray = Object.entries(marketCategories).map(([key, value]) => { const mappedArray = Object.entries(marketCategories).map(([key, value]) => {
+12
View File
@@ -2,6 +2,7 @@ import { useSelector } from "react-redux";
import Layout from "../Partials/Layout"; import Layout from "../Partials/Layout";
import CommonHead from "../UserHeader/CommonHead"; import CommonHead from "../UserHeader/CommonHead";
import MainSection from "./MainSection"; import MainSection from "./MainSection";
import CustomBreadcrumb from "../Breadcrumb/CustomBreadcrumb";
export default function MarketPlace({ commonHeadData }) { export default function MarketPlace({ commonHeadData }) {
let { jobLists } = useSelector((state) => state.jobLists); let { jobLists } = useSelector((state) => state.jobLists);
@@ -13,6 +14,17 @@ export default function MarketPlace({ commonHeadData }) {
<> <>
<Layout> <Layout>
<CommonHead commonHeadData={commonHeadData} /> <CommonHead commonHeadData={commonHeadData} />
<div className="mb-5">
<CustomBreadcrumb
title = {'Market'}
breadcrumb={
[
{ link: "/", title: "Home" },
{ link: "/market", title: "Market", active: true},
]
}
/>
</div>
<MainSection <MainSection
marketPlaceProduct={marketData} marketPlaceProduct={marketData}
categories={categories} categories={categories}
@@ -20,7 +20,7 @@ export default function ActiveJobMessage({ activeJobMesList }) {
return ( return (
<div className='flex flex-col justify-between'> <div className='flex flex-col justify-between'>
<div className="w-full min-h-[450px] max-h-[450px] overflow-y-scroll"> <div className="w-full h-full min-h-[400px] max-h-[400px] overflow-y-auto">
<table className="wallet-activity w-full table-auto border-collapse text-left"> <table className="wallet-activity w-full table-auto border-collapse text-left">
<thead className='border-b-2'> <thead className='border-b-2'>
<tr className='text-slate-600'> <tr className='text-slate-600'>
+14 -7
View File
@@ -286,7 +286,7 @@ function ActiveJobs(props) {
<path d="M19 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H19v-2z" /> <path d="M19 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H19v-2z" />
</svg> </svg>
</button> </button>
<h1 className="text-xl lg:text-2xl font-bold text-dark-gray dark:text-white tracking-wide"> <h1 className="text-[20px] font-bold text-dark-gray dark:text-white tracking-wide">
{props.details?.title && props.details.title} {props.details?.title && props.details.title}
</h1> </h1>
</div> </div>
@@ -412,7 +412,7 @@ function ActiveJobs(props) {
</div> </div>
{tab == "message" ? ( {tab == "message" ? (
<textarea <textarea
className="p-4 w-full h-[300px] text-base text-slate-600 dark:text-white bg-white dark:bg-black border border-slate-300 outline-none" className="p-4 w-full h-[200px] text-base text-slate-600 dark:text-white bg-white dark:bg-black border border-slate-300 outline-none"
// rows="10" // rows="10"
style={{ resize: "none" }} style={{ resize: "none" }}
name="message" name="message"
@@ -421,7 +421,7 @@ function ActiveJobs(props) {
autoFocus autoFocus
/> />
) : ( ) : (
<div className="p-4 w-full h-[300px] text-base text-slate-600 border border-slate-300"> <div className="p-4 w-full h-[200px] text-base text-slate-600 border border-slate-300">
<div className="files"> <div className="files">
<label <label
htmlFor="file" htmlFor="file"
@@ -535,16 +535,23 @@ function ActiveJobs(props) {
{/* MESSAGE SECTION */} {/* MESSAGE SECTION */}
<div className="w-full lg:w-1/2"> <div className="w-full lg:w-1/2">
<div className="flex justify-between items-center gap-5"> <div className="flex justify-between items-center gap-5">
<p className="text-lg font-bold text-dark-gray dark:text-white tracking-wide"> <p className="w-full text-lg font-bold text-dark-gray dark:text-white tracking-wide flex items-center gap-2">
Message <span>Message</span>
<button
type="button"
onClick={popUpHandler}
className="text-[12px] tracking-wider text-emerald-600 dark:text-emerald-300"
>
View all
</button>
</p> </p>
<button {/* <button
type="button" type="button"
onClick={popUpHandler} onClick={popUpHandler}
className="btn-gradient text-base tracking-wide px-4 py-2 rounded-full text-white cursor-pointer flex justify-center items-center" className="btn-gradient text-base tracking-wide px-4 py-2 rounded-full text-white cursor-pointer flex justify-center items-center"
> >
View all View all
</button> </button> */}
</div> </div>
{props.activeJobMesList.loading ? ( {props.activeJobMesList.loading ? (
<LoadingSpinner size="16" color="sky-blue" /> <LoadingSpinner size="16" color="sky-blue" />
@@ -13,13 +13,6 @@ function CurrentJobAction() {
<div> <div>
Waiting for the completion message from the client before you can approve. Waiting for the completion message from the client before you can approve.
</div> </div>
{/*<div className="flex flex-col flex-[0.9]"> </div>*/}
</div>
</td>
<td className="text-right py-4 px-2">
<div className="flex justify-center items-center">
.
</div> </div>
</td> </td>
</tr> </tr>
@@ -112,7 +112,7 @@ function ReviewJobAction({jobDetails}) {
<tr> <tr>
<td> <td>
<div className="flex justify-center items-center"> <div className="flex justify-center items-center">
<button type="button" onClick={popUpHandler} className="w-[150px] h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"> <button type="button" onClick={popUpHandler} className="w-[130px] h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white">
Reject or Accept Reject or Accept
</button> </button>
</div> </div>
@@ -0,0 +1,153 @@
import React, { useState } from "react";
import { useLocation, useNavigate } from "react-router-dom";
import { PriceFormatter } from "../Helpers/PriceFormatter";
import { handlePagingFunc } from "../Pagination/HandlePagination";
import PaginatedList from "../Pagination/PaginatedList";
export default function MyPastDueTaskTable({ MyJobList, className }) {
const navigate = useNavigate();
let { pathname } = useLocation();
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-3 sm: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>
{
<>
{MyJobList &&
MyJobList?.result_list &&
MyJobList.result_list.length > 0 ? (
currentActiveJobList.map((value, index) => {
let deliveryDate = value?.delivery_date?.split(" ")[0];
let thePrice = PriceFormatter(
value?.price * 0.01,
value?.currency_code,
value?.currency
);
let image = `${
MyJobList.session_image_server
}${localStorage.getItem("session_token")}/job/${
value.job_uid
}`;
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="max-w-[60px] max-h-[60px] min-w-[60px] min-h-[60px] p-2 bg-alice-blue rounded-full overflow-hidden flex justify-center items-center">
<img
src={image}
alt="data"
className="w-full h-full rounded-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 flext-start gap-1">
Price:{" "}
<span className="text-purple">
{thePrice}
</span>
</span>
<div className="flex flex-col sm:flex-row items-start gap-1 md:gap-4 md:items-center">
<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">
Due:{" "}
<span className="text-purple">
{" "}
{deliveryDate}
</span>
</span>
<span className="text-sm text-thin-light-gray">
Sent to:{" "}
<span className="text-purple">
{" "}
{value.job_to === null
? "public"
: value.job_to}
</span>
</span>
</div>
</div>
</div>
</td>
<td className="text-right py-4 px-2">
<div className="flex justify-center items-center">
<button
type="button"
onClick={() => {
navigate("/manage-active-job", {
state: { ...value, pathname },
});
}}
className="px-4 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
{value.owner_status == "OWNER"
? "Review"
: "Send Updates"}
</button>
</div>
</td>
</tr>
);
})
) : (
<tr className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
<td className="p-2">No Past Due 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>
)}
</div>
);
}
@@ -0,0 +1,57 @@
import React, { useState } from "react";
import { Link } from "react-router-dom";
import Layout from "../Partials/Layout";
import CommonHead from "../UserHeader/CommonHead";
import MyPastDueTaskTable from "./MyPastDueTaskTable";
import CustomBreadcrumb from "../Breadcrumb/CustomBreadcrumb";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import { useSelector } from "react-redux";
export default function MyPastDueTasks(props) {
const { userDetails: { account_type } } = useSelector((state) => state?.userDetails); // Gets user details
return (
<Layout>
{account_type == 'FULL' &&
<CommonHead commonHeadData={props.commonHeadData} />
}
<div className="notification-page w-full mb-10">
<div className="notification-wrapper w-full">
{/* heading */}
{account_type == 'FULL' ?
<div className="sm:flex justify-between items-center mb-6">
<div className="mb-5 sm:mb-0">
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
<span
>
Past Due Task(s)
</span>
</h1>
</div>
</div>
:
<div className="mb-5">
<CustomBreadcrumb
title = {'Past Due Task(s)'}
breadcrumb={
[
{ link: "/", title: "Home" },
{ link: "/pastdue", title: "Past Due", active: true},
]
}
/>
</div>
}
{props.loading ?
<div className="w-full flex justify-center items-center bg-white rounded-2xl">
<LoadingSpinner size='10' color='sky-blue' height='h-[20rem]' />
</div>
:
<MyPastDueTaskTable MyJobList={props.MyJobList} />
}
</div>
</div>
</Layout>
);
}
+19 -30
View File
@@ -3,6 +3,7 @@ import { Link } from "react-router-dom";
import { toast } from "react-toastify"; import { toast } from "react-toastify";
import activeAidsBanner from "../../assets/images/kids-waiting.jpg"; import activeAidsBanner from "../../assets/images/kids-waiting.jpg";
import ParentWaitingTable from "./ParentWaitingTable"; import ParentWaitingTable from "./ParentWaitingTable";
import CustomBreadcrumb from "../Breadcrumb/CustomBreadcrumb";
export default function ParentWaiting({ className }) { export default function ParentWaiting({ className }) {
const [addFavorite, setValue] = useState(false); const [addFavorite, setValue] = useState(false);
@@ -19,9 +20,20 @@ export default function ParentWaiting({ className }) {
<> <>
<div className={`overview-section w-full ${className || ""}`}> <div className={`overview-section w-full ${className || ""}`}>
<div className="w-full mb-3 flex justify-between items-center gap-1"> <div className="w-full mb-3 flex justify-between items-center gap-1">
<h1 className="text-26 font-bold text-dark-gray dark:text-white"> {/* <h1 className="text-26 font-bold text-dark-gray dark:text-white">
Waiting for Parent to Get Started... Waiting for Parent to Get Started...
</h1> </h1> */}
<CustomBreadcrumb
title = {'Waiting for Parent to Get Started...'}
breadcrumb={
[
{ link: "/", title: "Home" },
{ link: "/suggested", title: "Suggested", active: true},
]
}
/>
<Link <Link
to='/familymarket' to='/familymarket'
className="px-4 h-10 flex justify-center items-center btn-gradient text-base rounded-full text-white" className="px-4 h-10 flex justify-center items-center btn-gradient text-base rounded-full text-white"
@@ -31,40 +43,17 @@ export default function ParentWaiting({ className }) {
</div> </div>
{/* <div className="overview-section-wrapper py-2 min-h-[450px] lg:flex lg:space-x-2 flex-1 lg:gap-8"> */} {/* <div className="overview-section-wrapper py-2 min-h-[450px] lg:flex lg:space-x-2 flex-1 lg:gap-8"> */}
<div className="overview-section-wrapper py-2 min-h-[400px] lg:grid grid-cols-2 gap-4"> <div className="overview-section-wrapper py-2 min-h-[400px] lg:grid grid-cols-2 gap-4">
<div className="mb-10 lg:mb-0 h-full w-full bg-white dark:bg-dark-white rounded-2xl overflow-hidden"> <div className="overview-countdown mb-10 lg:mb-0 h-full w-full flex flex-col justify-between p-4 rounded-2xl bg-white dark:bg-dark-white">
{<ParentWaitingTable />}
</div>
<div className="h-full w-full bg-white dark:bg-dark-white rounded-2xl overflow-hidden">
<img <img
src={activeAidsBanner} src={activeAidsBanner}
alt="banner" alt="banner"
className="w-full h-full" className="w-full h-full"
/> />
</div> </div>
<div className="overview-countdown h-full w-full flex flex-col justify-between p-4 rounded-2xl bg-white dark:bg-dark-white">
{<ParentWaitingTable />}
{/* <div className="lg:mb-0 mb-3">*/}
{/* <h1 className="text-2xl font-bold text-dark-gray dark:text-white tracking-wide">*/}
{/* Lock and Lob x Fiesta Spurs*/}
{/* </h1>*/}
{/* <span className="text-[18px] font-thin tracking-wide text-dark-gray dark:text-white">*/}
{/* ID : 2320382*/}
{/*</span>*/}
{/* </div>*/}
{/* /!* user *!/*/}
{/* <div className="flex items-center space-x-3 lg:mb-0 mb-3">*/}
{/* <div className="w-14 h-14 flex justify-center items-center rounded-full overflow-hidden">*/}
{/* <img src={HeroUser} alt="" />*/}
{/* </div>*/}
{/* <div>*/}
{/* <p className="text-xl tracking-wide font-bold antise text-dark-gray dark:text-white">*/}
{/* Brokln Simons*/}
{/* </p>*/}
{/* <p className="text-sm tracking-wide text-dark-gray dark:text-white">*/}
{/* @broklinslam_75*/}
{/* </p>*/}
{/* </div>*/}
{/* </div>*/}
</div>
</div> </div>
</div> </div>
</> </>
+3 -3
View File
@@ -75,7 +75,7 @@ export default function MyTasks({
/> />
)} )}
<div className="w-full mb-5 flex justify-between items-center gap-1"> <div className="w-full mb-5 flex justify-between items-center gap-1">
{userDetails.account_type == 'FULL'? {/* {userDetails.account_type == 'FULL'?
<h1 className="text-26 font-bold text-dark-gray dark:text-white"> <h1 className="text-26 font-bold text-dark-gray dark:text-white">
<span <span
className={`${selectTab === "today" ? "block" : "hidden"}`} className={`${selectTab === "today" ? "block" : "hidden"}`}
@@ -83,7 +83,7 @@ export default function MyTasks({
My Tasks My Tasks
</span> </span>
</h1> </h1>
: : */}
<CustomBreadcrumb <CustomBreadcrumb
title = 'My Tasks' title = 'My Tasks'
breadcrumb={ breadcrumb={
@@ -93,7 +93,7 @@ export default function MyTasks({
] ]
} }
/> />
} {/* } */}
{ActiveJobList?.data?.length > 0 && userDetails.account_type == 'FAMILY' && {ActiveJobList?.data?.length > 0 && userDetails.account_type == 'FAMILY' &&
<button <button
+95
View File
@@ -0,0 +1,95 @@
import React, { Suspense, lazy, useEffect, useState } from "react";
import { useSelector } from "react-redux";
import usersService from "../../services/UsersService";
import Layout from "../Partials/Layout";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import CustomBreadcrumb from "../Breadcrumb/CustomBreadcrumb";
const FamilyWalletBox = lazy(() => import("./FamilyWalletBox"));
const FamilyWallet = () => {
const apiCall = new usersService();
const { walletDetails } = useSelector((state) => state?.walletDetails); // WALLET STORE
const { walletTable } = useSelector((state) => state.tableReload);
const [paymentHistory, setPaymentHistory] = useState({
loading: true,
data: [],
});
const [allCountries, setAllCountries] = useState({
// STATE TO HOLD LIST OF COUNTRIES
loading: true,
data: [],
});
const getPaymentHistory = () => {
apiCall
.getPaymentHx()
.then((res) => {
if (res.data.internal_return < 0) {
setPaymentHistory({ loading: false, data: [] });
} else {
setPaymentHistory({ loading: false, data: res.data?.result_list });
}
})
.catch(() => {
setPaymentHistory({ loading: false, data: [] });
});
};
// FUNCTION TO GET COUNTRIES
const getCountry = () => {
apiCall
.getSignupCountryData()
.then((res) => {
if (res?.data?.internal_return < 0) {
setAllCountries((prev) => ({ loading: false, data: [] }));
return;
}
setAllCountries((prev) => ({
loading: false,
data: res?.data?.result_list,
}));
})
.catch((error) => {
setAllCountries((prev) => ({ loading: false, data: [] }));
});
};
useEffect(() => {
getCountry();
getPaymentHistory();
}, [walletTable]);
console.log(
"Testing all country: ",
allCountries,
"Testing wallet: ",
walletDetails
);
return (
<Layout>
<div className='mb-4'>
<CustomBreadcrumb
title={'Wallet'}
breadcrumb = {
[
{ link: "/", title: "Home" },
{ link: '/family-wallet', title: 'Wallet', active: true},
]
}
/>
</div>
<Suspense fallback={<LoadingSpinner size="16" color="sky-blue" />}>
<FamilyWalletBox
wallet={walletDetails}
payment={paymentHistory}
countries={allCountries.data}
/>
</Suspense>
</Layout>
);
};
export default FamilyWallet;
@@ -0,0 +1,34 @@
import { useSelector } from "react-redux";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import WalletItemCard from "./WalletItemCard";
import WalletItemCardFamily from "./WalletItemCardFamily";
/**
* Renders a list of wallet items or a loading spinner depending on the state of the `wallet` object.
*/
export default function FamilyWalletBox({ wallet, payment, countries }) {
const { loading, data } = wallet;
const { userDetails } = useSelector((state) => state.userDetails);
const accountType = userDetails?.account_type === "FAMILY";
return (
<div className="my-wallet-wrapper w-full mb-10">
<div className="main-wrapper w-full">
<div className="balance-inquery w-auto grid sm:grid-cols-2 lg:grid-cols-2 xl:grid-cols-[repeat(auto-fill,_minmax(354px,_1fr))] min-[1440px]:grid-cols-[repeat(auto-fill,_minmax(415px,_1fr))] gap-5 mb-11 h-auto">
{loading ? (
<div className="w-full h-full flex items-center justify-center bg-white">
<LoadingSpinner size="16" color="sky-blue" height='h-[30rem]' />
</div>
) : (
data.length > 0 && data.map((item) => (
<div key={item.wallet_uid} className="lg:w-full h-full mb-10 lg:mb-0">
<WalletItemCardFamily walletItem={item} payment={payment} countries={countries} />
</div>
))
)}
</div>
</div>
</div>
);
}
-16
View File
@@ -15,21 +15,6 @@ export default function WalletBox({ wallet, payment, countries }) {
return ( return (
<div className="my-wallet-wrapper w-full mb-10"> <div className="my-wallet-wrapper w-full mb-10">
<div className="main-wrapper w-full"> <div className="main-wrapper w-full">
{accountType ?
<div className="balance-inquery w-auto grid sm:grid-cols-2 lg:grid-cols-2 xl:grid-cols-[repeat(auto-fill,_minmax(354px,_1fr))] min-[1440px]:grid-cols-[repeat(auto-fill,_minmax(415px,_1fr))] gap-5 mb-11 h-auto">
{loading ? (
<div className="w-full h-full flex items-center justify-center">
<LoadingSpinner size="16" color="sky-blue" />
</div>
) : (
data.length > 0 && data.map((item) => (
<div key={item.wallet_uid} className="lg:w-full h-full mb-10 lg:mb-0">
<WalletItemCardFamily walletItem={item} payment={payment} countries={countries} />
</div>
))
)}
</div>
:
<div className="balance-inquery w-auto grid sm:grid-cols-2 lg:grid-cols-2 xl:grid-cols-[repeat(auto-fill,_minmax(354px,_1fr))] min-[1440px]:grid-cols-[repeat(auto-fill,_minmax(415px,_1fr))] gap-5 mb-11 h-auto"> <div className="balance-inquery w-auto grid sm:grid-cols-2 lg:grid-cols-2 xl:grid-cols-[repeat(auto-fill,_minmax(354px,_1fr))] min-[1440px]:grid-cols-[repeat(auto-fill,_minmax(415px,_1fr))] gap-5 mb-11 h-auto">
{loading ? ( {loading ? (
<div className="w-full h-full flex items-center justify-center"> <div className="w-full h-full flex items-center justify-center">
@@ -43,7 +28,6 @@ export default function WalletBox({ wallet, payment, countries }) {
)) ))
)} )}
</div> </div>
}
</div> </div>
</div> </div>
); );
+184 -172
View File
@@ -7,8 +7,11 @@ import Icons from "../Helpers/Icons";
import Accordion from "../Helpers/Accordion"; import Accordion from "../Helpers/Accordion";
import { PriceFormatter } from "../Helpers/PriceFormatter"; import { PriceFormatter } from "../Helpers/PriceFormatter";
import localImgLoad from "../../lib/localImgLoad"; import localImgLoad from "../../lib/localImgLoad";
import { useSelector } from "react-redux";
export default function WalletHeader(props) { export default function WalletHeader(props) {
const {userDetails: { account_type }} = useSelector((state) => state?.userDetails);
// debugger; // debugger;
//props.myWalletList.result_list //props.myWalletList.result_list
let { pathname } = useLocation(); let { pathname } = useLocation();
@@ -21,187 +24,196 @@ export default function WalletHeader(props) {
} }
return ( return (
<> <>
<div className="lg:flex hidden user-balance cursor-pointer lg:w-[152px] w-[150px] h-[48px] items-center rounded-full relative bg-sky-blue pr-1.5 pl-4"> {account_type == 'FULL' ?
<div <div className="lg:flex hidden user-balance cursor-pointer lg:w-[152px] w-[150px] h-[48px] items-center rounded-full relative bg-sky-blue pr-1.5 pl-4">
onClick={() => props.handlerBalance()} <div
className="flex items-center lg:justify-between justify-center w-full h-full" onClick={() => props.handlerBalance()}
> className="flex items-center lg:justify-between justify-center w-full h-full"
<span className="lg:block hidden"> >
<Icons name="wallet" /> <span className="lg:block hidden">
</span> <Icons name="wallet" />
<p className="lg:text-xl text-lg font-bold text-white">Wallet</p> </span>
<span className="lg:block hidden"> <p className="lg:text-xl text-lg font-bold text-white">Wallet</p>
<Icons name="deep-plus" /> <span className="lg:block hidden">
</span> <Icons name="deep-plus" />
</div> </span>
<div
className={`balance-dropdown w-96 z-30 bg-white dark:bg-dark-white absolute -left-24 rounded-lg cursor-pointer ${
props.balanceDropdown ? "active" : ""
}`}
>
<div className="heading border-b dark:border-[#5356fb29] border-light-purple px-7 py-6">
<h3 className="text-xl font-bold text-dark-gray dark:text-white">
Wallet
</h3>
</div> </div>
<div className="content px-7 pb-7"> <div
<ul> className={`balance-dropdown w-96 z-30 bg-white dark:bg-dark-white absolute -left-24 rounded-lg cursor-pointer ${
{props.myWalletList && props.balanceDropdown ? "active" : ""
props.myWalletList?.length > 0 && }`}
props.myWalletList.map((value, index) => >
{ <div className="heading border-b dark:border-[#5356fb29] border-light-purple px-7 py-6">
let image = value.code ? `${value.code.toLocaleLowerCase()}.svg` : 'default.png' <h3 className="text-xl font-bold text-dark-gray dark:text-white">
return( Wallet
<li </h3>
key={index} </div>
className="content-item py-4 border-b dark:border-[#5356fb29] border-light-purple hover:border-purple dark:hover:border-purple" <div className="content px-7 pb-7">
onClick={onWalletClick} <ul>
> {props.myWalletList &&
<div className="sm:flex justify-between items-center"> props.myWalletList?.length > 0 &&
<div className="account-name flex space-x-4 items-center mb-2 sm:mb-0"> props.myWalletList.map((value, index) =>
<div className="icon w-14 h-14 transition duration-300 ease-in-out rounded-full flex justify-center items-center bg-light-purple dark:bg-dark-light-purple "> {
<img src={localImgLoad(`images/currency/${image}`)} className="w-14 h-14" alt="" /> let image = value.code ? `${value.code.toLocaleLowerCase()}.svg` : 'default.png'
return(
<li
key={index}
className="content-item py-4 border-b dark:border-[#5356fb29] border-light-purple hover:border-purple dark:hover:border-purple"
onClick={onWalletClick}
>
<div className="sm:flex justify-between items-center">
<div className="account-name flex space-x-4 items-center mb-2 sm:mb-0">
<div className="icon w-14 h-14 transition duration-300 ease-in-out rounded-full flex justify-center items-center bg-light-purple dark:bg-dark-light-purple ">
<img src={localImgLoad(`images/currency/${image}`)} className="w-14 h-14" alt="" />
</div>
<div className="name">
<p className="text-2xl font-bold text-dark-gray dark:text-white">
{value.description}
</p>
</div>
</div> </div>
<div className="name"> <div>
<p className="text-2xl font-bold text-dark-gray dark:text-white"> <p className="eth text-xl font-bold text-purple">
{value.description} {PriceFormatter(value.amount * 0.01, value.code)}
</p> </p>
</div> </div>
</div> </div>
<div> </li>
<p className="eth text-xl font-bold text-purple"> )
{PriceFormatter(value.amount * 0.01, value.code)} }
</p> )}
</div>
</div>
</li>
)
}
)}
{/*<li className="content-item py-4 border-b dark:border-[#5356fb29] border-light-purple hover:border-purple dark:hover:border-purple">*/} {/*<li className="content-item py-4 border-b dark:border-[#5356fb29] border-light-purple hover:border-purple dark:hover:border-purple">*/}
{/* <div className="sm:flex justify-between items-center">*/} {/* <div className="sm:flex justify-between items-center">*/}
{/* <div className="account-name flex space-x-4 items-center mb-2 sm:mb-0">*/} {/* <div className="account-name flex space-x-4 items-center mb-2 sm:mb-0">*/}
{/* <div*/} {/* <div*/}
{/* className="icon w-14 h-14 transition duration-300 ease-in-out rounded-full flex justify-center items-center bg-light-purple dark:bg-dark-light-purple ">*/} {/* className="icon w-14 h-14 transition duration-300 ease-in-out rounded-full flex justify-center items-center bg-light-purple dark:bg-dark-light-purple ">*/}
{/* <img src={bank1} alt=""/>*/} {/* <img src={bank1} alt=""/>*/}
{/* </div>*/} {/* </div>*/}
{/* <div className="name">*/} {/* <div className="name">*/}
{/* <p className="text-base text-dark-gray dark:text-white font-medium">*/} {/* <p className="text-base text-dark-gray dark:text-white font-medium">*/}
{/* MetaMask*/} {/* MetaMask*/}
{/* </p>*/} {/* </p>*/}
{/* </div>*/} {/* </div>*/}
{/* </div>*/} {/* </div>*/}
{/* <div>*/} {/* <div>*/}
{/* <p className="eth text-xl font-bold text-purple">*/} {/* <p className="eth text-xl font-bold text-purple">*/}
{/* 75,320 ETH*/} {/* 75,320 ETH*/}
{/* </p>*/} {/* </p>*/}
{/* <p className="usd text-base text-thin-light-gray text-right">*/} {/* <p className="usd text-base text-thin-light-gray text-right">*/}
{/* (773.69 USD)*/} {/* (773.69 USD)*/}
{/* </p>*/} {/* </p>*/}
{/* </div>*/} {/* </div>*/}
{/* </div>*/} {/* </div>*/}
{/*</li>*/} {/*</li>*/}
{/*<li className="content-item py-4 border-b dark:border-[#5356fb29] border-light-purple hover:border-purple dark:hover:border-purple">*/} {/*<li className="content-item py-4 border-b dark:border-[#5356fb29] border-light-purple hover:border-purple dark:hover:border-purple">*/}
{/* <div className="sm:flex justify-between items-center">*/} {/* <div className="sm:flex justify-between items-center">*/}
{/* <div className="account-name flex space-x-4 items-center mb-2 sm:mb-0">*/} {/* <div className="account-name flex space-x-4 items-center mb-2 sm:mb-0">*/}
{/* <div*/} {/* <div*/}
{/* className="icon w-14 h-14 transition duration-300 ease-in-out rounded-full flex justify-center items-center bg-light-purple dark:bg-dark-light-purple ">*/} {/* className="icon w-14 h-14 transition duration-300 ease-in-out rounded-full flex justify-center items-center bg-light-purple dark:bg-dark-light-purple ">*/}
{/* <img src={bank2} alt=""/>*/} {/* <img src={bank2} alt=""/>*/}
{/* </div>*/} {/* </div>*/}
{/* <div className="name">*/} {/* <div className="name">*/}
{/* <p className="text-base text-dark-gray dark:text-white font-medium">*/} {/* <p className="text-base text-dark-gray dark:text-white font-medium">*/}
{/* Coinbase Wallet*/} {/* Coinbase Wallet*/}
{/* </p>*/} {/* </p>*/}
{/* </div>*/} {/* </div>*/}
{/* </div>*/} {/* </div>*/}
{/* <div>*/} {/* <div>*/}
{/* <p className="eth text-xl font-bold text-purple">*/} {/* <p className="eth text-xl font-bold text-purple">*/}
{/* 56,124 ETH*/} {/* 56,124 ETH*/}
{/* </p>*/} {/* </p>*/}
{/* <p className="usd text-base text-thin-light-gray text-right">*/} {/* <p className="usd text-base text-thin-light-gray text-right">*/}
{/* (773.69 USD)*/} {/* (773.69 USD)*/}
{/* </p>*/} {/* </p>*/}
{/* </div>*/} {/* </div>*/}
{/* </div>*/} {/* </div>*/}
{/*</li>*/} {/*</li>*/}
{/*<li className="content-item py-4 border-b dark:border-[#5356fb29] border-light-purple hover:border-purple dark:hover:border-purple">*/} {/*<li className="content-item py-4 border-b dark:border-[#5356fb29] border-light-purple hover:border-purple dark:hover:border-purple">*/}
{/* <div className="sm:flex justify-between items-center">*/} {/* <div className="sm:flex justify-between items-center">*/}
{/* <div className="account-name flex space-x-4 items-center mb-2 sm:mb-0">*/} {/* <div className="account-name flex space-x-4 items-center mb-2 sm:mb-0">*/}
{/* <div*/} {/* <div*/}
{/* className="icon w-14 h-14 transition duration-300 ease-in-out rounded-full flex justify-center items-center bg-light-purple dark:bg-dark-light-purple ">*/} {/* className="icon w-14 h-14 transition duration-300 ease-in-out rounded-full flex justify-center items-center bg-light-purple dark:bg-dark-light-purple ">*/}
{/* <img src={bank3} alt=""/>*/} {/* <img src={bank3} alt=""/>*/}
{/* </div>*/} {/* </div>*/}
{/* <div className="name">*/} {/* <div className="name">*/}
{/* <p className="text-base text-dark-gray dark:text-white font-medium">*/} {/* <p className="text-base text-dark-gray dark:text-white font-medium">*/}
{/* Bitski*/} {/* Bitski*/}
{/* </p>*/} {/* </p>*/}
{/* </div>*/} {/* </div>*/}
{/* </div>*/} {/* </div>*/}
{/* <div>*/} {/* <div>*/}
{/* <p className="eth text-xl font-bold text-purple">*/} {/* <p className="eth text-xl font-bold text-purple">*/}
{/* 99,123 ETH*/} {/* 99,123 ETH*/}
{/* </p>*/} {/* </p>*/}
{/* <p className="usd text-base text-thin-light-gray text-right">*/} {/* <p className="usd text-base text-thin-light-gray text-right">*/}
{/* (773.69 USD)*/} {/* (773.69 USD)*/}
{/* </p>*/} {/* </p>*/}
{/* </div>*/} {/* </div>*/}
{/* </div>*/} {/* </div>*/}
{/*</li>*/} {/*</li>*/}
{/*<li className="content-item py-5">*/} {/*<li className="content-item py-5">*/}
{/* <div className="sm:flex justify-between items-center">*/} {/* <div className="sm:flex justify-between items-center">*/}
{/* <div className="account-name flex space-x-4 items-center mb-2 sm:mb-0">*/} {/* <div className="account-name flex space-x-4 items-center mb-2 sm:mb-0">*/}
{/* <div*/} {/* <div*/}
{/* className="icon w-14 h-14 transition duration-300 ease-in-out rounded-full flex justify-center items-center bg-light-purple dark:bg-dark-light-purple ">*/} {/* className="icon w-14 h-14 transition duration-300 ease-in-out rounded-full flex justify-center items-center bg-light-purple dark:bg-dark-light-purple ">*/}
{/* <img src={bank4} alt=""/>*/} {/* <img src={bank4} alt=""/>*/}
{/* </div>*/} {/* </div>*/}
{/* <div className="name">*/} {/* <div className="name">*/}
{/* <p className="text-base text-dark-gray dark:text-white font-medium">*/} {/* <p className="text-base text-dark-gray dark:text-white font-medium">*/}
{/* WalletConnect*/} {/* WalletConnect*/}
{/* </p>*/} {/* </p>*/}
{/* </div>*/} {/* </div>*/}
{/* </div>*/} {/* </div>*/}
{/* <div>*/} {/* <div>*/}
{/* <p className="eth text-xl font-bold text-purple">*/} {/* <p className="eth text-xl font-bold text-purple">*/}
{/* 43,728 ETH*/} {/* 43,728 ETH*/}
{/* </p>*/} {/* </p>*/}
{/* <p className="usd text-base text-thin-light-gray text-right">*/} {/* <p className="usd text-base text-thin-light-gray text-right">*/}
{/* (773.69 USD)*/} {/* (773.69 USD)*/}
{/* </p>*/} {/* </p>*/}
{/* </div>*/} {/* </div>*/}
{/* </div>*/} {/* </div>*/}
{/*</li>*/} {/*</li>*/}
</ul> </ul>
<div className="add-money-btn flex justify-center items-center mt-3"> <div className="add-money-btn flex justify-center items-center mt-3">
{/* <button {/* <button
onClick={() => { onClick={() => {
if(pathname == '/my-wallet') props.setBalanceDropdown.toggle() if(pathname == '/my-wallet') props.setBalanceDropdown.toggle()
else navigate('/my-wallet', {replace: true}) else navigate('/my-wallet', {replace: true})
}} }}
type="button" type="button"
className="w-[122px] h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white" className="w-[122px] h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
> >
Manage Manage
</button> */} </button> */}
<Link <Link
to="/my-wallet" to="/my-wallet"
onClick={onWalletClick} onClick={onWalletClick}
className="w-[122px] h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white" className="w-[122px] h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
> >
Manage Manage
</Link> </Link>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> :
{/*<div*/} <div className="lg:flex hidden user-balance cursor-pointer lg:w-[152px] w-[150px] h-[48px] items-center rounded-full relative bg-sky-blue pr-1.5 pl-4">
{/* className="lg:hidden flex user-balance cursor-pointer lg:w-[252px] w-[150px] h-[48px] items-center rounded-full relative bg-purple">*/} <div
{/* <div className="flex items-center lg:justify-between justify-center w-full h-full">*/} onClick={() => navigate("/family-wallet", { replace: true })}
{/* <p className="lg:text-xl text-lg font-bold text-white">*/} className="flex items-center lg:justify-between justify-center w-full h-full"
{/* $ 234,435.34*/} >
{/* </p>*/} <span className="lg:block hidden">
{/* </div>*/} <Icons name="wallet" />
{/*</div>*/} </span>
<p className="lg:text-xl text-lg font-bold text-white">Wallet</p>
<span className="lg:block hidden">
<Icons name="deep-plus" />
</span>
</div>
</div>
}
<div className="lg:hidden block"></div> <div className="lg:hidden block"></div>
</> </>
); );
+1 -3
View File
@@ -34,9 +34,7 @@ export default function WalletItemCard({ walletItem, payment, countries }) {
dispatch(tableReload({ type: "WALLETTABLE" })); dispatch(tableReload({ type: "WALLETTABLE" }));
}; };
const currentWalletCurrency = countries const currentWalletCurrency = countries?.filter((country) => country.code === walletItem.country);
// .map((country) => country)
.filter((country) => country.code === walletItem.country);
const image = walletItem.code const image = walletItem.code
? `${walletItem.code.toLowerCase()}.svg` ? `${walletItem.code.toLowerCase()}.svg`
@@ -34,9 +34,7 @@ export default function WalletItemCardFamily({ walletItem, payment, countries })
dispatch(tableReload({ type: "WALLETTABLE" })); dispatch(tableReload({ type: "WALLETTABLE" }));
}; };
const currentWalletCurrency = countries const currentWalletCurrency = countries?.filter((country) => country.code === walletItem.country);
// .map((country) => country)
.filter((country) => country.code === walletItem.country);
const image = walletItem.code const image = walletItem.code
? `${walletItem.code.toLowerCase()}.svg` ? `${walletItem.code.toLowerCase()}.svg`
+41 -23
View File
@@ -1,18 +1,17 @@
import React, { useContext, useMemo, useState } from "react"; import React, { useContext } from "react";
import { Link, useLocation, useNavigate } from "react-router-dom"; import { Link, useLocation } from "react-router-dom";
import bank1 from "../../assets/images/bank-1.png"; import bank1 from "../../assets/images/bank-1.png";
import bank2 from "../../assets/images/bank-2.png"; import bank2 from "../../assets/images/bank-2.png";
import bank3 from "../../assets/images/bank-3.png"; import bank3 from "../../assets/images/bank-3.png";
import bank4 from "../../assets/images/bank-4.png"; import bank4 from "../../assets/images/bank-4.png";
import profileImg from "../../assets/images/profile.jpg"; import profileImg from "../../assets/images/profile.jpg";
import useToggle from "../../hooks/useToggle"; import useToggle from "../../hooks/useToggle";
import usersService from "../../services/UsersService";
import DarkModeContext from "../Contexts/DarkModeContext"; import DarkModeContext from "../Contexts/DarkModeContext";
import Icons from "../Helpers/Icons"; import Icons from "../Helpers/Icons";
import ModalCom from "../Helpers/ModalCom"; import ModalCom from "../Helpers/ModalCom";
import WalletHeader from "../MyWallet/WalletHeader"; import WalletHeader from "../MyWallet/WalletHeader";
import { useDispatch, useSelector } from "react-redux"; import { useSelector } from "react-redux";
import Flag from "../../assets/images/united-states.svg"; import Flag from "../../assets/images/united-states.svg";
import siteLogo from "../../assets/images/wrenchboard-logo-text.png"; import siteLogo from "../../assets/images/wrenchboard-logo-text.png";
// import { updateWalletDetails } from "../../store/walletDetails"; // import { updateWalletDetails } from "../../store/walletDetails";
@@ -21,17 +20,15 @@ import TimeDifference from "../Helpers/TimeDifference";
const DEFAULT_PROFILE_IMAGE = require("../../assets/images/profile.jpg"); const DEFAULT_PROFILE_IMAGE = require("../../assets/images/profile.jpg");
export default function Header({ logoutModalHandler, sidebarHandler }) { export default function Header({ logoutModalHandler, sidebarHandler }) {
const {userDetails: { account_type }} = useSelector((state) => state?.userDetails);
const [balanceDropdown, setbalanceValue] = useToggle(false); const [balanceDropdown, setbalanceValue] = useToggle(false);
const [notificationDropdown, setNotificationValue] = useToggle(false); const [notificationDropdown, setNotificationValue] = useToggle(false);
const [userProfileDropdown, setProfileDropdown] = useToggle(false); const [userProfileDropdown, setProfileDropdown] = useToggle(false);
const [moneyPopup, setPopup] = useToggle(false); const [moneyPopup, setPopup] = useToggle(false);
const darkMode = useContext(DarkModeContext); const darkMode = useContext(DarkModeContext);
const { userDetails } = useSelector((state) => state?.userDetails); const { userDetails } = useSelector((state) => state?.userDetails);
const { walletTable } = useSelector((state) => state.tableReload); // DETERMINES WHEN WALLET RELOADS
const [myWalletList, setMyWalletList] = useState([]);
const api = useMemo(() => new usersService(), []);
const dispatch = useDispatch();
const navigate = useNavigate();
const { notifications } = useSelector((state) => state?.notifications); // NOTIFICATION STORE const { notifications } = useSelector((state) => state?.notifications); // NOTIFICATION STORE
const { walletDetails } = useSelector((state) => state?.walletDetails); // WALLET STORE const { walletDetails } = useSelector((state) => state?.walletDetails); // WALLET STORE
@@ -48,7 +45,6 @@ export default function Header({ logoutModalHandler, sidebarHandler }) {
// 9308RDR122 // 9308RDR122
const handlerBalance = () => { const handlerBalance = () => {
setbalanceValue.toggle(); setbalanceValue.toggle();
if (notificationDropdown) { if (notificationDropdown) {
@@ -158,9 +154,10 @@ export default function Header({ logoutModalHandler, sidebarHandler }) {
</defs> </defs>
</svg> </svg>
</button> </button>
{/* search bar */}
<div className="search-bar lg:block hidden w-[376px]"> <div className="search-bar xl:hidden justify-center items-center w-[376px]">
{/*<SearchCom />*/} {/* Home */}
<HomeButton />
</div> </div>
{/* user info */} {/* user info */}
@@ -408,7 +405,7 @@ export default function Header({ logoutModalHandler, sidebarHandler }) {
</li> </li>
)} )}
<li className="content-item my-2 hover:bg-slate-100 transition duration-500 rounded-lg"> <li className="content-item my-2 hover:bg-slate-100 transition duration-500 rounded-lg">
<Link to="/my-wallet" className="notifications"> <Link to={ account_type == "FULL" ? "/my-wallet" : "/family-wallet"} className="notifications">
<div className="name"> <div className="name">
<p className="text-sm py-2 px-4 text-dark-gray dark:text-white hover:text-sky-blue transition font-medium"> <p className="text-sm py-2 px-4 text-dark-gray dark:text-white hover:text-sky-blue transition font-medium">
My Wallet My Wallet
@@ -506,15 +503,6 @@ export default function Header({ logoutModalHandler, sidebarHandler }) {
</div> </div>
</div> </div>
</div> </div>
{/* <div className="for-mobile-profile lg:hidden block">
<div
// to="/profile"
onClick={() => handlerProfile()}
className="lg:w-[62px] lg:h-[62px] w-[50px] h-[50px] rounded-full overflow-hidden block"
>
<img src={profileImg} alt="profile" className="w-full h-full" />
</div>
</div> */}
</div> </div>
</div> </div>
</div> </div>
@@ -697,3 +685,33 @@ const PageButton = () => {
</Link> </Link>
); );
}; };
const HomeButton = () => {
return (
<Link
to="/"
className="flex user-balance cursor-pointer w-[110px] h-[48px] items-center rounded-full relative bg-sky-blue pr-1.5 pl-4"
>
<div className="flex items-center lg:justify-between justify-center w-full h-full">
<span className="">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth={1.5}
stroke="currentColor"
className="w-7 h-7 stroke-white fill-white"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="m2.25 12 8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25"
/>
</svg>
</span>
<p className="lg:text-xl text-lg font-bold text-white">Home</p>
<span className=""></span>
</div>
</Link>
);
};
+20 -8
View File
@@ -33,6 +33,9 @@ export default function Resources(props) {
const CreatedBits = __resources?.productdata?.datas; const CreatedBits = __resources?.productdata?.datas;
const blogItems = __resources?.blogdata?.payload; const blogItems = __resources?.blogdata?.payload;
console.log(__resources);
console.log("Blog data >> ", blogItems);
// My Items Data // My Items Data
const [uploadedFiles, setUploadedFiles] = useState({ const [uploadedFiles, setUploadedFiles] = useState({
loading: false, loading: false,
@@ -63,7 +66,7 @@ export default function Resources(props) {
loading: false, loading: false,
msg: "success", msg: "success",
data: res?.result_list, data: res?.result_list,
image:res?.session_image_server image: res?.session_image_server,
})); }));
} catch (error) { } catch (error) {
setUploadedFiles((prev) => ({ setUploadedFiles((prev) => ({
@@ -79,7 +82,13 @@ export default function Resources(props) {
}, [uploadsTable]); }, [uploadsTable]);
// const [tab, setTab] = useState(tab_categories ? tab_categories[0]?.name : ""); // const [tab, setTab] = useState(tab_categories ? tab_categories[0]?.name : "");
const [tab, setTab] = useState(props.activeTab? props.activeTab : tab_categories ? tab_categories[0]?.name : ""); const [tab, setTab] = useState(
props.activeTab
? props.activeTab
: tab_categories
? tab_categories[0]?.name
: ""
);
const tabHandler = (value) => { const tabHandler = (value) => {
setTab(value); setTab(value);
@@ -105,8 +114,12 @@ export default function Resources(props) {
// const selectedTabComponent = tabComponents[tab] || defaultTabComponent; // const selectedTabComponent = tabComponents[tab] || defaultTabComponent;
const defaultTabComponent = props.activeTab ? tabComponents[props.activeTab] : <BlogTab blogdata={blogItems} />; const defaultTabComponent = props.activeTab ? (
const selectedTabComponent = tabComponents[tab] || defaultTabComponent; tabComponents[props.activeTab]
) : (
<BlogTab blogdata={blogItems} />
);
const selectedTabComponent = tabComponents[tab] || defaultTabComponent;
// Tab Item Component // Tab Item Component
const TabItem = ({ tabValue, isActive }) => { const TabItem = ({ tabValue, isActive }) => {
@@ -160,17 +173,16 @@ export default function Resources(props) {
<ul className="lg:flex lg:space-x-14 space-x-8"> <ul className="lg:flex lg:space-x-14 space-x-8">
{tabCategories?.length > 0 && {tabCategories?.length > 0 &&
tabCategories?.map((tabValue, idx) => { tabCategories?.map((tabValue, idx) => {
if(tabValue.enabled){ if (tabValue.enabled) {
return ( return (
<TabItem <TabItem
key={tabValue.id} key={tabValue.id}
tabValue={tabValue} tabValue={tabValue}
isActive={tab === tabValue.name || (idx === 0 && tab === "")} isActive={tab === tabValue.name || (idx === 0 && tab === "")}
/> />
) );
} }
} })}
)}
</ul> </ul>
); );
}; };
@@ -134,7 +134,7 @@ export default function MyUploadedFiles({ uploadedFiles }) {
prev={currentPage == 0 ? true : false} prev={currentPage == 0 ? true : false}
next={ next={
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >= currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
uploadedFiles?.data.length uploadedFiles?.data?.length
? true ? true
: false : false
} }
@@ -0,0 +1,12 @@
import React from "react";
import HomeActivities from "../../Home/HomeActivities";
const RecentActivitiesTab = () => {
return (
<div className="recent-activity-tab w-full">
<HomeActivities />
</div>
);
};
export default RecentActivitiesTab;
+2
View File
@@ -5,6 +5,7 @@ import NotificationSettingTab from "./NotificationSettingTab";
import PaymentMathodsTab from "./PaymentMathodsTab"; import PaymentMathodsTab from "./PaymentMathodsTab";
import PersonalInfoTab from "./PersonalInfoTab"; import PersonalInfoTab from "./PersonalInfoTab";
import PrivacyPolicyTab from "./PrivacyPolicyTab"; import PrivacyPolicyTab from "./PrivacyPolicyTab";
import RecentActivitiesTab from "./RecentActivitiesTab";
import TermsConditionTab from "./TermsConditionTab"; import TermsConditionTab from "./TermsConditionTab";
export { export {
@@ -15,5 +16,6 @@ export {
PaymentMathodsTab, PaymentMathodsTab,
PersonalInfoTab, PersonalInfoTab,
PrivacyPolicyTab, PrivacyPolicyTab,
RecentActivitiesTab,
TermsConditionTab, TermsConditionTab,
}; };
+12 -10
View File
@@ -1,10 +1,4 @@
import React, { import React, { useCallback, useEffect, useState } from "react";
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from "react";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
import usersService from "../../services/UsersService"; import usersService from "../../services/UsersService";
import Icons from "../Helpers/Icons"; import Icons from "../Helpers/Icons";
@@ -17,6 +11,7 @@ import {
PaymentMathodsTab, PaymentMathodsTab,
PersonalInfoTab, PersonalInfoTab,
PrivacyPolicyTab, PrivacyPolicyTab,
RecentActivitiesTab,
TermsConditionTab, TermsConditionTab,
} from "./Tabs"; } from "./Tabs";
import RecipientAccountTab from "./Tabs/RecipientAccountTab"; import RecipientAccountTab from "./Tabs/RecipientAccountTab";
@@ -102,24 +97,30 @@ export default function Settings({ faq }) {
}, },
{ {
id: 6, id: 6,
name: "recent_activities",
title: "Recent Activities",
iconName: "login-activity",
},
{
id: 7,
name: "password", name: "password",
title: "Change Password", title: "Change Password",
iconName: "password-hover", iconName: "password-hover",
}, },
{ {
id: 7, id: 8,
name: "faq", name: "faq",
title: "FAQ", title: "FAQ",
iconName: "block-question", iconName: "block-question",
}, },
{ {
id: 8, id: 9,
name: "privacy", name: "privacy",
title: "Privacy Policy", title: "Privacy Policy",
iconName: "page-right", iconName: "page-right",
}, },
{ {
id: 9, id: 10,
name: "terms", name: "terms",
title: "Terms and Conditions", title: "Terms and Conditions",
iconName: "page-right", iconName: "page-right",
@@ -166,6 +167,7 @@ export default function Settings({ faq }) {
</div> </div>
), ),
login_activity: <LoginActivityTab />, login_activity: <LoginActivityTab />,
recent_activities: <RecentActivitiesTab />,
password: <ChangePasswordTab />, password: <ChangePasswordTab />,
faq: <FaqTab datas={faq} />, faq: <FaqTab datas={faq} />,
privacy: <PrivacyPolicyTab />, privacy: <PrivacyPolicyTab />,
+11 -30
View File
@@ -1,37 +1,18 @@
import React from "react"; import React from "react";
import { Link } from "react-router-dom";
import RecomendedSliders from "./RecomendedSliders"; import RecomendedSliders from "./RecomendedSliders";
export default function CommonHead({ className, commonHeadData }) { export default function CommonHead({ className = "", commonHeadData = [] }) {
return ( return (
<div <>
className={`create-nft w-full lg:h-[140px] shadow lg:flex rounded-lg justify-between items-center md:p-2 p-2 bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] -2 border-pink mb-10 ${ {process.env.REACT_APP_SHOW_SLIDER_BANNERS === "1" && (
className || "" <div
}`} className={`create-nft w-full lg:h-[140px] shadow lg:flex rounded-lg justify-between items-center md:p-2 p-2 bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] -2 border-pink mb-10 ${className}`}
> >
{commonHeadData?.length > 0 && ( {commonHeadData?.length > 0 && (
<RecomendedSliders bannerData={commonHeadData} /> <RecomendedSliders bannerData={commonHeadData} />
)}
</div>
)} )}
{/*<div className="lg:w-8/12 w-full mb-8 lg:mb-0">*/} </>
{/* /!*<h1 className="text-2xl text-dark-gray dark:text-white font-bold mb-2">*!/*/}
{/* /!* This is common head which will appear as needed , will take many shape*!/*/}
{/* /!*</h1>*!/*/}
{/* /!*<p className="text-base text-thin-light-gray tracking-wide">*!/*/}
{/* /!* some space for extra texts here*!/*/}
{/* /!*</p>*!/*/}
{/* */}
{/*</div>*/}
{/*<div className="flex-1 flex lg:justify-end">*/}
{/* <div className="flex items-center space-x-5">*/}
{/* <Link*/}
{/* to="/mytask"*/}
{/* className="w-40 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"*/}
{/* >*/}
{/* View Task*/}
{/* </Link>*/}
{/* </div>*/}
{/*</div>*/}
</div>
); );
} }
+1 -1
View File
@@ -6,7 +6,7 @@ const LoadedPage = ({reloader}) => {
const { loading, data, error } = GetMyPageLoad(reloader); const { loading, data, error } = GetMyPageLoad(reloader);
return ( return (
<div className="w-full border border-gray-400 rounded-md p-4 flex flex-col h-72 gap-2 overflow-y-auto"> <div className="w-full border border-gray-400 rounded-md p-4 flex flex-col h-72 gap-2 overflow-y-auto dark:text-white">
{loading ? ( {loading ? (
<> <>
<h1 className="text-xl font-bold tracking-wide">...</h1> <h1 className="text-xl font-bold tracking-wide">...</h1>
+2 -1
View File
@@ -8,6 +8,7 @@ const YourPageForm = ({ values, onChange, onSubmit, loading, msg }) => (
fieldClass="px-4" fieldClass="px-4"
parentClass="flex items-center gap-1 justify-between" parentClass="flex items-center gap-1 justify-between"
labelClass="flex-[0.2] mb-0 font-semibold" labelClass="flex-[0.2] mb-0 font-semibold"
labalClass="dark:text-white"
inputClass="flex-[0.8]" inputClass="flex-[0.8]"
inputBg="bg-slate-100" inputBg="bg-slate-100"
label="Introduction: " label="Introduction: "
@@ -24,7 +25,7 @@ const YourPageForm = ({ values, onChange, onSubmit, loading, msg }) => (
</label> </label>
<textarea <textarea
style={{ resize: "none" }} style={{ resize: "none" }}
className="text-base px-4 py-2 rounded-md min-h-[100px] text-dark-gray dark:text-white w-full bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none flex-[0.8]" className="text-base px-4 py-2 rounded-[36px] min-h-[100px] text-dark-gray dark:text-white w-full bg-slate-100 focus:ring-0 focus:outline-none flex-[0.8]"
name="description" name="description"
cols="30" cols="30"
rows="2" rows="2"
+33 -42
View File
@@ -13,12 +13,39 @@ const YourPage = () => {
const handleChange = ({ target: { name, value } }) => const handleChange = ({ target: { name, value } }) =>
setPageValues((prev) => ({ ...prev, [name]: value })); setPageValues((prev) => ({ ...prev, [name]: value }));
const updateYourPageDetails = updateYourPage( const updateYourPageDetails = async () => {
pageValues, if (!pageValues.intro || !pageValues.description) return;
setResponse,
setPageValues, try {
setReloader setResponse({ loading: true, error: "", msg: "" });
);
let api = new usersService();
const res = await api.MyPageIntro(pageValues);
setTimeout(() => {
setResponse({
loading: false,
data: res.data,
msg: "Update Complete",
});
setReloader((prev) => !prev);
}, 1000);
setTimeout(() => {
setResponse({ msg: "" });
// Clear form after successful update
setPageValues({ intro: "", description: "" });
}, 3000);
} catch (error) {
return setResponse({
loading: false,
data: {},
error: "Error updating page",
msg: "",
});
}
};
return ( return (
<Layout> <Layout>
@@ -57,39 +84,3 @@ const responseInitialValues = {
error: "", error: "",
msg: "", msg: "",
}; };
function updateYourPage(pageValues, setResponse, setPageValues, setReloader) {
return async () => {
if (!pageValues.intro || !pageValues.description) return;
try {
setResponse({ loading: true, error: "", msg: "" });
let api = new usersService();
const res = await api.MyPageIntro(pageValues);
setTimeout(() => {
setResponse({
loading: false,
data: res.data,
msg: "Update Complete",
});
setReloader((prev) => !prev);
}, 1000);
setTimeout(() => {
setResponse({ msg: "" });
// Clear form after successful update
setPageValues({ intro: "", description: "" });
}, 3000);
} catch (error) {
return setResponse({
loading: false,
data: {},
error: "Error updating page",
msg: "",
});
}
};
}
@@ -0,0 +1,137 @@
import React, { useEffect, useState } from 'react'
import Layout from '../Partials/Layout'
import usersService from '../../services/UsersService'
import SearchCom from '../Helpers/SearchCom'
import LoadingSpinner from '../Spinners/LoadingSpinner'
import { useLocation } from 'react-router-dom'
import CustomBreadcrumb from '../Breadcrumb/CustomBreadcrumb'
import { localImgLoad } from '../../lib'
export default function FamAIQuestion() {
const apiCall = new usersService()
const {pathname} = useLocation()
const [requestStatus, setRequestStatus] = useState({loading: false, status: false, message: ''})
const [error, setError] = useState({question: '', searchPhrase: ''})
const [questions, setQuestions] = useState({loading: true, data: []})
const [askQuestion, setAskQuestion] = useState({question: '', searchPhrase: ''})
const changeAskQuestion = ({target: {name, value}}) => {
setAskQuestion(prev => ({...prev, [name]: value}))
setRequestStatus({loading: false, status: false, message: ''})
}
const onSearch = () => {
setError({question: '', searchPhrase: ''}) // sets error to false
if(!askQuestion.question){
return setError(prev => ({...prev, question: 'Select a question'}))
}
if(!askQuestion.searchPhrase){
return setError(prev => ({...prev, searchPhrase: 'Enter search parameter'}))
}
if(askQuestion.searchPhrase.length > 60){
return setError(prev => ({...prev, searchPhrase: 'Max of 60 characters'}))
}
setRequestStatus({loading: true, status: false, message: ''})
let reqData = {
question_key: '',
question: ''
}
apiCall.askResourcesResult().then(res => {
console.log(res.data.choices[0].text)
if(!res.data || res.data?.choices?.length < 1){
setRequestStatus({loading: false, status: false, message: 'No result found!'})
}
setRequestStatus({loading: false, status: false, message: res.data?.choices[0].text})
}).catch(error => {
setRequestStatus({loading: false, status: false, message: 'No result found!'})
})
}
useEffect(()=>{
apiCall.getResourceList().then(res => {
setQuestions({loading: false, data: res.data?.ask_categories?.data})
}).catch(error => {
setQuestions({loading: false, data: []})
console.log('ERROR', error)
})
}, [])
return (
<Layout>
<>
<div className='mb-4'>
<CustomBreadcrumb
title={pathname == '/ai-question' ? 'Questions' : 'AI Lab'}
breadcrumb = {
[
{ link: "/", title: "Home" },
{ link: pathname == '/ai-question' ? '/ai-question' : '/ai-lab', title: pathname == '/ai-question' ? 'Questions' : 'AI Lab', active: true},
]
}
/>
</div>
<div className={`w-full`}>
<div className="main-container w-full">
<div className="filter-section w-fullmb-6">
{/* <h1 className="text-xl lg:text-2xl font-bold text-dark-gray dark:text-white tracking-wide">Ask our A.I</h1> */}
<div className="mt-2 lg:grid grid-cols-2 gap-2 h-full lg:h-[500px]">
<div className="h-full mb-5 lg:mb-0">
<img className="w-full h-full rounded-2xl" src={localImgLoad(`images/resources-ask.jpg`)} alt='AI' />
</div>
<div className="p-8 bg-white rounded-2xl h-full">
<div className="input-wrapper border border-[#f5f8fa] dark:border-[#5e6278] w-full rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding text-[#5e6278] dark:text-gray-100 bg-[#f5f8fa] dark:bg-[#5e6278] text-base">
<select value={askQuestion.question} name='question' onChange={changeAskQuestion} className="input-field px-2 placeholder:text-base text-dark-gray w-full h-full tracking-wide dark:bg-[#11131F] bg-[#fafafa] focus:ring-0 focus:outline-none">
{questions.loading ?
<option value='' className="">Loading...</option>
:
<>
<option value='' className="">Find answer on:</option>
{questions.data.length > 0 && questions.data.map((item, index)=>(
<option key={index} value={item.question_key} className="">{item.name}</option>
))}
</>
}
</select>
</div>
{error.question && <p className="text-red-500 text-[12px]">{error.question}</p>}
{/* filter-search */}
<div className="w-full my-5 border-2 rounded-full">
<SearchCom
name={'searchPhrase'}
value={askQuestion.searchPhrase}
handleSearch={changeAskQuestion}
/>
</div>
{error.searchPhrase && <p className="text-red-500 text-[12px]">{error.searchPhrase}</p>}
<div className="w-full flex justify-end items-center border-b-2 pb-4">
<button
onClick={onSearch}
disabled={requestStatus.loading}
className="btn-gradient text-base tracking-wide px-4 py-2 rounded-full text-white cursor-pointer"
>
Search
</button>
</div>
<div className="search_result my-2 max-h-[400px] overflow-auto">
{requestStatus.loading ?
<LoadingSpinner size='8' color='sky-blue' height='h-[100px]' />
:
<p className="py-2 text-sm font-bold text-dark-gray dark:text-white tracking-wide">{requestStatus.message}</p>
}
</div>
</div>
</div>
</div>
</div>
</div>
</>
</Layout>
)
}
+108
View File
@@ -0,0 +1,108 @@
import React, { useEffect, useState } from 'react'
import Layout from '../Partials/Layout'
import SearchCom from '../Helpers/SearchCom'
import DataIteration from '../Helpers/DataIteration'
import FamBlogItem from './FamBlogItem'
import CustomBreadcrumb from '../Breadcrumb/CustomBreadcrumb'
import usersService from '../../services/UsersService'
import LoadingSpinner from '../Spinners/LoadingSpinner'
export default function FamBlog() {
const [blogData, setBlogData] = useState({loading: true, data: []});
const [filteredBlog, setFilteredBlog] = useState({value: '', data:[]}) // State to hold filter blog
const handleFilterBlog = ({target}) => {
let filterWord = target.value
let filteredData = []
if(!filterWord){
filteredData = blogData?.data?.blogdata
}else{
filteredData = blogData?.data?.blogdata?.filter(item => item.post_title.toLowerCase().startsWith(filterWord.toLowerCase()))
}
setFilteredBlog({value:target.value, data: filteredData})
}
const api = new usersService();
const getFamilyBlog = async () => {
setBlogData({loading: true, data: []})
try {
const res = await api.getFamilyBlogData();
setBlogData({loading: false, data:res.data});
setFilteredBlog(prev => ({...prev, data:res.data?.blogdata}))
} catch (error) {
setBlogData({loading: false, data: []})
throw new Error("Error getting mode");
}
};
useEffect(() => {
getFamilyBlog();
}, []);
return (
<Layout>
<>
<div className='mb-4'>
<CustomBreadcrumb
title='Blog'
breadcrumb = {
[
{ link: "/", title: "Home" },
{ link: "/fam-blog", title: "Blogs", active: true},
]
}
/>
</div>
<div className={`w-full`}>
<div className="main-container w-full">
<div className="filter-section w-full items-center sm:flex justify-between mb-6">
{/* filter-search */}
{blogData?.data?.blogdata?.length > 0 &&
<div className="sm:w-1/2 w-full sm:pr-20 pr-0 mb-5 sm:mb-0">
<SearchCom
placeholder='Search Blog Items...'
value={filteredBlog.value}
handleSearch={handleFilterBlog}
/>
</div>
}
</div>
<div className="content-section w-full-width">
{blogData.loading ?
<div className='flex justify-center items-center bg-white rounded-2xl'>
<LoadingSpinner size='10' color='sky-blue' height='h-[20rem]' />
</div>
: blogData?.data?.blogdata?.length > 0 && filteredBlog?.data?.length > 0?
<div className="grid lg:grid-cols-3 sm:grid-cols-2 grid-cols-1 gap-[30px]">
<DataIteration
datas={filteredBlog?.data}
startLength={process.env.REACT_APP_ZERO_STATE}
endLength={filteredBlog?.data?.length}
>
{({ datas }) => (
<div key={Math.random()}>
<FamBlogItem
datas={datas}
bg={blogData?.data?.image_url && blogData?.data?.image_url}
className=''
hidden={false}
/>
</div>
)}
</DataIteration>
</div>
:
<div className='h-[30rem] flex justify-center items-center bg-white rounded-2xl'>
<p>No Blog Found</p>
</div>
}
</div>
</div>
</div>
</>
</Layout>
)
}
@@ -0,0 +1,54 @@
import React from 'react'
import { Link } from 'react-router-dom';
export default function FamBlogItem({datas, className, bg, hidden=false}) {
return (
<div
className={`card-style-two w-full h-[336px] p-[20px] bg-white dark:bg-dark-white rounded-2xl section-shadow ${
className || ""
}`}
>
<div className="flex flex-col justify-between w-full h-full">
<div className="thumbnail-area w-full">
<div
className="w-full h-[236px] p-6 rounded-xl overflow-hidden bg-sky-200"
style={{
background: `url(${`${bg}${datas.meta_value}`}) 0% 0% / cover no-repeat`,
}}
>
<div className="product-two-options flex justify-between mb-5 relative">
<div className="status">
{datas?.isActive && (
<span className="text-xs px-3 py-1.5 tracking-wide rounded-full bg-gold text-white">
Active
</span>
)}
</div>
</div>
{hidden && <div className="flex justify-center"></div>}
</div>
</div>
<div className="details-area">
{/* title */}
<Link to={`/blog-page?blog_id=${datas?.ID ? datas.ID : '1'}`} className="mb-2.5" rel="noreferrer">
<h1 className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
{datas?.post_title ? datas?.post_title : "dummy title..."}
</h1>
</Link>
<div className="flex justify-between">
<div className="flex items-center space-x-2"></div>
<div className="my-1">
<Link
to={`/blog-page?blog_id=${datas?.ID ? datas.ID : '1'}`}
className="px-4 py-2.5 text-white text-sm bg-pink rounded-full tracking-wide"
rel="noreferrer"
>
View
</Link>
</div>
</div>
</div>
</div>
</div>
);
}
@@ -0,0 +1,10 @@
import React from 'react'
import Layout from '../Partials/Layout'
export default function FamGames() {
return (
<Layout>
<div>Family Games Page</div>
</Layout>
)
}
@@ -0,0 +1,10 @@
import React from 'react'
import Layout from '../Partials/Layout'
export default function FamInterest() {
return (
<Layout>
<div>Fam Interesting Dummy Page</div>
</Layout>
)
}
@@ -0,0 +1,180 @@
import React, { useState } from "react";
import { Link } from "react-router-dom";
import defaultImg from "../../assets/images/myfiles/default.svg";
import localImgLoad from "../../lib/localImgLoad";
import { PaginatedList, handlePagingFunc } from "../../components/Pagination";
import Layout from "../Partials/Layout";
import CustomBreadcrumb from "../Breadcrumb/CustomBreadcrumb";
export default function FamMyFiles() {
let uploadedFiles = [] // To be updated Later from replaced with real data 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 currentFiles = uploadedFiles?.data?.slice(
indexOfFirstItem,
indexOfLastItem
);
const handlePagination = (e) => {
handlePagingFunc(e, setCurrentPage);
};
return (
<Layout>
<>
<div className=''>
<CustomBreadcrumb
title='My Files'
breadcrumb = {
[
{ link: "/", title: "Home" },
{ link: "/myfiles", title: "My Files", active: true},
]
}
/>
</div>
<div className="mb-4 w-full flex justify-end item-center">
<Link
to="/my-uploads"
className="btn-gradient lg:flex hidden w-[153px] h-[46px] rounded-full text-white justify-center items-center"
>
Add My Item
</Link>
</div>
<div
className={`update-table w-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow relative min-h-[520px]`}
>
<div className="header w-full sm:flex justify-between items-center mb-5">
<div className="flex space-x-2 items-center mb-2 sm:mb-0">
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-wide">
My Uploads
</h1>
</div>
</div>
<div className="relative w-full overflow-x-auto sm:rounded-lg">
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
<tbody>
<>
{uploadedFiles?.data && uploadedFiles?.data.length ? (
currentFiles.map((value, idx) => {
let addedDate = value?.added?.split(" ")[0];
let formattedSize = formatFileSize(value?.file_size);
let imageLink = `${uploadedFiles?.image}${localStorage.getItem('session_token')}/myfile/${value.file_uid}`
return (
<tr
key={value?.file_uid}
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-[60px] h-[60px] p-2 bg-alice-blue rounded-full overflow-hidden flex justify-center items-center">
<img
src={
localImgLoad(
`images/myfiles/${value.banner}`
) || defaultImg
}
alt="data"
className="w-full h-full rounded-full"
/>
</div>
<div className="flex flex-col flex-[0.9]">
<h1 className="font-bold text-xl text-dark-gray dark:text-white">
{value.title || "Dummy Text"}
</h1>
<div>
{value.description || "Dummy Description"}
</div>
<span className="text-sm text-thin-light-gray flex flext-start gap-1">
Added:{" "}
<span className="text-purple">{addedDate}</span>
</span>
<div className="flex gap-4 items-center">
<span className="text-sm text-thin-light-gray">
File Name:{" "}
<span className="text-purple">
{" "}
{value.file_name}
</span>
</span>
<span className="text-sm text-thin-light-gray">
File Size:{" "}
<span className="text-purple">
{" "}
{formattedSize}
</span>
</span>
<span className="text-sm text-thin-light-gray">
File Type:{" "}
<span className="text-purple">
{" "}
{value?.file_type}
</span>
</span>
</div>
</div>
</div>
</td>
<td className="text-right py-4 px-2">
<div className="flex justify-center items-center">
<a
href={imageLink}
title="download"
// className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
<img
src={localImgLoad('images/icons/download-arrow.svg')}
alt='download-link'
className="w-auto h-6 flex justify-center items-center"
/>
</a>
</div>
</td>
</tr>
);
})
) : (
<tr className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
<td className="p-2" colSpan={3}>
No Files Currently!
</td>
</tr>
)}
</>
</tbody>
</table>
{/* PAGINATION BUTTON */}
<PaginatedList
onClick={handlePagination}
prev={currentPage == 0 ? true : false}
next={
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >=
uploadedFiles?.data?.length
? true
: false
}
data={uploadedFiles?.data}
start={indexOfFirstItem}
stop={indexOfLastItem}
/>
{/* END OF PAGINATION BUTTON */}
</div>
</div>
</>
</Layout>
);
}
const formatFileSize = (sizeInBytes) => {
if (sizeInBytes < 1024) {
return `${sizeInBytes} bytes`;
} else if (sizeInBytes < 1024 * 1024) {
const sizeInKB = (sizeInBytes / 1024).toFixed(2);
return `${sizeInKB} KB`;
} else {
const sizeInMB = (sizeInBytes / (1024 * 1024)).toFixed(2);
return `${sizeInMB} MB`;
}
};
@@ -0,0 +1,24 @@
import React from 'react'
import Layout from '../Partials/Layout'
import CustomBreadcrumb from '../Breadcrumb/CustomBreadcrumb'
export default function FamWorkInProgress() {
return (
<Layout>
<>
<div className='mb-4'>
<CustomBreadcrumb
title='Games and Interest'
breadcrumb = {
[
{ link: "/", title: "Home" },
{ link: "/work-in-progress", title: "Games and Interest", active: true},
]
}
/>
</div>
<div className='h-[20rem] w-full bg-white shadow-lg flex justify-center items-center rounded-2xl'>Work in Progress Coming Soon</div>
</>
</Layout>
)
}
+1 -2
View File
@@ -52,9 +52,8 @@
} }
.job-action { .job-action {
background-color: #4687ba; background-color: #4687ba;
height: 100px;
border-radius: 15px; border-radius: 15px;
padding: 5px; padding: 3px;
} }
.msg_box { .msg_box {
+4 -16
View File
@@ -264,8 +264,9 @@ const AuthRoute = ({ redirectPath = "/login", children }) => {
// setFamilyBannersList({loading:true, result:[]}); // setFamilyBannersList({loading:true, result:[]});
try { try {
const res = await apiCall.getFamilyBannersList(); const res = await apiCall.getFamilyBannersList();
dispatch(familyBannersList(res.data)) dispatch(familyBannersList({...res.data, loading:false}))
} catch (error) { } catch (error) {
dispatch(familyBannersList({loading:false}))
console.log("Error getting tasks"); console.log("Error getting tasks");
} }
}; };
@@ -287,23 +288,10 @@ const AuthRoute = ({ redirectPath = "/login", children }) => {
} }
}; };
getFamilyResourcesList() getFamilyResourcesList()
}, [isLogin.status, familyBannersListTable]); }, [isLogin.status]);
// useEffect(() => {
// apiCall
// .getHeroJBanners()
// .then((res) => {
// if (res.data.internal_return < 0) {
// return;
// }
// dispatch(commonHeadBanner(res.data));
// })
// .catch((error) => {
// console.log("ERROR ", error);
// });
// }, []);
//
// RENDER PAGE
return isLogin.loading && !loggedIn ? ( return isLogin.loading && !loggedIn ? (
<LoadingSpinner size="32" color="sky-blue" height="h-screen" /> <LoadingSpinner size="32" color="sky-blue" height="h-screen" />
) : !isLogin.status && !loggedIn ? ( ) : !isLogin.status && !loggedIn ? (
+18
View File
@@ -31,6 +31,10 @@ class usersService {
return this.postAuxEnd("/createuser", reqData); return this.postAuxEnd("/createuser", reqData);
} }
blogData() {
return this.getAuxEnd("/blogdata", null);
}
CompleteOauthLogin(reqData) { CompleteOauthLogin(reqData) {
localStorage.setItem("session_token", ``); localStorage.setItem("session_token", ``);
return this.postAuxEnd("/authlogin", reqData); return this.postAuxEnd("/authlogin", reqData);
@@ -1275,6 +1279,20 @@ class usersService {
}; };
return this.postAuxEnd("/familyresources", postData); return this.postAuxEnd("/familyresources", postData);
} }
// API FUNCTION TO GET FAMILY BLOG DATA
getFamilyBlogData() {
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("/blogdata", postData);
}
/* /*
- 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(username) - 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(username)
- 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(password) - 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(password)
+1 -1
View File
@@ -1,7 +1,7 @@
import { createSlice } from "@reduxjs/toolkit"; import { createSlice } from "@reduxjs/toolkit";
const initialState = { const initialState = {
familyBannersList: {} familyBannersList: {loading:true}
}; };
export const familyBannersListSlice = createSlice({ export const familyBannersListSlice = createSlice({
+10
View File
@@ -0,0 +1,10 @@
import React from 'react'
import FamAIQuestion from '../components/familyResources/FamAIQuestion'
export default function FamAIQuestionPage() {
return (
<>
<FamAIQuestion />
</>
)
}
+10
View File
@@ -0,0 +1,10 @@
import React from 'react'
import FamBlog from '../components/familyResources/FamBlog'
export default function FamBlogPage() {
return (
<>
<FamBlog />
</>
)
}
+9
View File
@@ -0,0 +1,9 @@
import React from 'react'
import FamGames from '../components/familyResources/FamGames'
export default function FamGamesPage() {
return (
<>
<FamGames />
</>
)
}
+10
View File
@@ -0,0 +1,10 @@
import React from 'react'
import FamInterest from '../components/familyResources/FamInterest'
export default function FamInterestPage() {
return (
<>
<FamInterest />
</>
)
}
+10
View File
@@ -0,0 +1,10 @@
import React from 'react'
import FamMyFiles from '../components/familyResources/FamMyFiles'
export default function FamMyFilesPage() {
return (
<>
<FamMyFiles />
</>
)
}
+10
View File
@@ -0,0 +1,10 @@
import React from 'react'
import FamWorkInProgress from '../components/familyResources/FamWorkInProgress'
export default function FamWorkInProgressPage() {
return (
<>
<FamWorkInProgress />
</>
)
}
+12
View File
@@ -0,0 +1,12 @@
import React from "react";
import FamilyActivities from "../components/FamilyAcc/FamilyActivities";
const FamilyActivitiesPage = () => {
return (
<>
<FamilyActivities />
</>
);
};
export default FamilyActivitiesPage;
+10
View File
@@ -0,0 +1,10 @@
import React from 'react'
import FamilyPending from '../components/FamilyAcc/FamilyPendingOffer'
export default function FamilyPendingOfferPage() {
return (
<>
<FamilyPending />
</>
)
}
+5
View File
@@ -0,0 +1,5 @@
import FamilyWallet from "../components/MyWallet/FamilyWallet";
export default function FamilyWalletPage() {
return <FamilyWallet />;
}
+1 -1
View File
@@ -39,7 +39,7 @@ function ManageActiveJobs() {
loading: false, loading: false,
error: false, error: false,
data: res.data.result_list, data: res.data.result_list,
image: res.data.session_image_server image: res.data.session_image_server,
}); });
}) })
.catch((error) => { .catch((error) => {
+2 -3
View File
@@ -1,7 +1,6 @@
import React, { useContext,useState, useEffect } from "react"; import React, { useContext,useState, useEffect } from "react";
import usersService from "../services/UsersService"; import usersService from "../services/UsersService";
//import MyJobs from "../components/MyJobs";
//import MyActiveJobs from "../components/MyActiveJobs";
import MyPastDueJobs from "../components/MyActiveJobs/MyPastDueJobs"; import MyPastDueJobs from "../components/MyActiveJobs/MyPastDueJobs";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
@@ -9,7 +8,7 @@ export default function MyPastDueJobsPage() {
let {commonHeadBanner} = useSelector(state => state.commonHeadBanner) let {commonHeadBanner} = useSelector(state => state.commonHeadBanner)
const [MyJobList, setMyJobList] = useState([]); const [MyJobList, setMyJobList] = useState([]);
const api = new usersService(); const api = new usersService();
//TARGET ENDPOINT[POST]http://10.204.5.100:9083/en/wrench/api/v1/jobmanageractive
const getMyJobList = async () => { const getMyJobList = async () => {
try { try {
const res = await api.getMyPastDueJobList(); const res = await api.getMyPastDueJobList();
+36
View File
@@ -0,0 +1,36 @@
import React, { useContext,useState, useEffect } from "react";
import usersService from "../services/UsersService";
import MyPastDueTasks from "../components/MyActiveJobs/MyPastDueTasks";
import { useSelector } from "react-redux";
export default function MyPastDueTasksPage() {
let {commonHeadBanner} = useSelector(state => state.commonHeadBanner)
const [MyJobList, setMyJobList] = useState({loading:true, data:[]});
const api = new usersService();
const getMyJobList = async () => {
try {
const res = await api.getMyPastDueJobList();
console.log("DATA", res.data);
setMyJobList({loading:false, data:res.data})
} catch (error) {
setMyJobList({loading:false, data:[]})
console.log("Error getting mode");
}
};
useEffect(() => {
getMyJobList();
}, []);
// debugger;
return (
<>
<MyPastDueTasks
MyJobList={MyJobList?.data}
loading={MyJobList?.loading}
commonHeadData={commonHeadBanner?.result_list}
/>
</>
);
}
+10
View File
@@ -0,0 +1,10 @@
import React from 'react'
import ParentWaitingLayout from '../components/FamilyAcc/ParentWaiting'
export default function ParentWaitingPage() {
return (
<>
<ParentWaitingLayout />
</>
)
}
-1
View File
@@ -6,7 +6,6 @@ export default function ResourcePage() {
const {state, pathname} = useLocation() // CHECKS IF THERE IS AN ACTIVE TAB WITH LINK BACK TO RESOURCES const {state, pathname} = useLocation() // CHECKS IF THERE IS AN ACTIVE TAB WITH LINK BACK TO RESOURCES
const [MyResourceData, setMyResourceData] = useState([]); const [MyResourceData, setMyResourceData] = useState([]);
const api = new usersService(); const api = new usersService();
const getMyResourceData = async () => { const getMyResourceData = async () => {
try { try {
const res = await api.getResourceList(); const res = await api.getResourceList();
+3
View File
@@ -23,6 +23,9 @@ module.exports = {
screens:{ screens:{
xxs: '400px', xxs: '400px',
xxl:'1900px' xxl:'1900px'
},
backgroundImage: {
'family-header-bg': "linear-gradient(90deg, rgba(45,126,241,1) 0%, rgba(58,143,195,1) 0%, rgba(11,100,119,1) 100%)",
} }
}, },
}, },