import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, } from '@/components/ui/dialog'; import { Badge } from '@/components/ui/badge'; import { ImageWithFallback } from '@/components/ImageWithFallback'; import { useTranslation } from '@/contexts/language'; import { sanitizeUrl } from '@/lib/sanitizeUrl'; import { parseLabExtras, labOptionLabel, PAYMENT_METHODS, AVAILABILITY_OPTIONS, RATE_CURRENCIES, ALL_RATE_UNITS, } from '@/lib/labExtras'; import { Banknote, Eye, Languages as LanguagesIcon, MapPin } from 'lucide-react'; export interface LabPreviewSkill { label: string; description?: string; } export interface LabPreviewDraft { title: string; bio: string; image?: string | null; location?: string; experience?: string; rate?: string; skills?: LabPreviewSkill[]; contact?: { phone?: string; email?: string; website?: string; instagram?: string; portfolio?: string; social?: string; noffer?: string; }; /** The form's shared enrichment tags (languages/availability/rate/payments/photo). */ extraTags?: string[][]; } interface LabProfilePreviewProps { open: boolean; onOpenChange: (open: boolean) => void; draft: LabPreviewDraft; heading: string; noun: string; accentText: string; accentChip: string; icon: React.ComponentType<{ className?: string }>; } /** * A "how it will look" preview of a Lab provider profile, built from the form's * current draft โ€” the create flow is long and otherwise blind until publish. * Deliberately a faithful *card*, not the full detail page (which fetches the * published event). */ export function LabProfilePreview({ open, onOpenChange, draft, heading, noun, accentText, accentChip, icon: Icon, }: LabProfilePreviewProps) { const { t } = useTranslation(); const extras = parseLabExtras({ tags: draft.extraTags ?? [] }); const rateAmount = extras.rateAmount; const rateDisplay = rateAmount ? `${rateAmount} ${labOptionLabel(RATE_CURRENCIES, extras.rateCurrency ?? 'sats', t)}` : draft.rate; const unitKey = extras.rateUnit ? ALL_RATE_UNITS.find((u) => u.value === extras.rateUnit)?.key : undefined; const contact = draft.contact ?? {}; const skills = (draft.skills ?? []).slice(0, 8); return ( {t('labUi.preview.title')} {t('labUi.preview.desc', { noun })}
{/* Header */}
{draft.image ? ( ) : (
)}

{draft.title || t('labUi.preview.untitled')}

{heading}
{draft.location && (

{draft.location}

)}
{/* Bio */}

{draft.bio || {t('labUi.preview.noBio')}}

{/* Skills */} {skills.length > 0 && (
{skills.map((s) => ( {s.label} ))}
)} {/* Rate + experience */} {(rateDisplay || draft.experience) && (
{rateDisplay && ( ๐Ÿ’ฐ {rateDisplay}{unitKey ? ` ยท ${t(unitKey)}` : ''} )} {draft.experience && ( {t('labUi.preview.years', { count: draft.experience })} )}
)} {/* Languages / availability / payments */} {(extras.languages.length > 0 || extras.availability.length > 0 || extras.paymentMethods.length > 0 || extras.payWhatYouCan) && (
{extras.languages.length > 0 && (

{extras.languages.join(', ')}

)} {extras.availability.length > 0 && (
{extras.availability.map((v) => ( {labOptionLabel(AVAILABILITY_OPTIONS, v, t)} ))}
)} {(extras.paymentMethods.length > 0 || extras.payWhatYouCan) && (
{extras.paymentMethods.map((m) => ( {labOptionLabel(PAYMENT_METHODS, m, t)} ))} {extras.payWhatYouCan && ( {t('labUi.detail.payWhatYouCan')} )}
)}
)} {/* Gallery preview */} {extras.photos.length > 0 && (
{extras.photos.slice(0, 8).map((url) => (
))}
)} {/* Contact */} {(sanitizeUrl(contact.website) || sanitizeUrl(contact.portfolio) || sanitizeUrl(contact.social) || contact.email || contact.phone || contact.instagram) && (
{contact.phone && ๐Ÿ“ž {contact.phone}} {contact.email && โœ‰๏ธ {contact.email}} {sanitizeUrl(contact.website) && ๐Ÿ”— {t('labUi.become.website')}} {contact.instagram && ๐Ÿ“ท {contact.instagram}} {sanitizeUrl(contact.portfolio) && ๐ŸŽจ {t('labUi.preview.portfolio')}}
)}

{t('labUi.preview.note')}

); }