@edgedev/create-edge-app 1.1.25 → 1.1.27

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 (111) hide show
  1. package/README.md +55 -20
  2. package/{agent.md → agents.md} +2 -0
  3. package/bin/cli.js +6 -6
  4. package/edge/components/auth/login.vue +384 -0
  5. package/edge/components/auth/register.vue +396 -0
  6. package/edge/components/auth.vue +108 -0
  7. package/edge/components/autoFileUpload.vue +215 -0
  8. package/edge/components/billing.vue +8 -0
  9. package/edge/components/buttonDivider.vue +14 -0
  10. package/edge/components/chip.vue +34 -0
  11. package/edge/components/clipboardButton.vue +42 -0
  12. package/edge/components/cms/block.vue +529 -0
  13. package/edge/components/cms/blockApi.vue +212 -0
  14. package/edge/components/cms/blockEditor.vue +725 -0
  15. package/edge/components/cms/blockInput.vue +66 -0
  16. package/edge/components/cms/blockPicker.vue +486 -0
  17. package/edge/components/cms/blockRender.vue +78 -0
  18. package/edge/components/cms/blockSheetContent.vue +28 -0
  19. package/edge/components/cms/codeEditor.vue +466 -0
  20. package/edge/components/cms/fontUpload.vue +327 -0
  21. package/edge/components/cms/htmlContent.vue +807 -0
  22. package/edge/components/cms/init_blocks/api_with_subarrays.html +17 -0
  23. package/edge/components/cms/init_blocks/array_with_collection.html +7 -0
  24. package/edge/components/cms/init_blocks/array_with_objects.html +7 -0
  25. package/edge/components/cms/init_blocks/carousel.html +103 -0
  26. package/edge/components/cms/init_blocks/contact_us.html +69 -0
  27. package/edge/components/cms/init_blocks/content_with_left_image.html +27 -0
  28. package/edge/components/cms/init_blocks/footer.html +24 -0
  29. package/edge/components/cms/init_blocks/header_divider.html +7 -0
  30. package/edge/components/cms/init_blocks/hero.html +35 -0
  31. package/edge/components/cms/init_blocks/hero_carousel.html +52 -0
  32. package/edge/components/cms/init_blocks/newsletter.html +117 -0
  33. package/edge/components/cms/init_blocks/post_content.html +7 -0
  34. package/edge/components/cms/init_blocks/post_title_header.html +21 -0
  35. package/edge/components/cms/init_blocks/posts_list.html +20 -0
  36. package/edge/components/cms/init_blocks/properties_showcase.html +100 -0
  37. package/edge/components/cms/init_blocks/property_carousel.html +59 -0
  38. package/edge/components/cms/init_blocks/property_detail.html +112 -0
  39. package/edge/components/cms/init_blocks/property_detail_header.html +34 -0
  40. package/edge/components/cms/init_blocks/property_results.html +137 -0
  41. package/edge/components/cms/init_blocks/property_search.html +75 -0
  42. package/edge/components/cms/init_blocks/simple_array.html +7 -0
  43. package/edge/components/cms/mediaCard.vue +116 -0
  44. package/edge/components/cms/mediaManager.vue +386 -0
  45. package/edge/components/cms/menu.vue +1103 -0
  46. package/edge/components/cms/optionsSelect.vue +107 -0
  47. package/edge/components/cms/page.vue +1785 -0
  48. package/edge/components/cms/posts.vue +1083 -0
  49. package/edge/components/cms/site.vue +1475 -0
  50. package/edge/components/cms/themeDefaultMenu.vue +548 -0
  51. package/edge/components/cms/themeEditor.vue +429 -0
  52. package/edge/components/dashboard.vue +776 -0
  53. package/edge/components/editor.vue +671 -0
  54. package/edge/components/fileTree.vue +72 -0
  55. package/edge/components/files.vue +89 -0
  56. package/edge/components/formSubtypes/myOrgs.vue +214 -0
  57. package/edge/components/formSubtypes/users.vue +336 -0
  58. package/edge/components/functionChips.vue +57 -0
  59. package/edge/components/gError.vue +98 -0
  60. package/edge/components/gHelper.vue +67 -0
  61. package/edge/components/gInput.vue +1331 -0
  62. package/edge/components/loggingIn.vue +41 -0
  63. package/edge/components/menu.vue +137 -0
  64. package/edge/components/menuContent.vue +132 -0
  65. package/edge/components/myAccount.vue +317 -0
  66. package/edge/components/myOrganizations.vue +75 -0
  67. package/edge/components/myProfile.vue +122 -0
  68. package/edge/components/orgSwitcher.vue +25 -0
  69. package/edge/components/organizationMembers.vue +522 -0
  70. package/edge/components/organizationSettings.vue +271 -0
  71. package/edge/components/shad/breadcrumbs.vue +35 -0
  72. package/edge/components/shad/button.vue +43 -0
  73. package/edge/components/shad/checkbox.vue +73 -0
  74. package/edge/components/shad/combobox.vue +238 -0
  75. package/edge/components/shad/datepicker.vue +184 -0
  76. package/edge/components/shad/dialog.vue +32 -0
  77. package/edge/components/shad/dropdownMenu.vue +54 -0
  78. package/edge/components/shad/dropdownMenuItem.vue +21 -0
  79. package/edge/components/shad/form.vue +59 -0
  80. package/edge/components/shad/html.vue +877 -0
  81. package/edge/components/shad/input.vue +139 -0
  82. package/edge/components/shad/number.vue +109 -0
  83. package/edge/components/shad/select.vue +151 -0
  84. package/edge/components/shad/selectTags.vue +278 -0
  85. package/edge/components/shad/switch.vue +67 -0
  86. package/edge/components/shad/tags.vue +137 -0
  87. package/edge/components/shad/textarea.vue +102 -0
  88. package/edge/components/shad/typeMoney.vue +167 -0
  89. package/edge/components/sideBar.vue +288 -0
  90. package/edge/components/sideBarContent.vue +268 -0
  91. package/edge/components/sidebarProvider.vue +33 -0
  92. package/edge/components/tooltip.vue +16 -0
  93. package/edge/components/userMenu.vue +148 -0
  94. package/edge/components/v/alert.vue +59 -0
  95. package/edge/components/v/alertTitle.vue +18 -0
  96. package/edge/components/v/card.vue +53 -0
  97. package/edge/components/v/cardActions.vue +18 -0
  98. package/edge/components/v/cardText.vue +18 -0
  99. package/edge/components/v/cardTitle.vue +20 -0
  100. package/edge/components/v/col.vue +56 -0
  101. package/edge/components/v/list.vue +46 -0
  102. package/edge/components/v/listItem.vue +26 -0
  103. package/edge/components/v/listItemTitle.vue +18 -0
  104. package/edge/components/v/row.vue +42 -0
  105. package/edge/components/v/toolbar.vue +24 -0
  106. package/edge/composables/global.ts +519 -0
  107. package/edge-pull.sh +2 -0
  108. package/edge-push.sh +1 -0
  109. package/edge-status.sh +14 -0
  110. package/package.json +1 -1
  111. package/edge-components-install.sh +0 -1
@@ -0,0 +1,466 @@
1
+ <script setup>
2
+ const props = defineProps({
3
+ modelValue: {
4
+ type: [String, Object],
5
+ default: '',
6
+ },
7
+ siteVars: {
8
+ type: Array,
9
+ default: () => [],
10
+ },
11
+ globals: {
12
+ type: Array,
13
+ default: () => [],
14
+ },
15
+ siteImages: {
16
+ type: Array,
17
+ default: () => [],
18
+ },
19
+ siteBlocks: {
20
+ type: Array,
21
+ default: () => [],
22
+ },
23
+ assets: {
24
+ type: Array,
25
+ default: () => [],
26
+ },
27
+ blocks: {
28
+ type: Array,
29
+ default: () => [],
30
+ },
31
+ images: {
32
+ type: Array,
33
+ default: () => [],
34
+ },
35
+ fields: {
36
+ type: Array,
37
+ default: () => [],
38
+ },
39
+ height: {
40
+ type: String,
41
+ default: 'calc(100vh - 400px)',
42
+ },
43
+ chatgpt: {
44
+ type: Boolean,
45
+ default: false,
46
+ },
47
+ language: {
48
+ type: String,
49
+ default: 'json',
50
+ },
51
+ title: {
52
+ type: String,
53
+ default: '',
54
+ },
55
+ error: {
56
+ type: String,
57
+ default: '',
58
+ },
59
+ })
60
+
61
+ const emit = defineEmits(['update:modelValue', 'lineClick'])
62
+ const localModelValue = ref(null)
63
+ const edgeFirebase = inject('edgeFirebase')
64
+ const expectsJsonObject = ref(false)
65
+
66
+ const editorOptions = {
67
+ mode: 'htmlmixed',
68
+ lineNumbers: true,
69
+ theme: 'default',
70
+ }
71
+ const state = reactive({
72
+ content: '',
73
+ afterMount: false,
74
+ insertDialog: false,
75
+ tab: 'globals',
76
+ selectionRange: null,
77
+ gpt: '',
78
+ editHistory: [],
79
+ currentHistory: 0,
80
+ gptLoading: false,
81
+ gptMenu: false,
82
+ undoredo: false,
83
+ gptHTML: '',
84
+ diffDialog: false,
85
+ chatGPT: false,
86
+ })
87
+
88
+ onMounted(() => {
89
+ nextTick(() => {
90
+ state.afterMount = true
91
+ })
92
+ })
93
+
94
+ const toEditorValue = (value) => {
95
+ if (props.language === 'json') {
96
+ if (value === null || value === undefined)
97
+ return ''
98
+ if (typeof value === 'object') {
99
+ try {
100
+ return JSON.stringify(value, null, 2)
101
+ }
102
+ catch (err) {
103
+ console.warn('Unable to stringify JSON object for editor', err)
104
+ return ''
105
+ }
106
+ }
107
+ if (typeof value === 'string') {
108
+ try {
109
+ return JSON.stringify(JSON.parse(value), null, 2)
110
+ }
111
+ catch {
112
+ return value
113
+ }
114
+ }
115
+ }
116
+ return value ?? ''
117
+ }
118
+
119
+ const toEmittedValue = (value) => {
120
+ if (props.language === 'json' && expectsJsonObject.value) {
121
+ try {
122
+ return value ? JSON.parse(value) : {}
123
+ }
124
+ catch (err) {
125
+ console.warn('Invalid JSON; emitting raw string instead of object')
126
+ return value
127
+ }
128
+ }
129
+ return value
130
+ }
131
+
132
+ watch(() => props.modelValue, (newValue) => {
133
+ if (state.afterMount) {
134
+ expectsJsonObject.value = props.language === 'json' && newValue !== null && typeof newValue === 'object'
135
+ localModelValue.value = toEditorValue(newValue)
136
+ }
137
+ })
138
+
139
+ watch(localModelValue, () => {
140
+ if (state.afterMount) {
141
+ emit('update:modelValue', toEmittedValue(localModelValue.value))
142
+ if (!state.undoredo) {
143
+ state.editHistory.push(localModelValue.value)
144
+ state.currentHistory = state.editHistory.length - 1
145
+ }
146
+ state.undoredo = false
147
+ }
148
+ }, { deep: true })
149
+
150
+ const undo = () => {
151
+ if (state.currentHistory > 0) {
152
+ state.undoredo = true
153
+ state.currentHistory--
154
+ localModelValue.value = state.editHistory[state.currentHistory]
155
+ }
156
+ }
157
+
158
+ const redo = () => {
159
+ console.log(state.editHistory)
160
+ if (state.currentHistory <= state.editHistory.length - 1) {
161
+ state.undoredo = true
162
+ state.currentHistory++
163
+ localModelValue.value = state.editHistory[state.currentHistory]
164
+ }
165
+ }
166
+
167
+ const editorCompRef = ref(null)
168
+ const editorInstanceRef = shallowRef(null)
169
+
170
+ const setCursor = () => {
171
+ const editor = editorInstanceRef.value
172
+ if (editor) {
173
+ const cm = editor
174
+ state.cursorPosition = cm.getPosition()
175
+ state.selectionRange = cm.getSelections?.() || [cm.getSelection()]
176
+ }
177
+ }
178
+
179
+ const initValue = ref()
180
+
181
+ onBeforeMount(() => {
182
+ expectsJsonObject.value = props.language === 'json' && props.modelValue !== null && typeof props.modelValue === 'object'
183
+ localModelValue.value = toEditorValue(edgeGlobal.dupObject(props.modelValue))
184
+ initValue.value = localModelValue.value
185
+ if (localModelValue.value) {
186
+ state.editHistory.push(localModelValue.value)
187
+ state.currentHistory = 0
188
+ }
189
+ })
190
+
191
+ const runChatGpt = async () => {
192
+ state.gptMenu = false
193
+ state.gptLoading = true
194
+
195
+ if (localModelValue.value !== state.editHistory[state.editHistory.length - 1]) {
196
+ state.editHistory.push(localModelValue.value)
197
+ }
198
+
199
+ const variables = {
200
+ globals: props.globals.map(global => `{{global_block_${global.name}}}`),
201
+ siteImages: props.siteImages.map(image => `{{site_image_${image.name}}}`),
202
+ siteBlocks: props.siteBlocks.map(block => `{{site_block_${block.name}}}`),
203
+ blocks: props.blocks.map(block => `{{block_${block.name}}}`),
204
+ images: props.images.map(image => `{{image_${image.name}}}`),
205
+ }
206
+
207
+ console.log(JSON.stringify(variables))
208
+
209
+ const results = await edgeFirebase.runFunction('landings-chatGpt', { prompt: state.gpt, currentFile: localModelValue.value, variables: JSON.stringify(variables) })
210
+ // localModelValue.value = results.data.html
211
+ if (localModelValue.value.length === 0) {
212
+ localModelValue.value = results.data.html
213
+ }
214
+ else {
215
+ state.gptHTML = results.data.html
216
+ state.diffDialog = true
217
+ }
218
+
219
+ state.editHistory.push(localModelValue.value)
220
+ state.currentHistory = state.editHistory.length - 1
221
+
222
+ state.gpt = ''
223
+ state.gptLoading = false
224
+ }
225
+
226
+ const handleMount = (editor) => {
227
+ editorInstanceRef.value = editor
228
+ editorInstanceRef.value?.getAction('editor.action.formatDocument').run()
229
+ editor.onMouseDown((event) => {
230
+ const position = event?.target?.position
231
+ const model = editor.getModel?.()
232
+ if (!position || !model)
233
+ return
234
+ const lineContent = model.getLineContent(position.lineNumber)
235
+ const offset = model.getOffsetAt(position)
236
+ emit('lineClick', {
237
+ lineNumber: position.lineNumber,
238
+ column: position.column,
239
+ lineContent,
240
+ offset,
241
+ })
242
+ })
243
+ }
244
+
245
+ const formatCode = () => {
246
+ const editorInstance = editorInstanceRef.value
247
+ if (!editorInstance)
248
+ return console.error('Editor instance not found')
249
+
250
+ const model = editorInstance.getModel()
251
+ if (!model)
252
+ return console.error('Editor model not found')
253
+
254
+ const value = model.getValue()
255
+
256
+ if (props.language === 'json') {
257
+ try {
258
+ const parsed = JSON.parse(value)
259
+ const pretty = JSON.stringify(parsed, null, 2)
260
+ model.setValue(pretty)
261
+ }
262
+ catch (e) {
263
+ console.warn('Invalid JSON — falling back to Monaco formatter')
264
+ editorInstance.getAction('editor.action.formatDocument')?.run()
265
+ }
266
+ }
267
+ else {
268
+ editorInstance.getAction('editor.action.formatDocument')?.run()
269
+ }
270
+ }
271
+
272
+ const insertBlock = (text) => {
273
+ if (!text && text !== '')
274
+ return
275
+ const editor = editorInstanceRef.value
276
+ if (!editor)
277
+ return console.error('Editor instance not ready')
278
+
279
+ let range = editor.getSelection()
280
+
281
+ if (!range) {
282
+ const position = editor.getPosition()
283
+ if (!position)
284
+ return console.error('No active selection or cursor position')
285
+ range = {
286
+ startLineNumber: position.lineNumber,
287
+ startColumn: position.column,
288
+ endLineNumber: position.lineNumber,
289
+ endColumn: position.column,
290
+ }
291
+ }
292
+
293
+ const op = { range, text, forceMoveMarkers: true }
294
+ editor.executeEdits('insert-block', [op])
295
+ editor.focus()
296
+ state.insertDialog = false
297
+ }
298
+
299
+ defineExpose({
300
+ insertSnippet: insertBlock,
301
+ })
302
+
303
+ const diffEditorRef = shallowRef()
304
+ const handleMountDiff = (editor) => {
305
+ diffEditorRef.value = editor
306
+ }
307
+ const getChanges = () => {
308
+ if (diffEditorRef.value) {
309
+ const modifiedEditor = diffEditorRef.value.getModifiedEditor()
310
+ const modifiedContent = modifiedEditor.getValue()
311
+ localModelValue.value = modifiedContent
312
+ initValue.value = modifiedContent
313
+ state.diffDialog = false
314
+ formatCode()
315
+ }
316
+ }
317
+ </script>
318
+
319
+ <template>
320
+ <Card class="border-0 px-0 shadow-none">
321
+ <edge-menu class="border-0 shadow-none py-2 px-0">
322
+ <template #start>
323
+ <Popover v-if="props.chatgpt">
324
+ <PopoverTrigger as-child>
325
+ <edge-shad-button
326
+ size="icon"
327
+ class="bg-slate-400 w-8 h-8"
328
+ >
329
+ <Bot class="w-5 h-5" />
330
+ </edge-shad-button>
331
+ </PopoverTrigger>
332
+ <PopoverContent class="w-[400px]">
333
+ <Card class="border-0 p-0 w-full">
334
+ <CardHeader class="p-2">
335
+ <CardTitle>
336
+ ChatGPT
337
+ </CardTitle>
338
+ </CardHeader>
339
+ <CardContent class="p-1">
340
+ <edge-logging-in v-if="state.gptLoading" />
341
+ <edge-shad-textarea
342
+ v-else
343
+ v-model="state.gpt"
344
+ label="Instructions"
345
+ name="gpt"
346
+ @keydown.enter.stop="runChatGpt"
347
+ />
348
+ </CardContent>
349
+ <CardFooter class="p-2 flex justify-end">
350
+ <edge-shad-button
351
+ color="primary"
352
+ class="bg-slate-400"
353
+ @click="runChatGpt"
354
+ >
355
+ Submit
356
+ </edge-shad-button>
357
+ </CardFooter>
358
+ </Card>
359
+ </PopoverContent>
360
+ </Popover>
361
+ <span>
362
+ {{ props.title }}
363
+ </span>
364
+ </template>
365
+ <template #center>
366
+ <div class="w-full px-2">
367
+ <Alert v-if="props.error" variant="destructive" class="rounded-[6px] py-1">
368
+ <TriangleAlert class="h-4 w-4" />
369
+ <AlertTitle>Error</AlertTitle>
370
+ <AlertDescription>
371
+ {{ props.error }}
372
+ </AlertDescription>
373
+ </Alert>
374
+ </div>
375
+ </template>
376
+ <template #end>
377
+ <edge-tooltip>
378
+ <edge-shad-button
379
+ size="icon"
380
+ class="bg-slate-400 w-8 h-8"
381
+ @click.prevent.stop="formatCode"
382
+ >
383
+ <AlignHorizontalJustifyStart class="w-4 h-4" />
384
+ </edge-shad-button>
385
+ <template #content>
386
+ Format Code
387
+ </template>
388
+ </edge-tooltip>
389
+ <insert-menu v-if="props.siteVars && props.siteVars.length" :items="props.siteVars" var-prefix="siteVar" insert-type="vars" @value-sent="insertBlock">
390
+ <Code class="w-4 h-4" /> Site Variables
391
+ </insert-menu>
392
+ <insert-menu v-if="props.globals && props.globals.length" :items="props.globals" var-prefix="globalVar" insert-type="vars" @value-sent="insertBlock">
393
+ <Globe class="w-4 h-4" /> Globals
394
+ </insert-menu>
395
+ </template>
396
+ </edge-menu>
397
+ <CardContent class="px-0">
398
+ <edge-shad-dialog
399
+ v-model="state.diffDialog"
400
+ >
401
+ <DialogContent class="w-screen h-screen max-h-screen max-w-screen">
402
+ <DialogHeader>
403
+ <DialogTitle>
404
+ Verify ChatGPT Changes
405
+ </DialogTitle>
406
+ <DialogDescription>
407
+ <edge-shad-button
408
+ variant="destructive"
409
+ class="mr-2 h-6"
410
+ @click="state.diffDialog = false"
411
+ >
412
+ Discard Changes
413
+ </edge-shad-button>
414
+ <edge-shad-button
415
+ class="h-6 bg-slate-800"
416
+ @click="getChanges"
417
+ >
418
+ Accept Changes
419
+ </edge-shad-button>
420
+ </DialogDescription>
421
+ </DialogHeader>
422
+
423
+ <vue-monaco-diff-editor
424
+ v-if="state.diffDialog"
425
+ ref="diffEditorRef"
426
+ :theme="edgeGlobal.isDarkMode() ? 'vs-dark' : 'vs'"
427
+ :original="localModelValue"
428
+ :modified="state.gptHTML"
429
+ :language="props.language"
430
+ :options="{
431
+ automaticLayout: true,
432
+ formatOnType: true,
433
+ formatOnPaste: true,
434
+ }"
435
+ style="height: calc(100vh - 120px)"
436
+ @mount="handleMountDiff"
437
+ />
438
+ </DialogContent>
439
+ </edge-shad-dialog>
440
+ <vue-monaco-editor
441
+ v-if="state.afterMount && state.diffDialog === false"
442
+ ref="editorCompRef"
443
+ v-model:value="localModelValue"
444
+ :theme="edgeGlobal.isDarkMode() ? 'vs-dark' : 'vs'"
445
+ :style="{ height: props.height }"
446
+ :language="props.language"
447
+ :options="{
448
+ automaticLayout: true,
449
+ formatOnType: true,
450
+ formatOnPaste: true,
451
+ }"
452
+ @mount="handleMount"
453
+ />
454
+ </CardContent>
455
+ </Card>
456
+ </template>
457
+
458
+ <style lang="scss" scoped>
459
+ /* Add this in your component's style section or in a global CSS file */
460
+ .codemirror-large-font {
461
+ font-size: 15px !important; /* Adjust the font size as needed */
462
+ }
463
+ .inverted-logo {
464
+ filter: invert(1);
465
+ }
466
+ </style>