add: share load

This commit is contained in:
Alexandro Uc Santos
2024-10-21 21:31:27 -06:00
parent 6dae5d9574
commit c8bbcdaad2
7 changed files with 193 additions and 16 deletions

View File

@@ -24,6 +24,11 @@
type: Boolean, type: Boolean,
required: false, required: false,
default: true default: true
},
share: {
type: Boolean,
required: false,
default: false
} }
}); });
@@ -90,6 +95,22 @@
window.open('/publico/tracking/' + code, '_blank'); window.open('/publico/tracking/' + code, '_blank');
} }
const sharePost = () => {
const url = `https://console.etaviaporte.com/publico/carga/${props.load._id}`;
const title = "";
navigator.share({
title: title,
url: url,
})
.then(() => {
console.log("Enlace compartido con éxito");
})
.catch((error) => {
console.log('Usuario cancelo')
});
}
</script> </script>
<template> <template>
@@ -161,7 +182,7 @@
{{ load.notes }} {{ load.notes }}
</div> </div>
<div class="btn-row"> <div class="btn-row">
<button v-if="load.status !== 'Draft' && load.load_status !== 'Published' && load.load_status !== 'Loading' && !tracking" <button v-if="load.status !== 'Draft' && load.load_status !== 'Published' && load.load_status !== 'Loading' && !tracking && !share"
type="button" type="button"
data-toggle="modal" data-target="#attachmentModal" data-toggle="modal" data-target="#attachmentModal"
class="btn-primary-sm" class="btn-primary-sm"
@@ -171,12 +192,15 @@
{{ t('evidence.evidence') }} {{ t('evidence.evidence') }}
</button> </button>
</div> </div>
<div class="btn-row" v-if="load?.company?._id === authStore?.user?.company._id"> <div class="btn-row" v-if="load?.company?._id === authStore?.user?.company._id && !share">
<button <button v-if="load.status !== 'Draft' && load.load_status !== 'Delivered'"
v-if="(authStore.user?.job_role === 'owner' || authStore.user?.job_role === 'manager') || authStore.user._id === props.load.posted_by" type="button"
class="btn-primary-sm bg-danger" class="btn-primary-sm"
@click="handleDeleteLoad" @click="sharePost"
><i class="fa-solid fa-ban clear-sm"></i> {{ t('buttons.cancel') }}</button> >
<i class="fa-solid fa-share-nodes"></i>
<span class="clear-sm ms-1">{{t('buttons.share')}}</span>
</button>
<button v-if="load.status !== 'Draft' && load.load_status !== 'Published' && load.load_status !== 'Loading'" <button v-if="load.status !== 'Draft' && load.load_status !== 'Published' && load.load_status !== 'Loading'"
type="button" type="button"
data-toggle="modal" data-target="#attachmentModal" data-toggle="modal" data-target="#attachmentModal"
@@ -184,14 +208,25 @@
@click="openAttachmentsModal" @click="openAttachmentsModal"
> >
<i class="fa-solid fa-image"></i> <i class="fa-solid fa-image"></i>
{{ t('evidence.evidence') }} <span class="clear-sm ms-1">{{ t('evidence.evidence') }}</span>
</button> </button>
<button <button
v-if="(authStore.user?.job_role === 'owner' || authStore.user?.job_role === 'manager') || authStore.user._id === props.load.posted_by" v-if="(authStore.user?.job_role === 'owner' || authStore.user?.job_role === 'manager') || authStore.user._id === props.load.posted_by"
class="btn-primary-sm" class="btn-primary-sm bg-danger"
@click="handleDeleteLoad"
>
<i class="fa-solid fa-trash"></i>
<span class="clear-sm ms-1">{{ t('buttons.cancel') }}</span>
</button>
<button
v-if="(authStore.user?.job_role === 'owner' || authStore.user?.job_role === 'manager') || authStore.user._id === props.load.posted_by"
class="btn-primary-sm bg-dark"
data-toggle="modal" data-target="#formLoadModal" data-toggle="modal" data-target="#formLoadModal"
@click="openEditModal" @click="openEditModal"
><i class="fa-solid fa-pen-to-square clear-sm"></i> {{t('loads.editLoad')}}</button> >
<i class="fa-solid fa-pen-to-square"></i>
<span class="clear-sm ms-1">{{t('loads.editLoad')}}</span>
</button>
<button <button
v-if="load.status !== 'Draft'" v-if="load.status !== 'Draft'"
class="btn-primary-sm" class="btn-primary-sm"
@@ -200,7 +235,7 @@
data-target="#proposalsModal" data-target="#proposalsModal"
>#{{ load.no_of_proposals }} {{t('loads.offers')}}</button> >#{{ load.no_of_proposals }} {{t('loads.offers')}}</button>
</div> </div>
<div class="btn-row" v-if="readOnly && authStore.user?.permissions === 'role_carrier'"> <div class="btn-row" v-if="readOnly && authStore.user?.permissions === 'role_carrier' || share">
<button <button
class="btn-primary-sm bg-dark" class="btn-primary-sm bg-dark"
data-toggle="modal" data-toggle="modal"

View File

@@ -82,7 +82,7 @@
<p><span>{{ t('labels.userRole') }}: </span>{{ getTypeUser(user.job_role, locale) }}</p> <p><span>{{ t('labels.userRole') }}: </span>{{ getTypeUser(user.job_role, locale) }}</p>
<p><span>{{ t('labels.phone1') }}: </span> <p><span>{{ t('labels.phone1') }}: </span>
{{user.phone}} {{user.phone}}
<a :href="whatsappLink" target="_blank"> <a v-if="readonly" :href="whatsappLink" target="_blank">
<i class="fab fa-whatsapp whatsapp"></i> <!-- Usando FontAwesome para el icono de WhatsApp --> <i class="fab fa-whatsapp whatsapp"></i> <!-- Usando FontAwesome para el icono de WhatsApp -->
</a> </a>
</p> </p>

View File

@@ -60,12 +60,13 @@
}); });
const initData = async() => { const initData = async() => {
const companyId = localStorage.getItem('id');
isLoading.value = true; isLoading.value = true;
let filterQuery = []; let filterQuery = [];
filterQuery.company = "company="+ authStore.user.company._id // filterQuery.company = "company="+ authStore.user.company._id
filterQuery.company = "company="+companyId
await vehiclesStore.fetchVehicles(filterQuery); await vehiclesStore.fetchVehicles(filterQuery);
if(!props.proposal) { if(!props.proposal) {
// vehiclesAvailable.value = vehiclesStore.vehicles.filter((vehicle) => vehicle.is_available);
vehiclesAvailable.value = vehiclesStore.vehicles; vehiclesAvailable.value = vehiclesStore.vehicles;
} else { } else {
// vehiclesAvailable.value = vehiclesStore.vehicles.filter((vehicle) => vehicle._id === props.proposal.vehicle._id); // vehiclesAvailable.value = vehiclesStore.vehicles.filter((vehicle) => vehicle._id === props.proposal.vehicle._id);

View File

@@ -97,7 +97,8 @@ const en = {
search: 'Search', search: 'Search',
profile: 'View profile', profile: 'View profile',
send: 'Send', send: 'Send',
download: 'Download' download: 'Download',
share: "Share"
}, },
errors: { errors: {
required: 'Field is required', required: 'Field is required',

View File

@@ -100,7 +100,8 @@ const es = {
search: 'Buscar', search: 'Buscar',
profile: 'Ver perfil', profile: 'Ver perfil',
send: 'Enviar', send: 'Enviar',
download: 'Descargar' download: 'Descargar',
share: "Compartir"
}, },
errors: { errors: {
required: 'Campo es requerido', required: 'Campo es requerido',

View File

@@ -52,6 +52,11 @@ const router = createRouter({
name: 'tracking-load', name: 'tracking-load',
component: () => import('../views/TrackingLoadView.vue'), component: () => import('../views/TrackingLoadView.vue'),
}, },
{
path: 'carga/:code',
name: 'share-load',
component: () => import('../views/ShareLoadView.vue'),
},
{ {
path: 'faqs', path: 'faqs',
name: 'faqs', name: 'faqs',

134
src/views/ShareLoadView.vue Normal file
View File

@@ -0,0 +1,134 @@
<script setup>
import { onMounted, ref, computed } from 'vue';
import { useRoute, RouterLink } from 'vue-router';
import Spiner from '../components/ui/Spiner.vue';
import CardLoad from '../components/CardLoad.vue';
import useDirectionsRender from '../composables/useDirectionRender';
import { GoogleMap, Marker, CustomMarker, Polyline } from 'vue3-google-map';
import CardEmpty from '../components/CardEmpty.vue';
import useTrackingLoad from '../composables/useTrackingLoad';
import { useI18n } from 'vue-i18n';
import MakeProposalModal from '../components/MakeProposalModal.vue';
const mapKey = import.meta.env.VITE_MAP_KEY;
const { getDirections } = useDirectionsRender()
const { getLoadTracking, load, loading } = useTrackingLoad();
const route = useRoute();
const zoom = ref(6);
const heightMap = ref(768);
const originCoords = ref(null);
const destinationCoords = ref(null);
const polylines = ref([]);
const windowWidth = ref(window.innerWidth);
onMounted(() => {
window.addEventListener('resize', handleResize);
if(window.innerWidth <= 1024) {
zoom.value = 4;
heightMap.value = 420;
}
initData();
});
const { t } = useI18n();
const initData = async() => {
const id = route.params['code'];
await getLoadTracking(id)
if(load.value !== null) {
// console.log(load.value);
const origin = load.value?.origin;
const destination = load.value?.destination;
if(origin && destination) {
originCoords.value = {lat: Number.parseFloat(origin.lat), lng: Number.parseFloat(origin.lng)};
destinationCoords.value = {lat: Number.parseFloat(destination.lat), lng: Number.parseFloat(destination.lng)};
polylines.value = await getDirections(originCoords.value, destinationCoords.value);
}
}
}
const handleResize = () => {
windowWidth.value = window.innerWidth
if(windowWidth.value <= 1024){
zoom.value = 4
heightMap.value = 420;
} else {
zoom.value = 6;
heightMap.value = 768;
}
}
const hasSession = computed(() => (localStorage.getItem('access') && localStorage.getItem('id')))
const handleResetCurrentLoad = () => {
}
const removeLoadOfList = (load) => {
}
</script>
<template>
<MakeProposalModal
v-if="load"
:load="load"
@reset-load="handleResetCurrentLoad"
@remove-load="removeLoadOfList"
/>
<h2 class="title text-center mt-5">Realizar oferta</h2>
<div
v-if="!hasSession"
class="alert alert-info text-dark mt-3 mb-2"
>
Para realizar oferta es necesario que inicies sesión en Etaviaporte
<RouterLink
class="btn btn-dark ms-4"
target="_blank"
:to="{name: 'login'}"
>
Iniciar sesión
</RouterLink>
</div>
<Spiner v-if="loading"/>
<div v-else>
<div v-if="load">
<CardLoad :load="load" :read-only="true" :tracking="false" :share="true"/>
<br/>
<GoogleMap
:api-key="mapKey"
:center="{lat:19.432600, lng:-99.133209}"
:zoom="zoom"
:min-zoom="2"
:max-zoom="20"
: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="t('loads.noInfo')"/>
</div>
</template>