admin/components/events/create/CreateEventPreviewCard.tsx
alisaza e1eaf5eff5 feat: initial ghabilee-admin backoffice app
Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js
app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
2026-09-05 13:12:59 +03:30

73 lines
2.9 KiB
TypeScript

'use client'
import type { EventWizardFormData } from '@/components/events/create/types'
import { formatToman } from '@/components/events/create/types'
import { cn } from '@/lib/cn'
import { texts } from '@/texts'
interface CreateEventPreviewCardProps {
categoryName?: string
cityName?: string
data: EventWizardFormData
endsAt: string
startsAt: string
}
interface PreviewField {
full?: boolean
label: string
value: string
}
/** Read-only event card that mirrors the information guests see before booking. */
export default function CreateEventPreviewCard({ categoryName, cityName, data, endsAt, startsAt }: CreateEventPreviewCardProps) {
const fields = [
{ label: texts.common.category, value: categoryName || texts.status.empty },
{ label: texts.events.start, value: startsAt || texts.status.empty },
{ label: texts.events.end, value: endsAt || texts.status.empty },
{ label: texts.events.location, value: cityName || texts.status.empty },
{ label: texts.events.price, value: data.isFree ? texts.events.free : formatToman(data.price) },
{ label: texts.events.capacity, value: String(data.capacity) },
{ full: true, label: texts.events.address, value: data.address || texts.status.empty },
] satisfies PreviewField[]
const poster = [...data.media].sort((a, b) => a.sortOrder - b.sortOrder).find((item) => item.isPoster) ?? data.media[0]
return (
<article className="overflow-hidden rounded-consumer-surface bg-consumer-surface">
<div
aria-label={poster ? texts.events.posterAria : texts.events.noPosterAria}
className={cn(
'flex min-h-48 items-end bg-cover bg-center p-5 sm:min-h-60',
!poster && 'bg-gradient-to-br from-primary-100 to-primary-50'
)}
role="img"
style={
poster
? {
backgroundImage: `linear-gradient(to top, color-mix(in srgb, var(--color-secondary-10) 72%, transparent), transparent 62%), url("${poster.url}")`,
}
: undefined
}
>
<div className={poster ? 'text-white' : 'text-primary-900'}>
<p className="mb-2 text-xs font-semibold opacity-80">{categoryName || texts.events.eventCategoryFallback}</p>
<h3 className="text-xl font-extrabold sm:text-2xl">{data.title || texts.events.eventTitleLabel}</h3>
{data.shortDescription ? <p className="mt-2 max-w-2xl text-sm leading-6 opacity-90">{data.shortDescription}</p> : null}
</div>
</div>
<div className="grid gap-2 grid-cols-2 mt-2">
{fields.map((field) => (
<div
key={field.label}
className={cn('rounded-2xl bg-consumer-surface-muted p-3', field.full && 'sm:col-span-2')}
>
<p className="mb-1 flex items-center gap-1 text-xs text-secondary-20">{field.label}</p>
<p className="text-sm font-semibold text-text-dark">{field.value}</p>
</div>
))}
</div>
</article>
)
}