@motor-cms/ui-admin 4.0.4 → 4.0.5
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.
|
@@ -160,7 +160,14 @@ function onEditFooter(): void {
|
|
|
160
160
|
}
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
+
const unlinkConfirmOpen = ref(false)
|
|
164
|
+
|
|
163
165
|
function onUnlinkFooter(): void {
|
|
166
|
+
unlinkConfirmOpen.value = true
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function executeUnlink(): void {
|
|
170
|
+
unlinkConfirmOpen.value = false
|
|
164
171
|
emit('unlinked')
|
|
165
172
|
}
|
|
166
173
|
</script>
|
|
@@ -169,7 +176,7 @@ function onUnlinkFooter(): void {
|
|
|
169
176
|
<div class="flex items-center justify-between gap-4 rounded-lg border border-default px-4 py-3">
|
|
170
177
|
<!-- Left: info -->
|
|
171
178
|
<div class="flex items-center gap-3 min-w-0">
|
|
172
|
-
<UIcon name="i-lucide-
|
|
179
|
+
<UIcon :name="pageInfo ? 'i-lucide-link' : 'i-lucide-unlink'" class="size-5 shrink-0" :class="pageInfo ? 'text-primary' : 'text-dimmed'" />
|
|
173
180
|
|
|
174
181
|
<div class="min-w-0">
|
|
175
182
|
<!-- Label -->
|
|
@@ -234,6 +241,7 @@ function onUnlinkFooter(): void {
|
|
|
234
241
|
{{ t('motor-admin.clients.global_components.edit_footer') }}
|
|
235
242
|
</UButton>
|
|
236
243
|
<UButton
|
|
244
|
+
icon="i-lucide-unlink"
|
|
237
245
|
variant="ghost"
|
|
238
246
|
color="error"
|
|
239
247
|
size="sm"
|
|
@@ -258,4 +266,47 @@ function onUnlinkFooter(): void {
|
|
|
258
266
|
</template>
|
|
259
267
|
</div>
|
|
260
268
|
</div>
|
|
269
|
+
|
|
270
|
+
<!-- Unlink confirmation modal -->
|
|
271
|
+
<UModal v-model:open="unlinkConfirmOpen">
|
|
272
|
+
<template #header>
|
|
273
|
+
{{ t('motor-admin.clients.global_components.unlink_footer') }}
|
|
274
|
+
</template>
|
|
275
|
+
<template #body>
|
|
276
|
+
<div class="space-y-3 text-sm">
|
|
277
|
+
<p>{{ t('motor-admin.clients.global_components.unlink_confirm') }}</p>
|
|
278
|
+
<div
|
|
279
|
+
v-if="pageInfo"
|
|
280
|
+
class="rounded-md bg-[var(--ui-bg-elevated)] px-3 py-2"
|
|
281
|
+
>
|
|
282
|
+
<div class="flex items-center gap-1.5">
|
|
283
|
+
<UIcon
|
|
284
|
+
name="i-lucide-panel-bottom"
|
|
285
|
+
class="size-3.5 shrink-0 text-muted"
|
|
286
|
+
/>
|
|
287
|
+
<span class="font-medium">{{ pageInfo.name }}</span>
|
|
288
|
+
</div>
|
|
289
|
+
</div>
|
|
290
|
+
<p class="text-muted">{{ t('motor-admin.clients.global_components.unlink_effect') }}</p>
|
|
291
|
+
</div>
|
|
292
|
+
</template>
|
|
293
|
+
<template #footer>
|
|
294
|
+
<div class="flex justify-end gap-2">
|
|
295
|
+
<UButton
|
|
296
|
+
color="neutral"
|
|
297
|
+
variant="outline"
|
|
298
|
+
@click="unlinkConfirmOpen = false"
|
|
299
|
+
>
|
|
300
|
+
{{ t('motor-core.global.cancel') }}
|
|
301
|
+
</UButton>
|
|
302
|
+
<UButton
|
|
303
|
+
color="error"
|
|
304
|
+
icon="i-lucide-unlink"
|
|
305
|
+
@click="executeUnlink"
|
|
306
|
+
>
|
|
307
|
+
{{ t('motor-admin.clients.global_components.unlink_footer') }}
|
|
308
|
+
</UButton>
|
|
309
|
+
</div>
|
|
310
|
+
</template>
|
|
311
|
+
</UModal>
|
|
261
312
|
</template>
|
|
@@ -53,7 +53,7 @@ export function useClientFrontendConfig(
|
|
|
53
53
|
const raw = options.clientRecord.value?.data?.frontend_config
|
|
54
54
|
if (!raw) return
|
|
55
55
|
|
|
56
|
-
const parsed = frontendConfigSchema.safeParse(raw)
|
|
56
|
+
const parsed = frontendConfigSchema(t).safeParse(raw)
|
|
57
57
|
|
|
58
58
|
if (parsed.success) {
|
|
59
59
|
Object.assign(state, parsed.data)
|
|
@@ -85,7 +85,7 @@ export function useClientFrontendConfig(
|
|
|
85
85
|
// ============================================
|
|
86
86
|
|
|
87
87
|
function validate(): boolean {
|
|
88
|
-
const result = frontendConfigSchema.safeParse(state)
|
|
88
|
+
const result = frontendConfigSchema(t).safeParse(state)
|
|
89
89
|
if (result.success) {
|
|
90
90
|
errors.value = {}
|
|
91
91
|
return true
|
|
@@ -55,6 +55,8 @@
|
|
|
55
55
|
"footer_created": "Footer erfolgreich erstellt.",
|
|
56
56
|
"published": "Veröffentlicht",
|
|
57
57
|
"draft": "Entwurf",
|
|
58
|
+
"unlink_confirm": "Möchten Sie die Verknüpfung zu diesem Footer wirklich lösen?",
|
|
59
|
+
"unlink_effect": "Der Footer wird nicht gelöscht, sondern nur die Verknüpfung zum Mandanten entfernt.",
|
|
58
60
|
"no_languages": "Keine Sprachen für diesen Mandanten konfiguriert. Erstellen Sie zuerst Navigationsbäume."
|
|
59
61
|
}
|
|
60
62
|
}
|
|
@@ -55,6 +55,8 @@
|
|
|
55
55
|
"footer_created": "Footer created successfully.",
|
|
56
56
|
"published": "Published",
|
|
57
57
|
"draft": "Draft",
|
|
58
|
+
"unlink_confirm": "Are you sure you want to unlink this footer?",
|
|
59
|
+
"unlink_effect": "The footer will not be deleted, only the link to the client will be removed.",
|
|
58
60
|
"no_languages": "No languages configured for this client. Add navigation trees first."
|
|
59
61
|
}
|
|
60
62
|
}
|
|
@@ -39,39 +39,45 @@ export interface FrontendConfig {
|
|
|
39
39
|
// Zod Schema (editable fields only, no globalComponents)
|
|
40
40
|
// ============================================
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
42
|
+
type TranslateFunction = (key: string) => string
|
|
43
|
+
|
|
44
|
+
function optionalUrlSchema(t: TranslateFunction) {
|
|
45
|
+
return z.string().refine(
|
|
46
|
+
(val) => val === '' || val === null || (() => { try { new URL(val); return true } catch { return false } })(),
|
|
47
|
+
{ message: t('motor-core.global.validation_url') }
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function frontendConfigSchema(t: TranslateFunction) {
|
|
52
|
+
return z.object({
|
|
53
|
+
brand: z.object({
|
|
54
|
+
name: z.string().min(1, { message: t('motor-core.global.validation_required') }),
|
|
55
|
+
logoAlt: z.string().min(1, { message: t('motor-core.global.validation_required') })
|
|
56
|
+
}),
|
|
57
|
+
colorScheme: z.string().min(1, { message: t('motor-core.global.validation_required') }),
|
|
58
|
+
logoSlug: z.string().min(1, { message: t('motor-core.global.validation_required') }),
|
|
59
|
+
contact: z.object({
|
|
60
|
+
contactUrl: z.string().url({ message: t('motor-core.global.validation_url') }),
|
|
61
|
+
email: z.string().email({ message: t('motor-core.global.validation_email') }),
|
|
62
|
+
whatsappUrl: optionalUrlSchema(t).nullable().optional().transform((v) => v ?? null)
|
|
63
|
+
}),
|
|
64
|
+
features: z.object({
|
|
65
|
+
orderLine: z.boolean().default(false),
|
|
66
|
+
appointments: z.boolean().default(false),
|
|
67
|
+
clickpath: z.boolean().default(false),
|
|
68
|
+
footerMenu: z.boolean().default(false)
|
|
69
|
+
}),
|
|
70
|
+
social: z.object({
|
|
71
|
+
instagram: optionalUrlSchema(t).nullable().optional().transform((v) => v ?? null),
|
|
72
|
+
facebook: optionalUrlSchema(t).nullable().optional().transform((v) => v ?? null)
|
|
73
|
+
}),
|
|
74
|
+
seo: z.object({
|
|
75
|
+
siteName: z.string().min(1, { message: t('motor-core.global.validation_required') })
|
|
76
|
+
})
|
|
71
77
|
})
|
|
72
|
-
}
|
|
78
|
+
}
|
|
73
79
|
|
|
74
|
-
export type FrontendConfigFormState = z.infer<typeof frontendConfigSchema
|
|
80
|
+
export type FrontendConfigFormState = z.infer<ReturnType<typeof frontendConfigSchema>>
|
|
75
81
|
|
|
76
82
|
// ============================================
|
|
77
83
|
// Form Field Definitions
|