Source: maps/MapMarkerWithGeolocationOqt.js

import React, { useMemo, useRef, useEffect, useState, useContext } from "react";
import { Marker, Popup, useMap } from 'react-leaflet';
import icon from "./Marker1.svg";
import L from 'leaflet';
import useGeolocation from "react-hook-geolocation";
import { InputOqt } from "../input";
import { MapGeolocationOqtContext } from "../..";

/**
 * Componente que renderiza una marca dentro de un mapa
 * @name Reactor.Components.Maps.MapMarkerWithGeolocationOqt
 * @param {string!} name Nombre del input
 * @param {string?} lat 
 *    Valor de latitud cuando no se obtienen los permisos para obtener la ubicación del dispositivo
 * @param {string?} lng 
 *    Valor de longitud cuando no se obtienen los permisos para obtener la ubicación del dispositivo
 * @param {string?} text 
 *    Un texto que aparece en un popup
 * @param {("true"|"false")} [readonly = "true"] 
 *    En el caso de no tener permisos para obtener la ubicación, 
 *    determina si el usuario puede mover la marca libremente
 * @param {("true"|"false")} [use_change = "true"] 
 *    Si es true, al modificarse su valor desencadena el evento change del form que lo contiene
 * @param {string?} icon 
 *    Source o path de un archivo svg para reemplazar el icono por defecto
 * @param {("true"|"false")} [debug = "false"] 
 *    Determina si se hará una salida de consola con datos de depuración
 * @class 
 * @returns {MapMarkerWithGeolocationOqtResult}
 * @example 
<map_geolocation debug="true">
  <map_marker_geolocation debug="true" lat="-35.10" lng="-63.89" name="mapa1" text="marca1" icon='<svg stroke-width="0" viewBox="0 0 24 24" height="60px" width="60px" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0V0z"></path><path d="M12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm8.94 3A8.994 8.994 0 0013 3.06V1h-2v2.06A8.994 8.994 0 003.06 11H1v2h2.06A8.994 8.994 0 0011 20.94V23h2v-2.06A8.994 8.994 0 0020.94 13H23v-2h-2.06zM12 19c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z"></path></svg>'>
  </map_marker_geolocation>
</map_geolocation>
<map_marker_geo name="seguimiento" lat="38.2111" lng="54.0121" text="aca estas vos" readonly="true" use_change="true"></map_marker_geo>
 */

const getIcon = (icon) => {
  return icon 
  ? new L.divIcon({
    html: icon,
    iconAnchor: null,
    popupAnchor: null,
    shadowUrl: null,
    shadowSize: null,
    shadowAnchor: null,
    iconSize: new L.Point(60, 75),
    className: 'leaflet-div-icon'
  })
  : markerIcon;
}

const geoOptions = {
  enableHighAccuracy: true
}

export const MapMarkerWithGeolocationOqt = ({ name, lat, lng, text, readonly = "true", use_change = "true", icon, debug = "false" }) => {

  const [ state, setState ] = useState({ lat, lng });
  const {latitude, longitude, speed, error} = useContext(MapGeolocationOqtContext);
  const customIcon = useMemo(()=>getIcon(icon), [icon]);

  const handleChangeLocation = (latLng) => {
    setState(state => ({...state, ...latLng }))
  }  

  useEffect(()=>{
    handleChangeLocation({lat: latitude || 0, lng: longitude || 0})
    debug === "true" && console.log({event: "change location", latitude, longitude, speed, error});
  }, [latitude, longitude]);

  return (
    <>
      <InputOqt type="hidden" value={state.lat} name={`${name}.lat`} use_change={use_change}/>
      <input type="hidden" value={state.lng} name={`${name}.lng`} use_change={use_change}/>
      <input type="hidden" value={speed} name={`${name}.speed`} use_change={use_change}/>
      <input type="hidden" value={error?.code} name={`${name}.error.code`} use_change={use_change}/>
      <input type="hidden" value={error?.message} name={`${name}.error.message`} use_change={use_change}/>
      {customIcon && 
        <Marker 
          draggable={false} 
          position={[state.lat, state.lng]} 
          icon={customIcon} >
        </Marker> 
      }
    </>
  )

}

const markerIcon = new L.Icon({
  iconUrl: icon,
  iconRetinaUrl: icon,
  iconAnchor: null,
  popupAnchor: null,
  shadowUrl: null,
  shadowSize: null,
  shadowAnchor: null,
  iconSize: new L.Point(60, 75),
  className: 'leaflet-div-icon'
});

/**
 * @typedef {Object} MapMarkerWithGeolocationOqtResult
 * @property {number} lat Latitud
 * @property {number} lng Longitud
 */