Basic node information mostly done
This commit is contained in:
parent
ed420d5ff1
commit
0645bbd877
25
astro/src/components/Contacts.tsx
Normal file
25
astro/src/components/Contacts.tsx
Normal file
@ -0,0 +1,25 @@
|
||||
import React from 'react'
|
||||
|
||||
type Props = {
|
||||
name: string | undefined;
|
||||
email?: string | undefined;
|
||||
phoneNumber?: string | undefined;
|
||||
role: 'maker' | 'retailer' | 'courier'
|
||||
}
|
||||
|
||||
const roleLabels = {
|
||||
maker: "Maker",
|
||||
retailer: "Retailer",
|
||||
courier: "Courier",
|
||||
}
|
||||
|
||||
export default function Contacts(props: Props) {
|
||||
return (
|
||||
<div className='flex flex-col'>
|
||||
{props.name && <p className='text-sm font-light'>{roleLabels[props.role]}:</p>}
|
||||
{props.name && <h2 className='text-xl font-bold underline-offset-2 underline py-2'>{props.name}</h2>}
|
||||
{props.phoneNumber && <p>Phone Number: <span className='font-semibold'>{props.phoneNumber}</span></p>}
|
||||
{props.email && <p>Email: <span className='font-semibold'>{props.email}</span></p>}
|
||||
</div>
|
||||
)
|
||||
}
|
@ -5,6 +5,7 @@ import L, { LatLngBounds } from 'leaflet';
|
||||
|
||||
import { useQuery, useMutation, useQueryClient, queryOptions } from "@tanstack/react-query";
|
||||
import axios from "axios";
|
||||
import Contacts from './Contacts';
|
||||
|
||||
//Todo: Move types to own file
|
||||
interface User {
|
||||
@ -60,8 +61,8 @@ interface Dispatch {
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
|
||||
maker?: Maker;
|
||||
retailer?: Retailer;
|
||||
maker: Maker;
|
||||
retailer: Retailer;
|
||||
products: Product[];
|
||||
|
||||
courier?: User;
|
||||
@ -173,19 +174,45 @@ const dashOpacities: Record<DispatchStatus, number> = {
|
||||
archived: 0.5
|
||||
}
|
||||
|
||||
interface NodeSelection {
|
||||
id: string,
|
||||
type: "maker" | "retailer" | "dispatch" | "none"
|
||||
}
|
||||
|
||||
export const KiosMap = () => {
|
||||
|
||||
const { data: makers, isLoading: isLoadingMakers } = useGetMakers();
|
||||
const { data: retailers, isLoading: isLoadingRetailers } = useGetRetailers();
|
||||
const { data: dispatches, isLoading: isLoadingDispatches } = useGetDispatches();
|
||||
|
||||
const [selectedNodeId, setSelectedNodeId] = useState<string>('')
|
||||
const [selectedNode, setSelectedNode] = useState<NodeSelection>({ id: "", type: "none" })
|
||||
|
||||
const handleSelectNode = (nodeId: string) => {
|
||||
setSelectedNodeId(nodeId)
|
||||
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)
|
||||
}
|
||||
|
||||
const handleAcceptRoute = () => {
|
||||
|
||||
}
|
||||
|
||||
const blackDotIcon = L.divIcon({
|
||||
className: 'bg-gray-950 rounded-full',
|
||||
iconSize: [20, 20],
|
||||
@ -207,9 +234,71 @@ export const KiosMap = () => {
|
||||
|
||||
return (
|
||||
<div className='w-full flex justify-center align-middle'>
|
||||
<div className=''>
|
||||
<div></div>
|
||||
</div>
|
||||
|
||||
{
|
||||
selectedNode.type !== 'none' && (
|
||||
<div className='absolute bg-white border-gray-950 border-2 z-[999] left-10 top-1/4 p-4'>
|
||||
<div className='flex gap-8 flex-col'>
|
||||
{selectedMaker !== undefined && (
|
||||
<Contacts
|
||||
name={selectedMaker.name}
|
||||
email={selectedMaker.email}
|
||||
phoneNumber={selectedMaker.phoneNumber}
|
||||
role={'maker'}
|
||||
/>
|
||||
)}
|
||||
|
||||
{selectedRetailer !== undefined && (
|
||||
<Contacts
|
||||
name={selectedRetailer.name}
|
||||
email={selectedRetailer.email}
|
||||
phoneNumber={selectedRetailer.phoneNumber}
|
||||
role={'retailer'}
|
||||
/>
|
||||
)}
|
||||
|
||||
{selectedDispatch !== undefined && (
|
||||
<div className='flex flex-col gap-4'>
|
||||
<Contacts
|
||||
name={selectedDispatch.maker.name}
|
||||
email={selectedDispatch.maker.email}
|
||||
phoneNumber={selectedDispatch.maker.phoneNumber}
|
||||
role={'maker'}
|
||||
/>
|
||||
|
||||
<Contacts
|
||||
name={selectedDispatch.retailer.name}
|
||||
email={selectedDispatch.retailer.email}
|
||||
phoneNumber={selectedDispatch.retailer.phoneNumber}
|
||||
role={'retailer'}
|
||||
/>
|
||||
|
||||
{selectedDispatch.courier !== undefined ? (
|
||||
|
||||
<Contacts
|
||||
name={selectedDispatch.courier.name}
|
||||
email={selectedDispatch.courier.email}
|
||||
phoneNumber={selectedDispatch.courier.phoneNumber}
|
||||
role={'courier'}
|
||||
/>
|
||||
) :
|
||||
<div>
|
||||
<h2 className='text-xl font-bold underline-offset-2 underline py-2'>No courier!</h2>
|
||||
<button
|
||||
className="border-2 border-gray-950 py-2 px-4 w-full hover:bg-gray-950 transition-all hover:text-white hover:font-bold"
|
||||
onClick={() => handleAcceptRoute()}
|
||||
>
|
||||
Accept route as courier
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
<MapContainer
|
||||
id="map"
|
||||
center={[-6.1815, 106.8228]}
|
||||
@ -220,6 +309,9 @@ export const KiosMap = () => {
|
||||
>
|
||||
<TileLayer url="https://tile.openstreetmap.org/{z}/{x}/{y}.png"
|
||||
maxZoom={19}
|
||||
eventHandlers={{
|
||||
click: () => handleSelectNode("", "none")
|
||||
}}
|
||||
attribution='© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
|
||||
/>
|
||||
|
||||
@ -227,12 +319,12 @@ export const KiosMap = () => {
|
||||
<LayerGroup>
|
||||
{makers.map((maker: any, index: number) => (
|
||||
<Marker
|
||||
eventHandlers={{
|
||||
click: () => handleSelectNode(maker.id)
|
||||
}}
|
||||
key={maker.id}
|
||||
eventHandlers={{
|
||||
click: () => handleSelectNode(maker.id, "maker")
|
||||
}}
|
||||
key={maker.id}
|
||||
position={[locationSwitcharoo(maker.location)[0], locationSwitcharoo(maker.location)[1]]}
|
||||
icon={selectedNodeId === maker.id ? selectedDotIcon : blackDotIcon}
|
||||
icon={selectedNode.id === maker.id ? selectedDotIcon : blackDotIcon}
|
||||
>
|
||||
{/* <Popup>{maker.name}</Popup> */}
|
||||
</Marker>
|
||||
@ -245,11 +337,11 @@ export const KiosMap = () => {
|
||||
{retailers.map((retailer: any, index: number) => (
|
||||
<Marker
|
||||
eventHandlers={{
|
||||
click: () => handleSelectNode(retailer.id)
|
||||
click: () => handleSelectNode(retailer.id, "retailer")
|
||||
}}
|
||||
key={retailer.id}
|
||||
position={[locationSwitcharoo(retailer.location)[0], locationSwitcharoo(retailer.location)[1]]}
|
||||
icon={selectedNodeId === retailer.id ? selectedDotIcon : blackDotIcon}
|
||||
icon={selectedNode.id === retailer.id ? selectedDotIcon : blackDotIcon}
|
||||
>
|
||||
{/* <Popup>{retailer.name}</Popup> */}
|
||||
</Marker>
|
||||
@ -282,11 +374,11 @@ export const KiosMap = () => {
|
||||
return (
|
||||
<Polyline
|
||||
eventHandlers={{
|
||||
click: () => handleSelectNode(dispatch.id)
|
||||
click: () => handleSelectNode(dispatch.id, "dispatch")
|
||||
}}
|
||||
key={dispatch.id}
|
||||
positions={[[start[0], start[1]], [end[0], end[1]]]}
|
||||
pathOptions={{color: selectedNodeId === dispatch.id ? dashColorSelected : dashColor}}
|
||||
pathOptions={{ color: selectedNode.id === dispatch.id ? dashColorSelected : dashColor }}
|
||||
opacity={dashOpacity}
|
||||
dashArray={dashArray} />
|
||||
);
|
||||
|
@ -72,6 +72,8 @@ export interface Product {
|
||||
export interface Maker {
|
||||
id: string;
|
||||
name: string;
|
||||
phoneNumber?: string;
|
||||
email?: string;
|
||||
/**
|
||||
* @minItems 2
|
||||
* @maxItems 2
|
||||
@ -84,6 +86,8 @@ export interface Maker {
|
||||
export interface Retailer {
|
||||
id: string;
|
||||
name: string;
|
||||
phoneNumber?: string;
|
||||
email?: string;
|
||||
/**
|
||||
* @minItems 2
|
||||
* @maxItems 2
|
||||
|
@ -14,6 +14,16 @@ const Makers: CollectionConfig = {
|
||||
type: 'text',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'phoneNumber',
|
||||
type: 'text',
|
||||
required: false
|
||||
},
|
||||
{
|
||||
name: 'email',
|
||||
type: 'email',
|
||||
required: false
|
||||
},
|
||||
{
|
||||
name: 'location',
|
||||
type: 'point',
|
||||
|
@ -15,6 +15,16 @@ const Retailers: CollectionConfig = {
|
||||
type: 'text',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'phoneNumber',
|
||||
type: 'text',
|
||||
required: false
|
||||
},
|
||||
{
|
||||
name: 'email',
|
||||
type: 'email',
|
||||
required: false
|
||||
},
|
||||
{
|
||||
name: 'location',
|
||||
type: 'point',
|
||||
|
Loading…
Reference in New Issue
Block a user