@consilioweb/admin-nav 0.4.3

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.

Potentially problematic release.


This version of @consilioweb/admin-nav might be problematic. Click here for more details.

package/dist/index.js ADDED
@@ -0,0 +1,575 @@
1
+ import { deepMergeSimple } from 'payload/shared';
2
+
3
+ // src/plugin.ts
4
+
5
+ // src/collections/AdminNavPreferences.ts
6
+ function createAdminNavPreferencesCollection(slug = "admin-nav-preferences", userCollectionSlug = "users") {
7
+ return {
8
+ slug,
9
+ admin: {
10
+ hidden: true
11
+ },
12
+ access: {
13
+ // Users can only read their own preferences
14
+ read: ({ req }) => {
15
+ if (!req.user) return false;
16
+ return { user: { equals: req.user.id } };
17
+ },
18
+ // Users can only create their own preferences
19
+ create: ({ req }) => !!req.user,
20
+ // Users can only update their own preferences
21
+ update: ({ req }) => {
22
+ if (!req.user) return false;
23
+ return { user: { equals: req.user.id } };
24
+ },
25
+ // Users can only delete their own preferences
26
+ delete: ({ req }) => {
27
+ if (!req.user) return false;
28
+ return { user: { equals: req.user.id } };
29
+ }
30
+ },
31
+ fields: [
32
+ {
33
+ name: "user",
34
+ type: "relationship",
35
+ relationTo: userCollectionSlug,
36
+ required: true,
37
+ unique: true,
38
+ index: true
39
+ },
40
+ {
41
+ name: "navLayout",
42
+ type: "json",
43
+ required: true
44
+ },
45
+ {
46
+ name: "version",
47
+ type: "number",
48
+ defaultValue: 1
49
+ }
50
+ ]
51
+ };
52
+ }
53
+
54
+ // src/endpoints/preferences.ts
55
+ function createGetPreferencesHandler(collectionSlug) {
56
+ return async (req) => {
57
+ if (!req.user) {
58
+ return Response.json({ error: "Unauthorized" }, { status: 401 });
59
+ }
60
+ try {
61
+ const result = await req.payload.find({
62
+ collection: collectionSlug,
63
+ where: { user: { equals: req.user.id } },
64
+ limit: 1,
65
+ depth: 0
66
+ });
67
+ const doc = result.docs[0];
68
+ return Response.json({
69
+ navLayout: doc?.navLayout ?? null,
70
+ version: doc?.version ?? null
71
+ });
72
+ } catch {
73
+ return Response.json({ navLayout: null, version: null });
74
+ }
75
+ };
76
+ }
77
+ function createSavePreferencesHandler(collectionSlug) {
78
+ return async (req) => {
79
+ if (!req.user) {
80
+ return Response.json({ error: "Unauthorized" }, { status: 401 });
81
+ }
82
+ let body;
83
+ try {
84
+ body = await req.json();
85
+ } catch {
86
+ return Response.json({ error: "Invalid JSON body" }, { status: 400 });
87
+ }
88
+ const { navLayout } = body;
89
+ if (!navLayout || typeof navLayout !== "object") {
90
+ return Response.json({ error: "navLayout is required" }, { status: 400 });
91
+ }
92
+ try {
93
+ const existing = await req.payload.find({
94
+ collection: collectionSlug,
95
+ where: { user: { equals: req.user.id } },
96
+ limit: 1,
97
+ depth: 0
98
+ });
99
+ const existingDoc = existing.docs[0];
100
+ if (existingDoc) {
101
+ await req.payload.update({
102
+ collection: collectionSlug,
103
+ id: existingDoc.id,
104
+ data: {
105
+ navLayout,
106
+ version: navLayout.version || 1
107
+ }
108
+ });
109
+ } else {
110
+ await req.payload.create({
111
+ collection: collectionSlug,
112
+ data: {
113
+ user: req.user.id,
114
+ navLayout,
115
+ version: navLayout.version || 1
116
+ }
117
+ });
118
+ }
119
+ return Response.json({ success: true });
120
+ } catch (err) {
121
+ const message = err instanceof Error ? err.message : "Unknown error";
122
+ return Response.json({ error: message }, { status: 500 });
123
+ }
124
+ };
125
+ }
126
+ function createResetPreferencesHandler(collectionSlug) {
127
+ return async (req) => {
128
+ if (!req.user) {
129
+ return Response.json({ error: "Unauthorized" }, { status: 401 });
130
+ }
131
+ try {
132
+ const existing = await req.payload.find({
133
+ collection: collectionSlug,
134
+ where: { user: { equals: req.user.id } },
135
+ limit: 1,
136
+ depth: 0
137
+ });
138
+ const existingDoc = existing.docs[0];
139
+ if (existingDoc) {
140
+ await req.payload.delete({
141
+ collection: collectionSlug,
142
+ id: existingDoc.id
143
+ });
144
+ }
145
+ return Response.json({ success: true });
146
+ } catch (err) {
147
+ const message = err instanceof Error ? err.message : "Unknown error";
148
+ return Response.json({ error: message }, { status: 500 });
149
+ }
150
+ };
151
+ }
152
+
153
+ // src/translations/fr.ts
154
+ var fr = {
155
+ "plugin-admin-nav": {
156
+ // Common actions
157
+ save: "Sauvegarder",
158
+ cancel: "Annuler",
159
+ reset: "R\xE9initialiser",
160
+ create: "Cr\xE9er",
161
+ ok: "OK",
162
+ close: "Fermer",
163
+ show: "Afficher",
164
+ hide: "Masquer",
165
+ edit: "Modifier",
166
+ delete: "Supprimer",
167
+ addItem: "+ Ajouter un item",
168
+ addGroup: "+ Ajouter un groupe",
169
+ addSubmenu: "+ Ajouter",
170
+ moveUp: "Monter",
171
+ moveDown: "Descendre",
172
+ // Field labels
173
+ labelField: "Label",
174
+ urlField: "URL",
175
+ iconField: "Ic\xF4ne",
176
+ titleField: "Titre",
177
+ idField: "ID (unique)",
178
+ // Titles
179
+ editItem: "Modifier l'item",
180
+ editGroup: "Modifier le groupe",
181
+ newGroup: "Nouveau groupe",
182
+ customizeTitle: "Personnaliser la navigation",
183
+ // Messages
184
+ loading: "Chargement\u2026",
185
+ saving: "Enregistrement\u2026",
186
+ savedSuccess: "Navigation sauvegard\xE9e !",
187
+ saveError: "Erreur lors de la sauvegarde",
188
+ resetSuccess: "Navigation r\xE9initialis\xE9e",
189
+ resetError: "Erreur lors de la r\xE9initialisation",
190
+ dndHint: "Glissez-d\xE9posez les groupes et items pour r\xE9organiser. Utilisez les ic\xF4nes pour masquer, modifier ou supprimer.",
191
+ // Confirmations
192
+ deleteGroupConfirm: "Supprimer ce groupe et tous ses items ?",
193
+ resetConfirm: "R\xE9initialiser la navigation par d\xE9faut ? Vos personnalisations seront perdues.",
194
+ // Submenus
195
+ submenus: "Sous-menus",
196
+ noSubmenus: "Aucun sous-menu",
197
+ noLabel: "sans label",
198
+ newLink: "Nouveau lien",
199
+ // Navigation
200
+ dashboard: "Tableau de bord",
201
+ customize: "Personnaliser",
202
+ // Checkboxes
203
+ matchPrefix: "Match prefix (actif si l'URL commence par le href)",
204
+ defaultCollapsed: "Repli\xE9 par d\xE9faut",
205
+ // IconPicker
206
+ searchIcon: "Rechercher une ic\xF4ne...",
207
+ dotColor: "Couleur dot :",
208
+ noIconFound: "Aucune ic\xF4ne trouv\xE9e",
209
+ // Multi-lang
210
+ multiLang: "Multi-langue",
211
+ // Placeholders
212
+ titlePlaceholder: "ex: Mon groupe",
213
+ idPlaceholder: "ex: mon-groupe",
214
+ childLabelPlaceholder: "Ex: Tickets ouverts",
215
+ childUrlPlaceholder: "Ex: /admin/collections/tickets?status=open",
216
+ childIconPlaceholder: "#00E5FF ou ChevronRight",
217
+ childIconLabel: "Ic\xF4ne (nom ou #couleur)"
218
+ }
219
+ };
220
+
221
+ // src/translations/en.ts
222
+ var en = {
223
+ "plugin-admin-nav": {
224
+ // Common actions
225
+ save: "Save",
226
+ cancel: "Cancel",
227
+ reset: "Reset",
228
+ create: "Create",
229
+ ok: "OK",
230
+ close: "Close",
231
+ show: "Show",
232
+ hide: "Hide",
233
+ edit: "Edit",
234
+ delete: "Delete",
235
+ addItem: "+ Add item",
236
+ addGroup: "+ Add group",
237
+ addSubmenu: "+ Add",
238
+ moveUp: "Move up",
239
+ moveDown: "Move down",
240
+ // Field labels
241
+ labelField: "Label",
242
+ urlField: "URL",
243
+ iconField: "Icon",
244
+ titleField: "Title",
245
+ idField: "ID (unique)",
246
+ // Titles
247
+ editItem: "Edit item",
248
+ editGroup: "Edit group",
249
+ newGroup: "New group",
250
+ customizeTitle: "Customize navigation",
251
+ // Messages
252
+ loading: "Loading\u2026",
253
+ saving: "Saving\u2026",
254
+ savedSuccess: "Navigation saved!",
255
+ saveError: "Error saving navigation",
256
+ resetSuccess: "Navigation reset",
257
+ resetError: "Error resetting navigation",
258
+ dndHint: "Drag and drop groups and items to reorder. Use the icons to hide, edit, or delete.",
259
+ // Confirmations
260
+ deleteGroupConfirm: "Delete this group and all its items?",
261
+ resetConfirm: "Reset to default navigation? Your customizations will be lost.",
262
+ // Submenus
263
+ submenus: "Submenus",
264
+ noSubmenus: "No submenus",
265
+ noLabel: "no label",
266
+ newLink: "New link",
267
+ // Navigation
268
+ dashboard: "Dashboard",
269
+ customize: "Customize",
270
+ // Checkboxes
271
+ matchPrefix: "Match prefix (active if URL starts with href)",
272
+ defaultCollapsed: "Collapsed by default",
273
+ // IconPicker
274
+ searchIcon: "Search icons...",
275
+ dotColor: "Dot color:",
276
+ noIconFound: "No icon found",
277
+ // Multi-lang
278
+ multiLang: "Multi-language",
279
+ // Placeholders
280
+ titlePlaceholder: "e.g. My group",
281
+ idPlaceholder: "e.g. my-group",
282
+ childLabelPlaceholder: "E.g. Open tickets",
283
+ childUrlPlaceholder: "E.g. /admin/collections/tickets?status=open",
284
+ childIconPlaceholder: "#00E5FF or ChevronRight",
285
+ childIconLabel: "Icon (name or #color)"
286
+ }
287
+ };
288
+
289
+ // src/translations/index.ts
290
+ var translations = {
291
+ en,
292
+ fr
293
+ };
294
+
295
+ // src/autoDiscover.ts
296
+ var SLUG_ICON_MAP = {
297
+ // Content
298
+ pages: "file-text",
299
+ posts: "newspaper",
300
+ articles: "newspaper",
301
+ blog: "newspaper",
302
+ media: "image",
303
+ images: "image",
304
+ files: "file-up",
305
+ categories: "tag",
306
+ tags: "tag",
307
+ // Users
308
+ users: "user-cog",
309
+ members: "users",
310
+ authors: "users",
311
+ // Forms
312
+ forms: "clipboard-list",
313
+ "form-submissions": "clipboard-list",
314
+ // Support
315
+ tickets: "ticket",
316
+ comments: "message-square",
317
+ messages: "message-square",
318
+ "chat-messages": "message-square",
319
+ // Projects
320
+ projects: "folder-kanban",
321
+ // Commerce
322
+ products: "box",
323
+ orders: "receipt",
324
+ // SEO
325
+ redirects: "shuffle",
326
+ "custom-redirects": "shuffle",
327
+ search: "search",
328
+ "seo-logs": "search-check",
329
+ // Config
330
+ header: "panel-top",
331
+ footer: "panel-bottom",
332
+ settings: "settings",
333
+ navigation: "link",
334
+ menus: "link",
335
+ // Misc
336
+ emails: "mail",
337
+ "email-logs": "mail-search",
338
+ "auth-logs": "shield-check",
339
+ notifications: "activity",
340
+ "admin-notifications": "activity",
341
+ logs: "activity"
342
+ };
343
+ function guessIcon(slug) {
344
+ if (SLUG_ICON_MAP[slug]) return SLUG_ICON_MAP[slug];
345
+ for (const [key, icon] of Object.entries(SLUG_ICON_MAP)) {
346
+ if (slug.includes(key)) return icon;
347
+ }
348
+ return "box";
349
+ }
350
+ function slugifyGroup(name) {
351
+ return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");
352
+ }
353
+ function resolvePayloadLabel(labels, slug) {
354
+ if (labels?.plural) return labels.plural;
355
+ if (labels?.singular) return labels.singular;
356
+ return slug.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
357
+ }
358
+ function autoDiscoverNav(config) {
359
+ const groupMap = /* @__PURE__ */ new Map();
360
+ const addToGroup = (groupName, item) => {
361
+ if (!groupMap.has(groupName)) {
362
+ groupMap.set(groupName, []);
363
+ }
364
+ groupMap.get(groupName).push(item);
365
+ };
366
+ for (const collection of config.collections || []) {
367
+ if (collection.admin?.hidden) continue;
368
+ if (collection.slug === "admin-nav-preferences") continue;
369
+ const groupName = collection.admin?.group || "Collections";
370
+ const label = resolvePayloadLabel(
371
+ collection.labels,
372
+ collection.slug
373
+ );
374
+ addToGroup(groupName, {
375
+ id: collection.slug,
376
+ href: `/admin/collections/${collection.slug}`,
377
+ label,
378
+ icon: guessIcon(collection.slug),
379
+ matchPrefix: true
380
+ });
381
+ }
382
+ for (const global of config.globals || []) {
383
+ if (global.admin?.hidden) continue;
384
+ const groupName = global.admin?.group || "Configuration";
385
+ const label = global.label || global.slug.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
386
+ addToGroup(groupName, {
387
+ id: `global-${global.slug}`,
388
+ href: `/admin/globals/${global.slug}`,
389
+ label,
390
+ icon: guessIcon(global.slug)
391
+ });
392
+ }
393
+ const views = config.admin?.components?.views;
394
+ if (views && typeof views === "object") {
395
+ for (const [key, view] of Object.entries(views)) {
396
+ if (!view || typeof view !== "object") continue;
397
+ const viewObj = view;
398
+ if (!viewObj.path) continue;
399
+ if (key === "nav-customizer") continue;
400
+ addToGroup("Views", {
401
+ id: `view-${key}`,
402
+ href: `/admin${viewObj.path}`,
403
+ label: key.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" "),
404
+ icon: guessIcon(key)
405
+ });
406
+ }
407
+ }
408
+ const groups = [];
409
+ for (const [name, items] of groupMap) {
410
+ groups.push({
411
+ id: slugifyGroup(name),
412
+ title: name,
413
+ items
414
+ });
415
+ }
416
+ return groups;
417
+ }
418
+
419
+ // src/plugin.ts
420
+ var adminNavPlugin = (pluginConfig) => (incomingConfig) => {
421
+ console.log("[admin-nav-plugin] Running plugin...");
422
+ const config = { ...incomingConfig };
423
+ const safeConfig = pluginConfig ?? {};
424
+ const collectionSlug = safeConfig.collectionSlug ?? "admin-nav-preferences";
425
+ const userCollectionSlug = safeConfig.userCollectionSlug ?? "users";
426
+ const basePath = safeConfig.endpointBasePath ?? "/admin-nav";
427
+ const defaultNav = safeConfig.defaultNav ?? autoDiscoverNav(incomingConfig);
428
+ if (!safeConfig.defaultNav) {
429
+ console.log(`[admin-nav-plugin] Auto-discovered ${defaultNav.length} nav group(s) from Payload config`);
430
+ }
431
+ config.i18n = {
432
+ ...config.i18n,
433
+ translations: deepMergeSimple(translations, config.i18n?.translations ?? {})
434
+ };
435
+ config.collections = [
436
+ ...config.collections || [],
437
+ createAdminNavPreferencesCollection(collectionSlug, userCollectionSlug)
438
+ ];
439
+ config.endpoints = [
440
+ ...config.endpoints || [],
441
+ {
442
+ path: `${basePath}/preferences`,
443
+ method: "get",
444
+ handler: createGetPreferencesHandler(collectionSlug)
445
+ },
446
+ {
447
+ path: `${basePath}/preferences`,
448
+ method: "patch",
449
+ handler: createSavePreferencesHandler(collectionSlug)
450
+ },
451
+ {
452
+ path: `${basePath}/preferences`,
453
+ method: "delete",
454
+ handler: createResetPreferencesHandler(collectionSlug)
455
+ }
456
+ ];
457
+ if (!config.admin) config.admin = {};
458
+ if (!config.admin.components) config.admin.components = {};
459
+ const navComponent = safeConfig.navComponentPath ?? "@consilioweb/admin-nav/client#AdminNav";
460
+ const existingBeforeNav = config.admin.components.beforeNavLinks || [];
461
+ config.admin.components.beforeNavLinks = [
462
+ navComponent,
463
+ ...Array.isArray(existingBeforeNav) ? existingBeforeNav : [existingBeforeNav]
464
+ ];
465
+ console.log("[admin-nav-plugin] beforeNavLinks set to:", config.admin.components.beforeNavLinks);
466
+ if (safeConfig.afterNav?.length) {
467
+ const existingAfterNav = config.admin.components.afterNavLinks || [];
468
+ config.admin.components.afterNavLinks = [
469
+ ...Array.isArray(existingAfterNav) ? existingAfterNav : [existingAfterNav],
470
+ ...safeConfig.afterNav
471
+ ];
472
+ }
473
+ if (safeConfig.addCustomizerView !== false) {
474
+ if (!config.admin.components.views) config.admin.components.views = {};
475
+ config.admin.components.views["nav-customizer"] = {
476
+ Component: "@consilioweb/admin-nav/views#NavCustomizerView",
477
+ path: "/nav-customizer"
478
+ };
479
+ }
480
+ config.endpoints = [
481
+ ...config.endpoints || [],
482
+ {
483
+ path: `${basePath}/default-nav`,
484
+ method: "get",
485
+ handler: async () => {
486
+ return Response.json({
487
+ defaultNav,
488
+ afterNav: safeConfig.afterNav || [],
489
+ basePath: `/api${basePath}`
490
+ });
491
+ }
492
+ }
493
+ ];
494
+ return config;
495
+ };
496
+
497
+ // src/icons.ts
498
+ var iconPaths = {
499
+ // Navigation & Layout
500
+ "home": "M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z M9 22V12h6v10",
501
+ "layout-dashboard": "M3 3h7v9H3z M14 3h7v5h-7z M14 12h7v9h-7z M3 16h7v5H3z",
502
+ "settings": "M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z M12 8a4 4 0 1 0 0 8 4 4 0 0 0 0-8z",
503
+ // Content
504
+ "file-text": "M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z M14 2v6h6 M16 13H8 M16 17H8 M10 9H8",
505
+ "newspaper": "M4 22h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2H8a2 2 0 0 0-2 2v16a2 2 0 0 1-2 2zm0 0a2 2 0 0 1-2-2v-9c0-1.1.9-2 2-2h2 M18 14h-8 M15 18h-5 M10 6h8v4h-8V6z",
506
+ "image": "M21 3H3a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h18a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2zM8.5 10a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm13.5 9l-5-6.5-3 3.5-2-2L3 19",
507
+ "tag": "M12 2H2v10l9.17 9.17a2 2 0 0 0 2.83 0l7.17-7.17a2 2 0 0 0 0-2.83L12 2zM7 7h.01",
508
+ "calendar": "M16 2v4 M8 2v4 M3 10h18 M21 6H3a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h18a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2z",
509
+ // Support
510
+ "ticket": "M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z M13 5v2 M13 17v2 M13 11v2",
511
+ "message-square": "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z",
512
+ "users": "M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2 M23 21v-2a4 4 0 0 0-3-3.87 M16 3.13a4 4 0 0 1 0 7.75 M9 7a4 4 0 1 0 0 8 4 4 0 0 0 0-8z",
513
+ "folder-kanban": "M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2z M8 10v4 M12 10v2 M16 10v6",
514
+ "file-up": "M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z M14 2v6h6 M12 12v6 M15 15l-3-3-3 3",
515
+ "mail-search": "M20 6H4a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h8 M22 22l-2.5-2.5 M4 8l8 5 8-5 M18 16a2 2 0 1 0 0 4 2 2 0 0 0 0-4z",
516
+ "shield-check": "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z M9 12l2 2 4-4",
517
+ // Management
518
+ "receipt": "M4 2v20l2-1 2 1 2-1 2 1 2-1 2 1 2-1 2 1V2l-2 1-2-1-2 1-2-1-2 1-2-1-2 1Z M16 8H8 M16 12H8 M10 16H8",
519
+ "clock": "M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20z M12 6v6l4 2",
520
+ "mail": "M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z M22 6l-10 7L2 6",
521
+ "clipboard-list": "M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2 M15 2H9a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1z M12 11h4 M12 16h4 M8 11h.01 M8 16h.01",
522
+ // Configuration
523
+ "panel-top": "M3 3h18a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z M3 9h18",
524
+ "panel-bottom": "M3 3h18a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z M3 15h18",
525
+ "user-cog": "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2 M9 7a4 4 0 1 0 0 8 4 4 0 0 0 0-8z M19.82 16.18l-.47.36a.87.87 0 0 0 0 1.4l.47.36a1.52 1.52 0 0 1-.75 2.62l-.58.08a.87.87 0 0 0-.7 1l.08.58a1.52 1.52 0 0 1-2.26 1.52l-.36-.47a.87.87 0 0 0-1.4 0l-.36.47a1.52 1.52 0 0 1-2.26-1.52l.08-.58a.87.87 0 0 0-.7-1l-.58-.08a1.52 1.52 0 0 1-.75-2.62l.47-.36a.87.87 0 0 0 0-1.4l-.47-.36a1.52 1.52 0 0 1 .75-2.62l.58-.08a.87.87 0 0 0 .7-1l-.08-.58a1.52 1.52 0 0 1 2.26-1.52l.36.47a.87.87 0 0 0 1.4 0l.36-.47A1.52 1.52 0 0 1 22 14.74l-.08.58a.87.87 0 0 0 .7 1l.58.08a1.52 1.52 0 0 1 .75 2.62z",
526
+ // SEO
527
+ "search-check": "M11 5a6 6 0 1 0 0 12 6 6 0 0 0 0-12z M21 21l-4.35-4.35 M8 11l2 2 4-4",
528
+ "bar-chart-3": "M18 20V10 M12 20V4 M6 20v-6",
529
+ "shuffle": "M16 3h5v5 M4 20L21 3 M21 16v5h-5 M15 15l6 6 M4 4l5 5",
530
+ "layers": "M12 2L2 7l10 5 10-5-10-5z M2 17l10 5 10-5 M2 12l10 5 10-5",
531
+ "activity": "M22 12h-4l-3 9L9 3l-3 9H2",
532
+ "search": "M11 3a8 8 0 1 0 0 16 8 8 0 0 0 0-16z M21 21l-4.35-4.35",
533
+ "file-code-2": "M4 22h14a2 2 0 0 0 2-2V7.5L14.5 2H6a2 2 0 0 0-2 2v4 M14 2v6h6 M9 18l3-3-3-3 M4 12l-3 3 3 3",
534
+ "git-branch": "M6 3v12 M18 9a3 3 0 1 0 0 6 M6 21a3 3 0 1 0 0-6 M18 9a9 9 0 0 1-9 9",
535
+ // Misc
536
+ "plus": "M12 5v14 M5 12h14",
537
+ "minus": "M5 12h14",
538
+ "x": "M18 6L6 18 M6 6l12 12",
539
+ "check": "M20 6L9 17l-5-5",
540
+ "chevron-down": "M6 9l6 6 6-6",
541
+ "chevron-right": "M9 18l6-6-6-6",
542
+ "grip-vertical": "M9 4h.01 M9 9h.01 M9 14h.01 M9 19h.01 M15 4h.01 M15 9h.01 M15 14h.01 M15 19h.01",
543
+ "eye": "M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8z M12 9a3 3 0 1 0 0 6 3 3 0 0 0 0-6z",
544
+ "eye-off": "M9.88 9.88a3 3 0 1 0 4.24 4.24 M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68 M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61 M1 1l22 22",
545
+ "pencil": "M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z M15 5l4 4",
546
+ "trash-2": "M3 6h18 M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6 M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2 M10 11v6 M14 11v6",
547
+ "save": "M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z M17 21v-8H7v8 M7 3v5h8",
548
+ "rotate-ccw": "M1 4v6h6 M3.51 15a9 9 0 1 0 2.13-9.36L1 10",
549
+ "move": "M5 9l-3 3 3 3 M9 5l3-3 3 3 M15 19l-3 3-3-3 M19 9l3 3-3 3 M2 12h20 M12 2v20",
550
+ "palette": "M12 2a10 10 0 0 0-8.66 15A2 2 0 0 0 5.07 19H6a2 2 0 0 1 2 2 2 2 0 0 0 2 2 10 10 0 0 0 2-20z M6 10a1 1 0 1 0 0-2 1 1 0 0 0 0 2z M10 7a1 1 0 1 0 0-2 1 1 0 0 0 0 2z M15 7a1 1 0 1 0 0-2 1 1 0 0 0 0 2z M18 10a1 1 0 1 0 0-2 1 1 0 0 0 0 2z",
551
+ "box": "M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z M3.27 6.96L12 12.01l8.73-5.05 M12 22.08V12",
552
+ "star": "M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z",
553
+ "heart": "M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z",
554
+ "zap": "M13 2L3 14h9l-1 8 10-12h-9l1-8z",
555
+ "globe": "M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20z M2 12h20 M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z",
556
+ "link": "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71 M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71",
557
+ "external-link": "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6 M15 3h6v6 M10 14L21 3"
558
+ };
559
+ function getIconNames() {
560
+ return Object.keys(iconPaths);
561
+ }
562
+ function getIconPath(name) {
563
+ return iconPaths[name];
564
+ }
565
+
566
+ // src/utils.ts
567
+ function isMultiLang(label) {
568
+ return typeof label === "object" && label !== null;
569
+ }
570
+ function resolveLabel(label, lang, fallback) {
571
+ if (typeof label === "string") return label;
572
+ return label[lang] ?? (fallback ? label[fallback] : void 0) ?? Object.values(label)[0] ?? "";
573
+ }
574
+
575
+ export { adminNavPlugin, autoDiscoverNav, createAdminNavPreferencesCollection, createGetPreferencesHandler, createResetPreferencesHandler, createSavePreferencesHandler, getIconNames, getIconPath, iconPaths, isMultiLang, resolveLabel };
package/dist/views.cjs ADDED
@@ -0,0 +1,32 @@
1
+ 'use strict';
2
+
3
+ var templates = require('@payloadcms/next/templates');
4
+ var navigation = require('next/navigation');
5
+ var client = require('@consilioweb/admin-nav/client');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+
8
+ // src/views/NavCustomizerView.tsx
9
+ var NavCustomizerView = (props) => {
10
+ const { initPageResult } = props;
11
+ if (!initPageResult?.req?.user) {
12
+ navigation.redirect("/admin/login");
13
+ }
14
+ const { req, visibleEntities, permissions, locale } = initPageResult;
15
+ return /* @__PURE__ */ jsxRuntime.jsx(
16
+ templates.DefaultTemplate,
17
+ {
18
+ i18n: req.i18n,
19
+ locale,
20
+ params: {},
21
+ payload: req.payload,
22
+ permissions,
23
+ req,
24
+ searchParams: {},
25
+ user: req.user,
26
+ visibleEntities,
27
+ children: /* @__PURE__ */ jsxRuntime.jsx(client.NavCustomizer, {})
28
+ }
29
+ );
30
+ };
31
+
32
+ exports.NavCustomizerView = NavCustomizerView;
@@ -0,0 +1,11 @@
1
+ import { AdminViewServerProps } from 'payload';
2
+ import React from 'react';
3
+
4
+ /**
5
+ * NavCustomizerView — Server component wrapper.
6
+ * Wraps the client NavCustomizer in Payload's DefaultTemplate to get the admin sidebar + header.
7
+ */
8
+
9
+ declare const NavCustomizerView: React.FC<AdminViewServerProps>;
10
+
11
+ export { NavCustomizerView };
@@ -0,0 +1,11 @@
1
+ import { AdminViewServerProps } from 'payload';
2
+ import React from 'react';
3
+
4
+ /**
5
+ * NavCustomizerView — Server component wrapper.
6
+ * Wraps the client NavCustomizer in Payload's DefaultTemplate to get the admin sidebar + header.
7
+ */
8
+
9
+ declare const NavCustomizerView: React.FC<AdminViewServerProps>;
10
+
11
+ export { NavCustomizerView };
package/dist/views.js ADDED
@@ -0,0 +1,30 @@
1
+ import { DefaultTemplate } from '@payloadcms/next/templates';
2
+ import { redirect } from 'next/navigation';
3
+ import { NavCustomizer } from '@consilioweb/admin-nav/client';
4
+ import { jsx } from 'react/jsx-runtime';
5
+
6
+ // src/views/NavCustomizerView.tsx
7
+ var NavCustomizerView = (props) => {
8
+ const { initPageResult } = props;
9
+ if (!initPageResult?.req?.user) {
10
+ redirect("/admin/login");
11
+ }
12
+ const { req, visibleEntities, permissions, locale } = initPageResult;
13
+ return /* @__PURE__ */ jsx(
14
+ DefaultTemplate,
15
+ {
16
+ i18n: req.i18n,
17
+ locale,
18
+ params: {},
19
+ payload: req.payload,
20
+ permissions,
21
+ req,
22
+ searchParams: {},
23
+ user: req.user,
24
+ visibleEntities,
25
+ children: /* @__PURE__ */ jsx(NavCustomizer, {})
26
+ }
27
+ );
28
+ };
29
+
30
+ export { NavCustomizerView };