feat: introduce employees and logistics management modules
- Added new modules for managing employees and logistics, including routes for creating, editing, and viewing employee details and logistics cycles. - Implemented UI components for employee forms and detail views, with validation schemas for employee data. - Integrated language support for English and Indonesian in the new modules. - Developed unit tests for employee remote data services and transformers to ensure functionality and reliability. This commit enhances the application by providing structured management for employees and logistics, improving user experience and data handling.
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
import { useEffect } from 'react';
|
||||
import { CircleMarker, MapContainer, Polyline, TileLayer, Tooltip, useMap } from 'react-leaflet';
|
||||
import { Box, Text } from '@mantine/core';
|
||||
import type { RouteGeometry } from './route-geometry';
|
||||
import { toLeafletLatLngs } from './route-geometry';
|
||||
import 'leaflet/dist/leaflet.css';
|
||||
|
||||
function FitRouteBounds({ positions }: { positions: Array<[number, number]> }) {
|
||||
const map = useMap();
|
||||
useEffect(() => {
|
||||
if (positions.length === 0) return;
|
||||
if (positions.length === 1) {
|
||||
map.setView(positions[0], 14);
|
||||
return;
|
||||
}
|
||||
map.fitBounds(positions, { padding: [24, 24] });
|
||||
}, [map, positions]);
|
||||
return null;
|
||||
}
|
||||
|
||||
export interface RouteMapProps {
|
||||
geometry?: RouteGeometry | null;
|
||||
height?: number;
|
||||
}
|
||||
|
||||
export function RouteMap({ geometry, height = 280 }: RouteMapProps) {
|
||||
const positions = toLeafletLatLngs(geometry);
|
||||
|
||||
if (positions.length === 0) {
|
||||
return (
|
||||
<Box h={height} bdrs="md" bd="1px solid var(--mantine-color-default-border)" p="md">
|
||||
<Text size="sm" c="dimmed">
|
||||
No route geometry
|
||||
</Text>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Box h={height} bdrs="md" style={{ overflow: 'hidden' }}>
|
||||
<MapContainer center={positions[0]} zoom={12} style={{ height: '100%', width: '100%' }} scrollWheelZoom>
|
||||
<TileLayer attribution="© OpenStreetMap contributors" url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
|
||||
<Polyline positions={positions} pathOptions={{ color: 'var(--mantine-color-blue-6)', weight: 4 }} />
|
||||
{positions.map((position, index) => (
|
||||
<CircleMarker key={`${position[0]}-${position[1]}-${index}`} center={position} radius={8} pathOptions={{ color: 'var(--mantine-color-blue-8)' }}>
|
||||
<Tooltip permanent>{index + 1}</Tooltip>
|
||||
</CircleMarker>
|
||||
))}
|
||||
<FitRouteBounds positions={positions} />
|
||||
</MapContainer>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user