Use tRPC and react-hook-form

This commit is contained in:
Timothy Armes
2023-09-11 10:28:02 +02:00
parent 7111f000e5
commit ac633670ab
42 changed files with 5490 additions and 587 deletions
+42 -80
View File
@@ -1,111 +1,73 @@
"use client";
import { ChangeEvent, useMemo, useRef } from "react";
import { useMemo, useRef } from "react";
import { useSetAtom } from "jotai";
import L from "leaflet";
import L, { LatLngLiteral } from "leaflet";
import "leaflet-defaulticon-compatibility";
import "leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.css";
import "leaflet/dist/leaflet.css";
import { useTranslations } from "next-intl";
import { useFormContext, useWatch } from "react-hook-form";
import { MapContainer, Marker, TileLayer } from "react-leaflet";
import MapEvents from "@/app/[lang]/components/MapEvents";
import { mapBoundsAtom } from "@/app/atoms";
import { MapProps } from "@/types";
const Map = ({ position, setPosition, center }: MapProps) => {
const t = useTranslations("Map");
const center: LatLngLiteral = { lat: 47.0844, lng: 2.3964 };
const latValue = position.lat.toFixed(4);
const lngValue = position.lng.toFixed(4);
const Map = () => {
const { control, setValue } = useFormContext();
const latValue = useWatch({ control, name: "tournament.coordinates.0" });
const lngValue = useWatch({ control, name: "tournament.coordinates.1" });
const setMapBounds = useSetAtom(mapBoundsAtom);
const markerRef = useRef<L.Marker | null>(null);
const handleLatChange = ({ target }: ChangeEvent<HTMLInputElement>) => {
const newLat = Number(target.value);
setPosition((prevPosition) => ({ ...prevPosition, lat: newLat }));
};
const handleLngChange = ({ target }: ChangeEvent<HTMLInputElement>) => {
const newLng = Number(target.value);
setPosition((prevPosition) => ({ ...prevPosition, lng: newLng }));
};
const eventHandlers = useMemo(
() => ({
dragend() {
const marker = markerRef.current;
if (marker != null) {
setPosition(marker.getLatLng());
const position = marker.getLatLng();
setValue(
"tournament.coordinates.0",
Math.round((position.lat + Number.EPSILON) * 10000) / 10000,
);
setValue(
"tournament.coordinates.1",
Math.round((position.lng + Number.EPSILON) * 10000) / 10000,
);
}
},
}),
[setPosition],
[setValue],
);
return (
<>
<div className="col-span-2 sm:col-span-1">
<label
htmlFor="lat"
className="mb-2 block text-sm font-medium text-gray-900 dark:text-gray-300"
>
{t("latLabel")}
</label>
<input
value={latValue}
onChange={handleLatChange}
type="number"
id="lat"
className="dark:shadow-sm-light block w-full rounded-lg border border-gray-300 bg-gray-50 p-3 text-sm text-gray-900 shadow-sm focus:border-primary-500 focus:ring-primary-500 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-primary-500 dark:focus:ring-primary-500"
required
/>
</div>
<div className="col-span-2 sm:col-span-1">
<label
htmlFor="lng"
className="mb-2 block text-sm font-medium text-gray-900 dark:text-gray-300"
>
{t("lngLabel")}
</label>
<input
value={lngValue}
onChange={handleLngChange}
type="number"
id="lng"
className="dark:shadow-sm-light block w-full rounded-lg border border-gray-300 bg-gray-50 p-3 text-sm text-gray-900 shadow-sm focus:border-primary-500 focus:ring-primary-500 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-primary-500 dark:focus:ring-primary-500"
required
/>
</div>
<section id="map" className="z-0 col-span-4 flex h-auto">
<MapContainer
center={center}
zoom={5}
scrollWheelZoom={false}
style={{ height: "600px", flexGrow: 1 }}
ref={(map) => {
if (map) {
setMapBounds(map.getBounds());
}
}}
>
<MapEvents />
<TileLayer
attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<Marker
position={position}
draggable={true}
ref={markerRef}
eventHandlers={eventHandlers}
/>
</MapContainer>
</section>
</>
<MapContainer
center={center}
zoom={5}
scrollWheelZoom={false}
style={{ height: "600px", flexGrow: 1 }}
ref={(map) => {
if (map) {
setMapBounds(map.getBounds());
}
}}
>
<MapEvents />
<TileLayer
attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<Marker
position={{ lat: latValue, lng: lngValue }}
draggable={true}
ref={markerRef}
eventHandlers={eventHandlers}
/>
</MapContainer>
);
};