// Dependencies import { linkClasses, formatNumber, orderBy, clone } from '@freesewing/utils' // Hooks import React, { useState, useEffect } from 'react' import { useBackend } from '@freesewing/react/hooks/useBackend' // Components import { Spinner } from '@freesewing/react/components/Spinner' import { Link as WebLink } from '@freesewing/react/components/Link' import { ChartWrapper } from '@freesewing/react/components/Echart' import { Popout } from '@freesewing/react/components/Popout' const option = { tooltip: { trigger: 'axis', show: true, axisPointer: { type: 'line', lineStyle: { type: 'dashed', }, }, }, title: { left: 'center', }, grid: { left: '40', right: '60', containLabel: true, }, toolbox: { feature: { saveAsImage: {}, magicType: { type: ['line', 'bar'], }, }, }, yAxis: { type: 'value', }, } /** * A component to display generic stats from the FreeSewing backend * * @component * @param {object} props - All component props * @param {React.FC} [props.Link = false] - An optional framework-specific Link component * @returns {JSX.Element} */ export const Stats = ({ Link = false }) => { if (!Link) Link = WebLink const [stats, setStats] = useState() const [error, setError] = useState(false) const backend = useBackend() useEffect(() => { getStats(backend, setStats, setError) }, []) if (!stats) return (
) const designTop = orderBy( Object.entries(stats.designs).map(([design, count]) => ({ design, count })), 'count', 'desc' ).slice(0, 50) const optionD = clone(option) optionD.title.text = 'Top 50 FreeSewing Designs' optionD.xAxis = { type: 'category', data: designTop.map((entry) => entry.design), name: 'Design', } optionD.series = [ { data: designTop.map((entry) => entry.count), type: 'bar', }, ] const optionU = clone(option) optionU.title.text = 'Top 25 FreeSewing Users' optionU.xAxis = { type: 'category', data: stats.topUsers.map((user) => user.username), name: 'User', } optionU.series = [ { data: stats.topUsers.map((user) => user.calls), type: 'bar', }, ] if (error) return ( This is unexpected. You may want to report this. ) return ( <>

Top Users

Note: Ordered by JWT calls made to the FreeSewing backend
    {stats.topUsers.map((u) => (
  1. {u.username} : {formatNumber(u.calls)}
  2. ))}

Top Designs

Note: Ordered by patterns stored in the FreeSewing backend
    {Object.entries(stats.designs).map(([d, c]) => (
  1. {d} : {formatNumber(c)}
  2. ))}
) } const Stat = ({ title, value, desc = 'Total Number Stored' }) => (
{title}
{formatNumber(value)}
{desc}
) const getStats = async (backend, setStats, setError) => { const result = await backend.getStats() if (result[0] === 200 && result[1]) setStats(result[1]) else setError(true) }