fix: resolve white screen crashes and restructure layout hierarchy
- Move NavBar from App.vue to layouts/default.vue to fix nested v-app/v-main - Replace VSkeletonLoader with v-progress-circular to avoid genStructure crash - Initialize payment_methods as [] and add fallback in v-select - Remove duplicate fetchClients call from mounted() - Add authStore.user check in admin route guard - Replace window.location.href with router.push for SPA navigation - Add !important to page-header gradient styles
This commit is contained in:
10
src/App.vue
10
src/App.vue
@@ -1,19 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-app>
|
<v-app>
|
||||||
<NavBar />
|
<router-view />
|
||||||
<v-main>
|
|
||||||
<router-view />
|
|
||||||
</v-main>
|
|
||||||
</v-app>
|
</v-app>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import NavBar from './components/NavBar.vue';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'App',
|
name: 'App',
|
||||||
components: {
|
|
||||||
NavBar,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -13,10 +13,15 @@
|
|||||||
|
|
||||||
<!-- Loading -->
|
<!-- Loading -->
|
||||||
<template v-if="loading">
|
<template v-if="loading">
|
||||||
<v-skeleton-loader
|
<v-sheet class="d-flex flex-column align-center justify-center pa-12 rounded-lg" elevation="2">
|
||||||
class="mb-4 rounded-lg"
|
<v-progress-circular
|
||||||
type="card-heading, list-item-two-line, list-item-two-line"
|
indeterminate
|
||||||
></v-skeleton-loader>
|
color="primary"
|
||||||
|
size="64"
|
||||||
|
width="6"
|
||||||
|
></v-progress-circular>
|
||||||
|
<p class="text-body-1 text-grey mt-4">Cargando datos...</p>
|
||||||
|
</v-sheet>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
@@ -246,7 +251,7 @@
|
|||||||
<v-row align="center">
|
<v-row align="center">
|
||||||
<v-col cols="12" md="6">
|
<v-col cols="12" md="6">
|
||||||
<v-select
|
<v-select
|
||||||
:items="payment_methods"
|
:items="payment_methods || []"
|
||||||
v-model="purchase.payment_method"
|
v-model="purchase.payment_method"
|
||||||
item-title="text"
|
item-title="text"
|
||||||
item-value="value"
|
item-value="value"
|
||||||
@@ -337,7 +342,7 @@
|
|||||||
show_alert_purchase: false,
|
show_alert_purchase: false,
|
||||||
client_search: '',
|
client_search: '',
|
||||||
product_search: '',
|
product_search: '',
|
||||||
payment_methods: null,
|
payment_methods: [],
|
||||||
purchase: {
|
purchase: {
|
||||||
date: this.getCurrentDate(),
|
date: this.getCurrentDate(),
|
||||||
customer: null,
|
customer: null,
|
||||||
@@ -471,15 +476,13 @@
|
|||||||
formatPrice(price) {
|
formatPrice(price) {
|
||||||
return new Intl.NumberFormat('es-CO', { style: 'currency', currency: 'COP', minimumFractionDigits: 0 }).format(price);
|
return new Intl.NumberFormat('es-CO', { style: 'currency', currency: 'COP', minimumFractionDigits: 0 }).format(price);
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
mounted() {
|
};
|
||||||
this.fetchClients();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
.page-header {
|
.page-header {
|
||||||
background: linear-gradient(135deg, #1565C0 0%, #0D47A1 100%);
|
background: linear-gradient(135deg, #1565C0 0%, #0D47A1 100%) !important;
|
||||||
|
color: white !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.product-line:nth-child(odd) {
|
.product-line:nth-child(odd) {
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-app>
|
<div>
|
||||||
|
<NavBar />
|
||||||
<v-main>
|
<v-main>
|
||||||
<router-view />
|
<router-view />
|
||||||
</v-main>
|
</v-main>
|
||||||
|
|
||||||
<AppFooter />
|
<AppFooter />
|
||||||
</v-app>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
//
|
import NavBar from '@/components/NavBar.vue';
|
||||||
|
import AppFooter from '@/components/AppFooter.vue';
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ router.beforeEach((to, from, next) => {
|
|||||||
|
|
||||||
if (requiresAuth && !isAuthenticated) {
|
if (requiresAuth && !isAuthenticated) {
|
||||||
next({ path: '/autenticarse', replace: true })
|
next({ path: '/autenticarse', replace: true })
|
||||||
} else if (requiresAdmin && !authStore.isAdmin) {
|
} else if (requiresAdmin && !authStore.isAdmin && authStore.user) {
|
||||||
next({ path: '/', replace: true })
|
next({ path: '/', replace: true })
|
||||||
} else {
|
} else {
|
||||||
next()
|
next()
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import AuthService from '@/services/auth';
|
import AuthService from '@/services/auth';
|
||||||
|
import router from '@/router';
|
||||||
|
|
||||||
const http = axios.create({
|
const http = axios.create({
|
||||||
baseURL: import.meta.env.VITE_DJANGO_BASE_URL,
|
baseURL: import.meta.env.VITE_DJANGO_BASE_URL,
|
||||||
@@ -32,7 +33,7 @@ http.interceptors.response.use(
|
|||||||
return http.request(originalRequest);
|
return http.request(originalRequest);
|
||||||
} catch (refreshError) {
|
} catch (refreshError) {
|
||||||
AuthService.logout();
|
AuthService.logout();
|
||||||
window.location.href = '/autenticarse';
|
router.push('/autenticarse');
|
||||||
return Promise.reject(refreshError);
|
return Promise.reject(refreshError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user