@edgedev/create-edge-app 1.1.26 → 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.
@@ -42,7 +42,12 @@ const state = reactive({
42
42
  name: { bindings: { 'field-type': 'text', 'label': 'Name' }, cols: '12', value: '' },
43
43
  theme: { bindings: { 'field-type': 'collection', 'label': 'Themes', 'collection-path': 'themes' }, cols: '12', value: '' },
44
44
  allowedThemes: { bindings: { 'field-type': 'tags', 'label': 'Allowed Themes' }, cols: '12', value: [] },
45
- logo: { bindings: { 'field-type': 'text', 'label': 'Logo' }, cols: '12', value: '' },
45
+ logo: { bindings: { 'field-type': 'text', 'label': 'Dark logo' }, cols: '12', value: '' },
46
+ logoLight: { bindings: { 'field-type': 'text', 'label': 'Logo Light' }, cols: '12', value: '' },
47
+ logoText: { bindings: { 'field-type': 'text', 'label': 'Logo Text' }, cols: '12', value: '' },
48
+ logoType: { bindings: { 'field-type': 'select', 'label': 'Logo Type', 'items': ['image', 'text'] }, cols: '12', value: 'image' },
49
+ brandLogoDark: { bindings: { 'field-type': 'text', 'label': 'Brand Logo Dark' }, cols: '12', value: '' },
50
+ brandLogoLight: { bindings: { 'field-type': 'text', 'label': 'Brand Logo Light' }, cols: '12', value: '' },
46
51
  favicon: { bindings: { 'field-type': 'text', 'label': 'Favicon' }, cols: '12', value: '' },
47
52
  menuPosition: { bindings: { 'field-type': 'select', 'label': 'Menu Position', 'items': ['left', 'center', 'right'] }, cols: '12', value: 'right' },
48
53
  domains: { bindings: { 'field-type': 'tags', 'label': 'Domains', 'helper': 'Add or remove domains' }, cols: '12', value: [] },
@@ -63,6 +68,9 @@ const state = reactive({
63
68
  hasError: false,
64
69
  updating: false,
65
70
  logoPickerOpen: false,
71
+ logoLightPickerOpen: false,
72
+ brandLogoDarkPickerOpen: false,
73
+ brandLogoLightPickerOpen: false,
66
74
  faviconPickerOpen: false,
67
75
  aiSectionOpen: false,
68
76
  selectedPostId: '',
@@ -92,6 +100,11 @@ const schemas = {
92
100
  }).min(1, { message: 'Theme is required' }),
93
101
  allowedThemes: z.array(z.string()).optional(),
94
102
  logo: z.string().optional(),
103
+ logoLight: z.string().optional(),
104
+ logoText: z.string().optional(),
105
+ logoType: z.enum(['image', 'text']).optional(),
106
+ brandLogoDark: z.string().optional(),
107
+ brandLogoLight: z.string().optional(),
95
108
  favicon: z.string().optional(),
96
109
  menuPosition: z.enum(['left', 'center', 'right']).optional(),
97
110
  metaTitle: z.string().optional(),
@@ -443,6 +456,11 @@ const isSiteDiff = computed(() => {
443
456
  theme: publishedSite.theme,
444
457
  allowedThemes: publishedSite.allowedThemes,
445
458
  logo: publishedSite.logo,
459
+ logoLight: publishedSite.logoLight,
460
+ logoText: publishedSite.logoText,
461
+ logoType: publishedSite.logoType,
462
+ brandLogoDark: publishedSite.brandLogoDark,
463
+ brandLogoLight: publishedSite.brandLogoLight,
446
464
  favicon: publishedSite.favicon,
447
465
  menuPosition: publishedSite.menuPosition,
448
466
  contactEmail: publishedSite.contactEmail,
@@ -455,6 +473,11 @@ const isSiteDiff = computed(() => {
455
473
  theme: siteData.value.theme,
456
474
  allowedThemes: siteData.value.allowedThemes,
457
475
  logo: siteData.value.logo,
476
+ logoLight: siteData.value.logoLight,
477
+ logoText: siteData.value.logoText,
478
+ logoType: siteData.value.logoType,
479
+ brandLogoDark: siteData.value.brandLogoDark,
480
+ brandLogoLight: siteData.value.brandLogoLight,
458
481
  favicon: siteData.value.favicon,
459
482
  menuPosition: siteData.value.menuPosition,
460
483
  contactEmail: siteData.value.contactEmail,
@@ -481,6 +504,11 @@ const discardSiteSettings = async () => {
481
504
  theme: publishedSite.theme || '',
482
505
  allowedThemes: publishedSite.allowedThemes || [],
483
506
  logo: publishedSite.logo || '',
507
+ logoLight: publishedSite.logoLight || '',
508
+ logoText: publishedSite.logoText || '',
509
+ logoType: publishedSite.logoType || 'image',
510
+ brandLogoDark: publishedSite.brandLogoDark || '',
511
+ brandLogoLight: publishedSite.brandLogoLight || '',
484
512
  favicon: publishedSite.favicon || '',
485
513
  menuPosition: publishedSite.menuPosition || '',
486
514
  contactEmail: publishedSite.contactEmail || '',
@@ -637,6 +665,12 @@ watch(pages, (pagesCollection) => {
637
665
  watch(() => state.siteSettings, (open) => {
638
666
  if (!open)
639
667
  state.logoPickerOpen = false
668
+ if (!open)
669
+ state.logoLightPickerOpen = false
670
+ if (!open)
671
+ state.brandLogoDarkPickerOpen = false
672
+ if (!open)
673
+ state.brandLogoLightPickerOpen = false
640
674
  if (!open)
641
675
  state.faviconPickerOpen = false
642
676
  })
@@ -1099,176 +1133,319 @@ const pageSettingsUpdated = async (pageData) => {
1099
1133
  @error="formErrors"
1100
1134
  >
1101
1135
  <template #main="slotProps">
1102
- <div class="p-6 space-y-4 h-[calc(100vh-140px)] overflow-y-auto">
1103
- <edge-shad-input
1104
- v-model="slotProps.workingDoc.name"
1105
- name="name"
1106
- label="Name"
1107
- placeholder="Enter name"
1108
- class="w-full"
1109
- />
1110
- <edge-shad-tags
1111
- v-model="slotProps.workingDoc.domains"
1112
- name="domains"
1113
- label="Domains"
1114
- placeholder="Add or remove domains"
1115
- class="w-full"
1116
- />
1117
- <edge-shad-input
1118
- v-model="slotProps.workingDoc.contactEmail"
1119
- name="contactEmail"
1120
- label="Contact Email"
1121
- placeholder="name@example.com"
1122
- class="w-full"
1123
- />
1124
- <edge-shad-select-tags
1125
- v-if="isAdmin"
1126
- :model-value="Array.isArray(slotProps.workingDoc.allowedThemes) ? slotProps.workingDoc.allowedThemes : []"
1127
- name="allowedThemes"
1128
- label="Allowed Themes"
1129
- placeholder="Select allowed themes"
1130
- class="w-full"
1131
- :items="themeOptions"
1132
- item-title="label"
1133
- item-value="value"
1134
- @update:model-value="(value) => {
1135
- const normalized = Array.isArray(value) ? value : []
1136
- slotProps.workingDoc.allowedThemes = normalized
1137
- if (normalized.length && !normalized.includes(slotProps.workingDoc.theme)) {
1138
- slotProps.workingDoc.theme = normalized[0] || ''
1139
- }
1140
- }"
1141
- />
1142
- <edge-shad-select
1143
- :model-value="slotProps.workingDoc.theme || ''"
1144
- name="theme"
1145
- label="Theme"
1146
- placeholder="Select a theme"
1147
- class="w-full"
1148
- :items="themeItemsForAllowed(slotProps.workingDoc.allowedThemes, slotProps.workingDoc.theme)"
1149
- item-title="label"
1150
- item-value="value"
1151
- @update:model-value="value => (slotProps.workingDoc.theme = value || '')"
1152
- />
1153
- <div class="space-y-2">
1154
- <label class="text-sm font-medium text-foreground flex items-center justify-between">
1155
- Logo
1156
- <edge-shad-button
1157
- type="button"
1158
- variant="link"
1159
- class="px-0 h-auto text-sm"
1160
- @click="state.logoPickerOpen = !state.logoPickerOpen"
1161
- >
1162
- {{ state.logoPickerOpen ? 'Hide picker' : 'Select logo' }}
1163
- </edge-shad-button>
1164
- </label>
1165
- <div class="flex items-center gap-4">
1166
- <div v-if="slotProps.workingDoc.logo" class="flex items-center gap-3">
1167
- <img :src="slotProps.workingDoc.logo" alt="Logo preview" class="h-16 w-auto rounded-md border border-border bg-muted object-contain">
1168
- <edge-shad-button
1169
- type="button"
1170
- variant="ghost"
1171
- class="h-8"
1172
- @click="slotProps.workingDoc.logo = ''"
1173
- >
1174
- Remove
1175
- </edge-shad-button>
1176
- </div>
1177
- <span v-else class="text-sm text-muted-foreground italic">No logo selected</span>
1178
- </div>
1179
- <div v-if="state.logoPickerOpen" class="mt-2 border border-dashed rounded-lg p-2">
1180
- <edge-cms-media-manager
1181
- :site="props.site"
1182
- :select-mode="true"
1183
- :default-tags="['Logos']"
1184
- @select="(url) => {
1185
- slotProps.workingDoc.logo = url
1186
- state.logoPickerOpen = false
1187
- }"
1136
+ <div class="p-6 h-[calc(100vh-140px)] overflow-y-auto">
1137
+ <Tabs class="w-full" default-value="general">
1138
+ <TabsList class="w-full flex flex-wrap gap-2 bg-muted/40 p-1 rounded-lg">
1139
+ <TabsTrigger value="general" class="text-md uppercase font-medium">
1140
+ General
1141
+ </TabsTrigger>
1142
+ <TabsTrigger value="appearance" class="text-md uppercase font-medium">
1143
+ Appearance
1144
+ </TabsTrigger>
1145
+ <TabsTrigger value="branding" class="text-md uppercase font-medium">
1146
+ Branding
1147
+ </TabsTrigger>
1148
+ <TabsTrigger value="seo" class="text-md uppercase font-medium">
1149
+ SEO
1150
+ </TabsTrigger>
1151
+ </TabsList>
1152
+ <TabsContent value="general" class="pt-4 space-y-4">
1153
+ <edge-shad-input
1154
+ v-model="slotProps.workingDoc.name"
1155
+ name="name"
1156
+ label="Name"
1157
+ placeholder="Enter name"
1158
+ class="w-full"
1188
1159
  />
1189
- </div>
1190
- </div>
1191
- <div class="space-y-2">
1192
- <label class="text-sm font-medium text-foreground flex items-center justify-between">
1193
- Favicon
1194
- <edge-shad-button
1195
- type="button"
1196
- variant="link"
1197
- class="px-0 h-auto text-sm"
1198
- @click="state.faviconPickerOpen = !state.faviconPickerOpen"
1199
- >
1200
- {{ state.faviconPickerOpen ? 'Hide picker' : 'Select favicon' }}
1201
- </edge-shad-button>
1202
- </label>
1203
- <div class="flex items-center gap-4">
1204
- <div v-if="slotProps.workingDoc.favicon" class="flex items-center gap-3">
1205
- <img :src="slotProps.workingDoc.favicon" alt="Favicon preview" class="h-12 w-12 rounded-md border border-border bg-muted object-contain">
1206
- <edge-shad-button
1207
- type="button"
1208
- variant="ghost"
1209
- class="h-8"
1210
- @click="slotProps.workingDoc.favicon = ''"
1211
- >
1212
- Remove
1213
- </edge-shad-button>
1214
- </div>
1215
- <span v-else class="text-sm text-muted-foreground italic">No favicon selected</span>
1216
- </div>
1217
- <div v-if="state.faviconPickerOpen" class="mt-2 border border-dashed rounded-lg p-2">
1218
- <edge-cms-media-manager
1219
- :site="props.site"
1220
- :select-mode="true"
1221
- :default-tags="['Logos']"
1222
- @select="(url) => {
1223
- slotProps.workingDoc.favicon = url
1224
- state.faviconPickerOpen = false
1225
- }"
1160
+ <edge-shad-tags
1161
+ v-model="slotProps.workingDoc.domains"
1162
+ name="domains"
1163
+ label="Domains"
1164
+ placeholder="Add or remove domains"
1165
+ class="w-full"
1226
1166
  />
1227
- </div>
1228
- </div>
1229
- <edge-shad-select
1230
- :model-value="slotProps.workingDoc.menuPosition || ''"
1231
- name="menuPosition"
1232
- label="Menu Position"
1233
- placeholder="Select menu position"
1234
- class="w-full"
1235
- :items="menuPositionOptions"
1236
- item-title="label"
1237
- item-value="value"
1238
- @update:model-value="value => (slotProps.workingDoc.menuPosition = value || '')"
1239
- />
1240
- <edge-shad-select-tags
1241
- v-if="Object.keys(orgUsers).length > 0 && isAdmin"
1242
- v-model="slotProps.workingDoc.users" :disabled="!edgeGlobal.isAdminGlobal(edgeFirebase).value"
1243
- :items="Object.values(orgUsers)" name="users" label="Users"
1244
- item-title="meta.name" item-value="userId" placeholder="Select users" class="w-full" :multiple="true"
1245
- />
1246
- <Card>
1247
- <CardHeader>
1248
- <CardTitle>SEO</CardTitle>
1249
- <CardDescription>Default settings if the information is not entered on the page.</CardDescription>
1250
- </CardHeader>
1251
- <CardContent class="pt-0">
1252
1167
  <edge-shad-input
1253
- v-model="slotProps.workingDoc.metaTitle"
1254
- label="Meta Title"
1255
- name="metaTitle"
1168
+ v-model="slotProps.workingDoc.contactEmail"
1169
+ name="contactEmail"
1170
+ label="Contact Email"
1171
+ placeholder="name@example.com"
1172
+ class="w-full"
1173
+ />
1174
+ <edge-shad-select-tags
1175
+ v-if="Object.keys(orgUsers).length > 0 && isAdmin"
1176
+ v-model="slotProps.workingDoc.users" :disabled="!edgeGlobal.isAdminGlobal(edgeFirebase).value"
1177
+ :items="userOptions" name="users" label="Users"
1178
+ item-title="label" item-value="value" placeholder="Select users" class="w-full" :multiple="true"
1179
+ />
1180
+ <p v-else class="text-sm text-muted-foreground">
1181
+ No organization users available for this site.
1182
+ </p>
1183
+ </TabsContent>
1184
+ <TabsContent value="appearance" class="pt-4 space-y-4">
1185
+ <edge-shad-select-tags
1186
+ v-if="isAdmin"
1187
+ :model-value="Array.isArray(slotProps.workingDoc.allowedThemes) ? slotProps.workingDoc.allowedThemes : []"
1188
+ name="allowedThemes"
1189
+ label="Allowed Themes"
1190
+ placeholder="Select allowed themes"
1191
+ class="w-full"
1192
+ :items="themeOptions"
1193
+ item-title="label"
1194
+ item-value="value"
1195
+ @update:model-value="(value) => {
1196
+ const normalized = Array.isArray(value) ? value : []
1197
+ slotProps.workingDoc.allowedThemes = normalized
1198
+ if (normalized.length && !normalized.includes(slotProps.workingDoc.theme)) {
1199
+ slotProps.workingDoc.theme = normalized[0] || ''
1200
+ }
1201
+ }"
1256
1202
  />
1257
- <edge-shad-textarea
1258
- v-model="slotProps.workingDoc.metaDescription"
1259
- label="Meta Description"
1260
- name="metaDescription"
1203
+ <edge-shad-select
1204
+ :model-value="slotProps.workingDoc.theme || ''"
1205
+ name="theme"
1206
+ label="Theme"
1207
+ placeholder="Select a theme"
1208
+ class="w-full"
1209
+ :items="themeItemsForAllowed(slotProps.workingDoc.allowedThemes, slotProps.workingDoc.theme)"
1210
+ item-title="label"
1211
+ item-value="value"
1212
+ @update:model-value="value => (slotProps.workingDoc.theme = value || '')"
1261
1213
  />
1262
- <edge-cms-code-editor
1263
- v-model="slotProps.workingDoc.structuredData"
1264
- title="Structured Data (JSON-LD)"
1265
- language="json"
1266
- name="structuredData"
1267
- height="300px"
1268
- class="mb-4 w-full"
1214
+ <edge-shad-select
1215
+ :model-value="slotProps.workingDoc.menuPosition || ''"
1216
+ name="menuPosition"
1217
+ label="Menu Position"
1218
+ placeholder="Select menu position"
1219
+ class="w-full"
1220
+ :items="menuPositionOptions"
1221
+ item-title="label"
1222
+ item-value="value"
1223
+ @update:model-value="value => (slotProps.workingDoc.menuPosition = value || '')"
1269
1224
  />
1270
- </CardContent>
1271
- </Card>
1225
+ </TabsContent>
1226
+ <TabsContent value="branding" class="pt-4 space-y-4">
1227
+ <div class="space-y-2">
1228
+ <label class="text-sm font-medium text-foreground flex items-center justify-between">
1229
+ Dark logo
1230
+ <edge-shad-button
1231
+ type="button"
1232
+ variant="link"
1233
+ class="px-0 h-auto text-sm"
1234
+ @click="state.logoPickerOpen = !state.logoPickerOpen"
1235
+ >
1236
+ {{ state.logoPickerOpen ? 'Hide picker' : 'Select logo' }}
1237
+ </edge-shad-button>
1238
+ </label>
1239
+ <div class="flex items-center gap-4">
1240
+ <div v-if="slotProps.workingDoc.logo" class="flex items-center gap-3">
1241
+ <img :src="slotProps.workingDoc.logo" alt="Logo preview" class="h-16 w-auto rounded-md border border-border bg-muted object-contain">
1242
+ <edge-shad-button
1243
+ type="button"
1244
+ variant="ghost"
1245
+ class="h-8"
1246
+ @click="slotProps.workingDoc.logo = ''"
1247
+ >
1248
+ Remove
1249
+ </edge-shad-button>
1250
+ </div>
1251
+ <span v-else class="text-sm text-muted-foreground italic">No logo selected</span>
1252
+ </div>
1253
+ <div v-if="state.logoPickerOpen" class="mt-2 border border-dashed rounded-lg p-2">
1254
+ <edge-cms-media-manager
1255
+ :site="props.site"
1256
+ :select-mode="true"
1257
+ :default-tags="['Logos']"
1258
+ @select="(url) => {
1259
+ slotProps.workingDoc.logo = url
1260
+ state.logoPickerOpen = false
1261
+ }"
1262
+ />
1263
+ </div>
1264
+ </div>
1265
+ <div class="space-y-2">
1266
+ <label class="text-sm font-medium text-foreground flex items-center justify-between">
1267
+ Light logo
1268
+ <edge-shad-button
1269
+ type="button"
1270
+ variant="link"
1271
+ class="px-0 h-auto text-sm"
1272
+ @click="state.logoLightPickerOpen = !state.logoLightPickerOpen"
1273
+ >
1274
+ {{ state.logoLightPickerOpen ? 'Hide picker' : 'Select logo' }}
1275
+ </edge-shad-button>
1276
+ </label>
1277
+ <div class="flex items-center gap-4">
1278
+ <div v-if="slotProps.workingDoc.logoLight" class="flex items-center gap-3">
1279
+ <img :src="slotProps.workingDoc.logoLight" alt="Light logo preview" class="h-16 w-auto rounded-md border border-border bg-muted object-contain">
1280
+ <edge-shad-button
1281
+ type="button"
1282
+ variant="ghost"
1283
+ class="h-8"
1284
+ @click="slotProps.workingDoc.logoLight = ''"
1285
+ >
1286
+ Remove
1287
+ </edge-shad-button>
1288
+ </div>
1289
+ <span v-else class="text-sm text-muted-foreground italic">No light logo selected</span>
1290
+ </div>
1291
+ <div v-if="state.logoLightPickerOpen" class="mt-2 border border-dashed rounded-lg p-2">
1292
+ <edge-cms-media-manager
1293
+ :site="props.site"
1294
+ :select-mode="true"
1295
+ :default-tags="['Logos']"
1296
+ @select="(url) => {
1297
+ slotProps.workingDoc.logoLight = url
1298
+ state.logoLightPickerOpen = false
1299
+ }"
1300
+ />
1301
+ </div>
1302
+ </div>
1303
+ <div v-if="isAdmin" class="space-y-4 border border-dashed rounded-lg p-4">
1304
+ <div class="text-sm font-semibold text-foreground">
1305
+ Umbrella Brand
1306
+ </div>
1307
+ <div class="space-y-2">
1308
+ <label class="text-sm font-medium text-foreground flex items-center justify-between">
1309
+ Dark brand logo
1310
+ <edge-shad-button
1311
+ type="button"
1312
+ variant="link"
1313
+ class="px-0 h-auto text-sm"
1314
+ @click="state.brandLogoDarkPickerOpen = !state.brandLogoDarkPickerOpen"
1315
+ >
1316
+ {{ state.brandLogoDarkPickerOpen ? 'Hide picker' : 'Select logo' }}
1317
+ </edge-shad-button>
1318
+ </label>
1319
+ <div class="flex items-center gap-4">
1320
+ <div v-if="slotProps.workingDoc.brandLogoDark" class="flex items-center gap-3">
1321
+ <img :src="slotProps.workingDoc.brandLogoDark" alt="Brand dark logo preview" class="h-16 w-auto rounded-md border border-border bg-muted object-contain">
1322
+ <edge-shad-button
1323
+ type="button"
1324
+ variant="ghost"
1325
+ class="h-8"
1326
+ @click="slotProps.workingDoc.brandLogoDark = ''"
1327
+ >
1328
+ Remove
1329
+ </edge-shad-button>
1330
+ </div>
1331
+ <span v-else class="text-sm text-muted-foreground italic">No brand dark logo selected</span>
1332
+ </div>
1333
+ <div v-if="state.brandLogoDarkPickerOpen" class="mt-2 border border-dashed rounded-lg p-2">
1334
+ <edge-cms-media-manager
1335
+ :site="props.site"
1336
+ :select-mode="true"
1337
+ :default-tags="['Logos']"
1338
+ @select="(url) => {
1339
+ slotProps.workingDoc.brandLogoDark = url
1340
+ state.brandLogoDarkPickerOpen = false
1341
+ }"
1342
+ />
1343
+ </div>
1344
+ </div>
1345
+ <div class="space-y-2">
1346
+ <label class="text-sm font-medium text-foreground flex items-center justify-between">
1347
+ Light brand logo
1348
+ <edge-shad-button
1349
+ type="button"
1350
+ variant="link"
1351
+ class="px-0 h-auto text-sm"
1352
+ @click="state.brandLogoLightPickerOpen = !state.brandLogoLightPickerOpen"
1353
+ >
1354
+ {{ state.brandLogoLightPickerOpen ? 'Hide picker' : 'Select logo' }}
1355
+ </edge-shad-button>
1356
+ </label>
1357
+ <div class="flex items-center gap-4">
1358
+ <div v-if="slotProps.workingDoc.brandLogoLight" class="flex items-center gap-3">
1359
+ <img :src="slotProps.workingDoc.brandLogoLight" alt="Brand light logo preview" class="h-16 w-auto rounded-md border border-border bg-muted object-contain">
1360
+ <edge-shad-button
1361
+ type="button"
1362
+ variant="ghost"
1363
+ class="h-8"
1364
+ @click="slotProps.workingDoc.brandLogoLight = ''"
1365
+ >
1366
+ Remove
1367
+ </edge-shad-button>
1368
+ </div>
1369
+ <span v-else class="text-sm text-muted-foreground italic">No brand light logo selected</span>
1370
+ </div>
1371
+ <div v-if="state.brandLogoLightPickerOpen" class="mt-2 border border-dashed rounded-lg p-2">
1372
+ <edge-cms-media-manager
1373
+ :site="props.site"
1374
+ :select-mode="true"
1375
+ :default-tags="['Logos']"
1376
+ @select="(url) => {
1377
+ slotProps.workingDoc.brandLogoLight = url
1378
+ state.brandLogoLightPickerOpen = false
1379
+ }"
1380
+ />
1381
+ </div>
1382
+ </div>
1383
+ </div>
1384
+ <div class="space-y-2">
1385
+ <label class="text-sm font-medium text-foreground flex items-center justify-between">
1386
+ Favicon
1387
+ <edge-shad-button
1388
+ type="button"
1389
+ variant="link"
1390
+ class="px-0 h-auto text-sm"
1391
+ @click="state.faviconPickerOpen = !state.faviconPickerOpen"
1392
+ >
1393
+ {{ state.faviconPickerOpen ? 'Hide picker' : 'Select favicon' }}
1394
+ </edge-shad-button>
1395
+ </label>
1396
+ <div class="flex items-center gap-4">
1397
+ <div v-if="slotProps.workingDoc.favicon" class="flex items-center gap-3">
1398
+ <img :src="slotProps.workingDoc.favicon" alt="Favicon preview" class="h-12 w-12 rounded-md border border-border bg-muted object-contain">
1399
+ <edge-shad-button
1400
+ type="button"
1401
+ variant="ghost"
1402
+ class="h-8"
1403
+ @click="slotProps.workingDoc.favicon = ''"
1404
+ >
1405
+ Remove
1406
+ </edge-shad-button>
1407
+ </div>
1408
+ <span v-else class="text-sm text-muted-foreground italic">No favicon selected</span>
1409
+ </div>
1410
+ <div v-if="state.faviconPickerOpen" class="mt-2 border border-dashed rounded-lg p-2">
1411
+ <edge-cms-media-manager
1412
+ :site="props.site"
1413
+ :select-mode="true"
1414
+ :default-tags="['Logos']"
1415
+ @select="(url) => {
1416
+ slotProps.workingDoc.favicon = url
1417
+ state.faviconPickerOpen = false
1418
+ }"
1419
+ />
1420
+ </div>
1421
+ </div>
1422
+ </TabsContent>
1423
+ <TabsContent value="seo" class="pt-4">
1424
+ <div class="space-y-4">
1425
+ <p class="text-sm text-muted-foreground">
1426
+ Default settings if the information is not entered on the page.
1427
+ </p>
1428
+ <edge-shad-input
1429
+ v-model="slotProps.workingDoc.metaTitle"
1430
+ label="Meta Title"
1431
+ name="metaTitle"
1432
+ />
1433
+ <edge-shad-textarea
1434
+ v-model="slotProps.workingDoc.metaDescription"
1435
+ label="Meta Description"
1436
+ name="metaDescription"
1437
+ />
1438
+ <edge-cms-code-editor
1439
+ v-model="slotProps.workingDoc.structuredData"
1440
+ title="Structured Data (JSON-LD)"
1441
+ language="json"
1442
+ name="structuredData"
1443
+ height="300px"
1444
+ class="mb-4 w-full"
1445
+ />
1446
+ </div>
1447
+ </TabsContent>
1448
+ </Tabs>
1272
1449
  </div>
1273
1450
  <SheetFooter class="pt-2 flex justify-between">
1274
1451
  <edge-shad-button variant="destructive" class="text-white" @click="state.siteSettings = false">
@@ -57,7 +57,10 @@ const state = reactive({
57
57
  "navBorder": "",
58
58
  "navActive": "#3B82F6",
59
59
  "navHoverBg": "",
60
- "navActiveBg": ""
60
+ "navActiveBg": "",
61
+ "sideNavBg": "#FFFFFF",
62
+ "sideNavText": "#000000",
63
+ "sideNavActive": "#AFBD23"
61
64
  },
62
65
  "fontFamily": {
63
66
  "sans": ["Overpass", "sans-serif"],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edgedev/create-edge-app",
3
- "version": "1.1.26",
3
+ "version": "1.1.27",
4
4
  "description": "Create Edge Starter App",
5
5
  "bin": {
6
6
  "create-edge-app": "./bin/cli.js"