refactor: SocialIcons
handling
This commit is contained in:
parent
3c8ad67774
commit
fbeab5a744
9 changed files with 114 additions and 147 deletions
|
@ -1,18 +1,35 @@
|
||||||
---
|
---
|
||||||
import AvatarComponent from '@/components/ui/avatar'
|
import AvatarComponent from '@/components/ui/avatar'
|
||||||
import { buttonVariants } from '@/components/ui/button'
|
|
||||||
import { cn } from '@/lib/utils'
|
import { cn } from '@/lib/utils'
|
||||||
import Link from '@components/Link.astro'
|
import Link from '@components/Link.astro'
|
||||||
|
import type { Link as SocialLink } from '@consts'
|
||||||
import type { CollectionEntry } from 'astro:content'
|
import type { CollectionEntry } from 'astro:content'
|
||||||
import { Github, Globe, Linkedin, Twitter } from 'lucide-react'
|
import SocialIcons from './SocialIcons.astro'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
author: CollectionEntry<'authors'>
|
author: CollectionEntry<'authors'>
|
||||||
linkDisabled?: boolean
|
linkDisabled?: boolean
|
||||||
}
|
}
|
||||||
const { author, linkDisabled = false } = Astro.props
|
const { author, linkDisabled = false } = Astro.props
|
||||||
const { name, avatar, bio, pronouns, github, twitter, linkedin, website } =
|
const {
|
||||||
author.data
|
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
|
<div
|
||||||
|
@ -47,64 +64,7 @@ const { name, avatar, bio, pronouns, github, twitter, linkedin, website } =
|
||||||
</div>
|
</div>
|
||||||
<p class="text-sm text-muted-foreground">{bio}</p>
|
<p class="text-sm text-muted-foreground">{bio}</p>
|
||||||
</div>
|
</div>
|
||||||
<ul class="flex gap-2">
|
<SocialIcons links={socialLinks} />
|
||||||
{
|
|
||||||
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>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
---
|
---
|
||||||
import Container from '@components/Container.astro'
|
import Container from '@components/Container.astro'
|
||||||
|
import { SOCIAL_LINKS } from '@consts'
|
||||||
import SocialIcons from './SocialIcons.astro'
|
import SocialIcons from './SocialIcons.astro'
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -13,7 +14,7 @@ import SocialIcons from './SocialIcons.astro'
|
||||||
© {new Date().getFullYear()} All rights reserved.
|
© {new Date().getFullYear()} All rights reserved.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<SocialIcons />
|
<SocialIcons links={SOCIAL_LINKS} />
|
||||||
</div>
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
|
@ -28,13 +28,13 @@ const { title, description, image = '/static/twitter-card.png' } = Astro.props
|
||||||
<meta name="title" content={title} />
|
<meta name="title" content={title} />
|
||||||
<meta name="description" content={description} />
|
<meta name="description" content={description} />
|
||||||
|
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
<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="32x32" href="/favicon-32x32.png" />
|
||||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
|
||||||
<link rel="manifest" href="/site.webmanifest">
|
<link rel="manifest" href="/site.webmanifest" />
|
||||||
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#121212">
|
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#121212" />
|
||||||
<meta name="msapplication-TileColor" content="#121212">
|
<meta name="msapplication-TileColor" content="#121212" />
|
||||||
<meta name="theme-color" content="#121212">
|
<meta name="theme-color" content="#121212" />
|
||||||
|
|
||||||
<meta property="og:type" content="website" />
|
<meta property="og:type" content="website" />
|
||||||
<meta property="og:url" content={Astro.url} />
|
<meta property="og:url" content={Astro.url} />
|
||||||
|
|
|
@ -13,7 +13,7 @@ import logo from '../../public/static/logo.svg'
|
||||||
transition:persist
|
transition:persist
|
||||||
>
|
>
|
||||||
<Container>
|
<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
|
<Link
|
||||||
href="/"
|
href="/"
|
||||||
class="flex flex-shrink-0 items-center gap-2 text-xl font-semibold transition-colors duration-300 hover:text-primary"
|
class="flex flex-shrink-0 items-center gap-2 text-xl font-semibold transition-colors duration-300 hover:text-primary"
|
||||||
|
|
|
@ -1,59 +1,57 @@
|
||||||
---
|
---
|
||||||
import { buttonVariants } from '@/components/ui/button'
|
import { buttonVariants } from '@/components/ui/button'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
import Link from '@components/Link.astro'
|
import Link from '@components/Link.astro'
|
||||||
import { SITE } from '@consts'
|
import type { Link as SocialLink } from '@consts'
|
||||||
import { Github, Linkedin, Mail, Rss, Twitter } from 'lucide-react'
|
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">
|
<ul class={cn('not-prose flex flex-wrap gap-2', className)} role="list">
|
||||||
|
{
|
||||||
|
links.map((link) => {
|
||||||
|
const { href, ariaLabel, Icon } = getSocialLink(link)
|
||||||
|
return (
|
||||||
<li>
|
<li>
|
||||||
<Link
|
<Link
|
||||||
href="#"
|
href={href}
|
||||||
aria-label="Twitter"
|
aria-label={ariaLabel}
|
||||||
title="Twitter"
|
title={ariaLabel}
|
||||||
class={buttonVariants({ variant: 'outline', size: 'icon' })}
|
class={buttonVariants({ variant: 'outline', size: 'icon' })}
|
||||||
>
|
>
|
||||||
<Twitter className="size-4" />
|
<Icon 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>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -34,7 +34,7 @@ function buildToc(headings: Heading[]) {
|
||||||
Table of Contents
|
Table of Contents
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/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"
|
viewBox="0 0 20 20"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
>
|
>
|
||||||
|
@ -45,7 +45,7 @@ function buildToc(headings: Heading[]) {
|
||||||
</svg>
|
</svg>
|
||||||
</summary>
|
</summary>
|
||||||
<nav>
|
<nav>
|
||||||
<ul class="py-3">
|
<ul class="pt-3">
|
||||||
{toc.map((heading) => <TableOfContentsHeading heading={heading} />)}
|
{toc.map((heading) => <TableOfContentsHeading heading={heading} />)}
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
|
@ -6,7 +6,7 @@ export type Site = {
|
||||||
SITEURL: string
|
SITEURL: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type NavigationLink = {
|
export type Link = {
|
||||||
href: string
|
href: string
|
||||||
label: string
|
label: string
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,15 @@ export const SITE: Site = {
|
||||||
SITEURL: 'https://astro-erudite.vercel.app',
|
SITEURL: 'https://astro-erudite.vercel.app',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const NAV_LINKS: NavigationLink[] = [
|
export const NAV_LINKS: Link[] = [
|
||||||
{ href: '/blog', label: 'blog' },
|
{ href: '/blog', label: 'blog' },
|
||||||
{ href: '/authors', label: 'authors' },
|
{ href: '/authors', label: 'authors' },
|
||||||
{ href: '/about', label: 'about' },
|
{ href: '/about', label: 'about' },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
export const SOCIAL_LINKS: Link[] = [
|
||||||
|
{ href: 'https://github.com/jktrn', label: 'GitHub' },
|
||||||
|
{ href: 'https://twitter.com/enscry', label: 'Twitter' },
|
||||||
|
{ href: 'jason@enscribe.dev', label: 'Email' },
|
||||||
|
{ href: '/rss.xml', label: 'RSS' },
|
||||||
|
]
|
||||||
|
|
|
@ -4,6 +4,7 @@ pronouns: 'he/him'
|
||||||
avatar: 'https://gravatar.com/avatar/9bfdc4ec972793cf05cb91efce5f4aaaec2a0da1bf4ec34dad0913f1d845faf6.webp?size=256'
|
avatar: 'https://gravatar.com/avatar/9bfdc4ec972793cf05cb91efce5f4aaaec2a0da1bf4ec34dad0913f1d845faf6.webp?size=256'
|
||||||
bio: 'd(-_-)b'
|
bio: 'd(-_-)b'
|
||||||
website: 'https://enscribe.dev'
|
website: 'https://enscribe.dev'
|
||||||
twitter: 'enscry'
|
twitter: 'https://twitter.com/enscry'
|
||||||
github: 'jktrn'
|
github: 'https://github.com/jktrn'
|
||||||
|
mail: 'jason@enscribe.dev'
|
||||||
---
|
---
|
||||||
|
|
Loading…
Add table
Reference in a new issue