File size: 2,172 Bytes
766d85d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import { useState, useEffect } from 'react'
import { ExternalLink } from 'lucide-react'
import { collabApi } from '../../api/client'

// ── Website Thumbnail (fetches OG image) ────────────────────────────────────
const ogCache = {}

interface WebsiteThumbnailProps {
  url: string
  tripId: number
  color: string
}

export function WebsiteThumbnail({ url, tripId, color }: WebsiteThumbnailProps) {
  const [data, setData] = useState(ogCache[url] || null)
  const [failed, setFailed] = useState(false)

  useEffect(() => {
    if (ogCache[url]) { setData(ogCache[url]); return }
    collabApi.linkPreview(tripId, url).then(d => { ogCache[url] = d; setData(d) }).catch(() => setFailed(true))
  }, [url, tripId])

  const domain = (() => { try { return new URL(url).hostname.replace('www.', '') } catch { return 'link' } })()

  return (
    <a href={url} target="_blank" rel="noopener noreferrer" title={data?.title || url}
      style={{
        width: 48, height: 48, borderRadius: 8, cursor: 'pointer', overflow: 'hidden',
        background: data?.image ? 'none' : 'var(--bg-tertiary)', border: 'none',
        display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 2,
        textDecoration: 'none', transition: 'transform 0.12s, box-shadow 0.12s', flexShrink: 0,
      }}
      onMouseEnter={e => { e.currentTarget.style.transform = 'scale(1.08)'; e.currentTarget.style.boxShadow = '0 2px 8px rgba(0,0,0,0.15)' }}
      onMouseLeave={e => { e.currentTarget.style.transform = 'scale(1)'; e.currentTarget.style.boxShadow = 'none' }}>
      {data?.image && !failed ? (
        <img src={data.image} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover' }} onError={() => setFailed(true)} />
      ) : (
        <>
          <ExternalLink size={14} color="var(--text-muted)" />
          <span style={{ fontSize: 7, fontWeight: 600, color: 'var(--text-muted)', maxWidth: 42, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', textAlign: 'center' }}>
            {domain}
          </span>
        </>
      )}
    </a>
  )
}