Commits (3)
export default function Loader() {
return (
<div className="flex items-center justify-center py-12">
<div className="h-40 w-40 animate-spin rounded-full border-4 border-[#3a3f44] border-t-[#8884d8]" />
</div>
)
}
......@@ -8,6 +8,7 @@ ChartJS.register(LinearScale, PointElement, Tooltip, Legend)
import { searchDepartments, getCorrelation, type Department, type CorrelationPoint } from '../../services/points.services'
import { TAX_TYPES, YEARS } from '../../constants'
import ErrorDiv from '../molecules/ErrorDiv'
import Loader from '../molecules/Loader'
export default function Points() {
// Department search autocomplete results from API
......@@ -235,9 +236,11 @@ export default function Points() {
</button>
</div>
{loading && <Loader />}
{error && <ErrorDiv message={error} />}
{!error && data.length > 0 && (
{!loading && !error && data.length > 0 && (
<>
<div className="flex flex-wrap gap-4 items-end">
<p className="text-sm text-[#b0afaf]">
......
......@@ -5,6 +5,7 @@ import { LineChart, Line, XAxis, YAxis, Tooltip, Legend, ResponsiveContainer, Ca
import { getTimeSeries, type TimeSeriesData } from '../../services/temporal.services'
import { TAX_TYPES, YEARS, COLORS } from '../../constants'
import ErrorDiv from '../molecules/ErrorDiv'
import Loader from '../molecules/Loader'
interface TemporalProps {
regions: string[]
......@@ -153,21 +154,41 @@ export default function Temporal({ regions }: TemporalProps) {
</div>
)}
{loading && <Loader />}
{error && <ErrorDiv message={error} />}
{!error && chartData.length > 0 && (
{!loading && !error && chartData.length > 0 && (
<ResponsiveContainer width="100%" height={400}>
<LineChart data={chartData}>
<CartesianGrid strokeDasharray="3 3" stroke="#3a3f44" />
<XAxis dataKey="year" stroke="#b0afaf" />
<YAxis stroke="#b0afaf" tickFormatter={(v: number) => `${v}%`} />
<Tooltip
contentStyle={{
backgroundColor: '#212529',
border: '1px solid #3a3f44',
borderRadius: 8,
content={({ payload, label }) => {
if (!payload || payload.length === 0) return null
return (
<div
className="tooltip-scroll"
style={{
backgroundColor: '#212529',
border: '1px solid #3a3f44',
borderRadius: 8,
padding: '8px 12px',
maxHeight: 300,
overflowY: 'auto',
}}
>
<p style={{ margin: '0 0 4px', color: '#b0afaf' }}>{label}</p>
{[...payload].sort((a, b) => Number(b.value) - Number(a.value)).map(item => (
<p key={item.name} style={{ margin: '2px 0', color: item.color }}>
{item.name} : {item.value}%
</p>
))}
</div>
)
}}
formatter={(value, name) => [`${value}%`, name]}
wrapperStyle={{ zIndex: 10, pointerEvents: 'auto' }}
/>
<Legend
wrapperStyle={{
......
......@@ -21,3 +21,21 @@ h1 {
opacity: 0;
transform: scaleY(0);
}
.tooltip-scroll::-webkit-scrollbar {
width: 6px;
}
.tooltip-scroll::-webkit-scrollbar-track {
background: #1a1d21;
border-radius: 3px;
}
.tooltip-scroll::-webkit-scrollbar-thumb {
background: #3a3f44;
border-radius: 3px;
}
.tooltip-scroll::-webkit-scrollbar-thumb:hover {
background: #8884d8;
}