add: calendar view & calculator view
This commit is contained in:
67
src/components/CardBudget.vue
Normal file
67
src/components/CardBudget.vue
Normal file
@@ -0,0 +1,67 @@
|
||||
<script setup>
|
||||
defineProps({
|
||||
budget: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="card-fixed card-budget">
|
||||
<div>
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-md-6 col-sm-12">
|
||||
<p><span>Cliente:</span> {{budget.client}}</p>
|
||||
<p v-if="budget.material"><span>Material:</span> {{budget.material.name}}</p>
|
||||
<p><span>Origen:</span> {{budget.origin}}</p>
|
||||
<p><span>Destino:</span> {{budget.destination}}</p>
|
||||
<p><span>Tipo de camión:</span> {{budget.truck_type}}</p>
|
||||
<p><span>Total KM recorridos:</span> {{budget.total_km_travel}}</p>
|
||||
</div>
|
||||
<div class="col-lg-6 col-md-6 col-sm-12">
|
||||
<p><span>Total Litros De Diesel Consumidos: </span> {{parseFloat( budget.total_fuel_consumed).toFixed(2)}}</p>
|
||||
<p><span>Total Costo Del Diesel:</span> {{"$" + parseFloat( budget.total_cost_fuel).toFixed(2)}}</p>
|
||||
<p><span>Total Antes De Iva:</span> ${{budget.total_before_tax}}</p>
|
||||
<p><span>Total Utilidad Por Kilometro:</span> {{"$" + parseFloat( budget.total_utility_per_km).toFixed(2)}}</p>
|
||||
<p><span>Total Utilidad:</span> {{"$" + parseFloat( budget.total_profit).toFixed(2)}}</p>
|
||||
<!-- <p>{{ $t('CALCULATOR.PROFIT_PERCENTAGE') }}: {{budget.profit_percentage}}%</p> -->
|
||||
<p><span>Porcentaje De Utilidad:</span> {{parseFloat(budget.profit_percentage).toFixed(2) + "%"}}</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<button class="btn-primary-sm radius-sm">
|
||||
<i class="fa-solid fa-trash" /> <span class="clear-xsm">Eliminar</span>
|
||||
</button>
|
||||
<button class="btn-primary-sm radius-sm">
|
||||
<i class="fa-solid fa-pen-to-square" /> <span class="clear-xsm">Editar</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-dark">
|
||||
<i class="fa-solid fa-print" /> <span class="clear-xsm">Imprimir</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card-budget {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1rem;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
p span {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.card-footer {
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
gap: 1rem;
|
||||
}
|
||||
</style>
|
||||
@@ -1,11 +1,14 @@
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { ref, onMounted, reactive } from 'vue';
|
||||
import CardEmpty from './CardEmpty.vue';
|
||||
import Spiner from './ui/Spiner.vue';
|
||||
import BadgeError from './ui/BadgeError.vue';
|
||||
import { GoogleMap, Marker } from 'vue3-google-map';
|
||||
import useDirectionsRender from '../composables/useDirectionRender';
|
||||
import { useAuthStore } from '../stores/auth';
|
||||
import { useVehiclesStore } from '../stores/vehicles';
|
||||
import { saveProposal } from '../services/vehicles'
|
||||
import Swal from 'sweetalert2';
|
||||
|
||||
|
||||
const zoom = ref(6);
|
||||
@@ -13,11 +16,16 @@
|
||||
const originCoords = ref(null);
|
||||
const destinationCoords = ref(null);
|
||||
const isLoading = ref(false);
|
||||
const loadingSubmit = ref(false);
|
||||
const windowWidth = ref(window.innerWidth);
|
||||
const authStore = useAuthStore();
|
||||
const vehiclesStore = useVehiclesStore();
|
||||
const vehicle = ref(null);
|
||||
const comments = ref('');
|
||||
const msgError = ref('');
|
||||
|
||||
const form = reactive({
|
||||
vehicle: "",
|
||||
comments: '',
|
||||
});
|
||||
|
||||
const { geocodeAddress } = useDirectionsRender()
|
||||
|
||||
@@ -58,6 +66,48 @@
|
||||
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 formData = {
|
||||
carrier: authStore.user.company,
|
||||
bidder : authStore.user._id,
|
||||
comment: form.comments,
|
||||
vehicle : form.vehicle,
|
||||
load : props.load._id
|
||||
}
|
||||
|
||||
loadingSubmit.value = true;
|
||||
const result = await saveProposal(formData);
|
||||
if(result !== null) {
|
||||
document.getElementById('btnClosemakeProposalModal').click();
|
||||
Swal.fire({
|
||||
title: '<strong>Oferta creada con éxito!</strong>',
|
||||
icon: 'success'
|
||||
})
|
||||
} else {
|
||||
Swal.fire({
|
||||
title: '<strong>Oferta no se pudo crear!</strong>',
|
||||
icon: 'error'
|
||||
})
|
||||
}
|
||||
loadingSubmit.value = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -65,7 +115,7 @@
|
||||
<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">Ofertas</h2>
|
||||
<h2 class="title mt-2 mb-3">Realizar oferta</h2>
|
||||
<button
|
||||
id="btnClosemakeProposalModal"
|
||||
type="button"
|
||||
@@ -81,15 +131,15 @@
|
||||
<Spiner v-if="isLoading"/>
|
||||
<div v-else>
|
||||
<div v-if="load">
|
||||
<form class="box-form mb-4">
|
||||
<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"
|
||||
:value="vehicle"
|
||||
@input="$event => $emit('update:vehicle', $event.target.value)"
|
||||
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>
|
||||
@@ -102,12 +152,13 @@
|
||||
name="comment"
|
||||
id="comment"
|
||||
placeholder="Escribe aqui..."
|
||||
:value="comments"
|
||||
@input="$event => $emit('update:comments', $event.target.value)"
|
||||
v-model="form.comments"
|
||||
></textarea>
|
||||
</div>
|
||||
<div class="box-btns">
|
||||
<input
|
||||
<Spiner v-if="loadingSubmit"/>
|
||||
<input
|
||||
v-else
|
||||
type="submit"
|
||||
class="btn-primary-sm"
|
||||
value="Enviar"
|
||||
|
||||
@@ -44,7 +44,10 @@ import CardEmpty from './CardEmpty.vue';
|
||||
|
||||
if(load != null) {
|
||||
const index = loadsStore.loads.findIndex((load) => load._id === load_id);
|
||||
loadsStore.loads[index] = load;
|
||||
loadsStore.loads[index] = {
|
||||
...loadsStore.loads[index],
|
||||
...load
|
||||
};
|
||||
const proposal_id = proposal._id;
|
||||
|
||||
let formData = {
|
||||
@@ -106,7 +109,10 @@ import CardEmpty from './CardEmpty.vue';
|
||||
let load = await loadsStore.updateLoad(load_id, loadData);
|
||||
if(load) {
|
||||
const index = loadsStore.loads.findIndex((load) => load._id === load_id);
|
||||
loadsStore.loads[index] = load;
|
||||
loadsStore.loads[index] = {
|
||||
...loadsStore.loads[index],
|
||||
...load
|
||||
};
|
||||
let formData = {
|
||||
accepted_by : null,
|
||||
accepted_date : null,
|
||||
|
||||
56
src/components/ui/BadgeError.vue
Normal file
56
src/components/ui/BadgeError.vue
Normal file
@@ -0,0 +1,56 @@
|
||||
<script setup>
|
||||
defineProps({
|
||||
msg: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
isError: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
showIcon: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="msg.length > 0" class="badge" :class="[isError ? 'badge-error' : 'badge-success']">
|
||||
<span>
|
||||
<i v-if="showIcon && isError" class="fa-solid fa-circle-exclamation me-2"></i>
|
||||
<i v-if="showIcon && !isError" class="fa-solid fa-circle-check"></i>
|
||||
{{ msg }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.badge {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
color: #FFF;
|
||||
font-size: 1rem;
|
||||
font-weight: 700;
|
||||
border-radius: 8px;
|
||||
justify-content: center;
|
||||
padding: 10px 16px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.badge-error {
|
||||
background-color: rgb(238, 101, 101);
|
||||
}
|
||||
.badge-success {
|
||||
background-color: rgb(29, 162, 113);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.badge {
|
||||
font-size: 0.8rem;
|
||||
font-weight: 400;
|
||||
border-radius: 8px;
|
||||
padding: 10px 12px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user