245 lines
8.4 KiB
React
245 lines
8.4 KiB
React
import React, { useState } from "react";
|
|
import { useNavigate } from "react-router-dom";
|
|
import { handlePagingFunc } from "../Pagination/HandlePagination";
|
|
import PaginatedList from "../Pagination/PaginatedList";
|
|
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
|
|
|
import familyImage from "../../assets/images/no-family-side.png";
|
|
import { formatDateString } from "../../lib";
|
|
import localImgLoad from "../../lib/localImgLoad";
|
|
|
|
/**
|
|
* Renders a list of family members that can be managed.
|
|
* It has its current maximum members at 8 and it comes with pagination and loading spinner functionality.
|
|
|
|
* @returns {JSX.Element} - The rendered component.
|
|
*/
|
|
export default function FamilyTable({
|
|
className,
|
|
familyList,
|
|
loader,
|
|
popUpHandler,
|
|
imageServer,
|
|
}) {
|
|
const navigate = useNavigate();
|
|
const [currentPage, setCurrentPage] = useState(0);
|
|
const itemsPerPage = Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
|
const indexOfFirstItem = Number(currentPage);
|
|
const indexOfLastItem =
|
|
Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
|
|
const currentFamilyList = familyList?.slice(
|
|
indexOfFirstItem,
|
|
indexOfLastItem
|
|
);
|
|
|
|
const handleManageClick = (familyMember) => {
|
|
navigate("/manage-family", { state: familyMember });
|
|
};
|
|
|
|
const handlePagination = (e) => {
|
|
handlePagingFunc(e, setCurrentPage);
|
|
};
|
|
|
|
/**
|
|
* Renders a table row for a family member.
|
|
* @returns {JSX.Element} - The table row component.
|
|
*/
|
|
const FamilyRow = ({
|
|
firstname,
|
|
lastname,
|
|
age,
|
|
added,
|
|
last_login,
|
|
task_count,
|
|
family_uid,
|
|
banner,
|
|
enable_traking,
|
|
profile_picture,
|
|
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 trackingStatus =
|
|
enable_traking === "0"
|
|
? "Stopped"
|
|
: enable_traking === "100"
|
|
? "Active"
|
|
: "";
|
|
|
|
return (
|
|
<tr
|
|
className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50"
|
|
key={key}
|
|
>
|
|
<td className="py-4">
|
|
<div className="flex space-x-2 items-center w-full">
|
|
<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}`)
|
|
}
|
|
alt={`Avatar of ${firstname} ${lastname}`}
|
|
className="w-full h-full"
|
|
/>
|
|
</div>
|
|
<div className="flex flex-col flex-[0.9]">
|
|
<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>
|
|
</span>
|
|
<span className="text-sm text-thin-light-gray">
|
|
Last Login:{" "}
|
|
<span className="text-purple ml-1">{loginDate}</span>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
|
|
<td className="text-center py-4 px-2">
|
|
<div className="flex space-x-1 items-center justify-center">
|
|
<span
|
|
className={`text-base font-medium whitespace-nowrap ${
|
|
enable_traking === "0"
|
|
? "text-[#FF0000] dark:text-[#FF6666]"
|
|
: enable_traking === "100"
|
|
? "text-[#00A000] dark:text-[#00FF00]"
|
|
: "text-dark-gray dark:text-white"
|
|
}`}
|
|
>
|
|
{trackingStatus}
|
|
</span>
|
|
</div>
|
|
</td>
|
|
|
|
<td className="text-center py-4 px-2">
|
|
<div className="flex space-x-1 items-center justify-center">
|
|
<span className="text-base text-dark-gray dark:text-white font-medium whitespace-nowrap">
|
|
{task_count}
|
|
</span>
|
|
</div>
|
|
</td>
|
|
|
|
<td className="text-right py-4 px-2 flex items-center justify-center">
|
|
<button
|
|
onClick={() =>
|
|
handleManageClick({
|
|
firstname,
|
|
lastname,
|
|
age,
|
|
added,
|
|
last_login,
|
|
task_count,
|
|
family_uid,
|
|
banner,
|
|
image,
|
|
})
|
|
}
|
|
type="button"
|
|
className="w-12 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
|
>
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
viewBox="0 0 11 20"
|
|
id="Arrow"
|
|
className="w-[0.7rem]"
|
|
>
|
|
<path
|
|
fillRule="evenodd"
|
|
d="M.366 19.708c.405.39 1.06.39 1.464 0l8.563-8.264a1.95 1.95 0 0 0 0-2.827L1.768.292A1.063 1.063 0 0 0 .314.282a.976.976 0 0 0-.011 1.425l7.894 7.617a.975.975 0 0 1 0 1.414L.366 18.295a.974.974 0 0 0 0 1.413"
|
|
// fill=""
|
|
className="color000000 svgShape fill-[#fff]"
|
|
></path>
|
|
</svg>
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
);
|
|
};
|
|
|
|
return (
|
|
<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 ${
|
|
className || ""
|
|
}`}
|
|
>
|
|
<div className="relative w-full h-full overflow-x-auto sm:rounded-lg">
|
|
{loader ? (
|
|
<div className="h-full min-h-[500px] w-full overflow-hidden flex justify-center items-center">
|
|
<LoadingSpinner size="16" color="sky-blue" />
|
|
</div>
|
|
) : (
|
|
<>
|
|
{familyList?.length > 0 ? (
|
|
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400 relative">
|
|
<thead className="sticky top-0">
|
|
<tr className="text-base text-thin-light-gray whitespace-nowrap border-b dark:border-[#5356fb29] default-border-bottom ">
|
|
<th className="py-4">Name</th>
|
|
<th className="py-4 text-center">Tracking</th>
|
|
<th className="py-4 text-center">No of Tasks</th>
|
|
<th className="py-4 text-right"></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody className="h-full">
|
|
{currentFamilyList?.map((familyMember, index) => {
|
|
return (
|
|
<FamilyRow
|
|
key={index}
|
|
{...familyMember}
|
|
imageServer={imageServer}
|
|
/>
|
|
);
|
|
})}
|
|
</tbody>
|
|
</table>
|
|
) : (
|
|
<div className="font-bold text-center text-xl md:text-2xl lg:text-4xl text-dark-gray md:flex items-center justify-between">
|
|
<div className="p-2 w-full md:w-1/2">
|
|
<p className="mb-4 p-3 md:p-16">
|
|
Add your family, assign tasks, and get the whole team
|
|
engaged.
|
|
</p>
|
|
<button
|
|
onClick={popUpHandler}
|
|
type="button"
|
|
className="text-white btn-gradient text-lg tracking-wide px-5 py-2 rounded-full"
|
|
>
|
|
Add Family
|
|
</button>
|
|
</div>
|
|
<div className="p-2 w-full md:w-1/2">
|
|
<img className="w-full" src={familyImage} alt="Add Family" />
|
|
</div>
|
|
</div>
|
|
)}
|
|
</>
|
|
)}
|
|
</div>
|
|
{/* PAGINATION BUTTON */}
|
|
<PaginatedList
|
|
onClick={handlePagination}
|
|
prev={currentPage == 0}
|
|
next={currentPage + itemsPerPage >= familyList?.length}
|
|
data={familyList}
|
|
start={indexOfFirstItem}
|
|
stop={indexOfLastItem}
|
|
/>
|
|
{/* END OF PAGINATION BUTTON */}
|
|
</div>
|
|
);
|
|
}
|