Compare commits
3 Commits
63b02db9b3
...
ca592fe9d7
Author | SHA1 | Date | |
---|---|---|---|
ca592fe9d7 | |||
9c47b05d64 | |||
aa70c5d1da |
@ -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",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -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 = {
|
||||||
|
@ -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 ">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user