Compare commits

...

25 Commits

Author SHA1 Message Date
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
52 changed files with 1386 additions and 556 deletions
+14 -4
View File
@@ -59,7 +59,12 @@ import VerifyYouPagesTwo from "./views/VerifyYouPagesTwo";
import YourPages from "./views/YourPage_";
import ParentWaitingPage from "./views/ParentWaitingPage";
import FamilyPendingOfferPage from "./views/FamilyPendingOfferPage";
import FamilyPastDuePage from "./views/FamilyPastDuePage";
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";
export default function Routers() {
return (
@@ -120,26 +125,31 @@ export default function Routers() {
<Route exact path="/notification" element={<Notification />} />
<Route exact path="/market-place" element={<MarketPlacePage />} />
<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="/tracking" element={<TrackingPage />} />
<Route exact path="/calendar" element={<CalendarPage />} />
<Route exact path="/resources" element={<ResourcePage />} />
<Route exact path="/my-wallet/*" element={<MyWalletPage />} />
<Route exact path="/family-wallet" element={<FamilyWalletPage />} />
<Route exact path="/my-coupon" element={<MyCouponPage />} />
<Route exact path="/notification" element={<Notification />} />
<Route exact path="/market-place" element={<MarketPlacePage />} />
<Route exact path="/market" element={<MarketPlacePage />} />
<Route exact path="/familymarket" element={<FamilyMarketPage />} />
<Route exact path="/suggested" element={<ParentWaitingPage />} />
<Route exact path="/pastdue" element={<FamilyPastDuePage />} />
<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
exact
path="/familysettings"
element={<FamilySettingsPage />}
/>
<Route exact path="/pastdue" element={<MyPastDueTasksPage />} />
<Route exact path="/notification" element={<Notification />} />
<Route exact path="/mytask" element={<MyTaskPage />} />
<Route exact path="/myjobs" element={<MyJobsPage />} />
+32 -11
View File
@@ -4,9 +4,15 @@ import usersService from "../../services/UsersService";
import Layout from "../Partials/Layout";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import CommonHead from "../UserHeader/CommonHead";
import { useSelector } from "react-redux";
import CustomBreadcrumb from "../Breadcrumb/CustomBreadcrumb";
export default function BlogItem(props) {
const {
userDetails: { account_type },
} = useSelector((state) => state?.userDetails); // CHECKS IF USER Details account type
const apiCall = new usersService()
const navigate = useNavigate()
@@ -33,11 +39,26 @@ export default function BlogItem(props) {
},[blog_id])
return (
<Layout>
<CommonHead
commonHeadData={props.commonHeadData}
/>
{account_type == 'FULL' &&
<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="mb-5">
{/* <div className="mb-5">
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
<span
className={`${selectTab === "today" ? "block" : "hidden"}`}
@@ -45,7 +66,7 @@ export default function BlogItem(props) {
{blogdata.data?.blogdata?.[0]?.post_title}
</span>
</h1>
</div>
</div> */}
<div className="notification-wrapper w-full bg-white p-8 rounded-2xl">
{blogdata?.loading ?
<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 ?
<div className="w-full">
{/* heading */}
<div className="sm:flex justify-between items-center mb-6">
{/* <div className="mb-5">
{/* <div className="sm:flex justify-between items-center mb-6">
<div className="mb-5">
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
<span
className={`${selectTab === "today" ? "block" : "hidden"}`}
@@ -62,10 +83,10 @@ export default function BlogItem(props) {
{blogdata.data?.blogdata?.[0]?.post_title}
</span>
</h1>
</div> */}
{/* <div className="slider-btns flex space-x-4">
</div> */}
</div>
</div>
<div className="slider-btns flex space-x-4">
</div>
</div> */}
<div dangerouslySetInnerHTML={{__html: blogdata.data?.blogdata?.[0]?.post_content}}>
</div>
</div>
@@ -1,5 +1,4 @@
import React from "react";
import CountDown from "../Helpers/CountDown";
// import HomeSliders from "./HomeSliders";
import { useSelector } from "react-redux";
@@ -41,39 +40,6 @@ export default function FamilyParentDashboard({
</p>
</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">
Last Login : {loginDate}
</span>
@@ -1,5 +1,4 @@
import React from "react";
import CountDown from "../Helpers/CountDown";
// import HomeSliders from "./HomeSliders";
import { useSelector } from "react-redux";
@@ -38,38 +37,6 @@ export default function HomeDashboard({ className, bannerList, nextDueTask }) {
</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">
Last Login : {loginDate}
</span>
@@ -1,5 +1,4 @@
import React from "react";
import CountDown from "../Helpers/CountDown";
// import HomeSliders from "./HomeSliders";
import { useSelector } from "react-redux";
@@ -42,38 +41,6 @@ export default function JobOwnerDashboard({
</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">
Last Login : {loginDate}
</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 { 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 CountDown from "../Helpers/CountDown";
// import HomeSliders from "./HomeSliders";
import { useSelector } from "react-redux";
import HomeSliders from "../Home/HomeSliders";
export default function WorkerDashboard({ className, bannerList, nextDueTask }) {
export default function WorkerDashboard({
className,
bannerList,
nextDueTask,
}) {
const settings = {
autoplay: true,
dots: true,
@@ -57,32 +59,37 @@ export default function WorkerDashboard({ className, bannerList, nextDueTask })
</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>
{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>
</div>
)}
)}
{/* action */}
<div className="flex lg:space-x-3 space-x-1 items-center">
<Link to="/mytask" className="text-white text-base">
@@ -1,5 +1,4 @@
import React from "react";
import CountDown from "../Helpers/CountDown";
// import HomeSliders from "./HomeSliders";
import { useSelector } from "react-redux";
@@ -41,39 +40,6 @@ export default function WorkerDashboard({
</p>
</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">
Last Login : {loginDate}
</span>
+13 -1
View File
@@ -4,6 +4,7 @@ import SearchCom from "../Helpers/SearchCom";
import FamilyMarketCard from "../Cards/FamilyMarketCard";
import usersService from "../../services/UsersService";
import SuggestTask from "../FamilyPopup/SuggestTask";
import CustomBreadcrumb from "../Breadcrumb/CustomBreadcrumb";
export default function FamilyMarket() {
const [popUp, setPopUp] = useState(false);
@@ -53,12 +54,23 @@ export default function FamilyMarket() {
<div className="notification-page w-full mb-10">
<div className="notification-wrapper w-full">
{/* heading */}
<div className="sm:flex justify-between items-center mb-6">
{/* <div className="sm:flex 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>Suggest Task to the Parents</span>
</h1>
</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>
{/* Body */}
<div className="filter-section w-full items-center sm:flex justify-between mb-6">
@@ -3,6 +3,7 @@ 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();
@@ -25,8 +26,21 @@ export default function FamilyPendingOffer() {
},[])
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
+25 -9
View File
@@ -19,7 +19,7 @@ export default function FamilyTable({
familyList,
loader,
popUpHandler,
imageServer
imageServer,
}) {
const navigate = useNavigate();
const [currentPage, setCurrentPage] = useState(0);
@@ -55,14 +55,19 @@ export default function FamilyTable({
banner,
enable_traking,
profile_picture,
imageServer
imageServer,
username,
}) => {
// Check for valid dates
const addedDate = added ? added.split(" ")[0] : "N/A";
const loginDate = last_login ? formatDateString(last_login) : "N/A";
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 =
enable_traking === "0"
? "Stopped"
@@ -80,14 +85,19 @@ export default function FamilyTable({
<div className="w-[60px] h-[60px] rounded-full overflow-hidden flex justify-center items-center">
<img
// src={profile_picture}
src={image || profile_picture || localImgLoad(`images/icons/${banner}`)}
src={
image ||
profile_picture ||
localImgLoad(`images/icons/${banner}`)
}
alt={`Avatar of ${firstname} ${lastname}`}
className="w-full h-full"
/>
</div>
<div className="flex flex-col flex-[0.9]">
<h1 className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
{`${firstname} ${lastname} (${age < 10 ? `0${age}` : age})`}
<h1 className="font-bold text-lg text-dark-gray dark:text-white whitespace-nowrap">
{`${firstname} ${lastname}`}{" "}
<span className="ml-1 text-sm">{`[${username}]`}</span>
</h1>
<span className="text-sm text-thin-light-gray">
Added: <span className="text-purple ml-1">{addedDate}</span>
@@ -136,7 +146,7 @@ export default function FamilyTable({
task_count,
family_uid,
banner,
image
image,
})
}
type="button"
@@ -186,7 +196,13 @@ export default function FamilyTable({
</thead>
<tbody className="h-full">
{currentFamilyList?.map((familyMember, index) => {
return <FamilyRow key={index} {...familyMember} imageServer={imageServer} />;
return (
<FamilyRow
key={index}
{...familyMember}
imageServer={imageServer}
/>
);
})}
</tbody>
</table>
@@ -14,6 +14,7 @@ export default function InputCom({
forgotPassword,
parentClass,
labelClass,
labalClass,
inputClass,
fieldClass,
onClick,
@@ -53,7 +54,7 @@ export default function InputCom({
<div className={`flex items-center justify-between mb-2.5 ${labelClass}`}>
{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}
>
{label}
+16 -54
View File
@@ -7,14 +7,14 @@ import { useDispatch, useSelector } from "react-redux";
import { tableReload } from "../../store/TableReloads";
import LoadingSpinner from "../Spinners/LoadingSpinner";
export default function FamilyDash({ MyActiveJobList, serverImg }) {
export default function FamilyDash({ MyActiveJobList=[], serverImg }) {
// console.log("PROPS IN FAMILY DASH->", familyOffers?.result_list);
const dispatch = useDispatch();
const userApi = new usersService();
const trending = MyActiveJobList;
// const trending = MyActiveJobList;
const { familyBannersList } = useSelector((state) => state.familyBannersList);
@@ -24,25 +24,6 @@ export default function FamilyDash({ MyActiveJobList, serverImg }) {
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(()=>{
if(reloadBanner >= 2){
dispatch(tableReload({ type: "FAMILYBANNERSLIST" })); // RELOAD FAMILY BANNERS LIST EVERY 10 MINS
@@ -60,17 +41,17 @@ export default function FamilyDash({ MyActiveJobList, serverImg }) {
return (
<div>
<div className="home-page-wrapper">
{/* <CommonHead commonHeadData={props.commonHeadData} /> */}
{/* Header */}
<div className="text-white mb-4 p-2 w-full rounded-xl bg-sky-blue place-content-center">
<div className="w-full flex flex-wrap gap-x-4">
<p className="text-lg font-normal leading-5">Welcome</p>
<div className="">
<h1 className="text-lg font-normal leading-5">{`${userDetails?.firstname} ${userDetails?.lastname}`}</h1>
<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">
<div className="w-full flex flex-wrap gap-x-4 ">
<p className="text-lg font-normal leading-5">Welcome</p>
<div className="">
<h1 className="text-lg font-normal leading-5">{`${userDetails?.firstname} ${userDetails?.lastname}`}</h1>
</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 className="leading-4">Last Login: {`${userDetails?.last_login.split(' ')[0]}`}</p>
</div>
</div>
@@ -112,29 +93,10 @@ export default function FamilyDash({ MyActiveJobList, serverImg }) {
<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">
{tab_categories.data.map((item) => {
// onClick={()=>navigate('/resources', {state:{tab:'created'}})}
let resourceState = ''
switch(item?.action){
case 'fam-blog':
resourceState = 'blog'
break
case 'ai-question':
resourceState = 'onsale'
break
case 'myfiles':
resourceState = 'created'
break
case 'ai-lab':
resourceState = 'onsale'
break
default:
resourceState = 'blog'
break
}
// console.log('EX', item.enabled, item?.action, resourceState)
if(item.enabled){
// if(item.enabled){
// }
return (
<Link key={item.uid} to={'/resources'} state={{tab:resourceState}} className={`group 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="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' />
@@ -151,7 +113,7 @@ export default function FamilyDash({ MyActiveJobList, serverImg }) {
</div>
</div>
</Link>
)}
)
})}
</div>
</div>
@@ -167,13 +129,13 @@ export default function FamilyDash({ MyActiveJobList, serverImg }) {
/>
)} */}
{trending && trending.length > 0 && (
{/* {trending && trending.length > 0 && (
<FamilyActiveLSlde
trending={trending}
className="mb-10"
image_server={serverImg}
/>
)}
)} */}
</div>
</div>
);
+2 -24
View File
@@ -58,17 +58,13 @@ export default function Home(props) {
useEffect(() => {
const fetchData = async () => {
await Promise.all([getHomeDate(), getMyOffersList()]);
await Promise.all([getHomeDate(), getMyOffersList(), getMyActiveJobList()]);
};
if(userDetails?.account_type == 'FULL'){
fetchData();
}
}, []);
useEffect(() => {
getMyActiveJobList();
}, []);
return (
<Layout>
<div className="home-page-wrapper">
@@ -78,7 +74,7 @@ export default function Home(props) {
commonHeadData={props.bannerList}
// familyOffers={MyOffersList?.data}
serverImg = {userDetails?.session_image_server}
MyActiveJobList={MyActiveJobList?.data}
// MyActiveJobList={MyActiveJobList?.data}
/>
) : userDetails && userDetails?.account_type == "FULL" ? (
<FullAccountDash
@@ -97,21 +93,3 @@ export default function Home(props) {
</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>
@@ -20,7 +20,7 @@ export default function ActiveJobMessage({ activeJobMesList }) {
return (
<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">
<thead className='border-b-2'>
<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" />
</svg>
</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}
</h1>
</div>
@@ -412,7 +412,7 @@ function ActiveJobs(props) {
</div>
{tab == "message" ? (
<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"
style={{ resize: "none" }}
name="message"
@@ -421,7 +421,7 @@ function ActiveJobs(props) {
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">
<label
htmlFor="file"
@@ -535,16 +535,23 @@ function ActiveJobs(props) {
{/* MESSAGE SECTION */}
<div className="w-full lg:w-1/2">
<div className="flex justify-between items-center gap-5">
<p className="text-lg font-bold text-dark-gray dark:text-white tracking-wide">
Message
<p className="w-full text-lg font-bold text-dark-gray dark:text-white tracking-wide flex items-center gap-2">
<span>Message</span>
<button
type="button"
onClick={popUpHandler}
className="text-[12px] tracking-wider text-emerald-600 dark:text-emerald-300"
>
View all
</button>
</p>
<button
{/* <button
type="button"
onClick={popUpHandler}
className="btn-gradient text-base tracking-wide px-4 py-2 rounded-full text-white cursor-pointer flex justify-center items-center"
>
View all
</button>
</button> */}
</div>
{props.activeJobMesList.loading ? (
<LoadingSpinner size="16" color="sky-blue" />
@@ -13,13 +13,6 @@ function CurrentJobAction() {
<div>
Waiting for the completion message from the client before you can approve.
</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>
</td>
</tr>
@@ -112,7 +112,7 @@ function ReviewJobAction({jobDetails}) {
<tr>
<td>
<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
</button>
</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>
);
}
+14 -2
View File
@@ -3,6 +3,7 @@ import { Link } from "react-router-dom";
import { toast } from "react-toastify";
import activeAidsBanner from "../../assets/images/kids-waiting.jpg";
import ParentWaitingTable from "./ParentWaitingTable";
import CustomBreadcrumb from "../Breadcrumb/CustomBreadcrumb";
export default function ParentWaiting({ className }) {
const [addFavorite, setValue] = useState(false);
@@ -19,9 +20,20 @@ export default function ParentWaiting({ className }) {
<>
<div className={`overview-section w-full ${className || ""}`}>
<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...
</h1>
</h1> */}
<CustomBreadcrumb
title = {'Waiting for Parent to Get Started...'}
breadcrumb={
[
{ link: "/", title: "Home" },
{ link: "/suggested", title: "Suggested", active: true},
]
}
/>
<Link
to='/familymarket'
className="px-4 h-10 flex justify-center items-center btn-gradient text-base rounded-full text-white"
+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 (
<div className="my-wallet-wrapper w-full mb-10">
<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">
{loading ? (
<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>
);
+184 -172
View File
@@ -7,8 +7,11 @@ import Icons from "../Helpers/Icons";
import Accordion from "../Helpers/Accordion";
import { PriceFormatter } from "../Helpers/PriceFormatter";
import localImgLoad from "../../lib/localImgLoad";
import { useSelector } from "react-redux";
export default function WalletHeader(props) {
const {userDetails: { account_type }} = useSelector((state) => state?.userDetails);
// debugger;
//props.myWalletList.result_list
let { pathname } = useLocation();
@@ -21,187 +24,196 @@ export default function WalletHeader(props) {
}
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">
<div
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>
<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
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>
{account_type == 'FULL' ?
<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">
<div
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>
<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 className="content px-7 pb-7">
<ul>
{props.myWalletList &&
props.myWalletList?.length > 0 &&
props.myWalletList.map((value, index) =>
{
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
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 className="content px-7 pb-7">
<ul>
{props.myWalletList &&
props.myWalletList?.length > 0 &&
props.myWalletList.map((value, index) =>
{
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 className="name">
<p className="text-2xl font-bold text-dark-gray dark:text-white">
{value.description}
<div>
<p className="eth text-xl font-bold text-purple">
{PriceFormatter(value.amount * 0.01, value.code)}
</p>
</div>
</div>
<div>
<p className="eth text-xl font-bold text-purple">
{PriceFormatter(value.amount * 0.01, value.code)}
</p>
</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">*/}
{/* <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={bank1} alt=""/>*/}
{/* </div>*/}
{/* <div className="name">*/}
{/* <p className="text-base text-dark-gray dark:text-white font-medium">*/}
{/* MetaMask*/}
{/* </p>*/}
{/* </div>*/}
{/* </div>*/}
{/* <div>*/}
{/* <p className="eth text-xl font-bold text-purple">*/}
{/* 75,320 ETH*/}
{/* </p>*/}
{/* <p className="usd text-base text-thin-light-gray text-right">*/}
{/* (773.69 USD)*/}
{/* </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">*/}
{/* <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={bank2} alt=""/>*/}
{/* </div>*/}
{/* <div className="name">*/}
{/* <p className="text-base text-dark-gray dark:text-white font-medium">*/}
{/* Coinbase Wallet*/}
{/* </p>*/}
{/* </div>*/}
{/* </div>*/}
{/* <div>*/}
{/* <p className="eth text-xl font-bold text-purple">*/}
{/* 56,124 ETH*/}
{/* </p>*/}
{/* <p className="usd text-base text-thin-light-gray text-right">*/}
{/* (773.69 USD)*/}
{/* </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">*/}
{/* <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={bank3} alt=""/>*/}
{/* </div>*/}
{/* <div className="name">*/}
{/* <p className="text-base text-dark-gray dark:text-white font-medium">*/}
{/* Bitski*/}
{/* </p>*/}
{/* </div>*/}
{/* </div>*/}
{/* <div>*/}
{/* <p className="eth text-xl font-bold text-purple">*/}
{/* 99,123 ETH*/}
{/* </p>*/}
{/* <p className="usd text-base text-thin-light-gray text-right">*/}
{/* (773.69 USD)*/}
{/* </p>*/}
{/* </div>*/}
{/* </div>*/}
{/*</li>*/}
{/*<li className="content-item py-5">*/}
{/* <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={bank4} alt=""/>*/}
{/* </div>*/}
{/* <div className="name">*/}
{/* <p className="text-base text-dark-gray dark:text-white font-medium">*/}
{/* WalletConnect*/}
{/* </p>*/}
{/* </div>*/}
{/* </div>*/}
{/* <div>*/}
{/* <p className="eth text-xl font-bold text-purple">*/}
{/* 43,728 ETH*/}
{/* </p>*/}
{/* <p className="usd text-base text-thin-light-gray text-right">*/}
{/* (773.69 USD)*/}
{/* </p>*/}
{/* </div>*/}
{/* </div>*/}
{/*</li>*/}
</ul>
<div className="add-money-btn flex justify-center items-center mt-3">
{/* <button
onClick={() => {
if(pathname == '/my-wallet') props.setBalanceDropdown.toggle()
else navigate('/my-wallet', {replace: true})
}}
type="button"
className="w-[122px] h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
Manage
</button> */}
<Link
to="/my-wallet"
onClick={onWalletClick}
className="w-[122px] h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
Manage
</Link>
{/*<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="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={bank1} alt=""/>*/}
{/* </div>*/}
{/* <div className="name">*/}
{/* <p className="text-base text-dark-gray dark:text-white font-medium">*/}
{/* MetaMask*/}
{/* </p>*/}
{/* </div>*/}
{/* </div>*/}
{/* <div>*/}
{/* <p className="eth text-xl font-bold text-purple">*/}
{/* 75,320 ETH*/}
{/* </p>*/}
{/* <p className="usd text-base text-thin-light-gray text-right">*/}
{/* (773.69 USD)*/}
{/* </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">*/}
{/* <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={bank2} alt=""/>*/}
{/* </div>*/}
{/* <div className="name">*/}
{/* <p className="text-base text-dark-gray dark:text-white font-medium">*/}
{/* Coinbase Wallet*/}
{/* </p>*/}
{/* </div>*/}
{/* </div>*/}
{/* <div>*/}
{/* <p className="eth text-xl font-bold text-purple">*/}
{/* 56,124 ETH*/}
{/* </p>*/}
{/* <p className="usd text-base text-thin-light-gray text-right">*/}
{/* (773.69 USD)*/}
{/* </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">*/}
{/* <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={bank3} alt=""/>*/}
{/* </div>*/}
{/* <div className="name">*/}
{/* <p className="text-base text-dark-gray dark:text-white font-medium">*/}
{/* Bitski*/}
{/* </p>*/}
{/* </div>*/}
{/* </div>*/}
{/* <div>*/}
{/* <p className="eth text-xl font-bold text-purple">*/}
{/* 99,123 ETH*/}
{/* </p>*/}
{/* <p className="usd text-base text-thin-light-gray text-right">*/}
{/* (773.69 USD)*/}
{/* </p>*/}
{/* </div>*/}
{/* </div>*/}
{/*</li>*/}
{/*<li className="content-item py-5">*/}
{/* <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={bank4} alt=""/>*/}
{/* </div>*/}
{/* <div className="name">*/}
{/* <p className="text-base text-dark-gray dark:text-white font-medium">*/}
{/* WalletConnect*/}
{/* </p>*/}
{/* </div>*/}
{/* </div>*/}
{/* <div>*/}
{/* <p className="eth text-xl font-bold text-purple">*/}
{/* 43,728 ETH*/}
{/* </p>*/}
{/* <p className="usd text-base text-thin-light-gray text-right">*/}
{/* (773.69 USD)*/}
{/* </p>*/}
{/* </div>*/}
{/* </div>*/}
{/*</li>*/}
</ul>
<div className="add-money-btn flex justify-center items-center mt-3">
{/* <button
onClick={() => {
if(pathname == '/my-wallet') props.setBalanceDropdown.toggle()
else navigate('/my-wallet', {replace: true})
}}
type="button"
className="w-[122px] h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
Manage
</button> */}
<Link
to="/my-wallet"
onClick={onWalletClick}
className="w-[122px] h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
>
Manage
</Link>
</div>
</div>
</div>
</div>
</div>
{/*<div*/}
{/* className="lg:hidden flex user-balance cursor-pointer lg:w-[252px] w-[150px] h-[48px] items-center rounded-full relative bg-purple">*/}
{/* <div className="flex items-center lg:justify-between justify-center w-full h-full">*/}
{/* <p className="lg:text-xl text-lg font-bold text-white">*/}
{/* $ 234,435.34*/}
{/* </p>*/}
{/* </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">
<div
onClick={() => navigate("/family-wallet", { replace: true })}
className="flex items-center lg:justify-between justify-center w-full h-full"
>
<span className="lg:block hidden">
<Icons name="wallet" />
</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>
</>
);
+1 -3
View File
@@ -34,9 +34,7 @@ export default function WalletItemCard({ walletItem, payment, countries }) {
dispatch(tableReload({ type: "WALLETTABLE" }));
};
const currentWalletCurrency = countries
// .map((country) => country)
.filter((country) => country.code === walletItem.country);
const currentWalletCurrency = countries?.filter((country) => country.code === walletItem.country);
const image = walletItem.code
? `${walletItem.code.toLowerCase()}.svg`
@@ -34,9 +34,7 @@ export default function WalletItemCardFamily({ walletItem, payment, countries })
dispatch(tableReload({ type: "WALLETTABLE" }));
};
const currentWalletCurrency = countries
// .map((country) => country)
.filter((country) => country.code === walletItem.country);
const currentWalletCurrency = countries?.filter((country) => country.code === walletItem.country);
const image = walletItem.code
? `${walletItem.code.toLowerCase()}.svg`
+4 -1
View File
@@ -20,6 +20,9 @@ import TimeDifference from "../Helpers/TimeDifference";
const DEFAULT_PROFILE_IMAGE = require("../../assets/images/profile.jpg");
export default function Header({ logoutModalHandler, sidebarHandler }) {
const {userDetails: { account_type }} = useSelector((state) => state?.userDetails);
const [balanceDropdown, setbalanceValue] = useToggle(false);
const [notificationDropdown, setNotificationValue] = useToggle(false);
const [userProfileDropdown, setProfileDropdown] = useToggle(false);
@@ -402,7 +405,7 @@ export default function Header({ logoutModalHandler, sidebarHandler }) {
</li>
)}
<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">
<p className="text-sm py-2 px-4 text-dark-gray dark:text-white hover:text-sky-blue transition font-medium">
My Wallet
+1 -1
View File
@@ -6,7 +6,7 @@ const LoadedPage = ({reloader}) => {
const { loading, data, error } = GetMyPageLoad(reloader);
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 ? (
<>
<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"
parentClass="flex items-center gap-1 justify-between"
labelClass="flex-[0.2] mb-0 font-semibold"
labalClass="dark:text-white"
inputClass="flex-[0.8]"
inputBg="bg-slate-100"
label="Introduction: "
@@ -24,7 +25,7 @@ const YourPageForm = ({ values, onChange, onSubmit, loading, msg }) => (
</label>
<textarea
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"
cols="30"
rows="2"
+33 -42
View File
@@ -13,12 +13,39 @@ const YourPage = () => {
const handleChange = ({ target: { name, value } }) =>
setPageValues((prev) => ({ ...prev, [name]: value }));
const updateYourPageDetails = updateYourPage(
pageValues,
setResponse,
setPageValues,
setReloader
);
const updateYourPageDetails = 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: "",
});
}
};
return (
<Layout>
@@ -57,39 +84,3 @@ const responseInitialValues = {
error: "",
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>
);
}
@@ -1,10 +1,10 @@
import React from 'react'
import Layout from '../Partials/Layout'
export default function FamilyPastDue() {
export default function FamGames() {
return (
<Layout>
<div>Family PastDue Page Here</div>
<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 {
background-color: #4687ba;
height: 100px;
border-radius: 15px;
padding: 5px;
padding: 3px;
}
.msg_box {
+2 -15
View File
@@ -288,23 +288,10 @@ const AuthRoute = ({ redirectPath = "/login", children }) => {
}
};
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 ? (
<LoadingSpinner size="32" color="sky-blue" height="h-screen" />
) : !isLogin.status && !loggedIn ? (
+14
View File
@@ -1279,6 +1279,20 @@ class usersService {
};
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(password)
+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 />
</>
)
}
-10
View File
@@ -1,10 +0,0 @@
import React from 'react'
import FamilyPastDue from '../components/FamilyAcc/FamilyPastDue'
export default function FamilyPastDuePage() {
return (
<>
<FamilyPastDue />
</>
)
}
+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,
error: false,
data: res.data.result_list,
image: res.data.session_image_server
image: res.data.session_image_server,
});
})
.catch((error) => {
+2 -3
View File
@@ -1,7 +1,6 @@
import React, { useContext,useState, useEffect } from "react";
import usersService from "../services/UsersService";
//import MyJobs from "../components/MyJobs";
//import MyActiveJobs from "../components/MyActiveJobs";
import MyPastDueJobs from "../components/MyActiveJobs/MyPastDueJobs";
import { useSelector } from "react-redux";
@@ -9,7 +8,7 @@ export default function MyPastDueJobsPage() {
let {commonHeadBanner} = useSelector(state => state.commonHeadBanner)
const [MyJobList, setMyJobList] = useState([]);
const api = new usersService();
//TARGET ENDPOINT[POST]http://10.204.5.100:9083/en/wrench/api/v1/jobmanageractive
const getMyJobList = async () => {
try {
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}
/>
</>
);
}
+3
View File
@@ -23,6 +23,9 @@ module.exports = {
screens:{
xxs: '400px',
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%)",
}
},
},