@nextsparkjs/core 0.1.0-beta.116 → 0.1.0-beta.118

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 (44) hide show
  1. package/dist/components/dashboard/block-editor/config-panel.d.ts.map +1 -1
  2. package/dist/components/dashboard/block-editor/config-panel.js +37 -1
  3. package/dist/components/dashboard/block-editor/entity-fields-sidebar.d.ts.map +1 -1
  4. package/dist/components/dashboard/block-editor/entity-fields-sidebar.js +57 -1
  5. package/dist/components/devtools/DevtoolsSidebar.d.ts +5 -2
  6. package/dist/components/devtools/DevtoolsSidebar.d.ts.map +1 -1
  7. package/dist/components/devtools/DevtoolsSidebar.js +101 -43
  8. package/dist/components/superadmin/layouts/SuperadminSidebar.d.ts +4 -1
  9. package/dist/components/superadmin/layouts/SuperadminSidebar.d.ts.map +1 -1
  10. package/dist/components/superadmin/layouts/SuperadminSidebar.js +55 -2
  11. package/dist/components/ui/simple-relation-select.d.ts.map +1 -1
  12. package/dist/components/ui/simple-relation-select.js +5 -20
  13. package/dist/components/ui/timezone-select.js +21 -21
  14. package/dist/hooks/useAuth.js +1 -1
  15. package/dist/lib/auth-client.d.ts +2 -69
  16. package/dist/lib/auth-client.d.ts.map +1 -1
  17. package/dist/lib/auth-client.js +2 -2
  18. package/dist/lib/entities/schema-generator.d.ts.map +1 -1
  19. package/dist/lib/entities/schema-generator.js +4 -4
  20. package/dist/lib/entities/types.d.ts +19 -0
  21. package/dist/lib/entities/types.d.ts.map +1 -1
  22. package/dist/lib/services/translation.service.d.ts +14 -0
  23. package/dist/lib/services/translation.service.d.ts.map +1 -1
  24. package/dist/lib/services/translation.service.js +63 -4
  25. package/dist/nextspark-registries.d.ts +20 -0
  26. package/dist/styles/classes.json +3 -2
  27. package/dist/styles/ui.css +1 -1
  28. package/dist/templates/app/devtools/layout.tsx +3 -1
  29. package/dist/templates/app/devtools/plugins/[plugin]/page.tsx +17 -0
  30. package/dist/templates/app/superadmin/layout.tsx +3 -1
  31. package/dist/templates/app/superadmin/plugins/[plugin]/page.tsx +17 -0
  32. package/dist/types/plugin.d.ts +29 -0
  33. package/dist/types/plugin.d.ts.map +1 -1
  34. package/package.json +2 -2
  35. package/scripts/build/registry/discovery/plugins.mjs +25 -2
  36. package/scripts/build/registry/generators/entity-registry.mjs +10 -0
  37. package/scripts/build/registry/generators/plugin-registry.mjs +92 -3
  38. package/scripts/build/registry/generators/template-registry.mjs +7 -1
  39. package/scripts/build/registry/generators/translation-registry.mjs +81 -2
  40. package/scripts/db/run-migrations.mjs +26 -0
  41. package/templates/app/devtools/layout.tsx +3 -1
  42. package/templates/app/devtools/plugins/[plugin]/page.tsx +17 -0
  43. package/templates/app/superadmin/layout.tsx +3 -1
  44. package/templates/app/superadmin/plugins/[plugin]/page.tsx +17 -0
@@ -1 +1 @@
1
- {"version":3,"file":"config-panel.d.ts","sourceRoot":"","sources":["../../../../src/components/dashboard/block-editor/config-panel.tsx"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAA;AACxF,OAAO,KAAK,EAAE,YAAY,EAAoC,MAAM,uBAAuB,CAAA;AAS3F,UAAU,gBAAgB;IACxB,YAAY,EAAE,kBAAkB,CAAA;IAChC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACrC,mBAAmB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;IAC5D,YAAY,EAAE,YAAY,CAAA;IAC1B,oBAAoB,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAA;CACvD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAC1B,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,oBAAoB,EACrB,EAAE,gBAAgB,2CA6alB"}
1
+ {"version":3,"file":"config-panel.d.ts","sourceRoot":"","sources":["../../../../src/components/dashboard/block-editor/config-panel.tsx"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAA;AACxF,OAAO,KAAK,EAAE,YAAY,EAAmB,MAAM,uBAAuB,CAAA;AAiB1E,UAAU,gBAAgB;IACxB,YAAY,EAAE,kBAAkB,CAAA;IAChC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACrC,mBAAmB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;IAC5D,YAAY,EAAE,YAAY,CAAA;IAC1B,oBAAoB,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAA;CACvD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAC1B,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,oBAAoB,EACrB,EAAE,gBAAgB,2CA6dlB"}
@@ -28,6 +28,14 @@ import {
28
28
  } from "lucide-react";
29
29
  import { cn } from "../../../lib/utils/index.js";
30
30
  import { sel } from "../../../lib/test/index.js";
31
+ import { SimpleRelationSelect } from "../../ui/simple-relation-select.js";
32
+ import {
33
+ Select,
34
+ SelectContent,
35
+ SelectItem,
36
+ SelectTrigger,
37
+ SelectValue
38
+ } from "../../ui/select.js";
31
39
  function ConfigPanel({
32
40
  entityConfig,
33
41
  entityFields,
@@ -62,10 +70,38 @@ function ConfigPanel({
62
70
  }, [sidebarFields.length, taxonomiesEnabled]);
63
71
  const showSeoSection = ((_e = entityConfig.builder) == null ? void 0 : _e.seo) !== false;
64
72
  const renderField = (fieldName) => {
73
+ var _a2;
65
74
  const value = entityFields[fieldName];
75
+ const sidebarFieldsConfig = (_a2 = entityConfig.builder) == null ? void 0 : _a2.sidebarFieldsConfig;
76
+ const fieldConfig = sidebarFieldsConfig == null ? void 0 : sidebarFieldsConfig.find((f) => f.name === fieldName);
77
+ const fieldLabel = (fieldConfig == null ? void 0 : fieldConfig.label) || fieldName.charAt(0).toUpperCase() + fieldName.slice(1).replace(/([A-Z])/g, " $1");
78
+ if ((fieldConfig == null ? void 0 : fieldConfig.type) === "relation" && fieldConfig.relation) {
79
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
80
+ /* @__PURE__ */ jsx(Label, { htmlFor: fieldName, children: fieldLabel }),
81
+ /* @__PURE__ */ jsx(
82
+ SimpleRelationSelect,
83
+ {
84
+ entityType: fieldConfig.relation.entity,
85
+ titleField: fieldConfig.relation.titleField,
86
+ value: value || void 0,
87
+ onChange: (v) => onEntityFieldChange(fieldName, v ?? null),
88
+ userFiltered: fieldConfig.relation.userFiltered,
89
+ placeholder: "Select..."
90
+ }
91
+ )
92
+ ] }, fieldName);
93
+ }
94
+ if ((fieldConfig == null ? void 0 : fieldConfig.type) === "select" && fieldConfig.options) {
95
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
96
+ /* @__PURE__ */ jsx(Label, { htmlFor: fieldName, children: fieldLabel }),
97
+ /* @__PURE__ */ jsxs(Select, { value: value || "", onValueChange: (v) => onEntityFieldChange(fieldName, v), children: [
98
+ /* @__PURE__ */ jsx(SelectTrigger, { id: fieldName, children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select..." }) }),
99
+ /* @__PURE__ */ jsx(SelectContent, { children: fieldConfig.options.map((opt) => /* @__PURE__ */ jsx(SelectItem, { value: opt.value, children: opt.label }, opt.value)) })
100
+ ] })
101
+ ] }, fieldName);
102
+ }
66
103
  const isTextarea = fieldName.toLowerCase().includes("excerpt") || fieldName.toLowerCase().includes("description") || fieldName.toLowerCase().includes("summary");
67
104
  const isImage = fieldName.toLowerCase().includes("image") || fieldName.toLowerCase().includes("thumbnail") || fieldName.toLowerCase().includes("photo");
68
- const fieldLabel = fieldName.charAt(0).toUpperCase() + fieldName.slice(1).replace(/([A-Z])/g, " $1");
69
105
  if (isTextarea) {
70
106
  return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
71
107
  /* @__PURE__ */ jsxs(Label, { htmlFor: fieldName, className: "flex items-center gap-2", children: [
@@ -1 +1 @@
1
- {"version":3,"file":"entity-fields-sidebar.d.ts","sourceRoot":"","sources":["../../../../src/components/dashboard/block-editor/entity-fields-sidebar.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAA;AASxF,UAAU,wBAAwB;IAChC,YAAY,EAAE,kBAAkB,CAAA;IAChC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;IACjD,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC7B,gBAAgB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAA;CAChD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,YAAY,EACZ,MAAM,EACN,QAAQ,EACR,kBAAuB,EACvB,gBAAgB,EACjB,EAAE,wBAAwB,2CA6M1B"}
1
+ {"version":3,"file":"entity-fields-sidebar.d.ts","sourceRoot":"","sources":["../../../../src/components/dashboard/block-editor/entity-fields-sidebar.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAA;AAiBxF,UAAU,wBAAwB;IAChC,YAAY,EAAE,kBAAkB,CAAA;IAChC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;IACjD,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC7B,gBAAgB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAA;CAChD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,YAAY,EACZ,MAAM,EACN,QAAQ,EACR,kBAAuB,EACvB,gBAAgB,EACjB,EAAE,wBAAwB,2CAoR1B"}
@@ -10,6 +10,14 @@ import { Badge } from "../../ui/badge.js";
10
10
  import { ScrollArea } from "../../ui/scroll-area.js";
11
11
  import { Checkbox } from "../../ui/checkbox.js";
12
12
  import { FileText, Image, Tag, Loader2 } from "lucide-react";
13
+ import { SimpleRelationSelect } from "../../ui/simple-relation-select.js";
14
+ import {
15
+ Select,
16
+ SelectContent,
17
+ SelectItem,
18
+ SelectTrigger,
19
+ SelectValue
20
+ } from "../../ui/select.js";
13
21
  function EntityFieldsSidebar({
14
22
  entityConfig,
15
23
  fields,
@@ -35,10 +43,58 @@ function EntityFieldsSidebar({
35
43
  });
36
44
  const taxonomyItems = (taxonomyData == null ? void 0 : taxonomyData.data) || [];
37
45
  const renderField = (fieldName) => {
46
+ var _a2;
38
47
  const value = fields[fieldName];
48
+ const sidebarFieldsConfig = (_a2 = entityConfig.builder) == null ? void 0 : _a2.sidebarFieldsConfig;
49
+ const fieldConfig = sidebarFieldsConfig == null ? void 0 : sidebarFieldsConfig.find((f) => f.name === fieldName);
50
+ const fieldLabel = (fieldConfig == null ? void 0 : fieldConfig.label) || fieldName.charAt(0).toUpperCase() + fieldName.slice(1).replace(/([A-Z])/g, " $1");
51
+ if ((fieldConfig == null ? void 0 : fieldConfig.type) === "relation" && fieldConfig.relation) {
52
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
53
+ /* @__PURE__ */ jsx(Label, { htmlFor: fieldName, children: fieldLabel }),
54
+ /* @__PURE__ */ jsx(
55
+ SimpleRelationSelect,
56
+ {
57
+ entityType: fieldConfig.relation.entity,
58
+ titleField: fieldConfig.relation.titleField,
59
+ value: value || void 0,
60
+ onChange: (v) => onChange(fieldName, v ?? null),
61
+ userFiltered: fieldConfig.relation.userFiltered,
62
+ placeholder: "Select..."
63
+ }
64
+ )
65
+ ] }, fieldName);
66
+ }
67
+ if ((fieldConfig == null ? void 0 : fieldConfig.type) === "select" && fieldConfig.options) {
68
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
69
+ /* @__PURE__ */ jsx(Label, { htmlFor: fieldName, children: fieldLabel }),
70
+ /* @__PURE__ */ jsxs(Select, { value: value || "", onValueChange: (v) => onChange(fieldName, v), children: [
71
+ /* @__PURE__ */ jsx(SelectTrigger, { id: fieldName, children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select..." }) }),
72
+ /* @__PURE__ */ jsx(SelectContent, { children: fieldConfig.options.map((opt) => /* @__PURE__ */ jsx(SelectItem, { value: opt.value, children: opt.label }, opt.value)) })
73
+ ] })
74
+ ] }, fieldName);
75
+ }
76
+ if ((fieldConfig == null ? void 0 : fieldConfig.type) === "textarea") {
77
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
78
+ /* @__PURE__ */ jsxs(Label, { htmlFor: fieldName, className: "flex items-center gap-2", children: [
79
+ /* @__PURE__ */ jsx(FileText, { className: "h-4 w-4 text-muted-foreground" }),
80
+ fieldLabel
81
+ ] }),
82
+ /* @__PURE__ */ jsx(
83
+ Textarea,
84
+ {
85
+ id: fieldName,
86
+ value: value || "",
87
+ onChange: (e) => onChange(fieldName, e.target.value),
88
+ placeholder: fieldConfig.placeholder || t("placeholders.excerpt"),
89
+ rows: fieldConfig.rows || 4,
90
+ className: "resize-none",
91
+ "data-cy": sel("blockEditor.entityFieldsPanel.field", { name: fieldName })
92
+ }
93
+ )
94
+ ] }, fieldName);
95
+ }
39
96
  const isTextarea = fieldName.toLowerCase().includes("excerpt") || fieldName.toLowerCase().includes("description") || fieldName.toLowerCase().includes("summary");
40
97
  const isImage = fieldName.toLowerCase().includes("image") || fieldName.toLowerCase().includes("thumbnail") || fieldName.toLowerCase().includes("photo");
41
- const fieldLabel = fieldName.charAt(0).toUpperCase() + fieldName.slice(1).replace(/([A-Z])/g, " $1");
42
98
  if (isTextarea) {
43
99
  return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
44
100
  /* @__PURE__ */ jsxs(Label, { htmlFor: fieldName, className: "flex items-center gap-2", children: [
@@ -1,9 +1,12 @@
1
+ import type { PluginNavItem } from "../../types/plugin";
1
2
  /**
2
3
  * DevTools Sidebar Component
3
4
  *
4
5
  * Specialized sidebar for developer navigation within the /devtools area.
6
+ * Reads plugin navigation items from @nextsparkjs/registries automatically.
5
7
  * Includes collapsible functionality and purple/violet branding.
6
- * Based on AdminSidebar pattern but with distinct developer-focused styling.
7
8
  */
8
- export declare function DevtoolsSidebar(): import("react/jsx-runtime").JSX.Element;
9
+ export declare function DevtoolsSidebar({ pluginItems: pluginItemsProp }?: {
10
+ pluginItems?: PluginNavItem[];
11
+ }): import("react/jsx-runtime").JSX.Element;
9
12
  //# sourceMappingURL=DevtoolsSidebar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DevtoolsSidebar.d.ts","sourceRoot":"","sources":["../../../src/components/devtools/DevtoolsSidebar.tsx"],"names":[],"mappings":"AAiCA;;;;;;GAMG;AACH,wBAAgB,eAAe,4CAuO9B"}
1
+ {"version":3,"file":"DevtoolsSidebar.d.ts","sourceRoot":"","sources":["../../../src/components/devtools/DevtoolsSidebar.tsx"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAcxD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,EAAE,WAAW,EAAE,eAAe,EAAE,GAAE;IAAE,WAAW,CAAC,EAAE,aAAa,EAAE,CAAA;CAAO,2CAqRvG"}
@@ -16,17 +16,35 @@ import {
16
16
  GitBranch,
17
17
  LayoutGrid,
18
18
  Tag,
19
- Clock
19
+ Clock,
20
+ Puzzle,
21
+ Star,
22
+ Bell,
23
+ Globe
20
24
  } from "lucide-react";
21
25
  import { cn } from "../../lib/utils/index.js";
22
26
  import { Button } from "../ui/button.js";
23
27
  import { useState } from "react";
24
28
  import { useTranslations } from "next-intl";
25
- function DevtoolsSidebar() {
29
+ import { getPluginNavItems } from "@nextsparkjs/registries/plugin-registry.client";
30
+ const PLUGIN_ICON_MAP = {
31
+ Puzzle,
32
+ Settings,
33
+ Star,
34
+ Code,
35
+ LayoutGrid,
36
+ Bell,
37
+ Globe,
38
+ Layers,
39
+ GitBranch,
40
+ Tag
41
+ };
42
+ function DevtoolsSidebar({ pluginItems: pluginItemsProp } = {}) {
26
43
  const pathname = usePathname();
27
44
  const [isCollapsed, setIsCollapsed] = useState(false);
28
45
  const t = useTranslations("devtools");
29
46
  const tCommon = useTranslations("common");
47
+ const pluginItems = pluginItemsProp ?? getPluginNavItems("devtools");
30
48
  const sidebarItems = [
31
49
  {
32
50
  titleKey: "nav.home",
@@ -89,6 +107,32 @@ function DevtoolsSidebar() {
89
107
  descriptionKey: "nav.scheduledActionsDescription"
90
108
  }
91
109
  ];
110
+ const renderPluginItem = (item) => {
111
+ const IconComponent = PLUGIN_ICON_MAP[item.icon ?? ""] ?? Puzzle;
112
+ const isActive = pathname === item.href || pathname.startsWith(item.href + "/");
113
+ return /* @__PURE__ */ jsxs(
114
+ Link,
115
+ {
116
+ href: item.href,
117
+ "data-cy": `devtools-plugin-nav-${item.href.split("/").pop()}`,
118
+ className: cn(
119
+ "flex items-center gap-3 px-3 py-2 rounded-lg transition-colors",
120
+ "hover:bg-accent hover:text-accent-foreground",
121
+ isActive ? "bg-violet-600 text-white dark:bg-violet-700" : "text-foreground",
122
+ isCollapsed && "justify-center"
123
+ ),
124
+ title: isCollapsed ? item.label : item.description,
125
+ children: [
126
+ /* @__PURE__ */ jsx(IconComponent, { className: "h-5 w-5 flex-shrink-0" }),
127
+ !isCollapsed && /* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
128
+ /* @__PURE__ */ jsx("div", { className: "text-sm font-medium", children: item.label }),
129
+ item.description && /* @__PURE__ */ jsx("p", { className: "text-xs opacity-80", children: item.description })
130
+ ] })
131
+ ]
132
+ },
133
+ item.href
134
+ );
135
+ };
92
136
  return /* @__PURE__ */ jsxs(
93
137
  "div",
94
138
  {
@@ -119,59 +163,73 @@ function DevtoolsSidebar() {
119
163
  }
120
164
  )
121
165
  ] }),
122
- /* @__PURE__ */ jsx("div", { className: "flex-1 p-3 space-y-2", children: sidebarItems.map((item) => {
123
- var _a;
124
- const IconComponent = item.icon;
125
- const isActive = pathname === item.href || pathname.startsWith(item.href + "/");
126
- const title = t(item.titleKey);
127
- const description = item.descriptionKey ? t(item.descriptionKey) : void 0;
128
- if (item.disabled) {
166
+ /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "p-3 space-y-1", children: [
167
+ sidebarItems.map((item) => {
168
+ var _a;
169
+ const IconComponent = item.icon;
170
+ const isActive = pathname === item.href || pathname.startsWith(item.href + "/");
171
+ const title = t(item.titleKey);
172
+ const description = item.descriptionKey ? t(item.descriptionKey) : void 0;
173
+ if (item.disabled) {
174
+ return /* @__PURE__ */ jsxs(
175
+ "div",
176
+ {
177
+ className: cn(
178
+ "flex items-center gap-3 px-3 py-2 rounded-lg text-muted-foreground cursor-not-allowed opacity-60",
179
+ isCollapsed && "justify-center"
180
+ ),
181
+ title: isCollapsed ? `${title} (${tCommon("comingSoon")})` : description,
182
+ children: [
183
+ /* @__PURE__ */ jsx(IconComponent, { className: "h-5 w-5 flex-shrink-0" }),
184
+ !isCollapsed && /* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
185
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
186
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: title }),
187
+ /* @__PURE__ */ jsx("span", { className: "text-xs bg-muted text-muted-foreground px-2 py-0.5 rounded", children: tCommon("soon") })
188
+ ] }),
189
+ description && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: description })
190
+ ] })
191
+ ]
192
+ },
193
+ item.titleKey
194
+ );
195
+ }
129
196
  return /* @__PURE__ */ jsxs(
130
- "div",
197
+ Link,
131
198
  {
199
+ href: item.href,
200
+ "data-cy": `devtools-nav-${(_a = item.titleKey.split(".").pop()) == null ? void 0 : _a.toLowerCase().replace(/\s+/g, "-")}`,
132
201
  className: cn(
133
- "flex items-center gap-3 px-3 py-2 rounded-lg text-muted-foreground cursor-not-allowed opacity-60",
202
+ "flex items-center gap-3 px-3 py-2 rounded-lg transition-colors",
203
+ "hover:bg-accent hover:text-accent-foreground",
204
+ isActive ? "bg-violet-600 text-white dark:bg-violet-700" : "text-foreground",
134
205
  isCollapsed && "justify-center"
135
206
  ),
136
- title: isCollapsed ? `${title} (${tCommon("comingSoon")})` : description,
207
+ title: isCollapsed ? title : description,
137
208
  children: [
138
209
  /* @__PURE__ */ jsx(IconComponent, { className: "h-5 w-5 flex-shrink-0" }),
139
210
  !isCollapsed && /* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
140
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
141
- /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: title }),
142
- /* @__PURE__ */ jsx("span", { className: "text-xs bg-muted text-muted-foreground px-2 py-0.5 rounded", children: tCommon("soon") })
143
- ] }),
144
- description && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: description })
211
+ /* @__PURE__ */ jsx("div", { className: "text-sm font-medium", children: title }),
212
+ description && /* @__PURE__ */ jsx("p", { className: "text-xs opacity-80", children: description })
145
213
  ] })
146
214
  ]
147
215
  },
148
216
  item.titleKey
149
217
  );
150
- }
151
- return /* @__PURE__ */ jsxs(
152
- Link,
153
- {
154
- href: item.href,
155
- "data-cy": `devtools-nav-${(_a = item.titleKey.split(".").pop()) == null ? void 0 : _a.toLowerCase().replace(/\s+/g, "-")}`,
156
- className: cn(
157
- "flex items-center gap-3 px-3 py-2 rounded-lg transition-colors",
158
- "hover:bg-accent hover:text-accent-foreground",
159
- isActive ? "bg-violet-600 text-white dark:bg-violet-700" : "text-foreground",
160
- isCollapsed && "justify-center"
161
- ),
162
- title: isCollapsed ? title : description,
163
- children: [
164
- /* @__PURE__ */ jsx(IconComponent, { className: "h-5 w-5 flex-shrink-0" }),
165
- !isCollapsed && /* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
166
- /* @__PURE__ */ jsx("div", { className: "text-sm font-medium", children: title }),
167
- description && /* @__PURE__ */ jsx("p", { className: "text-xs opacity-80", children: description })
168
- ] })
169
- ]
170
- },
171
- item.titleKey
172
- );
173
- }) }),
174
- /* @__PURE__ */ jsxs("div", { className: "p-3 border-t border-border space-y-2", children: [
218
+ }),
219
+ pluginItems.length > 0 && /* @__PURE__ */ jsxs("div", { className: "pt-3 space-y-1", children: [
220
+ !isCollapsed && /* @__PURE__ */ jsx(
221
+ "p",
222
+ {
223
+ className: "px-3 py-1 text-xs font-semibold text-muted-foreground uppercase tracking-wider",
224
+ "data-cy": "devtools-plugins-section-label",
225
+ children: "Plugins"
226
+ }
227
+ ),
228
+ isCollapsed && /* @__PURE__ */ jsx("div", { className: "my-1 border-t border-border" }),
229
+ pluginItems.map(renderPluginItem)
230
+ ] })
231
+ ] }) }),
232
+ /* @__PURE__ */ jsxs("div", { className: "p-3 border-t border-border space-y-1", children: [
175
233
  /* @__PURE__ */ jsxs(
176
234
  Link,
177
235
  {
@@ -214,7 +272,7 @@ function DevtoolsSidebar() {
214
272
  ]
215
273
  }
216
274
  ),
217
- !isCollapsed && /* @__PURE__ */ jsxs("div", { className: "mt-3 p-2 bg-violet-50 dark:bg-violet-950 border border-violet-200 dark:border-violet-800 rounded-lg", children: [
275
+ !isCollapsed && /* @__PURE__ */ jsxs("div", { className: "mt-2 p-2 bg-violet-50 dark:bg-violet-950 border border-violet-200 dark:border-violet-800 rounded-lg", children: [
218
276
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-violet-700 dark:text-violet-300", children: [
219
277
  /* @__PURE__ */ jsx(Code, { className: "h-3 w-3" }),
220
278
  /* @__PURE__ */ jsx("span", { className: "text-xs font-medium", children: t("restrictedArea") })
@@ -1,8 +1,11 @@
1
+ import type { PluginNavItem } from "../../../types/plugin";
1
2
  /**
2
3
  * Superadmin Sidebar Component
3
4
  *
4
5
  * Specialized sidebar for super admin navigation within Superadmin Panel.
5
6
  * Includes collapsible functionality and clear visual hierarchy.
6
7
  */
7
- export declare function SuperadminSidebar(): import("react/jsx-runtime").JSX.Element;
8
+ export declare function SuperadminSidebar({ pluginItems: pluginItemsProp }?: {
9
+ pluginItems?: PluginNavItem[];
10
+ }): import("react/jsx-runtime").JSX.Element;
8
11
  //# sourceMappingURL=SuperadminSidebar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SuperadminSidebar.d.ts","sourceRoot":"","sources":["../../../../src/components/superadmin/layouts/SuperadminSidebar.tsx"],"names":[],"mappings":"AA+BA;;;;;GAKG;AACH,wBAAgB,iBAAiB,4CAuMhC"}
1
+ {"version":3,"file":"SuperadminSidebar.d.ts","sourceRoot":"","sources":["../../../../src/components/superadmin/layouts/SuperadminSidebar.tsx"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAe3D;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,WAAW,EAAE,eAAe,EAAE,GAAE;IAAE,WAAW,CAAC,EAAE,aAAa,EAAE,CAAA;CAAO,2CAgPzG"}
@@ -13,15 +13,38 @@ import {
13
13
  ChevronLeft,
14
14
  ChevronRight,
15
15
  CreditCard,
16
- FileText
16
+ FileText,
17
+ Puzzle,
18
+ Star,
19
+ Bell,
20
+ Globe,
21
+ Layers,
22
+ GitBranch,
23
+ LayoutGrid,
24
+ Tag,
25
+ Code
17
26
  } from "lucide-react";
18
27
  import { cn } from "../../../lib/utils/index.js";
19
28
  import { Button } from "../../ui/button.js";
20
29
  import { sel } from "../../../lib/test/index.js";
21
30
  import { useState } from "react";
22
- function SuperadminSidebar() {
31
+ import { getPluginNavItems } from "@nextsparkjs/registries/plugin-registry.client";
32
+ const PLUGIN_ICON_MAP = {
33
+ Puzzle,
34
+ Settings,
35
+ Star,
36
+ Code,
37
+ LayoutGrid,
38
+ Bell,
39
+ Globe,
40
+ Layers,
41
+ GitBranch,
42
+ Tag
43
+ };
44
+ function SuperadminSidebar({ pluginItems: pluginItemsProp } = {}) {
23
45
  const pathname = usePathname();
24
46
  const [isCollapsed, setIsCollapsed] = useState(false);
47
+ const pluginItems = pluginItemsProp ?? getPluginNavItems("superadmin");
25
48
  const sidebarItems = [
26
49
  {
27
50
  title: "Dashboard",
@@ -155,6 +178,36 @@ function SuperadminSidebar() {
155
178
  item.title
156
179
  );
157
180
  }) }),
181
+ pluginItems.length > 0 && /* @__PURE__ */ jsxs("div", { className: "px-3 pb-2 space-y-1", children: [
182
+ !isCollapsed && /* @__PURE__ */ jsx("p", { className: "px-3 py-1 text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: "Plugins" }),
183
+ isCollapsed && /* @__PURE__ */ jsx("div", { className: "my-1 border-t border-border" }),
184
+ pluginItems.map((item) => {
185
+ const IconComponent = PLUGIN_ICON_MAP[item.icon ?? ""] ?? Puzzle;
186
+ const isActive = pathname === item.href || pathname.startsWith(item.href + "/");
187
+ return /* @__PURE__ */ jsxs(
188
+ Link,
189
+ {
190
+ href: item.href,
191
+ "data-cy": `superadmin-plugin-nav-${item.href.split("/").pop()}`,
192
+ className: cn(
193
+ "flex items-center gap-3 px-3 py-2 rounded-lg transition-colors",
194
+ "hover:bg-accent hover:text-accent-foreground",
195
+ isActive ? "bg-primary text-primary-foreground" : "text-foreground",
196
+ isCollapsed && "justify-center"
197
+ ),
198
+ title: isCollapsed ? item.label : item.description,
199
+ children: [
200
+ /* @__PURE__ */ jsx(IconComponent, { className: "h-5 w-5 flex-shrink-0" }),
201
+ !isCollapsed && /* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
202
+ /* @__PURE__ */ jsx("div", { className: "text-sm font-medium", children: item.label }),
203
+ item.description && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: item.description })
204
+ ] })
205
+ ]
206
+ },
207
+ item.href
208
+ );
209
+ })
210
+ ] }),
158
211
  /* @__PURE__ */ jsxs("div", { className: "p-3 border-t border-border", children: [
159
212
  /* @__PURE__ */ jsxs(
160
213
  Link,
@@ -1 +1 @@
1
- {"version":3,"file":"simple-relation-select.d.ts","sourceRoot":"","sources":["../../../src/components/ui/simple-relation-select.tsx"],"names":[],"mappings":"AAsBA,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACzB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,KAAK,IAAI,CAAA;IACnD,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,eAAe,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAEzD,YAAY,CAAC,EAAE,OAAO,CAAA;IAEtB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,wBAAgB,oBAAoB,CAAC,EACnC,KAAK,EACL,QAAQ,EACR,UAAU,EACV,UAAU,EACV,QAAgB,EAChB,WAA8B,EAC9B,QAAgB,EAChB,QAAQ,EACR,SAAS,EACT,eAAuB,EACvB,eAAoB,EACpB,YAAoB,EACpB,MAAM,GACP,EAAE,yBAAyB,2CAkmB3B"}
1
+ {"version":3,"file":"simple-relation-select.d.ts","sourceRoot":"","sources":["../../../src/components/ui/simple-relation-select.tsx"],"names":[],"mappings":"AAuBA,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACzB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,KAAK,IAAI,CAAA;IACnD,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,eAAe,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAEzD,YAAY,CAAC,EAAE,OAAO,CAAA;IAEtB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,wBAAgB,oBAAoB,CAAC,EACnC,KAAK,EACL,QAAQ,EACR,UAAU,EACV,UAAU,EACV,QAAgB,EAChB,WAA8B,EAC9B,QAAgB,EAChB,QAAQ,EACR,SAAS,EACT,eAAuB,EACvB,eAAoB,EACpB,YAAoB,EACpB,MAAM,GACP,EAAE,yBAAyB,2CAklB3B"}
@@ -5,6 +5,7 @@ import { Button } from "./button.js";
5
5
  import { Badge } from "./badge.js";
6
6
  import { X } from "lucide-react";
7
7
  import { parseChildEntity, getEntityApiPath } from "@nextsparkjs/registries/entity-registry.client";
8
+ import { fetchWithTeam } from "../../lib/api/entities.js";
8
9
  import {
9
10
  Popover,
10
11
  PopoverContent,
@@ -78,12 +79,8 @@ function SimpleRelationSelect({
78
79
  console.warn(`No specific API available for entity type: ${entityType}`);
79
80
  return [];
80
81
  }
81
- const response = await fetch(url.toString(), {
82
+ const response = await fetchWithTeam(url.toString(), {
82
83
  method: "GET",
83
- headers: {
84
- "Content-Type": "application/json",
85
- ...teamId && { "x-team-id": teamId }
86
- },
87
84
  credentials: "include"
88
85
  });
89
86
  if (response.ok) {
@@ -124,12 +121,8 @@ function SimpleRelationSelect({
124
121
  return [];
125
122
  }
126
123
  }
127
- const response = await fetch(url.toString(), {
124
+ const response = await fetchWithTeam(url.toString(), {
128
125
  method: "GET",
129
- headers: {
130
- "Content-Type": "application/json",
131
- ...teamId && { "x-team-id": teamId }
132
- },
133
126
  credentials: "include"
134
127
  });
135
128
  if (response.ok) {
@@ -198,12 +191,8 @@ function SimpleRelationSelect({
198
191
  return;
199
192
  }
200
193
  }
201
- const response = await fetch(url.toString(), {
194
+ const response = await fetchWithTeam(url.toString(), {
202
195
  method: "GET",
203
- headers: {
204
- "Content-Type": "application/json",
205
- ...teamId && { "x-team-id": teamId }
206
- },
207
196
  credentials: "include"
208
197
  });
209
198
  if (response.ok) {
@@ -269,12 +258,8 @@ function SimpleRelationSelect({
269
258
  console.warn(`No specific API available for entity type: ${entityType}`);
270
259
  return [];
271
260
  }
272
- const response = await fetch(url.toString(), {
261
+ const response = await fetchWithTeam(url.toString(), {
273
262
  method: "GET",
274
- headers: {
275
- "Content-Type": "application/json",
276
- ...teamId && { "x-team-id": teamId }
277
- },
278
263
  credentials: "include"
279
264
  });
280
265
  if (response.ok) {
@@ -4,35 +4,35 @@ import { Globe } from "lucide-react";
4
4
  import { Combobox } from "./combobox.js";
5
5
  import { cn } from "../../lib/utils/index.js";
6
6
  const timezones = [
7
- { value: "America/Argentina/Buenos_Aires", label: "Buenos Aires (GMT-3)", description: "Argentina Standard Time" },
8
- { value: "America/New_York", label: "New York (GMT-5)", description: "Eastern Standard Time" },
9
- { value: "America/Los_Angeles", label: "Los Angeles (GMT-8)", description: "Pacific Standard Time" },
10
- { value: "America/Chicago", label: "Chicago (GMT-6)", description: "Central Standard Time" },
11
- { value: "America/Denver", label: "Denver (GMT-7)", description: "Mountain Standard Time" },
12
- { value: "America/Mexico_City", label: "Mexico City (GMT-6)", description: "Central Standard Time" },
13
- { value: "America/Lima", label: "Lima (GMT-5)", description: "Peru Time" },
14
- { value: "America/Bogota", label: "Bogot\xE1 (GMT-5)", description: "Colombia Time" },
15
- { value: "America/Santiago", label: "Santiago (GMT-4)", description: "Chile Standard Time" },
16
- { value: "America/Caracas", label: "Caracas (GMT-4)", description: "Venezuela Time" },
17
- { value: "America/Sao_Paulo", label: "S\xE3o Paulo (GMT-3)", description: "Brasilia Time" },
18
- { value: "Europe/London", label: "London (GMT+0)", description: "Greenwich Mean Time" },
19
- { value: "Europe/Madrid", label: "Madrid (GMT+1)", description: "Central European Time" },
20
- { value: "Europe/Paris", label: "Paris (GMT+1)", description: "Central European Time" },
21
- { value: "Europe/Berlin", label: "Berlin (GMT+1)", description: "Central European Time" },
22
- { value: "Europe/Rome", label: "Rome (GMT+1)", description: "Central European Time" },
23
- { value: "Europe/Moscow", label: "Moscow (GMT+3)", description: "Moscow Standard Time" },
7
+ { value: "Pacific/Auckland", label: "Auckland (GMT+12)", description: "New Zealand Standard Time" },
8
+ { value: "Australia/Sydney", label: "Sydney (GMT+10)", description: "Australian Eastern Standard Time" },
9
+ { value: "Australia/Melbourne", label: "Melbourne (GMT+10)", description: "Australian Eastern Standard Time" },
24
10
  { value: "Asia/Tokyo", label: "Tokyo (GMT+9)", description: "Japan Standard Time" },
25
11
  { value: "Asia/Shanghai", label: "Shanghai (GMT+8)", description: "China Standard Time" },
26
12
  { value: "Asia/Hong_Kong", label: "Hong Kong (GMT+8)", description: "Hong Kong Time" },
27
13
  { value: "Asia/Singapore", label: "Singapore (GMT+8)", description: "Singapore Standard Time" },
28
14
  { value: "Asia/Mumbai", label: "Mumbai (GMT+5:30)", description: "India Standard Time" },
29
15
  { value: "Asia/Dubai", label: "Dubai (GMT+4)", description: "Gulf Standard Time" },
30
- { value: "Australia/Sydney", label: "Sydney (GMT+10)", description: "Australian Eastern Standard Time" },
31
- { value: "Australia/Melbourne", label: "Melbourne (GMT+10)", description: "Australian Eastern Standard Time" },
32
- { value: "Pacific/Auckland", label: "Auckland (GMT+12)", description: "New Zealand Standard Time" },
16
+ { value: "Europe/Moscow", label: "Moscow (GMT+3)", description: "Moscow Standard Time" },
33
17
  { value: "Africa/Cairo", label: "Cairo (GMT+2)", description: "Eastern European Time" },
34
18
  { value: "Africa/Johannesburg", label: "Johannesburg (GMT+2)", description: "South Africa Standard Time" },
35
- { value: "UTC", label: "UTC (GMT+0)", description: "Coordinated Universal Time" }
19
+ { value: "Europe/Berlin", label: "Berlin (GMT+1)", description: "Central European Time" },
20
+ { value: "Europe/Madrid", label: "Madrid (GMT+1)", description: "Central European Time" },
21
+ { value: "Europe/Paris", label: "Paris (GMT+1)", description: "Central European Time" },
22
+ { value: "Europe/Rome", label: "Rome (GMT+1)", description: "Central European Time" },
23
+ { value: "UTC", label: "UTC (GMT+0)", description: "Coordinated Universal Time" },
24
+ { value: "Europe/London", label: "London (GMT+0)", description: "Greenwich Mean Time" },
25
+ { value: "America/Argentina/Buenos_Aires", label: "Buenos Aires (GMT-3)", description: "Argentina Standard Time" },
26
+ { value: "America/Sao_Paulo", label: "S\xE3o Paulo (GMT-3)", description: "Brasilia Time" },
27
+ { value: "America/Caracas", label: "Caracas (GMT-4)", description: "Venezuela Time" },
28
+ { value: "America/Santiago", label: "Santiago (GMT-4)", description: "Chile Standard Time" },
29
+ { value: "America/Bogota", label: "Bogot\xE1 (GMT-5)", description: "Colombia Time" },
30
+ { value: "America/Lima", label: "Lima (GMT-5)", description: "Peru Time" },
31
+ { value: "America/New_York", label: "New York (GMT-5)", description: "Eastern Standard Time" },
32
+ { value: "America/Chicago", label: "Chicago (GMT-6)", description: "Central Standard Time" },
33
+ { value: "America/Mexico_City", label: "Mexico City (GMT-6)", description: "Central Standard Time" },
34
+ { value: "America/Denver", label: "Denver (GMT-7)", description: "Mountain Standard Time" },
35
+ { value: "America/Los_Angeles", label: "Los Angeles (GMT-8)", description: "Pacific Standard Time" }
36
36
  ];
37
37
  function TimezoneSelect({
38
38
  value,
@@ -52,7 +52,7 @@ function useAuth() {
52
52
  };
53
53
  const handleResetPassword = async (email) => {
54
54
  try {
55
- const { data, error } = await authClient.forgetPassword({
55
+ const { data, error } = await authClient.requestPasswordReset({
56
56
  email,
57
57
  redirectTo: `${origin}/reset-password`
58
58
  });