mirror of
https://github.com/r-freeman/portfolio.git
synced 2024-11-22 13:35:41 +00:00
Changes to dashboard and added CardGroup component
This commit is contained in:
parent
c34ad0fa5c
commit
de56c2aec7
22
components/CardGroup.tsx
Normal file
22
components/CardGroup.tsx
Normal 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>
|
||||
)
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
import {getTotalFollowers, getTotalRepos, getTotalStars} from '@/lib/github'
|
||||
import {getAllArticles} from '@/lib/getAllArticles'
|
||||
import {getViews} from '@/lib/views'
|
||||
import {CardProps} from '@/types'
|
||||
import {Metric} from '@/types'
|
||||
|
||||
export async function getDashboardData() {
|
||||
const [totalRepos, totalFollowers] = await Promise.all([
|
||||
@ -13,43 +13,44 @@ export async function getDashboardData() {
|
||||
const totalArticles = (await getAllArticles()).length
|
||||
const totalArticleViews = (await getViews()).views
|
||||
|
||||
const data: CardProps[] = [
|
||||
const metrics: Metric[] = [
|
||||
{
|
||||
title: "Repos",
|
||||
metric: totalRepos,
|
||||
value: totalRepos,
|
||||
group: "GitHub",
|
||||
href: "https://github.com/r-freeman?tab=repositories"
|
||||
},
|
||||
{
|
||||
title: "Followers",
|
||||
metric: totalFollowers,
|
||||
value: totalFollowers,
|
||||
group: "GitHub",
|
||||
href: "https://github.com/r-freeman?tab=followers"
|
||||
},
|
||||
{
|
||||
title: "Stars",
|
||||
metric: totalStars,
|
||||
value: totalStars,
|
||||
group: "GitHub",
|
||||
href: "https://github.com/r-freeman/"
|
||||
},
|
||||
{
|
||||
title: "Total Articles",
|
||||
metric: totalArticles,
|
||||
value: totalArticles,
|
||||
group: "Website",
|
||||
href: "/writing"
|
||||
},
|
||||
{
|
||||
title: "Total Article Views",
|
||||
metric: totalArticleViews,
|
||||
value: totalArticleViews,
|
||||
group: "Website",
|
||||
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);
|
||||
return acc
|
||||
}, {} as { [key: string]: CardProps[] })
|
||||
}, {} as { [key: string]: Metric[] })
|
||||
|
||||
return Object.entries(groups).map(([groupName, groupItems]) => {
|
||||
return {groupName, groupItems}
|
||||
|
@ -3,18 +3,20 @@ import Head from 'next/head'
|
||||
import {GetStaticProps} from 'next'
|
||||
import {SimpleLayout} from '@/components/SimpleLayout'
|
||||
import {Card} from '@/components/Card'
|
||||
import {CardGroup} from '@/components/CardGroup'
|
||||
import {numberFormat} from '@/lib/numberFormat'
|
||||
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 (
|
||||
<>
|
||||
<Head>
|
||||
<title>Dashboard - Ryan Freeman</title>
|
||||
<meta
|
||||
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
|
||||
property="og:title"
|
||||
@ -22,33 +24,27 @@ export default function Dashboard({cardGroups}: { cardGroups: CardGroupProps })
|
||||
/>
|
||||
<meta
|
||||
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>
|
||||
<SimpleLayout
|
||||
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"
|
||||
>
|
||||
{cardGroups.map(({groupName, groupItems}, index) => (
|
||||
<section key={index}>
|
||||
<h2 className="text-sm font-semibold text-zinc-800 dark:text-zinc-100 mb-8">{groupName}</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"
|
||||
>
|
||||
{groupItems.map((card) => (
|
||||
<Card as="li" key={card.title}>
|
||||
{metrics.map(({groupName, groupItems}) => (
|
||||
<CardGroup title={groupName} key={groupName}>
|
||||
{groupItems.map((item) => (
|
||||
<Card as="li" key={item.title}>
|
||||
<h2 className="text-base font-semibold transition group-hover:text-indigo-500 text-zinc-800 dark:text-zinc-400">
|
||||
<Card.Link href={card.href}>{card.title}</Card.Link>
|
||||
<Card.Link href={item.href}>{item.title}</Card.Link>
|
||||
</h2>
|
||||
<Card.Description className="text-zinc-800 dark:text-zinc-100 font-semibold text-5xl">
|
||||
{typeof card.metric === "number" ? numberFormat(card.metric) : card.metric}
|
||||
{typeof item.value === "number" ? numberFormat(item.value) : item.value}
|
||||
</Card.Description>
|
||||
</Card>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
</CardGroup>
|
||||
))}
|
||||
</SimpleLayout>
|
||||
</>
|
||||
@ -58,7 +54,7 @@ export default function Dashboard({cardGroups}: { cardGroups: CardGroupProps })
|
||||
export const getStaticProps: GetStaticProps = async () => {
|
||||
return {
|
||||
props: {
|
||||
cardGroups: await getDashboardData()
|
||||
metrics: await getDashboardData()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,16 +24,16 @@ export type Repo = {
|
||||
}
|
||||
}
|
||||
|
||||
export type CardProps = {
|
||||
export type Metric = {
|
||||
title: string
|
||||
metric: number | string
|
||||
value: number | string
|
||||
group: string
|
||||
href: string
|
||||
}
|
||||
|
||||
export type CardGroupProps = [
|
||||
export type MetricGroup = [
|
||||
{
|
||||
groupName: string,
|
||||
groupItems: CardProps[]
|
||||
groupItems: Metric[]
|
||||
}
|
||||
]
|
||||
|
Loading…
Reference in New Issue
Block a user