Compare commits

..

3 Commits

3 changed files with 139 additions and 113 deletions

View File

@ -58,8 +58,9 @@ const HorizontalBarChart = ({
barHeight: "60%", barHeight: "60%",
distributed: true, distributed: true,
horizontal: true, horizontal: true,
borderRadius: 10,
dataLabels: { dataLabels: {
position: "center", position: "top",
}, },
}, },
}, },

View File

@ -27,83 +27,94 @@ const LineChart = ({
return <div className="text-center text-gray-500">No data to display</div>; return <div className="text-center text-gray-500">No data to display</div>;
} }
const chartOptions = { const chartOptions = {
chart: { chart: {
type: "line", type: "line",
height: 350, height: 350,
zoom: { enabled: false }, zoom: {
toolbar: { show: false }, enabled: true,
background: 'transparent' type: 'x',
}, autoScaleYaxis: true
colors, },
dataLabels: { toolbar: {
enabled: false // Hide value labels on dots show: true,
}, tools: {
stroke: { zoom: true,
curve: 'straight', zoomin: true,
width: 2 zoomout: true,
}, pan: true,
grid: { reset: true
show: false,
xaxis: {
lines: {
show: false
}
},
yaxis: {
lines: {
show: false
}
}
},
markers: {
size: 5, // Increase dot visibility
strokeWidth: 0,
hover: {
size: 7
}
},
xaxis: {
categories,
labels: {
show: true,
rotate: -45,
style: {
fontSize: '12px'
}
},
axisBorder: { show: false },
axisTicks: { show: false },
tooltip: { enabled: false }
},
yaxis: {
labels: { show: false },
axisBorder: { show: false },
axisTicks: { show: false },
min: 0
},
legend: {
show: true // Optional: Hide legend if not needed
},
tooltip: {
enabled: true // Keep this if you want value on hover
} }
}; },
background: 'transparent'
},
colors,
dataLabels: {
enabled: false
},
stroke: {
curve: 'smooth',
width: 2
},
grid: {
show: false,
xaxis: {
lines: {
show: false
}
},
yaxis: {
lines: {
show: false
}
}
},
markers: {
size: 5,
strokeWidth: 0,
hover: {
size: 7
}
},
xaxis: {
type: 'category',
categories,
labels: {
show: true,
rotate: -45,
style: {
fontSize: '12px'
}
},
tooltip: { enabled: false }
},
yaxis: {
labels: { show: false },
axisBorder: { show: false },
axisTicks: { show: false },
min: 0
},
legend: {
show: true
},
tooltip: {
enabled: true,
x: {
formatter: (val, opts) => val
}
}
};
return (
<div className="w-full overflow-x-auto">
<ReactApexChart
return ( options={chartOptions}
<div className="w-full"> series={seriesData}
<ReactApexChart type="line"
options={chartOptions} height={350}
series={seriesData} />
type="line" </div>
height={350} );
/>
</div>
);
}; };
LineChart.propTypes = { LineChart.propTypes = {

View File

@ -12,14 +12,28 @@ import {
const Dashboard = () => { const Dashboard = () => {
const { projects,loading } = useProjects(); const { projects,loading } = useProjects();
const [selectedProjectId, setSelectedProjectId] = useState('all'); const [selectedProjectId, setSelectedProjectId] = useState('all');
const [FromDate, setFromDate] = useState(() => { const [range, setRange] = useState('1W');
const today = new Date();
return today.toISOString().split('T')[0]; // YYYY-MM-DD const getDaysFromRange = (range) => {
}); switch (range) {
const [days, setDays] = useState(10); case '1D': return 1;
const { projectsCardData, } = useDashboardProjectsCardData(); case '1W': return 7;
const { teamsCardData,} = useDashboardTeamsCardData(); case '15D': return 15;
const { tasksCardData, } = useDashboardTasksCardData(); case '1M': return 30;
case '3M': return 90;
case '1Y': return 365;
case '5Y': return 1825;
default: return 7;
}
};
const days = getDaysFromRange(range);
const today = new Date();
const FromDate = today.toISOString().split('T')[0]; // Always today
const { projectsCardData } = useDashboardProjectsCardData();
const { teamsCardData } = useDashboardTeamsCardData();
const { tasksCardData } = useDashboardTasksCardData();
const { dashboard_data, loading: isLineChartLoading } = useDashboard_Data({ const { dashboard_data, loading: isLineChartLoading } = useDashboard_Data({
days, days,
@ -27,6 +41,9 @@ const { tasksCardData, } = useDashboardTasksCardData();
projectId: selectedProjectId === 'all' ? 0 : selectedProjectId, projectId: selectedProjectId === 'all' ? 0 : selectedProjectId,
}); });
// Sort dashboard_data by date ascending
const sortedDashboardData = [...dashboard_data].sort((a, b) => new Date(a.date) - new Date(b.date));
// Bar chart logic // Bar chart logic
const projectNames = projects?.map(p => p.name) || []; const projectNames = projects?.map(p => p.name) || [];
const projectProgress = projects?.map(p => { const projectProgress = projects?.map(p => {
@ -40,15 +57,15 @@ const { tasksCardData, } = useDashboardTasksCardData();
const lineChartSeries = [ const lineChartSeries = [
{ {
name: 'Planned Work', name: 'Planned Work',
data: dashboard_data.map(d => d.plannedTask || 0), data: sortedDashboardData.map(d => d.plannedTask || 0),
}, },
{ {
name: 'Completed Work', name: 'Completed Work',
data: dashboard_data.map(d => d.completedTask || 0), data: sortedDashboardData.map(d => d.completedTask || 0),
}, },
]; ];
const lineChartCategories = dashboard_data.map(d => const lineChartCategories = sortedDashboardData.map(d =>
new Date(d.date).toLocaleDateString('en-US', { month: 'short', day: 'numeric' }) new Date(d.date).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })
); );
@ -135,15 +152,16 @@ const { tasksCardData, } = useDashboardTasksCardData();
{/* Line Chart */} {/* Line Chart */}
<div className="col-xxl-6 col-lg-6"> <div className="col-xxl-6 col-lg-6">
<div className="card h-100"> <div className="card h-100">
<div className="card-header d-flex flex-wrap align-items-center justify-content-between"> <div className="card-header">
<div className="card-title mb-0 text-start"> {/* Row 1: Title + Project Selector */}
<h5 className="mb-1">Project Progress</h5> <div className="d-flex flex-wrap justify-content-between align-items-center mb-2">
<p className="card-subtitle">Progress Overview by Project</p> <div className="card-title mb-0 text-start">
</div> <h5 className="mb-1">Project Progress</h5>
<div className="d-flex flex-wrap gap-2 align-items-center"> <p className="card-subtitle">Progress Overview by Project</p>
{/* Project Dropdown */} </div>
<div className="btn-group"> <div className="btn-group">
<button type="button" className="btn btn-label-primary"> <button type="button" className="btn btn-label-primary btn-sm">
{selectedProjectId === 'all' {selectedProjectId === 'all'
? 'All Projects' ? 'All Projects'
: projects?.find(p => p.id === selectedProjectId)?.name || 'Select Project'} : projects?.find(p => p.id === selectedProjectId)?.name || 'Select Project'}
@ -171,25 +189,21 @@ const { tasksCardData, } = useDashboardTasksCardData();
))} ))}
</ul> </ul>
</div> </div>
</div>
{/* From Date */} {/* Row 2: Time Range Buttons */}
<input <div className="d-flex flex-wrap gap-2 mt-2">
type="date" {['1D', '1W', '15D', '1M', '3M', '1Y', '5Y'].map((key) => (
className="form-control" <button
value={FromDate} key={key}
onChange={(e) => setFromDate(e.target.value)} className={`border-0 bg-transparent px-2 py-1 text-sm rounded ${range === key ? 'fw-bold border-bottom border-primary text-primary' : 'text-muted'
style={{ maxWidth: '150px' }} }`}
/> style={{ cursor: 'pointer', transition: 'all 0.2s ease' }}
onClick={() => setRange(key)}
{/* Days */} >
<input {key}
type="number" </button>
className="form-control" ))}
value={days}
min={1}
onChange={(e) => setDays(Number(e.target.value))}
style={{ maxWidth: '100px' }}
/>
</div> </div>
</div> </div>
<div className="card-body "> <div className="card-body ">