types#Route TypeScript Examples

The following examples show how to use types#Route. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: mapbox.tsx    From routes with MIT License 4 votes vote down vote up
MapBox = ({ routes, initialLng = lng, initialLat = lat }: MapBoxProps): JSX.Element => {
  const [stateMap, setStateMap] = useState(null)
  const mapContainer = useRef()

  const router = useRouter()
  const queryRoute = router.query.slug

  useEffect(() => {
    const map = new mapboxgl.Map({
      container: mapContainer.current,
      style: 'mapbox://styles/mapbox/outdoors-v11',
      center: [initialLng, initialLat],
      zoom,
    })

    // Add zoom/rotate control to the map
    map.addControl(new mapboxgl.NavigationControl())

    // Add geolocate control to the map.
    map.addControl(
      new mapboxgl.GeolocateControl({
        positionOptions: {
          enableHighAccuracy: true,
        },
        trackUserLocation: true,
      }),
    )

    // Add fullscreen control to the map
    map.addControl(new mapboxgl.FullscreenControl())

    map.on('load', () => {
      routes.forEach((route: Route) => {
        const {
          slug,
          color,
          geoJson: { features },
        } = route
        const { coordinates: startCoordinates } = features[0].geometry
        const { coordinates: endCoordinates } = features[features.length - 1].geometry
        const isCollection = features.length > 1
        const bbox = extent(route.geoJson)

        const dash = isCollection && queryRoute ? { 'line-dasharray': ['get', 'dash'] } : {}

        map.addSource(slug, {
          type: 'geojson',
          data: route.geoJson,
        })
        // Our path/route
        map.addLayer({
          id: slug,
          type: 'line',
          source: slug,
          layout: {
            'line-join': 'round',
            'line-cap': 'round',
          },
          paint: {
            'line-color': color,
            'line-width': 4,
            ...dash,
          },
        })
        // Add a fill layer as source for hover, or we lose our click target when inside the path
        map.addLayer({
          id: `${slug}-fill`,
          type: 'fill',
          source: slug,
          paint: {
            'fill-color': 'transparent',
            'fill-outline-color': 'transparent',
          },
        })

        map.addLayer({
          id: `${slug}-start`,
          type: 'circle',
          source: {
            type: 'geojson',
            data: {
              type: 'Feature',
              properties: {
                description: 'Activity Start',
              },
              geometry: {
                type: 'Point',
                coordinates: startCoordinates[0],
              },
            },
          },
          paint: {
            'circle-color': '#87CF3E',
            'circle-radius': 5,
            'circle-opacity': 1,
          },
        })

        map.addLayer({
          id: `${slug}-end`,
          type: 'circle',
          source: {
            type: 'geojson',
            data: {
              type: 'Feature',
              properties: {
                description: 'Activitiy End',
              },
              geometry: {
                type: 'Point',
                coordinates: endCoordinates.pop(),
              },
            },
          },
          paint: {
            'circle-color': 'red',
            'circle-radius': 5,
            'circle-opacity': 1,
          },
        })

        map.on('click', `${slug}-fill`, () => {
          // Fit map to bounds/route
          map.fitBounds(bbox, {
            padding: 20,
          })

          router.push(`/${slug}`)
        })

        map.on('mouseenter', `${slug}-fill`, () => {
          // Change the cursor style as a UI indicator.
          map.getCanvas().style.cursor = 'pointer'
          // Increase width of route path
          map.setPaintProperty(slug, 'line-width', 6)
        })

        map.on('mouseleave', `${slug}-fill`, () => {
          map.getCanvas().style.cursor = ''
          map.setPaintProperty(slug, 'line-width', 4)
        })
      })

      setStateMap(map)
    })

    return () => map.remove()
  }, [])

  useEffect(() => {
    if (queryRoute && stateMap) {
      routes.forEach((route: Route) => {
        const {
          slug,
          geoJson: { features },
        } = route
        const isCollection = features.length > 1

        if (slug === queryRoute) {
          stateMap.setLayoutProperty(slug, 'visibility', 'visible')
          stateMap.setLayoutProperty(`${slug}-fill`, 'visibility', 'visible')
          stateMap.setLayoutProperty(`${slug}-end`, 'visibility', 'visible')
          stateMap.setLayoutProperty(`${slug}-start`, 'visibility', 'visible')
          if (isCollection) {
            stateMap.setPaintProperty(slug, 'line-dasharray', ['get', 'dash'])
          }

          const bbox = extent(route.geoJson)
          // Fit map to bounds/route
          stateMap.fitBounds(bbox, {
            padding: 20,
          })
        } else {
          stateMap.setLayoutProperty(slug, 'visibility', 'none')
          stateMap.setLayoutProperty(`${slug}-fill`, 'visibility', 'none')
          stateMap.setLayoutProperty(`${slug}-end`, 'visibility', 'none')
          stateMap.setLayoutProperty(`${slug}-start`, 'visibility', 'none')
          if (isCollection) {
            stateMap.setPaintProperty(slug, 'line-dasharray', null)
          }
        }
      })
    } else {
      routes.forEach((route: Route) => {
        const {
          slug,
          geoJson: { features },
        } = route
        const isCollection = features.length > 1
        if (stateMap) {
          stateMap.setLayoutProperty(slug, 'visibility', 'visible')
          stateMap.setLayoutProperty(`${slug}-fill`, 'visibility', 'visible')
          stateMap.setLayoutProperty(`${slug}-end`, 'visibility', 'none')
          stateMap.setLayoutProperty(`${slug}-start`, 'visibility', 'none')
          if (isCollection) {
            stateMap.setPaintProperty(slug, 'line-dasharray', null)
          }
          stateMap.flyTo({
            center: [lng, lat],
            essential: true,
            zoom,
          })
        }
      })
    }
  }, [queryRoute, stateMap])

  return <div className="absolute inset-0" ref={mapContainer} />
}
Example #2
Source File: [slug].tsx    From routes with MIT License 4 votes vote down vote up
RoutePage = ({ routes }: { routes: Route[] }): JSX.Element | null => {
  const router = useRouter()
  const route = routes.find(x => x.slug === router.query.slug)
  const isSmall = useIsSmall()
  if (!route) {
    return null
  }
  const { name } = route.geoJson.features[0].properties
  const seoTitle = `${name} | ${route.swimrun ? 'Swimrun route' : 'Trail running & hiking route'}`
  const link = route.geoJson.features[0].properties?.links?.[0]?.href
  const statBoxClassName = 'justify-center p-2 border border-gray-200 rounded'

  return (
    <motion.div className="min-h-screen bg-white" initial={{ x: 430 }} animate={{ x: 0 }} transition={{ ease: 'easeOut', duration: 0.2 }}>
      <NextSeo
        title={seoTitle}
        description={route.description}
        openGraph={{
          url: `https://routes.samuekraft.com/?route=${route.slug}`,
          title: seoTitle,
          description: route.description,
          images: [
            {
              url: `https://routes.samuelkraft.com/og/${route.slug}.png`,
              width: 1012,
              height: 516,
            },
          ],
        }}
      />
      {route && (
        <>
          <nav className="sticky top-0 z-10 flex items-center justify-between px-5 py-3 -mx-5 border-b border-gray-200 bg-blur">
            <Link href="/">
              <a>
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  fill="none"
                  viewBox="0 0 24 24"
                  stroke="currentColor"
                  className="w-[20px] mr-1 -mt-0.5 inline-block"
                >
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
                </svg>
                <span className="inline-block font-semibold">Routes</span>
              </a>
            </Link>
            <Button
              href={`/gpx/${route.slug}.gpx`}
              onClick={() => event({ category: 'gpx', action: 'download', label: route.slug as string })}
            >
              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" className="w-[16px] inline-block mr-1 -mt-px">
                <path
                  fillRule="evenodd"
                  d="M3 17a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm3.293-7.707a1 1 0 011.414 0L9 10.586V3a1 1 0 112 0v7.586l1.293-1.293a1 1 0 111.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z"
                  clipRule="evenodd"
                />
              </svg>
              Download gpx
            </Button>
          </nav>
          <header className="text-center py-14">
            <h1 className="px-5 py-3 mb-0 -mx-5 text-3xl font-bold text-center -top-5 text-forest-darkest">{name}</h1>
            {(route.location || route.swimrun) && (
              <div className="flex items-center justify-center">
                {route.location && (
                  <div className="flex items-center justify-center text-gray-400">
                    <svg
                      xmlns="http://www.w3.org/2000/svg"
                      fill="none"
                      viewBox="0 0 24 24"
                      stroke="currentColor"
                      className="w-[14px] mr-1.5 -mt-1"
                    >
                      <path
                        strokeLinecap="round"
                        strokeLinejoin="round"
                        strokeWidth={2}
                        d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z"
                      />
                      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
                    </svg>
                    <span className="text-xs font-semibold tracking-wide uppercase">{route.location}</span>
                  </div>
                )}
                {route.location && route.swimrun && <span className="block mx-3 text-gray-400" />}
                {route.swimrun && (
                  <div className="flex items-center justify-center text-gray-400">
                    <svg
                      className="inline-block w-[14px] h-auto mr-1.5 -mt-0.5"
                      width="94"
                      height="57"
                      viewBox="0 0 94 57"
                      fill="none"
                      xmlns="http://www.w3.org/2000/svg"
                    >
                      <path
                        d="M10.2189 20.7904C18.9549 13.2884 25.8559 7.35737 44.5779 17.9364C53.5719 23.0174 60.8269 24.9354 66.8669 24.9344C77.4419 24.9344 84.2929 19.0514 90.2189 13.9594C92.3319 12.1454 92.6039 8.92437 90.8259 6.76537C89.0479 4.60637 85.8939 4.32737 83.7809 6.14437C75.0459 13.6494 68.1459 19.5784 49.4179 8.99737C24.6789 -4.97763 13.0919 4.97737 3.78088 12.9744C1.66888 14.7894 1.39588 18.0104 3.17388 20.1694C4.95088 22.3274 8.10487 22.6064 10.2189 20.7904ZM83.7809 36.6784C75.0459 44.1814 68.1459 50.1114 49.4179 39.5314C24.6789 25.5554 13.0919 35.5104 3.78088 43.5084C1.66888 45.3244 1.39588 48.5454 3.17388 50.7014C4.95088 52.8604 8.10588 53.1394 10.2189 51.3234C18.9549 43.8204 25.8559 37.8904 44.5779 48.4684C53.5719 53.5494 60.8269 55.4684 66.8669 55.4684C77.4419 55.4684 84.2929 49.5844 90.2189 44.4934C92.3319 42.6774 92.6039 39.4564 90.8259 37.2994C89.0489 35.1384 85.8949 34.8614 83.7809 36.6784Z"
                        fill={colors.blue[500]}
                        stroke={colors.blue[500]}
                        strokeWidth="5"
                      />
                    </svg>
                    <span className="text-xs font-semibold tracking-wide text-blue-500 uppercase">Swimrun</span>
                  </div>
                )}
              </div>
            )}
          </header>
          {!isSmall && (
            <div className="block text-xl text-forest pb-[50%] relative -mx-5">
              <MapBox routes={[route]} />
            </div>
          )}
          <div className="p-2 mb-2 border border-gray-200 rounded">
            <Chart coordinates={route.gpxGeoJson.features[0].geometry.coordinates} />
          </div>
          <ul className="grid grid-cols-2 grid-rows-2 gap-2 mb-6">
            <Stat type="Distance" value={`${Math.round(route.distance * 10) / 10} km`} centered className={statBoxClassName} />
            <Stat type="Elevation" value={`${Math.round(route.elevation)} m`} centered className={statBoxClassName} />
            <Stat type="Stifa" value={Math.round(route.elevation / route.distance)} centered className={statBoxClassName} />
            {route.rating && (
              <Stat
                type="Rating"
                value={
                  <>
                    {route.rating}
                    <span className="text-xs text-gray-400">/5</span>
                  </>
                }
                centered
                className={statBoxClassName}
              />
            )}
          </ul>

          {route.description && <p className="mb-3 leading-relaxed whitespace-pre-wrap">{route.description}</p>}

          {link && (
            <p className="mb-5">
              See route on{' '}
              <a
                className="text-forest"
                href={route.geoJson.features[0].properties.links[0].href}
                target="_blank"
                rel="noopener noreferrer"
              >
                Strava
              </a>
              .
            </p>
          )}
        </>
      )}
    </motion.div>
  )
}