Changes to dashboard and added CardGroup component

This commit is contained in:
r-freeman 2023-01-29 23:04:28 +00:00
parent c34ad0fa5c
commit de56c2aec7
4 changed files with 57 additions and 38 deletions

22
components/CardGroup.tsx Normal file
View File

@ -0,0 +1,22 @@
import React, {ReactNode, useId} from 'react'
type CardGroupProps = {
title: string
children: ReactNode
}
export function CardGroup({title, children}: CardGroupProps) {
const id = useId()
return (
<section aria-labelledby={id}>
<h2 id={id} className="text-sm font-semibold text-zinc-800 dark:text-zinc-100 mb-8">{title}</h2>
<ul
role="list"
className="grid grid-cols-1 gap-x-12 gap-y-16 sm:grid-cols-2 lg:grid-cols-3 mb-16"
>
{children}
</ul>
</section>
)
}

View File

@ -1,7 +1,7 @@
import {getTotalFollowers, getTotalRepos, getTotalStars} from '@/lib/github' import {getTotalFollowers, getTotalRepos, getTotalStars} from '@/lib/github'
import {getAllArticles} from '@/lib/getAllArticles' import {getAllArticles} from '@/lib/getAllArticles'
import {getViews} from '@/lib/views' import {getViews} from '@/lib/views'
import {CardProps} from '@/types' import {Metric} from '@/types'
export async function getDashboardData() { export async function getDashboardData() {
const [totalRepos, totalFollowers] = await Promise.all([ const [totalRepos, totalFollowers] = await Promise.all([
@ -13,43 +13,44 @@ export async function getDashboardData() {
const totalArticles = (await getAllArticles()).length const totalArticles = (await getAllArticles()).length
const totalArticleViews = (await getViews()).views const totalArticleViews = (await getViews()).views
const data: CardProps[] = [ const metrics: Metric[] = [
{ {
title: "Repos", title: "Repos",
metric: totalRepos, value: totalRepos,
group: "GitHub", group: "GitHub",
href: "https://github.com/r-freeman?tab=repositories" href: "https://github.com/r-freeman?tab=repositories"
}, },
{ {
title: "Followers", title: "Followers",
metric: totalFollowers, value: totalFollowers,
group: "GitHub", group: "GitHub",
href: "https://github.com/r-freeman?tab=followers" href: "https://github.com/r-freeman?tab=followers"
}, },
{ {
title: "Stars", title: "Stars",
metric: totalStars, value: totalStars,
group: "GitHub", group: "GitHub",
href: "https://github.com/r-freeman/" href: "https://github.com/r-freeman/"
}, },
{ {
title: "Total Articles", title: "Total Articles",
metric: totalArticles, value: totalArticles,
group: "Website", group: "Website",
href: "/writing" href: "/writing"
}, },
{ {
title: "Total Article Views", title: "Total Article Views",
metric: totalArticleViews, value: totalArticleViews,
group: "Website", group: "Website",
href: "/writing" href: "/writing"
} }
] ]
const groups = data.reduce((acc: { [key: string]: CardProps[] }, item) => { // sort metrics into named groups
const groups = metrics.reduce((acc: { [key: string]: Metric[] }, item) => {
(acc[item.group] = acc[item.group] || []).push(item); (acc[item.group] = acc[item.group] || []).push(item);
return acc return acc
}, {} as { [key: string]: CardProps[] }) }, {} as { [key: string]: Metric[] })
return Object.entries(groups).map(([groupName, groupItems]) => { return Object.entries(groups).map(([groupName, groupItems]) => {
return {groupName, groupItems} return {groupName, groupItems}

View File

@ -3,18 +3,20 @@ import Head from 'next/head'
import {GetStaticProps} from 'next' import {GetStaticProps} from 'next'
import {SimpleLayout} from '@/components/SimpleLayout' import {SimpleLayout} from '@/components/SimpleLayout'
import {Card} from '@/components/Card' import {Card} from '@/components/Card'
import {CardGroup} from '@/components/CardGroup'
import {numberFormat} from '@/lib/numberFormat' import {numberFormat} from '@/lib/numberFormat'
import {getDashboardData} from '@/lib/dashboard' import {getDashboardData} from '@/lib/dashboard'
import type {CardGroupProps} from '@/types' import type {MetricGroup} from '@/types'
export default function Dashboard({cardGroups}: { cardGroups: CardGroupProps }) {
export default function Dashboard({metrics}: { metrics: MetricGroup }) {
return ( return (
<> <>
<Head> <Head>
<title>Dashboard - Ryan Freeman</title> <title>Dashboard - Ryan Freeman</title>
<meta <meta
name="description" name="description"
content="This is my digital life in numbers which is updated daily. I use this dashboard to track various metrics across platforms like Spotify, GitHub, Twitter and more." content="This is my digital life in numbers which is updated daily. I use this dashboard to keep track of various metrics across platforms like Spotify, GitHub, Twitter and more."
/> />
<meta <meta
property="og:title" property="og:title"
@ -22,33 +24,27 @@ export default function Dashboard({cardGroups}: { cardGroups: CardGroupProps })
/> />
<meta <meta
property="og:description" property="og:description"
content="This is my digital life in numbers which is updated daily. I use this dashboard to track various metrics across platforms like Spotify, GitHub, Twitter and more." content="This is my digital life in numbers which is updated daily. I use this dashboard to keep track of various metrics across platforms like Spotify, GitHub, Twitter and more."
/> />
</Head> </Head>
<SimpleLayout <SimpleLayout
title="Dashboard." title="Dashboard."
intro="This is my digital life in numbers which is updated daily. I use this dashboard to track various metrics across platforms like Spotify, GitHub, Twitter and more." intro="This is my digital life in numbers which is updated daily. I use this dashboard to keep track of various metrics across platforms like Spotify, GitHub, Twitter and more."
gradient="bg-gradient-to-r from-orange-300 to-rose-300" gradient="bg-gradient-to-r from-orange-300 to-rose-300"
> >
{cardGroups.map(({groupName, groupItems}, index) => ( {metrics.map(({groupName, groupItems}) => (
<section key={index}> <CardGroup title={groupName} key={groupName}>
<h2 className="text-sm font-semibold text-zinc-800 dark:text-zinc-100 mb-8">{groupName}</h2> {groupItems.map((item) => (
<ul <Card as="li" key={item.title}>
role="list" <h2 className="text-base font-semibold transition group-hover:text-indigo-500 text-zinc-800 dark:text-zinc-400">
className="grid grid-cols-1 gap-x-12 gap-y-16 sm:grid-cols-2 lg:grid-cols-3 mb-16" <Card.Link href={item.href}>{item.title}</Card.Link>
> </h2>
{groupItems.map((card) => ( <Card.Description className="text-zinc-800 dark:text-zinc-100 font-semibold text-5xl">
<Card as="li" key={card.title}> {typeof item.value === "number" ? numberFormat(item.value) : item.value}
<h2 className="text-base font-semibold transition group-hover:text-indigo-500 text-zinc-800 dark:text-zinc-400"> </Card.Description>
<Card.Link href={card.href}>{card.title}</Card.Link> </Card>
</h2> ))}
<Card.Description className="text-zinc-800 dark:text-zinc-100 font-semibold text-5xl"> </CardGroup>
{typeof card.metric === "number" ? numberFormat(card.metric) : card.metric}
</Card.Description>
</Card>
))}
</ul>
</section>
))} ))}
</SimpleLayout> </SimpleLayout>
</> </>
@ -58,7 +54,7 @@ export default function Dashboard({cardGroups}: { cardGroups: CardGroupProps })
export const getStaticProps: GetStaticProps = async () => { export const getStaticProps: GetStaticProps = async () => {
return { return {
props: { props: {
cardGroups: await getDashboardData() metrics: await getDashboardData()
} }
} }
} }

View File

@ -24,16 +24,16 @@ export type Repo = {
} }
} }
export type CardProps = { export type Metric = {
title: string title: string
metric: number | string value: number | string
group: string group: string
href: string href: string
} }
export type CardGroupProps = [ export type MetricGroup = [
{ {
groupName: string, groupName: string,
groupItems: CardProps[] groupItems: Metric[]
} }
] ]