enhanced preorder map

This commit is contained in:
2025-09-18 13:23:22 +02:00
parent 59e8e4a7a6
commit 93e85d54b0
3 changed files with 149 additions and 43 deletions
@@ -94,9 +94,9 @@
}
.tooltip-content-wrapper.marker-label-saturated {
background-color: rgba(212, 237, 218, 0.9);
border-color: #81c784;
color: #155724;
background-color: #28a745; /* A solid, vibrant green */
border-color: #218838; /* A slightly darker border for definition */
color: white; /* White text for maximum contrast */
}
div.leaflet-marker-icon.custom-div-icon {
@@ -89,9 +89,12 @@ Vue.component('PreorderRimoTypeMap', {
},
watch: {
selectedCampaign(newCampaignId) {
const localStorageKey = 'rimoMapSelectedCampaign';
if (newCampaignId) {
localStorage.setItem(localStorageKey, newCampaignId);
this.fetchAllMapData();
} else {
localStorage.removeItem(localStorageKey);
this.mapMarkers = [];
this.fcpMarkers = [];
this.faults = {};
@@ -103,9 +106,20 @@ Vue.component('PreorderRimoTypeMap', {
this.allCampaigns = window.TT_CONFIG?.ALL_CAMPAIGNS || [];
const urlParams = new URLSearchParams(window.location.search);
const campaignIdParam = urlParams.get('preordercampaign_id');
const localStorageKey = 'rimoMapSelectedCampaign';
if (this.allCampaigns.length === 1) this.selectedCampaign = this.allCampaigns[0].id;
if (this.allCampaigns.length > 1 && campaignIdParam && this.allCampaigns.some(c => String(c.id) === campaignIdParam)) this.selectedCampaign = campaignIdParam;
if (campaignIdParam && this.allCampaigns.some(c => String(c.id) === campaignIdParam)) {
// URL parameter has priority and will be saved by the watcher
this.selectedCampaign = campaignIdParam;
} else {
const savedCampaignId = localStorage.getItem(localStorageKey);
if (savedCampaignId && this.allCampaigns.some(c => String(c.id) === savedCampaignId)) {
this.selectedCampaign = savedCampaignId;
} else if (this.allCampaigns.length === 1) {
// Fallback for first time or if saved campaign is invalid
this.selectedCampaign = this.allCampaigns[0].id;
}
}
},
mounted() {
if (window.TT_CONFIG?.ALL_USERS) {
@@ -402,20 +416,48 @@ Vue.component('PreorderRimoTypeMap', {
}
}
},
async saveFaults() {
if (!this.editingFault) return;
const { hausnummerId, data } = this.editingFault;
async saveFaults(hausnummerIdToUpdate) {
const hausnummerId = hausnummerIdToUpdate || this.editingFault?.hausnummerId;
if (!hausnummerId) {
if (this.editingFault) this.editingFault = null;
return;
}
this.$set(this.faults, hausnummerId, data);
if (this.editingFault && this.editingFault.hausnummerId === hausnummerId) {
this.$set(this.faults, hausnummerId, this.editingFault.data);
}
const response = await axios.post(`${window.TT_CONFIG.BASE_PATH}/Preorder/RimoTypeMapSaveFaults`, {
campaignId: this.selectedCampaign,
faults: this.faults
});
if (response.data.success) {
window.notify('success', 'Fehlerbericht gespeichert.');
this.$refs.ttMap?.map.closePopup();
this.mapMarkers = this.processData(this.rawRimoData);
const mapComponent = this.$refs.ttMap;
if (mapComponent && mapComponent.markerLayer) {
mapComponent.markerLayer.eachLayer(marker => {
if (marker.tt_hausnummerId == hausnummerId) {
const rimoItem = this.rawRimoData.find(item => item.hausnummer_id == hausnummerId);
if (rimoItem) {
const rimoType = this.getNormalizedRimoType(rimoItem.rimo_type);
const fault = this.faults[hausnummerId];
const hasFault = fault && !fault.done;
const markerIconDef = this.getMarkerIcon(rimoType);
const newIcon = L.divIcon({
className: `custom-div-icon marker-${rimoType} ${hasFault ? 'marker-has-fault' : ''}`,
html: `<div class="rimo-marker ${markerIconDef.class}"><i class="${markerIconDef.icon} rimo-icon"></i></div>`,
iconSize: [30, 30],
iconAnchor: [15, 30],
});
marker.setIcon(newIcon);
}
}
});
}
} else {
window.notify('error', 'Fehlerbericht konnte nicht gespeichert werden.');
}
@@ -431,7 +473,7 @@ Vue.component('PreorderRimoTypeMap', {
done_at: new Date().toISOString()
});
await this.saveFaults();
await this.saveFaults(hausnummerId);
},
zoomToFaultMarker(hausnummerId) {
const map = this.$refs.ttMap?.map;
@@ -494,7 +536,7 @@ Vue.component('PreorderRimoTypeMap', {
style="min-width: 300px;"
></tt-select>
</div>
<div class="map-filter-container" v-if="selectedCampaign">
<div class="map-filter-container" style="margin-top: 8px" v-if="selectedCampaign">
<h6 class="mr-2 font-weight-bold align-self-center">Filter:</h6>
<button v-for="filter in filterOptions"
:key="filter.value"