diff --git a/packages/app/public/preview/dashboard.png b/packages/app/public/preview/dashboard.png new file mode 100644 index 00000000..d8c9082e Binary files /dev/null and b/packages/app/public/preview/dashboard.png differ diff --git a/packages/app/src/components/presets/dashboard.js b/packages/app/src/components/presets/dashboard.js new file mode 100644 index 00000000..3a6e54e7 --- /dev/null +++ b/packages/app/src/components/presets/dashboard.js @@ -0,0 +1,280 @@ +/* eslint-disable no-use-before-define,react/jsx-pascal-case */ + +import Inline from '../inline.macro' +import { Box, Fetch, Flex, Image, Link, Spinner, Text, polished } from './scope' + +const code = ( + + <> + + + + {payload => { + // Theme + const { background, barColor, color, lineColor, pieColors } = query.themes[query.theme] || query.themes.dark + const tintBg = polished.darken(0.1, background) + + // Loading state + if (payload === null) { + return ( + + + + ) + } + + // Line Chart data (Daily Requests) + const LC_WIDTH = 840 + const LC_HEIGHT = 184 + const LC_Y_AXIS_WIDTH = 2 + + const yAxisMarkers = Array.from(Array(10).keys()) + + const largestDay = Object.values(payload.byDay).reduce((acc, day) => day.reqs > acc.reqs ? day : acc, { reqs: 0 }) + + const dayData = Object.entries(payload.byDay) + .map(([name, day]) => ({ ...day, name, percent: day.reqs / largestDay.reqs * 100 })) + .reverse() + + const yCoordinates = dayData.map(day => (LC_HEIGHT) - ((LC_HEIGHT) / 100 * day.percent) + 4) + + const xOffset = LC_WIDTH / dayData.length + + const openPath = yCoordinates.reduce((acc, y, index) => { + if (index === 0) { + return `M 0,${y}` + } + + const isLastCoordinate = index === yCoordinates.length - 1 + const x = !isLastCoordinate ? xOffset * index : LC_WIDTH + + return `${acc} L ${x},${y}` + }, '') + + const closedPath = `${openPath} L ${LC_WIDTH},${LC_HEIGHT} L 0,${LC_HEIGHT}Z` + + // Bar Chart data (Monthly Requests) + const largestMonth = Object.values(payload.byMonth).reduce((acc, month) => month.reqs > acc.reqs ? month : acc, { reqs: 0 }) + + const months = Object.entries(payload.byMonth) + .map(([name, month]) => ({ ...month, name, percent: Math.round((month.reqs / largestMonth.reqs) * 100) })).reverse() + + // Pie Chart data (Quarterly Requests) + const byQuarterTotal = Object.values(payload.byQuarter).reduce((acc, quarter) => acc + quarter.reqs, 0) + + const quarters = Object.entries(payload.byQuarter) + .map(([name, quarter]) => ({ ...quarter, name, percent: Math.round((quarter.reqs / byQuarterTotal) * 100) })) + .reverse() + + const quarterCssPercentages = quarters + .map((quarter, index, arr) => { + const prevPercent = index > 0 ? (arr[index - 1].percent || 0) : 0 + return quarter.percent + prevPercent + }) + .map((percent, index) => { + const color = pieColors[index] + return `${color} 0, ${color} ${percent}%` + }).join(', ') + + return ( + <> + + {/* Header */} + + + {query.title} + + + + {/* Daily analytics */} + + + Daily Requests + + + ๐Ÿ—“ {dayData[0].name} -> {dayData[dayData.length - 1].name} + + {largestDay.reqs_pretty} + + {yAxisMarkers.map((_, i) => + )} + + + + + + + + {yCoordinates.map((y, index) => { + const x = index !== yCoordinates.length - 1 ? (index * xOffset) : LC_WIDTH + + return ( + + ) + })} + + + + + + {/* Monthly analytics */} + + + Monthly Requests + + + + {months.map(month => ( + + + {month.reqs_pretty} + + + {month.name} + + + ))} + + + + {/* Quarterly analytics */} + + + Quarterly Requests + + + + + + + {quarters.map((quarter, index) => ( + + + + {quarter.reqs_pretty}
{quarter.name} +
+
+ ))} +
+
+
+
+
+
+ + ) + }} +
+ +
+) + +const query = { + url: 'https://analytics.microlink.io/', + logo: 'https://cdn.microlink.io/logo/logo.svg', + title: 'microlink.io API ยท Analytics', + theme: 'dark', + themes: { + dark: { + background: '#2e2e42', + color: '#fafafa', + lineColor: '#b4e7b7', + barColor: '#34ace0', + pieColors: ['#706fd3', '#33d9b2', '#ff793f', '#34ace0'] + }, + light: { + background: '#fefefe', + color: '#20222f', + lineColor: '#7ed6df', + barColor: '#218c74', + pieColors: ['#ff7979', '#f9ca24', '#686de0', '#c7ecee'] + } + } +} + +export const dashboard = { name: 'Dashboard', code, query } diff --git a/packages/app/src/components/presets/index.js b/packages/app/src/components/presets/index.js index 8ff1bafd..24ed8262 100644 --- a/packages/app/src/components/presets/index.js +++ b/packages/app/src/components/presets/index.js @@ -9,6 +9,7 @@ export { chrisBiscardi } from './chris-biscardi' export { ckgrafico } from './ckgrafico' export { conference } from './conference' export { contentz } from './contentz' +export { dashboard } from './dashboard' export { device } from './device' export { dracula } from './dracula' export { draculaShop } from './dracula-shop'