resolve merge conflics
This commit is contained in:
@@ -3,6 +3,11 @@ body {
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.flex-d-column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.w-lg-45{
|
||||
width: 45%;
|
||||
}
|
||||
@@ -47,6 +52,10 @@ body {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.pointer {
|
||||
cursor: pointer
|
||||
}
|
||||
|
||||
.btn-lg-block{
|
||||
width: 100%;
|
||||
}
|
||||
@@ -183,6 +192,16 @@ td {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.custom-input-fill {
|
||||
background-color: white;
|
||||
border-radius: 8px;
|
||||
border-width: 1px !important;
|
||||
border-color: rgb(226, 214, 214) !important;
|
||||
border-style: solid !important;
|
||||
padding: 12px 12px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.custom-input:enabled{
|
||||
border: none;
|
||||
}
|
||||
@@ -202,6 +221,16 @@ td {
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.required {
|
||||
/* color: #FBBA33; */
|
||||
color: black;
|
||||
}
|
||||
|
||||
.border-required {
|
||||
border-radius: 5px;
|
||||
border: 1px solid #FBBA33 !important;
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
th {
|
||||
font-size: 13px;
|
||||
|
||||
@@ -90,6 +90,11 @@
|
||||
loadsStore.openProposalsModal = true;
|
||||
}
|
||||
|
||||
const openCarrierInfoModal = () => {
|
||||
loadsStore.currentLoad = props.load
|
||||
loadsStore.openCarrierInfoModal = true;
|
||||
}
|
||||
|
||||
const handleTracking = () => {
|
||||
let code = props.load._id;
|
||||
window.open('/publico/tracking/' + code, '_blank');
|
||||
@@ -142,7 +147,18 @@
|
||||
{{ load.company?.company_name }}
|
||||
</p>
|
||||
<div v-if="!readOnly">
|
||||
<p><span>{{t('loads.postStatus')}}:</span> <span class="simple">{{ getStatusPublished(load) }}</span></p>
|
||||
<p>
|
||||
<span>{{t('loads.postStatus')}}: </span>
|
||||
<span class="simple"> {{ getStatusPublished(load) }}</span>
|
||||
<i
|
||||
v-if="load.status !== 'Draft' && load.status !== 'Published'"
|
||||
class="fa-solid fa-truck me-1 ms-1 pointer"
|
||||
data-toggle="modal"
|
||||
data-target="#carrierInfoModal"
|
||||
@click="openCarrierInfoModal()"
|
||||
style="color: green; font-size: 20px;"
|
||||
></i>
|
||||
</p>
|
||||
<p :style="{color: getStatusLoad(load).color}"><span>{{t('loads.loadStatus')}}:</span> <span class="simple">{{ getStatusLoad(load).status }}</span></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
109
src/components/CarrierInfoModal.vue
Normal file
109
src/components/CarrierInfoModal.vue
Normal file
@@ -0,0 +1,109 @@
|
||||
<script setup>
|
||||
import { getDateMonthDay } from '../helpers/date_formats';
|
||||
import { useLoadsStore } from '../stores/loads';
|
||||
import VehicleInfo from './VehicleInfo.vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
const props = defineProps({
|
||||
load: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
const { t } = useI18n();
|
||||
const loadsStore = useLoadsStore();
|
||||
|
||||
const clearModal = () => {
|
||||
loadsStore.currentLoad = null;
|
||||
loadsStore.openCarrierInfoModal = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="modal fade" id="carrierInfoModal" 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">Información del transportista</h2>
|
||||
<button
|
||||
id="btnCloseCarrierInfoModal"
|
||||
type="button"
|
||||
@click="clearModal()"
|
||||
class="close bg-white" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body view-proposals">
|
||||
<div>
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-md-12">
|
||||
<p>{{ t('global.company') }}: <span>{{ load?.carrier?.company_name }}</span></p>
|
||||
<p>{{ t('proposals.bidder') }}: <span>{{ load?.bidder?.first_name }} {{ load?.bidder?.last_name }}</span></p>
|
||||
<p>{{ t('proposals.numCarrier') }}: <span>{{load?.carrier?.company_code}}</span></p>
|
||||
</div>
|
||||
<div class="col-lg-6 col-md-12">
|
||||
<p>{{ t('labels.date') }}: <span>{{ getDateMonthDay(load?.carrier?.createdAt) }}</span></p>
|
||||
<p>RFC: <span v-if="load.vehicle">{{load?.carrier?.rfc}}</span></p>
|
||||
</div>
|
||||
</div>
|
||||
<VehicleInfo
|
||||
v-if="load.vehicle"
|
||||
:vehicle="load.vehicle"
|
||||
:driver="load.driver"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-dark"
|
||||
@click="clearModal()"
|
||||
data-dismiss="modal">{{ t('buttons.close') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.view-proposals {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.card-proposal {
|
||||
flex-direction: column;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1rem;
|
||||
font-weight: 400;
|
||||
color: #323032;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
p span {
|
||||
color: #323032;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.indicator-check {
|
||||
width: 120px;
|
||||
padding: 10px 12px;
|
||||
background: #FFF;
|
||||
border: 1px solid green;
|
||||
border-radius: 50px;
|
||||
color: green;
|
||||
}
|
||||
|
||||
.box-note {
|
||||
padding: 12px 16px;
|
||||
background-color: aqua;
|
||||
border-radius: 13px;
|
||||
}
|
||||
</style>
|
||||
@@ -182,21 +182,21 @@
|
||||
:error="errors.address"
|
||||
/>
|
||||
<div class="mb-4 mt-3">
|
||||
<label class="custom-label">{{ t('directory.state')}}*</label>
|
||||
<label class="custom-label required">{{ t('directory.state')}}*</label>
|
||||
<States
|
||||
v-model="locationForm.state"
|
||||
/>
|
||||
<span class="error-msg" v-if="errors.state">{{ errors.state }}</span>
|
||||
</div>
|
||||
<div class="mb-4 mt-3">
|
||||
<label class="custom-label">{{ t('directory.city')}}*</label>
|
||||
<label class="custom-label required">{{ t('directory.city')}}*</label>
|
||||
<Cities
|
||||
v-model="locationForm.city"
|
||||
/>
|
||||
<span class="error-msg" v-if="errors.city">{{ errors.city }}</span>
|
||||
</div>
|
||||
<div class="d-flex flex-column mb-4">
|
||||
<label class="custom-label" for="role">{{ t('directory.typeDirectory') + '*'}}</label>
|
||||
<label class="custom-label required" for="role">{{ t('directory.typeDirectory') + '*'}}</label>
|
||||
<select
|
||||
class="custom-input-light"
|
||||
name="type"
|
||||
|
||||
@@ -20,14 +20,16 @@
|
||||
});
|
||||
|
||||
const { t } = useI18n();
|
||||
onMounted(() => {
|
||||
const authStore = useAuthStore();
|
||||
const companyStore = useCompanyStore();
|
||||
|
||||
onMounted(async() => {
|
||||
if(props.user) {
|
||||
console.log(props.user)
|
||||
userForm.job_role = props.user.job_role;
|
||||
userForm.name = props.user.first_name;
|
||||
userForm.last_name = props.user.last_name;
|
||||
userForm.email = props.user.email;
|
||||
userForm.phone = props.user.phone;
|
||||
userForm.job_role = props.user.job_role;
|
||||
userForm.categories = props.user.categories;
|
||||
userForm.user_city = props.user.user_city?.map(m =>{
|
||||
return { city_name: m };
|
||||
@@ -39,14 +41,15 @@
|
||||
return { meta_value:m };
|
||||
});
|
||||
userForm.user_description = props.user.user_description;
|
||||
if(props.user.job_role === 'warehouse') {
|
||||
await loadWarehouses();
|
||||
userForm.warehouse = warehouses.value.find(w => w._id === props.user.branch?._id);
|
||||
}
|
||||
} else {
|
||||
Object.assign(userForm, initState);
|
||||
}
|
||||
})
|
||||
|
||||
const authStore = useAuthStore();
|
||||
const companyStore = useCompanyStore();
|
||||
|
||||
const initState = {
|
||||
name: '',
|
||||
last_name: '',
|
||||
@@ -59,6 +62,7 @@
|
||||
user_state: [],
|
||||
truck_type: [],
|
||||
user_description: '',
|
||||
warehouse: null
|
||||
};
|
||||
|
||||
const userForm = reactive({
|
||||
@@ -70,10 +74,14 @@
|
||||
last_name: null,
|
||||
email: null,
|
||||
phone: null,
|
||||
job_role: null,
|
||||
warehouse: null
|
||||
})
|
||||
|
||||
const formRef = ref(null);
|
||||
const loading = ref(false);
|
||||
const loadingWarehouses = ref(false);
|
||||
const warehouses = ref([]);
|
||||
|
||||
const title = computed(() => {
|
||||
return (props.user) ? t('labels.editUser') : t('labels.createUser');
|
||||
@@ -83,7 +91,7 @@
|
||||
|
||||
const saveUser = async() => {
|
||||
validations()
|
||||
if(errors.value.name || errors.value.last_name || errors.value.email || errors.value.phone){
|
||||
if(errors.value.name || errors.value.last_name || errors.value.email || errors.value.phone || errors.value.job_role || errors.value.warehouse) {
|
||||
return;
|
||||
} else {
|
||||
let userData ={
|
||||
@@ -98,13 +106,14 @@
|
||||
user_city: userForm.user_city?.length <= 0 ? null : userForm.user_city?.map((e) => e.city_name),
|
||||
user_state: userForm.user_state?.length <= 0 ? null : userForm.user_state?.map((e) => e.state_name),
|
||||
truck_type: userForm.truck_type?.length <= 0 ? null : userForm.truck_type?.map((e) => e.meta_value),
|
||||
user_description: userForm.user_description
|
||||
user_description: userForm.user_description,
|
||||
branch: userForm.warehouse?._id
|
||||
}
|
||||
|
||||
|
||||
const dataUpdate = {
|
||||
categories: userForm.categories,
|
||||
name: userForm.name + ' ' + userForm.last_name
|
||||
name: userForm.name + ' ' + userForm.last_name,
|
||||
branch: userForm.warehouse
|
||||
}
|
||||
|
||||
let result = 'error';
|
||||
@@ -141,8 +150,26 @@
|
||||
last_name: userForm.last_name.length <= 1 ? t('errors.lastname') : null,
|
||||
email: !validateEmail(userForm.email) ? t('errors.email') : null,
|
||||
phone: userForm.phone.length < 10 ? t('errors.phone') : null,
|
||||
job_role: userForm.job_role === '' ? t('errors.required') : null,
|
||||
warehouse: (userForm.job_role == 'warehouse' && userForm.warehouse === null)
|
||||
? t('errors.required')
|
||||
: null
|
||||
};
|
||||
}
|
||||
|
||||
const handleRoleChange = async () => {
|
||||
if (userForm.job_role === "warehouse") {
|
||||
await loadWarehouses();
|
||||
}
|
||||
}
|
||||
|
||||
const loadWarehouses = async () => {
|
||||
loadingWarehouses.value = true;
|
||||
warehouses.value = await companyStore.getLocationsLoads('loading');
|
||||
loadingWarehouses.value = false;
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -194,48 +221,81 @@
|
||||
:filled="false"
|
||||
:error="errors.email"
|
||||
/>
|
||||
<div class="d-flex flex-column">
|
||||
<label class="custom-label" for="role">{{ t('labels.userRole') }}</label>
|
||||
<div
|
||||
v-if="userForm.job_role !== 'owner'"
|
||||
class="d-flex flex-column"
|
||||
>
|
||||
<label class="custom-label required" for="role">{{ t('labels.userRole') }}*</label>
|
||||
<select
|
||||
class="custom-input-light"
|
||||
name="role"
|
||||
id="role"
|
||||
v-model="userForm.job_role"
|
||||
@change="handleRoleChange"
|
||||
>
|
||||
<option disabled value="">-- {{ t('labels.selectedRol') }} --</option>
|
||||
<!-- <option value="owner">Dueño</option> -->
|
||||
<option value="manager">{{ t('labels.manager') }}</option>
|
||||
<option value="staff">{{ t('labels.staff') }}</option>
|
||||
<option v-if="authStore.user?.permissions === 'role_carrier'" value="driver">{{ t('labels.driver') }}</option>
|
||||
<option
|
||||
v-if="authStore.user?.permissions === 'role_shipper'"
|
||||
value="warehouse"
|
||||
>
|
||||
{{ t('labels.warehouse') }}
|
||||
</option>
|
||||
<option
|
||||
v-if="authStore.user?.permissions === 'role_carrier'"
|
||||
value="driver"
|
||||
>
|
||||
{{ t('labels.driver') }}
|
||||
</option>
|
||||
</select>
|
||||
<span class="error-msg" v-if="errors.job_role">{{ errors.job_role }}</span>
|
||||
</div>
|
||||
<div class="mb-4 mt-3">
|
||||
<label class="custom-label">{{ t('global.segments') }}</label>
|
||||
<Segments
|
||||
v-model="userForm.categories"
|
||||
:multiple="true"
|
||||
/>
|
||||
<div v-if="userForm.job_role === 'warehouse'">
|
||||
<Spiner v-if="loadingWarehouses"/>
|
||||
<div class="d-flex flex-column my-4" v-if="!loadingWarehouses">
|
||||
<label class="custom-label required" for="locationLoad">{{ t('labels.warehouses') }}*</label>
|
||||
<select
|
||||
class="custom-input-light"
|
||||
name="locationLoad"
|
||||
id="locationLoad"
|
||||
v-model="userForm.warehouse"
|
||||
>
|
||||
<option disabled value="null">-- {{ t('labels.warehouseSelect') }} --</option>
|
||||
<option v-for="loc in warehouses" :value="loc">{{ loc.branch_name }}</option>
|
||||
</select>
|
||||
<span class="error-msg" v-if="errors.warehouse">{{ errors.warehouse }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-4 mt-3">
|
||||
<label class="custom-label">{{ t('directory.typeTruck') }}</label>
|
||||
<TruckTypes
|
||||
v-model="userForm.truck_type"
|
||||
:multiple="true"
|
||||
/>
|
||||
</div>
|
||||
<div class="mb-4 mt-3">
|
||||
<label class="custom-label">{{ t('labels.locationLoadState') }}</label>
|
||||
<States
|
||||
v-model="userForm.user_state"
|
||||
:multiple="true"
|
||||
/>
|
||||
</div>
|
||||
<div class="mb-4 mt-3">
|
||||
<label class="custom-label">{{ t('labels.locationLoadCity') }}</label>
|
||||
<Cities
|
||||
v-model="userForm.user_city"
|
||||
:multiple="true"
|
||||
/>
|
||||
<div v-else>
|
||||
<div class="mb-4 mt-3">
|
||||
<label class="custom-label">{{ t('global.segments') }}</label>
|
||||
<Segments
|
||||
v-model="userForm.categories"
|
||||
:multiple="true"
|
||||
/>
|
||||
</div>
|
||||
<div class="mb-4 mt-3">
|
||||
<label class="custom-label">{{ t('directory.typeTruck') }}</label>
|
||||
<TruckTypes
|
||||
v-model="userForm.truck_type"
|
||||
:multiple="true"
|
||||
/>
|
||||
</div>
|
||||
<div class="mb-4 mt-3">
|
||||
<label class="custom-label">{{ t('labels.locationLoadState') }}</label>
|
||||
<States
|
||||
v-model="userForm.user_state"
|
||||
:multiple="true"
|
||||
/>
|
||||
</div>
|
||||
<div class="mb-4 mt-3">
|
||||
<label class="custom-label">{{ t('labels.locationLoadCity') }}</label>
|
||||
<Cities
|
||||
v-model="userForm.user_city"
|
||||
:multiple="true"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex flex-column">
|
||||
<label class="custom-label" for="description">{{ t('labels.userInfo') }}</label>
|
||||
|
||||
@@ -163,14 +163,14 @@
|
||||
<form @submit.prevent="handleSaveVehicle" autocomplete="off" class="vehicle-form">
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-12 mt-4">
|
||||
<label class="custom-label">{{ t('directory.typeTruck') }}*</label>
|
||||
<label class="custom-label required">{{ t('directory.typeTruck') }}*</label>
|
||||
<TruckTypes
|
||||
v-model="vehicleForm.truck_type"
|
||||
/>
|
||||
<span class="error-msg" v-if="errors.truck_type">{{ errors.truck_type }}</span>
|
||||
</div>
|
||||
<div class="col-lg-6 col-12 mt-4">
|
||||
<label class="custom-label">{{ t('vehicles.segments') }}*</label>
|
||||
<label class="custom-label required">{{ t('vehicles.segments') }}*</label>
|
||||
<Segments
|
||||
v-model="vehicleForm.categories"
|
||||
:multiple="true"
|
||||
@@ -217,14 +217,14 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-12 mb-4">
|
||||
<label class="custom-label">{{ t('labels.stateBase') }}*</label>
|
||||
<label class="custom-label required">{{ t('labels.stateBase') }}*</label>
|
||||
<States
|
||||
v-model="vehicleForm.state"
|
||||
/>
|
||||
<span class="error-msg" v-if="errors.state">{{ errors.state }}</span>
|
||||
</div>
|
||||
<div class="col-lg-6 col-12 mb-4">
|
||||
<label class="custom-label">{{ t('labels.cityBase') }}*</label>
|
||||
<label class="custom-label required">{{ t('labels.cityBase') }}*</label>
|
||||
<Cities
|
||||
v-model="vehicleForm.city"
|
||||
/>
|
||||
@@ -233,14 +233,14 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-12 mb-4">
|
||||
<label class="custom-label">{{t('vehicles.destinationState')}}*</label>
|
||||
<label class="custom-label required">{{t('vehicles.destinationState')}}*</label>
|
||||
<States
|
||||
v-model="vehicleForm.destinoState"
|
||||
/>
|
||||
<span class="error-msg" v-if="errors.destinoState">{{ errors.destinoState }}</span>
|
||||
</div>
|
||||
<div class="col-lg-6 col-12 mb-4">
|
||||
<label class="custom-label">{{t('vehicles.destinationCity')}}*</label>
|
||||
<label class="custom-label required">{{t('vehicles.destinationCity')}}*</label>
|
||||
<Cities
|
||||
v-model="vehicleForm.destinoCity"
|
||||
/>
|
||||
|
||||
@@ -75,16 +75,11 @@
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener('resize', handleResize);
|
||||
// mapRef.value = this.$refs.myMap;
|
||||
if(window.innerWidth <= 1024) {
|
||||
zoom.value = 4;
|
||||
heightMap.value = 420;
|
||||
}
|
||||
// if(companyStore.locationsLoads.length <= 0) {
|
||||
// getLocations();
|
||||
// }
|
||||
formLoad.owner = auth.user?.first_name + ' ' + auth.user?.last_name;
|
||||
//origin_formatted_address
|
||||
if(loadStore.currentLoad){
|
||||
const dateStart = getDateTime(loadStore.currentLoad.est_loading_date, 0);
|
||||
const dateEnd = getDateTime(loadStore.currentLoad.est_unloading_date, 0);
|
||||
@@ -100,10 +95,7 @@
|
||||
formLoad.weight = loadStore.currentLoad.weight;
|
||||
formLoad.dateLoad = dateStart.substring(0, 10);
|
||||
formLoad.dateDownload = dateEnd.substring(0, 10);
|
||||
// formLoad.dateLoad = loadStore.currentLoad.est_loading_date?.substring(0, 10);
|
||||
// formLoad.dateDownload = loadStore.currentLoad.est_unloading_date?.substring(0, 10);
|
||||
formLoad.truckType = loadStore.currentLoad.truck_type ? {meta_value: loadStore.currentLoad.truck_type} : null;
|
||||
|
||||
origin.locationName = loadStore.currentLoad.origin.company_name;
|
||||
origin.address = loadStore.currentLoad.origin.street_address1;
|
||||
origin.state = loadStore.currentLoad.origin?.state ? { state_name: loadStore.currentLoad.origin.state } : null;
|
||||
@@ -119,6 +111,7 @@
|
||||
destination.country = loadStore.currentLoad.destination.country;
|
||||
destination.postalCode = loadStore.currentLoad.destination.zipcode;
|
||||
destinationRef.value = loadStore.currentLoad.destination.landmark;
|
||||
locationLoadSelected.value = loadStore.currentLoad?.shipper_warehouse || null; /// Selected warehouse
|
||||
getCoordsMap();
|
||||
}
|
||||
|
||||
@@ -197,6 +190,7 @@
|
||||
});
|
||||
|
||||
const origin = reactive({
|
||||
id: null,
|
||||
locationName: '',
|
||||
address: '',
|
||||
state: '',
|
||||
@@ -254,10 +248,10 @@
|
||||
},
|
||||
company: auth.user.company,
|
||||
posted_by: auth.user._id,
|
||||
posted_by_name: formLoad.owner
|
||||
posted_by_name: formLoad.owner,
|
||||
shipper_warehouse: locationLoadSelected.value?._id || null,
|
||||
};
|
||||
|
||||
|
||||
return loadData;
|
||||
}
|
||||
|
||||
@@ -269,7 +263,8 @@
|
||||
const dataLocal = {
|
||||
company: auth.user.company,
|
||||
categories: formLoad.segment || null,
|
||||
product: formLoad.terms?.length <= 0 ? null : formLoad.terms
|
||||
product: formLoad.terms?.length <= 0 ? null : formLoad.terms,
|
||||
shipper_warehouse: locationLoadSelected.value,
|
||||
};
|
||||
if(resp) {
|
||||
const index = loadStore.loads.findIndex((load) => load._id === resp._id);
|
||||
@@ -289,7 +284,8 @@
|
||||
const load = {
|
||||
...resp,
|
||||
...loadData,
|
||||
categories: [loadData.categories]
|
||||
categories: [loadData.categories],
|
||||
shipper_warehouse: locationLoadSelected.value,
|
||||
}
|
||||
|
||||
loadStore.loads.unshift(load);
|
||||
@@ -389,14 +385,14 @@
|
||||
<div class="form-box">
|
||||
<div class="form-section">
|
||||
<div class="mb-4 mt-3">
|
||||
<label class="custom-label">{{ t('global.segment') }}*</label>
|
||||
<label class="custom-label required">{{ t('global.segment') }}*</label>
|
||||
<Segments
|
||||
v-model="formLoad.segment"
|
||||
/>
|
||||
<span class="error-msg" v-if="submited && errors.segment">{{ errors.segment }}</span>
|
||||
</div>
|
||||
<div class="mb-4 mt-3">
|
||||
<label class="custom-label">{{ t('directory.typeTruck') }}*</label>
|
||||
<label class="custom-label required">{{ t('directory.typeTruck') }}*</label>
|
||||
<TruckTypes
|
||||
v-model="formLoad.truckType"
|
||||
/>
|
||||
@@ -499,14 +495,14 @@
|
||||
v-model:field="origin.address"
|
||||
/>
|
||||
<div class="mb-4 mt-3">
|
||||
<label class="custom-label">{{ t('global.city') }}*</label>
|
||||
<label class="custom-label required">{{ t('global.city') }}*</label>
|
||||
<Cities
|
||||
v-model="origin.city"
|
||||
/>
|
||||
<span class="error-msg" v-if="submited && errors.cityOrigin">{{ errors.cityOrigin }}</span>
|
||||
</div>
|
||||
<div class="mb-4 mt-3">
|
||||
<label class="custom-label">{{ t('global.state') }}*</label>
|
||||
<label class="custom-label required">{{ t('global.state') }}*</label>
|
||||
<States
|
||||
v-model="origin.state"
|
||||
/>
|
||||
@@ -570,14 +566,14 @@
|
||||
v-model:field="destination.address"
|
||||
/>
|
||||
<div class="mb-4 mt-3">
|
||||
<label class="custom-label">{{t('global.city')}}*</label>
|
||||
<label class="custom-label required">{{t('global.city')}}*</label>
|
||||
<Cities
|
||||
v-model="destination.city"
|
||||
/>
|
||||
<span class="error-msg" v-if="submited && errors.cityDestination">{{ errors.cityDestination }}</span>
|
||||
</div>
|
||||
<div class="mb-4 mt-3">
|
||||
<label class="custom-label">{{t('global.state')}}*</label>
|
||||
<label class="custom-label required">{{t('global.state')}}*</label>
|
||||
<States
|
||||
v-model="destination.state"
|
||||
/>
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
noty.notifications = resp.data;
|
||||
}
|
||||
|
||||
const roleCheck = 'store';
|
||||
const roleCheck = 'warehouse';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
const getProposalsData = async() => {
|
||||
isLoading.value = true;
|
||||
await loadsStore.getProposalsOfLoads(loadsStore.currentLoad._id);
|
||||
console.log(loadsStore.proposalsOfLoads)
|
||||
isLoading.value = false;
|
||||
}
|
||||
|
||||
@@ -41,6 +42,8 @@
|
||||
vehicle: proposal.vehicle._id,
|
||||
}
|
||||
|
||||
console.log(proposal)
|
||||
|
||||
isLoadingActions.value = true;
|
||||
let load = await loadsStore.updateLoad(load_id, loadData);
|
||||
if(load != null) {
|
||||
@@ -53,7 +56,9 @@
|
||||
loadsStore.loads[index] = {
|
||||
...loadsStore.loads[index],
|
||||
...load,
|
||||
...dataLocal
|
||||
...dataLocal,
|
||||
carrier: proposal.carrier,
|
||||
vehicle: proposal.vehicle,
|
||||
};
|
||||
const proposal_id = proposal._id;
|
||||
|
||||
@@ -185,18 +190,21 @@
|
||||
<div class="col-lg-6 col-md-12">
|
||||
<p>{{ t('global.company') }}: <span>{{ proposal.carrier.company_name }}</span></p>
|
||||
<p>{{ t('proposals.bidder') }}: <span>{{ proposal.bidder.first_name }} {{ proposal.bidder.last_name }}</span></p>
|
||||
<p>{{ t('proposals.numCarrier') }}: <span v-if="proposal.vehicle">{{proposal.vehicle.vehicle_code}}</span></p>
|
||||
<p>{{ t('proposals.numCarrier') }}: <span>{{proposal.carrier.company_code}}</span></p>
|
||||
</div>
|
||||
<div class="col-lg-6 col-md-12">
|
||||
<p>{{ t('labels.date') }}: <span>{{ getDateMonthDay(proposal.createdAt) }}</span></p>
|
||||
<p>{{ t('directory.typeTruck') }}: <span v-if="proposal.vehicle">{{proposal.vehicle.truck_type}}</span></p>
|
||||
<p>{{ t('global.carrier') }}: <span v-if="proposal._driver">{{proposal._driver}}</span></p>
|
||||
<p>{{ t('labels.date') }}: <span>{{ getDateMonthDay(proposal.carrier.createdAt) }}</span></p>
|
||||
<p>RFC: <span>{{proposal.carrier.rfc}}</span></p>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="proposal.comment" class="box-note">
|
||||
{{ proposal.comment }}
|
||||
</div>
|
||||
<VehicleInfo v-if="proposal.vehicle" :vehicle="proposal.vehicle"/>
|
||||
<VehicleInfo
|
||||
v-if="proposal.vehicle"
|
||||
:vehicle="proposal.vehicle"
|
||||
:driver="proposal.driver"
|
||||
/>
|
||||
<Spiner v-if="isLoadingActions"/>
|
||||
<div class="d-flex justify-content-end gap-3" v-else>
|
||||
<div v-if="proposal.is_accepted" class="indicator-check">
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
});
|
||||
}
|
||||
|
||||
const roleCheck = 'store';
|
||||
const roleCheck = 'warehouse';
|
||||
|
||||
|
||||
</script>
|
||||
@@ -128,7 +128,9 @@
|
||||
class="nav-link" :to="{name: 'published-trucks'}">{{ t('global.acceptedOffers') }}</RouterLink>
|
||||
</div>
|
||||
</li>
|
||||
<li :class="[route.name === 'calendar' ? 'bg-nav-active' : '']">
|
||||
<li
|
||||
v-if="jobRole !== roleCheck"
|
||||
:class="[route.name === 'calendar' ? 'bg-nav-active' : '']">
|
||||
<div>
|
||||
<i class="fa-regular fa-calendar" :class="[route.name === 'calendar' ? 'router-link-active' : '']"></i>
|
||||
<RouterLink
|
||||
@@ -136,6 +138,17 @@
|
||||
class="nav-link" :to="{name: 'calendar'}">{{ t('global.calendar') }}</RouterLink>
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
v-if="jobRole === roleCheck"
|
||||
:class="[route.name === 'store' ? 'bg-nav-active' : '']"
|
||||
>
|
||||
<div>
|
||||
<i class="fa-solid fa-shop-lock" :class="[route.name === 'store' ? 'router-link-active' : '']"></i>
|
||||
<RouterLink
|
||||
active-class="router-link-active"
|
||||
class="nav-link" :to="{name: 'store'}">{{ t('store.title') }}</RouterLink>
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
v-if="permission === 'role_carrier' && jobRole !== roleCheck"
|
||||
:class="[route.name === 'calculator' ? 'bg-nav-active' : '']">
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import { ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
defineProps({
|
||||
const props = defineProps({
|
||||
vehicle: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
driver: {
|
||||
type: Object,
|
||||
required: false
|
||||
}
|
||||
})
|
||||
|
||||
@@ -16,6 +21,16 @@ import { useI18n } from 'vue-i18n';
|
||||
const toogle = () => {
|
||||
isShow.value = !isShow.value;
|
||||
}
|
||||
|
||||
const driver = computed(() => {
|
||||
console.log(props.driver);
|
||||
if(props?.driver) {
|
||||
return !props?.driver ? 'No definido'
|
||||
: props?.driver.first_name + ' ' + props?.driver.last_name
|
||||
} else {
|
||||
return props.vehicle.driver.first_name + ' ' + props.vehicle.driver.last_name;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -31,7 +46,7 @@ import { useI18n } from 'vue-i18n';
|
||||
<div class="col-lg-6">
|
||||
<p>{{ t('labels.codeId') }}: <span>{{ vehicle.vehicle_code.toUpperCase() }}</span></p>
|
||||
<p>{{ t('directory.typeTruck') }}: <span>{{ vehicle.truck_type }}</span></p>
|
||||
<p>{{ t('vehicles.assignedDriver') }}: <span>{{ vehicle.driver.first_name + ' ' + vehicle.driver.last_name }}</span></p>
|
||||
<p>{{ t('vehicles.assignedDriver') }}: <span>{{ driver }}</span></p>
|
||||
<p>{{ t('global.segment') }}: <span>{{ vehicle._categories }}</span></p>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
required: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
});
|
||||
defineEmits(['update:selectedCities', 'clear-option'])
|
||||
@@ -49,6 +53,9 @@
|
||||
:selectLabel="t('global.helpSelected')"
|
||||
:selectedLabel="t('global.selected')"
|
||||
:deselectLabel="t('global.removeSelected')"
|
||||
:class="[
|
||||
required ? 'border-required' : '',
|
||||
]"
|
||||
>
|
||||
<template #noResult>
|
||||
{{ t('global.notFound') }}
|
||||
|
||||
@@ -48,10 +48,17 @@
|
||||
|
||||
<template>
|
||||
<div class="d-flex flex-column gap-2 mb-4">
|
||||
<label class="custom-label" :for="name">{{ label }}</label>
|
||||
<label
|
||||
class="custom-label"
|
||||
:class="[label.includes('*') ? 'required' : '']"
|
||||
:for="name"
|
||||
>{{ label }}</label>
|
||||
<input
|
||||
class="custom-input"
|
||||
:class="[!filled ? 'custom-input-light' : '']"
|
||||
:class="[
|
||||
!filled ? 'custom-input-light' : '',
|
||||
// label.includes('*') ? 'border-required' : ''
|
||||
]"
|
||||
:type="type"
|
||||
:id="name"
|
||||
:name="name"
|
||||
@@ -77,6 +84,6 @@
|
||||
.error-msg {
|
||||
color: red;
|
||||
font-size: 12px;
|
||||
font-weight: 300;
|
||||
font-weight: 400;
|
||||
}
|
||||
</style>
|
||||
@@ -19,6 +19,10 @@
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
required: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
});
|
||||
defineEmits(['update:selectedProduct', 'clear-option'])
|
||||
@@ -49,6 +53,9 @@
|
||||
:selectLabel="t('global.helpSelected')"
|
||||
:selectedLabel="t('global.selected')"
|
||||
:deselectLabel="t('global.removeSelected')"
|
||||
:class="[
|
||||
required ? 'border-required' : '',
|
||||
]"
|
||||
>
|
||||
<template #noResult>
|
||||
{{ t('global.notFound') }}
|
||||
|
||||
@@ -15,6 +15,10 @@
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
required: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
});
|
||||
defineEmits(['update:selectedCategory', 'clear-option'])
|
||||
@@ -44,6 +48,9 @@
|
||||
:selectLabel="t('global.helpSelected')"
|
||||
:selectedLabel="t('global.selected')"
|
||||
:deselectLabel="t('global.removeSelected')"
|
||||
:class="[
|
||||
required ? 'border-required' : '',
|
||||
]"
|
||||
>
|
||||
<template #noResult>
|
||||
{{ t('global.notFound') }}
|
||||
|
||||
@@ -15,6 +15,10 @@
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
required: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
});
|
||||
defineEmits(['update:selectedState', 'clear-option'])
|
||||
@@ -45,8 +49,9 @@
|
||||
:selectLabel="t('global.helpSelected')"
|
||||
:selectedLabel="t('global.selected')"
|
||||
:deselectLabel="t('global.removeSelected')"
|
||||
|
||||
|
||||
:class="[
|
||||
required ? 'border-required' : '',
|
||||
]"
|
||||
>
|
||||
<template #noResult>
|
||||
{{ t('global.notFound') }}
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
required: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
});
|
||||
defineEmits(['update:selectedTruckType', 'clear-option'])
|
||||
@@ -53,6 +57,9 @@
|
||||
:selectLabel="t('global.helpSelected')"
|
||||
:selectedLabel="t('global.selected')"
|
||||
:deselectLabel="t('global.removeSelected')"
|
||||
:class="[
|
||||
required ? 'border-required' : '',
|
||||
]"
|
||||
>
|
||||
<template #noResult>
|
||||
{{ t('global.notFound') }}
|
||||
|
||||
@@ -7,7 +7,8 @@ export default function useCalendar() {
|
||||
|
||||
const getCalendarDate = async(startDate, endDate, filter) => {
|
||||
loading.value = true;
|
||||
const resp = await getCalendar(startDate, endDate, filter);
|
||||
const filters = `date[lte]=${endDate}&date[gte]=${startDate}&global=${filter}`
|
||||
const resp = await getCalendar(filters);
|
||||
if(resp === null) {
|
||||
loading.value = false;
|
||||
loads.value = [];
|
||||
|
||||
@@ -35,7 +35,7 @@ export const getStatusLoad = (load, locale = 'es') => {
|
||||
};
|
||||
}
|
||||
|
||||
export const eventStatusLoad = (loadStatus) => {
|
||||
export const eventStatusLoad = (loadStatus, locale = 'es') => {
|
||||
let color;
|
||||
let status;
|
||||
switch (loadStatus) {
|
||||
@@ -58,13 +58,15 @@ export const eventStatusLoad = (loadStatus) => {
|
||||
break;
|
||||
case 'Delivered':
|
||||
color = "blue";
|
||||
status = "#1B70AF";
|
||||
status = "Entregado";
|
||||
break;
|
||||
default:
|
||||
color = "yellow";
|
||||
status = 'Sin publicar';
|
||||
break;
|
||||
}
|
||||
|
||||
status = (locale === 'es') ? status : loadStatus;
|
||||
return {
|
||||
color,
|
||||
status
|
||||
|
||||
@@ -8,6 +8,8 @@ export const getTypeUser = (value, locale = 'es') => {
|
||||
return (locale == 'es') ? 'Gerente' : 'Manager';
|
||||
case 'owner':
|
||||
return (locale == 'es') ? 'Propietario' : 'Owner';
|
||||
case 'warehouse':
|
||||
return (locale == 'es') ? 'Bodega' : 'Warehouse';
|
||||
|
||||
default:
|
||||
return (locale == 'es') ? 'Personal' : 'Staff';
|
||||
|
||||
@@ -51,6 +51,9 @@ const en = {
|
||||
completed: 'Offers completed',
|
||||
all: 'All offers',
|
||||
load: 'Load',
|
||||
warehouse: 'Warehouse',
|
||||
warehouses: 'Warehouses',
|
||||
warehouseSelect: 'Select warehouse',
|
||||
download: 'Download',
|
||||
select: 'Select',
|
||||
additionalInformation: 'Additional information',
|
||||
@@ -70,6 +73,12 @@ const en = {
|
||||
originTruckKm1: "Truck origin to load origin(KM)",
|
||||
originTruckKm2: "Loading origin to unloading destination(KM)",
|
||||
destinationTruck1: "Unloading destination to base-yard(KM)",
|
||||
alls: 'All',
|
||||
published: 'Published',
|
||||
loading: 'Loading',
|
||||
transit: 'In transit',
|
||||
downloading: 'Downloading',
|
||||
delivered: 'Delivered',
|
||||
},
|
||||
buttons: {
|
||||
enter: "Enter here",
|
||||
@@ -478,6 +487,9 @@ const en = {
|
||||
acceptedProposalDesc: 'Your offer has been accepted in the upload',
|
||||
rejectedProposalDesc: 'Your offer has been rejected on upload',
|
||||
},
|
||||
store: {
|
||||
title: "Warehouse"
|
||||
}
|
||||
};
|
||||
|
||||
export default en;
|
||||
@@ -68,11 +68,20 @@ const es = {
|
||||
vehicle: 'Vehiculo',
|
||||
comment: 'Comentario',
|
||||
tons: "Toneladas",
|
||||
warehouse: 'Bodega',
|
||||
warehouses: 'Bodegas',
|
||||
warehouseSelect: 'Seleccionar bodega',
|
||||
priceTons: "Precio por toneladas",
|
||||
tonLoad: "Tonelaje aproximado de carga",
|
||||
originTruckKm1: "Origen del camión al origin de carga(KM)",
|
||||
originTruckKm2: "Origen de carga a destino de descarga(KM)",
|
||||
destinationTruck1: "Destino de descarga al patio-base(KM)"
|
||||
destinationTruck1: "Destino de descarga al patio-base(KM)",
|
||||
alls: 'Todos',
|
||||
published: 'Publicado',
|
||||
loading: 'Cargando',
|
||||
transit: 'En transito',
|
||||
downloading: 'Descargando',
|
||||
delivered: 'Entregado',
|
||||
},
|
||||
buttons: {
|
||||
enter: "Ingresa aqui",
|
||||
@@ -487,6 +496,9 @@ const es = {
|
||||
acceptedProposalDesc: 'Tu oferta ha sido aceptada en la carga',
|
||||
rejectedProposalDesc: 'Tu oferta ha sido rechazada en la carga',
|
||||
},
|
||||
store: {
|
||||
title: "Bodega"
|
||||
}
|
||||
};
|
||||
|
||||
export default es;
|
||||
@@ -94,7 +94,10 @@ const router = createRouter({
|
||||
{
|
||||
path: 'profile',
|
||||
name: 'profile',
|
||||
meta: { permissions: ['role_shipper', 'role_carrier'] },
|
||||
meta: {
|
||||
permissions: ['role_shipper', 'role_carrier'],
|
||||
roles: ['manager', 'staff', 'owner', 'warehouse']
|
||||
},
|
||||
component: () => import('../views/EditProfileView.vue'),
|
||||
},
|
||||
{
|
||||
@@ -138,10 +141,19 @@ const router = createRouter({
|
||||
name: 'calendar',
|
||||
meta: {
|
||||
permissions: ['role_shipper', 'role_carrier'],
|
||||
roles: ['staff', 'manager', 'owner', 'store']
|
||||
roles: ['staff', 'manager', 'owner']
|
||||
},
|
||||
component: () => import('../views/CalendarView.vue'),
|
||||
},
|
||||
{
|
||||
path: 'bodega',
|
||||
name: 'store',
|
||||
meta: {
|
||||
permissions: ['role_shipper'],
|
||||
roles: ['warehouse']
|
||||
},
|
||||
component: () => import('../views/store/StoreView.vue'),
|
||||
},
|
||||
{
|
||||
path: 'cargas',
|
||||
meta: { permissions: ['role_shipper'] },
|
||||
@@ -211,15 +223,16 @@ router.beforeEach( async(to, from, next) => {
|
||||
}
|
||||
|
||||
if (permissions && !permissions.includes(permissionUser)) {
|
||||
if(role === 'store') { /// Check if user is store
|
||||
return next({name: 'calendar'});
|
||||
if(role === 'warehouse') { /// Check if user is store
|
||||
return next({name: 'store'});
|
||||
} else {
|
||||
return next({name: 'home'});
|
||||
}
|
||||
}
|
||||
|
||||
if(roles && !roles.includes(role)) {
|
||||
return next({name: 'calendar'});
|
||||
// return next({name: 'calendar'});
|
||||
return next({name: 'store'});
|
||||
}
|
||||
|
||||
next();
|
||||
|
||||
@@ -158,9 +158,9 @@ export const deleteLocation = async(id) => {
|
||||
}
|
||||
}
|
||||
|
||||
export const getCalendar = async(startDate, endDate, global) => {
|
||||
export const getCalendar = async(filters) => {
|
||||
try {
|
||||
const endpoint = `/v1/loads/calendar?$sort[createdAt]=-1&date[lte]=${endDate}&date[gte]=${startDate}&global=${global}&elements=1000`;
|
||||
const endpoint = `/v1/loads/calendar?$sort[createdAt]=-1&elements=1000&${filters}`;
|
||||
const {data} = await api.get(endpoint);
|
||||
return {
|
||||
msg: "success",
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import { defineStore } from "pinia";
|
||||
import { ref } from "vue";
|
||||
import api from "../lib/axios";
|
||||
import { getCalendar } from "../services/company";
|
||||
|
||||
export const useLoadsStore = defineStore('load', () => {
|
||||
|
||||
const currentLoad = ref(null);
|
||||
const loads = ref([])
|
||||
const loadsWarehouse = ref([])
|
||||
const loadsDashboard = ref([]);
|
||||
const loadsTotal = ref(0)
|
||||
const loadsCurrentPage = ref(0)
|
||||
@@ -13,6 +15,7 @@ export const useLoadsStore = defineStore('load', () => {
|
||||
const openModalEdit = ref(false);
|
||||
const openAttachmentsModal = ref(false);
|
||||
const openProposalsModal = ref(false);
|
||||
const openCarrierInfoModal = ref(false);
|
||||
|
||||
const getLoadsAll = async(reload = false) => {
|
||||
const companyid = localStorage.getItem('id');
|
||||
@@ -61,6 +64,24 @@ export const useLoadsStore = defineStore('load', () => {
|
||||
}
|
||||
}
|
||||
|
||||
const getLoadsWarehouse = async(filterQuery, reload = false) => {
|
||||
let filterArr = Object.values(filterQuery);
|
||||
let cleanfilterArr = filterArr.filter(n=>n);
|
||||
var filterStr = "";
|
||||
if(cleanfilterArr.length >0){
|
||||
filterStr = cleanfilterArr.join("&");
|
||||
}
|
||||
if(loadsWarehouse.value.length <= 0 || reload) {
|
||||
try {
|
||||
const endpoint = `/v1/loads/find?${filterStr}`;
|
||||
const {data} = await api.get(endpoint);
|
||||
loadsWarehouse.value = data.data;
|
||||
} catch (error) {
|
||||
loadsWarehouse.value = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const getProposalsOfLoads = async(filterQuery) => {
|
||||
try {
|
||||
const endpoint = `/v1/proposals/find?load=${filterQuery}`;
|
||||
@@ -140,6 +161,7 @@ export const useLoadsStore = defineStore('load', () => {
|
||||
loadsTotal.value = 0;
|
||||
loadsCurrentPage.value = 0;
|
||||
proposalsOfLoads.value = [];
|
||||
loadsWarehouse.value = [];
|
||||
openModalEdit.value = false;
|
||||
openAttachmentsModal.value = false;
|
||||
openProposalsModal.value = false;
|
||||
@@ -151,11 +173,14 @@ export const useLoadsStore = defineStore('load', () => {
|
||||
openModalEdit,
|
||||
openProposalsModal,
|
||||
openAttachmentsModal,
|
||||
openCarrierInfoModal,
|
||||
getProposalsOfLoads,
|
||||
getCompanyLoads,
|
||||
getLoadsAll,
|
||||
getProposalCompanyAll,
|
||||
getLoadsWarehouse,
|
||||
loadsDashboard,
|
||||
loadsWarehouse,
|
||||
deleteLoad,
|
||||
getLoad,
|
||||
saveLoad,
|
||||
@@ -167,5 +192,6 @@ export const useLoadsStore = defineStore('load', () => {
|
||||
loadsTotal,
|
||||
currentLoad,
|
||||
proposalsOfLoads,
|
||||
|
||||
}
|
||||
});
|
||||
@@ -240,7 +240,7 @@
|
||||
v-model:field="company.rfc"
|
||||
/>
|
||||
<div class="mb-4">
|
||||
<label class="custom-label">{{ t('labels.questionSegments') }} *</label>
|
||||
<label class="custom-label required">{{ t('labels.questionSegments') }} *</label>
|
||||
<Segments
|
||||
v-model="company.segments"
|
||||
:multiple="true"
|
||||
@@ -261,7 +261,7 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label class="custom-label">{{ t('labels.questionTrucks') }} *</label>
|
||||
<label class="custom-label required">{{ t('labels.questionTrucks') }} *</label>
|
||||
<TruckTypes
|
||||
v-model="company.truckTypes"
|
||||
:multiple="true"
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
const result = await auth.updateProfile(userData)
|
||||
loading.value = false;
|
||||
if(result.msg === 'success') {
|
||||
msgSuccess.value = t('errors.msgUpdateUser');
|
||||
msgSuccess.value = t('profile.msgUpdateUser');
|
||||
clearMessages();
|
||||
} else {
|
||||
msgError.value = t('errors.generic');
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
import CardEmpty from '../components/CardEmpty.vue';
|
||||
import Pagination from '../components/Pagination.vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import CarrierInfoModal from '../components/CarrierInfoModal.vue';
|
||||
|
||||
const loadStore = useLoadsStore();
|
||||
const loading = ref(false);
|
||||
@@ -94,6 +95,7 @@
|
||||
<AttachmentsModal v-if="loadStore.openAttachmentsModal"/>
|
||||
<FormLoadModal v-if="loadStore.openModalEdit"/>
|
||||
<ProposalsModal v-if="loadStore.openProposalsModal"/>
|
||||
<CarrierInfoModal :load="loadStore.currentLoad" v-if="loadStore.openCarrierInfoModal"/>
|
||||
<div>
|
||||
<h2 class="title mb-5">{{ t('loads.title') }}</h2>
|
||||
<div>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import AttachmentsModal from '../components/AttachmentsModal.vue';
|
||||
import { useLoadsStore } from '../stores/loads';
|
||||
import CarrierInfoModal from '../components/CarrierInfoModal.vue';
|
||||
|
||||
const mapKey = import.meta.env.VITE_MAP_KEY;
|
||||
|
||||
@@ -91,10 +92,16 @@
|
||||
heightMap.value = 768;
|
||||
}
|
||||
}
|
||||
|
||||
const openModal = () => {
|
||||
loadStore.openCarrierInfoModal = true;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AttachmentsModal v-if="loadStore.openAttachmentsModal"/>
|
||||
<CarrierInfoModal :load="load" v-if="loadStore.openCarrierInfoModal"/>
|
||||
<h2 class="title text-center mt-5">{{ t('loads.trackingLoad') }}</h2>
|
||||
<Spiner v-if="loading"/>
|
||||
<div v-else>
|
||||
@@ -119,15 +126,23 @@
|
||||
>
|
||||
<Marker v-if="originCoords" :options="{position: originCoords, label: 'O', title: 'Destino'}" />
|
||||
<Marker v-if="destinationCoords" :options="{position: destinationCoords, label: 'D', title: 'Origen'}" />
|
||||
<!-- v-if="vehicleLastLocation && load.vehicle.background_tracking && isLoadActive" -->
|
||||
<!-- <CustomMarker
|
||||
:options="{position: vehicleLastLocation}"
|
||||
:clickable="false"
|
||||
:draggable="false"
|
||||
> -->
|
||||
<CustomMarker
|
||||
v-if="vehicleLastLocation && load.vehicle.background_tracking && isLoadActive"
|
||||
:options="{position: vehicleLastLocation}"
|
||||
:clickable="false"
|
||||
:draggable="false"
|
||||
>
|
||||
<div
|
||||
style="text-align: center"
|
||||
data-toggle="modal"
|
||||
data-target="#carrierInfoModal"
|
||||
@click="openModal()"
|
||||
>
|
||||
<div style="text-align: center">
|
||||
<!-- <img src="/images/freeTruck.png" width="25" height="25" /> -->
|
||||
<i class="fa-solid fa-truck" :style="{fontSize: 25 + 'px', color: 'green'}"></i>
|
||||
</div>
|
||||
</CustomMarker>
|
||||
|
||||
199
src/views/store/StoreView.vue
Normal file
199
src/views/store/StoreView.vue
Normal file
@@ -0,0 +1,199 @@
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { onMounted } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import LoadStoreCard from './components/LoadStoreCard.vue';
|
||||
import { useLoadsStore } from '../../stores/loads';
|
||||
import { useAuthStore } from '../../stores/auth';
|
||||
import Spiner from '../../components/ui/Spiner.vue';
|
||||
import CustomPopup from '../../components/CustomPopup.vue';
|
||||
|
||||
const authStore = useAuthStore();
|
||||
const loadStore = useLoadsStore();
|
||||
const { t } = useI18n()
|
||||
|
||||
const query = ref('');
|
||||
const date = ref(new Date());
|
||||
const loadsFilters = ref([]);
|
||||
const filterQuery = ref([]);
|
||||
const loading = ref(false);
|
||||
const openPopup = ref(false);
|
||||
const status = ref({value: 'all', label: 'Todos'});
|
||||
const options = ref([]);
|
||||
|
||||
onMounted(async() => {
|
||||
date.value = (new Date()).toISOString().substring(0, 10);
|
||||
options.value = [
|
||||
{value: 'all', label: t('labels.alls')},
|
||||
{value: 'Published',label: t('labels.published')},
|
||||
{value: 'Loading',label: t('labels.loading')},
|
||||
{value: 'Transit',label: t('labels.transit')},
|
||||
]
|
||||
status.value = {value: 'all', label: t('labels.alls')};
|
||||
await getDataLoads(false);
|
||||
})
|
||||
|
||||
const getDataLoads = async (reload) => {
|
||||
loading.value = true;
|
||||
const dateSelected = new Date(date.value);
|
||||
const startDate = dateSelected.toISOString();
|
||||
const endDateSpeac = new Date(dateSelected).setDate(dateSelected.getDate() + 1);
|
||||
const endDate = (new Date(endDateSpeac)).toISOString();
|
||||
filterQuery.value.branch = 'shipper_warehouse=' + authStore.user.branch;
|
||||
filterQuery.value.start = 'est_loading_date[gte]=' + startDate.substring(0, 10).replaceAll('-', '/');
|
||||
filterQuery.value.end = 'est_loading_date[lte]=' + endDate.substring(0, 10).replaceAll('-', '/');
|
||||
await loadStore.getLoadsWarehouse(filterQuery.value, reload);
|
||||
loadsFilters.value = loadStore.loadsWarehouse;
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
/// methods:
|
||||
const search = () => {
|
||||
if(query.value == "") {
|
||||
loadsFilters.value = loadStore.loads;
|
||||
}
|
||||
if(query.value.length >= 1){
|
||||
loadsFilters.value = loadStore.loadsWarehouse.filter(
|
||||
load => load.shipment_code.toLowerCase().includes(query.value.toLowerCase())
|
||||
|| load?.carrier?.company_name.toLowerCase().includes(query.value.toLowerCase())
|
||||
|| load?.product?.name.toLowerCase().includes(query.value.toLowerCase())
|
||||
|| load?.vehicle?.truck_type.toLowerCase().includes(query.value.toLowerCase())
|
||||
|| load?.vehicle?.circulation_serial_number.toLowerCase().includes(query.value.toLowerCase())
|
||||
|| load?.vehicle?.trailer_plate_1.toLowerCase().includes(query.value.toLowerCase())
|
||||
|| load?.vehicle?.trailer_plate_2.toLowerCase().includes(query.value.toLowerCase())
|
||||
|| load?.driver?.first_name.toLowerCase().includes(query.value.toLowerCase())
|
||||
);
|
||||
} else {
|
||||
loadsFilters.value = loadStore.loadsWarehouse;
|
||||
}
|
||||
}
|
||||
|
||||
const handleDate = async () => {
|
||||
status.value = {value: 'all', label: t('labels.alls')};
|
||||
await getDataLoads(true);
|
||||
}
|
||||
|
||||
const closePopup = () => {
|
||||
openPopup.value = false
|
||||
}
|
||||
|
||||
const changeStatus = (value) => {
|
||||
status.value = value;
|
||||
openPopup.value = false
|
||||
if(value.value == 'all') {
|
||||
loadsFilters.value = loadStore.loadsWarehouse;
|
||||
} else {
|
||||
loadsFilters.value = loadStore.loadsWarehouse.filter(
|
||||
load => load.load_status.toLowerCase().includes(value.value.toLowerCase())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
v-if="openPopup"
|
||||
>
|
||||
<CustomPopup
|
||||
:options="options"
|
||||
:value="status"
|
||||
@change-value="changeStatus"
|
||||
@close-popup="closePopup"
|
||||
selected-color="#e3a11e"
|
||||
/>
|
||||
</div>
|
||||
<h2 class="title mb-4">{{ t('store.title') }}</h2>
|
||||
<div class="box-filters">
|
||||
<div class="box-search">
|
||||
<input
|
||||
class="form-control custom-search"
|
||||
type="search" name=""
|
||||
:placeholder="t('buttons.search')"
|
||||
id="store-search"
|
||||
@:input="search()"
|
||||
v-model="query"
|
||||
aria-label="Search"
|
||||
/>
|
||||
</div>
|
||||
<div class="date-filter">
|
||||
<input
|
||||
placeholder="Fecha"
|
||||
type="date"
|
||||
class="custom-input-fill"
|
||||
v-model="date"
|
||||
@change="handleDate($event)"
|
||||
/>
|
||||
</div>
|
||||
<div class="status-filter"
|
||||
@click="openPopup = true"
|
||||
>
|
||||
<span class="clear-sm">{{ status.label }}</span>
|
||||
<i class="fa-solid fa-filter"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div v-if="loading" class="d-flex justify-content-center">
|
||||
<Spiner />
|
||||
</div>
|
||||
<LoadStoreCard
|
||||
v-else
|
||||
v-for="load in loadsFilters"
|
||||
:key="load.shipment_code"
|
||||
:load="load"
|
||||
/>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.box-filters {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: end;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.box-search {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.status-filter {
|
||||
padding: 12px 8px;
|
||||
background-color: #FFF;
|
||||
border-radius: 5px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
border: 1px rgb(186, 175, 175) solid;
|
||||
gap: 1rem;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.custom-search {
|
||||
width: 100%;
|
||||
padding: 12px 20px;
|
||||
}
|
||||
|
||||
.bg-white {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.box-filters {
|
||||
gap: 0.2rem;
|
||||
}
|
||||
|
||||
.date-filter input {
|
||||
padding: 12px 8px;
|
||||
width: 130px;
|
||||
}
|
||||
|
||||
.box-search {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</style>
|
||||
86
src/views/store/components/LoadStoreCard.vue
Normal file
86
src/views/store/components/LoadStoreCard.vue
Normal file
@@ -0,0 +1,86 @@
|
||||
<script setup>
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { getDateTime } from '../../../helpers/date_formats';
|
||||
import { eventStatusLoad } from '../../../helpers/status';
|
||||
import { computed } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
load: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
const { t, locale } = useI18n()
|
||||
|
||||
const status = eventStatusLoad(props.load.load_status, locale.value);
|
||||
|
||||
const driver = computed(() => {
|
||||
return !props.load?.driver ? 'No definido'
|
||||
: props.load?.driver.first_name + ' ' + props.load?.driver.last_name
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="col-lg-6 col-12 mt-4"
|
||||
>
|
||||
<div class="card-info flex-d-column">
|
||||
<div class="d-flex justify-content-between bg-white">
|
||||
<div class="flex-direction-column">
|
||||
<h2>{{ load.shipment_code }}</h2>
|
||||
<p><span class="font-bold">{{ t('labels.date') }}: </span> {{ getDateTime(load.est_loading_date, 0) }}</p>
|
||||
<p><span class="font-bold" >{{ t('global.company') }}: </span> {{ load?.carrier?.company_name ?? 'No definido' }}</p>
|
||||
<p><span class="font-bold" >{{ t('loads.product') }}: </span> {{ load.product?.name }}</p>
|
||||
<p><span class="font-bold" >{{ t('loads.weight') }}: </span> {{ load.weight }}kg</p>
|
||||
</div>
|
||||
<div class="flex-direction-column">
|
||||
<p> <div class="indicator" :style="{backgroundColor: status.color}"></div> <strong :style="{color: status.color}">{{ status.status }}</strong></p>
|
||||
<p> <span class="font-bold">{{ t('directory.typeTruck') }}: </span> {{ load?.vehicle?.truck_type ?? 'No definido' }}</p>
|
||||
<p> <span class="font-bold">{{ t('vehicles.truckPlates') }}: </span> {{ load?.vehicle?.circulation_serial_number ?? 'No definido' }}</p>
|
||||
<p v-if="load?.vehicle?.trailer_plate_1">
|
||||
<span class="font-bold">{{ t('vehicles.trailerPlates') }} 1: </span> {{ load?.vehicle?.trailer_plate_1 }}
|
||||
</p>
|
||||
<p v-if="load?.vehicle?.trailer_plate_2">
|
||||
<span class="font-bold">{{ t('vehicles.trailerPlates') }} 2: </span> {{ load?.vehicle?.trailer_plate_2 }}
|
||||
</p>
|
||||
<p> <span class="font-bold">{{ t('labels.driver') }}: </span> {{ driver }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-note" v-if="load.notes">
|
||||
<span class="label"><i class="fa-solid fa-clipboard" style="color: #FBBA33; font-size: 1.1rem;"></i> Nota:</span>
|
||||
<span>{{ load.notes }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.indicator {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
.box-note {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0.8rem;
|
||||
font-size: 1rem;
|
||||
background-color: #FFF;
|
||||
border-radius: 13px;
|
||||
border: 1px solid #E5E5E5;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-weight: bold;
|
||||
font-size: 0.9rem;
|
||||
color: #303233;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user