From f9e19e036b6f644ff5fd216919688e7dbf15a844 Mon Sep 17 00:00:00 2001 From: Qrzy Date: Fri, 21 Feb 2020 11:10:12 +0100 Subject: [PATCH] Add orders list to my account --- .eslintrc.json | 7 +- .../api-client/src/api/getMe/defaultQuery.ts | 8 +- .../api-client/src/fragments/index.ts | 1 + .../composables/src/useUser/index.ts | 13 ++-- .../composables/tests/useUser/useUser.spec.ts | 45 +++++++++-- packages/commercetools/helpers/src/index.ts | 38 +++++++-- .../helpers/tests/orderHelpers.spec.ts | 42 ++++++++++ .../commercetools/theme/pages/Checkout.vue | 2 +- packages/core/interfaces/index.ts | 2 + .../theme/pages/MyAccount/OrderHistory.vue | 78 +++++++++---------- yarn.lock | 43 ++-------- 11 files changed, 181 insertions(+), 98 deletions(-) create mode 100644 packages/commercetools/helpers/tests/orderHelpers.spec.ts diff --git a/.eslintrc.json b/.eslintrc.json index 55937f3b4..51e3f1db5 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -119,7 +119,12 @@ "no-mixed-operators": 2, "no-multi-assign": 2, "no-unneeded-ternary": 2, - "object-property-newline": 2, + "object-property-newline": [ + 2, + { + "allowAllPropertiesOnSameLine": true + } + ], "operator-linebreak": 2, "quote-props": [ 2, diff --git a/packages/commercetools/api-client/src/api/getMe/defaultQuery.ts b/packages/commercetools/api-client/src/api/getMe/defaultQuery.ts index b501513b2..4c069acbd 100644 --- a/packages/commercetools/api-client/src/api/getMe/defaultQuery.ts +++ b/packages/commercetools/api-client/src/api/getMe/defaultQuery.ts @@ -1,5 +1,5 @@ import gql from 'graphql-tag'; -import { CartFragment, CustomerFragment } from './../../fragments'; +import { CartFragment, CustomerFragment, OrderFragment } from './../../fragments'; const basicProfile = gql` ${CartFragment} @@ -16,6 +16,7 @@ const basicProfile = gql` const fullProfile = gql` ${CartFragment} ${CustomerFragment} + ${OrderFragment} query getMe($locale: Locale!) { me { @@ -25,6 +26,11 @@ const fullProfile = gql` customer { ...DefaultCustomer } + orders { + results { + ...DefaultOrder + } + } } } `; diff --git a/packages/commercetools/api-client/src/fragments/index.ts b/packages/commercetools/api-client/src/fragments/index.ts index d9d7136d8..a6449a918 100644 --- a/packages/commercetools/api-client/src/fragments/index.ts +++ b/packages/commercetools/api-client/src/fragments/index.ts @@ -143,6 +143,7 @@ export const OrderFragment = ` orderState id version + createdAt } `; diff --git a/packages/commercetools/composables/src/useUser/index.ts b/packages/commercetools/composables/src/useUser/index.ts index ebfad9ff5..74adbc0fc 100644 --- a/packages/commercetools/composables/src/useUser/index.ts +++ b/packages/commercetools/composables/src/useUser/index.ts @@ -1,6 +1,6 @@ import { ref, Ref, watch, computed } from '@vue/composition-api'; import { UseUser, AgnosticUserLogin, AgnosticUserRegister } from '@vue-storefront/interfaces'; -import { Customer, CustomerSignMeUpDraft, CustomerSignMeInDraft } from '@vue-storefront/commercetools-api/lib/src/types/GraphQL'; +import { Customer, CustomerSignMeUpDraft, CustomerSignMeInDraft, Order } from '@vue-storefront/commercetools-api/lib/src/types/GraphQL'; import { customerSignMeUp, customerSignMeIn, @@ -9,13 +9,13 @@ import { } from '@vue-storefront/commercetools-api'; import { cart } from './../useCart'; -type UserRef = Ref type RegisterFn = (userData: AgnosticUserRegister) => Promise type LoginFn = (userData: AgnosticUserLogin) => Promise type LogoutFn = () => Promise type UserData = CustomerSignMeUpDraft | CustomerSignMeInDraft -const user: UserRef = ref({}); +const user: Ref = ref({}); +const orders: Ref = ref([]); const loading = ref(false); const error = ref(null); const isAuthenticated = computed(() => user.value && Object.keys(user.value).length > 0); @@ -33,7 +33,7 @@ const authenticate = async (userData: UserData, fn) => { loading.value = false; }; -export default function useUser(): UseUser { +export default function useUser(): UseUser, RegisterFn, LoginFn, LogoutFn, Ref> { watch(user, async () => { if (isAuthenticated.value) { return; @@ -44,7 +44,9 @@ export default function useUser(): UseUser ({ customerSignMeUp: jest.fn(), customerSignMeIn: jest.fn(), customerSignOut: jest.fn(), - getMe: () => ({ data: { me: { customer: { firstName: 'loaded customer', - lastName: 'loaded customer' } } } }) + getMe: () => ({ + data: { + me: { + customer: { + firstName: 'loaded customer', + lastName: 'loaded customer' + }, + orders: { + results: [] + } + } + } + }) })); describe('[commercetools-composables] useUser', () => { @@ -16,8 +27,12 @@ describe('[commercetools-composables] useUser', () => { }); it('registers new customer', async () => { - const user = { customer: { firstName: 'john', - lastName: 'doe' } }; + const user = { + customer: { + firstName: 'john', + lastName: 'doe' + } + }; (customerSignMeUp as any).mockReturnValue(Promise.resolve({ data: { user } })); const wrapper = mountComposable(useUser); @@ -33,16 +48,22 @@ describe('[commercetools-composables] useUser', () => { }); it('login customer and log out', async () => { - const user = { customer: { firstName: 'john', - lastName: 'doe' } }; + const user = { + customer: { + firstName: 'john', + lastName: 'doe' + } + }; (customerSignMeIn as any).mockReturnValue(Promise.resolve({ data: { user } })); const wrapper = mountComposable(useUser); await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick(); - wrapper.vm.$data.login({ email: 'john@doe.com', - password: '123' }); + wrapper.vm.$data.login({ + email: 'john@doe.com', + password: '123' + }); expect(wrapper.vm.$data.loading).toBeTruthy(); await wrapper.vm.$nextTick(); @@ -71,4 +92,12 @@ describe('[commercetools-composables] useUser', () => { lastName: 'loaded customer' }); }); + + it('loads current customer with orders', async () => { + const wrapper = mountComposable(useUser); + await wrapper.vm.$nextTick(); + await wrapper.vm.$nextTick(); + expect(wrapper.vm.$data.orders).toEqual([]); + }); + }); diff --git a/packages/commercetools/helpers/src/index.ts b/packages/commercetools/helpers/src/index.ts index 1a5485ec0..8c796b333 100644 --- a/packages/commercetools/helpers/src/index.ts +++ b/packages/commercetools/helpers/src/index.ts @@ -1,11 +1,23 @@ import { - UiMediaGalleryItem, - UiCategory, AgnosticProductAttribute, - AgnosticTotals + AgnosticTotals, + UiCategory, + UiMediaGalleryItem } from '@vue-storefront/interfaces'; -import { ProductVariant, Image, Category, Cart, LineItem, ShippingMethod, Customer } from './types/GraphQL'; -import { formatAttributeList, getVariantByAttributes } from './_utils'; +import { + Cart, + Category, + Customer, + Image, + LineItem, + Order, + ProductVariant, + ShippingMethod +} from './types/GraphQL'; +import { + formatAttributeList, + getVariantByAttributes +} from './_utils'; interface ProductVariantFilters { master?: boolean; @@ -76,8 +88,10 @@ export const getProductAttributes = (products: ProductVariant[] | ProductVariant ...prev, [curr.name]: isSingleProduct ? curr.value : [ ...(prev[curr.name] || []), - { value: curr.value, - label: curr.label } + { + value: curr.value, + label: curr.label + } ] }); @@ -201,3 +215,13 @@ export const getUserFirstName = (user: Customer): string => user ? user.firstNam export const getUserLastName = (user: Customer): string => user ? user.lastName : ''; export const getUserFullName = (user: Customer): string => user ? `${user.firstName} ${user.lastName}` : ''; + +// Order + +export const getOrderDate = (order: Order): string => order?.createdAt || ''; + +export const getOrderNumber = (order: Order): string => order?.id || ''; + +export const getOrderStatus = (order: Order): string => order?.orderState || ''; + +export const getOrderTotal = (order: Order): number | null => order ? order.totalPrice.centAmount / 100 : null; diff --git a/packages/commercetools/helpers/tests/orderHelpers.spec.ts b/packages/commercetools/helpers/tests/orderHelpers.spec.ts new file mode 100644 index 000000000..ad5d9a4e6 --- /dev/null +++ b/packages/commercetools/helpers/tests/orderHelpers.spec.ts @@ -0,0 +1,42 @@ +import { + getOrderDate, + getOrderNumber, + getOrderStatus, + getOrderTotal +} from '../src'; +import { OrderState, Order } from '../src/types/GraphQL'; + +const order: Order = { + createdAt: 123456789, + id: '645ygdf', + orderState: OrderState.Complete, + totalPrice: { + centAmount: 12345, + currencyCode: 'USD' + } +} as any; + +describe('[commercetools-helpers] order helpers', () => { + it('returns default values', () => { + expect(getOrderDate(null)).toBe(''); + expect(getOrderNumber(null)).toBe(''); + expect(getOrderStatus(null)).toBe(''); + expect(getOrderTotal(null)).toBe(null); + }); + + it('returns date', () => { + expect(getOrderDate(order)).toEqual(123456789); + }); + + it('returns order number', () => { + expect(getOrderNumber(order)).toEqual('645ygdf'); + }); + + it('returns status', () => { + expect(getOrderStatus(order)).toEqual(OrderState.Complete); + }); + + it('returns total gross', () => { + expect(getOrderTotal(order)).toEqual(123.45); + }); +}); diff --git a/packages/commercetools/theme/pages/Checkout.vue b/packages/commercetools/theme/pages/Checkout.vue index ad927a2e3..9ff4bcbb1 100644 --- a/packages/commercetools/theme/pages/Checkout.vue +++ b/packages/commercetools/theme/pages/Checkout.vue @@ -51,7 +51,7 @@ export default { CartPreview, OrderReview }, - setup(context) { + setup(props, context) { const showCartPreview = ref(true); const currentStep = ref(0); diff --git a/packages/core/interfaces/index.ts b/packages/core/interfaces/index.ts index 6873c957c..b9ee7662e 100644 --- a/packages/core/interfaces/index.ts +++ b/packages/core/interfaces/index.ts @@ -14,8 +14,10 @@ export interface UseUser REGISTER, LOGIN, LOGOUT, + ORDERS > { user: USER; + orders: ORDERS; register: REGISTER; login: LOGIN; logout: LOGOUT; diff --git a/packages/core/theme-module/theme/pages/MyAccount/OrderHistory.vue b/packages/core/theme-module/theme/pages/MyAccount/OrderHistory.vue index 4506bc09f..26082d15b 100644 --- a/packages/core/theme-module/theme/pages/MyAccount/OrderHistory.vue +++ b/packages/core/theme-module/theme/pages/MyAccount/OrderHistory.vue @@ -1,11 +1,11 @@