Compare commits

..

15 Commits

11 changed files with 213 additions and 36 deletions
+2
View File
@@ -50,6 +50,7 @@ import FamilyMarketPage from "./views/FamilyMarketPage";
import FacebookRedirect from "./views/FacebookRedirect";
import AppleRedirectPage from "./views/AppleRedirectPage";
import LndPage from "./views/LndPage";
import FamilySettingsPage from "./views/FamilySettingsPage";
export default function Routers() {
return (
@@ -98,6 +99,7 @@ export default function Routers() {
<Route exact path="/market-place" element={<MarketPlacePage />} />
<Route exact path="/market" element={<MarketPlacePage />} />
<Route exact path="/familymarket" element={<FamilyMarketPage />} />
<Route exact path="/familysettings" element={<FamilySettingsPage />} />
<Route exact path="/notification" element={<Notification />} />
<Route exact path="/mytask" element={<MyTaskPage />} />
<Route exact path="/myjobs" element={<MyJobsPage />} />
@@ -5,6 +5,8 @@ import { PriceFormatter } from "../../Helpers/PriceFormatter";
import LoadingSpinner from "../../Spinners/LoadingSpinner";
import Detail from "../../jobPopout/popoutcomponent/Detail";
import { NewTasks } from "./forms";
import { tableReload } from "../../../store/TableReloads";
import { useDispatch } from "react-redux";
const AssignTaskPopout = React.memo(
({
@@ -19,6 +21,8 @@ const AssignTaskPopout = React.memo(
}) => {
const apiCall = new usersService();
const dispatch = useDispatch()
let [requestStatus, setRequestStatus] = useState({
loading: false,
status: false,
@@ -90,11 +94,11 @@ const AssignTaskPopout = React.memo(
const requiredFields = {
banner,
// category,
country,
currency:country,
description,
job_detail,
'job detail':job_detail,
price,
timeline_days,
timeline:timeline_days,
title,
};
@@ -104,7 +108,7 @@ const AssignTaskPopout = React.memo(
setRequestStatus({
loading: false,
status: false,
message: `${field} is empty`,
message: `${field[0].toUpperCase()+field.slice(1).toLowerCase()} is empty`,
});
return setTimeout(() => {
setRequestStatus({ loading: false, status: false, message: "" });
@@ -145,6 +149,7 @@ const AssignTaskPopout = React.memo(
message: "action successful",
});
setUpdatePage(prev => !prev) // Updates family task page by calling the useeffect hook
dispatch(tableReload({ type: "WALLETTABLE" })); // RELOADS USER WALLET
setTimeout(() => {
setRequestStatus({ loading: false, status: false, message: "" });
action(); // FUNCTION THAT CLOSES THE MODAL BOX
@@ -0,0 +1,30 @@
import React from "react";
import Layout from "../../Partials/Layout";
import { Link } from "react-router-dom";
const FamilySettings = () => {
return (
<Layout>
<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={``}>Family Settings</span>
</h1>
</div>
<Link to="/acc-family">Go Back</Link>
</div>
{/* Something Here */}
{/* <form className="logout-modal-body w-full flex flex-col items-center px-10 py-8 gap-4"></form> */}
<div className="w-full bg-white dark:bg-dark-white overflow-y-auto rounded-2xl section-shadow h-full ">
<div className="update-table w-full h-full p-4 bg-white dark:bg-dark-white overflow-y-auto rounded-2xl section-shadow min-h-[520px] flex flex-col justify-between "></div>
</div>
</div>
</div>
</Layout>
);
};
export default FamilySettings;
+29 -18
View File
@@ -5,6 +5,7 @@ import React, {
useMemo,
useState,
} from "react";
import { Link } from "react-router-dom";
import usersService from "../../services/UsersService";
import InputCom from "../Helpers/Inputs/InputCom";
import ModalCom from "../Helpers/ModalCom";
@@ -13,7 +14,6 @@ import LoadingSpinner from "../Spinners/LoadingSpinner";
import FamilyTable from "./FamilyTable";
export default function FamilyAcc() {
const [selectTab, setValue] = useState("today");
// State to store the selected year and month
const [selectedYear, setSelectedYear] = useState("");
const [selectedMonth, setSelectedMonth] = useState("");
@@ -33,10 +33,6 @@ export default function FamilyAcc() {
setPopUp((prev) => !prev);
};
const filterHandler = (value) => {
setValue(value);
};
// Handle year selection
const handleYearChange = (e) => {
setSelectedYear(e.target.value);
@@ -116,7 +112,7 @@ export default function FamilyAcc() {
const { data } = res;
if (data?.internal_return >= 0 && data?.status === "OK") {
const { result_list, session_image_server } = data;
setFamilyList({result_list, session_image_server});
setFamilyList({ result_list, session_image_server });
setLoader(false);
} else {
return;
@@ -146,12 +142,9 @@ export default function FamilyAcc() {
<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={`${selectTab === "today" ? "block" : "hidden"}`}
>
Family Accounts
</span>
{familyList?.result_list?.length < process.env.REACT_APP_MAX_FAMILY_MEMBERS &&
<span className={``}>Family Accounts</span>
{familyList?.result_list?.length <
process.env.REACT_APP_MAX_FAMILY_MEMBERS &&
!loader && (
<button
onClick={popUpHandler}
@@ -163,12 +156,30 @@ export default function FamilyAcc() {
)}
</h1>
</div>
<div className="slider-btns flex space-x-4">
<div
onClick={() => filterHandler("today")}
className="relative"
></div>
</div>
<Link
to={`/familysettings`}
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%)]"
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth={1.5}
stroke="currentColor"
className="w-6 h-6 dark:stroke-white"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
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>
<Suspense fallback={<LoadingSpinner color="sky-blue" size="16" />}>
<FamilyTable
+106
View File
@@ -0,0 +1,106 @@
import React, {useEffect, useState} from 'react'
import Image from '../../assets/images/taskbanners/default.jpg'
import usersService from '../../services/UsersService';
import { handlePagingFunc } from '../../components/Pagination/HandlePagination';
import PaginatedList from '../../components/Pagination/PaginatedList';
import LoadingSpinner from '../Spinners/LoadingSpinner';
import { AmountTo2DP } from '../Helpers/PriceFormatter';
function JobsCompleted() {
const apiCall = new usersService()
let [familyRewardHistory, setFamilyRewardHistory] = useState({ // FOR PURCHASE HISTORY
loading: true,
data: [],
error: false
})
const [currentPage, setCurrentPage] = useState(0);
const indexOfFirstItem = Number(currentPage);
const indexOfLastItem = Number(indexOfFirstItem)+Number(process.env.REACT_APP_ITEM_PER_PAGE);
const currentReward = familyRewardHistory?.data?.slice(indexOfFirstItem, indexOfLastItem);
const handlePagination = (e) => {
handlePagingFunc(e,setCurrentPage)
}
//FUNCTION TO GET FAMILY REWARD HISTORY
const getJobCompletedHistory = ()=>{
// apiCall.getFamilyRewardHx().then((res)=>{
// if(res.data.internal_return < 0){ // success but no data
// setFamilyRewardHistory(prev => ({...prev, loading: false}))
// return
// }
// setFamilyRewardHistory(prev => ({...prev, loading: false, data: res.data.result_list}))
// }).catch((error)=>{
// setFamilyRewardHistory(prev => ({...prev, loading: false, error: true}))
// })
setTimeout(()=>{
setFamilyRewardHistory(prev => ({...prev, loading: false, error:true}))
},3000)
}
useEffect(()=>{
getJobCompletedHistory()
}, [])
return (
<div className='flex flex-col justify-between min-h-[500px]'>
{familyRewardHistory.loading ?
<LoadingSpinner size='16' color='sky-blue' height='h-[500px]' />
: familyRewardHistory.data.length ?
<table className="wallet-activity w-full table-auto border-collapse text-left">
<thead className='border-b-2'>
<tr className='text-slate-600'>
<th className="p-2"></th>
<th className="p-2">Amount</th>
<th className="p-2">Date</th>
<th className="p-2">Confirmation</th>
</tr>
</thead>
<tbody>
{currentReward.map((item, index) => {
let date = new Date(item.added).toLocaleDateString()
return (
<tr key={index} className='text-slate-500'>
<td className="p-2">
<div className='flex items-center gap-2'>
<img src={item.icon} className='min-w-[60px] max-w-[60px] min-h-[60px] max-h-[60px] rounded-full bg-slate-500' alt='Reward Logo' />
<div className='flex flex-col'>
<h1 className='text-lg font-bold'>Reward to {item.rec_firstname} {item.rec_lastname}</h1>
<p className='text-sm'>{item.description}</p>
</div>
</div>
</td>
<td className="p-2">{AmountTo2DP(item.amount*0.01)} {item.currency}</td>
<td className="p-2">{date}</td>
<td className="p-2">{item.confirmation}</td>
</tr>
)
}
)}
</tbody>
</table>
:familyRewardHistory.error ?
<div className="p-2 text-slate-500 flex flex-col grow justify-center items-center">
<span>Opps! an error occurred. Please try again!</span>
</div>
:
<div className="p-2 text-slate-500 flex flex-col grow justify-center items-center">
<span>No Completed Job History Found!</span>
</div>
}
{/* PAGINATION BUTTON */}
<PaginatedList onClick={handlePagination} prev={currentPage == 0 ? true : false} next={currentPage+Number(process.env.REACT_APP_ITEM_PER_PAGE) >= familyRewardHistory?.data?.length ? true : false} data={familyRewardHistory?.data} start={indexOfFirstItem} stop={indexOfLastItem} />
{/* END OF PAGINATION BUTTON */}
</div>
)
}
export default JobsCompleted
+18
View File
@@ -11,6 +11,7 @@ import PurchasesTable from "../MyWallet/WalletComponent/PurchasesTable";
import RecentActivityTable from "../MyWallet/WalletComponent/RecentActivityTable";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import RewardsTable from "./RewardsTable";
import JobsCompleted from "./JobsCompleted";
export default function History() {
@@ -249,6 +250,15 @@ export default function History() {
>
Rewards
</button>
<button
name="jobs_completed"
onClick={(e) => setTab(e.target.name)}
className={`px-4 py-1 rounded-t-2xl ${
tab == "jobs_completed" ? "bg-[#4687ba] border-[2px] border-[#4687ba] text-white" : "bg-white text-[#000] border-t-[2px]"
}`}
>
Jobs Completed
</button>
</div>
{/* END OF switch button */}
<div className="history-tables w-full">
@@ -286,6 +296,14 @@ export default function History() {
</div>
}
{/* END OF REWARD SECTION */}
{/* JOBS COMPLETED SECTION */}
{tab == 'jobs_completed' &&
<div className="wallet w-full border-t">
<JobsCompleted />
</div>
}
{/* END OF JOBS COMPLETED SECTION */}
</div>
</div>
{/*<HistoryTable />*/}
@@ -3,9 +3,12 @@ import ModalCom from '../../Helpers/ModalCom'
import LoadingSpinner from '../../Spinners/LoadingSpinner'
import { useNavigate } from 'react-router-dom'
import usersService from '../../../services/UsersService'
import { useDispatch } from 'react-redux'
import { tableReload } from '../../../store/TableReloads'
function ReviewJobAction({jobDetails}) {
const dispatch = useDispatch()
const apiCall = new usersService()
const navigate = useNavigate()
@@ -48,6 +51,7 @@ function ReviewJobAction({jobDetails}) {
return
}
setReqStatus({loading:false, status: true, message: 'job completion accepted successfully'})
dispatch(tableReload({ type: "WALLETTABLE" }));
setTimeout(()=>{ // Sets popout to false and navigates user to /my-review-jobs after 3 seconds
popUpHandler()
navigate('/my-review-jobs', {replace: true})
@@ -50,7 +50,7 @@ export default function WalletItemCardFamily({ walletItem, payment, countries })
background: `url(${background}) 0% 0% / cover no-repeat`,
}}
>
<div className="wallet w-full flex justify-between items-start gap-3">
<div className="wallet w-full flex justify-between items-center gap-3">
<div className="min-w-[100px] min-h-[100px] max-w-min md:max-w-[150px] max-h-min md:max-h-[150px] rounded-full bg-[#e3e3e3] flex justify-center items-center">
<img
src={localImgLoad(`images/currency/${image}`)}
@@ -75,18 +75,6 @@ export default function WalletItemCardFamily({ walletItem, payment, countries })
</div>
</div>
<p className="text-lg text-white tracking-wide flex justify-center items-center gap-8">
HOLDINGS :{" "}
<span className="xxs:scale-100 lg:scale-100 xl:scale-125">
{PriceFormatter(
walletItem.escrow * 0.01,
walletItem.code,
undefined,
"text-[2rem]"
)}
</span>
</p>
<div className="my-2 w-full h-[1px] bg-white"></div>
{/* <WalletAction
@@ -6,8 +6,11 @@ import CommonHead from "../UserHeader/CommonHead";
import usersService from "../../services/UsersService";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import OthersInterestedTable from "./OthersInterestedTable";
import { useDispatch } from "react-redux";
import { tableReload } from "../../store/TableReloads";
export default function ManageInterestOffer(props) {
const dispatch = useDispatch()
const navigate = useNavigate()
const apiCall = new usersService()
@@ -89,6 +92,7 @@ export default function ManageInterestOffer(props) {
setRedirectTime(prev => prev - 1)
}, 1000);
setRequestStatus({loading: false, status: true, message: `Offer ${name}ed`, processType: ''})
dispatch(tableReload({ type: "WALLETTABLE" }));
setTimeout(()=>{
navigate('/offer-interest', {replace: true})
clearInterval(intervalTime)
+1 -1
View File
@@ -6,4 +6,4 @@ export default function FamilyManagePage() {
<FamilyManage />
</>
);
}
}
+9
View File
@@ -0,0 +1,9 @@
import FamilySettings from "../components/FamilyAcc/FamilySettings";
export default function FamilySettingsPage() {
return (
<>
<FamilySettings />
</>
);
}