@motor-cms/ui-admin 1.0.1-alpha.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.
Files changed (103) hide show
  1. package/README.md +77 -0
  2. package/app/components/form/inputs/CategoryTreeInput.vue +154 -0
  3. package/app/components/form/inputs/CategoryTreePicker.vue +355 -0
  4. package/app/components/form/inputs/NestedDraggable.vue +217 -0
  5. package/app/components/form/inputs/QuicklinksInput.vue +186 -0
  6. package/app/lang/de/motor-admin/CLAUDE.md +21 -0
  7. package/app/lang/de/motor-admin/ai_system_prompts.json +12 -0
  8. package/app/lang/de/motor-admin/categories.json +12 -0
  9. package/app/lang/de/motor-admin/category_trees.json +14 -0
  10. package/app/lang/de/motor-admin/clients.json +26 -0
  11. package/app/lang/de/motor-admin/config_variables.json +14 -0
  12. package/app/lang/de/motor-admin/domains.json +19 -0
  13. package/app/lang/de/motor-admin/email_templates.json +38 -0
  14. package/app/lang/de/motor-admin/global.json +5 -0
  15. package/app/lang/de/motor-admin/languages.json +16 -0
  16. package/app/lang/de/motor-admin/permissions.json +14 -0
  17. package/app/lang/de/motor-admin/roles.json +15 -0
  18. package/app/lang/de/motor-admin/users.json +22 -0
  19. package/app/lang/en/motor-admin/CLAUDE.md +7 -0
  20. package/app/lang/en/motor-admin/ai_system_prompts.json +12 -0
  21. package/app/lang/en/motor-admin/categories.json +12 -0
  22. package/app/lang/en/motor-admin/category_trees.json +14 -0
  23. package/app/lang/en/motor-admin/clients.json +26 -0
  24. package/app/lang/en/motor-admin/config_variables.json +14 -0
  25. package/app/lang/en/motor-admin/domains.json +18 -0
  26. package/app/lang/en/motor-admin/email_templates.json +33 -0
  27. package/app/lang/en/motor-admin/global.json +5 -0
  28. package/app/lang/en/motor-admin/languages.json +16 -0
  29. package/app/lang/en/motor-admin/permissions.json +14 -0
  30. package/app/lang/en/motor-admin/roles.json +15 -0
  31. package/app/lang/en/motor-admin/users.json +22 -0
  32. package/app/pages/dashboard.vue +5 -0
  33. package/app/pages/index.vue +39 -0
  34. package/app/pages/login.vue +85 -0
  35. package/app/pages/motor-admin/ai-system-prompts/CLAUDE.md +7 -0
  36. package/app/pages/motor-admin/ai-system-prompts/[id]/edit.vue +48 -0
  37. package/app/pages/motor-admin/ai-system-prompts/create.vue +40 -0
  38. package/app/pages/motor-admin/ai-system-prompts/index.vue +68 -0
  39. package/app/pages/motor-admin/category-trees/CLAUDE.md +7 -0
  40. package/app/pages/motor-admin/category-trees/[id]/CLAUDE.md +7 -0
  41. package/app/pages/motor-admin/category-trees/[id]/categories/[categoryId]/edit.vue +73 -0
  42. package/app/pages/motor-admin/category-trees/[id]/categories/create.vue +64 -0
  43. package/app/pages/motor-admin/category-trees/[id]/edit.vue +45 -0
  44. package/app/pages/motor-admin/category-trees/[id]/index.vue +81 -0
  45. package/app/pages/motor-admin/category-trees/create.vue +37 -0
  46. package/app/pages/motor-admin/category-trees/index.vue +54 -0
  47. package/app/pages/motor-admin/clients/CLAUDE.md +11 -0
  48. package/app/pages/motor-admin/clients/[id]/CLAUDE.md +11 -0
  49. package/app/pages/motor-admin/clients/[id]/edit.vue +45 -0
  50. package/app/pages/motor-admin/clients/create.vue +37 -0
  51. package/app/pages/motor-admin/clients/index.vue +46 -0
  52. package/app/pages/motor-admin/config-variables/CLAUDE.md +11 -0
  53. package/app/pages/motor-admin/config-variables/[id]/edit.vue +44 -0
  54. package/app/pages/motor-admin/config-variables/create.vue +36 -0
  55. package/app/pages/motor-admin/config-variables/index.vue +66 -0
  56. package/app/pages/motor-admin/domains/CLAUDE.md +11 -0
  57. package/app/pages/motor-admin/domains/[id]/edit.vue +54 -0
  58. package/app/pages/motor-admin/domains/create.vue +46 -0
  59. package/app/pages/motor-admin/domains/index.vue +98 -0
  60. package/app/pages/motor-admin/email-templates/CLAUDE.md +12 -0
  61. package/app/pages/motor-admin/email-templates/[id]/CLAUDE.md +7 -0
  62. package/app/pages/motor-admin/email-templates/[id]/edit.vue +56 -0
  63. package/app/pages/motor-admin/email-templates/create.vue +48 -0
  64. package/app/pages/motor-admin/email-templates/index.vue +67 -0
  65. package/app/pages/motor-admin/index.vue +12 -0
  66. package/app/pages/motor-admin/languages/CLAUDE.md +7 -0
  67. package/app/pages/motor-admin/languages/[id]/edit.vue +44 -0
  68. package/app/pages/motor-admin/languages/create.vue +36 -0
  69. package/app/pages/motor-admin/languages/index.vue +44 -0
  70. package/app/pages/motor-admin/permission-groups/CLAUDE.md +14 -0
  71. package/app/pages/motor-admin/permission-groups/[id]/CLAUDE.md +11 -0
  72. package/app/pages/motor-admin/permission-groups/[id]/edit.vue +49 -0
  73. package/app/pages/motor-admin/permission-groups/create.vue +41 -0
  74. package/app/pages/motor-admin/permission-groups/index.vue +43 -0
  75. package/app/pages/motor-admin/roles/CLAUDE.md +7 -0
  76. package/app/pages/motor-admin/roles/[id]/edit.vue +47 -0
  77. package/app/pages/motor-admin/roles/create.vue +40 -0
  78. package/app/pages/motor-admin/roles/index.vue +45 -0
  79. package/app/pages/motor-admin/theme-preview/CLAUDE.md +7 -0
  80. package/app/pages/motor-admin/theme-preview/index.vue +4801 -0
  81. package/app/pages/motor-admin/theme-preview/themes/CLAUDE.md +11 -0
  82. package/app/pages/motor-admin/theme-preview/themes/asymmetric-brutalist.md +381 -0
  83. package/app/pages/motor-admin/theme-preview/themes/bold-modern.md +231 -0
  84. package/app/pages/motor-admin/theme-preview/themes/geometric-minimal.md +778 -0
  85. package/app/pages/motor-admin/theme-preview/themes/gradient-flow.md +1057 -0
  86. package/app/pages/motor-admin/theme-preview/themes/liquid-glass.md +823 -0
  87. package/app/pages/motor-admin/theme-preview/themes/neon-amber.md +1223 -0
  88. package/app/pages/motor-admin/theme-preview/themes/neon-terminal.md +779 -0
  89. package/app/pages/motor-admin/theme-preview/themes/neon-violet.md +1134 -0
  90. package/app/pages/motor-admin/theme-preview/themes/professional-clean.md +232 -0
  91. package/app/pages/motor-admin/theme-preview/themes/refined-brutalist.md +462 -0
  92. package/app/pages/motor-admin/theme-preview/themes/wild-card.md +263 -0
  93. package/app/pages/motor-admin/users/CLAUDE.md +17 -0
  94. package/app/pages/motor-admin/users/[id]/CLAUDE.md +11 -0
  95. package/app/pages/motor-admin/users/[id]/edit.vue +83 -0
  96. package/app/pages/motor-admin/users/create.vue +40 -0
  97. package/app/pages/motor-admin/users/index.vue +66 -0
  98. package/app/pages/profile.vue +363 -0
  99. package/app/pages/search.vue +91 -0
  100. package/app/types/generated/form-meta.ts +258 -0
  101. package/app/types/generated/grid-meta.ts +172 -0
  102. package/nuxt.config.ts +1 -0
  103. package/package.json +26 -0
@@ -0,0 +1,217 @@
1
+ <!-- app/components/form/inputs/NestedDraggable.vue -->
2
+ <script setup lang="ts">
3
+ import type { TreeNode } from '@motor-cms/ui-core/app/types/tree'
4
+
5
+ defineOptions({ name: 'FormInputsNestedDraggable' })
6
+
7
+ defineProps<{
8
+ items: TreeNode[]
9
+ parentId: number | null
10
+ depth: number
11
+ }>()
12
+
13
+ const {
14
+ currentId, nonSelectableIds, moveItem,
15
+ isEditMode, isDragging, expandedIds, toggleNode,
16
+ handleDragOver, cleanupAutoExpand
17
+ } = inject<{
18
+ currentId: ComputedRef<number | undefined>
19
+ nonSelectableIds: ComputedRef<Set<number>>
20
+ moveItem: (itemId: number, newParentId: number | null, newIndex: number) => void
21
+ isEditMode: ComputedRef<boolean>
22
+ isDragging: Ref<boolean>
23
+ expandedIds: ComputedRef<Set<number>>
24
+ toggleNode: (id: number) => void
25
+ handleDragOver: (itemId: number) => void
26
+ cleanupAutoExpand: (dropParentId: number | null) => void
27
+ }>('categoryTree')!
28
+
29
+ function isExpanded(id: number): boolean {
30
+ return expandedIds.value.has(id)
31
+ }
32
+
33
+ function hasChildren(item: TreeNode): boolean {
34
+ return item.children.length > 0
35
+ }
36
+
37
+ function onItemDragOver(item: TreeNode) {
38
+ if (!isDragging.value) return
39
+ handleDragOver(item.id)
40
+ }
41
+
42
+ const listRef = ref<HTMLElement | null>(null)
43
+ let sortableInstance: { destroy: () => void } | null = null
44
+
45
+ onMounted(async () => {
46
+ if (!listRef.value || !isEditMode.value) return
47
+
48
+ const { default: Sortable } = await import('sortablejs')
49
+
50
+ sortableInstance = Sortable.create(listRef.value, {
51
+ group: { name: 'categories' },
52
+ animation: 200,
53
+ fallbackOnBody: true,
54
+ swapThreshold: 0.5,
55
+ invertSwap: true,
56
+ invertedSwapThreshold: 0.5,
57
+ emptyInsertThreshold: 8,
58
+ filter: '.no-drag',
59
+ preventOnFilter: false,
60
+ ghostClass: 'opacity-30',
61
+ onStart() {
62
+ isDragging.value = true
63
+ },
64
+ onMove(evt) {
65
+ // Prevent dropping into the current item's own descendants
66
+ const targetParentIdStr = (evt.to as HTMLElement).dataset.parentId
67
+ if (targetParentIdStr) {
68
+ const targetParentId = parseInt(targetParentIdStr)
69
+ if (!isNaN(targetParentId) && nonSelectableIds.value.has(targetParentId)) {
70
+ return false
71
+ }
72
+ }
73
+ return true
74
+ },
75
+ onEnd(evt) {
76
+ isDragging.value = false
77
+
78
+ if (evt.newIndex === undefined || evt.oldIndex === undefined) {
79
+ cleanupAutoExpand(null)
80
+ return
81
+ }
82
+
83
+ const itemId = parseInt(evt.item.dataset.id!)
84
+ if (isNaN(itemId)) {
85
+ cleanupAutoExpand(null)
86
+ return
87
+ }
88
+
89
+ const targetParentIdStr = (evt.to as HTMLElement).dataset.parentId
90
+ const newParentId = targetParentIdStr ? parseInt(targetParentIdStr) : null
91
+ const newIndex = evt.newIndex
92
+
93
+ // Revert DOM change — let Vue handle re-rendering from reactive data
94
+ if (evt.from !== evt.to) {
95
+ evt.to.removeChild(evt.item)
96
+ const ref = evt.from.children[evt.oldIndex] || null
97
+ evt.from.insertBefore(evt.item, ref)
98
+ } else {
99
+ evt.from.removeChild(evt.item)
100
+ const ref = evt.from.children[evt.oldIndex] || null
101
+ evt.from.insertBefore(evt.item, ref)
102
+ }
103
+
104
+ moveItem(itemId, newParentId, newIndex)
105
+ cleanupAutoExpand(newParentId)
106
+ }
107
+ })
108
+ })
109
+
110
+ onBeforeUnmount(() => {
111
+ sortableInstance?.destroy()
112
+ })
113
+ </script>
114
+
115
+ <template>
116
+ <ul
117
+ ref="listRef"
118
+ :data-parent-id="parentId ?? ''"
119
+ :class="[
120
+ 'list-none',
121
+ depth > 0 ? 'ml-4 pl-3' : '',
122
+ depth > 0 && items.length > 0 ? 'border-l border-[var(--ui-border)]' : '',
123
+ items.length === 0 ? 'min-h-[8px]' : '',
124
+ isEditMode && items.length > 0 ? 'pb-1' : ''
125
+ ]"
126
+ >
127
+ <li
128
+ v-for="item in items"
129
+ :key="item.id"
130
+ :data-id="item.id"
131
+ :class="{ 'no-drag': item.id !== currentId }"
132
+ >
133
+ <!-- Current item: highlighted + draggable -->
134
+ <div
135
+ v-if="item.id === currentId"
136
+ class="flex items-center gap-1 px-2 py-1.5 my-0.5 cursor-grab active:cursor-grabbing"
137
+ >
138
+ <span class="shrink-0 w-4" />
139
+ <span class="inline-flex items-center gap-1 rounded-md px-1.5 py-0.5 -my-0.5 ring-2 ring-[var(--ui-primary)] bg-[var(--ui-primary)]/10 font-semibold text-[var(--ui-primary)]">
140
+ <UIcon
141
+ name="i-lucide-grip-vertical"
142
+ class="shrink-0 size-4 opacity-60"
143
+ />
144
+ {{ item.name || '…' }}
145
+ </span>
146
+ </div>
147
+
148
+ <!-- Non-selectable descendants (dimmed) -->
149
+ <div
150
+ v-else-if="nonSelectableIds.has(item.id)"
151
+ class="flex items-center gap-1 px-2 py-1.5 my-0.5 opacity-40"
152
+ @dragover="onItemDragOver(item)"
153
+ >
154
+ <button
155
+ v-if="hasChildren(item)"
156
+ class="shrink-0 size-6 sm:size-4 flex items-center justify-center"
157
+ type="button"
158
+ @click.stop="toggleNode(item.id)"
159
+ >
160
+ <UIcon
161
+ name="i-lucide-chevron-right"
162
+ class="size-3.5 transition-transform duration-200"
163
+ :class="{ 'rotate-90': isExpanded(item.id) }"
164
+ />
165
+ </button>
166
+ <span
167
+ v-else
168
+ class="shrink-0 w-6 sm:w-4"
169
+ />
170
+ <UIcon
171
+ :name="hasChildren(item) ? (isExpanded(item.id) ? 'i-lucide-folder-open' : 'i-lucide-folder') : 'i-lucide-file'"
172
+ class="shrink-0 size-4"
173
+ />
174
+ {{ item.name }}
175
+ </div>
176
+
177
+ <!-- Other items (static) -->
178
+ <div
179
+ v-else
180
+ class="flex items-center gap-1 px-2 py-1.5 my-0.5"
181
+ @dragover="onItemDragOver(item)"
182
+ >
183
+ <button
184
+ v-if="hasChildren(item)"
185
+ class="shrink-0 size-6 sm:size-4 flex items-center justify-center rounded hover:bg-[var(--ui-bg-elevated)] transition-colors cursor-pointer"
186
+ type="button"
187
+ @click.stop="toggleNode(item.id)"
188
+ >
189
+ <UIcon
190
+ name="i-lucide-chevron-right"
191
+ class="size-3.5 transition-transform duration-200"
192
+ :class="{ 'rotate-90': isExpanded(item.id) }"
193
+ />
194
+ </button>
195
+ <span
196
+ v-else
197
+ class="shrink-0 w-6 sm:w-4"
198
+ />
199
+ <UIcon
200
+ :name="hasChildren(item) ? (isExpanded(item.id) ? 'i-lucide-folder-open' : 'i-lucide-folder') : 'i-lucide-file'"
201
+ class="shrink-0 size-4 opacity-60"
202
+ />
203
+ {{ item.name }}
204
+ </div>
205
+
206
+ <!-- Children container:
207
+ - Skip for current item (its children move with it, no need to render)
208
+ - Always render in drag mode (expanded shows items, collapsed is empty drop target) -->
209
+ <FormInputsNestedDraggable
210
+ v-if="item.id !== currentId && isEditMode"
211
+ :items="isExpanded(item.id) ? item.children : []"
212
+ :parent-id="item.id"
213
+ :depth="depth + 1"
214
+ />
215
+ </li>
216
+ </ul>
217
+ </template>
@@ -0,0 +1,186 @@
1
+ <!-- app/components/form/inputs/QuicklinksInput.vue -->
2
+ <script setup lang="ts">
3
+ interface Quicklink {
4
+ url: string
5
+ url_label: string
6
+ position: number
7
+ }
8
+
9
+ const props = defineProps<{
10
+ modelValue: Quicklink[]
11
+ }>()
12
+
13
+ const emit = defineEmits<{
14
+ 'update:modelValue': [value: Quicklink[]]
15
+ }>()
16
+
17
+ const { t } = useI18n()
18
+
19
+ // Input state for adding a new link
20
+ const newUrl = ref('')
21
+ const newLabel = ref('')
22
+ const urlError = ref('')
23
+
24
+ const canAdd = computed(() => {
25
+ if (!newUrl.value || !newLabel.value) return false
26
+ try {
27
+ new URL(newUrl.value)
28
+ return true
29
+ } catch {
30
+ return false
31
+ }
32
+ })
33
+
34
+ function validateUrl() {
35
+ if (!newUrl.value) {
36
+ urlError.value = ''
37
+ return
38
+ }
39
+ try {
40
+ new URL(newUrl.value)
41
+ urlError.value = ''
42
+ } catch {
43
+ urlError.value = t('motor-core.global.validation_url')
44
+ }
45
+ }
46
+
47
+ function addLink() {
48
+ if (!canAdd.value) return
49
+ const links = [...props.modelValue]
50
+ links.push({
51
+ url: newUrl.value,
52
+ url_label: newLabel.value,
53
+ position: links.length
54
+ })
55
+ emit('update:modelValue', links)
56
+ newUrl.value = ''
57
+ newLabel.value = ''
58
+ urlError.value = ''
59
+ }
60
+
61
+ function removeLink(index: number) {
62
+ const links = props.modelValue
63
+ .filter((_, i) => i !== index)
64
+ .map((link, i) => ({ ...link, position: i }))
65
+ emit('update:modelValue', links)
66
+ }
67
+
68
+ // Drag reorder
69
+ const listRef = ref<HTMLElement | null>(null)
70
+ let sortableInstance: { destroy: () => void } | null = null
71
+
72
+ async function initSortable() {
73
+ if (!listRef.value) return
74
+ sortableInstance?.destroy()
75
+ const { default: Sortable } = await import('sortablejs')
76
+ sortableInstance = Sortable.create(listRef.value, {
77
+ animation: 150,
78
+ handle: '.drag-handle',
79
+ onEnd(evt) {
80
+ const { oldIndex, newIndex } = evt
81
+ if (oldIndex == null || newIndex == null || oldIndex === newIndex) return
82
+
83
+ // Revert DOM swap — let Vue re-render from updated data
84
+ const parent = evt.item.parentNode!
85
+ if (oldIndex < newIndex) {
86
+ const refNode = parent.children[oldIndex] ?? null
87
+ parent.insertBefore(evt.item, refNode)
88
+ } else {
89
+ const refNode = parent.children[oldIndex + 1] ?? null
90
+ parent.insertBefore(evt.item, refNode)
91
+ }
92
+
93
+ const links = [...props.modelValue]
94
+ const [moved] = links.splice(oldIndex, 1)
95
+ if (moved) {
96
+ links.splice(newIndex, 0, moved)
97
+ emit('update:modelValue', links.map((l, i) => ({ ...l, position: i })))
98
+ }
99
+ }
100
+ })
101
+ }
102
+
103
+ watch(() => props.modelValue.length, () => {
104
+ nextTick(() => initSortable())
105
+ })
106
+
107
+ onMounted(() => {
108
+ if (props.modelValue.length > 0) {
109
+ nextTick(() => initSortable())
110
+ }
111
+ })
112
+
113
+ onBeforeUnmount(() => {
114
+ sortableInstance?.destroy()
115
+ })
116
+ </script>
117
+
118
+ <template>
119
+ <div>
120
+ <!-- Existing links -->
121
+ <div
122
+ v-if="modelValue.length > 0"
123
+ ref="listRef"
124
+ class="mb-4 divide-y divide-default rounded-lg ring-1 ring-[var(--ui-border)]"
125
+ >
126
+ <div
127
+ v-for="(link, index) in modelValue"
128
+ :key="index"
129
+ class="flex items-center gap-3 px-3 py-2 group"
130
+ >
131
+ <UIcon
132
+ name="i-lucide-grip-vertical"
133
+ class="drag-handle size-4 text-muted cursor-grab shrink-0"
134
+ />
135
+ <div class="flex-1 min-w-0">
136
+ <div class="text-sm font-medium truncate">
137
+ {{ link.url_label }}
138
+ </div>
139
+ <div class="text-xs text-muted truncate">
140
+ {{ link.url }}
141
+ </div>
142
+ </div>
143
+ <UButton
144
+ icon="i-lucide-trash-2"
145
+ variant="ghost"
146
+ color="error"
147
+ size="xs"
148
+ class="opacity-0 group-hover:opacity-100 transition-opacity shrink-0"
149
+ @click="removeLink(index)"
150
+ />
151
+ </div>
152
+ </div>
153
+
154
+ <!-- Add new link -->
155
+ <div class="flex items-start gap-3">
156
+ <div class="flex-1">
157
+ <UInput
158
+ v-model="newUrl"
159
+ :placeholder="t('motor-builder.search_configs.link_url')"
160
+ class="w-full"
161
+ @blur="validateUrl"
162
+ @keydown.enter.prevent="addLink"
163
+ />
164
+ <p
165
+ v-if="urlError"
166
+ class="text-xs text-[var(--ui-error)] mt-1"
167
+ >
168
+ {{ urlError }}
169
+ </p>
170
+ </div>
171
+ <UInput
172
+ v-model="newLabel"
173
+ :placeholder="t('motor-builder.search_configs.link_url_label')"
174
+ class="flex-1"
175
+ @keydown.enter.prevent="addLink"
176
+ />
177
+ <UButton
178
+ icon="i-lucide-plus"
179
+ variant="outline"
180
+ :disabled="!canAdd"
181
+ class="shrink-0"
182
+ @click="addLink"
183
+ />
184
+ </div>
185
+ </div>
186
+ </template>
@@ -0,0 +1,21 @@
1
+ <claude-mem-context>
2
+ # Recent Activity
3
+
4
+ <!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
5
+
6
+ ### Feb 12, 2026
7
+
8
+ | ID | Time | T | Title | Read |
9
+ |----|------|---|-------|------|
10
+ | #24269 | 3:11 PM | 🟣 | Permissions Multi-Select Field Added to Permission-Groups Form | ~435 |
11
+ | #24251 | 1:14 PM | 🔵 | Comprehensive Application Refactoring Staged for Commit | ~515 |
12
+
13
+ ### Feb 18, 2026
14
+
15
+ | ID | Time | T | Title | Read |
16
+ |----|------|---|-------|------|
17
+ | #27326 | 5:36 PM | ✅ | Password UX Translation Keys Added | ~171 |
18
+ | #27302 | 5:30 PM | ✅ | Translation Key Added for Filter Count Badge | ~147 |
19
+ | #27301 | " | 🔵 | Grid Translation Keys Inventory | ~233 |
20
+ | #27271 | 5:27 PM | 🔵 | i18n Translation Keys Structure Reviewed | ~251 |
21
+ </claude-mem-context>
@@ -0,0 +1,12 @@
1
+ {
2
+ "ai_system_prompts": "KI-System-Prompts",
3
+ "title": "KI-System-Prompts",
4
+ "subtitle": "KI-System-Prompts verwalten",
5
+ "add": "KI-System-Prompt hinzufügen",
6
+ "prompt": "Prompt",
7
+ "prompt_description": "Der System-Prompt-Text, der an das KI-Modell gesendet wird",
8
+ "create_title": "KI-System-Prompt erstellen",
9
+ "edit_title": "KI-System-Prompt bearbeiten",
10
+ "created_success": "KI-System-Prompt erfolgreich erstellt.",
11
+ "updated_success": "KI-System-Prompt erfolgreich aktualisiert."
12
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "categories": "Kategorien",
3
+ "category": "Kategorie",
4
+ "title": "Kategorien",
5
+ "add": "Kategorie hinzufügen",
6
+ "create_title": "Kategorie erstellen",
7
+ "edit_title": "Kategorie bearbeiten",
8
+ "created_success": "Kategorie wurde erfolgreich erstellt",
9
+ "updated_success": "Kategorie wurde erfolgreich aktualisiert",
10
+ "parent": "Übergeordnete Kategorie",
11
+ "root": "Stamm (oberste Ebene)"
12
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "category_trees": "Kategoriebäume",
3
+ "category_tree": "Kategoriebaum",
4
+ "title": "Kategoriebäume",
5
+ "subtitle": "Kategoriebäume und ihre Kategorien verwalten",
6
+ "add": "Kategoriebaum hinzufügen",
7
+ "create_title": "Kategoriebaum erstellen",
8
+ "edit_title": "Kategoriebaum bearbeiten",
9
+ "created_success": "Kategoriebaum wurde erfolgreich erstellt",
10
+ "updated_success": "Kategoriebaum wurde erfolgreich aktualisiert",
11
+ "children": "Kinder",
12
+ "children_title": "Kategorien in \"{name}\"",
13
+ "children_subtitle": "Kategorien in diesem Baum verwalten"
14
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "clients": "Mandanten",
3
+ "client": "Mandant",
4
+ "title": "Mandanten",
5
+ "subtitle": "Systemmandanten verwalten",
6
+ "add": "Mandant hinzufügen",
7
+ "create_title": "Mandant erstellen",
8
+ "edit_title": "Mandant bearbeiten",
9
+ "created_success": "Mandant erfolgreich erstellt.",
10
+ "updated_success": "Mandant erfolgreich aktualisiert.",
11
+ "slug": "Slug",
12
+ "slug_description": "URL-freundlicher Bezeichner, automatisch aus Name generiert",
13
+ "address": "Adresse",
14
+ "zip": "PLZ",
15
+ "city": "Stadt",
16
+ "country": "Land",
17
+ "country_iso_3166_1": "Ländercode",
18
+ "website": "Webseite",
19
+ "description": "Beschreibung",
20
+ "contact_name": "Kontaktperson",
21
+ "contact_email": "Kontakt-E-Mail",
22
+ "contact_phone": "Telefon",
23
+ "group_address": "Adresse",
24
+ "group_contact": "Kontakt",
25
+ "group_other": "Sonstiges"
26
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "config_variables": "Konfigurationsvariablen",
3
+ "title": "Konfigurationsvariablen",
4
+ "subtitle": "Konfigurationsvariablen verwalten",
5
+ "add": "Konfigurationsvariable hinzufügen",
6
+ "package": "Paket",
7
+ "group": "Gruppe",
8
+ "value": "Wert",
9
+ "is_invisible": "Versteckt",
10
+ "create_title": "Konfigurationsvariable erstellen",
11
+ "edit_title": "Konfigurationsvariable bearbeiten",
12
+ "created_success": "Konfigurationsvariable erfolgreich erstellt.",
13
+ "updated_success": "Konfigurationsvariable erfolgreich aktualisiert."
14
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "domain": "Domain",
3
+ "domains": "Domains",
4
+ "title": "Domains",
5
+ "subtitle": "Systemdomains verwalten",
6
+ "add": "Domain hinzufügen",
7
+ "create_title": "Domain erstellen",
8
+ "edit_title": "Domain bearbeiten",
9
+ "created_success": "Domain erfolgreich erstellt.",
10
+ "updated_success": "Domain erfolgreich aktualisiert.",
11
+ "host": "Host",
12
+ "protocol": "Protokoll",
13
+ "port": "Port",
14
+ "path": "Pfad",
15
+ "target": "Ziel",
16
+ "parameters": "Parameter",
17
+ "group_connection": "Verbindung",
18
+ "group_routing": "Routing"
19
+ }
@@ -0,0 +1,38 @@
1
+ {
2
+ "email_templates": "E-Mail-Vorlagen",
3
+ "title": "E-Mail-Vorlagen",
4
+ "subtitle": "E-Mail-Vorlagen verwalten",
5
+ "add": "E-Mail-Vorlage hinzufügen",
6
+ "create_title": "E-Mail-Vorlage erstellen",
7
+ "edit_title": "E-Mail-Vorlage bearbeiten",
8
+ "slug": "Slug",
9
+ "slug_description": "URL-freundlicher Bezeichner, automatisch aus dem Namen generiert",
10
+ "subject": "Betreff",
11
+ "subject_description": "Betreffzeile der E-Mail",
12
+ "body_text": "Inhalt (Text)",
13
+ "body_text_description": "Nur-Text-Version des E-Mail-Inhalts",
14
+ "body_html": "Inhalt (HTML)",
15
+ "body_html_description": "HTML-Version des E-Mail-Inhalts",
16
+ "has_body_html": "HTML",
17
+ "default_sender_name": "Absendername",
18
+ "default_sender_email": "Absender-E-Mail",
19
+ "default_sender_email_description": "Wird als Absenderadresse verwendet",
20
+ "default_recipient_name": "Empfängername",
21
+ "default_recipient_email": "Empfänger-E-Mail",
22
+ "default_cc_email": "CC-E-Mail",
23
+ "default_cc_email_description": "Kommagetrennte Liste von CC-Adressen",
24
+ "default_bcc_email": "BCC-E-Mail",
25
+ "default_bcc_email_description": "Kommagetrennte Liste von BCC-Adressen",
26
+ "default_replyto_email": "Antwort-an-E-Mail",
27
+ "default_replyto_name": "Antwort-an-Name",
28
+ "group_content": "Inhalt",
29
+ "group_sender": "Absender-Standardwerte",
30
+ "group_recipient": "Empfänger-Standardwerte",
31
+ "usage_title": "Verwendung",
32
+ "created_success": "E-Mail-Vorlage erfolgreich erstellt.",
33
+ "updated_success": "E-Mail-Vorlage erfolgreich aktualisiert.",
34
+ "help": {
35
+ "body_text": "Geben Sie {ALLE_FORMULARFELDER} im Textfeld ein, um alle Variablen eines Formulars auszugeben, die dem Template übermittelt werden.",
36
+ "body_html": "Geben Sie {ALLE_FORMULARFELDER} im Textfeld ein, um alle Variablen eines Formulars auszugeben, die dem Template übermittelt werden."
37
+ }
38
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "dashboard": "Dashboard",
3
+ "administration": "Administration",
4
+ "section_subtitle": "Benutzer, Rollen, Berechtigungen und Systemeinstellungen verwalten"
5
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "languages": "Sprachen",
3
+ "language": "Sprache",
4
+ "title": "Sprachen",
5
+ "subtitle": "Systemsprachen verwalten",
6
+ "add": "Sprache hinzufügen",
7
+ "code": "Code",
8
+ "english_name": "Englischer Name",
9
+ "native_name": "Eigenname",
10
+ "create_title": "Sprache erstellen",
11
+ "edit_title": "Sprache bearbeiten",
12
+ "created_success": "Sprache erfolgreich erstellt.",
13
+ "updated_success": "Sprache erfolgreich aktualisiert.",
14
+ "iso_639_1": "ISO 639-1 Code",
15
+ "iso_639_1_description": "Zweibuchstabiger Sprachcode (z.B. en, de, fr)"
16
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "permissions": "Berechtigungen",
3
+ "permission_group": "Berechtigungsgruppe",
4
+ "permission_groups": "Berechtigungsgruppen",
5
+ "title": "Berechtigungsgruppen",
6
+ "subtitle": "Berechtigungsgruppen verwalten",
7
+ "add": "Berechtigungsgruppe hinzufügen",
8
+ "position": "Position",
9
+ "create_title": "Berechtigungsgruppe erstellen",
10
+ "edit_title": "Berechtigungsgruppe bearbeiten",
11
+ "created_success": "Berechtigungsgruppe erfolgreich erstellt.",
12
+ "updated_success": "Berechtigungsgruppe erfolgreich aktualisiert.",
13
+ "group_permissions": "Berechtigungen"
14
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "roles": "Rollen",
3
+ "role": "Rolle",
4
+ "title": "Rollen",
5
+ "subtitle": "Benutzerrollen verwalten",
6
+ "add": "Rolle hinzufügen",
7
+ "guard": "Guard",
8
+ "permissions": "Berechtigungen",
9
+ "create_title": "Rolle erstellen",
10
+ "edit_title": "Rolle bearbeiten",
11
+ "created_success": "Rolle erfolgreich erstellt.",
12
+ "updated_success": "Rolle erfolgreich aktualisiert.",
13
+ "guard_name": "Guard-Name",
14
+ "group_access": "Berechtigungen"
15
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "users": "Benutzer",
3
+ "user": "Benutzer",
4
+ "title": "Benutzer",
5
+ "subtitle": "Systembenutzer verwalten",
6
+ "add": "Benutzer hinzufügen",
7
+ "avatar": "",
8
+ "clients": "Mandanten",
9
+ "roles": "Rollen",
10
+ "permissions": "Berechtigungen",
11
+ "create_title": "Benutzer erstellen",
12
+ "edit_title": "Benutzer bearbeiten",
13
+ "created_success": "Benutzer wurde erfolgreich erstellt",
14
+ "updated_success": "Benutzer wurde erfolgreich aktualisiert",
15
+ "password": "Passwort",
16
+ "password_description": "Leer lassen, um das aktuelle Passwort beizubehalten",
17
+ "change_password": "Passwort ändern",
18
+ "password_confirmation": "Passwort bestätigen",
19
+ "password_mismatch": "Passwörter stimmen nicht überein",
20
+ "group_security": "Sicherheit",
21
+ "group_access": "Zugriff"
22
+ }
@@ -0,0 +1,7 @@
1
+ <claude-mem-context>
2
+ # Recent Activity
3
+
4
+ <!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
5
+
6
+ *No recent activity*
7
+ </claude-mem-context>
@@ -0,0 +1,12 @@
1
+ {
2
+ "ai_system_prompts": "AI System Prompts",
3
+ "title": "AI System Prompts",
4
+ "subtitle": "Manage AI system prompts",
5
+ "add": "Add AI System Prompt",
6
+ "prompt": "Prompt",
7
+ "prompt_description": "The system prompt text sent to the AI model",
8
+ "create_title": "Create AI System Prompt",
9
+ "edit_title": "Edit AI System Prompt",
10
+ "created_success": "AI system prompt created successfully.",
11
+ "updated_success": "AI system prompt updated successfully."
12
+ }