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 { useQuery, useMutation, useQueryClient, queryOptions } from "@tanstack/react-query";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
import Contacts from './Contacts';
|
||||||
|
|
||||||
//Todo: Move types to own file
|
//Todo: Move types to own file
|
||||||
interface User {
|
interface User {
|
||||||
@ -60,8 +61,8 @@ interface Dispatch {
|
|||||||
createdAt: string;
|
createdAt: string;
|
||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
|
|
||||||
maker?: Maker;
|
maker: Maker;
|
||||||
retailer?: Retailer;
|
retailer: Retailer;
|
||||||
products: Product[];
|
products: Product[];
|
||||||
|
|
||||||
courier?: User;
|
courier?: User;
|
||||||
@ -173,19 +174,45 @@ const dashOpacities: Record<DispatchStatus, number> = {
|
|||||||
archived: 0.5
|
archived: 0.5
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface NodeSelection {
|
||||||
|
id: string,
|
||||||
|
type: "maker" | "retailer" | "dispatch" | "none"
|
||||||
|
}
|
||||||
|
|
||||||
export const KiosMap = () => {
|
export const KiosMap = () => {
|
||||||
|
|
||||||
const { data: makers, isLoading: isLoadingMakers } = useGetMakers();
|
const { data: makers, isLoading: isLoadingMakers } = useGetMakers();
|
||||||
const { data: retailers, isLoading: isLoadingRetailers } = useGetRetailers();
|
const { data: retailers, isLoading: isLoadingRetailers } = useGetRetailers();
|
||||||
const { data: dispatches, isLoading: isLoadingDispatches } = useGetDispatches();
|
const { data: dispatches, isLoading: isLoadingDispatches } = useGetDispatches();
|
||||||
|
|
||||||
const [selectedNodeId, setSelectedNodeId] = useState<string>('')
|
const [selectedNode, setSelectedNode] = useState<NodeSelection>({ id: "", type: "none" })
|
||||||
|
|
||||||
const handleSelectNode = (nodeId: string) => {
|
let selectedMaker: Maker | undefined = undefined;
|
||||||
setSelectedNodeId(nodeId)
|
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)
|
console.log("set id:", nodeId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleAcceptRoute = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
const blackDotIcon = L.divIcon({
|
const blackDotIcon = L.divIcon({
|
||||||
className: 'bg-gray-950 rounded-full',
|
className: 'bg-gray-950 rounded-full',
|
||||||
iconSize: [20, 20],
|
iconSize: [20, 20],
|
||||||
@ -207,9 +234,71 @@ export const KiosMap = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='w-full flex justify-center align-middle'>
|
<div className='w-full flex justify-center align-middle'>
|
||||||
<div className=''>
|
|
||||||
<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>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
<MapContainer
|
<MapContainer
|
||||||
id="map"
|
id="map"
|
||||||
center={[-6.1815, 106.8228]}
|
center={[-6.1815, 106.8228]}
|
||||||
@ -220,6 +309,9 @@ export const KiosMap = () => {
|
|||||||
>
|
>
|
||||||
<TileLayer url="https://tile.openstreetmap.org/{z}/{x}/{y}.png"
|
<TileLayer url="https://tile.openstreetmap.org/{z}/{x}/{y}.png"
|
||||||
maxZoom={19}
|
maxZoom={19}
|
||||||
|
eventHandlers={{
|
||||||
|
click: () => handleSelectNode("", "none")
|
||||||
|
}}
|
||||||
attribution='© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
|
attribution='© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@ -228,11 +320,11 @@ export const KiosMap = () => {
|
|||||||
{makers.map((maker: any, index: number) => (
|
{makers.map((maker: any, index: number) => (
|
||||||
<Marker
|
<Marker
|
||||||
eventHandlers={{
|
eventHandlers={{
|
||||||
click: () => handleSelectNode(maker.id)
|
click: () => handleSelectNode(maker.id, "maker")
|
||||||
}}
|
}}
|
||||||
key={maker.id}
|
key={maker.id}
|
||||||
position={[locationSwitcharoo(maker.location)[0], locationSwitcharoo(maker.location)[1]]}
|
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> */}
|
{/* <Popup>{maker.name}</Popup> */}
|
||||||
</Marker>
|
</Marker>
|
||||||
@ -245,11 +337,11 @@ export const KiosMap = () => {
|
|||||||
{retailers.map((retailer: any, index: number) => (
|
{retailers.map((retailer: any, index: number) => (
|
||||||
<Marker
|
<Marker
|
||||||
eventHandlers={{
|
eventHandlers={{
|
||||||
click: () => handleSelectNode(retailer.id)
|
click: () => handleSelectNode(retailer.id, "retailer")
|
||||||
}}
|
}}
|
||||||
key={retailer.id}
|
key={retailer.id}
|
||||||
position={[locationSwitcharoo(retailer.location)[0], locationSwitcharoo(retailer.location)[1]]}
|
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> */}
|
{/* <Popup>{retailer.name}</Popup> */}
|
||||||
</Marker>
|
</Marker>
|
||||||
@ -282,11 +374,11 @@ export const KiosMap = () => {
|
|||||||
return (
|
return (
|
||||||
<Polyline
|
<Polyline
|
||||||
eventHandlers={{
|
eventHandlers={{
|
||||||
click: () => handleSelectNode(dispatch.id)
|
click: () => handleSelectNode(dispatch.id, "dispatch")
|
||||||
}}
|
}}
|
||||||
key={dispatch.id}
|
key={dispatch.id}
|
||||||
positions={[[start[0], start[1]], [end[0], end[1]]]}
|
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}
|
opacity={dashOpacity}
|
||||||
dashArray={dashArray} />
|
dashArray={dashArray} />
|
||||||
);
|
);
|
||||||
|
@ -72,6 +72,8 @@ export interface Product {
|
|||||||
export interface Maker {
|
export interface Maker {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
|
phoneNumber?: string;
|
||||||
|
email?: string;
|
||||||
/**
|
/**
|
||||||
* @minItems 2
|
* @minItems 2
|
||||||
* @maxItems 2
|
* @maxItems 2
|
||||||
@ -84,6 +86,8 @@ export interface Maker {
|
|||||||
export interface Retailer {
|
export interface Retailer {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
|
phoneNumber?: string;
|
||||||
|
email?: string;
|
||||||
/**
|
/**
|
||||||
* @minItems 2
|
* @minItems 2
|
||||||
* @maxItems 2
|
* @maxItems 2
|
||||||
|
@ -14,6 +14,16 @@ const Makers: CollectionConfig = {
|
|||||||
type: 'text',
|
type: 'text',
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'phoneNumber',
|
||||||
|
type: 'text',
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'email',
|
||||||
|
type: 'email',
|
||||||
|
required: false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'location',
|
name: 'location',
|
||||||
type: 'point',
|
type: 'point',
|
||||||
|
@ -15,6 +15,16 @@ const Retailers: CollectionConfig = {
|
|||||||
type: 'text',
|
type: 'text',
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'phoneNumber',
|
||||||
|
type: 'text',
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'email',
|
||||||
|
type: 'email',
|
||||||
|
required: false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'location',
|
name: 'location',
|
||||||
type: 'point',
|
type: 'point',
|
||||||
|
Loading…
Reference in New Issue
Block a user