import ApolloClient, { gql } from "apollo-boost" import React from "react" import ReactDOM from "react-dom" import Chart from "react-apexcharts" import { ApolloProvider, Query } from "react-apollo" import moment from "moment" const initAnalytics = ({ elementId, errorMessage, labels, title, uri }) => { const element = document.getElementById(elementId) if (!element) console.error("Element with id " + element + "doesn't exist!") const client = new ApolloClient({ credentials: "same-origin", uri: uri }) ReactDOM.render( , element ) } const getAnalytics = gql` query getAnalytics($span: Int!) { analytics(span: $span) { users { ...data } userDeletions { ...data } threads { ...data } posts { ...data } attachments { ...data } dataDownloads { ...data } } } fragment data on AnalyticsData { current currentCumulative previous previousCumulative } ` class Analytics extends React.Component { state = { span: 30 } setSpan = span => { this.setState({ span }) } render() { const { errorMessage, labels, title } = this.props const { span } = this.state return (

{title}

{({ loading, error, data }) => { if (loading) return if (error) return const { analytics } = data return ( <> ) }}
) } } const SpanPicker = ({ span, setSpan }) => (
{[30, 90, 180, 360].map(choice => ( ))}
) const Spinner = () => (
Loading...
) const Error = ({ message }) => (
{message}
) const CURRENT = "C" const PREVIOUS = "P" const CURRENT_SERIES = 0 const AnalyticsItem = ({ data, legend, name, negative, span }) => { const options = { legend: { show: false }, chart: { animations: { enabled: false }, parentHeightOffset: 0, toolbar: { show: false } }, colors: ["#6554c0", "#b3d4ff"], grid: { padding: { top: 0 } }, stroke: { width: 2 }, tooltip: { x: { show: false }, y: { title: { formatter: function(series, { dataPointIndex }) { const now = moment() if (series === PREVIOUS) now.subtract(span, "days") now.subtract(span - dataPointIndex - 1, "days") return now.format("ll") } }, formatter: function(value, { dataPointIndex, seriesIndex }) { if (seriesIndex === CURRENT_SERIES) { return data.current[dataPointIndex] } return data.previous[dataPointIndex] } } }, xaxis: { axisBorder: { show: false }, axisTicks: { show: false }, labels: { show: false }, categories: [], tooltip: { enabled: false } }, yaxis: { tickAmount: 2, max: m => m || 1, show: false } } const series = [ { name: CURRENT, data: data.currentCumulative }, { name: PREVIOUS, data: data.previousCumulative } ] return (
{name}
{({ width }) => width > 1 && ( ) }
) } const Summary = ({ data, negative }) => { const current = data.current.reduce((a, b) => a + b) const previous = data.previous.reduce((a, b) => a + b) const diff = current - previous let color = "text-light" let icon = "fas fa-equals" if (negative) { if (diff > 0) color = "text-danger" if (diff < 0) color = "text-success" } else { if (diff > 0) color = "text-success" if (diff < 0) color = "text-danger" } if (diff > 0) { icon = "fas fa-chevron-up" } if (diff < 0) { icon = "fas fa-chevron-down" } return (
{current}
{Math.abs(diff)}
) } class ChartContainer extends React.Component { state = { width: 1, height: 1 } element = React.createRef() componentDidMount() { this.timer = window.setInterval(this.updateSize, 3000) this.updateSize() } componentWillUnmount() { window.clearInterval(this.timer) } updateSize = () => { this.setState({ width: this.element.current.clientWidth, height: this.element.current.clientHeight }) } render() { return (
{this.props.children(this.state)}
) } } export default initAnalytics