src/components/AuthorCard.astro (view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
--- import Link from '@/components/Link.astro' import AvatarComponent from '@/components/ui/avatar' import type { Link as SocialLink } from '@/consts' import { cn } from '@/lib/utils' import type { CollectionEntry } from 'astro:content' 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, 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 class="overflow-hidden rounded-xl border p-4 transition-colors duration-300 ease-in-out has-[a:hover]:bg-secondary/50" > <div class="flex flex-wrap gap-4"> <Link href={`/authors/${author.slug}`} class={cn('block', linkDisabled && 'pointer-events-none')} > <AvatarComponent client:load src={avatar} alt={`Avatar of ${name}`} fallback={name[0]} className={cn( 'size-32 rounded-md', !linkDisabled && 'transition-shadow duration-300 hover:cursor-pointer hover:ring-2 hover:ring-primary', )} /> </Link> <div class="flex flex-grow flex-col justify-between gap-y-4"> <div> <div class="flex flex-wrap items-center gap-x-2"> <h3 class="text-lg font-semibold">{name}</h3> { pronouns && ( <span class="text-sm text-muted-foreground">({pronouns})</span> ) } </div> <p class="text-sm text-muted-foreground">{bio}</p> </div> <SocialIcons links={socialLinks} /> </div> </div> </div> |