Skip to content

Commit

Permalink
Merge pull request #89 from vuestorefront/feat-#82/checkout-middleware
Browse files Browse the repository at this point in the history
feat: #82/checkout middleware
  • Loading branch information
Baroshem committed Sep 14, 2021
2 parents b364e6d + d3c0ea3 commit da02273
Show file tree
Hide file tree
Showing 11 changed files with 92 additions and 3 deletions.
1 change: 1 addition & 0 deletions docs/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ module.exports = {
['/theme/customer-checkout', 'Customer step in checkout'],
['/theme/composables', 'Composables'],
['/theme/helpers', 'Helpers'],
['/theme/checkout-middleware', 'Checkout middleware'],
]
},
{
Expand Down
1 change: 1 addition & 0 deletions docs/changelog/1.0.0-beta.2.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@
* [Docs]: generate API Client reference in the docs [#45](https://github.com/vuestorefront/vendure/issues/45)
* [Docs]: add section about theme in docs [#55](https://github.com/vuestorefront/vendure/issues/55)
* [Feature]: update packages due to security report [#85](https://github.com/vuestorefront/vendure/issues/85)
* [Feature]: implement checkout middleware and fix payment error [#82](https://github.com/vuestorefront/vendure/issues/82)
14 changes: 14 additions & 0 deletions docs/theme/checkout-middleware.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Checkout middleware

Router middleware responsible for checking if customer can visit certain steps of checkout page.
Uses following helpers to verify if a page can be displayed to the customer:

* `canEnterPayment`

* `canEnterThankYou`

* `canEnterShipping`

* `canEnterBilling`

If a helper returns false, customer will be redirected to homepage.
12 changes: 12 additions & 0 deletions docs/theme/helpers.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ const getTreeWithoutEmptyCategories = (categoryTree: AgnosticCategoryTree[]): Ag
* `EMAIL_ADDRESS_CONFLICT_ERROR` - Vendure error when a customer email was already used
* `ARRANGING_PAYMENT` - state in checkout that needs to be transitioned in order to correctly process checkout.
## Product
* `getProductVariantByConfiguration` - returns a product variant that was configures from options (i.e. `screen-size`, `ram`)
Expand All @@ -37,3 +39,13 @@ const mapOrderAddressToAddressForm = (orderAddress: OrderAddress): AddressForm

const getCalculatedPrice = (price: number): number
```
## Checkout
* `canEnterPayment` - verifies if customer can enter this state
* `canEnterThankYou` - verifies if customer can enter this state
* `canEnterShipping` - verifies if customer can enter this state
* `canEnterBilling` - verifies if customer can enter this state
2 changes: 1 addition & 1 deletion packages/composables/src/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export type SearchResultValue<SEARCH_DATA, SEARCH_INPUT> = {
input?: SEARCH_INPUT;
}

export { OrderAddress } from '@vue-storefront/vendure-api';
export { OrderAddress, Order } from '@vue-storefront/vendure-api';

// TODO: Replace later with types from vendure-api after implementing api-client functions
export interface ForgotPasswordResult {
Expand Down
18 changes: 18 additions & 0 deletions packages/theme/helpers/checkout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Context } from '@nuxt/types';
import { Order } from '@vue-storefront/vendure';
import { ARRANGING_PAYMENT } from './constants';

export const canEnterThankYou = (context: Context): boolean => Boolean(context.route.query?.order);

export const canEnterShipping = (cart: Order): boolean => Boolean(cart?.customer);

export const canEnterBilling = (cart: Order): boolean => Boolean(cart?.shippingAddress?.streetLine1 && cart?.shippingAddress?.country);

export const canEnterPayment = (cart: Order): boolean => canEnterShipping(cart) && canEnterBilling(cart) && cart?.shipping && cart?.state === ARRANGING_PAYMENT;

export enum CheckoutSteps {
Shipping = 'shipping',
Billing = 'billing',
Payment = 'payment',
ThankYou = 'thank-you'
}
1 change: 1 addition & 0 deletions packages/theme/helpers/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export const COUNTRIES = [
];

export const EMAIL_ADDRESS_CONFLICT_ERROR = 'EMAIL_ADDRESS_CONFLICT_ERROR';
export const ARRANGING_PAYMENT = 'ArrangingPayment';
1 change: 1 addition & 0 deletions packages/theme/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './category';
export * from './shipping-billing';
export * from './constants';
export * from './product';
export * from './checkout';
26 changes: 26 additions & 0 deletions packages/theme/middleware/checkout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { canEnterShipping, canEnterBilling, canEnterPayment, canEnterThankYou, CheckoutSteps } from '../helpers';

export default async ({ app, $vsf }) => {
const currentPath = app.context.route.fullPath.split('/checkout/')[1];

if (!currentPath) return;

const cart = await $vsf.$vendure.api.getCart();
const activeCart = cart?.data?.activeOrder;

if (!cart?.data || !activeCart) return;

if (currentPath === CheckoutSteps.Shipping && !canEnterShipping(activeCart)) {
app.context.redirect('/');

} else if (currentPath === CheckoutSteps.Billing && !canEnterBilling(activeCart)) {
app.context.redirect('/');

} else if (currentPath === CheckoutSteps.Payment && !canEnterPayment(activeCart)) {
app.context.redirect('/');

} else if (currentPath === CheckoutSteps.ThankYou && !canEnterThankYou(app.context)) {
app.context.redirect('/');

}
};
3 changes: 2 additions & 1 deletion packages/theme/nuxt.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@ export default {
extendRoutes(routes) {
getRoutes(`${__dirname}/_theme`)
.forEach((route) => routes.unshift(route));
}
},
middleware: ['checkout'],
},
publicRuntimeConfig: {
theme
Expand Down
16 changes: 15 additions & 1 deletion packages/theme/pages/Checkout/Customer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,11 @@ import {
SfButton,
SfSelect
} from '@storefront-ui/vue';
import { ref } from '@vue/composition-api';
import { ref, onMounted } from '@vue/composition-api';
import { required, min, digits, email } from 'vee-validate/dist/rules';
import { ValidationProvider, ValidationObserver, extend } from 'vee-validate';
import { useVSFContext } from '@vue-storefront/core';
import { useCart } from '@vue-storefront/vendure';
import { EMAIL_ADDRESS_CONFLICT_ERROR } from '~/helpers';
extend('required', {
Expand Down Expand Up @@ -122,6 +123,7 @@ export default {
setup (_, { root }) {
const isFormSubmitted = ref(false);
const { $vendure } = useVSFContext();
const { cart, load } = useCart();
const errorMessage = ref('');
const form = ref({
Expand All @@ -140,6 +142,18 @@ export default {
isFormSubmitted.value = true;
};
onMounted(async () => {
await load();
const customer = cart?.value.customer;
if (customer) {
form.value = {
firstName: customer?.firstName,
lastName: customer?.lastName,
emailAddress: customer?.emailAddress
};
}
});
return {
isFormSubmitted,
form,
Expand Down

0 comments on commit da02273

Please sign in to comment.