Files
krow-demo/src/components/krow/ActivityCharts.jsx
2026-08-07 23:53:15 +05:30

107 lines
3.8 KiB
JavaScript

import React, { useMemo } from 'react';
import {
ResponsiveContainer,
LineChart,
Line,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
BarChart,
Bar,
PieChart,
Pie,
Cell,
Legend,
} from 'recharts';
const PIE_COLORS = ['#0A39DF', '#059669', '#333F48', '#D97706', '#DC2626', '#0891B2', '#DB2777'];
function last7Days() {
const days = [];
for (let i = 6; i >= 0; i--) {
const d = new Date();
d.setDate(d.getDate() - i);
days.push(d.toISOString().split('T')[0]);
}
return days;
}
export default function ActivityCharts({ activities }) {
const timeSeries = useMemo(() => {
const days = last7Days();
return days.map((day) => {
const dayActivities = activities.filter((a) => (a.created_date || '').slice(0, 10) === day);
return {
date: day.slice(5),
signups: dayActivities.filter((a) => a.event_type === 'signup').length,
logins: dayActivities.filter((a) => a.event_type === 'login').length,
actions: dayActivities.length,
};
});
}, [activities]);
const byType = useMemo(() => {
const counts = {};
activities.forEach((a) => {
counts[a.event_type] = (counts[a.event_type] || 0) + 1;
});
return Object.entries(counts).map(([name, value]) => ({ name, value }));
}, [activities]);
const byRole = useMemo(() => {
const counts = {};
activities.forEach((a) => {
counts[a.account_type] = (counts[a.account_type] || 0) + 1;
});
return Object.entries(counts).map(([name, value]) => ({ name, value }));
}, [activities]);
return (
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
<div className="bg-white rounded-xl border border-[#E5E7EB] p-5">
<h3 className="text-[14px] font-semibold text-[#111827] mb-4">Activity (Last 7 Days)</h3>
<ResponsiveContainer width="100%" height={240}>
<LineChart data={timeSeries}>
<CartesianGrid strokeDasharray="3 3" stroke="#F3F4F6" />
<XAxis dataKey="date" tick={{ fontSize: 11 }} stroke="#9CA3AF" />
<YAxis tick={{ fontSize: 11 }} stroke="#9CA3AF" allowDecimals={false} />
<Tooltip />
<Legend wrapperStyle={{ fontSize: 12 }} />
<Line type="monotone" dataKey="signups" stroke="#0A39DF" strokeWidth={2} />
<Line type="monotone" dataKey="logins" stroke="#059669" strokeWidth={2} />
<Line type="monotone" dataKey="actions" stroke="#D97706" strokeWidth={2} />
</LineChart>
</ResponsiveContainer>
</div>
<div className="bg-white rounded-xl border border-[#E5E7EB] p-5">
<h3 className="text-[14px] font-semibold text-[#111827] mb-4">Actions by Type</h3>
<ResponsiveContainer width="100%" height={240}>
<BarChart data={byType}>
<CartesianGrid strokeDasharray="3 3" stroke="#F3F4F6" />
<XAxis dataKey="name" tick={{ fontSize: 10 }} stroke="#9CA3AF" interval={0} angle={-20} textAnchor="end" height={50} />
<YAxis tick={{ fontSize: 11 }} stroke="#9CA3AF" allowDecimals={false} />
<Tooltip />
<Bar dataKey="value" fill="#0A39DF" radius={[4, 4, 0, 0]} />
</BarChart>
</ResponsiveContainer>
</div>
<div className="bg-white rounded-xl border border-[#E5E7EB] p-5">
<h3 className="text-[14px] font-semibold text-[#111827] mb-4">Users by Role</h3>
<ResponsiveContainer width="100%" height={240}>
<PieChart>
<Pie data={byRole} dataKey="value" nameKey="name" cx="50%" cy="50%" outerRadius={80} label>
{byRole.map((_, i) => (
<Cell key={i} fill={PIE_COLORS[i % PIE_COLORS.length]} />
))}
</Pie>
<Tooltip />
<Legend wrapperStyle={{ fontSize: 12 }} />
</PieChart>
</ResponsiveContainer>
</div>
</div>
);
}