feat: tags

Signed-off-by: Filipe Medeiros <hello@filipesm.eu>
This commit is contained in:
Filipe Medeiros 2022-12-25 14:08:27 +00:00
parent 95bea24ec1
commit 2b51277f1d
Signed by: filipe
GPG key ID: 9533BD5467CC1E78
7 changed files with 136 additions and 11 deletions

View file

@ -2,11 +2,13 @@ import Card, {
CardCta,
CardDescription,
CardEyebrow,
CardTags,
CardTitle,
} from '@/components/server/Card'
import SimpleLayout from '@/components/server/SimpleLayout'
import formatDate from '@/lib/formatDate'
import { getFirstBlogPosts } from '@/lib/notion/content/blogPosts'
import { SelectColor } from '@/lib/notion/types'
import richTextAsPlainText from '@/lib/notion/utils/richTextToPlainText'
export const revalidate = 600
@ -16,11 +18,13 @@ function BlogPost({
title,
description,
publishDate,
topics,
}: {
slug: string
title: string
description: string
publishDate: string
topics: { name: string; color: SelectColor }[]
}) {
return (
<article className="md:grid md:grid-cols-4 md:items-baseline">
@ -35,6 +39,16 @@ function BlogPost({
{formatDate(publishDate)}
</CardEyebrow>
<CardDescription>{description}</CardDescription>
<CardTags>
{topics.map((topic) => (
<span
key={topic.name}
className={`notion-color-${topic.color} rounded bg-[var(--light-bg)] p-1 text-[var(--light-text)] dark:bg-[var(--dark-bg)] dark:text-[var(--dark-text)]`}
>
{topic.name}
</span>
))}
</CardTags>
<CardCta> o artigo</CardCta>
</Card>
<CardEyebrow
@ -65,6 +79,9 @@ export default async function Blog() {
description={richTextAsPlainText(
blogPost.properties.Description.rich_text,
)}
topics={blogPost.properties.Topics.multi_select.map(
({ name, color }) => ({ name, color }),
)}
slug={richTextAsPlainText(blogPost.properties.Slug.rich_text)}
publishDate={richTextAsPlainText(
blogPost.properties.PublishDate.date?.start ??

View file

@ -2,12 +2,38 @@ import { PropsWithChildren } from 'react'
import Header from '@/components/client/Header'
import Footer from '@/components/server/Footer'
import colorMap from '@/lib/notion/utils/colorMap'
import './globals.css'
const notionColorsCssVars = Object.entries(colorMap)
.map(([name, colors]) =>
[
`--notion-${name}-dark-text:${colors.dark.text};`,
`--notion-${name}-dark-bg:${colors.dark.bg};`,
`--notion-${name}-light-text:${colors.light.text};`,
`--notion-${name}-light-bg:${colors.light.bg};`,
].join(''),
)
.join('')
const notionEachColorClass = Object.entries(colorMap)
.map(
([name]) =>
`.notion-color-${name}{--dark-text:var(--notion-${name}-dark-text);--dark-bg:var(--notion-${name}-dark-bg);--light-text:var(--notion-${name}-light-text);--light-bg:var(--notion-${name}-light-bg);}`,
)
.join('')
export default function BaseLayout({ children }: PropsWithChildren) {
return (
<html className="h-full antialiased" lang="pt-PT">
<head>
<style
dangerouslySetInnerHTML={{
__html: `:root{${notionColorsCssVars}} ${notionEachColorClass}`,
}}
/>
</head>
<body className="flex h-full flex-col bg-zinc-50 font-serif dark:bg-black">
<div className="fixed inset-0 flex justify-center sm:px-8">
<div className="flex w-full max-w-7xl lg:px-8">

View file

@ -1,12 +1,13 @@
import Head from 'next/head'
import Image, { ImageProps } from 'next/image'
import { type ElementType } from 'react'
import { type ElementType, Fragment } from 'react'
import Button from '@/components/client/Button'
import Card, {
CardCta,
CardDescription,
CardEyebrow,
CardTags,
CardTitle,
} from '@/components/server/Card'
import Container from '@/components/server/Container'
@ -25,6 +26,8 @@ import FarfetchLogo from '@/images/logos/farfetch.png'
import ThreeSigmaLogo from '@/images/logos/threeSigma.png'
import formatDate from '@/lib/formatDate'
import { getFirstBlogPosts } from '@/lib/notion/content/blogPosts'
import { SelectColor } from '@/lib/notion/types'
import colorMap from '@/lib/notion/utils/colorMap'
import richTextAsPlainText from '@/lib/notion/utils/richTextToPlainText'
function BriefcaseIcon(props: IconProps) {
@ -68,11 +71,14 @@ function BlogPost({
title,
description,
publishDate,
topics,
}: {
slug: string
title: string
description: string
publishDate: string
topics: { name: string; color: SelectColor }[]
}) {
return (
<Card as="article">
@ -81,6 +87,16 @@ function BlogPost({
{formatDate(publishDate)}
</CardEyebrow>
<CardDescription>{description}</CardDescription>
<CardTags>
{topics.map((topic) => (
<span
key={topic.name}
className={`notion-color-${topic.color} rounded bg-[var(--light-bg)] p-1 text-[var(--light-text)] dark:bg-[var(--dark-bg)] dark:text-[var(--dark-text)]`}
>
{topic.name}
</span>
))}
</CardTags>
<CardCta> o artigo</CardCta>
</Card>
)
@ -241,8 +257,6 @@ function Resume() {
export default async function Home() {
const { results: blogPosts } = await getFirstBlogPosts()
console.log(blogPosts)
return (
<>
<Container className="mt-9">
@ -302,6 +316,12 @@ export default async function Home() {
description={richTextAsPlainText(
blogPost.properties.Description.rich_text,
)}
topics={blogPost.properties.Topics.multi_select.map(
({ name, color }) => ({
name,
color,
}),
)}
slug={richTextAsPlainText(blogPost.properties.Slug.rich_text)}
publishDate={richTextAsPlainText(
blogPost.properties.PublishDate.date?.start ??

View file

@ -56,6 +56,10 @@ export function CardDescription({ children }: PropsWithChildren) {
)
}
export function CardTags({ children }: PropsWithChildren) {
return <div className="z-10 mt-2 flex gap-1 text-sm">{children}</div>
}
export function CardCta({ children }: PropsWithChildren) {
return (
<div
@ -103,9 +107,11 @@ export default function Card({
as: Component = 'div',
className,
children,
}: PropsWithChildren<{ className?: string; as?: ElementType }>) {
id,
}: PropsWithChildren<{ id?: string; className?: string; as?: ElementType }>) {
return (
<Component
id={id}
className={clsx(className, 'group relative flex flex-col items-start')}
>
{children}

View file

@ -0,0 +1,44 @@
const colorMap = {
default: {
dark: { text: '#FFFFFF', bg: '#2F3437' },
light: { text: '#37352F', bg: '#FFFFFF' },
},
gray: {
dark: { text: '#979A9B', bg: '#454B4E' },
light: { text: '#9B9A97', bg: '#EBECED' },
},
brown: {
dark: { text: '#937264', bg: '#434040' },
light: { text: '#64473A', bg: '#E9E5E3' },
},
orange: {
dark: { text: '#FFA344', bg: '#594A3A' },
light: { text: '#D9730D', bg: '#FAEBDD' },
},
yellow: {
dark: { text: '#FFDC49', bg: '#59563B' },
light: { text: '#DFAB01', bg: '#FBF3DB' },
},
green: {
dark: { text: '#4DAB9A', bg: '#354C4B' },
light: { text: '#0F7B6C', bg: '#DDEDEA' },
},
blue: {
dark: { text: '#529CCA', bg: '#364954' },
light: { text: '#0B6E99', bg: '#DDEBF1' },
},
purple: {
dark: { text: '#9A6DD7', bg: '#443F57' },
light: { text: '#6940A5', bg: '#EAE4F2' },
},
pink: {
dark: { text: '#E255A1', bg: '#533B4C' },
light: { text: '#AD1A72', bg: '#F4DFEB' },
},
red: {
dark: { text: '#FF7369', bg: '#594141' },
light: { text: '#E03E3E', bg: '#FBE4E4' },
},
}
export default colorMap

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long