From 52b32bd60891df245a0f63502be7156a0d12f7ef Mon Sep 17 00:00:00 2001 From: Alexandr SaVBaD Waltz Date: Fri, 11 Jul 2025 18:39:13 +0300 Subject: [PATCH] Features: 1) Introduce `useUserBaseData` composable to fetch and manage user's wishlist, orders, and promocodes; 2) Add reusable `useOrders` and `useOrderOverwrite` composables with advanced filtering and pagination; 3) Implement `order.vue` component for detailed order displays with UI enhancements; Fixes: 1) Replace deprecated context usage in `useAvatarUpload` mutation; 2) Resolve incorrect locale parsing in `useDate` utility and fix non-reactive cart state in `profile/cart.vue`; 3) Update stale imports and standardize type naming across composables; Extra: 1) Refactor i18n strings including order status and search-related texts; 2) Replace temporary workarounds with `apollo-upload-client` configuration and add `apollo-upload-link.ts` plugin; 3) Cleanup redundant files, comments, and improve SCSS structure with new variables and placeholders. --- .../assets/styles/modules/normalize.scss | 11 + storefront/components/cards/order.vue | 246 ++++++++++++++++++ storefront/components/cards/product.vue | 2 +- .../components/skeletons/cards/order.vue | 88 +++++++ storefront/components/store/filter.vue | 2 +- storefront/composables/auth/useLogin.ts | 16 +- storefront/composables/auth/useRefresh.ts | 15 +- storefront/composables/date/useDate.ts | 17 +- storefront/composables/orders/index.ts | 3 +- storefront/composables/orders/useOrders.ts | 79 ++++++ .../composables/orders/usePendingOrder.ts | 28 -- .../composables/promocodes/usePromocodes.ts | 1 + storefront/composables/store/useStore.ts | 4 +- storefront/composables/user/index.ts | 3 +- .../composables/user/useAvatarUpload.ts | 12 +- .../composables/user/useUserBaseData.ts | 41 +++ storefront/config/constants.ts | 12 +- .../graphql/fragments/orders.fragment.ts | 1 + .../graphql/fragments/promocodes.fragment.ts | 2 - storefront/graphql/mutations/user.ts | 4 +- .../graphql/queries/combined/userBaseData.ts | 18 ++ .../graphql/queries/standalone/orders.ts | 14 +- storefront/i18n/locales/en-gb.json | 29 ++- storefront/middleware/auth.ts | 11 + storefront/nuxt.config.ts | 17 +- storefront/package-lock.json | 37 ++- storefront/package.json | 2 +- storefront/pages/index.vue | 5 + storefront/pages/product/[slug].vue | 2 +- storefront/pages/profile.vue | 17 +- storefront/pages/profile/cart.vue | 43 +-- storefront/pages/profile/orders.vue | 219 +++++++++++++++- storefront/pages/profile/promocodes.vue | 71 +++-- storefront/pages/profile/wishlist.vue | 11 +- storefront/plugins/apollo-upload-link.ts | 21 ++ storefront/stores/user.ts | 3 +- storefront/types/api/orders.ts | 10 +- storefront/types/api/user.ts | 12 +- storefront/types/app/orders.ts | 1 + storefront/types/app/promocodes.ts | 2 - 40 files changed, 984 insertions(+), 148 deletions(-) create mode 100644 storefront/components/cards/order.vue create mode 100644 storefront/components/skeletons/cards/order.vue create mode 100644 storefront/composables/orders/useOrders.ts delete mode 100644 storefront/composables/orders/usePendingOrder.ts create mode 100644 storefront/composables/user/useUserBaseData.ts create mode 100644 storefront/graphql/queries/combined/userBaseData.ts create mode 100644 storefront/middleware/auth.ts create mode 100644 storefront/plugins/apollo-upload-link.ts diff --git a/storefront/assets/styles/modules/normalize.scss b/storefront/assets/styles/modules/normalize.scss index 1121d157..39a3a0aa 100644 --- a/storefront/assets/styles/modules/normalize.scss +++ b/storefront/assets/styles/modules/normalize.scss @@ -37,6 +37,17 @@ button:focus-visible { margin-inline: auto; } +//::-webkit-scrollbar { +// width: 12px; +//} +// +//::-webkit-scrollbar-thumb { +// background-color: rgba($accent, 0.5); +// border-radius: $default_border_radius; +// -webkit-transition: all .2s ease; +// transition: all .2s ease; +//} + ::-webkit-scrollbar-thumb { background: $accent; } diff --git a/storefront/components/cards/order.vue b/storefront/components/cards/order.vue new file mode 100644 index 00000000..c59f0432 --- /dev/null +++ b/storefront/components/cards/order.vue @@ -0,0 +1,246 @@ + + + + + \ No newline at end of file diff --git a/storefront/components/cards/product.vue b/storefront/components/cards/product.vue index 1877728e..61e7ea7e 100644 --- a/storefront/components/cards/product.vue +++ b/storefront/components/cards/product.vue @@ -130,7 +130,7 @@ import 'swiper/css'; import 'swiper/css/effect-fade'; import 'swiper/css/pagination' import {useWishlistOverwrite} from "~/composables/wishlist"; -import {useOrderOverwrite} from "~/composables/orders/useOrderOverwrite"; +import {useOrderOverwrite} from "~/composables/orders"; import {CURRENCY} from "~/config/constants"; const props = defineProps<{ diff --git a/storefront/components/skeletons/cards/order.vue b/storefront/components/skeletons/cards/order.vue new file mode 100644 index 00000000..3a6846db --- /dev/null +++ b/storefront/components/skeletons/cards/order.vue @@ -0,0 +1,88 @@ + + + + + \ No newline at end of file diff --git a/storefront/components/store/filter.vue b/storefront/components/store/filter.vue index 951dd957..793e3686 100644 --- a/storefront/components/store/filter.vue +++ b/storefront/components/store/filter.vue @@ -83,7 +83,7 @@ const emit = defineEmits<{ }>(); const attributesQuery = useRouteQuery('attributes', ''); - +//TODO: price in filters const { selectedMap, selectedAllMap, diff --git a/storefront/composables/auth/useLogin.ts b/storefront/composables/auth/useLogin.ts index 7746d003..585ecad2 100644 --- a/storefront/composables/auth/useLogin.ts +++ b/storefront/composables/auth/useLogin.ts @@ -3,13 +3,11 @@ import type { ILoginResponse } from '~/types/api/auth'; import { isGraphQLError } from '~/utils/error'; import { useAppConfig } from '~/composables/config'; import { useLocaleRedirect } from '~/composables/languages'; -import { useWishlist } from '~/composables/wishlist'; -import { usePendingOrder } from '~/composables/orders'; import { useUserStore } from '~/stores/user'; import { useAppStore } from '~/stores/app'; import {DEFAULT_LOCALE} from "~/config/constants"; import {useNotification} from "~/composables/notification"; -import {usePromocodes} from "~/composables/promocodes"; +import {useUserBaseData} from "~/composables/user"; export function useLogin() { const { t } = useI18n(); @@ -70,10 +68,14 @@ export function useLogin() { await checkAndRedirect(authData.user.language); } - await useWishlist(); - await usePendingOrder(authData.user.email); - await usePromocodes(); - //TODO: combine three requests + // await useWishlist(); + // await useOrders({ + // userEmail: authData.user.email, + // status: "PENDING" + // }); + // await usePromocodes(); + + await useUserBaseData(authData.user.email); } watch(error, (err) => { diff --git a/storefront/composables/auth/useRefresh.ts b/storefront/composables/auth/useRefresh.ts index 88141257..14de8b87 100644 --- a/storefront/composables/auth/useRefresh.ts +++ b/storefront/composables/auth/useRefresh.ts @@ -1,13 +1,11 @@ import { REFRESH } from '@/graphql/mutations/auth'; import { useAppConfig } from '~/composables/config'; import { useLocaleRedirect } from '~/composables/languages'; -import { useWishlist } from '~/composables/wishlist'; -import { usePendingOrder } from '~/composables/orders'; import { useUserStore } from '~/stores/user'; import { isGraphQLError } from '~/utils/error'; import {DEFAULT_LOCALE} from "~/config/constants"; import {useNotification} from "~/composables/notification"; -import {usePromocodes} from "~/composables/promocodes"; +import {useUserBaseData} from "~/composables/user"; export function useRefresh() { const { t } = useI18n(); @@ -51,10 +49,13 @@ export function useRefresh() { cookieRefresh.value = data.refreshToken - await useWishlist(); - await usePendingOrder(data.user.email); - await usePromocodes(); - //TODO: combine three requests + // await useWishlist(); + // await useOrders({ + // userEmail: data.user.email, + // status: "PENDING" + // }); + // await usePromocodes(); + await useUserBaseData(data.user.email); } watch(error, (err) => { diff --git a/storefront/composables/date/useDate.ts b/storefront/composables/date/useDate.ts index 02008d9b..51ca3d59 100644 --- a/storefront/composables/date/useDate.ts +++ b/storefront/composables/date/useDate.ts @@ -1,14 +1,15 @@ export function useDate( iso: string | undefined, - locale: string = 'en-gb' -): string { - if (!iso) return ''; - const date = new Date(iso); - const parsedLocale = locale.replace('-', '-').toLocaleUpperCase() - - return new Intl.DateTimeFormat(parsedLocale, { + locale: string = 'en-gb', + options: Intl.DateTimeFormatOptions = { year: 'numeric', month: 'long', day: '2-digit' - }).format(date); + } +): string { + if (!iso) return '' + const date = new Date(iso) + const parsedLocale = locale.replace('_', '-').toLowerCase() + + return new Intl.DateTimeFormat(parsedLocale, options).format(date) } \ No newline at end of file diff --git a/storefront/composables/orders/index.ts b/storefront/composables/orders/index.ts index 95ea2494..ae44b440 100644 --- a/storefront/composables/orders/index.ts +++ b/storefront/composables/orders/index.ts @@ -1 +1,2 @@ -export * from './usePendingOrder'; \ No newline at end of file +export * from './useOrderOverwrite'; +export * from './useOrders'; \ No newline at end of file diff --git a/storefront/composables/orders/useOrders.ts b/storefront/composables/orders/useOrders.ts new file mode 100644 index 00000000..abfab368 --- /dev/null +++ b/storefront/composables/orders/useOrders.ts @@ -0,0 +1,79 @@ +import {GET_ORDERS} from "~/graphql/queries/standalone/orders"; +import type {IOrdersResponse} from "~/types"; +import {orderStatuses} from "~/config/constants"; + +interface IOrdersArguments { + userEmail: string, + status?: string, + after?: string, + search: string +} + +interface IOrderVars { + status: string, + userEmail: string, + first: number, + after?: string, + search: string +} + +export async function useOrders(args: IOrdersArguments) { + const cartStore = useCartStore(); + + const variables = reactive({ + status: args.status || '', + userEmail: args.userEmail, + first: 10, + after: args.after, + search: args.search + }); + + const { pending, data, error, refresh } = await useAsyncQuery( + GET_ORDERS, + variables + ); + + const orders = ref(data.value?.orders.edges.filter((order) => order.node.status !== orderStatuses.PENDING) ?? []); + const pageInfo = computed(() => data.value?.orders.pageInfo ?? null); + + if (!error.value && data.value?.orders.edges) { + if (args.status === orderStatuses.PENDING) { + cartStore.setCurrentOrders(data.value?.orders.edges[0].node); + } + } + + watch( + () => variables.after, + async (newCursor, oldCursor) => { + if (!newCursor || newCursor === oldCursor) return; + await refresh(); + const newEdges = data.value?.orders.edges ?? []; + orders.value.push(...newEdges); + } + ); + + watch( + [ + () => variables.status, + () => variables.search + ], + async () => { + variables.after = ''; + await refresh(); + orders.value = data.value?.orders.edges ?? []; + } + ); + + watch(error, (err) => { + if (err) { + console.error('useOrders error:', err); + } + }); + + return { + pending, + orders, + pageInfo, + variables + }; +} \ No newline at end of file diff --git a/storefront/composables/orders/usePendingOrder.ts b/storefront/composables/orders/usePendingOrder.ts deleted file mode 100644 index eccdeeb7..00000000 --- a/storefront/composables/orders/usePendingOrder.ts +++ /dev/null @@ -1,28 +0,0 @@ -import {GET_ORDERS} from "~/graphql/queries/standalone/orders"; -import type {IOrderResponse} from "~/types"; - -export async function usePendingOrder(userEmail: string) { - const cartStore = useCartStore(); - - const { data, error } = await useAsyncQuery( - GET_ORDERS, - { - status: "PENDING", - userEmail - } - ); - - if (!error.value && data.value?.orders.edges[0].node) { - cartStore.setCurrentOrders(data.value?.orders.edges[0].node); - } - - watch(error, (err) => { - if (err) { - console.error('usePendingOrder error:', err); - } - }); - - return { - - }; -} \ No newline at end of file diff --git a/storefront/composables/promocodes/usePromocodes.ts b/storefront/composables/promocodes/usePromocodes.ts index 190a002c..aeb4453b 100644 --- a/storefront/composables/promocodes/usePromocodes.ts +++ b/storefront/composables/promocodes/usePromocodes.ts @@ -7,6 +7,7 @@ export async function usePromocodes () { const { data, error } = await useAsyncQuery( GET_PROMOCODES ); + console.log(data.value) if (!error.value && data.value?.promocodes.edges) { promocodesStore.setPromocodes(data.value.promocodes.edges); diff --git a/storefront/composables/store/useStore.ts b/storefront/composables/store/useStore.ts index b3593361..092bdffa 100644 --- a/storefront/composables/store/useStore.ts +++ b/storefront/composables/store/useStore.ts @@ -1,7 +1,7 @@ import { GET_PRODUCTS } from '~/graphql/queries/standalone/products'; import type {IProductResponse} from '~/types'; -interface ProdVars { +interface IProdVars { first: number, categoriesSlugs: string, attributes?: string, @@ -19,7 +19,7 @@ export async function useStore( maxPrice?: number, productAfter?: string ) { - const variables = reactive({ + const variables = reactive({ first: 15, categoriesSlugs: slug, attributes, diff --git a/storefront/composables/user/index.ts b/storefront/composables/user/index.ts index 815f8579..e93561bb 100644 --- a/storefront/composables/user/index.ts +++ b/storefront/composables/user/index.ts @@ -1,4 +1,5 @@ export * from './useUserActivation'; export * from './useAvatarUpload'; export * from './useUserUpdating'; -export * from './useDeposit'; \ No newline at end of file +export * from './useDeposit'; +export * from './useUserBaseData'; \ No newline at end of file diff --git a/storefront/composables/user/useAvatarUpload.ts b/storefront/composables/user/useAvatarUpload.ts index 034161ca..317d9e46 100644 --- a/storefront/composables/user/useAvatarUpload.ts +++ b/storefront/composables/user/useAvatarUpload.ts @@ -6,17 +6,19 @@ import {useNotification} from "~/composables/notification"; export function useAvatarUpload() { const { t } = useI18n(); const userStore = useUserStore(); - const { mutate, onDone, loading, error } = useMutation(UPLOAD_AVATAR, { - context: { - hasUpload: true - }} + const { mutate, onDone, loading, error } = useMutation( + UPLOAD_AVATAR, + // { + // context: { hasUpload: true } + // } ); async function uploadAvatar(event: Event) { const file = (event.target as HTMLInputElement).files?.[0]; if (!file) return; + console.log(file) - await mutate({ avatar: file }); + await mutate({ file }); } onDone(({ data }) => { diff --git a/storefront/composables/user/useUserBaseData.ts b/storefront/composables/user/useUserBaseData.ts new file mode 100644 index 00000000..93fd30ec --- /dev/null +++ b/storefront/composables/user/useUserBaseData.ts @@ -0,0 +1,41 @@ +import type {IUserBaseDataResponse} from "~/types"; +import {getUserBaseData} from "~/graphql/queries/combined/userBaseData"; +import {orderStatuses} from "~/config/constants"; + +export async function useUserBaseData(userEmail: string) { + const wishlistStore = useWishlistStore(); + const cartStore = useCartStore(); + const promocodesStore = usePromocodeStore(); + + const { document, variables } = getUserBaseData( + { + userEmail, + status: orderStatuses.PENDING + }, + ); + + const { data, error } = await useAsyncQuery( + document, + variables + ); + + if (data.value?.wishlists.edges) { + wishlistStore.setWishlist(data.value.wishlists.edges[0].node); + } + if (data.value?.orders.edges) { + cartStore.setCurrentOrders(data.value?.orders.edges[0].node); + } + if (data.value?.promocodes.edges) { + promocodesStore.setPromocodes(data.value.promocodes.edges); + } + + watch(error, (err) => { + if (err) { + console.error('useUserBaseData error:', err); + } + }); + + return { + + }; +} \ No newline at end of file diff --git a/storefront/config/constants.ts b/storefront/config/constants.ts index 46614277..3c0149d1 100644 --- a/storefront/config/constants.ts +++ b/storefront/config/constants.ts @@ -87,4 +87,14 @@ export const SUPPORTED_LOCALES: LocaleDefinition[] = [ export const DEFAULT_LOCALE = SUPPORTED_LOCALES.find(locale => locale.default)?.code || 'en-gb'; -export const CURRENCY = '$' \ No newline at end of file +export const CURRENCY = '$'; + +export enum orderStatuses { + PENDING = 'PENDING', + FAILED = 'FAILED', + PAYMENT = 'PAYMENT', + CREATED = 'CREATED', + DELIVERING = 'DELIVERING', + FINISHED = 'FINISHED', + MOMENTAL = 'MOMENTAL' +} \ No newline at end of file diff --git a/storefront/graphql/fragments/orders.fragment.ts b/storefront/graphql/fragments/orders.fragment.ts index 68158e72..def5a2ce 100644 --- a/storefront/graphql/fragments/orders.fragment.ts +++ b/storefront/graphql/fragments/orders.fragment.ts @@ -7,6 +7,7 @@ export const ORDER_FRAGMENT = gql` status buyTime humanReadableId + notifications orderProducts { edges { node { diff --git a/storefront/graphql/fragments/promocodes.fragment.ts b/storefront/graphql/fragments/promocodes.fragment.ts index 17e3809f..b627d9c1 100644 --- a/storefront/graphql/fragments/promocodes.fragment.ts +++ b/storefront/graphql/fragments/promocodes.fragment.ts @@ -4,9 +4,7 @@ export const PROMOCODE_FRAGMENT = gql` discount discountType endTime - id startTime - usedOn uuid } ` \ No newline at end of file diff --git a/storefront/graphql/mutations/user.ts b/storefront/graphql/mutations/user.ts index 83ae9504..b684c9dd 100644 --- a/storefront/graphql/mutations/user.ts +++ b/storefront/graphql/mutations/user.ts @@ -43,10 +43,10 @@ export const UPDATE_USER = gql` export const UPLOAD_AVATAR = gql` mutation uploadAvatar( - $avatar: Upload! + $file: Upload! ) { uploadAvatar( - avatar: $avatar + file: $file ) { user { ...User diff --git a/storefront/graphql/queries/combined/userBaseData.ts b/storefront/graphql/queries/combined/userBaseData.ts new file mode 100644 index 00000000..ea1fba0a --- /dev/null +++ b/storefront/graphql/queries/combined/userBaseData.ts @@ -0,0 +1,18 @@ +import combineQuery from 'graphql-combine-query' +import {GET_WISHLIST} from "~/graphql/queries/standalone/wishlist"; +import {GET_PROMOCODES} from "~/graphql/queries/standalone/promocodes"; +import {GET_ORDERS} from "~/graphql/queries/standalone/orders"; + +export const getUserBaseData = ( + orderVariables?: { + userEmail?: string; + status?: string; + } +) => { + const { document, variables } = combineQuery('getUserBaseData') + .add(GET_WISHLIST) + .add(GET_PROMOCODES) + .add(GET_ORDERS, orderVariables || {}) + + return { document, variables }; +}; \ No newline at end of file diff --git a/storefront/graphql/queries/standalone/orders.ts b/storefront/graphql/queries/standalone/orders.ts index ca8042b7..bab80762 100644 --- a/storefront/graphql/queries/standalone/orders.ts +++ b/storefront/graphql/queries/standalone/orders.ts @@ -3,18 +3,28 @@ import {ORDER_FRAGMENT} from "@/graphql/fragments/orders.fragment.js"; export const GET_ORDERS = gql` query getOrders( $status: String!, - $userEmail: String! + $userEmail: String!, + $first: Int, + $after: String, + $search: String, ) { orders( status: $status, orderBy: "-buyTime", - userEmail: $userEmail + userEmail: $userEmail, + first: $first, + after: $after, + search: $search ) { edges { node { ...Order } } + pageInfo { + hasNextPage + endCursor + } } } ${ORDER_FRAGMENT} diff --git a/storefront/i18n/locales/en-gb.json b/storefront/i18n/locales/en-gb.json index 9499c815..02a6a4f4 100644 --- a/storefront/i18n/locales/en-gb.json +++ b/storefront/i18n/locales/en-gb.json @@ -25,6 +25,7 @@ }, "fields": { "search": "Search", + "searchOrder": "Search order", "name": "Name", "firstName": "First name", "lastName": "Last name", @@ -126,6 +127,7 @@ "home": "Home", "catalog": "Catalog", "contact": "Contact", + "orders": "Orders", "wishlist": "Wishlist", "cart": "Cart", "settings": "Settings", @@ -163,23 +165,42 @@ "referralTooltip": "You will get a referral link after a successful purchase" }, "orders": { - "title": "Orders" + "title": "Orders", + "chooseStatus": "Choose status", + "id": "ID", + "price": "Price", + "total": "Total", + "empty": "There are not any orders by this parameters.", + "statuses": { + "all": "All", + "failed": "Failed", + "payment": "Payment", + "created": "Created", + "delivering": "Delivering", + "finished": "Finished", + "momental": "Momental" + }, + "searchTooltip": "Enter order id or product name" }, "wishlist": { "title": "Wishlist", "total": "{quantity} items worth {amount}", - "deleteTooltip": "Delete all from wishlist" + "deleteTooltip": "Delete all from wishlist", + "empty": "Your wishlist is empty." }, "cart": { "title": "Cart", "quantity": "Quantity: ", - "total": "Total: " + "total": "Total", + "empty": "Your cart is empty." }, "balance": { "title": "Balance" }, "promocodes": { - "title": "Promocodes" + "title": "Promocodes", + "until": "Until", + "empty": "You don't have any promocodes." }, "logout": "Logout" } diff --git a/storefront/middleware/auth.ts b/storefront/middleware/auth.ts new file mode 100644 index 00000000..0f5e53dd --- /dev/null +++ b/storefront/middleware/auth.ts @@ -0,0 +1,11 @@ +export default defineNuxtRouteMiddleware(() => { + const userStore = useUserStore(); + const appStore = useAppStore(); + const localePath = useLocalePath(); + + if (!userStore.isAuthenticated) { + appStore.setActiveState('login'); + + return navigateTo(localePath('/')); + } +}) \ No newline at end of file diff --git a/storefront/nuxt.config.ts b/storefront/nuxt.config.ts index 85f79f0b..2c18aa5e 100644 --- a/storefront/nuxt.config.ts +++ b/storefront/nuxt.config.ts @@ -2,6 +2,7 @@ import { defineNuxtConfig } from 'nuxt/config'; import { i18nConfig } from './config/i18n'; import {fileURLToPath, URL} from "node:url"; import { resolve } from 'node:path'; +import createUploadLink from "apollo-upload-client/createUploadLink.mjs"; export default defineNuxtConfig({ ssr: true, @@ -92,6 +93,20 @@ export default defineNuxtConfig({ file: resolve(__dirname, 'pages/index.vue') } ) - } + }, + // 'apollo:client:created'(apolloClient, { key }) { + // console.log(key) + // console.log('log') + // if ( key !== 'default' ) return + // const runtime = useRuntimeConfig() + // const uploadLink = createUploadLink({ + // uri: `https://api.${runtime.public.evibesBaseDomain}/graphql/`, + // credentials: 'include', + // headers: { + // 'X-EVIBES-AUTH': useCookie(`${runtime.public.evibesProjectName?.toLowerCase()}-access`).value || '' + // } + // }) + // apolloClient.setLink(uploadLink) + // } } }) \ No newline at end of file diff --git a/storefront/package-lock.json b/storefront/package-lock.json index b39f0cc4..33198687 100644 --- a/storefront/package-lock.json +++ b/storefront/package-lock.json @@ -15,7 +15,7 @@ "@vueuse/integrations": "^13.3.0", "@vueuse/nuxt": "^13.3.0", "@vueuse/router": "^13.3.0", - "apollo-upload-client": "17.0.0", + "apollo-upload-client": "^18.0.1", "axios": "^1.9.0", "graphql-combine-query": "^1.2.4", "graphql-tag": "^2.12.6", @@ -3674,21 +3674,21 @@ } }, "node_modules/apollo-upload-client": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/apollo-upload-client/-/apollo-upload-client-17.0.0.tgz", - "integrity": "sha512-pue33bWVbdlXAGFPkgz53TTmxVMrKeQr0mdRcftNY+PoHIdbGZD0hoaXHvO6OePJAkFz7OiCFUf98p1G/9+Ykw==", + "version": "18.0.1", + "resolved": "https://registry.npmjs.org/apollo-upload-client/-/apollo-upload-client-18.0.1.tgz", + "integrity": "sha512-OQvZg1rK05VNI79D658FUmMdoI2oB/KJKb6QGMa2Si25QXOaAvLMBFUEwJct7wf+19U8vk9ILhidBOU1ZWv6QA==", "license": "MIT", "dependencies": { - "extract-files": "^11.0.0" + "extract-files": "^13.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >= 16.0.0" + "node": "^18.15.0 || >=20.4.0" }, "funding": { "url": "https://github.com/sponsors/jaydenseric" }, "peerDependencies": { - "@apollo/client": "^3.0.0", + "@apollo/client": "^3.8.0", "graphql": "14 - 16" } }, @@ -6223,17 +6223,32 @@ "license": "MIT" }, "node_modules/extract-files": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/extract-files/-/extract-files-11.0.0.tgz", - "integrity": "sha512-FuoE1qtbJ4bBVvv94CC7s0oTnKUGvQs+Rjf1L2SJFfS+HTVVjhPFtehPdQ0JiGPqVNfSSZvL5yzHHQq2Z4WNhQ==", + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/extract-files/-/extract-files-13.0.0.tgz", + "integrity": "sha512-FXD+2Tsr8Iqtm3QZy1Zmwscca7Jx3mMC5Crr+sEP1I303Jy1CYMuYCm7hRTplFNg3XdUavErkxnTzpaqdSoi6g==", "license": "MIT", + "dependencies": { + "is-plain-obj": "^4.1.0" + }, "engines": { - "node": "^12.20 || >= 14.13" + "node": "^14.17.0 || ^16.0.0 || >= 18.0.0" }, "funding": { "url": "https://github.com/sponsors/jaydenseric" } }, + "node_modules/extract-files/node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/extract-zip": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", diff --git a/storefront/package.json b/storefront/package.json index 53cfdde8..e8c6bb14 100644 --- a/storefront/package.json +++ b/storefront/package.json @@ -18,7 +18,7 @@ "@vueuse/integrations": "^13.3.0", "@vueuse/nuxt": "^13.3.0", "@vueuse/router": "^13.3.0", - "apollo-upload-client": "17.0.0", + "apollo-upload-client": "^18.0.1", "axios": "^1.9.0", "graphql-combine-query": "^1.2.4", "graphql-tag": "^2.12.6", diff --git a/storefront/pages/index.vue b/storefront/pages/index.vue index 689aefe2..714ccc1c 100644 --- a/storefront/pages/index.vue +++ b/storefront/pages/index.vue @@ -21,6 +21,7 @@ useHead({ const token = useRouteQuery('token', ''); const uid = useRouteQuery('uid', ''); +const referrer = useRouteQuery('referrer', ''); const { activateUser } = useUserActivation(); @@ -32,6 +33,10 @@ onMounted( async () => { if (route.path.includes('reset-password') && token.value && uid.value) { appStore.setActiveState('new-password'); } + + if (referrer.value) { + appStore.setActiveState('register'); + } }); diff --git a/storefront/pages/product/[slug].vue b/storefront/pages/product/[slug].vue index ea023cb7..1af3ec71 100644 --- a/storefront/pages/product/[slug].vue +++ b/storefront/pages/product/[slug].vue @@ -166,7 +166,7 @@ import 'swiper/css/navigation'; import {Navigation} from "swiper/modules"; import {CURRENCY} from "~/config/constants"; import {useWishlistOverwrite} from "~/composables/wishlist"; -import {useOrderOverwrite} from "~/composables/orders/useOrderOverwrite"; +import {useOrderOverwrite} from "~/composables/orders"; const route = useRoute(); const {t} = useI18n(); diff --git a/storefront/pages/profile.vue b/storefront/pages/profile.vue index ff86af6b..27fbc45a 100644 --- a/storefront/pages/profile.vue +++ b/storefront/pages/profile.vue @@ -12,35 +12,24 @@ \ No newline at end of file diff --git a/storefront/pages/profile/cart.vue b/storefront/pages/profile/cart.vue index e75ef0ae..fd78d5b4 100644 --- a/storefront/pages/profile/cart.vue +++ b/storefront/pages/profile/cart.vue @@ -3,37 +3,41 @@

{{ t('profile.cart.quantity') }} {{ productsInCartQuantity }}

-

{{ t('profile.cart.total') }} {{ totalPrice }}

+

{{ t('profile.cart.total') }}: {{ totalPrice }}{{ CURRENCY }}

{{ t('buttons.checkout') }}
- +
+ +
+

{{ t('profile.cart.empty') }}

\ No newline at end of file diff --git a/storefront/pages/profile/promocodes.vue b/storefront/pages/profile/promocodes.vue index 3dfe4284..e7ecd77c 100644 --- a/storefront/pages/profile/promocodes.vue +++ b/storefront/pages/profile/promocodes.vue @@ -1,29 +1,38 @@