translations users & directory

This commit is contained in:
Alexandro Uc Santos
2024-05-25 18:14:17 -06:00
parent 264a6c6dfc
commit 8f33177dad
14 changed files with 549 additions and 385 deletions

View File

@@ -2,6 +2,7 @@
import Swal from 'sweetalert2';
import { useCompanyStore } from '../stores/company';
import { useAuthStore } from '../stores/auth';
import { useI18n } from 'vue-i18n';
const props = defineProps({
location: {
@@ -14,21 +15,22 @@
const companyStore = useCompanyStore();
const authStore = useAuthStore();
const { t } = useI18n();
const handleDeleteLocation = async() => {
Swal.fire({
title: 'Eliminar Locación!',
text: '¿Estás seguro de eliminar este locación?',
title: t('directory.titleDel'),
text: t('directory.textDel'),
icon: 'warning',
showCancelButton: true,
cancelButtonColor: "#d33",
confirmButtonText: 'Eliminar',
cancelButtonText: 'Cancelar',
confirmButtonText: t('buttons.delete'),
cancelButtonText: t('buttons.cancel'),
}).then(async(result) => {
if(result.isConfirmed) {
Swal.fire({
title: 'Por favor espere!',
html: 'Eliminando locación...',// add html attribute if you want or remove
title: t('messages.loading'),
html: t('directory.loadingDel') + '..',// add html attribute if you want or remove
allowOutsideClick: false,
didOpen: () => {
Swal.showLoading()
@@ -41,14 +43,14 @@
if(resp != null) {
Swal.fire({
title: "Locación eliminado!",
text: "Tu locación ha sido eliminado exitosamente.",
title: t('directory.msgTitleDel'),
text: t('directory.msgDel'),
icon: "success"
});
} else {
Swal.fire({
title: "No eliminado!",
text: "Tu locación no se pudo eliminar, intente más tarde.",
title: t('errors.msgTitleNotDel'),
text: t('directory.msgNotDel'),
icon: "error"
});
}
@@ -62,12 +64,12 @@
<template>
<div class="card-fixed card-location">
<div>
<p><span>Nombre de la locación de carga:</span> {{location.branch_name}}</p>
<p><span>Dirección:</span> <template v-if="location.address">{{location.address}}, </template><template v-if="location.city">{{location.city}}, </template><template v-if="location.state">{{location.state}}</template></p>
<p><span>Teléfono:</span> {{location.phone}}</p>
<p><span>Tipos de camiones que se necesitan:</span> {{location.truck_type?.map((e) => e).join(', ')}}</p>
<p><span>Segmento:</span> {{location.categories?.map((e) => e.name).join(', ')}}</p>
<p v-if="location.description"><span>Información adicional de la locación de carga:</span></p>
<p><span>{{ t('directory.name') }}:</span> {{location.branch_name}}</p>
<p><span>{{ t('directory.address') }}:</span> <template v-if="location.address">{{location.address}}, </template><template v-if="location.city">{{location.city}}, </template><template v-if="location.state">{{location.state}}</template></p>
<p><span>{{ t('labels.phone') }}:</span> {{location.phone}}</p>
<p><span>{{ t('directory.typeTruckNeed') }}:</span> {{location.truck_type?.map((e) => e).join(', ')}}</p>
<p><span>{{ t('global.segments') }}:</span> {{location.categories?.map((e) => e.name).join(', ')}}</p>
<p v-if="location.description"><span>{{ t('directory.additionalInfoLocation') }}:</span></p>
<div v-if="location.description" class="box-note mb-4">
{{ location.description }}
</div>
@@ -77,14 +79,14 @@
class="btn btn-dark radius-sm"
@click="handleDeleteLocation"
>
<i class="fa-solid fa-trash" /> <span class="clear-xsm">Eliminar</span>
<i class="fa-solid fa-trash" /> <span class="clear-xsm">{{ t('buttons.delete') }}</span>
</button>
<button
class="btn-primary-sm radius-sm"
@click="$emit('set-location')"
data-toggle="modal" data-target="#locationFormModal"
>
<i class="fa-solid fa-pen-to-square" /> <span class="clear-xsm">Editar</span>
<i class="fa-solid fa-pen-to-square" /> <span class="clear-xsm">{{ t('buttons.edit') }}</span>
</button>
</div>
</div>

View File

@@ -3,7 +3,8 @@
import { getDateMonthDay } from '../helpers/date_formats';
import { useCompanyStore } from '../stores/company';
import { useAuthStore } from '../stores/auth';
import { useI18n } from 'vue-i18n';
const props = defineProps({
user: {
type: Object,
@@ -16,26 +17,27 @@
}
})
defineEmits(['set-user'])
const companyStore = useCompanyStore();
const authStore = useAuthStore();
const { t } = useI18n()
const handleDelete = async() => {
Swal.fire({
title: 'Eliminación de usuario!',
text: '¿Estás seguro de eliminar este usuario?',
title: t('users.titleDel'),
text: t('users.textDel'),
icon: 'warning',
showCancelButton: true,
cancelButtonColor: "#d33",
confirmButtonText: 'Eliminar',
cancelButtonText: 'Cancelar',
confirmButtonText: t('buttons.delete'),
cancelButtonText: t('buttons.cancel'),
}).then(async(result) => {
if(result.isConfirmed) {
Swal.fire({
title: 'Por favor espere!',
html: 'Elimininando usuario...',// add html attribute if you want or remove
title: t('messages.loading'),
html: t('users.loadingDel') + '...',// add html attribute if you want or remove
allowOutsideClick: false,
didOpen: () => {
Swal.showLoading()
@@ -47,14 +49,14 @@
if(resp === 'success') {
Swal.fire({
title: "Usuario eliminado!",
text: "El usuario ha sido eliminado exitosamente.",
title: t('users.msgTitleDel'),
text: t('users.msgDel'),
icon: "success"
});
} else {
Swal.fire({
title: "No eliminado!",
text: "El usuario no se pudo eliminar, intente más tarde.",
title: t('users.msgTitleNotDel'),
text: t('users.msgNotDel'),
icon: "error"
});
}
@@ -68,30 +70,30 @@
<div class="card-fixed flex-column">
<div class="row">
<div class="col-lg-6 col-sm-12">
<p><span>Nombre de usuario:</span> {{user.first_name}} {{user.last_name}}</p>
<p v-if="user.employee_id"><span class="font-weight-bold mr-1">Número de registro:</span> {{user.employee_id}}</p>
<p><span>Rol del usuario: </span>{{user.job_role}}</p>
<p><span>Teléfono 1: </span>{{user.phone}}</p>
<p><span>{{ t('labels.names') }}:</span> {{user.first_name}} {{user.last_name}}</p>
<p v-if="user.employee_id"><span class="font-weight-bold mr-1">{{ t('labels.registryNumber') }}:</span> {{user.employee_id}}</p>
<p><span>{{ t('labels.userRole') }}: </span>{{user.job_role}}</p>
<p><span>{{ t('labels.phone1') }}: </span>{{user.phone}}</p>
<!-- <p><span>Teléfono 2: </span>{{user.phone2}}</p> -->
<p><span>Email: </span>{{user.email}}</p>
<p><span>{{ t('labels.email') }}: </span>{{user.email}}</p>
</div>
<div class="col-lg-6 col-sm-12" v-if="readonly">
<p><span>Segmento: </span>{{user.categories?.map((e) => e.name).join(', ')}}</p>
<p><span>Locaciones de carga por municipio: </span>{{user._user_city}}</p>
<p><span>Locaciones de carga por estado: </span>{{user._user_state}}</p>
<p v-if="user.company.truck_type"><span>Tipos de transporte que utiliza: </span> {{user._truck_type}}</p>
<p ><span>Información adicional del usuario: </span> {{user.user_description}}</p>
<p ><span>Miembro desde: </span>{{getDateMonthDay(user.createdAt)}}</p>
<p><span>{{ t('global.segments') }}: </span>{{user.categories?.map((e) => e.name).join(', ')}}</p>
<p><span>{{ t('labels.locationLoadCity') }}: </span>{{user._user_city}}</p>
<p><span>{{ t('labels.locationLoadState') }}: </span>{{user._user_state}}</p>
<p v-if="user.company.truck_type"><span>{{ t('labels.truckUsed') }}: </span> {{user._truck_type}}</p>
<p ><span>{{ t('labels.userInfo') }}: </span> {{user.user_description}}</p>
<p ><span>{{ t('labels.memberSince') }}: </span>{{getDateMonthDay(user.createdAt)}}</p>
<p v-if="readonly" ><span>Tipo de afiliación: </span> {{user.company.membership}}</p>
<p><span>Rol del usuario: </span>{{user.job_role}}</p>
<p><span>{{ t('labels.userRole') }}: </span>{{user.job_role}}</p>
</div>
<div class="col-lg-6 col-sm-12" v-else>
<p><span>Segmento: </span>{{user.categories?.map((e) => e.name).join(', ')}}</p>
<p><span>Locaciones de carga por municipio: </span>{{user.user_city?.join(', ')}}</p>
<p><span>Locaciones de carga por estado: </span>{{user.user_state?.join(', ')}}</p>
<p v-if="user.truck_type"><span>Tipos de transporte que utiliza: </span> {{user.truck_type?.join(', ')}}</p>
<p ><span>Información adicional del usuario: </span> {{user.user_description}}</p>
<p ><span>Miembro desde: </span>{{getDateMonthDay(user.createdAt)}}</p>
<p><span>{{ t('global.segments') }}: </span>{{user.categories?.map((e) => e.name).join(', ')}}</p>
<p><span>{{ t('labels.locationLoadCity') }}: </span>{{user.user_city?.join(', ')}}</p>
<p><span>{{ t('labels.locationLoadState') }}: </span>{{user.user_state?.join(', ')}}</p>
<p v-if="user.truck_type"><span>{{ t('labels.truckUsed') }}: </span> {{user.truck_type?.join(', ')}}</p>
<p ><span>{{ t('labels.userInfo') }}: </span> {{user.user_description}}</p>
<p ><span>{{ t('labels.memberSince') }}: </span>{{getDateMonthDay(user.createdAt)}}</p>
<p v-if="readonly" ><span>Tipo de afiliación: </span> {{user.company.membership}}</p>
</div>
</div>
@@ -101,11 +103,11 @@
data-toggle="modal"
data-target="#userModal"
@click="$emit('set-user')"
><i class="fa-solid fa-pen-to-square"></i> Editar</button>
><i class="fa-solid fa-pen-to-square"></i> {{ t('buttons.edit') }}</button>
<button
class="btn btn-dark radius-sm"
@click="handleDelete"
><i class="fa-solid fa-trash"></i> Eliminar</button>
><i class="fa-solid fa-trash"></i> {{ t('buttons.delete') }}</button>
</div>
</div>
</template>

View File

@@ -9,6 +9,7 @@
import { useAuthStore } from '../stores/auth';
import { useCompanyStore } from '../stores/company';
import Swal from 'sweetalert2';
import { useI18n } from 'vue-i18n';
const props = defineProps({
location: {
@@ -21,11 +22,12 @@
const authStore = useAuthStore();
const companyStore = useCompanyStore()
const { t } = useI18n()
const loading = ref(false);
const title = computed(() => {
return (props.location) ? 'Editar Locación' : 'Crear Locación';
return (props.location) ? t('directory.editLocation') : t('directory.createLocation');
});
const initState = {
@@ -167,7 +169,7 @@
:error="errors.branch_name"
/>
<CustomInput
label="Dirección(s)*"
label="Dirección*"
name="address"
v-model:field="locationForm.address"
:filled="false"
@@ -226,14 +228,14 @@
/>
</div>
<div class="mb-4 mt-3">
<label class="custom-label">Tipo de transporte que se necesita</label>
<label class="custom-label">Tipo de transporte</label>
<TruckTypes
v-model="locationForm.truck_type"
:multiple="true"
/>
</div>
<div class="d-flex flex-column">
<label class="custom-label" for="description">Información adicional del usuario:</label>
<label class="custom-label" for="description">Información adicional:</label>
<textarea
class="custom-input-light"
name="description"

View File

@@ -8,6 +8,7 @@
import { useAuthStore } from '../stores/auth';
import { useCompanyStore } from '../stores/company';
import Swal from 'sweetalert2';
import { useI18n } from 'vue-i18n';
const props = defineProps({
user: {
@@ -16,6 +17,7 @@
}
});
const { t } = useI18n();
onMounted(() => {
if(props.user) {
console.log(props.user)
@@ -73,7 +75,7 @@
const loading = ref(false);
const title = computed(() => {
return (props.user) ? 'Editar usuario' : 'Crear usuario';
return (props.user) ? t('labels.editUser') : t('labels.createUser');
});
defineEmits(['reset-user']);
@@ -106,22 +108,22 @@
}
let result = 'error';
let action = 'Creado';
let action = t('messages.createdUser');
loading.value = true;
if(props.user !== null) {
// Se actualiza
result = await companyStore.updateUserCompany(props.user._id, userData, dataUpdate);
action = 'actualizado';
action = t('messages.updatedUser');
} else {
// Se crea
result = await companyStore.createUserCompany(userData, dataUpdate);
action = 'creado';
action = t('messages.createdUser');
}
loading.value = false;
if(result === 'success') {
document.getElementById('btnCloseuserModal').click();
Swal.fire({
title: `<strong>Usuario ${action} con éxito!</strong>`,
title: `<strong>${action}</strong>`,
icon: 'success'
})
} else {
@@ -135,10 +137,10 @@
const validations = () => {
errors.value = {
name: userForm.name.length < 4 ? 'Ingrese nombre' : null,
last_name: userForm.last_name.length <= 1 ? 'Ingrese apellido' : null,
email: !validateEmail(userForm.email) ? 'Ingrese email valido' : null,
phone: userForm.phone.length < 10 ? 'Ingrese numero teléfonico valido' : null,
name: userForm.name.length < 4 ? t('errors.name') : null,
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,
};
}
</script>
@@ -160,21 +162,21 @@
<div class="modal-body form-content">
<form @submit.prevent="saveUser" autocomplete="off" method="post" ref="formRef">
<CustomInput
label="Nombre(s)*"
:label="t('labels.names') + '*'"
name="name"
v-model:field="userForm.name"
:filled="false"
:error="errors.name"
/>
<CustomInput
label="Apellido(s)*"
:label="t('labels.lastnames') + '*'"
name="lastname"
v-model:field="userForm.last_name"
:filled="false"
:error="errors.last_name"
/>
<CustomInput
label="Teléfono*"
:label="t('labels.phone') + '*'"
name="phone1"
type="number"
v-model:field="userForm.phone"
@@ -184,7 +186,7 @@
:error="errors.phone"
/>
<CustomInput
label="Correo electronico*"
:label="t('labels.email') + '*'"
name="email"
type="email"
v-model:field="userForm.email"
@@ -193,18 +195,18 @@
:error="errors.email"
/>
<div class="d-flex flex-column">
<label class="custom-label" for="role">Rol de usuario:</label>
<label class="custom-label" for="role">{{ t('labels.userRole') }}</label>
<select
class="custom-input-light"
name="role"
id="role"
v-model="userForm.job_role"
>
<option disabled value="">-- Seleccionar rol --</option>
<option disabled value="">-- {{ t('labels.selectedRol') }} --</option>
<!-- <option value="owner">Dueño</option> -->
<option value="manager">Gerente</option>
<option value="staff">Personal</option>
<option v-if="authStore.user?.permissions === 'role_carrier'" value="driver">Conductor</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>
</select>
</div>
<!-- <div class="mb-4 mt-3">
@@ -222,21 +224,21 @@
/>
</div> -->
<div class="mb-4 mt-3">
<label class="custom-label">Locaciones de carga por estado</label>
<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">Locaciones de carga por municipio</label>
<label class="custom-label">{{ t('labels.locationLoadCity') }}</label>
<Cities
v-model="userForm.user_city"
:multiple="true"
/>
</div>
<div class="d-flex flex-column">
<label class="custom-label" for="description">Información adicional del usuario:</label>
<label class="custom-label" for="description">{{ t('labels.userInfo') }}</label>
<textarea
class="custom-input-light"
name="description"
@@ -249,13 +251,13 @@
<div>
<i class="fa-solid fa-circle-info info"></i>
</div>
<span>Al crear un nuevo usuario, informa al beneficiario de la cuenta, que debe utilizar su correo electrónico para establecer una contraseña en la sección <span class="font-bold">Olvidé mi contraseña</span> y así poder iniciar sesión.</span>
<span v-html="t('messages.msgCreatedUser')"></span>
</div>
<div class="mt-4 text-center">
<Spiner v-if="loading"/>
<button
v-else
class="btn btn-dark" type="submit">Guardar</button>
class="btn btn-dark" type="submit">{{t('buttons.save')}}</button>
</div>
</form>
</div>
@@ -264,7 +266,7 @@
type="button"
class="btn btn-dark"
@click="$emit('reset-user')"
data-dismiss="modal">Cerrar</button>
data-dismiss="modal">{{t('buttons.close')}}</button>
</div>
</div>
</div>

View File

@@ -7,6 +7,7 @@
import Custominput from './CustomInput.vue';
import { useCompanyStore } from '../../stores/company';
import { useNotificationsStore } from '../../stores/notifications';
import { useI18n } from 'vue-i18n';
const companyStore = useCompanyStore()
const notifications = useNotificationsStore()
@@ -16,6 +17,7 @@
const companyStates = ref([]);
const companyCity = ref([]);
const companyTruckType = ref([]);
const { t } = useI18n()
onMounted(() => {
if(companyStore.company){
@@ -57,19 +59,19 @@
is_company: companyStore.company._id,
company_type: companyStore.company.company_type,
meta_data: companyStore.company.meta_data,
categories: company.segments.map((e) => e._id),
company_city: company.cities.map((e) => e.city_name),
company_state: company.states.map((e) => e.state_name),
categories: company.segments.map((e) => e),
// company_city: company.cities.map((e) => e.city_name),
// company_state: company.states.map((e) => e.state_name),
truck_type: company.truckTypes.map((e) => e.meta_value),
company_description: company.description
};
console.log( companyData )
// console.log( companyData )
const result = await companyStore.editCompany(companyData);
loading.value = false;
if(result === 'success') {
document.getElementById('btnCloseEditCompany').click();
notifications.show = true;
notifications.text = 'Empresa actualizada';
notifications.text = t('messages.updateCompany');
} else {
msgError.value === result;
clearMessages();
@@ -85,13 +87,13 @@
const validations = () => {
if(company.segments.length === 0) {
return 'Agregue al menos un segmento';
}else if(company.states.length === 0) {
return 'Agregue al menos un estado';
} else if( company.cities.length === 0) {
msgError.value = 'Agregue al menos una ciudad';
return t('errors.segments');
// }else if(company.states.length === 0) {
// return t('errors.states');
// } else if( company.cities.length === 0) {
// msgError.value = t('errors.cities');
} else if(company.truckTypes.length === 0){
msgError.value = 'Agregue al menos un tipo de camión';
msgError.value = t('errors.trucks');
} else {
return '';
}
@@ -106,7 +108,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">Editar Empresa</h2>
<h2 class="title mt-2 mb-3">{{ t('company.edit') }}</h2>
<button id="btnCloseEditCompany" type="button" class="close bg-white" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
@@ -115,7 +117,7 @@
<form @submit.prevent="handleSave" class="view-form">
<NotificationBadge :msg="msgError" v-if="msgError != ''"/>
<div class="mb-4 mt-3">
<label class="custom-label">Segmento de la empresa</label>
<label class="custom-label">{{ t('labels.segmentsCompany') }}</label>
<Segments
v-model="company.segments"
:multiple="true"
@@ -136,14 +138,14 @@
/>
</div> -->
<div class="mb-4">
<label class="custom-label">Tipo de transportes que utiliza</label>
<label class="custom-label">{{ t('labels.truckUsed') }}</label>
<TruckTypes
v-model="company.truckTypes"
:multiple="true"
/>
</div>
<Custominput
label="Descripción de la empresa:"
:label=" t('labels.infoCompany')"
type="text"
name="description"
:filled="false"
@@ -153,11 +155,11 @@
<input
v-else
type="submit"
value="Cuardar cambios" class="btn-primary-lg btn-lg-block my-4">
:value="t('buttons.save')" class="btn-primary-lg btn-lg-block my-4">
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-dark" data-dismiss="modal">Cerrar</button>
<button type="button" class="btn btn-dark" data-dismiss="modal">{{t('buttons.close')}}</button>
</div>
</div>
</div>

View File

@@ -1,6 +1,9 @@
<script setup>
import { useI18n } from 'vue-i18n';
import { useNotificationsStore } from '../../stores/notifications';
const notifications = useNotificationsStore();
const { t } = useI18n()
</script>
<template>
<div class="noty-fixed">
@@ -9,7 +12,7 @@
<i v-if="notifications.error === false" class="fa-regular fa-circle-check text-success icon-category"></i>
<i v-else class="fa-solid fa-circle-exclamation text-danger"></i>
<div>
<h4 class="noty-title">Notificación</h4>
<h4 class="noty-title">{{ t('global.notification') }}</h4>
<p class="noty-body">{{ notifications.text }}</p>
</div>
<i class="fa-solid fa-xmark close-icon" @click="notifications.show = false"></i>