Add menu translations #82

Merged
jsegarra merged 10 commits from wbuezas/hedera-web-mindshore:feature/AddMenuTranslations into 4922-vueMigration 2024-09-09 20:19:32 +00:00
15 changed files with 466 additions and 145 deletions

View File

@ -44,6 +44,7 @@ const handleClick = () => {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow: hidden; overflow: hidden;
width: 100%;
* { * {
white-space: nowrap; white-space: nowrap;

View File

@ -40,25 +40,35 @@ export default {
] ]
}, },
of: 'de', of: 'de',
// Menu
home: 'Inici', // Sections titles
catalog: 'Catàleg', Home: 'Inici',
pendingOrders: 'Comandes pendents', Orders: 'Comandes',
confirmedOrders: 'Comandes confirmades', Ticket: `Detall de l'encarrec`,
invoices: 'Factures', 'Pending orders': 'Comandes pendents',
agencyPackages: 'Paquets per agència', 'Last orders': 'Comandes confirmades',
accountConfig: 'Configuració', Invoices: 'Factures',
addressesList: 'Adreces', Basket: 'Cistella',
addressDetails: 'Configuració', Catalog: 'Catàleg',
checkout: 'Configurar encàrrec', Administration: 'Administració',
controlPanel: 'Panell de control', 'Control panel': 'Panell de control',
adminConnections: 'Connexions', Users: 'Usuaris',
adminItems: 'Articles', Connections: 'Connexions',
adminVisits: 'Visites', Visits: 'Visites',
adminUsers: "Gestió d'usuaris", News: 'Notícies',
adminPhotos: 'Imatges', Photos: 'Imatges',
adminNews: 'Gestió de noticies', Images: 'Imatges',
adminNewsDetails: 'Afegir o editar notícia', Items: 'Articles',
Agencies: 'Agències',
Reports: 'Informes',
Configuration: 'Configuració',
Shelves: 'Prestatgeries',
Account: 'Compte',
Addresses: 'Adreces',
Confirm: 'Confirmar',
Checkout: `Configurar l'encarrec`,
'Address details': 'Configuració',
'Admin news details': `Afegir o editar notícia`,
// //
orderLoadedIntoBasket: 'Comanda carregada a la cistella!', orderLoadedIntoBasket: 'Comanda carregada a la cistella!',
loadAnOrder: loadAnOrder:
@ -69,5 +79,8 @@ export default {
remove: 'Esborrar', remove: 'Esborrar',
agency: 'Agència', agency: 'Agència',
noData: 'Sense dades', noData: 'Sense dades',
confirm: 'Confirmar' confirm: 'Confirmar',
delete: 'Esborrar',
confirmDelete: 'Estàs segur que vols esborrar la línia?',
emptyList: 'Llista buida'
}; };

View File

@ -53,25 +53,34 @@ export default {
] ]
}, },
// menu // Sections titles
home: 'Home', Home: 'Home',
catalog: 'Catalog', Orders: 'Orders',
pendingOrders: 'Pending orders', Ticket: 'Detalle del pedido',
confirmedOrders: 'Confirmed orders', 'Pending orders': 'Pending orders',
invoices: 'Invoices', 'Last orders': 'Confirmed orders',
agencyPackages: 'Bundles by agency', Invoices: 'Invoices',
accountConfig: 'Configuration', Basket: 'Basket',
addressesList: 'Addresses', Catalog: 'Catalog',
addressDetails: 'Configuration', Administration: 'Administration',
checkout: 'Configure order', 'Control panel': 'Control panel',
controlPanel: 'Control panel', Users: 'Users',
adminConnections: 'Connections', Connections: 'Connections',
adminItems: 'Items', Visits: 'Visits',
adminVisits: 'Visits', News: 'News',
adminUsers: 'User management', Photos: 'Images',
adminPhotos: 'Images', Images: 'Images',
adminNews: 'News management', Items: 'Items',
adminNewsDetails: 'Add or edit new', Agencies: 'Agencies',
Reports: 'Reports',
Configuration: 'Configuration',
Shelves: 'Shelves',
Account: 'Account',
Addresses: 'Addresses',
Confirm: 'Confirm',
Checkout: 'Configure order',
'Address details': 'Configuration',
'Admin news details': 'Add or edit new',
// //
orderLoadedIntoBasket: 'Order loaded into basket!', orderLoadedIntoBasket: 'Order loaded into basket!',
loadAnOrder: 'Please load a pending order to the cart or start a new one', loadAnOrder: 'Please load a pending order to the cart or start a new one',
@ -82,6 +91,9 @@ export default {
agency: 'Agency', agency: 'Agency',
noData: 'No data', noData: 'No data',
confirm: 'Confirm', confirm: 'Confirm',
delete: 'Delete',
confirmDelete: 'Are you sure you want to delete the line?',
emptyList: 'Empty list',
orders: 'Orders', orders: 'Orders',
order: 'Pending order', order: 'Pending order',

View File

@ -59,25 +59,34 @@ export default {
] ]
}, },
// Menu // Sections titles
home: 'Inicio', Home: 'Inicio',
catalog: 'Catálogo', Orders: 'Pedidos',
pendingOrders: 'Pedidos pendientes', Ticket: 'Pedido',
confirmedOrders: 'Pedidos confirmados', 'Pending orders': 'Pedidos pendientes',
invoices: 'Facturas', 'Last orders': 'Pedidos confirmados',
agencyPackages: 'Bultos por agencia', Invoices: 'Facturas',
accountConfig: 'Configuración', Basket: 'Cesta',
addressesList: 'Direcciones', Catalog: 'Catálogo',
addressDetails: 'Configuración', Administration: 'Administración',
checkout: 'Configurar pedido', 'Control panel': 'Panel de control',
controlPanel: 'Panel de control', Users: 'Usuarios',
adminConnections: 'Conexiones', Connections: 'Conexiones',
adminItems: 'Artículos', Visits: 'Visitas',
adminVisits: 'Visitas', News: 'Noticias',
adminUsers: 'Gestión de usuarios', Photos: 'Imágenes',
adminPhotos: 'Imágenes', Images: 'Imágenes',
adminNews: 'Gestión de noticias', Items: 'Artículos',
adminNewsDetails: 'Añadir o editar noticia', Agencies: 'Agencias',
Reports: 'Informes',
Configuration: 'Configuración',
Shelves: 'Estanterías',
Account: 'Cuenta',
Addresses: 'Direcciones',
Confirm: 'Confirmar',
Checkout: 'Configurar pedido',
'Address details': 'Configuración',
'Admin news details': 'Añadir o editar noticia',
// //
orderLoadedIntoBasket: '¡Pedido cargado en la cesta!', orderLoadedIntoBasket: '¡Pedido cargado en la cesta!',
loadAnOrder: loadAnOrder:
@ -89,6 +98,9 @@ export default {
agency: 'Agencia', agency: 'Agencia',
noData: 'Sin datos', noData: 'Sin datos',
confirm: 'Confirmar', confirm: 'Confirmar',
delete: 'Borrar',
confirmDelete: '¿Estás seguro de que quieres borrar la línea?',
emptyList: 'Lista vacía',
orders: 'Pedidos', orders: 'Pedidos',
order: 'Pedido pendiente', order: 'Pedido pendiente',

View File

@ -40,25 +40,35 @@ export default {
] ]
}, },
of: 'de', of: 'de',
// Menu
home: 'Accueil', // Sections titles
catalog: 'Catalogue', Home: 'Accueil',
pendingOrders: 'Commandes en attente', Orders: 'Commandes',
confirmedOrders: 'Commandes confirmées', Ticket: 'Détail de la commande',
invoices: 'Factures', 'Pending orders': 'Commandes en attente',
agencyPackages: 'Liste par agence', 'Last orders': 'Commandes confirmées',
accountConfig: 'Configuration', Invoices: 'Factures',
addressesList: 'Adresses', Basket: 'Panier',
addressDetails: 'Configuration', Catalog: 'Catalogue',
checkout: "Définissez l'ordre", Administration: 'Administration',
controlPanel: 'Panneau de configuration', 'Control panel': 'Panneau de configuration',
adminConnections: 'Connexions', Users: 'Utilisateurs',
adminItems: 'Articles', Connections: 'Connexions',
adminVisits: 'Visites', Visits: 'Visites',
adminUsers: 'Gestion des utilisateurs', News: 'Nouvelles',
adminPhotos: 'Images', Photos: 'Images',
adminNews: 'Gestion des nouvelles', Images: 'Images',
adminNewsDetails: 'Ajouter ou editer nouvelles', Items: 'Articles',
Agencies: 'Agences',
Reports: 'Rapports',
Configuration: 'Configuration',
Shelves: 'Étagères',
Account: 'Compte',
Addresses: 'Adresses',
Confirm: 'Confirmer',
Checkout: 'Configurer la commande',
'Address details': 'Configuration',
'Admin news details': 'Ajouter ou éditer une nouvelle',
// //
orderLoadedIntoBasket: 'Commande chargée dans le panier!', orderLoadedIntoBasket: 'Commande chargée dans le panier!',
loadAnOrder: loadAnOrder:
@ -69,5 +79,7 @@ export default {
remove: 'Effacer', remove: 'Effacer',
agency: 'Agence', agency: 'Agence',
noData: 'Aucune donnée', noData: 'Aucune donnée',
confirm: 'Confirmer' confirm: 'Confirmer',
delete: 'Effacer',
confirmDelete: 'Voulez-vous vraiment supprimer la ligne?'
}; };

View File

@ -40,26 +40,34 @@ export default {
] ]
}, },
of: 'de', of: 'de',
// Sections titles
// Menu Home: 'Início',
home: 'Principio', Orders: 'Pedidos',
catalog: 'Catálogo', Ticket: 'Detalhe do pedido',
pendingOrders: 'Pedidos pendentes', 'Pending orders': 'Pedidos pendentes',
confirmedOrders: 'Pedidos confirmados', 'Last orders': 'Pedidos confirmados',
invoices: 'Facturas', Invoices: 'Faturas',
agencyPackages: 'Bultos por agencia', Basket: 'Carrinho',
accountConfig: 'Configuração', Catalog: 'Catálogo',
addressesList: 'Moradas', Administration: 'Administração',
addressDetails: 'Configuração', 'Control panel': 'Painel de controle',
checkout: 'Configurar encomenda', Users: 'Usuários',
controlPanel: 'Painel de controle', Connections: 'Conexões',
adminConnections: 'Conexões', Visits: 'Visitas',
adminItems: 'Artigos', News: 'Notícias',
adminVisits: 'Visitas', Photos: 'Imagens',
adminUsers: 'Gestão de usuários', Images: 'Imagens',
adminPhotos: 'Imagens', Items: 'Artigos',
adminNews: 'Gestão de notícias', Agencies: 'Agências',
adminNewsDetails: 'Ajouter ou editer nouvelles', Reports: 'Informes',
Configuration: 'Configuração',
Shelves: 'Estantes',
Account: 'Conta',
Addresses: 'Moradas',
Confirm: 'Confirme',
Checkout: 'Configurar encomenda',
'Address details': 'Configuração',
'Admin news details': 'Adicionar ou editar notícia',
// //
orderLoadedIntoBasket: 'Pedido carregado na cesta!', orderLoadedIntoBasket: 'Pedido carregado na cesta!',
loadAnOrder: 'Carregue um pedido pendente no carrinho ou inicie um novo', loadAnOrder: 'Carregue um pedido pendente no carrinho ou inicie um novo',
@ -69,5 +77,7 @@ export default {
remove: 'Eliminar', remove: 'Eliminar',
agency: 'Agência', agency: 'Agência',
noData: 'Sem dados', noData: 'Sem dados',
confirm: 'Confirme' confirm: 'Confirme',
delete: 'Eliminar',
confirmDelete: 'Tens certeza que queres eliminar esta linha?'
}; };

View File

@ -95,12 +95,12 @@ const logoutSupplantedUser = async () => {
<QList v-for="item in menuEssentialLinks" :key="item.id"> <QList v-for="item in menuEssentialLinks" :key="item.id">
<QItem v-if="!item.childs" :to="`/${item.path}`"> <QItem v-if="!item.childs" :to="`/${item.path}`">
<QItemSection> <QItemSection>
<QItemLabel>{{ item.description }}</QItemLabel> <QItemLabel>{{ $t(item.description) }}</QItemLabel>
</QItemSection> </QItemSection>
</QItem> </QItem>
<QExpansionItem <QExpansionItem
v-if="item.childs" v-if="item.childs"
:label="item.description" :label="$t(item.description)"
expand-separator expand-separator
> >
<QList> <QList>
@ -112,7 +112,7 @@ const logoutSupplantedUser = async () => {
> >
<QItemSection> <QItemSection>
<QItemLabel> <QItemLabel>
{{ subitem.description }} {{ $t(subitem.description) }}
</QItemLabel> </QItemLabel>
</QItemSection> </QItemSection>
</QItem> </QItem>

View File

@ -1,7 +1,7 @@
import { i18n } from 'src/boot/i18n'; import { i18n } from 'src/boot/i18n';
import { date as qdate, format } from 'quasar'; import { date as qdate, format } from 'quasar';
const { pad } = format;
import { useAppStore } from 'stores/app'; import { useAppStore } from 'stores/app';
const { pad } = format;
export function currency(val) { export function currency(val) {
return typeof val === 'number' ? val.toFixed(2) + '€' : val; return typeof val === 'number' ? val.toFixed(2) + '€' : val;
@ -18,7 +18,6 @@ export function date(val, format = 'YYYY-MM-DD') {
export const formatDate = (timeStamp, format = 'YYYY-MM-DD') => { export const formatDate = (timeStamp, format = 'YYYY-MM-DD') => {
if (!timeStamp) return ''; if (!timeStamp) return '';
const appStore = useAppStore(); const appStore = useAppStore();
return qdate.formatDate(timeStamp, format, appStore.localeDates); return qdate.formatDate(timeStamp, format, appStore.localeDates);
}; };

View File

@ -1,14 +1,153 @@
<script setup> <script setup>
import { onBeforeMount } from 'vue'; import { onBeforeMount, ref, inject, onMounted } from 'vue';
import { useI18n } from 'vue-i18n';
import { useAppStore } from 'stores/app'; import { useAppStore } from 'stores/app';
import TicketDetails from 'src/pages/Ecomerce/TicketDetails.vue';
import { storeToRefs } from 'pinia';
import { useRoute } from 'vue-router';
const jApi = inject('jApi');
const { t } = useI18n();
const appStore = useAppStore(); const appStore = useAppStore();
const route = useRoute();
const { basketOrderId, isHeaderMounted } = storeToRefs(appStore);
const rows = ref([]);
const ticket = ref({});
const orderId = ref(null);
onBeforeMount(() => { onBeforeMount(() => {
appStore.check(); appStore.check();
}); });
onMounted(async () => {
orderId.value = route.params.id || basketOrderId.value;
if (orderId.value) await fetchData();
});
const getOrder = async () => {
try {
const [data] = await jApi.query(
`SELECT o.id, o.sent,
ag.description agency, v.code method,
ad.nickname, ad.postalCode, ad.city, ad.street
FROM myOrder o
JOIN vn.agencyMode ag ON ag.id = o.agencyModeFk
LEFT JOIN myAddress ad ON ad.id = o.addressFk
JOIN vn.deliveryMethod v ON v.id = o.deliveryMethodFk
WHERE o.id = #id;`,
{ id: orderId.value }
);
const { sent, method, agency, id, nickname, street, postalCode, city } =
data;
const taxBase = rows.value.reduce(
(acc, row) => acc + row.price * row.quantity,
0
);
const formattedData = {
id,
landed: new Date(sent),
agency,
method,
nickname,
street,
postalCode,
city,
taxBase
};
ticket.value = formattedData;
} catch (error) {
console.error(error);
}
};
const getItems = async () => {
try {
const data = await jApi.query(
`SELECT bi.id, bi.amount, bi.price, i.longName item,
i.tag5, i.value5, i.tag6, i.value6, i.tag7, i.value7,
i.image, im.updated
FROM myOrderRow bi
JOIN vn.item i ON i.id = bi.itemFk
LEFT JOIN image im
ON im.collectionFk = 'catalog'
AND im.name = i.image
jsegarra marked this conversation as resolved
Review

entiendo que hacemos esta asignación extra durante la fase de desarrollo para visualizar los datos, pero quizas nos la podemos cargar.
Idem para la linea 50

entiendo que hacemos esta asignación extra durante la fase de desarrollo para visualizar los datos, pero quizas nos la podemos cargar. Idem para la linea 50
Review

Esto pertenece a la otra PR

Esto pertenece a la otra PR
WHERE orderFk = #id`,
{ id: orderId.value }
);
const formattedData = data.map(i => {
const { amount: quantity, ...item } = i;
const formattedItem = {
quantity,
...item
};
return formattedItem;
});
rows.value = formattedData;
} catch (error) {
console.error(error);
}
};
const fetchData = async () => {
await getItems();
await getOrder();
};
</script> </script>
<template> <template>
<div>basket view</div> <Teleport v-if="isHeaderMounted" to="#actions">
<QBtn
icon="settings"
:label="t('configureOrder')"
:to="{ name: 'checkout', params: { id: orderId } }"
rounded
no-caps
/>
<QBtn
icon="shopping_bag"
:label="t('catalog')"
:to="{ name: 'catalog' }"
rounded
no-caps
/>
<QBtn
icon="shopping_cart_checkout"
:label="t('checkout')"
:to="{ name: 'confirm', params: { id: orderId } }"
rounded
no-caps
/>
</Teleport>
<QPage>
<TicketDetails
:rows="rows"
:ticket="ticket"
is-basket
:show-tax="false"
can-delete-items
@on-row-deleted="fetchData"
/>
</QPage>
</template> </template>
<i18n lang="yaml">
en-US:
configureOrder: Configure order
checkout: Checkout
es-ES:
configureOrder: Configurar pedido
checkout: Finalizar pedido
ca-ES:
configureOrder: Configurar encàrrec
checkout: Finalitzar comanda
fr-FR:
configureOrder: Définissez l'ordre
checkout: Finir la commande
pt-PT:
configureOrder: Configurar encomenda
checkout: Finalizar encomenda
</i18n>

View File

@ -278,6 +278,8 @@ onMounted(async () => {
today.value.setHours(0, 0, 0, 0); today.value.setHours(0, 0, 0, 0);
if (route.params.id) { if (route.params.id) {
notify(t('rememberReconfiguringImpact'), 'warning');
const [order] = await jApi.query( const [order] = await jApi.query(
`SELECT m.code deliveryMethod, o.sent, o.agencyModeFk, o.addressFk `SELECT m.code deliveryMethod, o.sent, o.agencyModeFk, o.addressFk
FROM myOrder o FROM myOrder o
@ -485,6 +487,7 @@ en-US:
pickup: Pickup pickup: Pickup
addressStepQuestion: Where do you want to receive the order? addressStepQuestion: Where do you want to receive the order?
addressStepQuestionPickup: To which address do you want to associate the order? (Optional) addressStepQuestionPickup: To which address do you want to associate the order? (Optional)
rememberReconfiguringImpact: Remember that if you reconfigure your order prices or quantities of your items may change
es-ES: es-ES:
receiveOrPickOrder: ¿Quieres recibir o recoger el pedido? receiveOrPickOrder: ¿Quieres recibir o recoger el pedido?
receiveOrder: Recibir en mi tienda receiveOrder: Recibir en mi tienda
@ -506,6 +509,7 @@ es-ES:
pickup: Recogida pickup: Recogida
addressStepQuestion: ¿Dónde quieres recibir el pedido? addressStepQuestion: ¿Dónde quieres recibir el pedido?
addressStepQuestionPickup: ¿A qué dirección quieres asociar el pedido? (Opcional) addressStepQuestionPickup: ¿A qué dirección quieres asociar el pedido? (Opcional)
rememberReconfiguringImpact: Recuerda que si vuelves a configurar el pedido los precios o cantidades de tus artículos podrían cambiar
ca-ES: ca-ES:
receiveOrPickOrder: Vols rebre o recollir la comanda? receiveOrPickOrder: Vols rebre o recollir la comanda?
receiveOrder: Rebre en mi tenda receiveOrder: Rebre en mi tenda
@ -527,6 +531,7 @@ ca-ES:
pickup: Recollida pickup: Recollida
addressStepQuestion: On vols rebre la comanda? addressStepQuestion: On vols rebre la comanda?
addressStepQuestionPickup: A què direcció vols associar la comanda? (Opcional) addressStepQuestionPickup: A què direcció vols associar la comanda? (Opcional)
rememberReconfiguringImpact: Recorda que si tornes a configurar la comanda els preus o quantitats dels teus articles podrien canviar
fr-FR: fr-FR:
receiveOrPickOrder: Voulez-vous recevoir ou récuperer l'ordre? receiveOrPickOrder: Voulez-vous recevoir ou récuperer l'ordre?
receiveOrder: Livraison à la boutique receiveOrder: Livraison à la boutique
@ -548,6 +553,7 @@ fr-FR:
pickup: Retrait pickup: Retrait
addressStepQuestion: Adresse livraison? addressStepQuestion: Adresse livraison?
addressStepQuestionPickup: À quelle adresse voulez-vous associer la commande? (Optionnel) addressStepQuestionPickup: À quelle adresse voulez-vous associer la commande? (Optionnel)
rememberReconfiguringImpact: Rappelez-vous que si jamais vous commandez des prix fixés ou les quantités de vos articles pourraient changer
pt-PT: pt-PT:
receiveOrPickOrder: Queres receber ou levantar a encomenda? receiveOrPickOrder: Queres receber ou levantar a encomenda?
receiveOrder: Receber na minha loja receiveOrder: Receber na minha loja
@ -569,4 +575,5 @@ pt-PT:
pickup: Recolhida pickup: Recolhida
addressStepQuestion: Onde queres receber a encomenda? addressStepQuestion: Onde queres receber a encomenda?
addressStepQuestionPickup: Para qual endereço deseja associar o pedido? (Opcional) addressStepQuestionPickup: Para qual endereço deseja associar o pedido? (Opcional)
rememberReconfiguringImpact: Lembre-se que si voltas a configurar a encomenda os preços ou quantidades de ítens poderíam variar
</i18n> </i18n>

View File

@ -0,0 +1 @@
<template>Confirm view</template>

View File

@ -63,7 +63,6 @@ const fetchInvoices = async () => {
LIMIT 100`, LIMIT 100`,
params params
); );
console.log(invoices.value);
}; };
onMounted(async () => { onMounted(async () => {

View File

@ -1,8 +1,12 @@
<script setup> <script setup>
import { inject } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { currency, formatDateTitle } from 'src/lib/filters.js';
import VnImg from 'src/components/ui/VnImg.vue'; import VnImg from 'src/components/ui/VnImg.vue';
import { currency, formatDateTitle } from 'src/lib/filters.js';
import { useVnConfirm } from 'src/composables/useVnConfirm.js';
defineProps({ defineProps({
ticket: { ticket: {
type: Object, type: Object,
@ -11,10 +15,21 @@ defineProps({
rows: { rows: {
type: Array, type: Array,
default: () => [] default: () => []
},
showTax: {
type: Boolean,
default: true
},
canDeleteItems: {
type: Boolean,
default: false
} }
}); });
const emit = defineEmits(['onRowDeleted']);
const jApi = inject('jApi');
const { t } = useI18n(); const { t } = useI18n();
const { openConfirmationModal } = useVnConfirm();
const lineDiscountSubtotal = line => { const lineDiscountSubtotal = line => {
return line.quantity * line.price; return line.quantity * line.price;
@ -22,31 +37,42 @@ const lineDiscountSubtotal = line => {
const lineSubtotal = line => const lineSubtotal = line =>
lineDiscountSubtotal(line) * ((100 - line.discount) / 100); lineDiscountSubtotal(line) * ((100 - line.discount) / 100);
const deleteRow = id => {
try {
jApi.execQuery(
`START TRANSACTION;
DELETE FROM hedera.myOrderRow WHERE ((id = #id));
COMMIT`,
{
id
}
);
emit('onRowDeleted');
} catch (error) {
console.error('Error deleting order item:', error);
}
};
</script> </script>
<template> <template>
<QCard <QCard class="vn-w-sm" style="padding: 32px">
class="vn-w-sm"
style="padding: 32px"
>
<QCardSection class="no-padding q-mb-md"> <QCardSection class="no-padding q-mb-md">
<div class="text-h6"> <div class="text-h6">#{{ ticket.id }}</div>
#{{ ticket.id }}
</div>
</QCardSection> </QCardSection>
<QCardSection class="no-padding q-mb-md q-gutter-y-xs"> <QCardSection class="no-padding q-mb-md q-gutter-y-xs">
<div class="text-subtitle1 text-bold"> <div class="text-subtitle1 text-bold">
{{ t('shippingInformation') }} {{ t('shippingInformation') }}
</div> </div>
<div> <div v-if="ticket.shipped">
{{ t('preparation') }} {{ t('preparation') }}
{{ formatDateTitle(ticket.shipped) }} {{ formatDateTitle(ticket.shipped) }}
</div> </div>
<div> <div v-if="ticket.landed">
{{ t('delivery') }} {{ t('delivery') }}
{{ formatDateTitle(ticket.landed) }} {{ formatDateTitle(ticket.landed) }}
</div> </div>
<div> <div v-if="ticket.method && ticket.agency">
{{ t(ticket.method != 'PICKUP' ? 'agency' : 'warehouse') }} {{ t(ticket.method != 'PICKUP' ? 'agency' : 'warehouse') }}
{{ ticket.agency }} {{ ticket.agency }}
</div> </div>
@ -58,9 +84,10 @@ const lineSubtotal = line =>
<div>{{ ticket.nickname }}</div> <div>{{ ticket.nickname }}</div>
<div>{{ ticket.street }}</div> <div>{{ ticket.street }}</div>
<div> <div>
{{ ticket.postalCode }} {{ ticket.city }} ({{ <span v-if="ticket.postalCode || ticket.city">
ticket.province {{ ticket.postalCode }}, {{ ticket.city }}
}}) </span>
<span v-if="ticket.province"> ({{ ticket.province }})</span>
</div> </div>
</QCardSection> </QCardSection>
<QCardSection <QCardSection
@ -69,16 +96,41 @@ const lineSubtotal = line =>
<span class="text-right"> <span class="text-right">
{{ t('total') }} {{ currency(ticket.taxBase) }} {{ t('total') }} {{ currency(ticket.taxBase) }}
</span> </span>
<span class="text-right"> <span v-if="showTax" class="text-right">
{{ t('totalTax') }} {{ currency(ticket.total) }} {{ t('totalTax') }} {{ currency(ticket.total) }}
</span> </span>
</QCardSection> </QCardSection>
<QSeparator inset /> <QSeparator inset />
<QList <div
v-for="row in rows" v-if="!rows.length"
:key="row.itemFk" class="row items-center justify-center q-pa-md"
style="margin-top: 32px"
> >
<QItem> <QIcon class="q-mr-md" name="block" size="sm" />
<span>{{ t('emptyList') }}</span>
</div>
<QList v-else v-for="(row, index) in rows" :key="index">
<QItem v-if="row">
<QItemSection v-if="canDeleteItems" avatar>
<QBtn
icon="delete"
rounded
no-caps
dense
flat
@click.stop="
openConfirmationModal(
null,
t('confirmDelete'),
() => deleteRow(row.id)
)
"
>
<QTooltip>
{{ t('delete') }}
</QTooltip>
</QBtn>
</QItemSection>
<QItemSection avatar> <QItemSection avatar>
<VnImg <VnImg
storage="catalog" storage="catalog"
@ -88,32 +140,28 @@ const lineSubtotal = line =>
/> />
</QItemSection> </QItemSection>
<QItemSection> <QItemSection>
<QItemLabel lines="1"> <QItemLabel v-if="row.concept" lines="1">
{{ row.concept }} {{ row.concept }}
</QItemLabel> </QItemLabel>
<QItemLabel <QItemLabel v-if="row.item" lines="1">
lines="1" {{ row.item }}
caption </QItemLabel>
> <QItemLabel lines="1" caption>
{{ row.value5 }} {{ row.value6 }} {{ row.value7 }} {{ row.value5 }} {{ row.value6 }} {{ row.value7 }}
</QItemLabel> </QItemLabel>
<QItemLabel lines="1"> <QItemLabel lines="1">
{{ row.quantity }} x {{ currency(row.price) }} {{ row.quantity }} x
{{ currency(row.price) }}
</QItemLabel> </QItemLabel>
</QItemSection> </QItemSection>
<QItemSection <QItemSection side class="total">
side
class="total"
>
<QItemLabel> <QItemLabel>
<span <span> {{ currency(lineDiscountSubtotal(row)) }}</span>
class="discount" <span class="discount" v-if="row.discount">
v-if="row.discount" -
>
{{ currency(lineDiscountSubtotal(row)) }} -
{{ currency(row.discount) }} = {{ currency(row.discount) }} =
{{ currency(lineSubtotal(row)) }}
</span> </span>
{{ currency(lineSubtotal(row)) }}
</QItemLabel> </QItemLabel>
</QItemSection> </QItemSection>
</QItem> </QItem>

View File

@ -22,8 +22,8 @@ export default route(function (/* { store, ssrContext } */) {
const createHistory = process.env.SERVER const createHistory = process.env.SERVER
? createMemoryHistory ? createMemoryHistory
: process.env.VUE_ROUTER_MODE === 'history' : process.env.VUE_ROUTER_MODE === 'history'
? createWebHistory ? createWebHistory
: createWebHashHistory; : createWebHashHistory;
const Router = createRouter({ const Router = createRouter({
scrollBehavior: () => ({ left: 0, top: 0 }), scrollBehavior: () => ({ left: 0, top: 0 }),
@ -41,7 +41,7 @@ export default route(function (/* { store, ssrContext } */) {
if (from.name === to.name) return; if (from.name === to.name) return;
const app = useAppStore(); const app = useAppStore();
app.$patch({ app.$patch({
title: i18n.global.t(to.name || 'home'), title: i18n.global.t(to.meta.title || 'home'),
subtitle: null, subtitle: null,
useRightDrawer: false, useRightDrawer: false,
rightDrawerOpen: true rightDrawerOpen: true

View File

@ -32,101 +32,169 @@ const routes = [
{ {
name: 'home', name: 'home',
path: '/cms/home', path: '/cms/home',
meta: {
title: 'Home'
},
component: () => import('src/pages/Cms/HomeView.vue') component: () => import('src/pages/Cms/HomeView.vue')
}, },
{ {
name: 'confirmedOrders', name: 'confirmedOrders',
path: '/ecomerce/orders', path: '/ecomerce/orders',
meta: {
title: 'Last orders'
},
component: () => import('pages/Ecomerce/OrdersView.vue') component: () => import('pages/Ecomerce/OrdersView.vue')
}, },
{ {
name: 'ticket', name: 'ticket',
path: '/ecomerce/ticket/:id', path: '/ecomerce/ticket/:id',
meta: {
title: 'Ticket'
},
component: () => import('pages/Ecomerce/TicketView.vue') component: () => import('pages/Ecomerce/TicketView.vue')
}, },
{ {
name: 'invoices', name: 'invoices',
path: '/ecomerce/invoices', path: '/ecomerce/invoices',
meta: {
title: 'Invoices'
},
component: () => import('pages/Ecomerce/InvoicesView.vue') component: () => import('pages/Ecomerce/InvoicesView.vue')
}, },
{ {
name: 'pendingOrders', name: 'pendingOrders',
path: '/ecomerce/pending', path: '/ecomerce/pending',
meta: {
title: 'Pending orders'
},
component: () => import('pages/Ecomerce/PendingOrders.vue') component: () => import('pages/Ecomerce/PendingOrders.vue')
}, },
{ {
name: 'catalog', name: 'catalog',
path: '/ecomerce/catalog/:category?/:type?', path: '/ecomerce/catalog/:category?/:type?',
meta: {
title: 'Catalog'
},
component: () => import('pages/Ecomerce/Catalog.vue') component: () => import('pages/Ecomerce/Catalog.vue')
}, },
{ {
name: 'basket', name: 'basket',
path: '/ecomerce/basket/:id?', path: '/ecomerce/basket/:id?',
meta: {
title: 'Basket'
},
component: () => import('pages/Ecomerce/BasketView.vue') component: () => import('pages/Ecomerce/BasketView.vue')
}, },
{
name: 'confirm',
path: '/ecomerce/confirm/:id?',
meta: {
title: 'Confirm'
},
component: () => import('pages/Ecomerce/ConfirmView.vue')
},
{ {
name: 'checkout', name: 'checkout',
path: '/ecomerce/checkout/:id?', path: '/ecomerce/checkout/:id?',
meta: {
title: 'Checkout'
},
component: () => import('pages/Ecomerce/CheckoutView.vue') component: () => import('pages/Ecomerce/CheckoutView.vue')
}, },
{ {
name: 'agencyPackages', name: 'agencyPackages',
path: '/agencies/packages', path: '/agencies/packages',
meta: {
title: 'Agencies'
},
component: () => import('src/pages/Agencies/PackagesView.vue') component: () => import('src/pages/Agencies/PackagesView.vue')
}, },
{ {
name: 'accountConfig', name: 'accountConfig',
path: '/account/conf', path: '/account/conf',
meta: {
title: 'Account'
},
component: () => import('pages/Account/AccountConfig.vue') component: () => import('pages/Account/AccountConfig.vue')
}, },
{ {
name: 'addressesList', name: 'addressesList',
path: '/account/address-list', path: '/account/address-list',
meta: {
title: 'Addresses'
},
component: () => import('pages/Account/AddressList.vue') component: () => import('pages/Account/AddressList.vue')
}, },
{ {
name: 'addressDetails', name: 'addressDetails',
path: '/account/address/:id?', path: '/account/address/:id?',
meta: {
title: 'Address details'
},
component: () => import('pages/Account/AddressDetails.vue') component: () => import('pages/Account/AddressDetails.vue')
}, },
{ {
name: 'controlPanel', name: 'controlPanel',
path: 'admin/links', path: 'admin/links',
meta: {
title: 'Control panel'
},
component: () => import('pages/Admin/LinksView.vue') component: () => import('pages/Admin/LinksView.vue')
}, },
{ {
name: 'adminUsers', name: 'adminUsers',
path: 'admin/users', path: 'admin/users',
meta: {
title: 'Users'
},
component: () => import('pages/Admin/UsersView.vue') component: () => import('pages/Admin/UsersView.vue')
}, },
{ {
name: 'adminConnections', name: 'adminConnections',
path: 'admin/connections', path: 'admin/connections',
meta: {
title: 'Connections'
},
component: () => import('pages/Admin/ConnectionsView.vue') component: () => import('pages/Admin/ConnectionsView.vue')
}, },
{ {
name: 'adminVisits', name: 'adminVisits',
path: 'admin/visits', path: 'admin/visits',
meta: {
title: 'Visits'
},
component: () => import('pages/Admin/VisitsView.vue') component: () => import('pages/Admin/VisitsView.vue')
}, },
{ {
name: 'adminNews', name: 'adminNews',
path: 'news/news', path: 'news/news',
meta: {
title: 'News'
},
component: () => import('pages/Admin/NewsView.vue') component: () => import('pages/Admin/NewsView.vue')
}, },
{ {
name: 'adminNewsDetails', name: 'adminNewsDetails',
path: 'news/new/:id?', path: 'news/new/:id?',
meta: {
title: 'Admin news details'
},
component: () => import('pages/Admin/NewsDetails.vue') component: () => import('pages/Admin/NewsDetails.vue')
}, },
{ {
name: 'adminPhotos', name: 'adminPhotos',
path: 'admin/photos', path: 'admin/photos',
meta: {
title: 'Photos'
},
component: () => import('pages/Admin/PhotosView.vue') component: () => import('pages/Admin/PhotosView.vue')
}, },
{ {
name: 'adminItems', name: 'adminItems',
path: 'admin/items', path: 'admin/items',
meta: {
title: 'Items'
},
component: () => import('pages/Admin/ItemsView.vue') component: () => import('pages/Admin/ItemsView.vue')
} }
] ]