Skip to content

Commit

Permalink
Merge pull request #5628 from vuestorefront/states-as-select
Browse files Browse the repository at this point in the history
feat: SfSelect for State
  • Loading branch information
Fifciu committed Mar 10, 2021
2 parents c759197 + 812002b commit 8a75e90
Show file tree
Hide file tree
Showing 17 changed files with 240 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,24 @@ describe('[commercetools-getters] cart helpers', () => {
expect(getCartShippingPrice(cart)).toEqual(4.44);
expect(getCartShippingPrice({ ...cart,
shippingInfo: null })).toEqual(0);

expect(getCartShippingPrice({ ...cart,
shippingInfo: {
shippingMethod: {
zoneRates: [
{
shippingRates: [
{
freeAbove: {
centAmount: 1000
}
}
]
}
]
}
}
})).toEqual(0);
});

it('returns cart total items', () => {
Expand Down
12 changes: 11 additions & 1 deletion packages/commercetools/composables/src/getters/cartGetters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,17 @@ export const getCartTotals = (cart: Cart): AgnosticTotals => {
};
};

export const getCartShippingPrice = (cart: Cart): number => cart && cart.shippingInfo ? cart.shippingInfo.price.centAmount / 100 : 0;
export const getCartShippingPrice = (cart: Cart): number => {
const total = cart?.totalPrice?.centAmount;
const shippingInfo = cart?.shippingInfo;
const centAmount = shippingInfo?.shippingMethod?.zoneRates[0].shippingRates[0].freeAbove?.centAmount;

if (!shippingInfo || !total || (centAmount && total >= centAmount)) {
return 0;
}

return shippingInfo.price.centAmount / 100;
};

export const getCartTotalItems = (cart: Cart): number => {
if (!cart) {
Expand Down
16 changes: 5 additions & 11 deletions packages/commercetools/composables/src/helpers/internals/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
import enhanceProduct from './enhanceProduct';
import mapPaginationParams from './mapPaginationParams';
import getFiltersFromProductsAttributes from './getFiltersFromProductsAttributes';
import getCouponsFromCart from './getCouponsFromCart';

export {
enhanceProduct,
mapPaginationParams,
getFiltersFromProductsAttributes,
getCouponsFromCart
};
export { default as enhanceProduct } from './enhanceProduct';
export { default as mapPaginationParams } from './mapPaginationParams';
export { default as getFiltersFromProductsAttributes } from './getFiltersFromProductsAttributes';
export { default as getCouponsFromCart } from './getCouponsFromCart';
export { default as makeId } from './makeId';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default () => Math.random().toString().substr(2);
13 changes: 6 additions & 7 deletions packages/commercetools/composables/src/useUserBilling/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useUserBillingFactory, UseUserBillingFactoryParams, Context } from '@vue-storefront/core';
import { makeId } from '../helpers/internals';

const addresses: any[] = [
{
Expand All @@ -8,8 +9,8 @@ const addresses: any[] = [
streetName: 'Warsawska',
streetNumber: '24',
apartment: '193A',
city: 'Phoenix',
state: null,
city: 'Palo Alto',
state: 'California',
postalCode: '26-620',
country: 'US',
phone: '560123456',
Expand All @@ -24,8 +25,8 @@ const addresses: any[] = [
streetName: 'Starachowicka',
streetNumber: '20',
apartment: '193A',
city: 'Atlanta',
state: null,
city: 'Las Vegas',
state: 'Nevada',
postalCode: '53-603',
country: 'US',
phone: '560123456',
Expand All @@ -39,8 +40,6 @@ const billing = {
addresses
};

const findBiggestId = () => addresses.reduce((highest, { id }) => Math.max(highest, id), 0);

const disableOldDefault = () => {
const oldDefault = addresses.find(address => address.isDefault);
if (oldDefault) {
Expand All @@ -63,7 +62,7 @@ const params: UseUserBillingFactoryParams<any, any> = {

const newAddress = {
...params.address,
id: findBiggestId() + 1
id: makeId()
};

if (params.address.isDefault) {
Expand Down
13 changes: 6 additions & 7 deletions packages/commercetools/composables/src/useUserShipping/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useUserShippingFactory, UseUserShippingFactoryParams, Context } from '@vue-storefront/core';
import { makeId } from '../helpers/internals';

const addresses: any[] = [
{
Expand All @@ -8,8 +9,8 @@ const addresses: any[] = [
streetName: 'Warsawska',
streetNumber: '193A',
apartment: '193A',
city: 'Phoenix',
state: null,
city: 'Palo Alto',
state: 'California',
postalCode: '26-620',
country: 'US',
phone: '560123456',
Expand All @@ -24,8 +25,8 @@ const addresses: any[] = [
streetName: 'Starachowicka',
streetNumber: '193A',
apartment: '193A',
city: 'Atlanta',
state: null,
city: 'Las Vegas',
state: 'Nevada',
postalCode: '53-603',
country: 'US',
phone: '560123456',
Expand All @@ -39,8 +40,6 @@ const shipping = {
addresses
};

const findBiggestId = () => addresses.reduce((highest, { id }) => Math.max(highest, id), 0);

const disableOldDefault = () => {
const oldDefault = addresses.find(address => address.isDefault);
if (oldDefault) {
Expand All @@ -63,7 +62,7 @@ const params: UseUserShippingFactoryParams<any, any> = {

const newAddress = {
...params.address,
id: findBiggestId() + 1
id: makeId()
};

if (params.address.isDefault) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
<SfProperty
name="Shipping"
v-if="selectedShippingMethod && selectedShippingMethod.zoneRates"
:value="$n(getShippingMethodPrice(selectedShippingMethod), 'currency')"
:value="$n(getShippingMethodPrice(selectedShippingMethod, totals.total), 'currency')"
class="sf-property--full-width sf-property--large property"
/>
<SfProperty
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<template #label="{ label }">
<div class="sf-radio__label shipping__label">
<div>{{ label }}</div>
<div v-if="method && method.zoneRates">{{ $n(getShippingMethodPrice(method), 'currency') }}</div>
<div v-if="method && method.zoneRates">{{ $n(getShippingMethodPrice(method, totals.total), 'currency') }}</div>
</div>
</template>
<template #description="{ localizedDescription }">
Expand Down Expand Up @@ -59,7 +59,7 @@
</template>

<script>
import { useCart, useShippingProvider } from '@vue-storefront/commercetools';
import { useCart, useShippingProvider, cartGetters } from '@vue-storefront/commercetools';
import {
SfHeading,
SfButton,
Expand Down Expand Up @@ -122,6 +122,7 @@ export default {
load
} = useShippingProvider();
const selectedShippingMethod = computed(() => state.value && state.value.response);
const totals = computed(() => cartGetters.getTotals(cart.value));
const error = reactive({
loadMethods: null
Expand Down Expand Up @@ -176,6 +177,7 @@ export default {
selectedShippingMethod,
selectShippingMethod,
getShippingMethodPrice,
totals,
isShippingMethodStepCompleted,
loading,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,19 +77,29 @@
/>
</ValidationProvider>
<ValidationProvider
rules="required|min:2"
name="state"
:rules="!statesInSelectedCountry ? null : 'required|min:2'"
v-slot="{ errors }"
class="form__element"
slim
>
<SfInput
data-cy="billing-details-input_state"
<SfSelect
v-model="form.state"
name="state"
label="State/Province"
name="state"
class="form__element form__element--half form__element--half-even form__select sf-select--underlined"
required
:valid="!errors[0]"
:errorMessage="errors[0]"
/>
:disabled="!statesInSelectedCountry"
>
<SfSelectOption
v-for="state in statesInSelectedCountry"
:key="state"
:value="state"
>
{{ state }}
</SfSelectOption>
</SfSelect>
</ValidationProvider>
</div>
<div class="form__horizontal">
Expand Down Expand Up @@ -171,7 +181,7 @@ import {
} from '@storefront-ui/vue';
import { required, min, oneOf } from 'vee-validate/dist/rules';
import { ValidationProvider, ValidationObserver, extend } from 'vee-validate';
import { reactive } from '@vue/composition-api';
import { reactive, computed, watch } from '@vue/composition-api';
import { useVSFContext } from '@vue-storefront/core';
extend('required', {
Expand Down Expand Up @@ -249,10 +259,26 @@ export default {
});
};
const statesInSelectedCountry = computed(() => {
if (!form.country) {
return null;
}
const selectedCountry = config.countries.find(country => country.name === form.country);
return selectedCountry && selectedCountry.states;
});
watch(statesInSelectedCountry, statesInSelectedCountry => {
const countryHasStates = statesInSelectedCountry && statesInSelectedCountry.length;
if (!countryHasStates && form.state) {
form.state = null;
}
});
return {
form,
submitForm,
countries: config.countries
countries: config.countries,
statesInSelectedCountry
};
}
};
Expand All @@ -268,9 +294,10 @@ export default {
display: flex;
align-items: center;
--select-option-font-size: var(--font-size--lg);
flex-wrap: wrap;
::v-deep .sf-select__dropdown {
font-size: var(--font-size--lg);
margin: 0;
// margin: 0;
font-family: var(--font-family--secondary);
font-weight: var(--font-weight--normal);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,19 +77,29 @@
/>
</ValidationProvider>
<ValidationProvider
rules="required|min:2"
name="state"
:rules="!statesInSelectedCountry ? null : 'required|min:2'"
v-slot="{ errors }"
class="form__element"
slim
>
<SfInput
data-cy="shipping-details-input_state"
<SfSelect
v-model="form.state"
name="state"
label="State/Province"
name="state"
class="form__element form__element--half form__element--half-even form__select sf-select--underlined"
required
:valid="!errors[0]"
:errorMessage="errors[0]"
/>
:disabled="!statesInSelectedCountry"
>
<SfSelectOption
v-for="state in statesInSelectedCountry"
:key="state"
:value="state"
>
{{ state }}
</SfSelectOption>
</SfSelect>
</ValidationProvider>
</div>
<div class="form__horizontal">
Expand Down Expand Up @@ -170,7 +180,7 @@ import {
} from '@storefront-ui/vue';
import { required, min, oneOf } from 'vee-validate/dist/rules';
import { ValidationProvider, ValidationObserver, extend } from 'vee-validate';
import { reactive } from '@vue/composition-api';
import { reactive, computed, watch } from '@vue/composition-api';
import { useVSFContext } from '@vue-storefront/core';
extend('required', {
Expand Down Expand Up @@ -248,10 +258,26 @@ export default {
});
};
const statesInSelectedCountry = computed(() => {
if (!form.country) {
return null;
}
const selectedCountry = config.countries.find(country => country.name === form.country);
return selectedCountry && selectedCountry.states;
});
watch(statesInSelectedCountry, statesInSelectedCountry => {
const countryHasStates = statesInSelectedCountry && statesInSelectedCountry.length;
if (!countryHasStates && form.state) {
form.state = null;
}
});
return {
form,
submitForm,
countries: config.countries
countries: config.countries,
statesInSelectedCountry
};
}
};
Expand All @@ -267,9 +293,10 @@ export default {
display: flex;
align-items: center;
--select-option-font-size: var(--font-size--lg);
flex-wrap: wrap;
::v-deep .sf-select__dropdown {
font-size: var(--font-size--lg);
margin: 0;
// margin: 0;
font-family: var(--font-family--secondary);
font-weight: var(--font-weight--normal);
}
Expand Down
Loading

0 comments on commit 8a75e90

Please sign in to comment.