@dev.smartpricing/message-composer-layer 1.0.20 → 1.0.21

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/app/api/brands.ts CHANGED
@@ -41,7 +41,7 @@ export const brandsApi = {
41
41
  preview: (data: {
42
42
  message: PostEntity<EmailMessage>
43
43
  parameters?: Record<string, unknown>
44
- brand?: BrandCascadeData | null
44
+ brand?: BrandCascadeData | undefined
45
45
  }) =>
46
46
  apiClient<CompileEmailResponse>('/message-groups/preview', {
47
47
  method: 'POST',
@@ -5,6 +5,10 @@ import { isValidUrl } from '@dev.smartpricing/message-composer-utils/utils'
5
5
 
6
6
  const socials = defineModel<BrandSocials>({ required: true })
7
7
 
8
+ const { t } = useI18n()
9
+
10
+ const touched = ref<Partial<Record<SocialPlatform, boolean>>>({})
11
+
8
12
  function socialLabel(platform: SocialPlatform): string {
9
13
  return platform.charAt(0).toUpperCase() + platform.slice(1)
10
14
  }
@@ -16,33 +20,48 @@ function updateUrl(platform: SocialPlatform, value: string) {
16
20
  updated[platform] = trimmed
17
21
  } else {
18
22
  delete updated[platform]
23
+ touched.value = { ...touched.value, [platform]: false }
19
24
  }
20
25
  socials.value = updated
21
26
  }
22
27
 
23
- function hasError(value: string | undefined): boolean {
24
- return !!value && !isValidUrl(value)
28
+ function onBlur(platform: SocialPlatform) {
29
+ if (socials.value?.[platform]) {
30
+ touched.value = { ...touched.value, [platform]: true }
31
+ }
32
+ }
33
+
34
+ function fieldError(platform: SocialPlatform): string | undefined {
35
+ const value = socials.value?.[platform]
36
+ if (!value || !touched.value[platform]) return undefined
37
+ return isValidUrl(value) ? undefined : t('pages.brands.validation.invalid_url_format')
25
38
  }
26
39
  </script>
27
40
 
28
41
  <template>
29
42
  <div class="space-y-4">
30
- <div
43
+ <UFormField
31
44
  v-for="platform in SOCIAL_PLATFORMS"
32
45
  :key="platform"
33
- class="flex items-center gap-3 p-3 rounded-lg border border-neutral-200"
46
+ :error="fieldError(platform)"
47
+ class="w-full"
34
48
  >
35
- <span class="text-sm font-medium w-24 shrink-0">
36
- {{ socialLabel(platform) }}
37
- </span>
38
- <UInput
39
- :model-value="socials?.[platform] ?? ''"
40
- :placeholder="`https://${platform}.com/...`"
41
- :color="hasError(socials?.[platform]) ? 'error' : undefined"
42
- class="flex-1"
43
- size="sm"
44
- @update:model-value="updateUrl(platform, $event as string)"
45
- />
46
- </div>
49
+ <UFieldGroup class="w-full">
50
+ <UBadge
51
+ class="w-34"
52
+ variant="outline"
53
+ color="neutral"
54
+ size="lg"
55
+ :label="socialLabel(platform)"
56
+ />
57
+ <UInput
58
+ :model-value="socials?.[platform] ?? ''"
59
+ :placeholder="`https://${platform}.com/...`"
60
+ :color="fieldError(platform) ? 'error' : undefined"
61
+ @update:model-value="updateUrl(platform, $event as string)"
62
+ @blur="onBlur(platform)"
63
+ />
64
+ </UFieldGroup>
65
+ </UFormField>
47
66
  </div>
48
67
  </template>
@@ -97,7 +97,6 @@ if (color.value === 'transparent') {
97
97
  <template>
98
98
  <UPopover :data-testid="colorInputTestIds.popover">
99
99
  <UButton
100
- :label="label"
101
100
  color="neutral"
102
101
  variant="outline"
103
102
  class="w-full"
@@ -106,9 +105,10 @@ if (color.value === 'transparent') {
106
105
  <template #leading>
107
106
  <span
108
107
  :style="chip"
109
- class="size-8 rounded-full border"
108
+ class="size-8 rounded-full border shrink-0"
110
109
  :class="isUsingDefault ? 'border-primary-400 border-2' : 'border-neutral-300'"
111
110
  />
111
+ <STruncatedText v-if="label" :text="label" />
112
112
  </template>
113
113
  <template #trailing>
114
114
  <slot name="trailing"></slot>
@@ -114,6 +114,7 @@ function askDelete(brand: BrandFromDb) {
114
114
  label: t('common.actions.cancel'),
115
115
  },
116
116
  action: async () => {
117
+ editingBrandId.value = undefined
117
118
  await deleteBrand(brand.id)
118
119
  emit('deleted', brand)
119
120
  useToast().add({
@@ -292,12 +292,12 @@ Diese Nachrichten müssen funktional sein, nicht werblich.
292
292
  add_color: 'Farbe hinzufügen',
293
293
  extracting_colors: 'Farben werden aus dem Logo extrahiert...',
294
294
  default_email_colors: 'Standard-E-Mail-Farben',
295
- email_bg_color: 'E-Mail-Hintergrundfarbe',
296
- email_content_bg_color: 'E-Mail-Inhalt-Hintergrundfarbe',
297
- email_text_color: 'E-Mail-Textfarbe',
295
+ email_bg_color: 'Hintergrund',
296
+ email_content_bg_color: 'Inhalt-Hintergrund',
297
+ email_text_color: 'Text',
298
298
  default_button_colors: 'Standard-Schaltflächen-Farben',
299
- button_text_color: 'Schaltflächen-Textfarbe',
300
- button_bg_color: 'Schaltflächen-Hintergrundfarbe',
299
+ button_text_color: 'Text',
300
+ button_bg_color: 'Hintergrund',
301
301
  default_font: 'Standardschriftart',
302
302
  },
303
303
  actions: {
@@ -308,6 +308,7 @@ Diese Nachrichten müssen funktional sein, nicht werblich.
308
308
  validation: {
309
309
  name_required: 'Name ist erforderlich',
310
310
  invalid_social_url: 'Eine oder mehrere Social-URLs sind ungültig',
311
+ invalid_url_format: 'Ungültiges URL-Format',
311
312
  },
312
313
  preview: {
313
314
  title: 'Vorschau',
@@ -741,6 +742,7 @@ Diese Nachrichten müssen funktional sein, nicht werblich.
741
742
  width: 'Logobreite',
742
743
  alignment: 'Ausrichtung',
743
744
  background: 'Hintergrundfarbe',
745
+ reset: 'Auf Standard zurücksetzen',
744
746
  },
745
747
  },
746
748
  footer: {
@@ -304,6 +304,7 @@ These messages must be functional, not promotional.
304
304
  validation: {
305
305
  name_required: 'Brand name is required',
306
306
  invalid_social_url: 'One or more social URLs are invalid',
307
+ invalid_url_format: 'Invalid URL format',
307
308
  },
308
309
  preview: {
309
310
  title: 'Preview',
@@ -289,12 +289,12 @@ Estos mensajes deben ser funcionales, no promocionales.
289
289
  add_color: 'Añadir color',
290
290
  extracting_colors: 'Extrayendo colores del logo...',
291
291
  default_email_colors: 'Colores de correo predeterminados',
292
- email_bg_color: 'Color de fondo del correo',
293
- email_content_bg_color: 'Color de fondo del contenido del correo',
294
- email_text_color: 'Color del texto del correo',
292
+ email_bg_color: 'Fondo',
293
+ email_content_bg_color: 'Fondo contenido',
294
+ email_text_color: 'Texto',
295
295
  default_button_colors: 'Colores de botón predeterminados',
296
- button_text_color: 'Color del texto del botón',
297
- button_bg_color: 'Color de fondo del botón',
296
+ button_text_color: 'Texto',
297
+ button_bg_color: 'Fondo',
298
298
  default_font: 'Fuente predeterminada',
299
299
  },
300
300
  actions: {
@@ -305,6 +305,7 @@ Estos mensajes deben ser funcionales, no promocionales.
305
305
  validation: {
306
306
  name_required: 'El nombre es obligatorio',
307
307
  invalid_social_url: 'Una o más URLs sociales no son válidas',
308
+ invalid_url_format: 'Formato de URL no válido',
308
309
  },
309
310
  preview: {
310
311
  title: 'Vista previa',
@@ -740,6 +741,7 @@ Estos mensajes deben ser funcionales, no promocionales.
740
741
  width: 'Ancho del logo',
741
742
  alignment: 'Alineación',
742
743
  background: 'Color de fondo',
744
+ reset: 'Restablecer valores predeterminados',
743
745
  },
744
746
  },
745
747
  footer: {
@@ -289,12 +289,12 @@ Ces messages doivent être fonctionnels, et non promotionnels.
289
289
  add_color: 'Ajouter une couleur',
290
290
  extracting_colors: 'Extraction des couleurs du logo...',
291
291
  default_email_colors: "Couleurs d'e-mail par défaut",
292
- email_bg_color: "Couleur de fond de l'e-mail",
293
- email_content_bg_color: "Couleur de fond du contenu de l'e-mail",
294
- email_text_color: "Couleur du texte de l'e-mail",
292
+ email_bg_color: 'Fond',
293
+ email_content_bg_color: 'Fond contenu',
294
+ email_text_color: 'Texte',
295
295
  default_button_colors: 'Couleurs de bouton par défaut',
296
- button_text_color: 'Couleur du texte du bouton',
297
- button_bg_color: 'Couleur de fond du bouton',
296
+ button_text_color: 'Texte',
297
+ button_bg_color: 'Fond',
298
298
  default_font: 'Police par défaut',
299
299
  },
300
300
  actions: {
@@ -305,6 +305,7 @@ Ces messages doivent être fonctionnels, et non promotionnels.
305
305
  validation: {
306
306
  name_required: 'Le nom est requis',
307
307
  invalid_social_url: 'Une ou plusieurs URL de réseaux sociaux sont invalides',
308
+ invalid_url_format: "Format d'URL invalide",
308
309
  },
309
310
  preview: {
310
311
  title: 'Aperçu',
@@ -744,6 +745,7 @@ Ces messages doivent être fonctionnels, et non promotionnels.
744
745
  width: 'Largeur du logo',
745
746
  alignment: 'Alignement',
746
747
  background: 'Couleur d’arrière-plan',
748
+ reset: 'Réinitialiser par défaut',
747
749
  },
748
750
  },
749
751
  footer: {
@@ -289,12 +289,12 @@ Questi messaggi devono essere funzionali, non promozionali.
289
289
  add_color: 'Aggiungi colore',
290
290
  extracting_colors: 'Estrazione dei colori dal logo...',
291
291
  default_email_colors: 'Colori email predefiniti',
292
- email_bg_color: 'Colore sfondo email',
293
- email_content_bg_color: 'Colore sfondo contenuto email',
294
- email_text_color: 'Colore testo email',
292
+ email_bg_color: 'Sfondo',
293
+ email_content_bg_color: 'Sfondo contenuto',
294
+ email_text_color: 'Testo',
295
295
  default_button_colors: 'Colori pulsante predefiniti',
296
- button_text_color: 'Colore testo pulsante',
297
- button_bg_color: 'Colore sfondo pulsante',
296
+ button_text_color: 'Testo',
297
+ button_bg_color: 'Sfondo',
298
298
  default_font: 'Font predefinito',
299
299
  },
300
300
  actions: {
@@ -305,6 +305,7 @@ Questi messaggi devono essere funzionali, non promozionali.
305
305
  validation: {
306
306
  name_required: 'Il nome è obbligatorio',
307
307
  invalid_social_url: 'Uno o più URL social non sono validi',
308
+ invalid_url_format: 'Formato URL non valido',
308
309
  },
309
310
  preview: {
310
311
  title: 'Anteprima',
@@ -738,6 +739,7 @@ Questi messaggi devono essere funzionali, non promozionali.
738
739
  width: 'Larghezza logo',
739
740
  alignment: 'Allineamento',
740
741
  background: 'Colore sfondo',
742
+ reset: 'Ripristina predefiniti',
741
743
  },
742
744
  },
743
745
  footer: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dev.smartpricing/message-composer-layer",
3
- "version": "1.0.20",
3
+ "version": "1.0.21",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./nuxt.config.ts",
@@ -39,7 +39,7 @@
39
39
  "vue-router": "^5.0.6",
40
40
  "vue3-emoji-picker": "^1.1.8",
41
41
  "zod": "^4.4.1",
42
- "@dev.smartpricing/message-composer-utils": "3.1.20"
42
+ "@dev.smartpricing/message-composer-utils": "3.1.21"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@nuxt/eslint": "^1.15.2",