Merge pull request '#7750 - first-beta-review' (!95) from wbuezas/hedera-web-mindshore:first-beta-review into beta
gitea/hedera-web/pipeline/head This commit looks good
Details
gitea/hedera-web/pipeline/head This commit looks good
Details
Reviewed-on: #95 Reviewed-by: Javier Segarra <jsegarra@verdnatura.es>
This commit is contained in:
commit
0f1bde3b77
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
|
||||||
|
);
|
||||||
|
|
||||||
|
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 } =
|
||||||
|
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