@codecavepro/brand 2.7.5 → 2.8.0
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.
|
@@ -35,11 +35,13 @@ const imageUrl = (url: string) => props.resolveImage?.(url) ?? url
|
|
|
35
35
|
rounded-[2.25rem] bg-surface-secondary hover:bg-surface-tertiary transition-colors cursor-pointer border-surface-tertiary border
|
|
36
36
|
${className ?? ''}`">
|
|
37
37
|
<div class="flex flex-col sm:flex-row gap-5 sm:gap-8 h-fit">
|
|
38
|
-
<
|
|
38
|
+
<div class="w-full h-full p-1">
|
|
39
|
+
<img loading="lazy" class="sm:w-[132px] sm:h-[132px] rounded-xl object-scale-down"
|
|
39
40
|
:src="imageUrl(article.cover.url)"
|
|
40
41
|
:alt="article.title"
|
|
41
42
|
:width="100"
|
|
42
43
|
:height="100"/>
|
|
44
|
+
</div>
|
|
43
45
|
<div class="space-y-2 sm:space-y-3">
|
|
44
46
|
<time class="text-body-secondary text-xs sm:text-sm" :datetime="article.date?.toString()">
|
|
45
47
|
{{ formattedDate(article.locale, article.date) }}
|
|
@@ -8,18 +8,21 @@ const props = withDefaults(
|
|
|
8
8
|
label: string
|
|
9
9
|
isRequired?: boolean
|
|
10
10
|
isError?: boolean
|
|
11
|
-
variant?: 'primary' | 'secondary'
|
|
12
11
|
size?: 'small' | 'medium'
|
|
13
12
|
modelValue?: boolean
|
|
14
13
|
}>(),
|
|
15
14
|
{
|
|
16
15
|
isRequired: false,
|
|
17
16
|
isError: false,
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
size: 'medium',
|
|
18
|
+
modelValue: false
|
|
20
19
|
}
|
|
21
20
|
)
|
|
22
21
|
|
|
22
|
+
const emit = defineEmits<{
|
|
23
|
+
'update:modelValue': [value: boolean]
|
|
24
|
+
}>()
|
|
25
|
+
|
|
23
26
|
const checkboxSize = computed(() => {
|
|
24
27
|
switch (props.size) {
|
|
25
28
|
case 'small':
|
|
@@ -28,6 +31,7 @@ const checkboxSize = computed(() => {
|
|
|
28
31
|
return 'w-6 h-6 before:w-[0.75em] before:h-[0.75em]'
|
|
29
32
|
}
|
|
30
33
|
})
|
|
34
|
+
|
|
31
35
|
const labelSize = computed(() => {
|
|
32
36
|
switch (props.size) {
|
|
33
37
|
case 'small':
|
|
@@ -36,45 +40,50 @@ const labelSize = computed(() => {
|
|
|
36
40
|
return 'text-sm'
|
|
37
41
|
}
|
|
38
42
|
})
|
|
39
|
-
const labelBaseClass = 'flex items-center w-fit text-body-primary cursor-pointer'
|
|
40
|
-
const labelVariantClass = computed(() => {
|
|
41
|
-
switch (props.variant) {
|
|
42
|
-
case 'secondary':
|
|
43
|
-
return `${labelBaseClass} ${labelSize.value} gap-2 py-2 px-3 bg-surface-secondary rounded-lg`
|
|
44
|
-
default:
|
|
45
|
-
return `${labelBaseClass} ${labelSize.value} gap-3`
|
|
46
|
-
}
|
|
47
|
-
})
|
|
48
|
-
const inputBaseClass = 'cursor-pointer transition-colors'
|
|
49
|
-
const borderClass = computed(() => {
|
|
50
|
-
return props.isError ? 'border-error checkbox-error' : 'border-outline-primary-hover hover:border-action'
|
|
51
|
-
});
|
|
52
43
|
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
44
|
+
const borderClass = computed(() =>
|
|
45
|
+
props.isError
|
|
46
|
+
? 'border-error checkbox-error'
|
|
47
|
+
: 'border-outline-primary-hover hover:border-action'
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
const labelClass = computed(
|
|
51
|
+
() => `flex items-center w-full ${labelSize.value} text-body-primary cursor-pointer gap-3`
|
|
52
|
+
)
|
|
61
53
|
|
|
62
|
-
|
|
54
|
+
const inputClass = computed(
|
|
55
|
+
() =>
|
|
56
|
+
`cursor-pointer transition-colors ${checkboxSize.value} border-2 ${borderClass.value}`
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
const handleChange = (event: Event) => {
|
|
60
|
+
emit(
|
|
61
|
+
'update:modelValue',
|
|
62
|
+
(event.target as HTMLInputElement).checked
|
|
63
|
+
)
|
|
64
|
+
}
|
|
63
65
|
</script>
|
|
64
66
|
|
|
65
67
|
<template>
|
|
66
|
-
<label :for="id" :class="
|
|
67
|
-
<input
|
|
68
|
-
:id="id"
|
|
69
|
-
type="checkbox"
|
|
70
|
-
:autocomplete="id"
|
|
71
|
-
:class="
|
|
68
|
+
<label :for="id" :class="labelClass">
|
|
69
|
+
<input
|
|
70
|
+
:id="id"
|
|
71
|
+
type="checkbox"
|
|
72
|
+
:autocomplete="id"
|
|
73
|
+
:class="`${inputClass} shrink-0`"
|
|
72
74
|
:data-size="size"
|
|
73
75
|
:checked="modelValue"
|
|
74
|
-
@change="
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
@change="handleChange"
|
|
77
|
+
/>
|
|
78
|
+
|
|
79
|
+
<span class="flex min-w-0 items-start">
|
|
80
|
+
<span class="min-w-0 break-words">
|
|
81
|
+
{{ label }}
|
|
82
|
+
</span>
|
|
83
|
+
<AsteriskIcon
|
|
84
|
+
v-if="isRequired"
|
|
85
|
+
class="mx-1 shrink-0"
|
|
86
|
+
/>
|
|
78
87
|
</span>
|
|
79
88
|
</label>
|
|
80
89
|
</template>
|
|
@@ -59,12 +59,20 @@ const formData = ref({
|
|
|
59
59
|
linkedinCompanyPage: createFormField('linkedinCompanyPage', ''),
|
|
60
60
|
services: createFormField('services', ''),
|
|
61
61
|
description: createFormField('description', ''),
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
62
|
+
|
|
63
|
+
consentToProcess: {
|
|
64
|
+
value: false,
|
|
65
|
+
error: '',
|
|
66
|
+
label: props.definition.consentToProcess.label,
|
|
67
|
+
required: props.definition.consentToProcess.required,
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
communicationConsent: {
|
|
71
|
+
value: false,
|
|
72
|
+
error: '',
|
|
73
|
+
label: props.definition.communicationConsent.label,
|
|
74
|
+
required: props.definition.communicationConsent.required,
|
|
75
|
+
},
|
|
68
76
|
})
|
|
69
77
|
|
|
70
78
|
const services = computed(() => props.definition.services.options ?? [])
|
|
@@ -120,7 +128,9 @@ const resetForm = () => {
|
|
|
120
128
|
formData.value.linkedinCompanyPage.value = '';
|
|
121
129
|
formData.value.description.value = '';
|
|
122
130
|
formData.value.services.value = '';
|
|
123
|
-
|
|
131
|
+
|
|
132
|
+
formData.value.consentToProcess.value = false;
|
|
133
|
+
formData.value.communicationConsent.value = false;
|
|
124
134
|
}
|
|
125
135
|
|
|
126
136
|
const currentValues = (): ContactFormValues => ({
|
|
@@ -131,7 +141,8 @@ const currentValues = (): ContactFormValues => ({
|
|
|
131
141
|
linkedinCompanyPage: formData.value.linkedinCompanyPage.value,
|
|
132
142
|
services: formData.value.services.value,
|
|
133
143
|
description: formData.value.description.value,
|
|
134
|
-
|
|
144
|
+
consentToProcess: formData.value.consentToProcess.value,
|
|
145
|
+
communicationConsent: formData.value.communicationConsent.value,
|
|
135
146
|
})
|
|
136
147
|
|
|
137
148
|
const isSubmitting = ref(false)
|
|
@@ -206,7 +217,7 @@ const fields = [
|
|
|
206
217
|
'firstName',
|
|
207
218
|
'companyName',
|
|
208
219
|
'linkedinCompanyPage',
|
|
209
|
-
'
|
|
220
|
+
'consentToProcess'
|
|
210
221
|
]
|
|
211
222
|
|
|
212
223
|
fields.forEach((key) => {
|
|
@@ -248,8 +259,8 @@ fields.forEach((key) => {
|
|
|
248
259
|
<TextField id="project" v-model="formData.description.value" :isRequired=formData.description.required :label=formData.description.label :isError="!!formData.description.error" :errorMessage="formData.description.error" :placeholder="formData.description.placeholder ?? ''" />
|
|
249
260
|
</fieldset>
|
|
250
261
|
<div class="space-y-2">
|
|
251
|
-
<Checkbox id="privacy" v-model="formData.
|
|
252
|
-
<Checkbox id="promotions" label="
|
|
262
|
+
<Checkbox id="privacy" v-model="formData.consentToProcess.value" :label="formData.consentToProcess.label" :isRequired="formData.consentToProcess.required" :isError="!!formData.consentToProcess.error" />
|
|
263
|
+
<Checkbox id="promotions" v-model="formData.communicationConsent.value" :label="formData.communicationConsent.label" :isRequired="formData.communicationConsent.required" :isError="!!formData.communicationConsent.error" />
|
|
253
264
|
</div>
|
|
254
265
|
</div>
|
|
255
266
|
<GlowButton @click="submitContactsForm" title="Leave consultation request" class="self-center lg:self-start" />
|
|
@@ -30,7 +30,9 @@ export type ContactFormFieldName =
|
|
|
30
30
|
| 'companyName'
|
|
31
31
|
| 'linkedinCompanyPage'
|
|
32
32
|
| 'services'
|
|
33
|
-
| 'description'
|
|
33
|
+
| 'description'
|
|
34
|
+
| 'consentToProcess'
|
|
35
|
+
| 'communicationConsent';
|
|
34
36
|
|
|
35
37
|
/** Labels, placeholders and options for the contact form, CRM-neutral. */
|
|
36
38
|
export type ContactFormDefinition = Record<ContactFormFieldName, CrmFormFieldSpec>;
|
|
@@ -44,7 +46,8 @@ export interface ContactFormValues {
|
|
|
44
46
|
linkedinCompanyPage: string;
|
|
45
47
|
services: string;
|
|
46
48
|
description: string;
|
|
47
|
-
|
|
49
|
+
consentToProcess: boolean;
|
|
50
|
+
communicationConsent: boolean;
|
|
48
51
|
}
|
|
49
52
|
|
|
50
53
|
/* A result rather than a thrown error, deliberately.
|
package/package.json
CHANGED