import { useEffect, useState } from "react"; import { PiDotsThreeOutlineVerticalFill } from "react-icons/pi"; import AccountNav from "./AccountNav"; import api from "../../config/api"; import { useNavigate, useParams } from "react-router-dom"; import { FaCheck } from "react-icons/fa"; import Cards from "../home/Cards"; import AddInviteModal from "./AddInviteModal"; import { Bounce, toast } from "react-toastify"; import { FaCheckCircle, FaClock, FaHourglassHalf, FaTasks, FaChevronDown, FaPlus, FaUserPlus, FaFilter, FaCalendarAlt } from 'react-icons/fa'; interface Transaction { id: number; status: string; active: boolean; subject: string | null; createdAt: number; expireAfter: number | null; } const formatDate = (timestamp: number) => { return new Date(timestamp * 1000).toLocaleString(); }; const Account = () => { const mapApiDataToCards = (data: any): CardData[] => { return [ { title: 'Action Needed', count: data.actionNeeded || 0, icon: , gradient: 'bg-gradient-to-br from-indigo-50 to-indigo-100', shadowColor: 'shadow-indigo-200/50', iconBg: 'bg-indigo-100 border-indigo-200', textColor: 'text-indigo-700', trend: 'up' }, { title: 'Expiring Soon', count: data.expiring || 0, icon: , gradient: 'bg-gradient-to-br from-rose-50 to-rose-100', shadowColor: 'shadow-rose-200/50', iconBg: 'bg-rose-100 border-rose-200', textColor: 'text-rose-700', trend: 'up' }, { title: 'Completed', count: data.completed || 0, icon: , gradient: 'bg-gradient-to-br from-teal-50 to-teal-100', shadowColor: 'shadow-teal-200/50', iconBg: 'bg-teal-100 border-teal-200', textColor: 'text-teal-700', trend: 'up' }, // { // title: 'Waiting for Others', // count: data.waitingForOthers || 0, // icon: , // gradient: 'bg-gradient-to-br from-blue-50 to-blue-100', // shadowColor: 'shadow-blue-200/50', // iconBg: 'bg-blue-100 border-blue-200', // textColor: 'text-blue-700', // trend: 'down' // }, // { // title: 'declined', // count: data.declined || 0, // icon: , // gradient: 'bg-gradient-to-br from-purple-50 to-purple-100', // shadowColor: 'shadow-purple-200/50', // iconBg: 'bg-purple-100 border-purple-200', // textColor: 'text-purple-700', // trend: 'down' // }, // { // title: 'cancelled', // count: data.cancelled || 0, // icon: , // gradient: 'bg-gradient-to-br from-green-50 to-green-100', // shadowColor: 'shadow-green-200/50', // iconBg: 'bg-green-100 border-green-200', // textColor: 'text-green-700', // trend: 'down' // }, { title: 'draft', count: data.draft || 0, icon: , gradient: 'bg-gradient-to-br from-stone-50 to-stone-100', shadowColor: 'shadow-stone-200/50', iconBg: 'bg-stone-100 border-stone-200', textColor: 'text-stone-700', trend: 'down' } // Add more cards here if needed ]; }; const [activeAccountId, setActiveAccountId] = useState( JSON.parse(sessionStorage.getItem('activeAccountId') || 'null') ); const [currentEmailId, setCurrentEmailId] = useState('null'); console.log("activeAccountId Trans.", activeAccountId) // const { accountId } = useParams<{ accountId: string }>(); const [transactions, setTransactions] = useState([]); const [selectedTransactions, setSelectedTransactions] = useState([]); const [accountsData, setAccountsData] = useState([]) const [inviteLoading, setInviteLoading] = useState(false); const [cards, setCards] = useState([]); const [accountID, setAccountID] = useState() const [isLoading, setIsLoading] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false); // const getUserDetails = async () => { // try { // let res = await api.get('/api/user/details') // let accountIDData = res?.data?.account?.id // setAccountID(accountIDData) // } catch (error) { // console.log(error) // } // } // useEffect(() => { // getUserDetails() // }, []) useEffect(() => { const userDetails = JSON.parse(sessionStorage.getItem('userDetails')); setCurrentEmailId(userDetails?.email) }, []); // Listen for sessionStorage changes useEffect(() => { const handleStorageChange = (e: StorageEvent) => { if (e.key === 'activeAccountId') { const newActiveAccountId = e.newValue ? JSON.parse(e.newValue) : null; setActiveAccountId(newActiveAccountId); } }; // Listen for storage events (works for changes from other tabs) window.addEventListener('storage', handleStorageChange); // Custom event listener for same-tab changes const handleCustomStorageChange = (e: CustomEvent) => { if (e.detail.key === 'activeAccountId') { setActiveAccountId(e.detail.newValue); } }; window.addEventListener('sessionStorageChange', handleCustomStorageChange as EventListener); return () => { window.removeEventListener('storage', handleStorageChange); window.removeEventListener('sessionStorageChange', handleCustomStorageChange as EventListener); }; }, []); const getDashboardData = async () => { setIsLoading(true) const payload = { account: activeAccountId }; try { const res = await api.get('/api/dashboard', { params: payload }); console.log("Dashboard Data:", res.data); const cardDataArray = mapApiDataToCards(res.data); setCards(cardDataArray); } catch (error) { console.error("Error fetching dashboard data:", error); } finally { setIsLoading(false) } }; const fetchTransactions = async () => { console.log("fetchTransactions") try { const response = await api(`/api/accounts/${activeAccountId}/transactions`); setTransactions(response.data || []); } catch (error) { console.error("Error fetching transactions:", error); } }; useEffect(() => { if (activeAccountId) { getDashboardData() fetchTransactions(); } }, [activeAccountId]); const handleOpenModal = () => { setIsModalOpen(true); }; // useEffect(() => { // if (accountID) fetchTransactions(); // }, [accountID]); // const getAccountDetails = async () => { // try { // let res = await api.get('/api/user/accounts') // let items = res?.data // setAccountsData(items) // } catch (error) { // console.log(error) // } // } // useEffect(() => { // getAccountDetails() // }, []) const navigate = useNavigate(); const handleTransactionClick = (id: number) => { navigate(`/accounts/${activeAccountId}/transactions/${id}`); }; const handleInvite = async (data: { i_accountName: number; email: string; role: string }) => { setInviteLoading(true); try { const payloadInvite = { email: data.email, role: data.role } let res = await api.post(`/api/accounts/${data.i_accountName}/invite`, payloadInvite) if (res?.data) { toast.success("Invite Sent Successfully...!", { position: "top-center", autoClose: 1500, hideProgressBar: false, closeOnClick: false, pauseOnHover: true, draggable: true, progress: undefined, theme: "light", transition: Bounce, }); await fetchTransactions() setIsModalOpen(false); } } catch (err) { console.error('Failed to invite', err); } finally { setInviteLoading(false); } }; return ( <> {transactions.length > 0 && (
{transactions.map((tx) => { const lastModifiedAt = new Date(tx.lastModifiedAt, "DD/MM/YYYY"); return ( handleTransactionClick(tx.id)} className="hover:bg-gray-50 cursor-pointer" > ) })}
Name Status Active Last Change Expire After (days) Sign Action
{selectedTransactions.includes(tx.id) && ( )}
{tx.subject || "Untitled"} {tx.status} {tx.active ? "Yes" : "No"} {formatDate(tx.lastModifiedAt)} {tx.expireAfter ?? "-"} {tx?.createdBy?.email === currentEmailId ? : "-"}
)} {isModalOpen && setIsModalOpen(false)} onInvite={handleInvite} inviteLoading={inviteLoading} accountOptions={accountsData} />} ); }; export default Account;