Compare commits

...

3 Commits

3 changed files with 139 additions and 113 deletions

View File

@ -58,8 +58,9 @@ const HorizontalBarChart = ({
barHeight: "60%",
distributed: true,
horizontal: true,
borderRadius: 10,
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>;
}
const chartOptions = {
chart: {
type: "line",
height: 350,
zoom: { enabled: false },
toolbar: { show: false },
background: 'transparent'
},
colors,
dataLabels: {
enabled: false // Hide value labels on dots
},
stroke: {
curve: 'straight',
width: 2
},
grid: {
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
const chartOptions = {
chart: {
type: "line",
height: 350,
zoom: {
enabled: true,
type: 'x',
autoScaleYaxis: true
},
toolbar: {
show: true,
tools: {
zoom: true,
zoomin: true,
zoomout: true,
pan: true,
reset: true
}
};
},
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">
<ReactApexChart
options={chartOptions}
series={seriesData}
type="line"
height={350}
/>
</div>
);
return (
<div className="w-full overflow-x-auto">
<ReactApexChart
options={chartOptions}
series={seriesData}
type="line"
height={350}
/>
</div>
);
};
LineChart.propTypes = {

View File

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