import React, { useEffect, useState } from 'react'; import { MapContainer, TileLayer, Marker, CircleMarker, Popup, Polyline, LayerGroup, GeoJSON, } from 'react-leaflet'; import 'leaflet/dist/leaflet.css'; import L, { LatLngBounds } from 'leaflet'; import Contacts from './Contacts'; import type { User, Node, Retailer, Maker, Product, Dispatch, DispatchStatus } from '../astroTypes'; import { useQuery, useMutation, useQueryClient, queryOptions } from "@tanstack/react-query"; import { useGetMakers, useGetDispatches, useGetRetailers, useGetUser, useGetMyself } from "../utils/hooks" import { Button, buttonVariants } from './ui/Button'; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog" import { LoginForm } from './LoginForm'; import { hasAuthCookie } from '@/utils/authUtils'; //Payload longitude and latitude are mislabeled in payload (lol) const locationSwitcharoo = (location: number[]) => { if (location.length === 2) { const correctedLocation = [location[1], location[0]] return correctedLocation; } console.error("locationSwitcharoo: Location array malformed") return location } const dashArrays: Record = { requested: '20, 10', accepted: '0, 0', archived: '1, 5', } const dashColors: Record = { requested: '#000', accepted: '#000', archived: '#000', } const dashColorSelected: string = '#f87171' //same as tw red 400 const dashOpacities: Record = { requested: 0.7, accepted: 0.7, archived: 0.5 } interface NodeSelection { id: string, type: "maker" | "retailer" | "dispatch" | "none" } export const KiosMap = () => { const [authToken, setAuthToken] = useState('') const { data: makers, isLoading: isLoadingMakers } = useGetMakers(); const { data: retailers, isLoading: isLoadingRetailers } = useGetRetailers(); const { data: dispatches, isLoading: isLoadingDispatches } = useGetDispatches(); const { data: myself, isLoading: isLoadingMyself } = useGetMyself(authToken); const [selectedNode, setSelectedNode] = useState({ id: "", type: "none" }) let selectedMaker: Maker | undefined = undefined; let selectedRetailer: Retailer | undefined = undefined; let selectedDispatch: Dispatch | undefined = undefined; if (selectedNode.type === "maker" && makers) { selectedMaker = makers.find(maker => maker.id === selectedNode.id && selectedNode.type === "maker"); } if (selectedNode.type === "retailer" && retailers) { selectedRetailer = retailers.find(retailer => retailer.id === selectedNode.id && selectedNode.type === "retailer"); } if (selectedNode.type === "dispatch" && dispatches) { selectedDispatch = dispatches.find(dispatch => dispatch.id === selectedNode.id && selectedNode.type === "dispatch"); } const handleSelectNode = (nodeId: string, typeParam: "maker" | "retailer" | "dispatch" | "none") => { setSelectedNode({ id: nodeId, type: typeParam }) console.log("set id:", nodeId) } //params: dispatch: Dispatch, courier: User const handleAcceptRoute = () => { } const handleOpenCatalogue = () => { } //params const handleRequestProduct = () => { } const blackDotIcon = L.divIcon({ className: 'bg-gray-950 rounded-full', iconSize: [20, 20], iconAnchor: [10, 10] }); const selectedDotIcon = L.divIcon({ className: 'bg-red-400 rounded-full ring-offset-2 ring-4 ring-red-400 ring-dashed', iconSize: [20, 20], iconAnchor: [10, 10] }); const bounds = new LatLngBounds( [-90, -180], // Southwest corner [90, 180] // Northeast corner ); return (
{(myself && myself.name) ?

Logged in as: {myself.name}

:

Logged in

} { (!hasAuthCookie() && !authToken) && Login }
Login
{ selectedNode.type !== 'none' && (
{selectedMaker !== undefined && (
{(selectedMaker.stock !== undefined && selectedMaker.stock.length > 0) && See catalogue {selectedMaker.name}'s stock
    {selectedMaker.stock.map((product, i) => { return (
  • {product.picture.url && {product.picture.alt }

    {product.name}

    {product.weight &&

    Weight: {product.weight}

    }
  • ) })}
}
)} {selectedRetailer !== undefined && ( <> )} {selectedDispatch !== undefined && (

Product{selectedDispatch.products.length > 1 && 's'}

{selectedDispatch.products.map((product, i) => { return (
{product.picture.alt}

{product.name}

) })}
{selectedDispatch.courier !== undefined ? ( ) :

No courier!

}
)}
) } handleSelectNode("", "none") }} attribution='© OpenStreetMap' /> {(makers && !isLoadingMakers) && {makers.map((maker: any, index: number) => ( handleSelectNode(maker.id, "maker") }} key={maker.id} position={[locationSwitcharoo(maker.location)[0], locationSwitcharoo(maker.location)[1]]} icon={selectedNode.id === maker.id ? selectedDotIcon : blackDotIcon} > {/* {maker.name} */} ))} } {(retailers && !isLoadingRetailers) && {retailers.map((retailer: any, index: number) => ( handleSelectNode(retailer.id, "retailer") }} key={retailer.id} position={[locationSwitcharoo(retailer.location)[0], locationSwitcharoo(retailer.location)[1]]} icon={selectedNode.id === retailer.id ? selectedDotIcon : blackDotIcon} > {/* {retailer.name} */} ))} } {(dispatches && !isLoadingDispatches) && {dispatches.map((dispatch: any, index: number) => { if (dispatch.maker && dispatch.retailer) { const start = locationSwitcharoo(dispatch.maker.location); const end = locationSwitcharoo(dispatch.retailer.location); let productsString = ''; dispatch.products.forEach((product: any, i: number) => { productsString += product.productTitle + (i + 1 < dispatch.products.length ? ', ' : ''); }); //status type should already be inferred when list of dispatches is created, weird that is is required const status: DispatchStatus = dispatch.status; const dashArray: string = dashArrays[status] const dashColor: string = dashColors[status] const dashOpacity: number = dashOpacities[status] return ( handleSelectNode(dispatch.id, "dispatch") }} key={dispatch.id} positions={[[start[0], start[1]], [end[0], end[1]]]} pathOptions={{ color: selectedNode.id === dispatch.id ? dashColorSelected : dashColor }} opacity={dashOpacity} dashArray={dashArray} /> ); } })} }
); };