refactor: SocialIcons handling

This commit is contained in:
enscribe 2024-09-13 11:45:15 -07:00
parent 3c8ad67774
commit fbeab5a744
No known key found for this signature in database
GPG key ID: 9BBD5C4114E25322
9 changed files with 114 additions and 147 deletions

View file

@ -1,18 +1,35 @@
---
import AvatarComponent from '@/components/ui/avatar'
import { buttonVariants } from '@/components/ui/button'
import { cn } from '@/lib/utils'
import Link from '@components/Link.astro'
import type { Link as SocialLink } from '@consts'
import type { CollectionEntry } from 'astro:content'
import { Github, Globe, Linkedin, Twitter } from 'lucide-react'
import SocialIcons from './SocialIcons.astro'
type Props = {
author: CollectionEntry<'authors'>
linkDisabled?: boolean
}
const { author, linkDisabled = false } = Astro.props
const { name, avatar, bio, pronouns, github, twitter, linkedin, website } =
author.data
const {
name,
avatar,
bio,
pronouns,
github,
twitter,
linkedin,
website,
mail,
} = author.data
const socialLinks: SocialLink[] = [
website && { href: website, label: 'Website' },
github && { href: github, label: 'GitHub' },
twitter && { href: twitter, label: 'Twitter' },
linkedin && { href: linkedin, label: 'LinkedIn' },
mail && { href: mail, label: 'Email' },
].filter(Boolean) as SocialLink[]
---
<div
@ -47,64 +64,7 @@ const { name, avatar, bio, pronouns, github, twitter, linkedin, website } =
</div>
<p class="text-sm text-muted-foreground">{bio}</p>
</div>
<ul class="flex gap-2">
{
github && (
<li>
<Link
href={`https://github.com/${github}`}
aria-label="GitHub"
title="GitHub"
class={buttonVariants({ variant: 'outline', size: 'icon' })}
>
<Github className="size-4" />
</Link>
</li>
)
}
{
twitter && (
<li>
<Link
href={`https://twitter.com/${twitter}`}
aria-label="Twitter"
title="Twitter"
class={buttonVariants({ variant: 'outline', size: 'icon' })}
>
<Twitter className="size-4" />
</Link>
</li>
)
}
{
linkedin && (
<li>
<Link
href={`https://linkedin.com/in/${linkedin}`}
aria-label="LinkedIn"
title="LinkedIn"
class={buttonVariants({ variant: 'outline', size: 'icon' })}
>
<Linkedin className="size-4" />
</Link>
</li>
)
}
{
website && (
<li>
<Link
href={website}
aria-label="Website"
title="Website"
class={buttonVariants({ variant: 'outline', size: 'icon' })}
>
<Globe className="size-4" />
</Link>
</li>
)
}
</ul>
<SocialIcons links={socialLinks} />
</div>
</div>
</div>

View file

@ -1,5 +1,6 @@
---
import Container from '@components/Container.astro'
import { SOCIAL_LINKS } from '@consts'
import SocialIcons from './SocialIcons.astro'
---
@ -13,7 +14,7 @@ import SocialIcons from './SocialIcons.astro'
&copy; {new Date().getFullYear()} All rights reserved.
</p>
</div>
<SocialIcons />
<SocialIcons links={SOCIAL_LINKS} />
</div>
</Container>
</footer>

View file

@ -28,13 +28,13 @@ const { title, description, image = '/static/twitter-card.png' } = Astro.props
<meta name="title" content={title} />
<meta name="description" content={description} />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#121212">
<meta name="msapplication-TileColor" content="#121212">
<meta name="theme-color" content="#121212">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
<link rel="manifest" href="/site.webmanifest" />
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#121212" />
<meta name="msapplication-TileColor" content="#121212" />
<meta name="theme-color" content="#121212" />
<meta property="og:type" content="website" />
<meta property="og:url" content={Astro.url} />

View file

@ -13,7 +13,7 @@ import logo from '../../public/static/logo.svg'
transition:persist
>
<Container>
<div class="flex flex-wrap items-center justify-between gap-x-4 py-4">
<div class="flex flex-wrap items-center justify-between gap-4 py-4">
<Link
href="/"
class="flex flex-shrink-0 items-center gap-2 text-xl font-semibold transition-colors duration-300 hover:text-primary"

View file

@ -1,59 +1,57 @@
---
import { buttonVariants } from '@/components/ui/button'
import { cn } from '@/lib/utils'
import Link from '@components/Link.astro'
import { SITE } from '@consts'
import { Github, Linkedin, Mail, Rss, Twitter } from 'lucide-react'
import type { Link as SocialLink } from '@consts'
import {
Github,
Globe,
Linkedin,
Mail,
MessageCircleQuestion,
Rss,
Twitter,
} from 'lucide-react'
interface Props {
links: SocialLink[]
className?: string
}
const { links, className } = Astro.props
const iconMap = {
Website: Globe,
GitHub: Github,
LinkedIn: Linkedin,
Twitter: Twitter,
Email: Mail,
RSS: Rss,
}
const getSocialLink = ({ href, label }: SocialLink) => ({
href: label === 'Email' ? `mailto:${href}` : href,
ariaLabel: label,
Icon: iconMap[label as keyof typeof iconMap] || MessageCircleQuestion,
})
---
<ul class="not-prose flex flex-wrap gap-2" role="list">
<li>
<Link
href="#"
aria-label="Twitter"
title="Twitter"
class={buttonVariants({ variant: 'outline', size: 'icon' })}
>
<Twitter className="size-4" />
</Link>
</li>
<li>
<Link
href="#"
aria-label="GitHub"
title="GitHub"
class={buttonVariants({ variant: 'outline', size: 'icon' })}
>
<Github className="size-4" />
</Link>
</li>
<li>
<Link
href="#"
aria-label="LinkedIn"
title="LinkedIn"
class={buttonVariants({ variant: 'outline', size: 'icon' })}
>
<Linkedin className="size-4" />
</Link>
</li>
<li>
<Link
href="#"
aria-label="Email"
title="Email"
class={buttonVariants({ variant: 'outline', size: 'icon' })}
>
<Mail className="size-4" />
</Link>
</li>
<li>
<Link
href={`${SITE.SITEURL}/rss.xml`}
aria-label="RSS feed"
title="RSS feed"
class={buttonVariants({ variant: 'outline', size: 'icon' })}
>
<Rss className="size-4" />
</Link>
</li>
<ul class={cn('not-prose flex flex-wrap gap-2', className)} role="list">
{
links.map((link) => {
const { href, ariaLabel, Icon } = getSocialLink(link)
return (
<li>
<Link
href={href}
aria-label={ariaLabel}
title={ariaLabel}
class={buttonVariants({ variant: 'outline', size: 'icon' })}
>
<Icon className="size-4" />
</Link>
</li>
)
})
}
</ul>

View file

@ -34,7 +34,7 @@ function buildToc(headings: Heading[]) {
Table of Contents
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5 transition-transform group-open:rotate-180"
class="size-5 transition-transform group-open:rotate-180"
viewBox="0 0 20 20"
fill="currentColor"
>
@ -45,7 +45,7 @@ function buildToc(headings: Heading[]) {
</svg>
</summary>
<nav>
<ul class="py-3">
<ul class="pt-3">
{toc.map((heading) => <TableOfContentsHeading heading={heading} />)}
</ul>
</nav>