mergepaths

This commit is contained in:
Casey Wittrock 2025-10-28 00:24:14 -05:00
parent 2828c0f9c8
commit 0ce7addff7
2 changed files with 98 additions and 70 deletions

View File

@ -7,11 +7,7 @@
<!-- Routes Data Table --> <!-- Routes Data Table -->
<div class="routes-table-container"> <div class="routes-table-container">
<DataTable <DataTable :data="tableData" :columns="columns" @row-click="viewRouteDetails" />
:data="tableData"
:columns="columns"
@row-click="viewRouteDetails"
/>
</div> </div>
<!-- Route Details Modal --> <!-- Route Details Modal -->
@ -20,18 +16,17 @@
<v-card-title class="d-flex justify-space-between align-center pa-4"> <v-card-title class="d-flex justify-space-between align-center pa-4">
<div> <div>
<h3>{{ selectedRoute.routeName }}</h3> <h3>{{ selectedRoute.routeName }}</h3>
<span class="text-subtitle-1 text-medium-emphasis">{{ selectedRoute.routeId }} - {{ selectedRoute.date }}</span> <span class="text-subtitle-1 text-medium-emphasis"
>{{ selectedRoute.routeId }} - {{ selectedRoute.date }}</span
>
</div> </div>
<div class="d-flex align-center gap-2"> <div class="d-flex align-center gap-2">
<v-chip <v-chip :color="getStatusColor(selectedRoute.status)" size="small">
:color="getStatusColor(selectedRoute.status)"
size="small"
>
{{ selectedRoute.status.toUpperCase() }} {{ selectedRoute.status.toUpperCase() }}
</v-chip> </v-chip>
<v-btn <v-btn
icon="mdi-close" icon="mdi-close"
variant="text" variant="text"
@click="routeDialog = false" @click="routeDialog = false"
></v-btn> ></v-btn>
</div> </div>
@ -45,42 +40,56 @@
<div class="route-info-panel"> <div class="route-info-panel">
<div class="route-summary pa-4"> <div class="route-summary pa-4">
<h4 class="mb-3">Route Summary</h4> <h4 class="mb-3">Route Summary</h4>
<div class="info-grid"> <div class="info-grid">
<div class="info-item"> <div class="info-item">
<v-icon class="mr-2" size="small">mdi-account-hard-hat</v-icon> <v-icon class="mr-2" size="small"
>mdi-account-hard-hat</v-icon
>
<span class="label">Technician:</span> <span class="label">Technician:</span>
<span class="value">{{ selectedRoute.technician }}</span> <span class="value">{{ selectedRoute.technician }}</span>
</div> </div>
<div class="info-item"> <div class="info-item">
<v-icon class="mr-2" size="small">mdi-clock-start</v-icon> <v-icon class="mr-2" size="small">mdi-clock-start</v-icon>
<span class="label">Start Time:</span> <span class="label">Start Time:</span>
<span class="value">{{ selectedRoute.startTime }}</span> <span class="value">{{ selectedRoute.startTime }}</span>
</div> </div>
<div class="info-item"> <div class="info-item">
<v-icon class="mr-2" size="small">mdi-car</v-icon> <v-icon class="mr-2" size="small">mdi-car</v-icon>
<span class="label">Vehicle:</span> <span class="label">Vehicle:</span>
<span class="value">{{ selectedRoute.vehicleId }}</span> <span class="value">{{ selectedRoute.vehicleId }}</span>
</div> </div>
<div class="info-item"> <div class="info-item">
<v-icon class="mr-2" size="small">mdi-map-marker-distance</v-icon> <v-icon class="mr-2" size="small"
>mdi-map-marker-distance</v-icon
>
<span class="label">Total Miles:</span> <span class="label">Total Miles:</span>
<span class="value">{{ selectedRoute.totalMileage }} mi</span> <span class="value"
>{{ selectedRoute.totalMileage }} mi</span
>
</div> </div>
<div class="info-item"> <div class="info-item">
<v-icon class="mr-2" size="small">mdi-timer</v-icon> <v-icon class="mr-2" size="small">mdi-timer</v-icon>
<span class="label">Est. Duration:</span> <span class="label">Est. Duration:</span>
<span class="value">{{ selectedRoute.estimatedDuration }}</span> <span class="value">{{
selectedRoute.estimatedDuration
}}</span>
</div> </div>
<div class="info-item"> <div class="info-item">
<v-icon class="mr-2" size="small">mdi-map-marker-multiple</v-icon> <v-icon class="mr-2" size="small"
>mdi-map-marker-multiple</v-icon
>
<span class="label">Stops:</span> <span class="label">Stops:</span>
<span class="value">{{ selectedRoute.completedStops }}/{{ selectedRoute.totalStops }}</span> <span class="value"
>{{ selectedRoute.completedStops }}/{{
selectedRoute.totalStops
}}</span
>
</div> </div>
</div> </div>
</div> </div>
@ -88,41 +97,52 @@
<!-- Stops List --> <!-- Stops List -->
<div class="stops-section pa-4"> <div class="stops-section pa-4">
<h4 class="mb-3">Route Stops</h4> <h4 class="mb-3">Route Stops</h4>
<div class="stops-list"> <div class="stops-list">
<div <div
v-for="stop in selectedRoute.stops" v-for="stop in selectedRoute.stops"
:key="stop.stopId" :key="stop.stopId"
class="stop-item" class="stop-item"
:class="getStopStatusClass(stop.status)" :class="getStopStatusClass(stop.status)"
> >
<div class="stop-number">{{ stop.stopId }}</div> <div class="stop-number">{{ stop.stopId }}</div>
<div class="stop-content"> <div class="stop-content">
<div class="stop-header"> <div class="stop-header">
<span class="customer-name">{{ stop.customer }}</span> <span class="customer-name">{{
<v-chip stop.customer
:color="getStopStatusColor(stop.status)" }}</span>
<v-chip
:color="getStopStatusColor(stop.status)"
size="x-small" size="x-small"
> >
{{ stop.status }} {{ stop.status }}
</v-chip> </v-chip>
</div> </div>
<div class="stop-details"> <div class="stop-details">
<div class="stop-address"> <div class="stop-address">
<v-icon size="x-small" class="mr-1">mdi-map-marker</v-icon> <v-icon size="x-small" class="mr-1"
>mdi-map-marker</v-icon
>
{{ stop.address }} {{ stop.address }}
</div> </div>
<div class="stop-service"> <div class="stop-service">
<v-icon size="x-small" class="mr-1">mdi-wrench</v-icon> <v-icon size="x-small" class="mr-1"
>mdi-wrench</v-icon
>
{{ stop.serviceType }} {{ stop.serviceType }}
</div> </div>
<div class="stop-time"> <div class="stop-time">
<v-icon size="x-small" class="mr-1">mdi-clock</v-icon> <v-icon size="x-small" class="mr-1"
{{ stop.estimatedTime }} ({{ stop.duration }} min) >mdi-clock</v-icon
>
{{ stop.estimatedTime }} ({{
stop.duration
}}
min)
</div> </div>
</div> </div>
</div> </div>
@ -138,8 +158,10 @@
<div class="map-content"> <div class="map-content">
<v-icon size="64" color="primary">mdi-map</v-icon> <v-icon size="64" color="primary">mdi-map</v-icon>
<h4 class="mt-3 mb-2">Route Map</h4> <h4 class="mt-3 mb-2">Route Map</h4>
<p class="text-body-2 text-center mb-4">Interactive map showing route path and stops</p> <p class="text-body-2 text-center mb-4">
Interactive map showing route path and stops
</p>
<!-- Mock Map Legend --> <!-- Mock Map Legend -->
<div class="map-legend"> <div class="map-legend">
<div class="legend-item"> <div class="legend-item">
@ -155,19 +177,31 @@
<span>Not Started</span> <span>Not Started</span>
</div> </div>
</div> </div>
<!-- Mock Route Stats --> <!-- Mock Route Stats -->
<div class="route-stats mt-4"> <div class="route-stats mt-4">
<div class="stat-item"> <div class="stat-item">
<div class="stat-value">{{ selectedRoute.totalMileage }}</div> <div class="stat-value">
{{ selectedRoute.totalMileage }}
</div>
<div class="stat-label">Total Miles</div> <div class="stat-label">Total Miles</div>
</div> </div>
<div class="stat-item"> <div class="stat-item">
<div class="stat-value">{{ selectedRoute.totalStops }}</div> <div class="stat-value">
{{ selectedRoute.totalStops }}
</div>
<div class="stat-label">Stops</div> <div class="stat-label">Stops</div>
</div> </div>
<div class="stat-item"> <div class="stat-item">
<div class="stat-value">{{ Math.round(selectedRoute.totalMileage / selectedRoute.totalStops * 10) / 10 }}</div> <div class="stat-value">
{{
Math.round(
(selectedRoute.totalMileage /
selectedRoute.totalStops) *
10,
) / 10
}}
</div>
<div class="stat-label">Avg Miles/Stop</div> <div class="stat-label">Avg Miles/Stop</div>
</div> </div>
</div> </div>
@ -182,19 +216,10 @@
<v-card-actions class="pa-4"> <v-card-actions class="pa-4">
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-btn <v-btn color="primary" variant="outlined" @click="routeDialog = false">
color="primary"
variant="outlined"
@click="routeDialog = false"
>
Close Close
</v-btn> </v-btn>
<v-btn <v-btn color="primary" @click="optimizeRoute"> Optimize Route </v-btn>
color="primary"
@click="optimizeRoute"
>
Optimize Route
</v-btn>
</v-card-actions> </v-card-actions>
</v-card> </v-card>
</v-dialog> </v-dialog>
@ -221,13 +246,13 @@ const columns = [
{ label: "Progress", fieldName: "progress", type: "text", sortable: true }, { label: "Progress", fieldName: "progress", type: "text", sortable: true },
{ label: "Total Stops", fieldName: "totalStops", type: "text", sortable: true }, { label: "Total Stops", fieldName: "totalStops", type: "text", sortable: true },
{ label: "Est. Duration", fieldName: "estimatedDuration", type: "text", sortable: true }, { label: "Est. Duration", fieldName: "estimatedDuration", type: "text", sortable: true },
{ label: "Actions", fieldName: "actions", type: "button", sortable: false } { label: "Actions", fieldName: "actions", type: "button", sortable: false },
]; ];
// Methods // Methods
const viewRouteDetails = (event) => { const viewRouteDetails = (event) => {
const routeId = event.data.routeId; const routeId = event.data.routeId;
const route = tableData.value.find(r => r.routeId === routeId); const route = tableData.value.find((r) => r.routeId === routeId);
if (route && route.fullData) { if (route && route.fullData) {
selectedRoute.value = route.fullData; selectedRoute.value = route.fullData;
routeDialog.value = true; routeDialog.value = true;
@ -261,7 +286,7 @@ const getStopStatusColor = (status) => {
}; };
const getStopStatusClass = (status) => { const getStopStatusClass = (status) => {
return `stop-status-${status.replace(' ', '-')}`; return `stop-status-${status.replace(" ", "-")}`;
}; };
const optimizeRoute = () => { const optimizeRoute = () => {
@ -272,9 +297,9 @@ const optimizeRoute = () => {
onMounted(async () => { onMounted(async () => {
try { try {
const data = await Api.getRouteData(); const data = await Api.getRouteData();
// Transform data for table display and keep full data reference // Transform data for table display and keep full data reference
tableData.value = data.map(route => ({ tableData.value = data.map((route) => ({
routeId: route.routeId, routeId: route.routeId,
routeName: route.routeName, routeName: route.routeName,
technician: route.technician, technician: route.technician,
@ -284,9 +309,9 @@ onMounted(async () => {
totalStops: route.totalStops, totalStops: route.totalStops,
estimatedDuration: route.estimatedDuration, estimatedDuration: route.estimatedDuration,
actions: "View Details", actions: "View Details",
fullData: route // Keep reference to full route data fullData: route, // Keep reference to full route data
})); }));
console.log("Loaded routes:", tableData.value); console.log("Loaded routes:", tableData.value);
} catch (error) { } catch (error) {
console.error("Error loading routes:", error); console.error("Error loading routes:", error);
@ -316,7 +341,7 @@ onMounted(async () => {
.routes-table-container { .routes-table-container {
background: white; background: white;
border-radius: 8px; border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
overflow: hidden; overflow: hidden;
} }
@ -379,7 +404,7 @@ onMounted(async () => {
} }
.stop-item:hover { .stop-item:hover {
box-shadow: 0 2px 8px rgba(0,0,0,0.1); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
} }
.stop-item.stop-status-completed { .stop-item.stop-status-completed {
@ -465,7 +490,7 @@ onMounted(async () => {
background: white; background: white;
padding: 32px; padding: 32px;
border-radius: 12px; border-radius: 12px;
box-shadow: 0 4px 16px rgba(0,0,0,0.1); box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
} }
.map-legend { .map-legend {
@ -529,17 +554,17 @@ onMounted(async () => {
flex-direction: column; flex-direction: column;
height: auto; height: auto;
} }
.route-info-panel { .route-info-panel {
border-right: none; border-right: none;
border-bottom: 1px solid #e0e0e0; border-bottom: 1px solid #e0e0e0;
} }
.map-panel { .map-panel {
width: 100%; width: 100%;
min-height: 300px; min-height: 300px;
} }
.info-grid { .info-grid {
grid-template-columns: 1fr; grid-template-columns: 1fr;
} }

View File

@ -1127,6 +1127,7 @@ class DataUtils {
}, },
], ],
}, },
<<<<<<< Updated upstream
]; ];
static dummyWarrantyData = [ static dummyWarrantyData = [
@ -1280,6 +1281,8 @@ class DataUtils {
warrantyType: "Parts Only", warrantyType: "Parts Only",
systemType: "Commercial Irrigation", systemType: "Commercial Irrigation",
}, },
=======
>>>>>>> Stashed changes
]; ];
} }