FollowPack.tsx raw
1 import { Button } from '@/components/ui/button'
2 import { getFollowPackInfoFromEvent } from '@/lib/event-metadata'
3 import { toFollowPack } from '@/lib/link'
4 import { useSecondaryPage } from '@/PageManager'
5 import { Event } from 'nostr-tools'
6 import { useMemo } from 'react'
7 import { useTranslation } from 'react-i18next'
8 import Image from '../Image'
9
10 export default function FollowPack({ event, className }: { event: Event; className?: string }) {
11 const { t } = useTranslation()
12 const { push } = useSecondaryPage()
13 const { title, description, image, pubkeys } = useMemo(
14 () => getFollowPackInfoFromEvent(event),
15 [event]
16 )
17
18 const handleViewDetails = (e: React.MouseEvent) => {
19 e.stopPropagation()
20 push(toFollowPack(event))
21 }
22
23 return (
24 <div className={className}>
25 <div className="flex items-start gap-2 mb-2">
26 {image && (
27 <Image
28 image={{ url: image, pubkey: event.pubkey }}
29 className="w-24 h-20 object-cover"
30 classNames={{
31 wrapper: 'w-24 h-20 flex-shrink-0',
32 errorPlaceholder: 'w-24 h-20'
33 }}
34 hideIfError
35 />
36 )}
37 <div className="flex-1 min-w-0">
38 <div className="flex items-center gap-2">
39 <h3 className="text-xl font-semibold mb-1 truncate">{title}</h3>
40 <span className="text-xs text-muted-foreground shrink-0">
41 {t('n users', { count: pubkeys.length })}
42 </span>
43 </div>
44 {description && (
45 <p className="text-sm text-muted-foreground line-clamp-2">{description}</p>
46 )}
47 </div>
48 </div>
49
50 <Button onClick={handleViewDetails} variant="outline" className="w-full">
51 {t('View Details')}
52 </Button>
53 </div>
54 )
55 }
56