mirror of
https://github.com/r-freeman/portfolio.git
synced 2024-11-22 13:15: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 {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}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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[]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
Loading…
Reference in New Issue
Block a user