277 lines
11 KiB
Vue
277 lines
11 KiB
Vue
<script setup>
|
|
import { ref, onMounted, reactive, computed } from 'vue';
|
|
import CardEmpty from './CardEmpty.vue';
|
|
import Spiner from './ui/Spiner.vue';
|
|
import BadgeError from './ui/BadgeError.vue';
|
|
import { GoogleMap, Marker, Polyline } from 'vue3-google-map';
|
|
import useDirectionsRender from '../composables/useDirectionRender';
|
|
import { useAuthStore } from '../stores/auth';
|
|
import { useCompanyStore } from '../stores/company';
|
|
import { useVehiclesStore } from '../stores/vehicles';
|
|
import { saveProposal } from '../services/vehicles'
|
|
import Swal from 'sweetalert2';
|
|
|
|
const mapKey = import.meta.env.VITE_MAP_KEY;
|
|
|
|
const zoom = ref(6);
|
|
const heightMap = ref(768);
|
|
const originCoords = ref(null);
|
|
const destinationCoords = ref(null);
|
|
const polylines = ref([]);
|
|
const isLoading = ref(false);
|
|
const loadingSubmit = ref(false);
|
|
const windowWidth = ref(window.innerWidth);
|
|
const authStore = useAuthStore();
|
|
const vehiclesStore = useVehiclesStore();
|
|
const msgError = ref('');
|
|
|
|
const form = reactive({
|
|
vehicle: "",
|
|
comments: '',
|
|
});
|
|
|
|
const { getDirections } = useDirectionsRender()
|
|
|
|
const props = defineProps({
|
|
load: {
|
|
type: Object,
|
|
required: true,
|
|
},
|
|
proposal: {
|
|
type: Object,
|
|
}
|
|
})
|
|
|
|
const companyStore = useCompanyStore();
|
|
|
|
|
|
defineEmits(['reset-load'])
|
|
|
|
onMounted(() => {
|
|
window.addEventListener('resize', handleResize);
|
|
if(window.innerWidth <= 1024) {
|
|
zoom.value = 4;
|
|
heightMap.value = 420;
|
|
}
|
|
initData();
|
|
});
|
|
|
|
const initData = async() => {
|
|
console.log('load: ', props.load);
|
|
isLoading.value = true;
|
|
let filterQuery = [];
|
|
filterQuery.company = "company="+ authStore.user.company
|
|
await vehiclesStore.fetchVehicles(filterQuery);
|
|
originCoords.value = {lat: Number.parseFloat(props.load.origin.lat), lng: Number.parseFloat(props.load.origin.lng)};
|
|
destinationCoords.value = {lat: Number.parseFloat(props.load.destination.lat), lng: Number.parseFloat(props.load.destination.lng)};;
|
|
polylines.value = await getDirections(originCoords.value, destinationCoords.value);
|
|
isLoading.value = false;
|
|
console.log(props.proposal);
|
|
if(props.proposal) {
|
|
form.vehicle = props.proposal.vehicle._id;
|
|
form.comments = props.proposal.comment;
|
|
}
|
|
}
|
|
|
|
const handleResize = () => {
|
|
windowWidth.value = window.innerWidth
|
|
if(windowWidth.value <= 1024){
|
|
zoom.value = 4
|
|
heightMap.value = 420;
|
|
} else {
|
|
zoom.value = 6;
|
|
heightMap.value = 768;
|
|
}
|
|
}
|
|
|
|
const handleSumit = async() => {
|
|
|
|
if(form.vehicle === ""){
|
|
msgError.value = 'Selecciona vehiculo para continuar';
|
|
setTimeout(() => {
|
|
msgError.value = '';
|
|
}, 5000);
|
|
return;
|
|
} else if (form.comments.trim().length <= 0) {
|
|
msgError.value = 'Agrega un comentario';
|
|
setTimeout(() => {
|
|
msgError.value = '';
|
|
}, 5000);
|
|
return;
|
|
}
|
|
|
|
msgError.value = '';
|
|
let result;
|
|
let action;
|
|
if(!props.proposal) {
|
|
let formData = {
|
|
carrier: authStore.user.company,
|
|
bidder : authStore.user._id,
|
|
comment: form.comments,
|
|
vehicle : form.vehicle,
|
|
load : props.load._id
|
|
}
|
|
loadingSubmit.value = true;
|
|
action = 'creada';
|
|
result = await companyStore.createPropsal(formData);
|
|
} else {
|
|
let formData = {
|
|
comment: form.comments,
|
|
vehicle : form.vehicle,
|
|
}
|
|
const index = vehiclesStore.vehicles.findIndex((prop) => prop._id === form.vehicle);
|
|
const vehicleSelected = vehiclesStore.vehicles[index];
|
|
console.log(vehicleSelected);
|
|
const localData = {
|
|
vehicle: vehicleSelected,
|
|
load: props.load,
|
|
_driver: vehicleSelected?.driver.first_name + ' ' + vehicleSelected?.driver.last_name
|
|
}
|
|
loadingSubmit.value = true;
|
|
action = 'actualizada'
|
|
result = await companyStore.updatePropsalLoad(props.proposal._id, formData, localData);
|
|
}
|
|
|
|
if(result === 'success') {
|
|
document.getElementById('btnClosemakeProposalModal').click();
|
|
Swal.fire({
|
|
title: `<strong>Oferta ${action} con éxito!</strong>`,
|
|
icon: 'success'
|
|
})
|
|
} else {
|
|
Swal.fire({
|
|
title: result,
|
|
icon: 'error'
|
|
})
|
|
}
|
|
loadingSubmit.value = false;
|
|
}
|
|
|
|
const title = computed(() => (props.proposal) ? 'Modificar oferta' : 'Realizar oferta');
|
|
const btnSubmit = computed(() => (props.proposal) ? 'Guardar' : 'Enviar');
|
|
</script>
|
|
|
|
<template>
|
|
<div class="modal fade" id="makeProposalModal" tabindex="-1" role="dialog" aria-labelledby="editcompany" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered modal-xl" role="document">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h2 class="title mt-2 mb-3">{{ title }}</h2>
|
|
<button
|
|
id="btnClosemakeProposalModal"
|
|
type="button"
|
|
class="close bg-white"
|
|
data-dismiss="modal"
|
|
aria-label="Close"
|
|
@click="$emit('reset-load')"
|
|
>
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
<div class="modal-body view-proposals">
|
|
<Spiner v-if="isLoading"/>
|
|
<div v-else>
|
|
<div v-if="load">
|
|
<form @submit.prevent="handleSumit" class="box-form mb-4">
|
|
<BadgeError :msg="msgError"/>
|
|
<div class="custom-selected-field">
|
|
<label class="custom-label" for="vehicle">Vehiculo:</label>
|
|
<select
|
|
class="custom-input-light"
|
|
name="vehicle"
|
|
id="vehicle"
|
|
v-model="form.vehicle"
|
|
>
|
|
<option disabled value="">-- Seleccionar vehículo --</option>
|
|
<option v-for="vehicle in vehiclesStore.vehicles" :value="vehicle._id">{{vehicle.vehicle_code}}</option>
|
|
</select>
|
|
</div>
|
|
<div class="custom-selected-field">
|
|
<label class="custom-label" for="comment">Comentario:</label>
|
|
<textarea
|
|
class="custom-input-light"
|
|
name="comment"
|
|
id="comment"
|
|
placeholder="Escribe aqui..."
|
|
v-model="form.comments"
|
|
></textarea>
|
|
</div>
|
|
<div class="box-btns">
|
|
<Spiner v-if="loadingSubmit"/>
|
|
<input
|
|
v-else
|
|
type="submit"
|
|
class="btn-primary-sm"
|
|
:value="btnSubmit"
|
|
/>
|
|
</div>
|
|
</form>
|
|
<GoogleMap
|
|
v-if="!proposal"
|
|
:api-key="mapKey"
|
|
:center="{lat:19.432600, lng:-99.133209}"
|
|
:zoom="zoom"
|
|
:min-zoom="2"
|
|
:max-zoom="12"
|
|
:style="{width: 100 + '%', height: heightMap + 'px'}"
|
|
:options="{
|
|
zoomControl: true,
|
|
mapTypeControl: true,
|
|
scaleControl: true,
|
|
streetViewControl: true,
|
|
rotateControl: true,
|
|
fullscreenControl: true
|
|
}"
|
|
>
|
|
<Marker v-if="originCoords" :options="{position: originCoords, label: 'O', title: 'Destino'}" />
|
|
<Marker v-if="destinationCoords" :options="{position: destinationCoords, label: 'D', title: 'Origen'}" />
|
|
<Polyline
|
|
v-if="polylines"
|
|
:options="{
|
|
path: polylines,
|
|
// geodesic: true,
|
|
strokeColor: '#2D90BB',
|
|
strokeOpacity: 0.7,
|
|
strokeWeight: 5,
|
|
clickable: true,
|
|
fillColor: '#75ad3e',
|
|
}"
|
|
/>
|
|
</GoogleMap>
|
|
</div>
|
|
<CardEmpty v-else text="No hay coincidencia"/>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button
|
|
type="button"
|
|
class="btn btn-dark"
|
|
data-dismiss="modal"
|
|
@click="$emit('reset-load')"
|
|
>Cerrar</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.box-form {
|
|
width: 90%;
|
|
align-items: center;
|
|
align-content: center;
|
|
justify-content: center;
|
|
margin: 0 auto;
|
|
}
|
|
.custom-selected-field {
|
|
display: flex;
|
|
flex-direction: column;
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.box-btns {
|
|
display: flex;
|
|
flex-direction: row;
|
|
justify-content: flex-end;
|
|
}
|
|
</style> |