Merge pull request #587 from Safelite/feature/digital/SSR-1148
Adds Cart Footer
This commit is contained in:
commit
5604d089ea
5 changed files with 170 additions and 67 deletions
|
|
@ -5,5 +5,12 @@ Object {
|
|||
"baseServiceLineItems": Array [],
|
||||
"deductible": null,
|
||||
"isExpanded": false,
|
||||
"widget": Object {
|
||||
"amountDue": "AmountDueTextWidget",
|
||||
"basePrice": "BasePriceWidget",
|
||||
"deductible": "DeductibleWidget",
|
||||
"salesTax": "SalesTaxWidget",
|
||||
"subtotal": "SubtotalWidget",
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -121,6 +121,58 @@ describe('cart-dropdown component', () => {
|
|||
// Assert
|
||||
expect(cartBasePrice.exists()).toBeTruthy();
|
||||
});
|
||||
test('cart footer', () => {
|
||||
// Arrange
|
||||
const reference = '#cart-footer';
|
||||
const isExpanded = true;
|
||||
const initialData = { isExpanded };
|
||||
const { wrapper } = getMountedComponent({}, {}, initialData);
|
||||
|
||||
// Act
|
||||
const cartFooter = wrapper.find(reference);
|
||||
|
||||
// Assert
|
||||
expect(cartFooter.exists()).toBeTruthy();
|
||||
});
|
||||
test('subtotal', () => {
|
||||
// Arrange
|
||||
const reference = '#cart-subtotal';
|
||||
const isExpanded = true;
|
||||
const initialData = { isExpanded };
|
||||
const { wrapper } = getMountedComponent({}, {}, initialData);
|
||||
|
||||
// Act
|
||||
const subtotal = wrapper.find(reference);
|
||||
|
||||
// Assert
|
||||
expect(subtotal.exists()).toBeTruthy();
|
||||
});
|
||||
test('tax', () => {
|
||||
// Arrange
|
||||
const reference = '#cart-sales-tax';
|
||||
const isExpanded = true;
|
||||
const initialData = { isExpanded };
|
||||
const { wrapper } = getMountedComponent({}, {}, initialData);
|
||||
|
||||
// Act
|
||||
const salesTax = wrapper.find(reference);
|
||||
|
||||
// Assert
|
||||
expect(salesTax.exists()).toBeTruthy();
|
||||
});
|
||||
test('bottom amount due', () => {
|
||||
// Arrange
|
||||
const reference = '#bottom-amount-due';
|
||||
const isExpanded = true;
|
||||
const initialData = { isExpanded };
|
||||
const { wrapper } = getMountedComponent({}, {}, initialData);
|
||||
|
||||
// Act
|
||||
const bottomAmountDue = wrapper.find(reference);
|
||||
|
||||
// Assert
|
||||
expect(bottomAmountDue.exists()).toBeTruthy();
|
||||
});
|
||||
});
|
||||
describe('does not display', () => {
|
||||
test('cart deductible when showDeductibleLineItem is false', () => {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div :class="[isExpanded ? 'pb-3' : 'pb-4']">
|
||||
<div :class="[isExpanded ? 'pb-5' : 'pb-4']">
|
||||
<div
|
||||
id="cart-dropdown-head"
|
||||
class="row cart-toggle flex align-items-center pt-4"
|
||||
|
|
@ -9,50 +9,73 @@
|
|||
aria-label="expand cart details"
|
||||
href="javascript:void(0)"
|
||||
class="col d-flex justify-content-between py-0">
|
||||
<span class="cart-label color-black">{{ amountDueLabel }}</span>
|
||||
<span class="cart-label amount-due">{{ getDisplayed(amountDue) }}</span>
|
||||
<span class="color-black">{{ amountDueLabel }}</span>
|
||||
<span class="color-green">{{ getDisplayed(amountDue) }}</span>
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
id="cart-table"
|
||||
class="cart-table">
|
||||
<!-- Deductible Line Item -->
|
||||
<div
|
||||
id="cart-deductible-or-base-price"
|
||||
class="mt-4 cart-line-item color-gray-100 px-5 py-1">
|
||||
id="cart-line-items"
|
||||
class="color-darker-gray">
|
||||
<div
|
||||
v-if="showDeductibleLineItem"
|
||||
id="cart-deductible"
|
||||
class="d-flex justify-content-between align-items-center">
|
||||
<span
|
||||
id="deductible-label"
|
||||
class="cart-label">{{ deductibleLabel }}</span>
|
||||
<span id="deductible-value">{{ getDisplayed(deductible) }}</span>
|
||||
id="cart-deductible-or-base-price"
|
||||
class="cart-deductible-or-base-price">
|
||||
<div
|
||||
v-if="showDeductibleLineItem"
|
||||
id="cart-deductible"
|
||||
class="d-flex justify-content-between align-items-center">
|
||||
<span id="deductible-label">{{ deductibleLabel }}</span>
|
||||
<span id="deductible-value">{{ getDisplayed(deductible) }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
id="cart-base-price"
|
||||
class="d-flex justify-content-between align-items-center">
|
||||
<span id="base-price-label">{{ basePriceLabel }}</span>
|
||||
<span id="base-price-value">{{ getDisplayed(baseServicePrice) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
id="cart-base-price"
|
||||
class="d-flex justify-content-between align-items-center">
|
||||
<span
|
||||
id="base-price-label"
|
||||
class="cart-label">{{ basePriceLabel }}</span>
|
||||
<span id="base-price-value">{{ getDisplayed(baseServicePrice) }}</span>
|
||||
|
||||
<!-- Packaged Cart Items -->
|
||||
|
||||
<!-- Nonpackaged Cart Items -->
|
||||
<!-- This will be a loop when this is implemented -->
|
||||
<div class="non-packaged-cart-item">
|
||||
<textLink
|
||||
linkType="text"
|
||||
text="Recycling"
|
||||
href="javascript:void(0)"
|
||||
@clickEvent="openModal(recyclingModalCmsWidgetName)" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Packaged Cart Items -->
|
||||
|
||||
<!-- Nonpackaged Cart Items -->
|
||||
<!-- This will be a loop when this is implemented -->
|
||||
<div class="non-packaged-cart-item">
|
||||
<textLink
|
||||
linkType="text"
|
||||
text="Recycling"
|
||||
href="javascript:void(0)"
|
||||
@clickEvent="openModal(recyclingModalCmsWidgetName)" />
|
||||
<div
|
||||
id="cart-footer"
|
||||
class="cart-footer">
|
||||
<div
|
||||
id="cart-subtotal-and-tax"
|
||||
class="subtotal-and-tax">
|
||||
<div
|
||||
id="cart-subtotal"
|
||||
class="col d-flex justify-content-between">
|
||||
<span id="subtotal-label">{{ subtotalLabel }}</span>
|
||||
<span id="subtotal-value">{{ getDisplayed(subTotal) }}</span>
|
||||
</div>
|
||||
<div
|
||||
id="cart-sales-tax"
|
||||
class="pt-1 col d-flex justify-content-between">
|
||||
<span id="sales-tax-label">{{ salesTaxLabel }}</span>
|
||||
<span id="sales-tax-value">{{ getDisplayed(salesTax) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
id="bottom-amount-due"
|
||||
class="bottom-amount-due col d-flex justify-content-between">
|
||||
<span id="bottom-amount-due-label">{{ amountDueLabel }}</span>
|
||||
<span id="bottom-amount-due-value">{{ getDisplayed(amountDue) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Sub total, sales tax, total columns -->
|
||||
</div>
|
||||
<contentGroupModal
|
||||
ref="RecycleModal"
|
||||
|
|
@ -69,6 +92,7 @@ import textBlock from '@/digital-components/text-block/text-block.vue';
|
|||
import textLink from '@/ux-components/text-link/text-link.vue';
|
||||
import getPriceOfLineItems from '@/helpers/price-calculator.js';
|
||||
import { formatAmountInDollars } from '@/helpers/text-helper.js';
|
||||
import widgetFields from '@/constants/cms-widget-fields.js';
|
||||
|
||||
const VERIFYING_COVERAGE = 'Verifying coverage';
|
||||
|
||||
|
|
@ -78,9 +102,6 @@ export default {
|
|||
textBlock,
|
||||
textLink },
|
||||
props: {
|
||||
amountDueLabel: String,
|
||||
basePriceLabel: String,
|
||||
deductibleLabel: String,
|
||||
recyclingModalCmsWidgetName: String,
|
||||
showAsPaid: Boolean
|
||||
},
|
||||
|
|
@ -95,7 +116,14 @@ export default {
|
|||
return {
|
||||
deductible: currentDeductible,
|
||||
baseServiceLineItems,
|
||||
isExpanded: false
|
||||
isExpanded: false,
|
||||
widget: {
|
||||
amountDue: 'AmountDueTextWidget',
|
||||
deductible: 'DeductibleWidget',
|
||||
basePrice: 'BasePriceWidget',
|
||||
subtotal: 'SubtotalWidget',
|
||||
salesTax: 'SalesTaxWidget'
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -120,6 +148,21 @@ export default {
|
|||
return this.showAsPaid
|
||||
? 0
|
||||
: this.subTotal + this.salesTax;
|
||||
},
|
||||
amountDueLabel() {
|
||||
return this.getCmsContent(this.widget.amountDue, widgetFields.TEXT_BLOCK_WIDGET.TEXT);
|
||||
},
|
||||
deductibleLabel() {
|
||||
return this.getCmsContent(this.widget.deductible, widgetFields.TEXT_BLOCK_WIDGET.TEXT);
|
||||
},
|
||||
basePriceLabel() {
|
||||
return this.getCmsContent(this.widget.basePrice, widgetFields.TEXT_BLOCK_WIDGET.TEXT);
|
||||
},
|
||||
subtotalLabel() {
|
||||
return this.getCmsContent(this.widget.subtotal, widgetFields.TEXT_BLOCK_WIDGET.TEXT);
|
||||
},
|
||||
salesTaxLabel() {
|
||||
return this.getCmsContent(this.widget.salesTax, widgetFields.TEXT_BLOCK_WIDGET.TEXT);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
@ -136,7 +179,6 @@ export default {
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
@ -145,11 +187,12 @@ export default {
|
|||
.color-black {
|
||||
color: $black;
|
||||
}
|
||||
.color-gray-100 {
|
||||
background-color: $gray-100;
|
||||
|
||||
.color-green {
|
||||
color: $green;
|
||||
}
|
||||
|
||||
.cart-line-item {
|
||||
.color-darker-gray {
|
||||
color: $darker-gray;
|
||||
}
|
||||
|
||||
|
|
@ -158,6 +201,29 @@ export default {
|
|||
transition: all 350ms ease-in;
|
||||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
|
||||
.cart-deductible-or-base-price {
|
||||
background-color: $gray-100;
|
||||
margin-top: 1rem;
|
||||
padding: 0.25rem 1.5rem;
|
||||
}
|
||||
|
||||
.cart-footer {
|
||||
border-top: 1px solid $green;
|
||||
}
|
||||
|
||||
.subtotal-and-tax {
|
||||
background-color: $green-150;
|
||||
font-weight: $font-weight-bold;
|
||||
color: $black;
|
||||
padding: 0.25rem 1.5rem;
|
||||
}
|
||||
|
||||
.bottom-amount-due {
|
||||
color: $white;
|
||||
background-color: $green;
|
||||
padding: 0.25rem 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.modal-content a.external-text) {
|
||||
|
|
@ -175,6 +241,8 @@ export default {
|
|||
}
|
||||
|
||||
.cart-toggle {
|
||||
font-weight: $font-weight-bold;
|
||||
|
||||
&:after {
|
||||
content: "";
|
||||
transition: all 0.5s ease;
|
||||
|
|
@ -201,13 +269,6 @@ export default {
|
|||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
.cart-label {
|
||||
font-weight: $font-weight-bold;
|
||||
line-height: 1.625;
|
||||
}
|
||||
.amount-due {
|
||||
color: $green;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -21,9 +21,6 @@
|
|||
<hr class="my-0" />
|
||||
<cartDropdown
|
||||
:showAsPaid="false"
|
||||
:amountDueLabel="amountDueText"
|
||||
:deductibleLabel="deductibleLabel"
|
||||
:basePriceLabel="basePriceLabel"
|
||||
recyclingModalCmsWidgetName="RecycleModal" />
|
||||
<hr class="mt-0 mb-5" />
|
||||
<div>Pia Alert Placeholder</div>
|
||||
|
|
@ -61,7 +58,6 @@ import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
|
|||
import { paymentMethods } from '@/constants/payment-method-constants';
|
||||
import globalRules from '@/constants/global-rules';
|
||||
import { Form } from 'vee-validate';
|
||||
import widgetFields from '@/constants/cms-widget-fields.js';
|
||||
|
||||
import { AppointmentTypeStrings } from '@/constants/schedule-constants';
|
||||
|
||||
|
|
@ -109,11 +105,6 @@ export default {
|
|||
paymentMethodInternalModel: this.getPaymentMethodFromStore(),
|
||||
rules: {
|
||||
optionRequired: globalRules.OPTION_REQUIRED
|
||||
},
|
||||
widget: {
|
||||
amountDue: 'AmountDueTextWidget',
|
||||
deductible: 'DeductibleWidget',
|
||||
basePrice: 'BasePriceWidget'
|
||||
}
|
||||
};
|
||||
},
|
||||
|
|
@ -132,15 +123,6 @@ export default {
|
|||
},
|
||||
paymentMethod() {
|
||||
return this.paymentMethodInternalModel;
|
||||
},
|
||||
amountDueText() {
|
||||
return this.getCmsContent(this.widget.amountDue, widgetFields.TEXT_BLOCK_WIDGET.TEXT);
|
||||
},
|
||||
deductibleLabel() {
|
||||
return this.getCmsContent(this.widget.deductible, widgetFields.TEXT_BLOCK_WIDGET.TEXT);
|
||||
},
|
||||
basePriceLabel() {
|
||||
return this.getCmsContent(this.widget.basePrice, widgetFields.TEXT_BLOCK_WIDGET.TEXT);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ $red-900: #330300;
|
|||
|
||||
// Greens
|
||||
$green-100: #e3f2ea;
|
||||
$green-150: #e6f2ec;
|
||||
$green-200: #bcedd4;
|
||||
$green-300: #94d7b6;
|
||||
$green-400: #5abc8c; // Used in theme
|
||||
|
|
|
|||
Loading…
Reference in a new issue