@viur/shop-components 0.1.15 → 0.1.17

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@viur/shop-components",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
4
4
  "description": "Frontend Vue components for the shop module of ViUR",
5
5
  "repository": {
6
6
  "type": "git",
@@ -7,7 +7,7 @@
7
7
  :skelkey="state.skelkey"
8
8
  :values="{'address_type':state.address_type, 'customer_type':'private'}"
9
9
  :useCategories="false"
10
- :layout="AddressFormLayout"
10
+ :layout="shopStore.state.UserDataLayout"
11
11
  @change="formChange"
12
12
  :default-language="state.language"
13
13
  error-style="decent"
@@ -18,7 +18,6 @@
18
18
  <script setup>
19
19
  import {computed, reactive, watch} from 'vue'
20
20
  import LoadingHandler from './LoadingHandler.vue';
21
- import AddressFormLayout from './AddressFormLayout.vue';
22
21
  import ViForm from "@viur/vue-utils/forms/ViForm.vue";
23
22
  import {useViurShopStore} from "../shop";
24
23
  import {useAddress} from "../composables/address";
@@ -91,4 +90,4 @@ watch(()=>addressState.billingIsShipping, (newVal,oldVal)=>{
91
90
 
92
91
  <style scoped>
93
92
 
94
- </style>
93
+ </style>
@@ -52,12 +52,12 @@
52
52
  </slot>
53
53
 
54
54
  <slot boneName="email"
55
- :widget="getBoneWidget(formState.structure['email']['type'])"
55
+ :widget="EmailCheckBone"
56
56
  label="placeholder">
57
57
  </slot>
58
58
 
59
59
  <slot boneName="phone"
60
- :widget="getBoneWidget(formState.structure['phone']['type'])"
60
+ :widget="PhoneCheckBone"
61
61
  label="placeholder">
62
62
  </slot>
63
63
 
@@ -66,6 +66,8 @@
66
66
  <script setup>
67
67
  import { inject } from "vue";
68
68
  import { getBoneWidget } from "@viur/vue-utils/bones/edit";
69
+ import EmailCheckBone from "../custombones/EmailCheckBone.vue";
70
+ import PhoneCheckBone from "../custombones/PhoneCheckBone.vue";
69
71
 
70
72
  const formState = inject("formState");
71
73
  const formUpdate = inject("formUpdate");
@@ -114,6 +116,13 @@ const formUpdate = inject("formUpdate");
114
116
  :deep(.wrapper-bone-country){
115
117
  grid-column: 1 / span 4;
116
118
  }
119
+ :deep(.wrapper-bone-email){
120
+ grid-column: 1 / span 4;
121
+ }
122
+
123
+ :deep(.wrapper-bone-phone){
124
+ grid-column: 1 / span 4;
125
+ }
117
126
 
118
127
  :deep(.wrapper-bone-is_default){
119
128
  padding: var(--sl-spacing-x-small) 0;
@@ -0,0 +1,115 @@
1
+ <template>
2
+ <div class="widget-bone-wrapper-email">
3
+ <sl-input
4
+ class="widget-bone widget-bone-email widget-bone-email-default"
5
+ :class="([`widget-bone-email-${name}`])"
6
+ :name="name"
7
+ ref="emailBone"
8
+ :disabled="boneState.readonly"
9
+ type="email"
10
+ :value="value"
11
+ @sl-change="changeEvent"
12
+ :required="boneState.bonestructure.required && !boneState.bonestructure.multiple && !boneState.bonestructure.languages"
13
+ :placeholder="boneState.label==='placeholder'?boneState?.bonestructure?.descr:undefined"
14
+ :data-user-invalid="boneState.errorMessages.length===0?undefined:true"
15
+ ></sl-input>
16
+
17
+ <sl-input
18
+ class="widget-bone widget-bone-email widget-bone-email-repeat"
19
+ :class="([`widget-bone-email-${name}`])"
20
+ ref="emailBone2"
21
+ :disabled="boneState.readonly"
22
+ type="email"
23
+ @sl-change="changeEvent"
24
+ :required="boneState.bonestructure.required && !boneState.bonestructure.multiple && !boneState.bonestructure.languages"
25
+ :placeholder="boneState.label==='placeholder'?boneState?.bonestructure?.descr:undefined"
26
+ :data-user-invalid="boneState.errorMessages.length===0?undefined:true"
27
+ ></sl-input>
28
+
29
+ </div>
30
+ </template>
31
+
32
+ <script setup>
33
+ import { reactive, onMounted, inject, ref, watchEffect } from "vue"
34
+ import { useTimeoutFn } from "@vueuse/core"
35
+ import { useI18n } from "vue-i18n"
36
+ defineOptions({
37
+ inheritAttrs: false
38
+ })
39
+ const props = defineProps( {
40
+ name: String,
41
+ value: [Object, String, Number, Boolean, Array],
42
+ index: Number,
43
+ lang: String,
44
+ bone:Object,
45
+ autofocus: Boolean
46
+ })
47
+ const i18n = useI18n()
48
+ const emit = defineEmits( ["change"])
49
+
50
+ const boneState = inject("boneState")
51
+ const state = reactive({
52
+
53
+ })
54
+
55
+ const emailBone = ref(null)
56
+ const emailBone2 = ref(null)
57
+
58
+ function changeEvent(event) {
59
+ console.dir(event.target)
60
+ if(emailBone.value.value!==emailBone2.value.value){
61
+ emailBone.value.setCustomValidity(i18n.t("messages.password_equal_error"))
62
+ emailBone.value.reportValidity()
63
+ console.log(event.target.classList)
64
+ if (!event.target.classList.contains('widget-bone-email-repeat')){
65
+ emit("change", props.name, event.target.value, props.lang, props.index,false)
66
+ }
67
+ }else{
68
+ emailBone.value.setCustomValidity('')
69
+ emit("change", props.name, event.target.value, props.lang, props.index,true)
70
+ }
71
+
72
+
73
+
74
+ }
75
+
76
+ watchEffect(() => {
77
+ if (props.autofocus) {
78
+ if (emailBone.value && emailBone.value !== null && emailBone !== null) {
79
+ const { start } = useTimeoutFn(() => {
80
+ emailBone.value.focus()
81
+ }, 600)
82
+
83
+ start()
84
+ }
85
+ }
86
+ })
87
+
88
+ onMounted(() => {
89
+ emit("change", props.name, props.value, props.lang, props.index) //init
90
+ })
91
+
92
+ </script>
93
+
94
+ <style scoped>
95
+ sl-input {
96
+ width: 100%;
97
+
98
+ &::part(base) {
99
+ border-top-left-radius: 0;
100
+ border-bottom-left-radius: 0;
101
+ }
102
+
103
+ @media (max-width: 900px) {
104
+ &::part(base) {
105
+ border-top-right-radius: 0;
106
+ border-bottom-left-radius: var(--sl-border-radius-medium);
107
+ }
108
+ }
109
+ }
110
+
111
+ .widget-bone-wrapper-email{
112
+ display:flex;
113
+ gap: var(--sl-spacing-small);
114
+ }
115
+ </style>
@@ -0,0 +1,144 @@
1
+ <template>
2
+ <div class="widget-bone-wrapper-string">
3
+ <sl-input
4
+ class="widget-bone widget-bone-string widget-bone-string-default"
5
+ :class="([`widget-bone-string-${name}`])"
6
+ :name="name"
7
+ ref="stringBone"
8
+ :disabled="boneState.readonly"
9
+ :value="value"
10
+ @sl-change="changeEvent"
11
+ :required="boneState.bonestructure.required && !boneState.bonestructure.multiple && !boneState.bonestructure.languages"
12
+ :placeholder="boneState.label==='placeholder'?boneState?.bonestructure?.descr:undefined"
13
+ :data-user-invalid="boneState.errorMessages.length===0?undefined:true"
14
+ :pattern="state.pattern"
15
+ :maxlength="boneState.maxlength"
16
+ :minlength="boneState.minlength"
17
+ ></sl-input>
18
+
19
+ <sl-input
20
+ class="widget-bone widget-bone-string widget-bone-string-repeat"
21
+ :class="([`widget-bone-email-${name}`])"
22
+ ref="stringBone2"
23
+ :disabled="boneState.readonly"
24
+
25
+ @sl-change="changeEvent"
26
+ :required="boneState.bonestructure.required && !boneState.bonestructure.multiple && !boneState.bonestructure.languages"
27
+ :placeholder="boneState.label==='placeholder'?boneState?.bonestructure?.descr:undefined"
28
+ :data-user-invalid="boneState.errorMessages.length===0?undefined:true"
29
+ :pattern="state.pattern"
30
+ :maxlength="boneState.maxlength"
31
+ :minlength="boneState.minlength"
32
+ ></sl-input>
33
+
34
+ </div>
35
+ </template>
36
+
37
+ <script setup>
38
+ import { reactive, onMounted, inject, ref, watchEffect, computed } from "vue"
39
+ import { useTimeoutFn } from "@vueuse/core"
40
+ import { useI18n } from "vue-i18n"
41
+ defineOptions({
42
+ inheritAttrs: false
43
+ })
44
+ const props = defineProps( {
45
+ name: String,
46
+ value: [Object, String, Number, Boolean, Array],
47
+ index: Number,
48
+ lang: String,
49
+ bone:Object,
50
+ autofocus: Boolean
51
+ })
52
+ const i18n = useI18n()
53
+ const emit = defineEmits( ["change"])
54
+
55
+ const boneState = inject("boneState")
56
+ const state = reactive({
57
+ pattern: computed(() => {
58
+ let pat = boneState.params?.pattern
59
+ if (!pat) return undefined
60
+
61
+ if (typeof(pat) === "String"){
62
+ return pat
63
+ }
64
+ return pat?.[boneState.defaultLanguage]
65
+ }),
66
+ pattern_error:computed(()=>{
67
+ let pat = boneState.params?.pattern_error
68
+ if (!pat) return ''
69
+
70
+ if (typeof(pat) === "String"){
71
+ return pat
72
+ }
73
+ return pat?.[boneState.defaultLanguage]?pat?.[boneState.defaultLanguage]:''
74
+ })
75
+ })
76
+
77
+ const stringBone = ref(null)
78
+ const stringBone2 = ref(null)
79
+
80
+ function changeEvent(event) {
81
+ for (const bone of [stringBone, stringBone2]){
82
+ let valid = bone.value.reportValidity()
83
+ let validStates = bone.value.validity
84
+ if(validStates['patternMismatch']){
85
+ bone.value.setCustomValidity(state.pattern_error)
86
+ return
87
+ }else{
88
+ bone.value.setCustomValidity('')
89
+ }
90
+ }
91
+ if(stringBone.value.value!==stringBone2.value.value){
92
+ stringBone.value.setCustomValidity(i18n.t("messages.phone_equal_error"))
93
+ stringBone.value.reportValidity()
94
+ console.log(event.target.classList)
95
+ if (!event.target.classList.contains('widget-bone-string-repeat')){
96
+ emit("change", props.name, event.target.value, props.lang, props.index,false)
97
+ }
98
+ }else{
99
+ stringBone.value.setCustomValidity('')
100
+ emit("change", props.name, event.target.value, props.lang, props.index,true)
101
+ }
102
+ }
103
+
104
+ watchEffect(() => {
105
+ if (props.autofocus) {
106
+ if (stringBone.value && stringBone.value !== null && stringBone !== null) {
107
+ const { start } = useTimeoutFn(() => {
108
+ stringBone.value.focus()
109
+ }, 600)
110
+
111
+ start()
112
+ }
113
+ }
114
+ })
115
+
116
+ onMounted(() => {
117
+ emit("change", props.name, props.value, props.lang, props.index) //init
118
+ })
119
+
120
+ </script>
121
+
122
+ <style scoped>
123
+ sl-input {
124
+ width: 100%;
125
+
126
+ &::part(base) {
127
+ border-top-left-radius: 0;
128
+ border-bottom-left-radius: 0;
129
+ }
130
+
131
+ @media (max-width: 900px) {
132
+ &::part(base) {
133
+ border-top-right-radius: 0;
134
+ border-bottom-left-radius: var(--sl-border-radius-medium);
135
+ }
136
+ }
137
+ }
138
+
139
+ .widget-bone-wrapper-string{
140
+ display:flex;
141
+ gap: var(--sl-spacing-small);
142
+ margin-bottom:var(--sl-spacing-small);
143
+ }
144
+ </style>
package/src/shop.js CHANGED
@@ -3,6 +3,7 @@ import { reactive, computed, watch, shallowRef } from "vue";
3
3
  import {ShopCart, ShopUserDataGuest, ShopShippingMethod, ShopPaymentProvider, ShopOrderComplete, ShopOrderConfirm} from './Steps/index'
4
4
  import { defineStore } from "pinia";
5
5
  import { useUrlSearchParams } from '@vueuse/core'
6
+ import AddressFormLayout from './components/AddressFormLayout.vue';
6
7
 
7
8
  import { Request } from "@viur/vue-utils";
8
9
 
@@ -119,8 +120,8 @@ export const useViurShopStore = defineStore("viurshopStore", () => {
119
120
 
120
121
 
121
122
  //checkout
122
- paymentProviderData:null
123
-
123
+ paymentProviderData:null,
124
+ UserDataLayout: shallowRef(AddressFormLayout)
124
125
  })
125
126
 
126
127
  function addTab({name, component, displayname, iconname, iconlibrary,active})
@@ -60,5 +60,7 @@ export default {
60
60
  wait_for_payment: 'Warte auf Zahlung...',
61
61
  remove_article_from_cart: 'Wollen sie den Artikel wirklich entfernen?',
62
62
  order_check_later: 'Sie können Ihre Bestellung am Ende noch einmal überprüfen.',
63
+ password_equal_error: 'E-Mail-Adressen stimmen nicht überein.',
64
+ phone_equal_error: "Telefonnummern stimmen nicht überein."
63
65
  },
64
66
  };
@@ -54,5 +54,7 @@ export default {
54
54
  wait_for_payment: 'Warte auf Zahlung...',
55
55
  remove_article_from_cart: 'Désirez-vous vraiment supprimer cet article du panier?',
56
56
  order_check_later: 'Vous pourrez revérifier vos données avant de valider votre commande.',
57
+ password_equal_error: "Les adresses e-mail ne correspondent pas.",
58
+ phone_equal_error: "Les numéros de téléphone ne correspondent pas."
57
59
  },
58
60
  };