diff options
| author | aman333nolawz <amananudhiu@gmail.com> | 2026-07-05 19:42:59 +0530 |
|---|---|---|
| committer | aman333nolawz <amananudhiu@gmail.com> | 2026-07-05 20:06:33 +0530 |
| commit | f4a459a27abe0fbd40e2953a3d69e5ecbad99ecb (patch) | |
| tree | f65c5d67514a6b75f13e7433da6d797fb6bfb63d | |
| parent | c2213095b0a039764f98ffee2c187545eadab1f6 (diff) | |
feat: Add card for event details
| -rw-r--r-- | src/components/EventDetails.astro | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/src/components/EventDetails.astro b/src/components/EventDetails.astro new file mode 100644 index 0000000..5923247 --- /dev/null +++ b/src/components/EventDetails.astro @@ -0,0 +1,109 @@ +--- +import Link from '@/components/Link.astro' +import { cn } from '@/lib/utils' +import { Icon } from 'astro-icon/components' + +interface Detail { + icon: string + label: string + value: string + href?: string +} + +interface EventDetailsProps { + title?: string + date?: string + time?: string + venue?: string + requirements?: string + registration?: string + organiser?: string + website?: string + details?: Detail[] + variant?: 'default' | 'compact' + class?: string +} + +const { + title, + date, + time, + venue, + requirements, + registration, + organiser, + website, + details = [], + variant = 'default', + class: className, +} = Astro.props + +const builtIns: Detail[] = [ + date && { icon: 'lucide:calendar', label: 'Date', value: date }, + time && { icon: 'lucide:clock', label: 'Time', value: time }, + venue && { icon: 'lucide:map-pin', label: 'Venue', value: venue }, + requirements && { icon: 'lucide:backpack', label: 'Requirements', value: requirements }, + registration && { icon: 'lucide:clipboard-check', label: 'Registration', value: registration, href: registration }, + organiser && { icon: 'lucide:users', label: 'Organiser', value: organiser }, + website && { icon: 'lucide:external-link', label: 'Website', value: website, href: website }, +].filter(Boolean) as Detail[] + +const allDetails = [...builtIns, ...details] +--- + +<div + class={cn( + 'not-prose rounded-xl border', + variant === 'compact' ? 'p-3' : 'p-4', + className, + )} +> + { + title && ( + <span + class={cn( + 'text-foreground flex items-center gap-2 font-medium', + variant === 'compact' ? 'mb-2 text-sm' : 'mb-3 text-base', + )} + > + <Icon name="lucide:info" class="size-4" /> + {title} + </span> + ) + } + + <dl class="flex flex-col divide-y"> + { + allDetails.map((detail) => ( + <div + class={cn( + 'flex flex-wrap items-center gap-x-4', + variant === 'compact' ? 'gap-y-0.5 py-1.5' : 'gap-y-1 py-2', + 'first:pt-0 last:pb-0', + )} + > + <dt + class={cn( + 'text-muted-foreground flex items-center gap-x-1.5 text-xs font-medium', + variant === 'compact' ? 'min-w-[90px]' : 'min-w-[110px]', + )} + > + <Icon name={detail.icon} class="size-3.5 shrink-0" /> + {detail.label} + </dt> + <dd class="flex-1 text-sm"> + {detail.href ? ( + <Link href={detail.href} external underline> + {detail.value} + </Link> + ) : ( + <span>{detail.value}</span> + )} + </dd> + </div> + )) + } + </dl> + + <slot /> +</div> |
