@lancom/shared 0.0.102 → 0.0.106

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/assets/js/api/admin.js +6 -0
  2. package/assets/js/models/print-area.js +8 -6
  3. package/assets/js/models/product-layers.js +3 -3
  4. package/assets/js/utils/fabric-helper.js +2 -4
  5. package/assets/js/utils/filters.js +7 -1
  6. package/assets/js/utils/prints.js +15 -4
  7. package/assets/js/utils/product.js +4 -4
  8. package/assets/scss/ui_kit/_table.scss +3 -0
  9. package/assets/scss/ui_kit/_typography.scss +6 -0
  10. package/components/checkout/order/address-form/address-form.vue +1 -0
  11. package/components/checkout/order/order-billing-information/order-billing-information.vue +7 -5
  12. package/components/checkout/payment/payment-cart/payment-cart.scss +2 -2
  13. package/components/common/color-picker.vue +6 -1
  14. package/components/common/file_uploader.vue +1 -1
  15. package/components/common/pricing_discounts_table/pricing-discounts-table.vue +14 -5
  16. package/components/common/pricing_table/pricing-table.scss +1 -3
  17. package/components/common/pricing_table/pricing-table.vue +13 -4
  18. package/components/common/products_list_dropdown/products-list-dropdown.vue +3 -1
  19. package/components/common/range/range.scss +23 -0
  20. package/components/common/range/range.vue +19 -0
  21. package/components/editor/editor.vue +3 -2
  22. package/components/editor/editor_layers/editor_layer_forms/editor_layer_form_text/editor-layer-form-text.vue +3 -1
  23. package/components/editor/editor_layers/editor_layers_toolbar/editor-layers-toolbar.vue +1 -0
  24. package/components/editor/editor_pricing/editor-pricing.vue +3 -123
  25. package/components/editor/editor_pricing/editor_pricing_details/editor-pricing-details.scss +0 -0
  26. package/components/editor/editor_pricing/editor_pricing_details/editor-pricing-details.vue +29 -0
  27. package/components/editor/editor_pricing/editor_pricing_details/editor_pricing_details_prints/editor-pricing-details-prints.scss +41 -0
  28. package/components/editor/editor_pricing/editor_pricing_details/editor_pricing_details_prints/editor-pricing-details-prints.vue +119 -0
  29. package/components/editor/editor_pricing/editor_pricing_details/editor_pricing_details_products/editor-pricing-details-products.scss +41 -0
  30. package/components/editor/editor_pricing/editor_pricing_details/editor_pricing_details_products/editor-pricing-details-products.vue +101 -0
  31. package/components/editor/editor_print_area_options/editor-print-area-options.vue +16 -15
  32. package/components/editor/editor_print_area_options/editor_print_area_option/editor-print-area-option.vue +12 -12
  33. package/components/editor/editor_product_details/editor-product-details.scss +1 -1
  34. package/components/editor/editor_product_details/editor-product-details.vue +22 -10
  35. package/components/editor/editor_workspace/editor-workspace.vue +10 -5
  36. package/components/editor/editor_workspace/editor_workspace_side/editor-workspace-side.vue +8 -5
  37. package/components/modals/cart_modal/cart-modal.vue +1 -1
  38. package/components/modals/order_modal/order-modal.vue +5 -7
  39. package/components/modals/payment_modal/payment-modal.vue +1 -1
  40. package/components/pricing/pricing_digital_printing/pricing-digital-printing.vue +1 -4
  41. package/components/pricing/pricing_example/pricing-example.scss +4 -1
  42. package/components/pricing/pricing_example/pricing-example.vue +106 -26
  43. package/components/pricing/pricing_garment/pricing-garment.scss +44 -31
  44. package/components/pricing/pricing_garment/pricing-garment.vue +24 -10
  45. package/components/pricing/pricing_main_section/pricing-main-section.scss +0 -1
  46. package/components/pricing/pricing_main_section/pricing-main-section.vue +6 -17
  47. package/components/pricing/pricing_print/pricing-print.scss +1 -1
  48. package/components/pricing/pricing_print/pricing-print.vue +19 -7
  49. package/components/pricing/pricing_products_calculator/pricing-products-calculator.scss +64 -0
  50. package/components/pricing/pricing_products_calculator/pricing-products-calculator.vue +86 -0
  51. package/components/pricing/pricing_products_calculator/pricing_product_calculator/pricing-product-calculator.scss +58 -0
  52. package/components/pricing/pricing_products_calculator/pricing_product_calculator/pricing-product-calculator.vue +296 -0
  53. package/components/pricing/pricing_products_calculator/pricing_product_calculator/pricing_product_print_calculator/pricing-product-print-calculator.scss +1 -0
  54. package/components/pricing/pricing_products_calculator/pricing_product_calculator/pricing_product_print_calculator/pricing-product-print-calculator.vue +26 -0
  55. package/components/pricing/pricing_products_calculator/pricing_product_calculator/print_size_icon/print-size-icon.scss +34 -0
  56. package/components/pricing/pricing_products_calculator/pricing_product_calculator/print_size_icon/print-size-icon.vue +55 -0
  57. package/components/pricing/pricing_screen_print/pricing-screen-print.vue +6 -3
  58. package/components/pricing/pricing_screen_printing/pricing-screen-printing.vue +1 -2
  59. package/components/product/gallery/gallery.scss +168 -0
  60. package/components/product/gallery/gallery.vue +252 -0
  61. package/components/product/layouts/product_fabric_and_size_info/product-fabric-and-size-info.vue +8 -6
  62. package/components/product/layouts/product_gallery/product-gallery.vue +10 -3
  63. package/components/product/layouts/product_size_table/product-size-table.vue +16 -39
  64. package/components/product/layouts/product_tier_prices/product-tier-prices.vue +3 -2
  65. package/components/product/product.vue +16 -5
  66. package/components/product/product_price_range/product-price-range.vue +20 -4
  67. package/components/product/product_prints_price_info/product_print_price_info/product_print_price_info_item/product-print-price-info-item.vue +14 -2
  68. package/components/product/product_prints_price_info/product_screen_print_price_info/product-screen-print-price-info.scss +5 -0
  69. package/components/product/product_prints_price_info/product_screen_print_price_info/product-screen-print-price-info.vue +53 -12
  70. package/components/product/product_sizes_info/product-sizes-info.vue +13 -2
  71. package/components/product/related_products/related-products.scss +34 -0
  72. package/components/product/related_products/related-products.vue +52 -0
  73. package/components/products/product_list/product-list.scss +2 -1
  74. package/components/products/product_list_product/product-list-product.scss +44 -20
  75. package/components/products/product_list_product/product-list-product.vue +6 -4
  76. package/components/products/products_aside/products-aside.vue +29 -4
  77. package/components/products/products_brands/products-brands.vue +9 -2
  78. package/components/products/products_filters/products-filters.vue +10 -0
  79. package/components/products/products_tags/products-tags.vue +7 -0
  80. package/components/products/products_types/products-types.vue +6 -1
  81. package/mixins/product-preview.js +1 -1
  82. package/nuxt.config.js +13 -1
  83. package/package.json +1 -1
  84. package/static/icons/{back_hoodie_a4_v.svg → back_hoodie_a4.svg} +0 -0
  85. package/static/icons/{back_hoodie_half_a4_h.svg → back_hoodie_half_a4.svg} +0 -0
  86. package/static/icons/{back_hoodie_rect10_l.svg → back_hoodie_rect10.svg} +0 -0
  87. package/static/icons/{back_polo_a4_v.svg → back_polo_a4.svg} +0 -0
  88. package/static/icons/{back_polo_half_a4_h.svg → back_polo_half_a4.svg} +0 -0
  89. package/static/icons/{back_polo_rect10_l.svg → back_polo_rect10.svg} +0 -0
  90. package/static/icons/{back_tee_a4_v.svg → back_tee_a4.svg} +0 -0
  91. package/static/icons/{back_tee_half_a4_h.svg → back_tee_half_a4.svg} +0 -0
  92. package/static/icons/{back_tee_rect10_l.svg → back_tee_rect10.svg} +0 -0
  93. package/static/icons/{front_hoodie_a4_v.svg → front_hoodie_a4.svg} +0 -0
  94. package/static/icons/{front_hoodie_half_a4_h.svg → front_hoodie_half_a4.svg} +0 -0
  95. package/static/icons/{front_hoodie_rect10_l.svg → front_hoodie_rect10.svg} +0 -0
  96. package/static/icons/{front_polo_a4_v.svg → front_polo_a4.svg} +0 -0
  97. package/static/icons/{front_polo_half_a4_h.svg → front_polo_half_a4.svg} +0 -0
  98. package/static/icons/{front_polo_rect10_l.svg → front_polo_rect10.svg} +0 -0
  99. package/static/icons/{front_tee_a4_v.svg → front_tee_a4.svg} +0 -0
  100. package/static/icons/{front_tee_half_a4_h.svg → front_tee_half_a4.svg} +0 -0
  101. package/static/icons/{front_tee_rect10_l.svg → front_tee_rect10.svg} +0 -0
  102. package/store/index.js +3 -1
  103. package/store/product.js +25 -14
  104. package/components/pricing/pricing_print/discounts_table/discounts-table.scss +0 -8
  105. package/components/pricing/pricing_print/discounts_table/discounts-table.vue +0 -91
  106. package/components/pricing/pricing_screen_print/discounts_table/discounts-table.scss +0 -14
  107. package/components/pricing/pricing_screen_print/discounts_table/discounts-table.vue +0 -78
@@ -4,12 +4,15 @@
4
4
  <div class="row PricingPrint__content">
5
5
  <div
6
6
  data-aos="aosFadeLeft"
7
- class="col-12 PricingPrint__col">
7
+ class="col-sm-4 col-12 PricingPrint__col">
8
8
  <h2 class="lc_h2">
9
- Digital printing price list
9
+ Digital print pricing
10
10
  </h2>
11
11
  <p class="PricingPrint__description">
12
- No setup costs. No minimum quantity. Price as per the print area
12
+ Smaller prints means we use less ink, more tees means we save time on order handling.
13
+ </p>
14
+ <p class="PricingPrint__description">
15
+ If you have a wholesale enquiry for <b>125 tees</b> or more, we can also screen print your tees with prices starting from <b>$2</b> to <b>$5</b> per print.
13
16
  </p>
14
17
  <div class="form-actions pull-left">
15
18
  <btn
@@ -21,9 +24,12 @@
21
24
  </div>
22
25
  <div
23
26
  data-aos="aosFadeRight"
24
- class="col-12 PricingPrint__col">
27
+ class="col-sm-8 col-12 PricingPrint__col">
25
28
  <div class="PricingPrint__table-container">
26
- <discounts-table :product="product" />
29
+ <product-print-price-info-item
30
+ :print="printType"
31
+ :visible-table-name="false"
32
+ :bordered="true" />
27
33
  </div>
28
34
  </div>
29
35
  </div>
@@ -33,18 +39,24 @@
33
39
 
34
40
  <script>
35
41
  import ContactUs from '@lancom/shared/components/asides/contact_us/contact-us';
36
- import DiscountsTable from './discounts_table/discounts-table';
42
+ import ProductPrintPriceInfoItem from '@lancom/shared/components/product/product_prints_price_info/product_print_price_info/product_print_price_info_item/product-print-price-info-item';
43
+ import { PRINT_TYPES } from '@lancom/shared/assets/js/constants/print-type';
37
44
 
38
45
  export default {
39
46
  name: 'PricingPrint',
40
47
  components: {
41
- DiscountsTable
48
+ ProductPrintPriceInfoItem
42
49
  },
43
50
  props: {
44
51
  product: {
45
52
  type: Object
46
53
  }
47
54
  },
55
+ computed: {
56
+ printType() {
57
+ return (this.product.printTypes || []).find(({ type }) => type === PRINT_TYPES.FULL_COLOUR);
58
+ }
59
+ },
48
60
  methods: {
49
61
  contactUs() {
50
62
  this.$aside.show(ContactUs);
@@ -0,0 +1,64 @@
1
+ @import "@/assets/scss/variables";
2
+ $product_types: tee, hoodie, polo;
3
+
4
+ .PricingProductsCalculator {
5
+ &__info {
6
+ margin-top: 30px;
7
+ }
8
+ &__product {
9
+ &-types {
10
+ display: grid;
11
+ grid-template-columns: repeat(3, 1fr);
12
+ grid-column-gap: 8px;
13
+ }
14
+ &-type {
15
+ position: relative;
16
+ &-info {
17
+ border-radius: 5px;
18
+ padding: 78px 25px 16px 25px;
19
+ text-align: center;
20
+ font-size: 14px;
21
+ line-height: 21px;
22
+ color: $gray;
23
+ background-color: #FFFFFF;
24
+ position: relative;
25
+ cursor: pointer;
26
+ transition: background-color .22s ease-in-out;
27
+ &:before {
28
+ content: '';
29
+ position: absolute;
30
+ top: 16px;
31
+ left: 0;
32
+ height: 50px;
33
+ width: 100%;
34
+ background-repeat: no-repeat;
35
+ background-size: contain;
36
+ background-position: center;
37
+ }
38
+ &.active {
39
+ background-color: $light_gray;
40
+ }
41
+ &.disabled {
42
+ opacity: .2;
43
+ pointer-events: none;
44
+ }
45
+ @each $type in $product_types {
46
+ &.#{$type}:before {
47
+ background-image: url(../../../static/icons/product_#{$type}.svg);
48
+ }
49
+ }
50
+ }
51
+ }
52
+ &-placeholder {
53
+ font-size: 14px;
54
+ line-height: 150%;
55
+ text-align: center;
56
+ color: $black;
57
+ position: absolute;
58
+ text-align: center;
59
+ top: 20px;
60
+ left: 0;
61
+ right: 0;
62
+ }
63
+ }
64
+ }
@@ -0,0 +1,86 @@
1
+ <template>
2
+ <section class="PricingProductsCalculator__wrapper">
3
+ <div class="col-12">
4
+ <div class="lc_h3">
5
+ Choose Product
6
+ </div>
7
+ <div class="PricingProductsCalculator__product-types">
8
+ <div
9
+ v-for="item in productTypes"
10
+ :key="item.type"
11
+ class="PricingProductsCalculator__product-type">
12
+ <div
13
+ class="PricingProductsCalculator__product-type-info"
14
+ :class="{
15
+ disabled: !item.product,
16
+ [item.type]: true,
17
+ active: item.product === activeProduct
18
+ }"
19
+ @click="activeProduct = item.product">
20
+ {{ item.label }}
21
+ <div
22
+ v-if="item.product"
23
+ class="lc_h3">
24
+ <product-price-range
25
+ :product="item.product"
26
+ :with-gst="true"
27
+ :without-gst="false"
28
+ :visible-price-info="false"
29
+ range-divider="to" />
30
+ </div>
31
+ </div>
32
+ <div
33
+ v-if="!item.product"
34
+ class="PricingProductsCalculator__product-placeholder">
35
+ Pricing <br /> coming soon
36
+ </div>
37
+ </div>
38
+ </div>
39
+ </div>
40
+ <div class="PricingProductsCalculator__info">
41
+ <pricing-product-calculator :product="activeProduct" />
42
+ </div>
43
+ </section>
44
+ </template>
45
+
46
+ <script>
47
+ import { PRODUCT_TYPES_LIST, PRODUCT_TYPES } from '@lancom/shared/assets/js/constants/product';
48
+ import ProductPriceRange from '@lancom/shared/components/product/product_price_range/product-price-range';
49
+ import PricingProductCalculator from './pricing_product_calculator/pricing-product-calculator';
50
+
51
+ export default {
52
+ name: 'PricingProductsCalculator',
53
+ components: {
54
+ PricingProductCalculator,
55
+ ProductPriceRange
56
+ },
57
+ props: {
58
+ products: {
59
+ type: Array,
60
+ required: true
61
+ }
62
+ },
63
+ data() {
64
+ return {
65
+ activeProduct: this.findProductByType(PRODUCT_TYPES.TEE)
66
+ };
67
+ },
68
+ computed: {
69
+ productTypes() {
70
+ return PRODUCT_TYPES_LIST.map(item => ({
71
+ ...item,
72
+ product: this.findProductByType(item.type)
73
+ }));
74
+ }
75
+ },
76
+ methods: {
77
+ findProductByType(type) {
78
+ return this.products.find(p => p.productType?.alias === type);
79
+ }
80
+ }
81
+ };
82
+ </script>
83
+
84
+ <style lang="scss" scoped>
85
+ @import 'pricing-products-calculator';
86
+ </style>
@@ -0,0 +1,58 @@
1
+ @import "@/assets/scss/variables";
2
+
3
+ .PricingProductCalculator {
4
+ &__prints {
5
+ margin-top: 20px;
6
+ }
7
+ &__icon {
8
+ height: 180px;
9
+ }
10
+ &__print-sizes {
11
+ display: flex;
12
+ width: 260px;
13
+ align-items: center;
14
+ flex-wrap: wrap;
15
+ }
16
+ &__print-size {
17
+ font-size: 16px;
18
+ line-height: 170%;
19
+ text-align: center;
20
+ color: $black;
21
+ background-color: $grey_3;
22
+ padding: 10px;
23
+ width: 120px;
24
+ margin: 4px;
25
+ cursor: pointer;
26
+ &--active {
27
+ color: $white;
28
+ background-color: $green;
29
+ }
30
+ &--full {
31
+ width: 248px;
32
+ }
33
+ }
34
+ &__delivery {
35
+ display: flex;
36
+ align-items: center;
37
+ &-postcode {
38
+ width: 300px;
39
+ margin-top: 15px;
40
+ margin-left: 20px;
41
+ }
42
+ }
43
+ &__breakdown {
44
+ font-size: 12px;
45
+ color: $gray;
46
+ border-bottom: 1px dashed $gray;
47
+ cursor: pointer;
48
+ }
49
+ &__cost {
50
+ font-size: 17px;
51
+ color: $black;
52
+ }
53
+ &__reprint {
54
+ font-size: 15px;
55
+ color: $gray;
56
+ margin-top: 10px;
57
+ }
58
+ }
@@ -0,0 +1,296 @@
1
+ <template>
2
+ <section class="PricingProductCalculator__wrapper">
3
+ <div class="lc_h3">
4
+ Print Details - {{ screenPrintMinQuantity }}
5
+ </div>
6
+ <div class="row">
7
+ <div
8
+ v-for="side in sides"
9
+ :key="side.type"
10
+ class="PricingProductCalculator__prints col-sm-6 col-12">
11
+ <div class="row">
12
+ <div class="col-4">
13
+ <PrintSizeIcon
14
+ class="PricingProductCalculator__icon"
15
+ :product="product"
16
+ :side="side" />
17
+ </div>
18
+ <div class="col-8">
19
+ <div class="PricingProductCalculator__print-sizes">
20
+ <div
21
+ v-for="size in side.printSizes"
22
+ :key="size._id"
23
+ class="PricingProductCalculator__print-size"
24
+ :class="{
25
+ 'PricingProductCalculator__print-size--active': side.printSize === size.alias
26
+ }"
27
+ @click="side.printSize = size.alias">
28
+ {{ size.name }}
29
+ </div>
30
+ <div
31
+ class="PricingProductCalculator__print-size PricingProductCalculator__print-size--full"
32
+ :class="{
33
+ 'PricingProductCalculator__print-size--active': !side.printSize
34
+ }"
35
+ @click="side.printSize = null">
36
+ no print
37
+ </div>
38
+ </div>
39
+ </div>
40
+ </div>
41
+ </div>
42
+ </div>
43
+ <div class="lc_h3">
44
+ Print Colours
45
+ </div>
46
+ <div class="row">
47
+ <div
48
+ v-for="side in sides"
49
+ :key="side.type"
50
+ class="PricingProductCalculator__prints col-sm-6 col-12">
51
+ <div style="padding: 0px 30px">
52
+ <range
53
+ v-model="side.colorsQuantity"
54
+ :min="1"
55
+ :max="maxScreenPrintColors"
56
+ :visible-steps="true" />
57
+ <div class="row">
58
+ <div class="col-6">
59
+ <label class="form-label PaymentModal__label-with-checkbox">
60
+ <checkbox
61
+ v-model="side.fullColor"
62
+ @change="onChangeFullColor(side)" />
63
+ <span class="lc_regular14 lc__grey1">
64
+ Full colour
65
+ </span>
66
+ </label>
67
+ </div>
68
+ <div class="col-6">
69
+ <label class="form-label PaymentModal__label-with-checkbox">
70
+ <checkbox v-model="side.hasUnderbase" />
71
+ <span class="lc_regular14 lc__grey1">
72
+ With Underbase
73
+ </span>
74
+ </label>
75
+ </div>
76
+ </div>
77
+ </div>
78
+ </div>
79
+ </div>
80
+ <div class="lc_h3">
81
+ Products Quantity
82
+ </div>
83
+ <div style="padding: 30px">
84
+ <range
85
+ v-model="quantity"
86
+ :min="1"
87
+ :max="999"
88
+ :visible-steps="true" />
89
+ </div>
90
+ <div class="PricingProductCalculator__delivery">
91
+ <div class="lc_h5 mr-10">
92
+ Delivery
93
+ </div>
94
+ <div class="PricingProductCalculator__delivery-postcode">
95
+ <postcode-select v-model="postcode" />
96
+ </div>
97
+ </div>
98
+ <div class="row">
99
+ <div
100
+ v-for="(printTypePricing, index) in printTypesPricing"
101
+ :key="index"
102
+ class="PricingProductCalculator__prints col-6">
103
+ <div class="row">
104
+ <div class="col-6">
105
+ <div
106
+ v-if="printTypePricing.prints[0]"
107
+ class="mb-10">
108
+ <div class="lc_h4">
109
+ {{ labels[printTypePricing.type] }}
110
+ </div>
111
+ <div class="lc_regular13">
112
+ Minimum: {{ printTypePricing.prints[0].printType.minQuantity > 1 ? printTypePricing.prints[0].printType.minQuantity : 'No minimum' }}
113
+ </div>
114
+ </div>
115
+ <div class="PricingProductCalculator__cost">
116
+ Cost Per Unit: <b>{{ printTypePricing.pricing.products.price | price }}</b>
117
+ </div>
118
+ <div>
119
+ <v-popover
120
+ trigger="hover"
121
+ :delay="{ hide: 400 }"
122
+ popover-class="tooltip popover white">
123
+ <span class="PricingProductCalculator__breakdown">
124
+ breakdown
125
+ </span>
126
+ <template
127
+ slot="popover">
128
+ <product-total-pricing :pricing="printTypePricing.pricing" />
129
+ </template>
130
+ </v-popover>
131
+ </div>
132
+ </div>
133
+ <div class="col-6">
134
+ <btn
135
+ btn-class="green"
136
+ btn-label="Edit"
137
+ @onclick="goToEditor()">
138
+ </btn>
139
+ </div>
140
+ </div>
141
+ <div class="PricingProductCalculator__reprint">
142
+ <div v-if="printTypePricing.type === 'full colour print'">
143
+ Repeat Print same cost
144
+ </div>
145
+ <div v-else>
146
+ Repeat Print: {{ (printTypePricing.pricing.products.price - printTypePricing.pricing.products.prints.totalSetupPrice) | price }}
147
+ </div>
148
+ </div>
149
+ </div>
150
+ </div>
151
+ </section>
152
+ </template>
153
+
154
+ <script>
155
+ import { getPrintAreasSizes, getPrintAreaSizes } from '@lancom/shared/assets/js/utils/prints';
156
+ import PostcodeSelect from '@lancom/shared/components/common/postcode_select/postcode-select';
157
+ import { getProductsForCalculatePricing, generateProductLink } from '@lancom/shared/assets/js/utils/product';
158
+ import Range from '@lancom/shared/components/common/range/range';
159
+ import api from '@lancom/shared/assets/js/api';
160
+ import { price } from '@lancom/shared/assets/js/utils/filters';
161
+ import ProductTotalPricing from '@lancom/shared/components/common/products_total_pricing/products-total-pricing';
162
+ import debounce from 'lodash.debounce';
163
+ import { mapGetters } from 'vuex';
164
+ import PrintSizeIcon from './print_size_icon/print-size-icon';
165
+
166
+ export default {
167
+ name: 'PricingProductCalculator',
168
+ filters: {
169
+ price
170
+ },
171
+ components: {
172
+ PrintSizeIcon,
173
+ PostcodeSelect,
174
+ Range,
175
+ ProductTotalPricing
176
+ },
177
+ props: {
178
+ product: {
179
+ type: Object,
180
+ required: true
181
+ }
182
+ },
183
+ data() {
184
+ const simpleProduct = [...this.product.simpleProducts].sort((a, b) => a.maxPrice - b.maxPrice)[0];
185
+ const frontPrintSize = getPrintAreasSizes(this.product.printAreas, 'front');
186
+ const backPrintSize = getPrintAreasSizes(this.product.printAreas, 'back');
187
+
188
+ const printTypes = this.product.printTypes.filter(printType => printType.type === 'screen print');
189
+ const screenPrintMinQuantity = Math.min(...printTypes.map(printType => printType.minQuantity));
190
+
191
+ return {
192
+ simpleProduct: { ...simpleProduct, amount: screenPrintMinQuantity || this.product.minimumOrderQuantity },
193
+ labels: {
194
+ 'screen print': 'Screen Print',
195
+ 'full colour print': 'Digital Print'
196
+ },
197
+ printTypesPricing: [],
198
+ availablePrintTypes: ['full colour print', 'screen print'],
199
+ postcode: null,
200
+ sides: [{
201
+ type: 'front',
202
+ printSize: frontPrintSize[0].alias,
203
+ printSizes: frontPrintSize,
204
+ colorsQuantity: 1,
205
+ hasUnderbase: false,
206
+ fullColor: false
207
+ }, {
208
+ type: 'back',
209
+ printSize: backPrintSize[0].alias,
210
+ printSizes: backPrintSize,
211
+ colorsQuantity: 1,
212
+ hasUnderbase: false,
213
+ fullColor: false
214
+ }],
215
+ calculatePricingWithDebounce: debounce(this.calculatePricing.bind(this), 500)
216
+ };
217
+ },
218
+ computed: {
219
+ ...mapGetters(['shop']),
220
+ maxScreenPrintColors() {
221
+ const printTypes = this.product.printTypes.filter(printType => printType.type === 'screen print');
222
+ return Math.max(...printTypes.map(printType => printType.colorsQuantity));
223
+ },
224
+ screenPrintMinQuantity() {
225
+ const printTypes = this.product.printTypes.filter(printType => printType.type === 'screen print');
226
+ return Math.min(...printTypes.map(printType => printType.minQuantity));
227
+ },
228
+ pricingPayload() {
229
+ return [
230
+ this.simpleProduct.amount,
231
+ this.sides.map(({ colorsQuantity, hasUnderbase, printSize }) => ({ colorsQuantity, hasUnderbase, printSize })),
232
+ this.postcode
233
+ ];
234
+ },
235
+ quantity: {
236
+ get() {
237
+ return this.simpleProduct.amount;
238
+ },
239
+ set(amount) {
240
+ if (amount < this.screenPrintMinQuantity) {
241
+ this.sides.forEach(side => {
242
+ side.fullColor = true;
243
+ this.onChangeFullColor(side);
244
+ });
245
+ }
246
+ this.simpleProduct.amount = amount;
247
+ }
248
+ }
249
+ },
250
+ watch: {
251
+ pricingPayload() {
252
+ this.calculatePricingWithDebounce();
253
+ }
254
+ },
255
+ mounted() {
256
+ this.calculatePricingWithDebounce();
257
+ },
258
+ methods: {
259
+ async calculatePricing() {
260
+ this.printTypesPricing = await Promise.all(
261
+ this.availablePrintTypes.map(async type => {
262
+ const prints = this.generateSidesPrints(type);
263
+ const layers = prints.map(({ printType, printSize, printArea }) => ({ printType: printType?._id, printSize: printSize?._id, printArea: printArea?._id }));
264
+ const entities = getProductsForCalculatePricing(this.product, [this.simpleProduct], layers, true, true);
265
+ const pricing = await api.calculateProductPrice({ entities, postcode: this.postcode }, this.shop._id);
266
+ return { pricing, prints, type };
267
+ })
268
+ );
269
+ },
270
+ generateSidesPrints(type) {
271
+ return this.sides
272
+ .filter(({ printSize }) => printSize)
273
+ .map(side => {
274
+ const printType = this.getSidePrintType(side, type) || {};
275
+ const printSize = side.printSizes.find(({ alias }) => alias === side.printSize);
276
+ const printArea = this.product.printAreas.find(printArea => getPrintAreaSizes(printArea).some(({ _id }) => _id === printSize?._id));
277
+ return { printType, printSize, printArea };
278
+ });
279
+ },
280
+ getSidePrintType(side, type) {
281
+ return this.product.printTypes.find(printType => type === printType.type && (type === 'full colour print' || (printType.colorsQuantity === side.colorsQuantity && !!printType.hasUnderbase === !!side.hasUnderbase)));
282
+ },
283
+ goToEditor() {
284
+ const link = generateProductLink(this.product, null, true);
285
+ this.$router.push(link);
286
+ },
287
+ onChangeFullColor(side) {
288
+ side.colorsQuantity = side.fullColor ? this.maxScreenPrintColors : 1;
289
+ }
290
+ }
291
+ };
292
+ </script>
293
+
294
+ <style lang="scss" scoped>
295
+ @import 'pricing-product-calculator';
296
+ </style>
@@ -0,0 +1,26 @@
1
+ <template>
2
+ <section class="PricingProductPrintCalculator__wrapper">
3
+ <div>{{ print.type }}</div>
4
+ </section>
5
+ </template>
6
+
7
+ <script>
8
+
9
+ export default {
10
+ name: 'PricingProductPrintCalculator',
11
+ props: {
12
+ product: {
13
+ type: Object,
14
+ required: true
15
+ },
16
+ side: {
17
+ type: Object,
18
+ required: true
19
+ }
20
+ }
21
+ };
22
+ </script>
23
+
24
+ <style lang="scss" scoped>
25
+ @import 'pricing-product-print-calculator';
26
+ </style>
@@ -0,0 +1,34 @@
1
+ @import "@/assets/scss/variables";
2
+ $product_types: tee, hoodie, polo;
3
+ $product_sides: front, back;
4
+ $print_areas: a3, a4, half_a4, rect10;
5
+
6
+ .PrintSizeIcon {
7
+ &__icon {
8
+ width: 100%;
9
+ height: 100%;
10
+ position: absolute;
11
+ background-repeat: no-repeat;
12
+ background-size: contain;
13
+ background-position: center;
14
+ &-container {
15
+ position: relative;
16
+ width: 150px;
17
+ height: 150px;
18
+ overflow: hidden;
19
+ }
20
+
21
+ @each $side in $product_sides {
22
+ @each $type in $product_types {
23
+ &.#{$side}.#{$type} {
24
+ background-image: url(../../../../../static/icons/#{$side}_#{$type}.svg);
25
+ }
26
+ @each $print_area in $print_areas {
27
+ &.#{$side}.#{$type}.#{$print_area} {
28
+ background-image: url(../../../../../static/icons/#{$side}_#{$type}_#{$print_area}.svg);
29
+ }
30
+ }
31
+ }
32
+ }
33
+ }
34
+ }
@@ -0,0 +1,55 @@
1
+ <template>
2
+ <div class="PrintSizeIcon__wrapper">
3
+ <div class="PrintSizeIcon__icon-container">
4
+ <transition
5
+ name="appear-from-top"
6
+ appear>
7
+ <div
8
+ :key="side.printSize"
9
+ class="PrintSizeIcon__icon view-transition"
10
+ :class="{
11
+ [side.type]: true,
12
+ [printSizeClassname]: true,
13
+ [productType]: true
14
+ }">
15
+ </div>
16
+ </transition>
17
+ </div>
18
+ </div>
19
+ </template>
20
+
21
+ <script>
22
+ const MAP_SIZE_ALIASES = {
23
+ a4_h: 'a4',
24
+ a4_v: 'a4',
25
+ rect10_l: 'rect10',
26
+ rect10_r: 'rect10'
27
+ };
28
+
29
+ export default {
30
+ name: 'PrintSizeIcon',
31
+ props: {
32
+ product: {
33
+ type: Object,
34
+ required: true
35
+ },
36
+ side: {
37
+ type: Object,
38
+ required: true
39
+ }
40
+ },
41
+ computed: {
42
+ productType() {
43
+ const { productType } = this.product || {};
44
+ return productType?.alias;
45
+ },
46
+ printSizeClassname() {
47
+ return MAP_SIZE_ALIASES[this.side.printSize] || this.side.printSize;
48
+ }
49
+ }
50
+ };
51
+ </script>
52
+
53
+ <style lang="scss" scoped>
54
+ @import 'print-size-icon';
55
+ </style>