165 lines
5.6 KiB
TypeScript
165 lines
5.6 KiB
TypeScript
import React, { useEffect, useState, useCallback } from 'react';
|
|
import AccountNav from '../accounts/AccountNav';
|
|
import Cards from './Cards';
|
|
import StartSection from './StartSection';
|
|
import api from '../../config/api';
|
|
import { FiFileText, FiClock, FiAlertTriangle, FiCheckCircle } from "react-icons/fi";
|
|
import { useSelector } from 'react-redux';
|
|
import { RootState } from '../../store/store';
|
|
|
|
interface CardData {
|
|
title: string;
|
|
count: number;
|
|
icon: JSX.Element;
|
|
gradient: string;
|
|
shadowColor: string;
|
|
iconBg: string;
|
|
textColor: string;
|
|
percentage?: number;
|
|
trend?: 'up' | 'down' | 'stable';
|
|
}
|
|
|
|
const Home = () => {
|
|
const mapApiDataToCards = (data: any): CardData[] => {
|
|
return [
|
|
{
|
|
title: "Action Required",
|
|
count: data.actionNeeded || 0,
|
|
icon: <FiFileText className="w-5 h-5 text-sky-500" />,
|
|
iconBg: "bg-sky-100 border-sky-200",
|
|
textColor: "text-sky-600",
|
|
gradient: "bg-white",
|
|
shadowColor: "shadow-sky-100",
|
|
},
|
|
{
|
|
title: "Waiting for Response",
|
|
count: data.waitingForOthers || 0,
|
|
icon: <FiClock className="w-5 h-5 text-yellow-500" />,
|
|
iconBg: "bg-yellow-100 border-yellow-200",
|
|
textColor: "text-yellow-600",
|
|
gradient: "bg-white",
|
|
shadowColor: "shadow-yellow-100",
|
|
},
|
|
{
|
|
title: "Expiring Soon",
|
|
count: data.expiring || 0,
|
|
icon: <FiAlertTriangle className="w-5 h-5 text-red-500" />,
|
|
iconBg: "bg-red-100 border-red-200",
|
|
textColor: "text-red-600",
|
|
gradient: "bg-white",
|
|
shadowColor: "shadow-red-100",
|
|
},
|
|
{
|
|
title: "Completed",
|
|
count: data.completed || 0,
|
|
icon: <FiCheckCircle className="w-5 h-5 text-green-500" />,
|
|
iconBg: "bg-green-100 border-green-200",
|
|
textColor: "text-green-600",
|
|
gradient: "bg-white",
|
|
shadowColor: "shadow-green-100",
|
|
},
|
|
];
|
|
};
|
|
|
|
const [activeAccountId, setActiveAccountId] = useState<string | null>(
|
|
JSON.parse(sessionStorage.getItem('activeAccountId') || 'null')
|
|
);
|
|
const [dashboardData, setDashboardData] = useState<any>(null);
|
|
const [fromDate, setFromDate] = useState<string>('');
|
|
const [toDate, setToDate] = useState<string>('');
|
|
const [cards, setCards] = useState<CardData[]>([]);
|
|
const [isLoading, setIsLoading] = useState<boolean>(false);
|
|
|
|
const userData = useSelector((state: RootState) => state.user);
|
|
|
|
console.log("activeAccountId", activeAccountId);
|
|
console.log("cards", cards);
|
|
|
|
const getDashboardData = async () => {
|
|
if (!activeAccountId) return;
|
|
|
|
setIsLoading(true);
|
|
const payload = {
|
|
account: activeAccountId
|
|
};
|
|
|
|
try {
|
|
const res = await api.get(`/api/accounts/${userData.account.id}/dashboard`, { params: payload });
|
|
setDashboardData(res.data);
|
|
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 handleDateRangeChange = useCallback(async (range: { from: string; to: string }) => {
|
|
const isoFrom = new Date(range.from).toISOString();
|
|
const isoTo = new Date(range.to).toISOString();
|
|
setFromDate(isoFrom);
|
|
setToDate(isoTo);
|
|
}, []);
|
|
|
|
// 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);
|
|
};
|
|
}, []);
|
|
|
|
// Re-fetch dashboard data when activeAccountId changes
|
|
useEffect(() => {
|
|
if (activeAccountId) {
|
|
getDashboardData();
|
|
}
|
|
}, [activeAccountId]);
|
|
|
|
// Set default date range on mount (last 7 days)
|
|
useEffect(() => {
|
|
const now = new Date();
|
|
const from = new Date();
|
|
from.setDate(now.getDate() - 7);
|
|
|
|
setFromDate(from.toISOString());
|
|
setToDate(now.toISOString());
|
|
}, []);
|
|
|
|
return (
|
|
<>
|
|
<Cards
|
|
onDateRangeChange={handleDateRangeChange}
|
|
dashboardData={dashboardData}
|
|
fromDate={fromDate}
|
|
toDate={toDate}
|
|
cards={cards}
|
|
isLoading={isLoading}
|
|
/>
|
|
<StartSection />
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default Home; |