fix: issues ux

This commit is contained in:
Alexandro Uc Santos
2024-03-02 18:34:14 -06:00
parent 1ab389605d
commit 6a54ed3dbe
14 changed files with 252 additions and 55 deletions

View File

@@ -85,6 +85,18 @@ body {
font-weight: 700;
}
.btn-primary-nav {
background-color: #FBBA33;
padding: 8px 16px;
color: #323030;
font-size: 1.1rem;
border: none;
text-decoration: none;
text-align: center;
border-radius: 8px;
font-weight: 700;
}
.btn-primary-sm:hover {
background-color: #e3a11e;
transition: background-color 300ms ease;

View File

@@ -164,7 +164,6 @@
Evidencias
</button>
<button
v-if="load.load_status !== 'Delivered'"
class="btn-primary-sm"
data-toggle="modal" data-target="#formLoadModal"
@click="openEditModal"

View File

@@ -25,16 +25,16 @@
onMounted(() => {
props.data.forEach(item => {
const index = dataMap.value.findIndex((e) => e.label === item);
if(index === -1) {
const index = dataMap.value.findIndex((e) => e.name?.toUpperCase() === item?.toUpperCase());
if(index === -1) { // Lo agrega
if(props.dataModel) {
const itemModel = props.dataModel.find((e) => e[props.targetFind] === item);
dataMap.value.push({
const itemModel = props.dataModel.find((e) => e[props.targetFind].toUpperCase() === item.toUpperCase());
const itemTem = {
label: (props.targetLabel) ? itemModel[props.targetLabel] : item,
data: 1,
...itemModel
})
};
dataMap.value.push(itemTem)
} else {
dataMap.value.push({
label: item,
@@ -42,11 +42,10 @@
color: 'green'
});
}
} else {
} else { // Lo actualiza
dataMap.value[index].data += 1;
}
});
chartData.value = {
labels: dataMap.value.map((e) => e.label),
datasets: [{

View File

@@ -25,11 +25,11 @@
<RouterLink
v-if="auth.user?.permissions.includes('role_carrier')"
active-class="router-link-active"
class="nav-link" :to="{name: 'search-loads'}">Cargas</RouterLink>
class="nav-link" :to="{name: 'search-loads'}"> <i class="fa-solid fa-truck-ramp-box me-1"></i> Cargas</RouterLink>
<RouterLink
v-if="auth.user?.permissions.includes('role_carrier')"
active-class="router-link-active"
class="nav-link" :to="{name: 'shippers'}">Embarcadores</RouterLink>
class="nav-link" :to="{name: 'shippers'}"><i class="fa-solid fa-book me-1"></i> Embarcadores</RouterLink>
</div>
</div>
</nav>
@@ -40,17 +40,21 @@
display: flex;
flex-direction: row;
justify-content: end;
align-items: center;
}
.custom-navbar {
display: block;
width: calc(100vw - 220px);
background-color: #FFF;
padding: 16px 0px;
}
.nav-options {
margin-left: 32px;
display: flex;
margin-left: 32px;
gap: 1rem;
margin-right: 32px;
}
.btn-menu {
@@ -59,8 +63,8 @@
.nav-link{
cursor: pointer;
color: #413f3c;
font-size: 1.2rem;
color: #FBBA33;
font-size: 1.3rem;
margin-right: 1.2rem;
font-weight: 500;
}
@@ -83,6 +87,18 @@
@media (max-width: 768px) {
.nav-options {
margin-left: 8px;
margin-right: 8px;
gap: 0.5rem;
}
.nav-link{
font-size: 1.1rem;
margin-right: 1.2rem;
font-weight: 500;
}
.custom-navbar {
width: 100vw !important;
}

View File

@@ -22,7 +22,9 @@
<nav id="sidebar">
<div class="sidebar-header">
<div class="logo">
<a href="https://etaviaporte.com/" target="_blank">
<img src="/images/logo-eta.png" alt="Eta viaporte" width="120">
</a>
</div>
<h2 class="my-4">COVO</h2>
<p><i class="fa-solid fa-user"></i> <span class="ms-2">{{ auth.user?.first_name + ' ' + auth.user?.last_name }}</span></p>
@@ -84,7 +86,7 @@
<i class="fa-solid fa-bullhorn" :class="[route.name === 'published-trucks' ? 'router-link-active' : '']"></i>
<RouterLink
active-class=""
class="nav-link" :to="{name: 'published-trucks'}">Publicaciones</RouterLink>
class="nav-link" :to="{name: 'published-trucks'}">Ofertas aceptadas</RouterLink>
</div>
</li>
<li :class="[route.name === 'calendar' ? 'bg-nav-active' : '']">

View File

@@ -1,12 +1,28 @@
import axios from "axios";
const baseUrl = import.meta.env.VITE_API_URL;
const accessToken = localStorage.getItem('access');
const api = axios.create({
baseURL: baseUrl,
headers: {
Authorization: 'Bearer ' + accessToken
},
baseURL: baseUrl
});
// Interceptar las solicitudes antes de enviarlas
api.interceptors.request.use(
(config) => {
// Obtener el token de acceso actualizado del localStorage
const accessToken = localStorage.getItem('access');
// Verificar si hay un token de acceso y agregarlo al encabezado de autorización
if (accessToken) {
config.headers.Authorization = `Bearer ${accessToken}`;
}
return config;
},
(error) => {
// Manejar errores de solicitud
return Promise.reject(error);
}
);
export default api;

9
src/lib/axiosPublic.js Normal file
View File

@@ -0,0 +1,9 @@
import axios from "axios";
const baseUrl = import.meta.env.VITE_API_URL;
const apiPublic = axios.create({
baseURL: baseUrl,
});
export default apiPublic;

View File

@@ -1,12 +1,10 @@
import api from "../lib/axios";
import apiPublic from "../lib//axiosPublic";
import {messagesError} from '../helpers/validations';
export const login = async(body) => {
try {
const endpoint = "/v1/account/authorize";
const {data} = await api.post(endpoint, body);
console.log(data);
console.log(data.accessToken);
const {data} = await apiPublic.post(endpoint, body);
if(data.accessToken !== null){
if(data.user.job_role !== 'driver'){
//TODO: Guardar token y datos del usuario
@@ -37,7 +35,7 @@ export const renewToken = async() => {
const session = localStorage.getItem('session');
try {
const endpoint = `/v1/account/authorize/${session}`;
const {data} = await api.get(endpoint);
const {data} = await apiPublic.get(endpoint);
console.log(data);
if(data.accessToken !== null){
return {
@@ -63,7 +61,7 @@ export const renewToken = async() => {
export const regiter = async(body) => {
try {
const endpoint = "/v1/account/signup";
const {data} = await api.post(endpoint, body);
const {data} = await apiPublic.post(endpoint, body);
return {
msg: 'success',
data
@@ -79,7 +77,7 @@ export const regiter = async(body) => {
export const regiterConfirm = async(body) => {
try {
const endpoint = "/v1/account/signup";
const {data} = await api.patch(endpoint, body);
const {data} = await apiPublic.patch(endpoint, body);
return {
msg: 'success',
data
@@ -103,7 +101,7 @@ export const regiterConfirm = async(body) => {
export const recoveryPassword = async(body) => {
try {
const endpoint = "/v1/account/recover";
const {data} = await api.post(endpoint, body);
const {data} = await apiPublic.post(endpoint, body);
return {
msg: 'success',
data
@@ -120,7 +118,7 @@ export const recoveryPassword = async(body) => {
export const recoveryPasswordConfirm = async(body) => {
try {
const endpoint = "/v1/account/recover";
const {data} = await api.patch(endpoint, body);
const {data} = await apiPublic.patch(endpoint, body);
return {
msg: 'success',
data

View File

@@ -5,6 +5,7 @@ import { renewToken } from '../services/auth';
import {useNotificationsStore} from './notifications';
import {useCompanyStore} from './company';
import { useLoadsStore } from "./loads";
import { useVehiclesStore } from "./vehicles";
export const useAuthStore = defineStore('auth', () => {
@@ -12,6 +13,7 @@ export const useAuthStore = defineStore('auth', () => {
const noty = useNotificationsStore();
const company = useCompanyStore();
const loadStore = useLoadsStore();
const vehiclesStore = useVehiclesStore();
const sesion = ref('')
const checking = ref(false);
const authStatus = ref('checking');
@@ -54,16 +56,20 @@ export const useAuthStore = defineStore('auth', () => {
});
const logout = () => {
console.log('logoo....');
sesion.value = '';
token.value = '';
company.clear();
localStorage.clear();
user.value = null;
console.log(company.company);
localStorage.removeItem('access');
localStorage.removeItem('id');
localStorage.removeItem('session');
sesion.value = '';
token.value = '';
user.value = null;
checking.value = false;
authStatus.value = 'checking'
company.clear();
loadStore.clear();
vehiclesStore.clear();
router.push({name: 'login'});
}

View File

@@ -139,15 +139,19 @@ export const useCompanyStore = defineStore('company', () => {
const clear = () => { //Cuando se cierra la sesion
company.value = null;
users.value = [];
drivers.value = [];
usersTotal.value = 0;
usersCurrentPage.value = 1;
drivers.value = [];
budgets.value = [];
proposals.value = [];
budgetsTotal.value = 0;
budgetsCurrentPage.value = 1;
locations.value = [];
locationsLoads.value = [];
locationsTotal.value = 0;
locationsCurrentPage.value = 1;
proposals.value = [];
proposalsTotal.value = 0;
proposalsCurrentPage.value = 1;
// companyid = null;
loading.value = false;
}

View File

@@ -6,6 +6,7 @@ export const useLoadsStore = defineStore('load', () => {
const currentLoad = ref(null);
const loads = ref([])
const loadsDashboard = ref([]);
const loadsTotal = ref(0)
const loadsCurrentPage = ref(1)
const proposalsOfLoads = ref([]);
@@ -13,6 +14,32 @@ export const useLoadsStore = defineStore('load', () => {
const openAttachmentsModal = ref(false);
const openProposalsModal = ref(false);
const getLoadsAll = async(reload = false) => {
const companyid = localStorage.getItem('id');
if(loadsDashboard.value.length <= 0 || reload) {
try {
const endpoint = `/loads?company=${companyid}`;
const {data} = await api.get(endpoint);
loadsDashboard.value = data.data;
} catch (error) {
loadsDashboard.value = [];
console.log(error);
}
}
}
const getProposalCompanyAll = async(reload = false) => {
const companyId = localStorage.getItem('id');
try {
if(loadsDashboard.value.length <= 0 || reload) {
const endpoint = `/proposals?carrier=${companyId}`;
const {data} = await api.get(endpoint);
loadsDashboard.value = data.data.map( (e) => e.load);
}
} catch (error) {
loadsDashboard.value = [];
}
}
const getCompanyLoads = async(filterQuery, reload = false) => {
const companyid = localStorage.getItem('id');
@@ -123,6 +150,9 @@ export const useLoadsStore = defineStore('load', () => {
const clear = () => {
currentLoad.value = null;
loads.value = [];
loadsDashboard.value = [];
loadsTotal.value = 0;
loadsCurrentPage.value = 1;
proposalsOfLoads.value = [];
openModalEdit.value = false;
openAttachmentsModal.value = false;
@@ -137,6 +167,9 @@ export const useLoadsStore = defineStore('load', () => {
openAttachmentsModal,
getProposalsOfLoads,
getCompanyLoads,
getLoadsAll,
getProposalCompanyAll,
loadsDashboard,
deleteLoad,
getLoad,
saveLoad,

View File

@@ -68,6 +68,11 @@ export const useVehiclesStore = defineStore('vehicles', () => {
}
}
const clear = () => {
vehicles.value = [];
vehiclesTotal.value = 0;
vehiclesCurrentPage.value = 1;
}
return {
@@ -77,6 +82,7 @@ export const useVehiclesStore = defineStore('vehicles', () => {
fetchVehicles,
createVehicleCompany,
updateVehicleCompany,
deleteVehicleCompany
deleteVehicleCompany,
clear
}
});

View File

@@ -6,7 +6,7 @@
import CardBudget from '../components/CardBudget.vue';
import CardEmpty from '../components/CardEmpty.vue';
import CreateBudgetModal from '../components/CreateBudgetModal.vue';
import Pagination from '../components/Pagination.vue';
import Pagination from '../components/Pagination.vue';
const companyStore = useCompanyStore();
const authStore = useAuthStore();

View File

@@ -3,16 +3,80 @@
import loadsType from '../data/loadsType.json';
import BarChartStatistics from '../components/BarChartStatistics.vue';
import DoughnutChartStatistics from '../components/DoughnutChartStatistics.vue';
import { useLoadsStore } from '../stores/loads';
import { onMounted, ref, watch } from 'vue';
import Spiner from '../components/ui/Spiner.vue';
import { useAuthStore } from '../stores/auth';
import { storeToRefs } from 'pinia';
const auth = useAuthStore();
const { checking, user } = storeToRefs(auth);
const loads = useLoadsStore();
const loading = ref(false);
const loadsData = ref([]);
const segmentsData = ref([]);
const cities = ref([]);
const states = ref([]);
const vehicles = ref([]);
const nOfLoads = ref(0);
onMounted(() => {
if(user.value) {
getData();
}
})
watch(user, async() => {
if(user.value) {
getData();
}
});
const getData = async() => {
loading.value = true;
if(user.value?.permissions?.includes("role_carrier")) {
await loads.getProposalCompanyAll();
} else {
await loads.getLoadsAll();
}
dataMap();
loading.value = false;
}
const dataMap = () => {
nOfLoads.value = loads.loadsDashboard.length;
loads.loadsDashboard.map((e) => {
if(e?.load_status) {
loadsData.value.push(e.load_status);
}
if(user.value?.permissions?.includes("role_shipper") && e?.categories) {
segmentsData.value.push(e?.categories[0].name)
}
if(user.value?.permissions?.includes("role_shipper") && e?.origin?.city) {
cities.value.push(e?.origin.city)
}
if(e?.origin?.state){
states.value.push(e?.origin.state)
}
if(e?.truck_type){
vehicles.value.push(e?.truck_type)
}
});
}
</script>
<template>
<h1 class="title my-4">Dashboard Administrativo</h1>
<div class="container-dashboard">
<div class="card-fixed card-dashboard">
<div class="card-fixed"
:class="[user?.permissions?.includes('role_shipper') ? 'card-dashboard' : 'card-dashboard-carrier']"
>
<h3>Total de cargas este mes</h3>
<div class="main-info">
35
{{ nOfLoads }}
<div class="indicator-text" style="color: green;">
<i class="fa-solid fa-arrow-up"></i>
<!-- <i class="fa-solid fa-arrow-down"></i> -->
@@ -21,22 +85,30 @@
</div>
</div>
<!-- <ChartLoad/> -->
<div class="card-fixed card-dashboard">
<div class="card-fixed"
:class="[user?.permissions?.includes('role_shipper') ? 'card-dashboard' : 'card-dashboard-carrier']"
>
<h3>Cargas activas</h3>
<div class="card-chart">
<Spiner v-if="loading"/>
<DoughnutChartStatistics
:data="['Published', 'Transit', 'Delivered', 'Published', 'Downloading', 'Loading']"
v-else
:data="loadsData"
:data-model="loadsType"
target-find="name"
target-label="status"
/>
</div>
</div>
<div class="card-fixed card-dashboard">
<div class="card-fixed"
:class="[user?.permissions?.includes('role_shipper') ? 'card-dashboard' : 'card-dashboard-carrier']"
v-if="user?.permissions?.includes('role_shipper')">
<h3>Segmentos más usados</h3>
<div class="card-chart">
<Spiner v-if="loading"/>
<DoughnutChartStatistics
:data="['Agricola', 'Agricola', 'Cemento', 'Agricola', 'Intermoadal', 'Agricola']"
v-else
:data="segmentsData"
:data-model="segments"
target-find="name"
/>
@@ -44,30 +116,42 @@
</div>
<!-- </div>
<div class="container-dashboard"> -->
<div class="card-fixed card-dashboard">
<div class="card-fixed"
:class="[user?.permissions?.includes('role_shipper') ? 'card-dashboard' : 'card-dashboard-carrier']"
>
<h3>Estados más usados</h3>
<div class="card-chart">
<Spiner v-if="loading"/>
<BarChartStatistics
label="Ciuades"
:data="['Yucatán', 'Guadalajara', 'Colima', 'Yucatán', 'Nuevo león', 'Yucatán', 'Guadalajara']"
v-else
label="Estados"
:data="states"
/>
</div>
</div>
<div class="card-fixed card-dashboard">
<div class="card-fixed"
:class="[user?.permissions?.includes('role_shipper') ? 'card-dashboard' : 'card-dashboard-carrier']"
v-if="user?.permissions?.includes('role_shipper')">
<h3>Ciudades más usadas</h3>
<div class="card-chart">
<Spiner v-if="loading"/>
<BarChartStatistics
label="Estados"
:data="['Mérida', 'Guadalajara', 'Colima', 'Guadalajara', 'Monterrey', 'Izamal', 'Mérida']"
v-else
label="Ciudades"
:data="cities"
/>
</div>
</div>
<div class="card-fixed card-dashboard">
<div class="card-fixed"
:class="[user?.permissions?.includes('role_shipper') ? 'card-dashboard' : 'card-dashboard-carrier']"
>
<h3>Tipo de transporte más usados</h3>
<div class="card-chart">
<Spiner v-if="loading"/>
<BarChartStatistics
v-else
label="Vehiculos"
:data="['FULL / DOBLE REMOLQUE', 'FULL', 'FULL / DOBLE REMOLQUE', 'FULL', 'FULL / DOBLE REMOLQUE', 'FULL', 'FULL / DOBLE REMOLQUE', 'Auto']"
:data="vehicles"
/>
</div>
</div>
@@ -92,8 +176,17 @@
flex-direction: column;
}
.card-dashboard-carrier {
width: 48%;
min-height: 300px;
max-height: 500px;
display: flex;
flex-direction: column;
}
.card-chart {
width: 100%;
/* max-height: 350px; */
/* max-width: 333px; */
display: flex;
flex-direction: column;
@@ -138,5 +231,9 @@
.card-dashboard {
width: 100%;
}
.card-dashboard-carrier {
width: 100%;
}
}
</style>