#7750 - first-beta-review #95
19
README.md
19
README.md
|
@ -6,31 +6,30 @@ Hedera is the main web page for Verdnatura.
|
||||||
|
|
||||||
Required dependencies.
|
Required dependencies.
|
||||||
|
|
||||||
* PHP >= 7.0
|
- PHP >= 7.0
|
||||||
* Node.js >= 18.0
|
- Node.js >= 18.0
|
||||||
|
|
||||||
Launch application for development.
|
Launch application for development.
|
||||||
|
|
||||||
```
|
```
|
||||||
$ quasar dev
|
$ quasar dev
|
||||||
```
|
```
|
||||||
|
|
||||||
Launch Salix backend.
|
Launch Salix backend.
|
||||||
```
|
|
||||||
npm run salix
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Launch legacy PHP backend.
|
pnpm run back
|
||||||
```
|
|
||||||
npm run back
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Run server side method from command line.
|
Run server side method from command line.
|
||||||
|
|
||||||
```
|
```
|
||||||
php hedera-web.php -m method_path
|
php hedera-web.php -m method_path
|
||||||
```
|
```
|
||||||
|
|
||||||
## Built with
|
## Built with
|
||||||
|
|
||||||
* [Webpack](https://webpack.js.org/)
|
- [Webpack](https://webpack.js.org/)
|
||||||
* [MooTools](https://mootools.net/)
|
- [MooTools](https://mootools.net/)
|
||||||
* [TinyMCE](https://www.tinymce.com/)
|
- [TinyMCE](https://www.tinymce.com/)
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { Connection } from '../js/db/connection';
|
||||||
import { useUserStore } from 'stores/user';
|
import { useUserStore } from 'stores/user';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import useNotify from 'src/composables/useNotify.js';
|
import useNotify from 'src/composables/useNotify.js';
|
||||||
|
import { useAppStore } from 'src/stores/app';
|
||||||
|
|
||||||
const { notify } = useNotify();
|
const { notify } = useNotify();
|
||||||
// Be careful when using SSR for cross-request state pollution
|
// Be careful when using SSR for cross-request state pollution
|
||||||
|
@ -37,9 +38,11 @@ const onResponseError = error => {
|
||||||
|
|
||||||
export default boot(({ app }) => {
|
export default boot(({ app }) => {
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
const appStore = useAppStore();
|
||||||
function addToken(config) {
|
function addToken(config) {
|
||||||
if (userStore.token) {
|
if (userStore.token) {
|
||||||
config.headers.Authorization = userStore.token;
|
config.headers.Authorization = userStore.token;
|
||||||
|
config.headers['Accept-Language'] = appStore.siteLang;
|
||||||
}
|
}
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,17 +129,20 @@ async function filterHandler(val, update) {
|
||||||
|
|
||||||
if (!$props.defaultFilter) return update();
|
if (!$props.defaultFilter) return update();
|
||||||
const newOptions = filter(val, myOptionsOriginal.value);
|
const newOptions = filter(val, myOptionsOriginal.value);
|
||||||
update(
|
|
||||||
() => {
|
setTimeout(() => {
|
||||||
myOptions.value = newOptions;
|
update(
|
||||||
},
|
() => {
|
||||||
ref => {
|
myOptions.value = newOptions;
|
||||||
if (val !== '' && ref.options.length > 0) {
|
},
|
||||||
ref.setOptionIndex(-1);
|
ref => {
|
||||||
ref.moveOptionSelection(1, true);
|
if (val !== '' && ref.options.length > 0) {
|
||||||
|
ref.setOptionIndex(-1);
|
||||||
|
ref.moveOptionSelection(1, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
);
|
}, 300);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -178,6 +181,13 @@ async function filterHandler(val, update) {
|
||||||
>
|
>
|
||||||
<slot :name="slotName" v-bind="slotData ?? {}" :key="slotName" />
|
<slot :name="slotName" v-bind="slotData ?? {}" :key="slotName" />
|
||||||
</template>
|
</template>
|
||||||
|
<template #no-option>
|
||||||
|
<QItem>
|
||||||
|
<QItemSection class="text-grey">
|
||||||
|
{{ t('emptyList') }}
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
</template>
|
||||||
</QSelect>
|
</QSelect>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -100,26 +100,21 @@ const onSubmit = async () => {
|
||||||
en-US:
|
en-US:
|
||||||
name: Name
|
name: Name
|
||||||
file: File
|
file: File
|
||||||
send: Send
|
|
||||||
imageAdded: Image added successfully
|
imageAdded: Image added successfully
|
||||||
es-ES:
|
es-ES:
|
||||||
name: Nombre
|
name: Nombre
|
||||||
file: Archivo
|
file: Archivo
|
||||||
send: Enviar
|
|
||||||
imageAdded: Imagen añadida correctamente
|
imageAdded: Imagen añadida correctamente
|
||||||
ca-ES:
|
ca-ES:
|
||||||
name: Nom
|
name: Nom
|
||||||
file: Arxiu
|
file: Arxiu
|
||||||
send: Enviar
|
|
||||||
imageAdded: Imatge afegida correctament
|
imageAdded: Imatge afegida correctament
|
||||||
fr-FR:
|
fr-FR:
|
||||||
name: Nom
|
name: Nom
|
||||||
file: Fichier
|
file: Fichier
|
||||||
send: Envoyer
|
|
||||||
imageAdded: Image ajoutée correctement
|
imageAdded: Image ajoutée correctement
|
||||||
pt-PT:
|
pt-PT:
|
||||||
name: Nome
|
name: Nome
|
||||||
file: Arquivo
|
file: Arquivo
|
||||||
send: Enviar
|
|
||||||
imageAdded: Imagen adicionada corretamente
|
imageAdded: Imagen adicionada corretamente
|
||||||
</i18n>
|
</i18n>
|
||||||
|
|
|
@ -67,6 +67,10 @@ const url = computed(() => {
|
||||||
return `${props.baseURL ?? app.imageUrl}/${props.storage}/${props.size}/${props.id}`;
|
return `${props.baseURL ?? app.imageUrl}/${props.storage}/${props.size}/${props.id}`;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const zoomUrl = computed(() => {
|
||||||
|
return `${props.baseURL ?? app.imageUrl}/${props.storage}/${props.zoomSize}/${props.id}`;
|
||||||
|
});
|
||||||
|
|
||||||
const rounded = computed(() => {
|
const rounded = computed(() => {
|
||||||
const roundedMap = {
|
const roundedMap = {
|
||||||
none: '',
|
none: '',
|
||||||
|
@ -114,7 +118,7 @@ const rounded = computed(() => {
|
||||||
|
|
||||||
<QDialog v-if="props.zoomSize" v-model="showZoom">
|
<QDialog v-if="props.zoomSize" v-model="showZoom">
|
||||||
<QImg
|
<QImg
|
||||||
:src="url"
|
:src="zoomUrl"
|
||||||
size="full"
|
size="full"
|
||||||
class="img_zoom"
|
class="img_zoom"
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
|
|
|
@ -6,10 +6,6 @@ defineProps({
|
||||||
type: String,
|
type: String,
|
||||||
default: 'emptyList'
|
default: 'emptyList'
|
||||||
},
|
},
|
||||||
emptyIcon: {
|
|
||||||
type: String,
|
|
||||||
default: 'block'
|
|
||||||
},
|
|
||||||
rows: {
|
rows: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => []
|
default: () => []
|
||||||
|
@ -29,7 +25,6 @@ const { t } = useI18n();
|
||||||
v-if="!rows?.length"
|
v-if="!rows?.length"
|
||||||
class="flex items-center q-pa-md justify-center items-center"
|
class="flex items-center q-pa-md justify-center items-center"
|
||||||
>
|
>
|
||||||
<QIcon :name="emptyIcon" size="sm" class="q-mr-sm" />
|
|
||||||
{{ t(emptyMessage) }}
|
{{ t(emptyMessage) }}
|
||||||
</span>
|
</span>
|
||||||
<QSpinner v-if="loading" color="primary" size="3em" :thickness="2" />
|
<QSpinner v-if="loading" color="primary" size="3em" :thickness="2" />
|
||||||
|
|
|
@ -40,6 +40,11 @@ const search = async () => {
|
||||||
query: searchTerm.value ? { search: searchTerm.value } : {}
|
query: searchTerm.value ? { search: searchTerm.value } : {}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!searchTerm.value) {
|
||||||
|
emit('onSearchError');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (props.sqlQuery) {
|
if (props.sqlQuery) {
|
||||||
data = await jApi.query(props.sqlQuery, {
|
data = await jApi.query(props.sqlQuery, {
|
||||||
[props.searchField]: searchTerm.value
|
[props.searchField]: searchTerm.value
|
||||||
|
|
|
@ -134,6 +134,7 @@ export default {
|
||||||
minQuantity: 'Quantitat mínima',
|
minQuantity: 'Quantitat mínima',
|
||||||
introduceSearchTerm: 'Introdueix un terme de cerca',
|
introduceSearchTerm: 'Introdueix un terme de cerca',
|
||||||
noOrdersFound: `No s'han trobat comandes`,
|
noOrdersFound: `No s'han trobat comandes`,
|
||||||
|
send: 'Enviar',
|
||||||
// Image related translations
|
// Image related translations
|
||||||
'Cant lock cache': 'No es pot bloquejar la memòria cau',
|
'Cant lock cache': 'No es pot bloquejar la memòria cau',
|
||||||
'Bad file format': 'Format de fitxer no reconegut',
|
'Bad file format': 'Format de fitxer no reconegut',
|
||||||
|
|
|
@ -168,6 +168,7 @@ export default {
|
||||||
minQuantity: 'Minimum quantity',
|
minQuantity: 'Minimum quantity',
|
||||||
introduceSearchTerm: 'Enter a search term',
|
introduceSearchTerm: 'Enter a search term',
|
||||||
noOrdersFound: 'No orders found',
|
noOrdersFound: 'No orders found',
|
||||||
|
send: 'Send',
|
||||||
// Image related translations
|
// Image related translations
|
||||||
'Cant lock cache': 'The cache could not be blocked',
|
'Cant lock cache': 'The cache could not be blocked',
|
||||||
'Bad file format': 'Unrecognized file format',
|
'Bad file format': 'Unrecognized file format',
|
||||||
|
|
|
@ -167,6 +167,7 @@ export default {
|
||||||
minQuantity: 'Cantidad mínima',
|
minQuantity: 'Cantidad mínima',
|
||||||
introduceSearchTerm: 'Introduce un término de búsqueda',
|
introduceSearchTerm: 'Introduce un término de búsqueda',
|
||||||
noOrdersFound: 'No se encontrado pedidos',
|
noOrdersFound: 'No se encontrado pedidos',
|
||||||
|
send: 'Enviar',
|
||||||
// Image related translations
|
// Image related translations
|
||||||
'Cant lock cache': 'La caché no pudo ser bloqueada',
|
'Cant lock cache': 'La caché no pudo ser bloqueada',
|
||||||
'Bad file format': 'Formato de archivo no reconocido',
|
'Bad file format': 'Formato de archivo no reconocido',
|
||||||
|
|
|
@ -135,6 +135,7 @@ export default {
|
||||||
minQuantity: 'Quantité minimum',
|
minQuantity: 'Quantité minimum',
|
||||||
introduceSearchTerm: 'Entrez un terme de recherche',
|
introduceSearchTerm: 'Entrez un terme de recherche',
|
||||||
noOrdersFound: 'Aucune commande trouvée',
|
noOrdersFound: 'Aucune commande trouvée',
|
||||||
|
send: 'Envoyer',
|
||||||
// Image related translations
|
// Image related translations
|
||||||
'Cant lock cache': "Le cache n'a pas pu être verrouillé",
|
'Cant lock cache': "Le cache n'a pas pu être verrouillé",
|
||||||
'Bad file format': 'Format de fichier non reconnu',
|
'Bad file format': 'Format de fichier non reconnu',
|
||||||
|
|
|
@ -133,6 +133,7 @@ export default {
|
||||||
minQuantity: 'Quantidade mínima',
|
minQuantity: 'Quantidade mínima',
|
||||||
introduceSearchTerm: 'Digite um termo de pesquisa',
|
introduceSearchTerm: 'Digite um termo de pesquisa',
|
||||||
noOrdersFound: 'Nenhum pedido encontrado',
|
noOrdersFound: 'Nenhum pedido encontrado',
|
||||||
|
send: 'Enviar',
|
||||||
// Image related translations
|
// Image related translations
|
||||||
'Cant lock cache': 'O cache não pôde ser bloqueado',
|
'Cant lock cache': 'O cache não pôde ser bloqueado',
|
||||||
'Bad file format': 'Formato de arquivo inválido',
|
'Bad file format': 'Formato de arquivo inválido',
|
||||||
|
|
|
@ -3,13 +3,11 @@
|
||||||
id="bg"
|
id="bg"
|
||||||
class="fullscreen row justify-center items-center layout-view scroll"
|
class="fullscreen row justify-center items-center layout-view scroll"
|
||||||
>
|
>
|
||||||
<div class="column q-pa-md row items-center justify-center">
|
<QPageContainer class="column q-pa-md row items-center justify-center">
|
||||||
<router-view v-slot="{ Component }">
|
<transition>
|
||||||
<transition>
|
<router-view />
|
||||||
<component :is="Component" />
|
</transition>
|
||||||
</transition>
|
</QPageContainer>
|
||||||
</router-view>
|
|
||||||
</div>
|
|
||||||
</QLayout>
|
</QLayout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ const logoutSupplantedUser = async () => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<QLayout view="hhh Lpr fFf">
|
<QLayout view="hhh LpR fFf">
|
||||||
<QHeader>
|
<QHeader>
|
||||||
<QToolbar>
|
<QToolbar>
|
||||||
<QBtn
|
<QBtn
|
||||||
|
@ -216,6 +216,10 @@ const logoutSupplantedUser = async () => {
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div .q-drawer-container {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
@include mobile {
|
@include mobile {
|
||||||
#actions {
|
#actions {
|
||||||
.q-btn {
|
.q-btn {
|
||||||
|
|
|
@ -109,12 +109,12 @@ const fetchData = async () => {
|
||||||
</QBtn>
|
</QBtn>
|
||||||
<QBtn
|
<QBtn
|
||||||
icon="shopping_bag"
|
icon="shopping_bag"
|
||||||
:label="t('catalog')"
|
:label="t('titles.Catalog')"
|
||||||
:to="{ name: 'catalog' }"
|
:to="{ name: 'catalog' }"
|
||||||
rounded
|
rounded
|
||||||
no-caps
|
no-caps
|
||||||
>
|
>
|
||||||
<QTooltip>{{ t('catalog') }}</QTooltip>
|
<QTooltip>{{ t('titles.Catalog') }}</QTooltip>
|
||||||
</QBtn>
|
</QBtn>
|
||||||
<QBtn
|
<QBtn
|
||||||
icon="shopping_cart_checkout"
|
icon="shopping_cart_checkout"
|
||||||
|
|
|
@ -25,8 +25,9 @@ const { t } = useI18n();
|
||||||
storage="catalog"
|
storage="catalog"
|
||||||
size="200x200"
|
size="200x200"
|
||||||
:id="item.image"
|
:id="item.image"
|
||||||
height="210px"
|
height="190px"
|
||||||
rounded="bottom"
|
rounded="bottom"
|
||||||
|
zoom-size="1600x900"
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class="column"
|
class="column"
|
||||||
|
@ -45,7 +46,7 @@ const { t } = useI18n();
|
||||||
</span>
|
</span>
|
||||||
<span> #{{ item.id }}</span>
|
<span> #{{ item.id }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="tags q-pt-xs text-caption">
|
<div class="tags text-caption">
|
||||||
<div
|
<div
|
||||||
v-for="(tag, index) in item.previewTags"
|
v-for="(tag, index) in item.previewTags"
|
||||||
:key="index"
|
:key="index"
|
||||||
|
@ -75,7 +76,7 @@ const { t } = useI18n();
|
||||||
<div class="row justify-between items-cente q-gutter-x-xs">
|
<div class="row justify-between items-cente q-gutter-x-xs">
|
||||||
<QBadge
|
<QBadge
|
||||||
:label="`x${item.grouping}`"
|
:label="`x${item.grouping}`"
|
||||||
color="grey"
|
color="grey-4"
|
||||||
class="col-2 justify-end text-body2"
|
class="col-2 justify-end text-body2"
|
||||||
>
|
>
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
|
@ -85,8 +86,7 @@ const { t } = useI18n();
|
||||||
<QBadge
|
<QBadge
|
||||||
outline
|
outline
|
||||||
:label="item.available"
|
:label="item.available"
|
||||||
color="accent"
|
color="grey-6"
|
||||||
text-color="black"
|
|
||||||
class="col justify-end text-body2"
|
class="col justify-end text-body2"
|
||||||
>
|
>
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
|
@ -97,7 +97,6 @@ const { t } = useI18n();
|
||||||
outline
|
outline
|
||||||
:label="currency(item.price)"
|
:label="currency(item.price)"
|
||||||
color="accent"
|
color="accent"
|
||||||
text-color="black"
|
|
||||||
class="col justify-end text-body2"
|
class="col justify-end text-body2"
|
||||||
>
|
>
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
|
@ -117,6 +116,7 @@ const { t } = useI18n();
|
||||||
height="105px"
|
height="105px"
|
||||||
rounded-borders="full"
|
rounded-borders="full"
|
||||||
class="q-mr-md"
|
class="q-mr-md"
|
||||||
|
zoom-size="1600x900"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #content>
|
<template #content>
|
||||||
|
@ -153,7 +153,8 @@ const { t } = useI18n();
|
||||||
<div class="row justify-end items-center q-gutter-x-xs q-mt-sm">
|
<div class="row justify-end items-center q-gutter-x-xs q-mt-sm">
|
||||||
<QBadge
|
<QBadge
|
||||||
:label="`x${item.grouping}`"
|
:label="`x${item.grouping}`"
|
||||||
color="grey"
|
color="grey-4"
|
||||||
|
text-color="black"
|
||||||
class="col-2 justify-end text-body2"
|
class="col-2 justify-end text-body2"
|
||||||
>
|
>
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
|
@ -163,8 +164,7 @@ const { t } = useI18n();
|
||||||
<QBadge
|
<QBadge
|
||||||
outline
|
outline
|
||||||
:label="item.available"
|
:label="item.available"
|
||||||
color="accent"
|
color="grey-6"
|
||||||
text-color="black"
|
|
||||||
class="col-3 justify-end text-body2"
|
class="col-3 justify-end text-body2"
|
||||||
>
|
>
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
|
@ -175,7 +175,6 @@ const { t } = useI18n();
|
||||||
outline
|
outline
|
||||||
:label="currency(item.price)"
|
:label="currency(item.price)"
|
||||||
color="accent"
|
color="accent"
|
||||||
text-color="black"
|
|
||||||
class="col-3 justify-end text-body2"
|
class="col-3 justify-end text-body2"
|
||||||
>
|
>
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
|
|
|
@ -1,7 +1,14 @@
|
||||||
<template>
|
<template>
|
||||||
<Teleport v-if="isHeaderMounted" to="#actions">
|
<Teleport v-if="isHeaderMounted" to="#actions">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<VnSearchBar :search-term="search" @on-search-error="items = []" />
|
<VnSearchBar
|
||||||
|
@on-search-error="
|
||||||
|
() => {
|
||||||
|
items = [];
|
||||||
|
search = '';
|
||||||
|
}
|
||||||
|
"
|
||||||
|
/>
|
||||||
<QBtn
|
<QBtn
|
||||||
:icon="viewTypeButtonContent.icon"
|
:icon="viewTypeButtonContent.icon"
|
||||||
:label="viewTypeButtonContent.label"
|
:label="viewTypeButtonContent.label"
|
||||||
|
@ -36,7 +43,7 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Teleport>
|
</Teleport>
|
||||||
<div style="padding-bottom: 5em">
|
<div>
|
||||||
<QDrawer v-model="rightDrawerOpen" side="right" :width="250" persistent>
|
<QDrawer v-model="rightDrawerOpen" side="right" :width="250" persistent>
|
||||||
<div class="q-pa-md">
|
<div class="q-pa-md">
|
||||||
<div class="basket-info q-gutter-y-sm">
|
<div class="basket-info q-gutter-y-sm">
|
||||||
|
@ -55,6 +62,9 @@
|
||||||
no-caps
|
no-caps
|
||||||
@click="redirectToCheckout()"
|
@click="redirectToCheckout()"
|
||||||
data-testid="orderModifyButton"
|
data-testid="orderModifyButton"
|
||||||
|
color="light-green-7"
|
||||||
|
unelevated
|
||||||
|
text-color="white"
|
||||||
>
|
>
|
||||||
{{ t('modify') }}
|
{{ t('modify') }}
|
||||||
</QBtn>
|
</QBtn>
|
||||||
|
@ -132,6 +142,12 @@
|
||||||
:disable="!category"
|
:disable="!category"
|
||||||
:label="t('category')"
|
:label="t('category')"
|
||||||
/>
|
/>
|
||||||
|
<div
|
||||||
|
v-if="isSomeFilterSelected"
|
||||||
|
class="q-mt-md text-grey-7"
|
||||||
|
>
|
||||||
|
{{ t('orderBy') }}
|
||||||
|
</div>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
v-if="isSomeFilterSelected"
|
v-if="isSomeFilterSelected"
|
||||||
v-model="selectedOrderBy"
|
v-model="selectedOrderBy"
|
||||||
|
@ -139,7 +155,7 @@
|
||||||
option-value="value"
|
option-value="value"
|
||||||
option-label="label"
|
option-label="label"
|
||||||
:is-clearable="false"
|
:is-clearable="false"
|
||||||
:label="t('orderBy')"
|
:label="t('sort')"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span
|
<span
|
||||||
|
@ -153,7 +169,7 @@
|
||||||
<div
|
<div
|
||||||
:class="
|
:class="
|
||||||
viewMode === 'grid'
|
viewMode === 'grid'
|
||||||
? 'q-pa-md row justify-center q-gutter-md'
|
? ' row justify-center q-gutter-md'
|
||||||
: 'column items-center'
|
: 'column items-center'
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
|
@ -167,7 +183,6 @@
|
||||||
v-else-if="!items || !items.length || !isSomeFilterSelected"
|
v-else-if="!items || !items.length || !isSomeFilterSelected"
|
||||||
class="text-subtitle1 text-grey-7 q-pa-md"
|
class="text-subtitle1 text-grey-7 q-pa-md"
|
||||||
>
|
>
|
||||||
<QIcon name="refresh" size="sm" class="q-mr-sm"></QIcon>
|
|
||||||
<span>{{ t('pleaseSetFilter') }}</span>
|
<span>{{ t('pleaseSetFilter') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<CatalogCard
|
<CatalogCard
|
||||||
|
@ -180,13 +195,13 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<QDialog v-model="showItemDialog" @hide="resetAmounts()">
|
<QDialog v-model="showItemDialog" @hide="resetAmounts()">
|
||||||
<QCard style="width: 25em" class="column">
|
<QCard v-if="selectedItem" style="width: 25em" class="column">
|
||||||
<div class="q-pa-md relative-position">
|
<div class="q-pa-md relative-position">
|
||||||
<div class="q-mb-md" style="display: flex">
|
<div class="q-mb-md" style="display: flex">
|
||||||
<VnImg
|
<VnImg
|
||||||
storage="catalog"
|
storage="catalog"
|
||||||
size="200x200"
|
size="200x200"
|
||||||
:id="'asd'"
|
:id="selectedItem.image"
|
||||||
width="112px"
|
width="112px"
|
||||||
height="112px"
|
height="112px"
|
||||||
rounded="bottom"
|
rounded="bottom"
|
||||||
|
@ -282,6 +297,7 @@
|
||||||
</QBtn>
|
</QBtn>
|
||||||
</div>
|
</div>
|
||||||
</QCard>
|
</QCard>
|
||||||
|
<QSpinner v-else color="primary" size="3em" :thickness="5" />
|
||||||
</QDialog>
|
</QDialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -744,7 +760,8 @@ const getSubcategories = async () => {
|
||||||
DROP TEMPORARY TABLE tmp.itemAvailable;`,
|
DROP TEMPORARY TABLE tmp.itemAvailable;`,
|
||||||
{ orderId: basketOrderId.value }
|
{ orderId: basketOrderId.value }
|
||||||
);
|
);
|
||||||
itemSubcategories.value = res.results[1].data;
|
const filtered = res.results[1].data.filter(item => item.category);
|
||||||
|
itemSubcategories.value = filtered.map(i => i.category);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error getting subcategories:', error);
|
console.error('Error getting subcategories:', error);
|
||||||
|
|||||||
}
|
}
|
||||||
|
@ -753,11 +770,13 @@ const getSubcategories = async () => {
|
||||||
const showItem = async item => {
|
const showItem = async item => {
|
||||||
if (checkGuest()) return;
|
if (checkGuest()) return;
|
||||||
|
|
||||||
const itemLots = await calcItem(item.id);
|
showItemDialog.value = true;
|
||||||
const tags = await getItemTags(item.id);
|
const [itemLots, tags] = await Promise.all([
|
||||||
|
calcItem(item.id),
|
||||||
|
getItemTags(item.id)
|
||||||
|
]);
|
||||||
item.lots = itemLots;
|
item.lots = itemLots;
|
||||||
item.tags = tags;
|
item.tags = tags;
|
||||||
showItemDialog.value = true;
|
|
||||||
selectedItem.value = item;
|
selectedItem.value = item;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -848,6 +867,7 @@ const onAddLotClick = async lot => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const resetAmounts = () => {
|
const resetAmounts = () => {
|
||||||
|
selectedItem.value = null;
|
||||||
addedItemsAmountAcc.value = {};
|
addedItemsAmountAcc.value = {};
|
||||||
amount.value = 0;
|
amount.value = 0;
|
||||||
};
|
};
|
||||||
|
@ -1031,6 +1051,8 @@ en-US:
|
||||||
filterBy: Filter by
|
filterBy: Filter by
|
||||||
chooseCategory: Choose a category
|
chooseCategory: Choose a category
|
||||||
youMustBeLoggedIn: You must be a registered user
|
youMustBeLoggedIn: You must be a registered user
|
||||||
|
sort: Order
|
||||||
|
amountNotAvailable: Amount not available
|
||||||
es-ES:
|
es-ES:
|
||||||
category: Categoría
|
category: Categoría
|
||||||
deleteFilter: Quitar filtro
|
deleteFilter: Quitar filtro
|
||||||
|
@ -1054,6 +1076,8 @@ es-ES:
|
||||||
filterBy: Filtrar por
|
filterBy: Filtrar por
|
||||||
chooseCategory: Elige una categoría
|
chooseCategory: Elige una categoría
|
||||||
youMustBeLoggedIn: Debes estar registrado como usuario
|
youMustBeLoggedIn: Debes estar registrado como usuario
|
||||||
|
sort: Ordenar
|
||||||
|
amountNotAvailable: Cantidad no disponible
|
||||||
ca-ES:
|
ca-ES:
|
||||||
category: Categoría
|
category: Categoría
|
||||||
deleteFilter: Eliminar filtro
|
deleteFilter: Eliminar filtro
|
||||||
|
@ -1075,6 +1099,8 @@ ca-ES:
|
||||||
filterBy: Filtrar per
|
filterBy: Filtrar per
|
||||||
chooseCategory: Tria una categoria
|
chooseCategory: Tria una categoria
|
||||||
youMustBeLoggedIn: Has d'estar registrat com a usuari
|
youMustBeLoggedIn: Has d'estar registrat com a usuari
|
||||||
|
sort: Ordenar
|
||||||
|
amountNotAvailable: Quantitat no disponible
|
||||||
fr-FR:
|
fr-FR:
|
||||||
category: Catégorie
|
category: Catégorie
|
||||||
deleteFilter: Supprimer le filtre
|
deleteFilter: Supprimer le filtre
|
||||||
|
@ -1096,6 +1122,8 @@ fr-FR:
|
||||||
filterBy: Filtrer par
|
filterBy: Filtrer par
|
||||||
chooseCategory: Choisissez une catégorie
|
chooseCategory: Choisissez une catégorie
|
||||||
youMustBeLoggedIn: Vous devez être un utilisateur enregistré
|
youMustBeLoggedIn: Vous devez être un utilisateur enregistré
|
||||||
|
sort: Trier
|
||||||
|
amountNotAvailable: Quantité non disponible
|
||||||
pt-PT:
|
pt-PT:
|
||||||
category: Categoria
|
category: Categoria
|
||||||
deleteFilter: Apagar filtro
|
deleteFilter: Apagar filtro
|
||||||
|
@ -1117,4 +1145,6 @@ pt-PT:
|
||||||
filterBy: Filtrar por
|
filterBy: Filtrar por
|
||||||
chooseCategory: Escolha uma categoria
|
chooseCategory: Escolha uma categoria
|
||||||
youMustBeLoggedIn: Deves estar registrado como usuario
|
youMustBeLoggedIn: Deves estar registrado como usuario
|
||||||
|
sort: Ordenar
|
||||||
|
amountNotAvailable: Quantidade não disponível
|
||||||
</i18n>
|
</i18n>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, inject, computed } from 'vue';
|
import { ref, onMounted, inject, computed, watch } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ const agencies = ref([]);
|
||||||
const warehouses = ref([]);
|
const warehouses = ref([]);
|
||||||
const currentStep = ref('method');
|
const currentStep = ref('method');
|
||||||
const id = route.params.id;
|
const id = route.params.id;
|
||||||
|
const defaultValues = ref(null);
|
||||||
const orderForm = ref({
|
const orderForm = ref({
|
||||||
method: 'AGENCY',
|
method: 'AGENCY',
|
||||||
date: formatDate(Date.vnNew(), 'YYYY/MM/DD'),
|
date: formatDate(Date.vnNew(), 'YYYY/MM/DD'),
|
||||||
|
@ -179,6 +180,15 @@ const getAgencies = async () => {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
agencies.value = results[1].data;
|
agencies.value = results[1].data;
|
||||||
|
|
||||||
|
if (agencies.value && agencies.value.length && defaultValues.value) {
|
||||||
|
const found = agencies.value.find(
|
||||||
|
agency => agency.id === defaultValues.value.defaultAgencyFk
|
||||||
|
);
|
||||||
|
|
||||||
jsegarra
commented
Duda, si no se encuentra no debería mostrar mensaje de error al usuario? Duda, si no se encuentra no debería mostrar mensaje de error al usuario?
Cambiar found por agency
wbuezas
commented
No creo que se deba mostrar un error por esto, supongo que por algo el hedera viejo no lo hacía No creo que se deba mostrar un error por esto, supongo que por algo el hedera viejo no lo hacía
|
|||||||
|
if (found)
|
||||||
|
orderForm.value.agency = defaultValues.value.defaultAgencyFk;
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error getting agencies:', error);
|
console.error('Error getting agencies:', error);
|
||||||
}
|
}
|
||||||
|
@ -284,6 +294,13 @@ const submit = async () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getDefaultValues = async () => {
|
||||||
|
return await jApi.query(
|
||||||
|
`SELECT deliveryMethod, agencyModeFk, addressFk, defaultAgencyFk
|
||||||
|
FROM myBasketDefaults`
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
today.value = Date.vnNew();
|
today.value = Date.vnNew();
|
||||||
today.value.setHours(0, 0, 0, 0);
|
today.value.setHours(0, 0, 0, 0);
|
||||||
|
@ -305,10 +322,21 @@ onMounted(async () => {
|
||||||
orderForm.value.agency = order.agencyModeFk;
|
orderForm.value.agency = order.agencyModeFk;
|
||||||
orderForm.value.address = order.addressFk;
|
orderForm.value.address = order.addressFk;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
const [_defaultValues] = await getDefaultValues();
|
||||||
|
if (_defaultValues) defaultValues.value = _defaultValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
getAddresses();
|
getAddresses();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => orderForm.value.method,
|
||||||
|
() => {
|
||||||
|
orderForm.value.address = '';
|
||||||
|
orderForm.value.agency = '';
|
||||||
|
}
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -468,7 +496,7 @@ onMounted(async () => {
|
||||||
</QTooltip>
|
</QTooltip>
|
||||||
</QBtn>
|
</QBtn>
|
||||||
<QBtn
|
<QBtn
|
||||||
v-if="showNavigationButtons"
|
v-if="showNavigationButtons || currentStep === 'confirm'"
|
||||||
@click="onNextStep(stepIndex)"
|
@click="onNextStep(stepIndex)"
|
||||||
:color="currentStep === 'confirm' ? 'accent ' : 'primary'"
|
:color="currentStep === 'confirm' ? 'accent ' : 'primary'"
|
||||||
:icon="
|
:icon="
|
||||||
|
@ -477,6 +505,7 @@ onMounted(async () => {
|
||||||
dense
|
dense
|
||||||
class="right-navigation-button"
|
class="right-navigation-button"
|
||||||
data-testid="checkoutStepperRightButton"
|
data-testid="checkoutStepperRightButton"
|
||||||
|
:loading="loading"
|
||||||
>
|
>
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
{{ t(`${step.nextButtonLabel || 'next'}`) }}
|
{{ t(`${step.nextButtonLabel || 'next'}`) }}
|
||||||
|
@ -491,7 +520,7 @@ onMounted(async () => {
|
||||||
@import 'src/css/responsive';
|
@import 'src/css/responsive';
|
||||||
|
|
||||||
.step-title {
|
.step-title {
|
||||||
min-width: 100%;
|
max-width: 90%;
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
@ -523,7 +552,7 @@ onMounted(async () => {
|
||||||
.left-navigation-button {
|
.left-navigation-button {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 5px;
|
left: 5px;
|
||||||
top: 50%;
|
top: 25px;
|
||||||
@include mobile {
|
@include mobile {
|
||||||
top: 35%;
|
top: 35%;
|
||||||
}
|
}
|
||||||
|
@ -532,7 +561,7 @@ onMounted(async () => {
|
||||||
.right-navigation-button {
|
.right-navigation-button {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 5px;
|
right: 5px;
|
||||||
top: 50%;
|
top: 25px;
|
||||||
@include mobile {
|
@include mobile {
|
||||||
top: 35%;
|
top: 35%;
|
||||||
}
|
}
|
||||||
|
|
|
@ -288,9 +288,8 @@ onMounted(async () => {
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-if="!transferAccounts.length"
|
v-if="!transferAccounts.length"
|
||||||
class="row items-center justify-center q-pa-md bg-red"
|
class="row items-center justify-center q-pa-md"
|
||||||
>
|
>
|
||||||
<QIcon class="q-mr-md" name="block" size="sm" />
|
|
||||||
<span>{{ t('emptyList') }}</span>
|
<span>{{ t('emptyList') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<QList>
|
<QList>
|
||||||
|
|
|
@ -172,7 +172,6 @@ const deleteRow = id => {
|
||||||
class="row items-center justify-center q-pa-md"
|
class="row items-center justify-center q-pa-md"
|
||||||
style="margin-top: 32px"
|
style="margin-top: 32px"
|
||||||
>
|
>
|
||||||
<QIcon class="q-mr-md" name="block" size="sm" />
|
|
||||||
<span>{{ t('emptyList') }}</span>
|
<span>{{ t('emptyList') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</QCard>
|
</QCard>
|
||||||
|
|
|
@ -136,8 +136,11 @@ const loginAsGuest = async () => {
|
||||||
outline
|
outline
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<p class="password-forgotten text-center q-mt-lg">
|
<p
|
||||||
<router-link to="/remember-password" class="link">
|
class="password-forgotten text-center q-mt-lg"
|
||||||
|
data-testid="recoverPasswordViewLink"
|
||||||
|
>
|
||||||
|
<router-link :to="{ name: 'recoverPassword' }" class="link">
|
||||||
{{ $t('haveForgottenPassword') }}
|
{{ $t('haveForgottenPassword') }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { api } from 'boot/axios';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import useNotify from 'src/composables/useNotify.js';
|
||||||
|
import VnInput from 'src/components/common/VnInput.vue';
|
||||||
|
|
||||||
|
const user = ref('');
|
||||||
|
const router = useRouter();
|
||||||
|
const { t } = useI18n();
|
||||||
|
const { notify } = useNotify();
|
||||||
|
|
||||||
|
const onSend = async () => {
|
||||||
|
const params = {
|
||||||
|
user: user.value,
|
||||||
|
app: 'hedera'
|
||||||
|
};
|
||||||
|
await api.post('VnUsers/recoverPassword', params);
|
||||||
|
notify(t('weHaveSentEmailToRecover'), 'positive');
|
||||||
|
router.push('/login');
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<QPage class="text-center">
|
||||||
|
<div>
|
||||||
|
<QIcon
|
||||||
|
name="contact_support"
|
||||||
|
class="block q-mx-auto text-accent"
|
||||||
|
style="font-size: 120px"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<QForm @submit="onSend" class="q-gutter-y-md text-grey-8">
|
||||||
|
<VnInput
|
||||||
|
v-model="user"
|
||||||
|
:label="t('user')"
|
||||||
|
autofocus
|
||||||
|
data-testid="recoverPasswordUserInput"
|
||||||
|
/>
|
||||||
|
<div class="q-mt-lg">
|
||||||
|
{{ t('weSendEmail') }}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<QBtn
|
||||||
|
type="submit"
|
||||||
|
:label="t('send')"
|
||||||
|
class="full-width q-mt-md"
|
||||||
|
color="primary"
|
||||||
|
rounded
|
||||||
|
no-caps
|
||||||
|
unelevated
|
||||||
|
data-testid="recoverPasswordSubmitButton"
|
||||||
|
/>
|
||||||
|
<div class="text-center q-mt-md">
|
||||||
|
<router-link to="/login" class="link">
|
||||||
|
{{ t('back') }}
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</QForm>
|
||||||
|
</div>
|
||||||
|
</QPage>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.q-btn {
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<i18n lang="yaml">
|
||||||
|
en-US:
|
||||||
|
inputEmail: Input email
|
||||||
|
rememberPassword: Rememeber password
|
||||||
|
weSendEmail: We will sent you an email to recover your password
|
||||||
|
weHaveSentEmailToRecover: We've sent you an email where you can recover your password
|
||||||
|
es-ES:
|
||||||
|
inputEmail: Introduce el correo electrónico
|
||||||
|
rememberPassword: Recordar contraseña
|
||||||
|
weSendEmail: Te enviaremos un correo para restablecer tu contraseña
|
||||||
|
weHaveSentEmailToRecover: Te hemos enviado un correo donde podrás recuperar tu contraseña
|
||||||
|
ca-ES:
|
||||||
|
inputEmail: Introdueix el correu electrònic
|
||||||
|
rememberPassword: Recordar contrasenya
|
||||||
|
weSendEmail: T'enviarem un correu per restablir la teva contrasenya
|
||||||
|
weHaveSentEmailToRecover: T'hem enviat un correu on podràs recuperar la teva contrasenya
|
||||||
|
fr-FR:
|
||||||
|
inputEmail: Entrez l'email
|
||||||
|
rememberPassword: Se souvenir du mot de passe
|
||||||
|
weSendEmail: Nous vous enverrons un e-mail pour récupérer votre mot de passe
|
||||||
|
weHaveSentEmailToRecover: Nous vous avons envoyé un e-mail où vous pouvez récupérer votre mot de passe
|
||||||
|
pr-BR:
|
||||||
|
inputEmail: Digite o e-mail
|
||||||
|
rememberPassword: Lembrar senha
|
||||||
|
weSendEmail: Enviaremos um e-mail para recuperar sua senha
|
||||||
|
weHaveSentEmailToRecover: Enviamos um e-mail onde você pode recuperar sua senha
|
||||||
|
</i18n>
|
|
@ -1,114 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="text-center">
|
|
||||||
<div>
|
|
||||||
<QIcon
|
|
||||||
name="contact_support"
|
|
||||||
class="block q-mx-auto text-accent"
|
|
||||||
style="font-size: 120px"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<QForm
|
|
||||||
@submit="onSend"
|
|
||||||
class="q-gutter-y-md text-grey-8"
|
|
||||||
>
|
|
||||||
<div class="text-h5">
|
|
||||||
<div>
|
|
||||||
{{ $t('dontWorry') }}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
{{ $t('fillData') }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<QInput
|
|
||||||
v-model="email"
|
|
||||||
:label="$t('user')"
|
|
||||||
:rules="[val => !!val || $t('inputEmail')]"
|
|
||||||
autofocus
|
|
||||||
/>
|
|
||||||
<div class="q-mt-lg">
|
|
||||||
{{ $t('weSendEmail') }}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<QBtn
|
|
||||||
type="submit"
|
|
||||||
:label="$t('send')"
|
|
||||||
class="full-width q-mt-md"
|
|
||||||
color="primary"
|
|
||||||
rounded
|
|
||||||
no-caps
|
|
||||||
unelevated
|
|
||||||
/>
|
|
||||||
<div class="text-center q-mt-md">
|
|
||||||
<router-link
|
|
||||||
to="/login"
|
|
||||||
class="link"
|
|
||||||
>
|
|
||||||
{{ $t('return') }}
|
|
||||||
</router-link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</QForm>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
#image {
|
|
||||||
height: 190px;
|
|
||||||
}
|
|
||||||
.q-btn {
|
|
||||||
height: 50px;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
color: inherit;
|
|
||||||
font-size: 0.8rem;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'VnRememberPasword',
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
email: ''
|
|
||||||
};
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
async onSend() {
|
|
||||||
const params = {
|
|
||||||
email: this.email
|
|
||||||
};
|
|
||||||
await this.$axios.post('Users/reset', params);
|
|
||||||
this.$q.notify({
|
|
||||||
message: this.$t('weHaveSentEmailToRecover'),
|
|
||||||
type: 'positive'
|
|
||||||
});
|
|
||||||
this.$router.push('/login');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<i18n lang="yaml">
|
|
||||||
en-US:
|
|
||||||
user: User
|
|
||||||
inputEmail: Input email
|
|
||||||
rememberPassword: Rememeber password
|
|
||||||
dontWorry: Don't worry!
|
|
||||||
fillData: Fill the data
|
|
||||||
weSendEmail: We will sent you an email to recover your password
|
|
||||||
weHaveSentEmailToRecover: We've sent you an email where you can recover your password
|
|
||||||
send: Send
|
|
||||||
return: Return
|
|
||||||
es-ES:
|
|
||||||
user: Usuario
|
|
||||||
inputEmail: Introduce el correo electrónico
|
|
||||||
rememberPassword: Recordar contraseña
|
|
||||||
dontWorry: ¡No te preocupes!
|
|
||||||
fillData: Rellena los datos
|
|
||||||
weSendEmail: Te enviaremos un correo para restablecer tu contraseña
|
|
||||||
weHaveSentEmailToRecover: Te hemos enviado un correo donde podrás recuperar tu contraseña
|
|
||||||
send: Enviar
|
|
||||||
return: Volver
|
|
||||||
</i18n>
|
|
|
@ -39,10 +39,11 @@ export default route(function (/* { store, ssrContext } */) {
|
||||||
|
|
||||||
Router.beforeEach((to, from, next) => {
|
Router.beforeEach((to, from, next) => {
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
const allowedRoutes = ['login', 'recoverPassword'];
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!userStore.storage.getItem('token') &&
|
!userStore.storage.getItem('token') &&
|
||||||
to.name !== 'login' &&
|
!allowedRoutes.includes(to.name) &&
|
||||||
!userStore.isGuest
|
!userStore.isGuest
|
||||||
) {
|
) {
|
||||||
return next({ name: 'login' });
|
return next({ name: 'login' });
|
||||||
|
|
|
@ -5,17 +5,17 @@ const routes = [
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
name: 'login',
|
name: 'login',
|
||||||
path: '/login/:email?',
|
path: '',
|
||||||
component: () => import('pages/Login/LoginView.vue')
|
component: () => import('pages/Login/LoginView.vue')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'rememberPassword',
|
name: 'recoverPassword',
|
||||||
path: '/remember-password',
|
path: 'recover',
|
||||||
component: () => import('pages/Login/RememberPassword.vue')
|
component: () => import('pages/Login/RecoverPassword.vue')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'resetPassword',
|
name: 'resetPassword',
|
||||||
path: '/reset-password',
|
path: 'reset',
|
||||||
component: () => import('pages/Login/ResetPassword.vue')
|
component: () => import('pages/Login/ResetPassword.vue')
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -20,12 +20,7 @@ export const useAppStore = defineStore('hedera', {
|
||||||
menuEssentialLinks: [],
|
menuEssentialLinks: [],
|
||||||
hiddenMenuLinks: new Set(['Reports']),
|
hiddenMenuLinks: new Set(['Reports']),
|
||||||
basketOrderId: null,
|
basketOrderId: null,
|
||||||
localeDates: {
|
|
||||||
days: [],
|
|
||||||
months: [],
|
|
||||||
daysShort: [],
|
|
||||||
monthsShort: []
|
|
||||||
},
|
|
||||||
siteLang: null,
|
siteLang: null,
|
||||||
localeOptions: [
|
localeOptions: [
|
||||||
{ label: t('langs.en'), lang: 'en-US', value: 'en' },
|
{ label: t('langs.en'), lang: 'en-US', value: 'en' },
|
||||||
|
@ -66,20 +61,9 @@ export const useAppStore = defineStore('hedera', {
|
||||||
this.$patch({ imageUrl });
|
this.$patch({ imageUrl });
|
||||||
},
|
},
|
||||||
|
|
||||||
getLocaleDates() {
|
|
||||||
const { messages, locale } = i18n.global;
|
|
||||||
this.localeDates = {
|
|
||||||
days: messages.value[locale.value].date.days,
|
|
||||||
months: messages.value[locale.value].date.months,
|
|
||||||
daysShort: messages.value[locale.value].date.daysShort,
|
|
||||||
monthsShort: messages.value[locale.value].date.monthsShort
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
this.updateSiteLocale(localStorage.getItem('siteLang') || 'es-ES');
|
this.updateSiteLocale(localStorage.getItem('siteLang') || 'es-ES');
|
||||||
this.getBasketOrderId();
|
this.getBasketOrderId();
|
||||||
this.getLocaleDates();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getBasketOrderId() {
|
getBasketOrderId() {
|
||||||
|
@ -187,6 +171,12 @@ export const useAppStore = defineStore('hedera', {
|
||||||
isDesktop() {
|
isDesktop() {
|
||||||
const $q = useQuasar();
|
const $q = useQuasar();
|
||||||
return $q?.screen?.width > 1024;
|
return $q?.screen?.width > 1024;
|
||||||
|
},
|
||||||
|
localeDates() {
|
||||||
|
const { messages, locale } = i18n.global;
|
||||||
|
const { days, months, daysShort, monthsShort } =
|
||||||
jsegarra marked this conversation as resolved
Outdated
jsegarra
commented
dale una vuelta porque esto se puede simplificar mucho dale una vuelta porque esto se puede simplificar mucho
|
|||||||
|
messages.value[locale.value].date;
|
||||||
|
return { days, months, daysShort, monthsShort };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
describe('Login Tests', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.visit('/#/login');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should ssend recover email', () => {
|
||||||
|
cy.dataCy('recoverPasswordViewLink').should('exist');
|
||||||
|
cy.dataCy('recoverPasswordViewLink').click();
|
||||||
|
cy.dataCy('recoverPasswordUserInput').find('input').should('exist');
|
||||||
|
cy.dataCy('recoverPasswordUserInput').find('input').type('developer');
|
||||||
|
cy.dataCy('recoverPasswordSubmitButton').should('exist');
|
||||||
|
cy.dataCy('recoverPasswordSubmitButton').click();
|
||||||
|
cy.checkNotify(
|
||||||
|
'positive',
|
||||||
|
'Te hemos enviado un correo donde podrás recuperar tu contraseña'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue
En lilium hemos quitado los trycatch porque si la peticion falla, el usuario no se entera.
Ya tenemos el controlador de axios, no?
Si, tenemos el controlador de axios