File size: 2,189 Bytes
2cc62ca
 
 
 
 
 
ffc05fe
 
 
 
2cc62ca
 
 
 
 
ffc05fe
 
2cc62ca
 
 
 
 
 
 
ffc05fe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2cc62ca
ffc05fe
 
 
 
 
 
 
 
 
 
2cc62ca
ffc05fe
 
2cc62ca
 
ffc05fe
2cc62ca
ffc05fe
 
2cc62ca
ffc05fe
 
 
 
 
 
2cc62ca
ffc05fe
 
 
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/**
 * src/components/RangeMap.jsx
 * Renders a Leaflet map with a range circle centered on the species' known habitat.
 */

import React, { useEffect, useState } from 'react'
import { motion } from 'framer-motion'
import styles from './RangeMap.module.css'

export default function RangeMap({ range, commonName, color }) {
  const [ready,        setReady]        = useState(false)
  const [MapContainer, setMapContainer] = useState(null)
  const [TileLayer,    setTileLayer]    = useState(null)
  const [Circle,       setCircle]       = useState(null)
  const [Popup,        setPopup]        = useState(null)

  useEffect(() => {
    import('react-leaflet').then(rl => {
      setMapContainer(() => rl.MapContainer)
      setTileLayer(() => rl.TileLayer)
      setCircle(() => rl.Circle)
      setPopup(() => rl.Popup)
      setReady(true)
    })
  }, [])

  if (!range) return null

  return (
    <motion.div
      className={styles.wrapper}
      initial={{ opacity: 0, y: 12 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ duration: 0.5, delay: 0.2 }}
    >
      <p className={styles.label}>Range Map</p>
      <div className={styles.mapContainer}>
        {ready && MapContainer ? (
          <MapContainer
            center={range.center}
            zoom={3}
            scrollWheelZoom={false}
            style={{ height: '100%', width: '100%' }}
            zoomControl={false}
          >
            <TileLayer
              attribution=""
              url="https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}{r}.png"
            />
            <Circle
              center={range.center}
              radius={800000}
              pathOptions={{
                color:       color ?? '#9a749a',
                fillColor:   color ?? '#9a749a',
                fillOpacity: 0.18,
                weight:      1.5,
              }}
            >
              <Popup>{commonName} — approximate range</Popup>
            </Circle>
          </MapContainer>
        ) : (
          <div className={styles.mapPlaceholder}>Loading map…</div>
        )}
      </div>
      <p className={styles.rangeDesc}>{range.description}</p>
    </motion.div>
  )
}