@umituz/web-dashboard 2.0.1 → 2.0.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.
Files changed (105) hide show
  1. package/dist/layouts/components/BrandLogo.js.map +1 -0
  2. package/dist/layouts/components/DashboardHeader.js.map +1 -0
  3. package/dist/layouts/components/DashboardLayout.js.map +1 -0
  4. package/dist/layouts/components/DashboardSidebar.js.map +1 -0
  5. package/dist/layouts/components/index.js.map +1 -0
  6. package/dist/layouts/hooks/dashboard.js.map +1 -0
  7. package/dist/layouts/hooks/index.js.map +1 -0
  8. package/dist/layouts/index.js.map +1 -0
  9. package/dist/layouts/theme/default.js.map +1 -0
  10. package/dist/layouts/theme/index.js.map +1 -0
  11. package/dist/layouts/theme/presets.js.map +1 -0
  12. package/dist/layouts/theme/utils.js.map +1 -0
  13. package/dist/layouts/utils/dashboard.js.map +1 -0
  14. package/dist/layouts/utils/index.js.map +1 -0
  15. package/dist/settings/components/SettingsLayout.d.ts +19 -0
  16. package/dist/settings/components/SettingsLayout.js +170 -0
  17. package/dist/settings/components/SettingsLayout.js.map +1 -0
  18. package/dist/settings/components/SettingsSection.d.ts +24 -0
  19. package/dist/settings/components/SettingsSection.js +73 -0
  20. package/dist/settings/components/SettingsSection.js.map +1 -0
  21. package/dist/settings/components/index.d.ts +5 -0
  22. package/dist/settings/components/index.js +169 -0
  23. package/dist/settings/components/index.js.map +1 -0
  24. package/dist/settings/hooks/index.d.ts +3 -0
  25. package/dist/settings/hooks/index.js +59 -0
  26. package/dist/settings/hooks/index.js.map +1 -0
  27. package/dist/settings/hooks/useSettings.d.ts +25 -0
  28. package/dist/settings/hooks/useSettings.js +59 -0
  29. package/dist/settings/hooks/useSettings.js.map +1 -0
  30. package/dist/settings/index.d.ts +7 -0
  31. package/dist/settings/index.js +259 -0
  32. package/dist/settings/index.js.map +1 -0
  33. package/dist/settings/types/index.d.ts +2 -0
  34. package/dist/settings/types/index.js +2 -0
  35. package/dist/settings/types/index.js.map +1 -0
  36. package/dist/settings/types/settings.d.ts +79 -0
  37. package/dist/settings/types/settings.js +2 -0
  38. package/dist/settings/types/settings.js.map +1 -0
  39. package/dist/settings/utils/index.d.ts +3 -0
  40. package/dist/settings/utils/index.js +39 -0
  41. package/dist/settings/utils/index.js.map +1 -0
  42. package/dist/settings/utils/settings.d.ts +50 -0
  43. package/dist/settings/utils/settings.js +39 -0
  44. package/dist/settings/utils/settings.js.map +1 -0
  45. package/package.json +25 -3
  46. package/dist/components/BrandLogo.js.map +0 -1
  47. package/dist/components/DashboardHeader.js.map +0 -1
  48. package/dist/components/DashboardLayout.js.map +0 -1
  49. package/dist/components/DashboardSidebar.js.map +0 -1
  50. package/dist/components/index.js.map +0 -1
  51. package/dist/hooks/dashboard.js.map +0 -1
  52. package/dist/hooks/index.js.map +0 -1
  53. package/dist/index.js.map +0 -1
  54. package/dist/theme/default.js.map +0 -1
  55. package/dist/theme/index.js.map +0 -1
  56. package/dist/theme/presets.js.map +0 -1
  57. package/dist/theme/utils.js.map +0 -1
  58. package/dist/utils/dashboard.js.map +0 -1
  59. package/dist/utils/index.js.map +0 -1
  60. /package/dist/{components → layouts/components}/BrandLogo.d.ts +0 -0
  61. /package/dist/{components → layouts/components}/BrandLogo.js +0 -0
  62. /package/dist/{components → layouts/components}/DashboardHeader.d.ts +0 -0
  63. /package/dist/{components → layouts/components}/DashboardHeader.js +0 -0
  64. /package/dist/{components → layouts/components}/DashboardLayout.d.ts +0 -0
  65. /package/dist/{components → layouts/components}/DashboardLayout.js +0 -0
  66. /package/dist/{components → layouts/components}/DashboardSidebar.d.ts +0 -0
  67. /package/dist/{components → layouts/components}/DashboardSidebar.js +0 -0
  68. /package/dist/{components → layouts/components}/index.d.ts +0 -0
  69. /package/dist/{components → layouts/components}/index.js +0 -0
  70. /package/dist/{hooks → layouts/hooks}/dashboard.d.ts +0 -0
  71. /package/dist/{hooks → layouts/hooks}/dashboard.js +0 -0
  72. /package/dist/{hooks → layouts/hooks}/index.d.ts +0 -0
  73. /package/dist/{hooks → layouts/hooks}/index.js +0 -0
  74. /package/dist/{index.d.ts → layouts/index.d.ts} +0 -0
  75. /package/dist/{index.js → layouts/index.js} +0 -0
  76. /package/dist/{theme → layouts/theme}/default.d.ts +0 -0
  77. /package/dist/{theme → layouts/theme}/default.js +0 -0
  78. /package/dist/{theme → layouts/theme}/index.d.ts +0 -0
  79. /package/dist/{theme → layouts/theme}/index.js +0 -0
  80. /package/dist/{theme → layouts/theme}/presets.d.ts +0 -0
  81. /package/dist/{theme → layouts/theme}/presets.js +0 -0
  82. /package/dist/{theme → layouts/theme}/utils.d.ts +0 -0
  83. /package/dist/{theme → layouts/theme}/utils.js +0 -0
  84. /package/dist/{types → layouts/types}/index.d.ts +0 -0
  85. /package/dist/{types → layouts/types}/index.js +0 -0
  86. /package/dist/{types → layouts/types}/index.js.map +0 -0
  87. /package/dist/{types → layouts/types}/layout.d.ts +0 -0
  88. /package/dist/{types → layouts/types}/layout.js +0 -0
  89. /package/dist/{types → layouts/types}/layout.js.map +0 -0
  90. /package/dist/{types → layouts/types}/notification.d.ts +0 -0
  91. /package/dist/{types → layouts/types}/notification.js +0 -0
  92. /package/dist/{types → layouts/types}/notification.js.map +0 -0
  93. /package/dist/{types → layouts/types}/sidebar.d.ts +0 -0
  94. /package/dist/{types → layouts/types}/sidebar.js +0 -0
  95. /package/dist/{types → layouts/types}/sidebar.js.map +0 -0
  96. /package/dist/{types → layouts/types}/theme.d.ts +0 -0
  97. /package/dist/{types → layouts/types}/theme.js +0 -0
  98. /package/dist/{types → layouts/types}/theme.js.map +0 -0
  99. /package/dist/{types → layouts/types}/user.d.ts +0 -0
  100. /package/dist/{types → layouts/types}/user.js +0 -0
  101. /package/dist/{types → layouts/types}/user.js.map +0 -0
  102. /package/dist/{utils → layouts/utils}/dashboard.d.ts +0 -0
  103. /package/dist/{utils → layouts/utils}/dashboard.js +0 -0
  104. /package/dist/{utils → layouts/utils}/index.d.ts +0 -0
  105. /package/dist/{utils → layouts/utils}/index.js +0 -0
@@ -0,0 +1,59 @@
1
+ "use client";
2
+
3
+ // src/domains/settings/hooks/useSettings.ts
4
+ import { useState, useCallback } from "react";
5
+ function useSettings(initialConfig) {
6
+ const [config, setConfig] = useState(initialConfig);
7
+ const updateItem = useCallback(
8
+ (sectionKey, itemKey, updates) => {
9
+ setConfig((prev) => ({
10
+ ...prev,
11
+ sections: prev.sections.map(
12
+ (section) => section.key === sectionKey ? {
13
+ ...section,
14
+ items: section.items.map(
15
+ (item) => item.key === itemKey ? { ...item, ...updates } : item
16
+ )
17
+ } : section
18
+ )
19
+ }));
20
+ },
21
+ []
22
+ );
23
+ const toggleItem = useCallback((sectionKey, itemKey) => {
24
+ setConfig((prev) => ({
25
+ ...prev,
26
+ sections: prev.sections.map(
27
+ (section) => section.key === sectionKey ? {
28
+ ...section,
29
+ items: section.items.map(
30
+ (item) => item.key === itemKey ? { ...item, enabled: item.enabled === void 0 ? true : !item.enabled } : item
31
+ )
32
+ } : section
33
+ )
34
+ }));
35
+ }, []);
36
+ const setItemBadge = useCallback((sectionKey, itemKey, badge) => {
37
+ setConfig((prev) => ({
38
+ ...prev,
39
+ sections: prev.sections.map(
40
+ (section) => section.key === sectionKey ? {
41
+ ...section,
42
+ items: section.items.map(
43
+ (item) => item.key === itemKey ? { ...item, badge } : item
44
+ )
45
+ } : section
46
+ )
47
+ }));
48
+ }, []);
49
+ return {
50
+ config,
51
+ updateItem,
52
+ toggleItem,
53
+ setItemBadge
54
+ };
55
+ }
56
+ export {
57
+ useSettings
58
+ };
59
+ //# sourceMappingURL=useSettings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/domains/settings/hooks/useSettings.ts"],"sourcesContent":["/**\n * Settings Hooks\n *\n * Custom React hooks for settings functionality\n */\n\nimport { useState, useCallback } from \"react\";\nimport type { SettingsConfig, SettingsItem } from \"../types/settings\";\n\n/**\n * Use Settings Hook\n *\n * Manages settings state and actions\n *\n * @param initialConfig - Initial settings configuration\n * @returns Settings state and actions\n */\nexport function useSettings(initialConfig: SettingsConfig) {\n const [config, setConfig] = useState<SettingsConfig>(initialConfig);\n\n const updateItem = useCallback(\n (sectionKey: string, itemKey: string, updates: Partial<SettingsItem>) => {\n setConfig((prev) => ({\n ...prev,\n sections: prev.sections.map((section) =>\n section.key === sectionKey\n ? {\n ...section,\n items: section.items.map((item) =>\n item.key === itemKey ? { ...item, ...updates } : item\n ),\n }\n : section\n ),\n }));\n },\n []\n );\n\n const toggleItem = useCallback((sectionKey: string, itemKey: string) => {\n setConfig((prev) => ({\n ...prev,\n sections: prev.sections.map((section) =>\n section.key === sectionKey\n ? {\n ...section,\n items: section.items.map((item) =>\n item.key === itemKey\n ? { ...item, enabled: item.enabled === undefined ? true : !item.enabled }\n : item\n ),\n }\n : section\n ),\n }));\n }, []);\n\n const setItemBadge = useCallback((sectionKey: string, itemKey: string, badge: number | undefined) => {\n setConfig((prev) => ({\n ...prev,\n sections: prev.sections.map((section) =>\n section.key === sectionKey\n ? {\n ...section,\n items: section.items.map((item) =>\n item.key === itemKey ? { ...item, badge } : item\n ),\n }\n : section\n ),\n }));\n }, []);\n\n return {\n config,\n updateItem,\n toggleItem,\n setItemBadge,\n };\n}\n"],"mappings":";;;AAMA,SAAS,UAAU,mBAAmB;AAW/B,SAAS,YAAY,eAA+B;AACzD,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAyB,aAAa;AAElE,QAAM,aAAa;AAAA,IACjB,CAAC,YAAoB,SAAiB,YAAmC;AACvE,gBAAU,CAAC,UAAU;AAAA,QACnB,GAAG;AAAA,QACH,UAAU,KAAK,SAAS;AAAA,UAAI,CAAC,YAC3B,QAAQ,QAAQ,aACZ;AAAA,YACE,GAAG;AAAA,YACH,OAAO,QAAQ,MAAM;AAAA,cAAI,CAAC,SACxB,KAAK,QAAQ,UAAU,EAAE,GAAG,MAAM,GAAG,QAAQ,IAAI;AAAA,YACnD;AAAA,UACF,IACA;AAAA,QACN;AAAA,MACF,EAAE;AAAA,IACJ;AAAA,IACA,CAAC;AAAA,EACH;AAEA,QAAM,aAAa,YAAY,CAAC,YAAoB,YAAoB;AACtE,cAAU,CAAC,UAAU;AAAA,MACnB,GAAG;AAAA,MACH,UAAU,KAAK,SAAS;AAAA,QAAI,CAAC,YAC3B,QAAQ,QAAQ,aACZ;AAAA,UACE,GAAG;AAAA,UACH,OAAO,QAAQ,MAAM;AAAA,YAAI,CAAC,SACxB,KAAK,QAAQ,UACT,EAAE,GAAG,MAAM,SAAS,KAAK,YAAY,SAAY,OAAO,CAAC,KAAK,QAAQ,IACtE;AAAA,UACN;AAAA,QACF,IACA;AAAA,MACN;AAAA,IACF,EAAE;AAAA,EACJ,GAAG,CAAC,CAAC;AAEL,QAAM,eAAe,YAAY,CAAC,YAAoB,SAAiB,UAA8B;AACnG,cAAU,CAAC,UAAU;AAAA,MACnB,GAAG;AAAA,MACH,UAAU,KAAK,SAAS;AAAA,QAAI,CAAC,YAC3B,QAAQ,QAAQ,aACZ;AAAA,UACE,GAAG;AAAA,UACH,OAAO,QAAQ,MAAM;AAAA,YAAI,CAAC,SACxB,KAAK,QAAQ,UAAU,EAAE,GAAG,MAAM,MAAM,IAAI;AAAA,UAC9C;AAAA,QACF,IACA;AAAA,MACN;AAAA,IACF,EAAE;AAAA,EACJ,GAAG,CAAC,CAAC;AAEL,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
@@ -0,0 +1,7 @@
1
+ export { SettingsLayout } from './components/SettingsLayout.js';
2
+ export { SettingsSection } from './components/SettingsSection.js';
3
+ export { useSettings } from './hooks/useSettings.js';
4
+ export { filterSettingsByPermission, findSettingsItem, findSettingsSection, generateSettingsKey, getSettingsDefaultRoute } from './utils/settings.js';
5
+ export { SettingsConfig, SettingsItem, SettingsLayoutProps, SettingsSectionProps, SettingsSection as SettingsSectionType } from './types/settings.js';
6
+ import 'react/jsx-runtime';
7
+ import 'lucide-react';
@@ -0,0 +1,259 @@
1
+ "use client";
2
+
3
+ // src/domains/settings/components/SettingsLayout.tsx
4
+ import { useState } from "react";
5
+ import { Outlet, useLocation, useNavigate } from "react-router-dom";
6
+
7
+ // src/domains/settings/components/SettingsSection.tsx
8
+ import { Link } from "react-router-dom";
9
+ import { ChevronRight } from "lucide-react";
10
+ import { cn } from "@umituz/web-design-system/utils";
11
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
12
+ var SettingsSection = ({
13
+ section,
14
+ currentPath,
15
+ onNavigate,
16
+ collapsed = false
17
+ }) => {
18
+ const filteredItems = section.items.filter((item) => item.enabled !== false);
19
+ if (filteredItems.length === 0) return null;
20
+ return /* @__PURE__ */ jsxs("div", { className: "mb-6 last:mb-0", children: [
21
+ !collapsed && /* @__PURE__ */ jsx("h3", { className: "px-2 mb-2 text-xs font-bold uppercase tracking-wider text-muted-foreground", children: section.title }),
22
+ /* @__PURE__ */ jsx("div", { className: "space-y-1", children: filteredItems.map((item) => {
23
+ const isActive = currentPath === item.path;
24
+ const itemContent = /* @__PURE__ */ jsxs(Fragment, { children: [
25
+ item.icon && /* @__PURE__ */ jsx(
26
+ item.icon,
27
+ {
28
+ className: cn(
29
+ "h-4 w-4 shrink-0",
30
+ isActive && "scale-110"
31
+ )
32
+ }
33
+ ),
34
+ !collapsed && /* @__PURE__ */ jsxs(Fragment, { children: [
35
+ /* @__PURE__ */ jsx("span", { className: "flex-1 text-left", children: item.label }),
36
+ item.badge !== void 0 && item.badge > 0 && /* @__PURE__ */ jsx("span", { className: "ml-auto flex h-5 min-w-5 items-center justify-center rounded-full bg-destructive px-1.5 text-[10px] font-bold text-destructive-foreground", children: item.badge > 99 ? "99+" : item.badge }),
37
+ item.path && /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4 text-muted-foreground" })
38
+ ] })
39
+ ] });
40
+ const itemClassName = cn(
41
+ "flex items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium transition-all duration-200 w-full",
42
+ "hover:bg-accent hover:text-accent-foreground",
43
+ isActive && "bg-accent text-accent-foreground",
44
+ collapsed ? "justify-center" : "justify-start"
45
+ );
46
+ if (item.path) {
47
+ return /* @__PURE__ */ jsx(
48
+ Link,
49
+ {
50
+ to: item.path,
51
+ onClick: () => onNavigate?.(item.path),
52
+ className: itemClassName,
53
+ title: collapsed ? item.label : void 0,
54
+ children: itemContent
55
+ },
56
+ item.key
57
+ );
58
+ }
59
+ return /* @__PURE__ */ jsx(
60
+ "button",
61
+ {
62
+ type: "button",
63
+ onClick: () => {
64
+ },
65
+ className: itemClassName,
66
+ title: collapsed ? item.label : void 0,
67
+ children: itemContent
68
+ },
69
+ item.key
70
+ );
71
+ }) })
72
+ ] });
73
+ };
74
+
75
+ // src/domains/settings/components/SettingsLayout.tsx
76
+ import { Skeleton } from "@umituz/web-design-system/atoms";
77
+ import { ChevronLeft, Menu } from "lucide-react";
78
+ import { Button } from "@umituz/web-design-system/atoms";
79
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
80
+ var SettingsLayout = ({
81
+ config
82
+ }) => {
83
+ const location = useLocation();
84
+ const navigate = useNavigate();
85
+ const [collapsed, setCollapsed] = useState(false);
86
+ const [mobileOpen, setMobileOpen] = useState(false);
87
+ const [loading, setLoading] = useState(true);
88
+ useState(() => {
89
+ setLoading(true);
90
+ const timer = setTimeout(() => setLoading(false), 200);
91
+ return () => clearTimeout(timer);
92
+ });
93
+ const handleNavigate = (path) => {
94
+ navigate(path);
95
+ setMobileOpen(false);
96
+ };
97
+ return /* @__PURE__ */ jsxs2("div", { className: "flex h-screen w-full bg-background font-sans", children: [
98
+ /* @__PURE__ */ jsxs2(
99
+ "aside",
100
+ {
101
+ className: `hidden md:flex flex-col shrink-0 border-r border-border bg-card transition-all duration-300 ${collapsed ? "w-16" : "w-64"}`,
102
+ children: [
103
+ /* @__PURE__ */ jsxs2("div", { className: "flex h-14 items-center justify-between border-b border-border px-4", children: [
104
+ !collapsed && /* @__PURE__ */ jsx2("h2", { className: "text-lg font-semibold text-foreground", children: config.brandName || "Settings" }),
105
+ /* @__PURE__ */ jsx2(
106
+ Button,
107
+ {
108
+ variant: "ghost",
109
+ size: "icon",
110
+ onClick: () => setCollapsed(!collapsed),
111
+ className: "ml-auto",
112
+ children: collapsed ? /* @__PURE__ */ jsx2(Menu, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx2(ChevronLeft, { className: "h-4 w-4" })
113
+ }
114
+ )
115
+ ] }),
116
+ /* @__PURE__ */ jsx2("nav", { className: "flex-1 overflow-y-auto p-2", children: config.sections.map((section) => /* @__PURE__ */ jsx2(
117
+ SettingsSection,
118
+ {
119
+ section,
120
+ currentPath: location.pathname,
121
+ onNavigate: handleNavigate,
122
+ collapsed
123
+ },
124
+ section.key
125
+ )) })
126
+ ]
127
+ }
128
+ ),
129
+ mobileOpen && /* @__PURE__ */ jsxs2("div", { className: "fixed inset-0 z-50 md:hidden", children: [
130
+ /* @__PURE__ */ jsx2(
131
+ "div",
132
+ {
133
+ className: "absolute inset-0 bg-background/80 backdrop-blur-sm",
134
+ onClick: () => setMobileOpen(false)
135
+ }
136
+ ),
137
+ /* @__PURE__ */ jsxs2("aside", { className: "absolute left-0 top-0 h-full w-64 border-r border-border bg-card shadow-xl", children: [
138
+ /* @__PURE__ */ jsxs2("div", { className: "flex h-14 items-center justify-between border-b border-border px-4", children: [
139
+ /* @__PURE__ */ jsx2("h2", { className: "text-lg font-semibold text-foreground", children: config.brandName || "Settings" }),
140
+ /* @__PURE__ */ jsx2(Button, { variant: "ghost", size: "icon", onClick: () => setMobileOpen(false), children: /* @__PURE__ */ jsx2(Menu, { className: "h-4 w-4" }) })
141
+ ] }),
142
+ /* @__PURE__ */ jsx2("nav", { className: "flex-1 overflow-y-auto p-2", children: config.sections.map((section) => /* @__PURE__ */ jsx2(
143
+ SettingsSection,
144
+ {
145
+ section,
146
+ currentPath: location.pathname,
147
+ onNavigate: handleNavigate
148
+ },
149
+ section.key
150
+ )) })
151
+ ] })
152
+ ] }),
153
+ /* @__PURE__ */ jsxs2("div", { className: "flex flex-1 flex-col overflow-hidden min-w-0", children: [
154
+ /* @__PURE__ */ jsx2("header", { className: "flex h-14 items-center justify-between border-b border-border bg-card/50 backdrop-blur-md px-4 shrink-0 md:hidden", children: /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-3", children: [
155
+ /* @__PURE__ */ jsx2(Button, { variant: "ghost", size: "icon", onClick: () => setMobileOpen(true), children: /* @__PURE__ */ jsx2(Menu, { className: "h-5 w-5" }) }),
156
+ /* @__PURE__ */ jsx2("h2", { className: "text-sm font-semibold text-foreground", children: config.brandName || "Settings" })
157
+ ] }) }),
158
+ /* @__PURE__ */ jsx2("main", { className: "flex-1 overflow-y-auto p-4 md:p-8", children: loading ? /* @__PURE__ */ jsxs2("div", { className: "mx-auto w-full max-w-4xl space-y-6", children: [
159
+ /* @__PURE__ */ jsx2(Skeleton, { className: "h-8 w-1/3 rounded-xl" }),
160
+ /* @__PURE__ */ jsx2("div", { className: "grid gap-4", children: Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ jsx2(Skeleton, { className: "h-24 rounded-xl" }, i)) })
161
+ ] }) : /* @__PURE__ */ jsx2(Outlet, {}) })
162
+ ] })
163
+ ] });
164
+ };
165
+
166
+ // src/domains/settings/hooks/useSettings.ts
167
+ import { useState as useState2, useCallback } from "react";
168
+ function useSettings(initialConfig) {
169
+ const [config, setConfig] = useState2(initialConfig);
170
+ const updateItem = useCallback(
171
+ (sectionKey, itemKey, updates) => {
172
+ setConfig((prev) => ({
173
+ ...prev,
174
+ sections: prev.sections.map(
175
+ (section) => section.key === sectionKey ? {
176
+ ...section,
177
+ items: section.items.map(
178
+ (item) => item.key === itemKey ? { ...item, ...updates } : item
179
+ )
180
+ } : section
181
+ )
182
+ }));
183
+ },
184
+ []
185
+ );
186
+ const toggleItem = useCallback((sectionKey, itemKey) => {
187
+ setConfig((prev) => ({
188
+ ...prev,
189
+ sections: prev.sections.map(
190
+ (section) => section.key === sectionKey ? {
191
+ ...section,
192
+ items: section.items.map(
193
+ (item) => item.key === itemKey ? { ...item, enabled: item.enabled === void 0 ? true : !item.enabled } : item
194
+ )
195
+ } : section
196
+ )
197
+ }));
198
+ }, []);
199
+ const setItemBadge = useCallback((sectionKey, itemKey, badge) => {
200
+ setConfig((prev) => ({
201
+ ...prev,
202
+ sections: prev.sections.map(
203
+ (section) => section.key === sectionKey ? {
204
+ ...section,
205
+ items: section.items.map(
206
+ (item) => item.key === itemKey ? { ...item, badge } : item
207
+ )
208
+ } : section
209
+ )
210
+ }));
211
+ }, []);
212
+ return {
213
+ config,
214
+ updateItem,
215
+ toggleItem,
216
+ setItemBadge
217
+ };
218
+ }
219
+
220
+ // src/domains/settings/utils/settings.ts
221
+ function findSettingsItem(config, itemKey) {
222
+ for (const section of config.sections) {
223
+ const item = section.items.find((i) => i.key === itemKey);
224
+ if (item) return item;
225
+ }
226
+ return void 0;
227
+ }
228
+ function findSettingsSection(config, sectionKey) {
229
+ return config.sections.find((s) => s.key === sectionKey);
230
+ }
231
+ function filterSettingsByPermission(items, userPermissions) {
232
+ if (!userPermissions) return items.filter((item) => item.permission === void 0);
233
+ return items.filter((item) => {
234
+ if (item.permission === void 0) return true;
235
+ return userPermissions.includes(item.permission);
236
+ });
237
+ }
238
+ function getSettingsDefaultRoute(config) {
239
+ if (config.defaultRoute) return config.defaultRoute;
240
+ for (const section of config.sections) {
241
+ const firstEnabled = section.items.find((item) => item.enabled !== false && item.path);
242
+ if (firstEnabled?.path) return firstEnabled.path;
243
+ }
244
+ return "/settings";
245
+ }
246
+ function generateSettingsKey(prefix, identifier) {
247
+ return `${prefix}_${identifier}`;
248
+ }
249
+ export {
250
+ SettingsLayout,
251
+ SettingsSection,
252
+ filterSettingsByPermission,
253
+ findSettingsItem,
254
+ findSettingsSection,
255
+ generateSettingsKey,
256
+ getSettingsDefaultRoute,
257
+ useSettings
258
+ };
259
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/domains/settings/components/SettingsLayout.tsx","../../src/domains/settings/components/SettingsSection.tsx","../../src/domains/settings/hooks/useSettings.ts","../../src/domains/settings/utils/settings.ts"],"sourcesContent":["import { useState } from \"react\";\nimport { Outlet, useLocation, useNavigate } from \"react-router-dom\";\nimport { SettingsSection } from \"./SettingsSection\";\nimport type { SettingsConfig } from \"../types/settings\";\nimport { Skeleton } from \"@umituz/web-design-system/atoms\";\nimport { ChevronLeft, Menu } from \"lucide-react\";\nimport { Button } from \"@umituz/web-design-system/atoms\";\n\ninterface SettingsLayoutProps {\n /** Settings configuration */\n config: SettingsConfig;\n}\n\n/**\n * Settings Layout Component\n *\n * Main layout wrapper for settings pages.\n * Provides sidebar navigation and content area.\n *\n * @param props - Settings layout props\n */\nexport const SettingsLayout = ({\n config,\n}: SettingsLayoutProps) => {\n const location = useLocation();\n const navigate = useNavigate();\n const [collapsed, setCollapsed] = useState(false);\n const [mobileOpen, setMobileOpen] = useState(false);\n const [loading, setLoading] = useState(true);\n\n // Simulate loading on route change\n useState(() => {\n setLoading(true);\n const timer = setTimeout(() => setLoading(false), 200);\n return () => clearTimeout(timer);\n });\n\n const handleNavigate = (path: string) => {\n navigate(path);\n setMobileOpen(false);\n };\n\n return (\n <div className=\"flex h-screen w-full bg-background font-sans\">\n {/* Desktop Sidebar */}\n <aside\n className={`hidden md:flex flex-col shrink-0 border-r border-border bg-card transition-all duration-300 ${\n collapsed ? \"w-16\" : \"w-64\"\n }`}\n >\n <div className=\"flex h-14 items-center justify-between border-b border-border px-4\">\n {!collapsed && (\n <h2 className=\"text-lg font-semibold text-foreground\">\n {config.brandName || \"Settings\"}\n </h2>\n )}\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => setCollapsed(!collapsed)}\n className=\"ml-auto\"\n >\n {collapsed ? <Menu className=\"h-4 w-4\" /> : <ChevronLeft className=\"h-4 w-4\" />}\n </Button>\n </div>\n\n <nav className=\"flex-1 overflow-y-auto p-2\">\n {config.sections.map((section) => (\n <SettingsSection\n key={section.key}\n section={section}\n currentPath={location.pathname}\n onNavigate={handleNavigate}\n collapsed={collapsed}\n />\n ))}\n </nav>\n </aside>\n\n {/* Mobile Menu Overlay */}\n {mobileOpen && (\n <div className=\"fixed inset-0 z-50 md:hidden\">\n <div\n className=\"absolute inset-0 bg-background/80 backdrop-blur-sm\"\n onClick={() => setMobileOpen(false)}\n />\n <aside className=\"absolute left-0 top-0 h-full w-64 border-r border-border bg-card shadow-xl\">\n <div className=\"flex h-14 items-center justify-between border-b border-border px-4\">\n <h2 className=\"text-lg font-semibold text-foreground\">\n {config.brandName || \"Settings\"}\n </h2>\n <Button variant=\"ghost\" size=\"icon\" onClick={() => setMobileOpen(false)}>\n <Menu className=\"h-4 w-4\" />\n </Button>\n </div>\n\n <nav className=\"flex-1 overflow-y-auto p-2\">\n {config.sections.map((section) => (\n <SettingsSection\n key={section.key}\n section={section}\n currentPath={location.pathname}\n onNavigate={handleNavigate}\n />\n ))}\n </nav>\n </aside>\n </div>\n )}\n\n {/* Main Content Area */}\n <div className=\"flex flex-1 flex-col overflow-hidden min-w-0\">\n {/* Mobile Header */}\n <header className=\"flex h-14 items-center justify-between border-b border-border bg-card/50 backdrop-blur-md px-4 shrink-0 md:hidden\">\n <div className=\"flex items-center gap-3\">\n <Button variant=\"ghost\" size=\"icon\" onClick={() => setMobileOpen(true)}>\n <Menu className=\"h-5 w-5\" />\n </Button>\n <h2 className=\"text-sm font-semibold text-foreground\">\n {config.brandName || \"Settings\"}\n </h2>\n </div>\n </header>\n\n <main className=\"flex-1 overflow-y-auto p-4 md:p-8\">\n {loading ? (\n <div className=\"mx-auto w-full max-w-4xl space-y-6\">\n <Skeleton className=\"h-8 w-1/3 rounded-xl\" />\n <div className=\"grid gap-4\">\n {Array.from({ length: 3 }).map((_, i) => (\n <Skeleton key={i} className=\"h-24 rounded-xl\" />\n ))}\n </div>\n </div>\n ) : (\n <Outlet />\n )}\n </main>\n </div>\n </div>\n );\n};\n\nexport default SettingsLayout;\n","import { Link } from \"react-router-dom\";\nimport { ChevronRight } from \"lucide-react\";\nimport { cn } from \"@umituz/web-design-system/utils\";\nimport type { SettingsSection as SettingsSectionType } from \"../types/settings\";\n\ninterface SettingsSectionProps {\n /** Section configuration */\n section: SettingsSectionType;\n /** Current path */\n currentPath?: string;\n /** On navigate callback */\n onNavigate?: (path: string) => void;\n /** Collapsed state */\n collapsed?: boolean;\n}\n\n/**\n * Settings Section Component\n *\n * Displays a section of settings items.\n *\n * @param props - Settings section props\n */\nexport const SettingsSection = ({\n section,\n currentPath,\n onNavigate,\n collapsed = false,\n}: SettingsSectionProps) => {\n const filteredItems = section.items.filter((item) => item.enabled !== false);\n\n if (filteredItems.length === 0) return null;\n\n return (\n <div className=\"mb-6 last:mb-0\">\n {!collapsed && (\n <h3 className=\"px-2 mb-2 text-xs font-bold uppercase tracking-wider text-muted-foreground\">\n {section.title}\n </h3>\n )}\n\n <div className=\"space-y-1\">\n {filteredItems.map((item) => {\n const isActive = currentPath === item.path;\n\n const itemContent = (\n <>\n {item.icon && (\n <item.icon\n className={cn(\n \"h-4 w-4 shrink-0\",\n isActive && \"scale-110\"\n )}\n />\n )}\n {!collapsed && (\n <>\n <span className=\"flex-1 text-left\">{item.label}</span>\n {item.badge !== undefined && item.badge > 0 && (\n <span className=\"ml-auto flex h-5 min-w-5 items-center justify-center rounded-full bg-destructive px-1.5 text-[10px] font-bold text-destructive-foreground\">\n {item.badge > 99 ? \"99+\" : item.badge}\n </span>\n )}\n {item.path && <ChevronRight className=\"h-4 w-4 text-muted-foreground\" />}\n </>\n )}\n </>\n );\n\n const itemClassName = cn(\n \"flex items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium transition-all duration-200 w-full\",\n \"hover:bg-accent hover:text-accent-foreground\",\n isActive && \"bg-accent text-accent-foreground\",\n collapsed ? \"justify-center\" : \"justify-start\"\n );\n\n if (item.path) {\n return (\n <Link\n key={item.key}\n to={item.path}\n onClick={() => onNavigate?.(item.path!)}\n className={itemClassName}\n title={collapsed ? item.label : undefined}\n >\n {itemContent}\n </Link>\n );\n }\n\n return (\n <button\n key={item.key}\n type=\"button\"\n onClick={() => {}}\n className={itemClassName}\n title={collapsed ? item.label : undefined}\n >\n {itemContent}\n </button>\n );\n })}\n </div>\n </div>\n );\n};\n","/**\n * Settings Hooks\n *\n * Custom React hooks for settings functionality\n */\n\nimport { useState, useCallback } from \"react\";\nimport type { SettingsConfig, SettingsItem } from \"../types/settings\";\n\n/**\n * Use Settings Hook\n *\n * Manages settings state and actions\n *\n * @param initialConfig - Initial settings configuration\n * @returns Settings state and actions\n */\nexport function useSettings(initialConfig: SettingsConfig) {\n const [config, setConfig] = useState<SettingsConfig>(initialConfig);\n\n const updateItem = useCallback(\n (sectionKey: string, itemKey: string, updates: Partial<SettingsItem>) => {\n setConfig((prev) => ({\n ...prev,\n sections: prev.sections.map((section) =>\n section.key === sectionKey\n ? {\n ...section,\n items: section.items.map((item) =>\n item.key === itemKey ? { ...item, ...updates } : item\n ),\n }\n : section\n ),\n }));\n },\n []\n );\n\n const toggleItem = useCallback((sectionKey: string, itemKey: string) => {\n setConfig((prev) => ({\n ...prev,\n sections: prev.sections.map((section) =>\n section.key === sectionKey\n ? {\n ...section,\n items: section.items.map((item) =>\n item.key === itemKey\n ? { ...item, enabled: item.enabled === undefined ? true : !item.enabled }\n : item\n ),\n }\n : section\n ),\n }));\n }, []);\n\n const setItemBadge = useCallback((sectionKey: string, itemKey: string, badge: number | undefined) => {\n setConfig((prev) => ({\n ...prev,\n sections: prev.sections.map((section) =>\n section.key === sectionKey\n ? {\n ...section,\n items: section.items.map((item) =>\n item.key === itemKey ? { ...item, badge } : item\n ),\n }\n : section\n ),\n }));\n }, []);\n\n return {\n config,\n updateItem,\n toggleItem,\n setItemBadge,\n };\n}\n","/**\n * Settings Utilities\n *\n * Utility functions for settings operations\n */\n\nimport type { SettingsConfig, SettingsItem, SettingsSection } from \"../types/settings\";\n\n/**\n * Find settings item by key\n *\n * @param config - Settings configuration\n * @param itemKey - Item key to find\n * @returns Item or undefined\n */\nexport function findSettingsItem(config: SettingsConfig, itemKey: string): SettingsItem | undefined {\n for (const section of config.sections) {\n const item = section.items.find((i) => i.key === itemKey);\n if (item) return item;\n }\n return undefined;\n}\n\n/**\n * Find settings section by key\n *\n * @param config - Settings configuration\n * @param sectionKey - Section key to find\n * @returns Section or undefined\n */\nexport function findSettingsSection(config: SettingsConfig, sectionKey: string): SettingsSection | undefined {\n return config.sections.find((s) => s.key === sectionKey);\n}\n\n/**\n * Filter settings items by permission\n *\n * @param items - Settings items to filter\n * @param userPermissions - User permissions\n * @returns Filtered items\n */\nexport function filterSettingsByPermission<T extends SettingsItem>(\n items: T[],\n userPermissions?: string[]\n): T[] {\n if (!userPermissions) return items.filter((item) => item.permission === undefined);\n\n return items.filter((item) => {\n if (item.permission === undefined) return true;\n return userPermissions.includes(item.permission);\n });\n}\n\n/**\n * Get default route from settings config\n *\n * @param config - Settings configuration\n * @returns Default route or first available route\n */\nexport function getSettingsDefaultRoute(config: SettingsConfig): string {\n if (config.defaultRoute) return config.defaultRoute;\n\n for (const section of config.sections) {\n const firstEnabled = section.items.find((item) => item.enabled !== false && item.path);\n if (firstEnabled?.path) return firstEnabled.path;\n }\n\n return \"/settings\";\n}\n\n/**\n * Generate settings item key\n *\n * @param prefix - Key prefix\n * @param identifier - Unique identifier\n * @returns Generated key\n */\nexport function generateSettingsKey(prefix: string, identifier: string): string {\n return `${prefix}_${identifier}`;\n}\n"],"mappings":"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","names":["jsx","jsxs","useState"]}
@@ -0,0 +1,2 @@
1
+ export { SettingsConfig, SettingsItem, SettingsLayoutProps, SettingsSection, SettingsSectionProps } from './settings.js';
2
+ import 'lucide-react';
@@ -0,0 +1,2 @@
1
+ "use client";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,79 @@
1
+ import { LucideIcon } from 'lucide-react';
2
+
3
+ /**
4
+ * Settings Types
5
+ *
6
+ * Type definitions for settings system
7
+ */
8
+
9
+ /**
10
+ * Settings item configuration
11
+ */
12
+ interface SettingsItem {
13
+ /** Unique key for the setting */
14
+ key: string;
15
+ /** Display label (can be i18n key) */
16
+ label: string;
17
+ /** Description text (optional) */
18
+ description?: string;
19
+ /** Icon component */
20
+ icon?: LucideIcon;
21
+ /** Route path for this setting */
22
+ path?: string;
23
+ /** Whether this item is enabled */
24
+ enabled?: boolean;
25
+ /** Required permission to access */
26
+ permission?: string;
27
+ /** Badge count (for notifications) */
28
+ badge?: number;
29
+ }
30
+ /**
31
+ * Settings section configuration
32
+ */
33
+ interface SettingsSection {
34
+ /** Section title */
35
+ title: string;
36
+ /** Section key */
37
+ key: string;
38
+ /** Items in this section */
39
+ items: SettingsItem[];
40
+ /** Optional: Section icon */
41
+ icon?: LucideIcon;
42
+ }
43
+ /**
44
+ * Settings layout configuration
45
+ */
46
+ interface SettingsConfig {
47
+ /** Settings sections */
48
+ sections: SettingsSection[];
49
+ /** Brand name */
50
+ brandName?: string;
51
+ /** Default route */
52
+ defaultRoute?: string;
53
+ }
54
+ /**
55
+ * Settings layout props
56
+ */
57
+ interface SettingsLayoutProps {
58
+ /** Settings configuration */
59
+ config: SettingsConfig;
60
+ /** Current path */
61
+ currentPath?: string;
62
+ /** On navigate callback */
63
+ onNavigate?: (path: string) => void;
64
+ }
65
+ /**
66
+ * Settings section component props
67
+ */
68
+ interface SettingsSectionProps {
69
+ /** Section configuration */
70
+ section: SettingsSection;
71
+ /** Current path */
72
+ currentPath?: string;
73
+ /** On navigate callback */
74
+ onNavigate?: (path: string) => void;
75
+ /** Collapsed state */
76
+ collapsed?: boolean;
77
+ }
78
+
79
+ export type { SettingsConfig, SettingsItem, SettingsLayoutProps, SettingsSection, SettingsSectionProps };
@@ -0,0 +1,2 @@
1
+ "use client";
2
+ //# sourceMappingURL=settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,3 @@
1
+ export { filterSettingsByPermission, findSettingsItem, findSettingsSection, generateSettingsKey, getSettingsDefaultRoute } from './settings.js';
2
+ import '../types/settings.js';
3
+ import 'lucide-react';
@@ -0,0 +1,39 @@
1
+ "use client";
2
+
3
+ // src/domains/settings/utils/settings.ts
4
+ function findSettingsItem(config, itemKey) {
5
+ for (const section of config.sections) {
6
+ const item = section.items.find((i) => i.key === itemKey);
7
+ if (item) return item;
8
+ }
9
+ return void 0;
10
+ }
11
+ function findSettingsSection(config, sectionKey) {
12
+ return config.sections.find((s) => s.key === sectionKey);
13
+ }
14
+ function filterSettingsByPermission(items, userPermissions) {
15
+ if (!userPermissions) return items.filter((item) => item.permission === void 0);
16
+ return items.filter((item) => {
17
+ if (item.permission === void 0) return true;
18
+ return userPermissions.includes(item.permission);
19
+ });
20
+ }
21
+ function getSettingsDefaultRoute(config) {
22
+ if (config.defaultRoute) return config.defaultRoute;
23
+ for (const section of config.sections) {
24
+ const firstEnabled = section.items.find((item) => item.enabled !== false && item.path);
25
+ if (firstEnabled?.path) return firstEnabled.path;
26
+ }
27
+ return "/settings";
28
+ }
29
+ function generateSettingsKey(prefix, identifier) {
30
+ return `${prefix}_${identifier}`;
31
+ }
32
+ export {
33
+ filterSettingsByPermission,
34
+ findSettingsItem,
35
+ findSettingsSection,
36
+ generateSettingsKey,
37
+ getSettingsDefaultRoute
38
+ };
39
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/domains/settings/utils/settings.ts"],"sourcesContent":["/**\n * Settings Utilities\n *\n * Utility functions for settings operations\n */\n\nimport type { SettingsConfig, SettingsItem, SettingsSection } from \"../types/settings\";\n\n/**\n * Find settings item by key\n *\n * @param config - Settings configuration\n * @param itemKey - Item key to find\n * @returns Item or undefined\n */\nexport function findSettingsItem(config: SettingsConfig, itemKey: string): SettingsItem | undefined {\n for (const section of config.sections) {\n const item = section.items.find((i) => i.key === itemKey);\n if (item) return item;\n }\n return undefined;\n}\n\n/**\n * Find settings section by key\n *\n * @param config - Settings configuration\n * @param sectionKey - Section key to find\n * @returns Section or undefined\n */\nexport function findSettingsSection(config: SettingsConfig, sectionKey: string): SettingsSection | undefined {\n return config.sections.find((s) => s.key === sectionKey);\n}\n\n/**\n * Filter settings items by permission\n *\n * @param items - Settings items to filter\n * @param userPermissions - User permissions\n * @returns Filtered items\n */\nexport function filterSettingsByPermission<T extends SettingsItem>(\n items: T[],\n userPermissions?: string[]\n): T[] {\n if (!userPermissions) return items.filter((item) => item.permission === undefined);\n\n return items.filter((item) => {\n if (item.permission === undefined) return true;\n return userPermissions.includes(item.permission);\n });\n}\n\n/**\n * Get default route from settings config\n *\n * @param config - Settings configuration\n * @returns Default route or first available route\n */\nexport function getSettingsDefaultRoute(config: SettingsConfig): string {\n if (config.defaultRoute) return config.defaultRoute;\n\n for (const section of config.sections) {\n const firstEnabled = section.items.find((item) => item.enabled !== false && item.path);\n if (firstEnabled?.path) return firstEnabled.path;\n }\n\n return \"/settings\";\n}\n\n/**\n * Generate settings item key\n *\n * @param prefix - Key prefix\n * @param identifier - Unique identifier\n * @returns Generated key\n */\nexport function generateSettingsKey(prefix: string, identifier: string): string {\n return `${prefix}_${identifier}`;\n}\n"],"mappings":";;;AAeO,SAAS,iBAAiB,QAAwB,SAA2C;AAClG,aAAW,WAAW,OAAO,UAAU;AACrC,UAAM,OAAO,QAAQ,MAAM,KAAK,CAAC,MAAM,EAAE,QAAQ,OAAO;AACxD,QAAI,KAAM,QAAO;AAAA,EACnB;AACA,SAAO;AACT;AASO,SAAS,oBAAoB,QAAwB,YAAiD;AAC3G,SAAO,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,QAAQ,UAAU;AACzD;AASO,SAAS,2BACd,OACA,iBACK;AACL,MAAI,CAAC,gBAAiB,QAAO,MAAM,OAAO,CAAC,SAAS,KAAK,eAAe,MAAS;AAEjF,SAAO,MAAM,OAAO,CAAC,SAAS;AAC5B,QAAI,KAAK,eAAe,OAAW,QAAO;AAC1C,WAAO,gBAAgB,SAAS,KAAK,UAAU;AAAA,EACjD,CAAC;AACH;AAQO,SAAS,wBAAwB,QAAgC;AACtE,MAAI,OAAO,aAAc,QAAO,OAAO;AAEvC,aAAW,WAAW,OAAO,UAAU;AACrC,UAAM,eAAe,QAAQ,MAAM,KAAK,CAAC,SAAS,KAAK,YAAY,SAAS,KAAK,IAAI;AACrF,QAAI,cAAc,KAAM,QAAO,aAAa;AAAA,EAC9C;AAEA,SAAO;AACT;AASO,SAAS,oBAAoB,QAAgB,YAA4B;AAC9E,SAAO,GAAG,MAAM,IAAI,UAAU;AAChC;","names":[]}
@@ -0,0 +1,50 @@
1
+ import { SettingsItem, SettingsConfig, SettingsSection } from '../types/settings.js';
2
+ import 'lucide-react';
3
+
4
+ /**
5
+ * Settings Utilities
6
+ *
7
+ * Utility functions for settings operations
8
+ */
9
+
10
+ /**
11
+ * Find settings item by key
12
+ *
13
+ * @param config - Settings configuration
14
+ * @param itemKey - Item key to find
15
+ * @returns Item or undefined
16
+ */
17
+ declare function findSettingsItem(config: SettingsConfig, itemKey: string): SettingsItem | undefined;
18
+ /**
19
+ * Find settings section by key
20
+ *
21
+ * @param config - Settings configuration
22
+ * @param sectionKey - Section key to find
23
+ * @returns Section or undefined
24
+ */
25
+ declare function findSettingsSection(config: SettingsConfig, sectionKey: string): SettingsSection | undefined;
26
+ /**
27
+ * Filter settings items by permission
28
+ *
29
+ * @param items - Settings items to filter
30
+ * @param userPermissions - User permissions
31
+ * @returns Filtered items
32
+ */
33
+ declare function filterSettingsByPermission<T extends SettingsItem>(items: T[], userPermissions?: string[]): T[];
34
+ /**
35
+ * Get default route from settings config
36
+ *
37
+ * @param config - Settings configuration
38
+ * @returns Default route or first available route
39
+ */
40
+ declare function getSettingsDefaultRoute(config: SettingsConfig): string;
41
+ /**
42
+ * Generate settings item key
43
+ *
44
+ * @param prefix - Key prefix
45
+ * @param identifier - Unique identifier
46
+ * @returns Generated key
47
+ */
48
+ declare function generateSettingsKey(prefix: string, identifier: string): string;
49
+
50
+ export { filterSettingsByPermission, findSettingsItem, findSettingsSection, generateSettingsKey, getSettingsDefaultRoute };
@@ -0,0 +1,39 @@
1
+ "use client";
2
+
3
+ // src/domains/settings/utils/settings.ts
4
+ function findSettingsItem(config, itemKey) {
5
+ for (const section of config.sections) {
6
+ const item = section.items.find((i) => i.key === itemKey);
7
+ if (item) return item;
8
+ }
9
+ return void 0;
10
+ }
11
+ function findSettingsSection(config, sectionKey) {
12
+ return config.sections.find((s) => s.key === sectionKey);
13
+ }
14
+ function filterSettingsByPermission(items, userPermissions) {
15
+ if (!userPermissions) return items.filter((item) => item.permission === void 0);
16
+ return items.filter((item) => {
17
+ if (item.permission === void 0) return true;
18
+ return userPermissions.includes(item.permission);
19
+ });
20
+ }
21
+ function getSettingsDefaultRoute(config) {
22
+ if (config.defaultRoute) return config.defaultRoute;
23
+ for (const section of config.sections) {
24
+ const firstEnabled = section.items.find((item) => item.enabled !== false && item.path);
25
+ if (firstEnabled?.path) return firstEnabled.path;
26
+ }
27
+ return "/settings";
28
+ }
29
+ function generateSettingsKey(prefix, identifier) {
30
+ return `${prefix}_${identifier}`;
31
+ }
32
+ export {
33
+ filterSettingsByPermission,
34
+ findSettingsItem,
35
+ findSettingsSection,
36
+ generateSettingsKey,
37
+ getSettingsDefaultRoute
38
+ };
39
+ //# sourceMappingURL=settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/domains/settings/utils/settings.ts"],"sourcesContent":["/**\n * Settings Utilities\n *\n * Utility functions for settings operations\n */\n\nimport type { SettingsConfig, SettingsItem, SettingsSection } from \"../types/settings\";\n\n/**\n * Find settings item by key\n *\n * @param config - Settings configuration\n * @param itemKey - Item key to find\n * @returns Item or undefined\n */\nexport function findSettingsItem(config: SettingsConfig, itemKey: string): SettingsItem | undefined {\n for (const section of config.sections) {\n const item = section.items.find((i) => i.key === itemKey);\n if (item) return item;\n }\n return undefined;\n}\n\n/**\n * Find settings section by key\n *\n * @param config - Settings configuration\n * @param sectionKey - Section key to find\n * @returns Section or undefined\n */\nexport function findSettingsSection(config: SettingsConfig, sectionKey: string): SettingsSection | undefined {\n return config.sections.find((s) => s.key === sectionKey);\n}\n\n/**\n * Filter settings items by permission\n *\n * @param items - Settings items to filter\n * @param userPermissions - User permissions\n * @returns Filtered items\n */\nexport function filterSettingsByPermission<T extends SettingsItem>(\n items: T[],\n userPermissions?: string[]\n): T[] {\n if (!userPermissions) return items.filter((item) => item.permission === undefined);\n\n return items.filter((item) => {\n if (item.permission === undefined) return true;\n return userPermissions.includes(item.permission);\n });\n}\n\n/**\n * Get default route from settings config\n *\n * @param config - Settings configuration\n * @returns Default route or first available route\n */\nexport function getSettingsDefaultRoute(config: SettingsConfig): string {\n if (config.defaultRoute) return config.defaultRoute;\n\n for (const section of config.sections) {\n const firstEnabled = section.items.find((item) => item.enabled !== false && item.path);\n if (firstEnabled?.path) return firstEnabled.path;\n }\n\n return \"/settings\";\n}\n\n/**\n * Generate settings item key\n *\n * @param prefix - Key prefix\n * @param identifier - Unique identifier\n * @returns Generated key\n */\nexport function generateSettingsKey(prefix: string, identifier: string): string {\n return `${prefix}_${identifier}`;\n}\n"],"mappings":";;;AAeO,SAAS,iBAAiB,QAAwB,SAA2C;AAClG,aAAW,WAAW,OAAO,UAAU;AACrC,UAAM,OAAO,QAAQ,MAAM,KAAK,CAAC,MAAM,EAAE,QAAQ,OAAO;AACxD,QAAI,KAAM,QAAO;AAAA,EACnB;AACA,SAAO;AACT;AASO,SAAS,oBAAoB,QAAwB,YAAiD;AAC3G,SAAO,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,QAAQ,UAAU;AACzD;AASO,SAAS,2BACd,OACA,iBACK;AACL,MAAI,CAAC,gBAAiB,QAAO,MAAM,OAAO,CAAC,SAAS,KAAK,eAAe,MAAS;AAEjF,SAAO,MAAM,OAAO,CAAC,SAAS;AAC5B,QAAI,KAAK,eAAe,OAAW,QAAO;AAC1C,WAAO,gBAAgB,SAAS,KAAK,UAAU;AAAA,EACjD,CAAC;AACH;AAQO,SAAS,wBAAwB,QAAgC;AACtE,MAAI,OAAO,aAAc,QAAO,OAAO;AAEvC,aAAW,WAAW,OAAO,UAAU;AACrC,UAAM,eAAe,QAAQ,MAAM,KAAK,CAAC,SAAS,KAAK,YAAY,SAAS,KAAK,IAAI;AACrF,QAAI,cAAc,KAAM,QAAO,aAAa;AAAA,EAC9C;AAEA,SAAO;AACT;AASO,SAAS,oBAAoB,QAAgB,YAA4B;AAC9E,SAAO,GAAG,MAAM,IAAI,UAAU;AAChC;","names":[]}