import {useEffect, useState} from 'react' import {Legend, Line, LineChart, ResponsiveContainer, Tooltip, XAxis, YAxis} from 'recharts' import {useT} from 'web/lib/locale' import {getCompletedProfilesCreations, getProfilesCreations} from 'web/lib/supabase/users' // Helper to convert rows into date -> count map function buildCounts(rows: any[]) { const counts: Record = {} for (const r of rows) { const date = new Date(r.created_time).toISOString().split('T')[0] counts[date] = (counts[date] || 0) + 1 } return counts } // Helper to turn count map into cumulative by sorted date array function cumulativeFromCounts(counts: Record, sortedDates: string[]) { const out: Record = {} let prev = 0 for (const d of sortedDates) { const v = counts[d] || 0 prev += v out[d] = prev } return out } export default function ChartMembers() { const [data, setData] = useState([]) const [chartHeight, setChartHeight] = useState(400) const t = useT() useEffect(() => { // Set responsive chart height: 300px on small widths, 400px otherwise function applyHeight() { if (typeof window !== 'undefined') { const isSmall = window.innerWidth < 420 setChartHeight(isSmall ? 320 : 400) } } applyHeight() window.addEventListener('resize', applyHeight) return () => window.removeEventListener('resize', applyHeight) }, []) useEffect(() => { async function load() { const [allProfiles, complatedProfiles] = await Promise.all([ getProfilesCreations(), getCompletedProfilesCreations(), ]) const countsAll = buildCounts(allProfiles) const countsCompleted = buildCounts(complatedProfiles) // Build a full daily date range from min to max date for equidistant time axis const allDates = Object.keys(countsAll) const completedDates = Object.keys(countsCompleted) const minDateStr = [...allDates, ...completedDates].sort((a, b) => a.localeCompare(b))[0] const maxDateStr = [...allDates, ...completedDates].sort((a, b) => b.localeCompare(a))[0] function toISODate(d: Date) { return new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate())) .toISOString() .split('T')[0] } function addDays(d: Date, days: number) { const nd = new Date(d) nd.setUTCDate(nd.getUTCDate() + days) return nd } function buildDailyRange(startStr: string, endStr: string) { const out: string[] = [] const start = new Date(startStr + 'T00:00:00.000Z') const end = new Date(endStr + 'T00:00:00.000Z') for (let d = start; d <= end; d = addDays(d, 1)) { out.push(toISODate(d)) } return out } const dates = buildDailyRange(minDateStr, maxDateStr) const cumAll = cumulativeFromCounts(countsAll, dates) const cumCompleted = cumulativeFromCounts(countsCompleted, dates) const merged = dates.map((date) => ({ date, dateTs: new Date(date + 'T00:00:00.000Z').getTime(), profilesCreations: cumAll[date] || 0, profilesCompletedCreations: cumCompleted[date] || 0, })) setData(merged) } void load() }, []) // One LineChart with two Line series sharing the same data array return (
{t('stats.number_members', 'Number of Members')} {/**/} new Date(ts).toISOString().split('T')[0]} label={{ value: t('charts.date', 'Date'), position: 'insideBottomRight', offset: -5, }} /> (payload && payload[0] && payload[0].payload?.date) || new Date(value as number).toISOString().split('T')[0] } />
) }