@carlonicora/nextjs-jsonapi 1.0.4 → 1.0.5

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 (282) hide show
  1. package/dist/{AbstractService-BKlpJA61.d.mts → AbstractService-B2n_JdiC.d.mts} +1 -1
  2. package/dist/{AbstractService-D9eSVKNa.d.ts → AbstractService-DtQTYovo.d.ts} +1 -1
  3. package/dist/{content.interface-Dg2lt_An.d.mts → AuthComponent-CPLvEerw.d.mts} +11 -15
  4. package/dist/{content.interface-BhyAiOFq.d.ts → AuthComponent-m6Qp4Hz6.d.ts} +11 -15
  5. package/dist/{BlockNoteEditor-UVO3VZZE.mjs → BlockNoteEditor-BLVXQPXV.mjs} +14 -18
  6. package/dist/{BlockNoteEditor-UVO3VZZE.mjs.map → BlockNoteEditor-BLVXQPXV.mjs.map} +1 -1
  7. package/dist/{BlockNoteEditor-VFWG6LXI.js → BlockNoteEditor-ZTDHULFT.js} +15 -19
  8. package/dist/BlockNoteEditor-ZTDHULFT.js.map +1 -0
  9. package/dist/JsonApiRequest-O7BGUMFO.mjs +23 -0
  10. package/dist/JsonApiRequest-VARLNKAF.js +23 -0
  11. package/dist/JsonApiRequest-VARLNKAF.js.map +1 -0
  12. package/dist/chunk-2LM6LCJW.mjs +1 -0
  13. package/dist/chunk-3APORDYP.mjs +7783 -0
  14. package/dist/chunk-3APORDYP.mjs.map +1 -0
  15. package/dist/{chunk-TMVHSY3Y.js → chunk-5ZEADNNP.js} +36 -17
  16. package/dist/chunk-5ZEADNNP.js.map +1 -0
  17. package/dist/{chunk-ECDTZBYO.mjs → chunk-74F6BBHH.mjs} +21 -2
  18. package/dist/chunk-74F6BBHH.mjs.map +1 -0
  19. package/dist/{chunk-GYWPEPOH.mjs → chunk-7C5RAEBO.mjs} +72 -68
  20. package/dist/chunk-7C5RAEBO.mjs.map +1 -0
  21. package/dist/chunk-A5DDIABK.js +1 -0
  22. package/dist/{chunk-TEGF6ZWG.js → chunk-AGAJMJ4T.js} +47 -9
  23. package/dist/chunk-AGAJMJ4T.js.map +1 -0
  24. package/dist/{chunk-CXQOWQSY.js → chunk-AYHKQWHH.js} +15 -2
  25. package/dist/chunk-AYHKQWHH.js.map +1 -0
  26. package/dist/{chunk-I2REI7OA.js → chunk-HMHGLXWC.js} +33 -15
  27. package/dist/chunk-HMHGLXWC.js.map +1 -0
  28. package/dist/chunk-IWFGEPAA.mjs +1 -0
  29. package/dist/chunk-JC3WJK65.js +1 -0
  30. package/dist/{chunk-L6EQEAXU.mjs → chunk-PYF2U6WG.mjs} +25 -7
  31. package/dist/chunk-PYF2U6WG.mjs.map +1 -0
  32. package/dist/{chunk-YDVTFM7X.mjs → chunk-RBIVEH2K.mjs} +42 -4
  33. package/dist/chunk-RBIVEH2K.mjs.map +1 -0
  34. package/dist/{chunk-V2JJPI7N.js → chunk-RZO2LOW4.js} +237 -233
  35. package/dist/chunk-RZO2LOW4.js.map +1 -0
  36. package/dist/{chunk-X4BIHJ2B.mjs → chunk-SM63SZCP.mjs} +15 -2
  37. package/dist/chunk-SM63SZCP.mjs.map +1 -0
  38. package/dist/chunk-WEC4YMOS.js +7783 -0
  39. package/dist/chunk-WEC4YMOS.js.map +1 -0
  40. package/dist/client/index.d.mts +21 -2
  41. package/dist/client/index.d.ts +21 -2
  42. package/dist/client/index.js +18 -245
  43. package/dist/client/index.js.map +1 -1
  44. package/dist/client/index.mjs +28 -255
  45. package/dist/client/index.mjs.map +1 -1
  46. package/dist/components/index.d.mts +293 -8
  47. package/dist/components/index.d.ts +293 -8
  48. package/dist/components/index.js +78 -2323
  49. package/dist/components/index.js.map +1 -1
  50. package/dist/components/index.mjs +172 -2417
  51. package/dist/components/index.mjs.map +1 -1
  52. package/dist/{config-hXufftVS.d.ts → config-BmnK65TD.d.mts} +1 -0
  53. package/dist/{config-hXufftVS.d.mts → config-BmnK65TD.d.ts} +1 -0
  54. package/dist/config-DQeAo9Kf.d.mts +49 -0
  55. package/dist/config-DQeAo9Kf.d.ts +49 -0
  56. package/dist/contexts/index.d.mts +109 -21
  57. package/dist/contexts/index.d.ts +109 -21
  58. package/dist/contexts/index.js +39 -7
  59. package/dist/contexts/index.js.map +1 -1
  60. package/dist/contexts/index.mjs +40 -8
  61. package/dist/core/index.d.mts +3 -4
  62. package/dist/core/index.d.ts +3 -4
  63. package/dist/core/index.js +3 -7
  64. package/dist/core/index.js.map +1 -1
  65. package/dist/core/index.mjs +4 -8
  66. package/dist/{d3.link.interface-QMdB22bC.d.mts → d3.link.interface-ClC4Irqp.d.mts} +2 -1
  67. package/dist/{d3.link.interface-QMdB22bC.d.ts → d3.link.interface-ClC4Irqp.d.ts} +2 -1
  68. package/dist/features/index.d.mts +17 -86
  69. package/dist/features/index.d.ts +17 -86
  70. package/dist/features/index.js +7 -16
  71. package/dist/features/index.js.map +1 -1
  72. package/dist/features/index.mjs +10 -19
  73. package/dist/hooks/index.d.mts +18 -43
  74. package/dist/hooks/index.d.ts +18 -43
  75. package/dist/hooks/index.js +20 -7
  76. package/dist/hooks/index.js.map +1 -1
  77. package/dist/hooks/index.mjs +19 -6
  78. package/dist/index.d.mts +10 -6
  79. package/dist/index.d.ts +10 -6
  80. package/dist/index.js +13 -10
  81. package/dist/index.js.map +1 -1
  82. package/dist/index.mjs +22 -19
  83. package/dist/interfaces/index.d.mts +2 -1
  84. package/dist/interfaces/index.d.ts +2 -1
  85. package/dist/notification.interface-BBgMUdLR.d.mts +14 -0
  86. package/dist/notification.interface-gyvT-Z2F.d.ts +14 -0
  87. package/dist/permissions/index.d.mts +2 -3
  88. package/dist/permissions/index.d.ts +2 -3
  89. package/dist/server/index.d.mts +38 -18
  90. package/dist/server/index.d.ts +38 -18
  91. package/dist/server/index.js +70 -2
  92. package/dist/server/index.js.map +1 -1
  93. package/dist/server/index.mjs +68 -0
  94. package/dist/server/index.mjs.map +1 -1
  95. package/dist/types-BUAlgqqh.d.ts +39 -0
  96. package/dist/{types-DluCaP1I.d.ts → types-Bl61ob-7.d.mts} +19 -2
  97. package/dist/{types-lQVA8d_P.d.mts → types-Bl61ob-7.d.ts} +19 -2
  98. package/dist/types-iVdVY7ba.d.mts +39 -0
  99. package/dist/useSocket-Cn7fB_B1.d.mts +25 -0
  100. package/dist/useSocket-DzMKRKCA.d.ts +25 -0
  101. package/dist/user.fields-CbdObSmS.d.mts +18 -0
  102. package/dist/user.fields-CbdObSmS.d.ts +18 -0
  103. package/dist/utils/index.d.mts +1 -2
  104. package/dist/utils/index.d.ts +1 -2
  105. package/package.json +5 -3
  106. package/src/client/index.ts +13 -0
  107. package/src/components/forms/index.ts +1 -0
  108. package/src/components/index.ts +5 -0
  109. package/src/components/tables/ContentListTable.tsx +1 -0
  110. package/src/contexts/CommonContext.tsx +52 -0
  111. package/src/contexts/SharedContext.tsx +2 -0
  112. package/src/contexts/SocketContext.tsx +65 -0
  113. package/src/contexts/index.ts +6 -1
  114. package/src/features/auth/components/containers/AuthContainer.tsx +32 -0
  115. package/src/features/auth/components/containers/index.ts +1 -0
  116. package/src/features/auth/components/details/LandingComponent.tsx +39 -0
  117. package/src/features/auth/components/details/index.ts +1 -0
  118. package/src/features/auth/components/forms/AcceptInvitation.tsx +136 -0
  119. package/src/features/auth/components/forms/ActivateAccount.tsx +75 -0
  120. package/src/features/auth/components/forms/Cookies.tsx +32 -0
  121. package/src/features/auth/components/forms/ForgotPassword.tsx +108 -0
  122. package/src/features/auth/components/forms/Login.tsx +118 -0
  123. package/src/features/auth/components/forms/Logout.tsx +19 -0
  124. package/src/features/auth/components/forms/RefreshUser.tsx +39 -0
  125. package/src/features/auth/components/forms/Register.tsx +150 -0
  126. package/src/features/auth/components/forms/ResetPassword.tsx +126 -0
  127. package/src/features/auth/components/forms/index.ts +9 -0
  128. package/src/features/auth/components/index.ts +3 -0
  129. package/src/features/auth/contexts/AuthContext.tsx +77 -0
  130. package/src/features/auth/contexts/index.ts +1 -0
  131. package/src/features/auth/enums/AuthComponent.ts +9 -0
  132. package/src/features/auth/enums/index.ts +1 -0
  133. package/src/features/auth/index.ts +2 -1
  134. package/src/features/auth/utils/AuthCookies.ts +134 -0
  135. package/src/features/auth/utils/index.ts +1 -0
  136. package/src/features/company/components/containers/AdminCompanyContainer.tsx +26 -0
  137. package/src/features/company/components/containers/CompanyContainer.tsx +17 -0
  138. package/src/features/company/components/containers/index.ts +2 -0
  139. package/src/features/company/components/details/CompanyDetails.tsx +26 -0
  140. package/src/features/company/components/details/index.ts +1 -0
  141. package/src/features/company/components/forms/CompanyConfigurationEditor.tsx +151 -0
  142. package/src/features/company/components/forms/CompanyConfigurationSecurityForm.tsx +97 -0
  143. package/src/features/company/components/forms/CompanyDeleter.tsx +121 -0
  144. package/src/features/company/components/forms/CompanyEditor.tsx +245 -0
  145. package/src/features/company/components/forms/CompanyLicense.tsx +213 -0
  146. package/src/features/company/components/forms/index.ts +5 -0
  147. package/src/features/company/components/index.ts +4 -0
  148. package/src/features/company/components/lists/CompaniesList.tsx +31 -0
  149. package/src/features/company/components/lists/index.ts +1 -0
  150. package/src/features/company/contexts/CompanyContext.tsx +99 -0
  151. package/src/features/company/contexts/index.ts +0 -0
  152. package/src/features/company/hooks/index.ts +1 -0
  153. package/src/features/company/hooks/useCompanyTableStructure.tsx +82 -0
  154. package/src/features/feature/components/forms/FormFeatures.tsx +141 -140
  155. package/src/features/feature/components/forms/index.ts +1 -0
  156. package/src/features/feature/components/index.ts +1 -1
  157. package/src/features/feature/index.ts +1 -2
  158. package/src/features/module/index.ts +1 -1
  159. package/src/features/notification/components/common/NotificationErrorBoundary.tsx +51 -0
  160. package/src/features/notification/components/common/index.ts +1 -0
  161. package/src/features/notification/components/containers/NotificationsListContainer.tsx +44 -0
  162. package/src/features/notification/components/containers/index.ts +1 -0
  163. package/src/features/notification/components/index.ts +5 -0
  164. package/src/features/notification/components/lists/NotificationsList.tsx +129 -0
  165. package/src/features/notification/components/lists/index.ts +1 -0
  166. package/src/features/notification/components/modals/NotificationModal.tsx +220 -0
  167. package/src/features/notification/components/modals/index.ts +1 -0
  168. package/src/features/notification/components/notifications/Notification.tsx +120 -0
  169. package/src/features/notification/components/notifications/PushNotificationProvider.tsx +9 -0
  170. package/src/features/notification/components/notifications/index.ts +2 -0
  171. package/src/features/notification/contexts/NotificationContext.tsx +187 -0
  172. package/src/features/notification/contexts/index.ts +1 -0
  173. package/src/features/notification/index.ts +1 -1
  174. package/src/features/push/index.ts +1 -1
  175. package/src/features/role/components/containers/RoleContainer.tsx +18 -0
  176. package/src/features/role/components/containers/index.ts +1 -0
  177. package/src/features/role/components/details/RoleDetails.tsx +21 -0
  178. package/src/features/role/components/details/index.ts +1 -0
  179. package/src/features/role/components/forms/FormRoles.tsx +82 -0
  180. package/src/features/role/components/forms/RemoveUserFromRole.tsx +108 -0
  181. package/src/features/role/components/forms/UserRoleAdd.tsx +128 -0
  182. package/src/features/role/components/forms/index.ts +3 -0
  183. package/src/features/role/components/index.ts +4 -0
  184. package/src/features/role/components/lists/RolesList.tsx +27 -0
  185. package/src/features/role/components/lists/UserRolesList.tsx +31 -0
  186. package/src/features/role/components/lists/index.ts +2 -0
  187. package/src/features/role/contexts/RoleContext.tsx +84 -0
  188. package/src/features/role/contexts/index.ts +1 -0
  189. package/src/features/role/hooks/index.ts +1 -0
  190. package/src/features/role/hooks/useRoleTableStructure.tsx +72 -0
  191. package/src/features/s3/index.ts +1 -1
  192. package/src/features/user/components/containers/UserContainer.tsx +23 -0
  193. package/src/features/user/components/containers/UserIndexContainer.tsx +12 -0
  194. package/src/features/user/components/containers/UsersListContainer.tsx +36 -0
  195. package/src/features/user/components/containers/index.ts +3 -0
  196. package/src/features/user/components/details/UserDetails.tsx +74 -0
  197. package/src/features/user/components/details/UserIndexDetails.tsx +28 -0
  198. package/src/features/user/components/details/index.ts +2 -0
  199. package/src/features/user/components/forms/RoleUserAdd.tsx +93 -0
  200. package/src/features/user/components/forms/UserAvatarEditor.tsx +78 -0
  201. package/src/features/user/components/forms/UserDeleter.tsx +49 -0
  202. package/src/features/user/components/forms/UserEditor.tsx +319 -0
  203. package/src/features/user/components/forms/UserMultiSelect.tsx +218 -0
  204. package/src/features/user/components/forms/UserReactivator.tsx +79 -0
  205. package/src/features/user/components/forms/UserResentInvitationEmail.tsx +88 -0
  206. package/src/features/user/components/forms/UserSelector.tsx +185 -0
  207. package/src/features/user/components/forms/index.ts +8 -0
  208. package/src/features/user/components/index.ts +3 -0
  209. package/src/features/user/components/lists/AdminUsersList.tsx +41 -0
  210. package/src/features/user/components/lists/CompanyUsersList.tsx +44 -0
  211. package/src/features/user/components/lists/RelevantUsersList.tsx +30 -0
  212. package/src/features/user/components/lists/RoleUsersList.tsx +31 -0
  213. package/src/features/user/components/lists/UserListInAdd.tsx +53 -0
  214. package/src/features/user/components/lists/UsersList.tsx +30 -0
  215. package/src/features/user/components/lists/UsersListByContentIds.tsx +30 -0
  216. package/src/features/user/components/lists/index.ts +7 -0
  217. package/src/features/user/components/widgets/UserAvatarList.tsx +31 -0
  218. package/src/features/user/components/widgets/UserSearchPopover.tsx +89 -0
  219. package/src/features/user/contexts/UserContext.tsx +106 -0
  220. package/src/features/user/contexts/index.ts +1 -0
  221. package/src/features/user/hooks/index.ts +2 -0
  222. package/src/features/user/hooks/useUserSearch.ts +53 -0
  223. package/src/features/user/hooks/useUserTableStructure.tsx +115 -0
  224. package/src/features/user/index.ts +0 -1
  225. package/src/hooks/index.ts +4 -0
  226. package/src/hooks/useCustomD3Graph.tsx +2 -0
  227. package/src/hooks/useNotificationSync.ts +20 -0
  228. package/src/hooks/usePageTracker.ts +69 -0
  229. package/src/hooks/usePushNotifications.ts +82 -0
  230. package/src/hooks/useSocket.ts +201 -0
  231. package/src/hooks/useTableGenerator.ts +6 -2
  232. package/src/i18n/config.ts +1 -0
  233. package/src/index.ts +4 -0
  234. package/src/interfaces/d3.link.interface.ts +2 -1
  235. package/src/server/ServerSession.ts +103 -0
  236. package/src/server/index.ts +2 -1
  237. package/src/unified/JsonApiRequest.ts +23 -0
  238. package/dist/ApiRequestDataTypeInterface-CUKFDBx2.d.mts +0 -20
  239. package/dist/ApiRequestDataTypeInterface-CUKFDBx2.d.ts +0 -20
  240. package/dist/BlockNoteEditor-VFWG6LXI.js.map +0 -1
  241. package/dist/JsonApiRequest-S3ICLM7B.mjs +0 -20
  242. package/dist/JsonApiRequest-ZZLSP26T.js +0 -20
  243. package/dist/JsonApiRequest-ZZLSP26T.js.map +0 -1
  244. package/dist/chunk-366S2JCC.mjs +0 -31
  245. package/dist/chunk-366S2JCC.mjs.map +0 -1
  246. package/dist/chunk-5W6AKZE6.mjs +0 -131
  247. package/dist/chunk-5W6AKZE6.mjs.map +0 -1
  248. package/dist/chunk-A3J3AAYM.mjs +0 -97
  249. package/dist/chunk-A3J3AAYM.mjs.map +0 -1
  250. package/dist/chunk-AWONBQQP.js +0 -97
  251. package/dist/chunk-AWONBQQP.js.map +0 -1
  252. package/dist/chunk-CXQOWQSY.js.map +0 -1
  253. package/dist/chunk-DKKMWBP4.mjs +0 -1
  254. package/dist/chunk-DKKMWBP4.mjs.map +0 -1
  255. package/dist/chunk-DO2HLAZO.js +0 -48
  256. package/dist/chunk-DO2HLAZO.js.map +0 -1
  257. package/dist/chunk-DZXDB3K2.mjs +0 -17
  258. package/dist/chunk-DZXDB3K2.mjs.map +0 -1
  259. package/dist/chunk-ECDTZBYO.mjs.map +0 -1
  260. package/dist/chunk-FY4SXJGU.js +0 -806
  261. package/dist/chunk-FY4SXJGU.js.map +0 -1
  262. package/dist/chunk-GYWPEPOH.mjs.map +0 -1
  263. package/dist/chunk-H6FMOA6B.js +0 -1
  264. package/dist/chunk-H6FMOA6B.js.map +0 -1
  265. package/dist/chunk-I2REI7OA.js.map +0 -1
  266. package/dist/chunk-J4Q36PMP.js +0 -31
  267. package/dist/chunk-J4Q36PMP.js.map +0 -1
  268. package/dist/chunk-L6EQEAXU.mjs.map +0 -1
  269. package/dist/chunk-MFO27OHB.mjs +0 -48
  270. package/dist/chunk-MFO27OHB.mjs.map +0 -1
  271. package/dist/chunk-RAF7PNLG.js +0 -131
  272. package/dist/chunk-RAF7PNLG.js.map +0 -1
  273. package/dist/chunk-RUR22SVM.js +0 -17
  274. package/dist/chunk-RUR22SVM.js.map +0 -1
  275. package/dist/chunk-TEGF6ZWG.js.map +0 -1
  276. package/dist/chunk-TMVHSY3Y.js.map +0 -1
  277. package/dist/chunk-V2JJPI7N.js.map +0 -1
  278. package/dist/chunk-WWWMJZEF.mjs +0 -806
  279. package/dist/chunk-WWWMJZEF.mjs.map +0 -1
  280. package/dist/chunk-X4BIHJ2B.mjs.map +0 -1
  281. package/dist/chunk-YDVTFM7X.mjs.map +0 -1
  282. /package/dist/{JsonApiRequest-S3ICLM7B.mjs.map → JsonApiRequest-O7BGUMFO.mjs.map} +0 -0
@@ -0,0 +1,31 @@
1
+ "use client";
2
+
3
+ import { useTranslations } from "next-intl";
4
+ import { ReactNode } from "react";
5
+ import { ContentListTable } from "../../../../components";
6
+ import { Modules } from "../../../../core";
7
+ import { DataListRetriever, useDataListRetriever } from "../../../../hooks";
8
+ import { CompanyFields, CompanyInterface, CompanyService } from "../../data";
9
+ import { CompanyEditor } from "../forms/CompanyEditor";
10
+
11
+ export function CompaniesList() {
12
+ const t = useTranslations();
13
+
14
+ const data: DataListRetriever<CompanyInterface> = useDataListRetriever({
15
+ retriever: (params) => CompanyService.findMany(params),
16
+ retrieverParams: {},
17
+ module: Modules.Company,
18
+ });
19
+
20
+ const functions: ReactNode[] = [<CompanyEditor key="create-account" />];
21
+
22
+ return (
23
+ <ContentListTable
24
+ data={data}
25
+ fields={[CompanyFields.name, CompanyFields.createdAt]}
26
+ tableGeneratorType={Modules.Company}
27
+ functions={functions}
28
+ title={t(`types.companies`, { count: 2 })}
29
+ />
30
+ );
31
+ }
@@ -0,0 +1 @@
1
+ export * from "./CompaniesList";
@@ -0,0 +1,99 @@
1
+ "use client";
2
+
3
+ import { useTranslations } from "next-intl";
4
+ import { createContext, ReactNode, useContext, useState } from "react";
5
+ import { SharedProvider } from "../../../contexts";
6
+ import { JsonApiHydratedDataInterface, Modules, rehydrate } from "../../../core";
7
+ import { usePageUrlGenerator } from "../../../hooks";
8
+ import { BreadcrumbItemData } from "../../../interfaces";
9
+ import { Action } from "../../../permissions";
10
+ import { getRoleId } from "../../../roles";
11
+ import { UserInterface } from "../../user";
12
+ import { useCurrentUserContext } from "../../user/contexts";
13
+ import { CompanyConfigurationEditor, CompanyDeleter, CompanyEditor } from "../components";
14
+ import { CompanyInterface } from "../data";
15
+
16
+ interface CompanyContextType {
17
+ company: CompanyInterface | undefined;
18
+ setCompany: (value: CompanyInterface | undefined) => void;
19
+ }
20
+
21
+ const CompanyContext = createContext<CompanyContextType | undefined>(undefined);
22
+
23
+ type CompanyProviderProps = {
24
+ children: ReactNode;
25
+ dehydratedCompany?: JsonApiHydratedDataInterface;
26
+ };
27
+
28
+ const defaultContextValue: CompanyContextType = {
29
+ company: undefined,
30
+ setCompany: () => {},
31
+ };
32
+
33
+ export const CompanyProvider = ({ children, dehydratedCompany }: CompanyProviderProps) => {
34
+ const generateUrl = usePageUrlGenerator();
35
+ const t = useTranslations();
36
+ const { hasPermissionToModule, hasRole } = useCurrentUserContext<UserInterface>();
37
+
38
+ const [company, setCompany] = useState<CompanyInterface | undefined>(
39
+ dehydratedCompany ? rehydrate<CompanyInterface>(Modules.Company, dehydratedCompany) : undefined,
40
+ );
41
+
42
+ const breadcrumb = () => {
43
+ const response: BreadcrumbItemData[] = [];
44
+
45
+ if (company)
46
+ response.push({
47
+ name: company.name,
48
+ href: generateUrl({ page: Modules.Company }),
49
+ });
50
+
51
+ return response;
52
+ };
53
+
54
+ const title = () => {
55
+ const response: any = {
56
+ type: t(`types.companies`, { count: company ? 1 : 2 }),
57
+ };
58
+
59
+ if (company) response.element = company.name;
60
+
61
+ const functions: ReactNode[] = [];
62
+
63
+ if (
64
+ company &&
65
+ hasRole(getRoleId().Administrator) &&
66
+ hasPermissionToModule({ module: Modules.Company, action: Action.Delete })
67
+ )
68
+ functions.push(<CompanyDeleter key="companyDeleter" company={company} />);
69
+
70
+ if (
71
+ hasRole(getRoleId().Administrator) ||
72
+ hasPermissionToModule({ module: Modules.Company, action: Action.Update })
73
+ ) {
74
+ if (company) functions.push(<CompanyConfigurationEditor key="companyConfigurationEditor" company={company} />);
75
+ functions.push(<CompanyEditor key="companyEditor" company={company} propagateChanges={setCompany} />);
76
+ }
77
+
78
+ if (functions.length > 0) response.functions = functions;
79
+
80
+ return response;
81
+ };
82
+
83
+ return (
84
+ <SharedProvider value={{ breadcrumbs: breadcrumb(), title: title() }}>
85
+ <CompanyContext.Provider
86
+ value={{
87
+ company: company,
88
+ setCompany: setCompany,
89
+ }}
90
+ >
91
+ {children}
92
+ </CompanyContext.Provider>
93
+ </SharedProvider>
94
+ );
95
+ };
96
+
97
+ export const useCompanyContext = (): CompanyContextType => {
98
+ return useContext(CompanyContext) ?? defaultContextValue;
99
+ };
File without changes
@@ -0,0 +1 @@
1
+ export * from "./useCompanyTableStructure";
@@ -0,0 +1,82 @@
1
+ "use client";
2
+
3
+ import { ColumnDef, Row } from "@tanstack/react-table";
4
+ import { useTranslations } from "next-intl";
5
+ import { useMemo } from "react";
6
+ import { cellDate, cellId } from "../../../components";
7
+ import { Modules } from "../../../core";
8
+ import { TableContent, usePageUrlGenerator, UseTableStructureHook } from "../../../hooks";
9
+ import { getRoleId } from "../../../roles";
10
+ import { Link } from "../../../shadcnui";
11
+ import { UserInterface } from "../../user";
12
+ import { useCurrentUserContext } from "../../user/contexts";
13
+ import { CompanyFields, CompanyInterface } from "../data";
14
+
15
+ export const useCompanyTableStructure: UseTableStructureHook<CompanyInterface, CompanyFields> = (params) => {
16
+ const t = useTranslations();
17
+ const generateUrl = usePageUrlGenerator();
18
+ const { hasRole } = useCurrentUserContext<UserInterface>();
19
+
20
+ // Memoize tableData to prevent infinite re-renders
21
+ const tableData = useMemo(() => {
22
+ return params.data.map((company: CompanyInterface) => {
23
+ const entry: TableContent<CompanyInterface> = {
24
+ jsonApiData: company,
25
+ };
26
+ entry[CompanyFields.companyId] = company.id;
27
+ params.fields.forEach((field) => {
28
+ entry[field] = company[field as keyof CompanyInterface];
29
+ });
30
+ return entry;
31
+ });
32
+ }, [params.data, params.fields]);
33
+
34
+ const fieldColumnMap: Partial<Record<CompanyFields, () => any>> = {
35
+ [CompanyFields.companyId]: () =>
36
+ cellId({
37
+ name: "companyId",
38
+ checkedIds: params.checkedIds,
39
+ toggleId: params.toggleId,
40
+ }),
41
+ [CompanyFields.name]: () => ({
42
+ id: "name",
43
+ accessorKey: "name",
44
+ header: t(`foundations.user.fields.name.label`),
45
+ cell: ({ row }: { row: Row<TableContent<CompanyInterface>> }) => {
46
+ const company = row.original.jsonApiData as CompanyInterface;
47
+ return (
48
+ <Link
49
+ href={
50
+ hasRole(getRoleId().Administrator)
51
+ ? generateUrl({
52
+ page: "/administration",
53
+ id: Modules.Company.pageUrl?.substring(1),
54
+ childPage: company.id,
55
+ })
56
+ : generateUrl({ page: Modules.Company, id: company.id })
57
+ }
58
+ >
59
+ {row.getValue("name")}
60
+ </Link>
61
+ );
62
+ },
63
+ enableSorting: false,
64
+ enableHiding: false,
65
+ }),
66
+ [CompanyFields.createdAt]: () =>
67
+ cellDate({
68
+ name: "createdAt",
69
+ title: t(`generic.date.create`),
70
+ }),
71
+ };
72
+
73
+ // Memoize columns to prevent infinite re-renders
74
+ const columns = useMemo(() => {
75
+ return params.fields.map((field) => fieldColumnMap[field]?.()).filter((col) => col !== undefined) as ColumnDef<
76
+ TableContent<CompanyInterface>
77
+ >[];
78
+ }, [params.fields, fieldColumnMap, t, generateUrl, hasRole]);
79
+
80
+ // Memoize the return object to prevent infinite re-renders
81
+ return useMemo(() => ({ data: tableData, columns: columns }), [tableData, columns]);
82
+ };
@@ -1,149 +1,150 @@
1
- // "use client";
1
+ "use client";
2
2
 
3
- // import { FeatureInterface, ModuleInterface } from "@carlonicora/nextjs-jsonapi/features";
4
- // import {
5
- // Accordion,
6
- // AccordionContent,
7
- // AccordionItem,
8
- // AccordionTrigger,
9
- // Checkbox,
10
- // FormLabel,
11
- // FormMessage,
12
- // } from "@carlonicora/nextjs-jsonapi/shadcnui";
3
+ import {
4
+ Accordion,
5
+ AccordionContent,
6
+ AccordionItem,
7
+ AccordionTrigger,
8
+ Checkbox,
9
+ FormLabel,
10
+ FormMessage,
11
+ } from "../../../../shadcnui";
12
+ import { ModuleInterface } from "../../../module";
13
+ import { FeatureInterface } from "../../data";
13
14
 
14
- // type FormFeaturesProps = {
15
- // form: any;
16
- // name?: string;
17
- // features: FeatureInterface[];
18
- // featureField?: string;
19
- // moduleField?: string;
20
- // };
15
+ type FormFeaturesProps = {
16
+ form: any;
17
+ name?: string;
18
+ features: FeatureInterface[];
19
+ featureField?: string;
20
+ moduleField?: string;
21
+ };
21
22
 
22
- // export function FormFeatures({
23
- // form,
24
- // name,
25
- // features,
26
- // featureField = "featureIds",
27
- // moduleField = "moduleIds",
28
- // }: FormFeaturesProps) {
29
- // const selectedFeatures: string[] = form.watch(featureField);
30
- // const selectedModules: string[] = form.watch(moduleField);
23
+ export function FormFeatures({
24
+ form,
25
+ name,
26
+ features,
27
+ featureField = "featureIds",
28
+ moduleField = "moduleIds",
29
+ }: FormFeaturesProps) {
30
+ const selectedFeatures: string[] = form.watch(featureField);
31
+ const selectedModules: string[] = form.watch(moduleField);
31
32
 
32
- // const toggleFeature = (feature: FeatureInterface, checked: boolean) => {
33
- // let newFeatureIds = [...selectedFeatures];
34
- // let newModuleIds = [...selectedModules];
33
+ const toggleFeature = (feature: FeatureInterface, checked: boolean) => {
34
+ let newFeatureIds = [...selectedFeatures];
35
+ let newModuleIds = [...selectedModules];
35
36
 
36
- // if (checked) {
37
- // if (!newFeatureIds.includes(feature.id)) {
38
- // newFeatureIds.push(feature.id);
39
- // }
40
- // feature.modules.forEach((module) => {
41
- // if (!newModuleIds.includes(module.id)) {
42
- // newModuleIds.push(module.id);
43
- // }
44
- // });
45
- // } else {
46
- // newFeatureIds = newFeatureIds.filter((id) => id !== feature.id);
47
- // feature.modules.forEach((module) => {
48
- // newModuleIds = newModuleIds.filter((id) => id !== module.id);
49
- // });
50
- // }
51
- // form.setValue(featureField, newFeatureIds);
52
- // form.setValue(moduleField, newModuleIds);
53
- // };
37
+ if (checked) {
38
+ if (!newFeatureIds.includes(feature.id)) {
39
+ newFeatureIds.push(feature.id);
40
+ }
41
+ feature.modules.forEach((module) => {
42
+ if (!newModuleIds.includes(module.id)) {
43
+ newModuleIds.push(module.id);
44
+ }
45
+ });
46
+ } else {
47
+ newFeatureIds = newFeatureIds.filter((id) => id !== feature.id);
48
+ feature.modules.forEach((module) => {
49
+ newModuleIds = newModuleIds.filter((id) => id !== module.id);
50
+ });
51
+ }
52
+ form.setValue(featureField, newFeatureIds);
53
+ form.setValue(moduleField, newModuleIds);
54
+ };
54
55
 
55
- // const toggleModule = (feature: FeatureInterface, module: ModuleInterface, checked: boolean) => {
56
- // const modulesForFeature = feature.modules.map((m) => m.id);
57
- // let newModuleIds = [...selectedModules];
56
+ const toggleModule = (feature: FeatureInterface, module: ModuleInterface, checked: boolean) => {
57
+ const modulesForFeature = feature.modules.map((m) => m.id);
58
+ let newModuleIds = [...selectedModules];
58
59
 
59
- // if (checked) {
60
- // if (!selectedFeatures.includes(feature.id)) {
61
- // newModuleIds = newModuleIds.filter((id) => !modulesForFeature.includes(id));
62
- // newModuleIds.push(module.id);
63
- // form.setValue(featureField, [...selectedFeatures, feature.id]);
64
- // } else {
65
- // if (!newModuleIds.includes(module.id)) {
66
- // newModuleIds.push(module.id);
67
- // }
68
- // }
69
- // } else {
70
- // newModuleIds = newModuleIds.filter((id) => id !== module.id);
71
- // const remaining = feature.modules.filter((m) => newModuleIds.includes(m.id));
72
- // if (remaining.length === 0) {
73
- // form.setValue(
74
- // featureField,
75
- // selectedFeatures.filter((id) => id !== feature.id),
76
- // );
77
- // }
78
- // }
79
- // form.setValue(moduleField, newModuleIds);
80
- // };
60
+ if (checked) {
61
+ if (!selectedFeatures.includes(feature.id)) {
62
+ newModuleIds = newModuleIds.filter((id) => !modulesForFeature.includes(id));
63
+ newModuleIds.push(module.id);
64
+ form.setValue(featureField, [...selectedFeatures, feature.id]);
65
+ } else {
66
+ if (!newModuleIds.includes(module.id)) {
67
+ newModuleIds.push(module.id);
68
+ }
69
+ }
70
+ } else {
71
+ newModuleIds = newModuleIds.filter((id) => id !== module.id);
72
+ const remaining = feature.modules.filter((m) => newModuleIds.includes(m.id));
73
+ if (remaining.length === 0) {
74
+ form.setValue(
75
+ featureField,
76
+ selectedFeatures.filter((id) => id !== feature.id),
77
+ );
78
+ }
79
+ }
80
+ form.setValue(moduleField, newModuleIds);
81
+ };
81
82
 
82
- // const isFeatureChecked = (feature: FeatureInterface) =>
83
- // selectedFeatures.includes(feature.id) || feature.modules.every((module) => selectedModules.includes(module.id));
83
+ const isFeatureChecked = (feature: FeatureInterface) =>
84
+ selectedFeatures.includes(feature.id) || feature.modules.every((module) => selectedModules.includes(module.id));
84
85
 
85
- // return (
86
- // <div className="flex w-full flex-col">
87
- // {name && <h2 className="mb-5 font-semibold">{name}</h2>}
88
- // {features.map((feature) => (
89
- // <Accordion
90
- // key={feature.id}
91
- // type="single"
92
- // collapsible
93
- // // className={`w-full p-0 ${feature.modules.filter((module) => !module.isCore).length === 0 ? "border-t" : ""}`}
94
- // className={`w-full p-0`}
95
- // >
96
- // <AccordionItem value={feature.id} className="p-0">
97
- // <div
98
- // className={`flex items-center justify-between p-0 ${feature.modules.filter((module) => !module.isCore).length === 0 ? "py-4" : ""}`}
99
- // >
100
- // <div className="flex items-center" onClick={(e) => e.stopPropagation()}>
101
- // <Checkbox
102
- // id={feature.id}
103
- // checked={isFeatureChecked(feature)}
104
- // onCheckedChange={(val) => {
105
- // toggleFeature(feature, val === true);
106
- // }}
107
- // />
108
- // <FormLabel htmlFor={feature.id} className="ml-3 cursor-pointer font-normal">
109
- // {feature.name}
110
- // </FormLabel>
111
- // </div>
112
- // {feature.modules.filter((module) => !module.isCore).length > 0 && (
113
- // <AccordionTrigger asChild>
114
- // <div className="w-full"></div>
115
- // </AccordionTrigger>
116
- // )}
117
- // </div>
118
- // {feature.modules.filter((module) => !module.isCore).length > 0 && (
119
- // <AccordionContent className="pl-6">
120
- // {feature.modules
121
- // .filter((module) => !module.isCore)
122
- // .sort((a: ModuleInterface, b: ModuleInterface) => a.name.localeCompare(b.name))
123
- // .map((module: ModuleInterface) => (
124
- // <div
125
- // key={module.id}
126
- // className="flex items-center border-t py-2"
127
- // onClick={(e) => e.stopPropagation()}
128
- // >
129
- // <Checkbox
130
- // id={module.id}
131
- // checked={selectedModules.includes(module.id)}
132
- // onCheckedChange={(val) => {
133
- // toggleModule(feature, module, val === true);
134
- // }}
135
- // />
136
- // <FormLabel htmlFor={module.id} className="ml-3 cursor-pointer font-normal">
137
- // {module.name}
138
- // </FormLabel>
139
- // </div>
140
- // ))}
141
- // </AccordionContent>
142
- // )}
143
- // </AccordionItem>
144
- // </Accordion>
145
- // ))}
146
- // <FormMessage />
147
- // </div>
148
- // );
149
- // }
86
+ return (
87
+ <div className="flex w-full flex-col">
88
+ {name && <h2 className="mb-5 font-semibold">{name}</h2>}
89
+ {features.map((feature) => (
90
+ <Accordion
91
+ key={feature.id}
92
+ type="single"
93
+ collapsible
94
+ // className={`w-full p-0 ${feature.modules.filter((module) => !module.isCore).length === 0 ? "border-t" : ""}`}
95
+ className={`w-full p-0`}
96
+ >
97
+ <AccordionItem value={feature.id} className="p-0">
98
+ <div
99
+ className={`flex items-center justify-between p-0 ${feature.modules.filter((module) => !module.isCore).length === 0 ? "py-4" : ""}`}
100
+ >
101
+ <div className="flex items-center" onClick={(e) => e.stopPropagation()}>
102
+ <Checkbox
103
+ id={feature.id}
104
+ checked={isFeatureChecked(feature)}
105
+ onCheckedChange={(val) => {
106
+ toggleFeature(feature, val === true);
107
+ }}
108
+ />
109
+ <FormLabel htmlFor={feature.id} className="ml-3 cursor-pointer font-normal">
110
+ {feature.name}
111
+ </FormLabel>
112
+ </div>
113
+ {feature.modules.filter((module) => !module.isCore).length > 0 && (
114
+ <AccordionTrigger asChild>
115
+ <div className="w-full"></div>
116
+ </AccordionTrigger>
117
+ )}
118
+ </div>
119
+ {feature.modules.filter((module) => !module.isCore).length > 0 && (
120
+ <AccordionContent className="pl-6">
121
+ {feature.modules
122
+ .filter((module) => !module.isCore)
123
+ .sort((a: ModuleInterface, b: ModuleInterface) => a.name.localeCompare(b.name))
124
+ .map((module: ModuleInterface) => (
125
+ <div
126
+ key={module.id}
127
+ className="flex items-center border-t py-2"
128
+ onClick={(e) => e.stopPropagation()}
129
+ >
130
+ <Checkbox
131
+ id={module.id}
132
+ checked={selectedModules.includes(module.id)}
133
+ onCheckedChange={(val) => {
134
+ toggleModule(feature, module, val === true);
135
+ }}
136
+ />
137
+ <FormLabel htmlFor={module.id} className="ml-3 cursor-pointer font-normal">
138
+ {module.name}
139
+ </FormLabel>
140
+ </div>
141
+ ))}
142
+ </AccordionContent>
143
+ )}
144
+ </AccordionItem>
145
+ </Accordion>
146
+ ))}
147
+ <FormMessage />
148
+ </div>
149
+ );
150
+ }
@@ -0,0 +1 @@
1
+ export * from "./FormFeatures";
@@ -1 +1 @@
1
- // export * from "./forms/FormFeatures";
1
+ export * from "./forms";
@@ -1,3 +1,2 @@
1
- // export * from "./components";
2
- export * from "./data";
3
1
  export * from "./feature.module";
2
+ export * from "./data";
@@ -1,2 +1,2 @@
1
- export * from "./data";
2
1
  export * from "./module.module";
2
+ export * from "./data";
@@ -0,0 +1,51 @@
1
+ "use client";
2
+
3
+ import React, { Component, ReactNode } from "react";
4
+
5
+ interface Props {
6
+ children: ReactNode;
7
+ fallback?: ReactNode;
8
+ }
9
+
10
+ interface State {
11
+ hasError: boolean;
12
+ error?: Error;
13
+ }
14
+
15
+ export class NotificationErrorBoundary extends Component<Props, State> {
16
+ constructor(props: Props) {
17
+ super(props);
18
+ this.state = { hasError: false };
19
+ }
20
+
21
+ static getDerivedStateFromError(error: Error): State {
22
+ // Update state so the next render will show the fallback UI
23
+ return { hasError: true, error };
24
+ }
25
+
26
+ componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
27
+ console.error("🚨 [NotificationErrorBoundary] Caught error:", error, errorInfo);
28
+ }
29
+
30
+ render() {
31
+ if (this.state.hasError) {
32
+ return (
33
+ this.props.fallback || (
34
+ <div className="flex items-center justify-center p-4 text-center">
35
+ <div className="text-muted-foreground text-sm">
36
+ <p>Something went wrong with notifications.</p>
37
+ <button
38
+ onClick={() => this.setState({ hasError: false })}
39
+ className="text-primary mt-2 underline hover:no-underline"
40
+ >
41
+ Try again
42
+ </button>
43
+ </div>
44
+ </div>
45
+ )
46
+ );
47
+ }
48
+
49
+ return this.props.children;
50
+ }
51
+ }
@@ -0,0 +1 @@
1
+ export * from "./NotificationErrorBoundary";
@@ -0,0 +1,44 @@
1
+ "use client";
2
+
3
+ import { useTranslations } from "next-intl";
4
+ import { Tab, TabsContainer } from "../../../../components";
5
+ import { useNotificationContext } from "../../contexts/NotificationContext";
6
+ import { NotificationErrorBoundary } from "../common";
7
+ import { NotificationsList } from "../lists/NotificationsList";
8
+
9
+ function NotificationsListContainerContent() {
10
+ const t = useTranslations();
11
+ const { notifications, isLoading, error } = useNotificationContext();
12
+
13
+ if (error) {
14
+ return (
15
+ <div className="flex items-center justify-center p-8 text-center">
16
+ <div className="text-destructive text-sm">
17
+ <p>Error loading notifications: {error}</p>
18
+ <p className="text-muted-foreground mt-2">Please try refreshing the page.</p>
19
+ </div>
20
+ </div>
21
+ );
22
+ }
23
+
24
+ const tabs: Tab[] = [
25
+ {
26
+ label: t(`foundations.notification.inbox`),
27
+ content: <NotificationsList archived={false} />,
28
+ },
29
+ {
30
+ label: t(`foundations.notification.archived`),
31
+ content: <NotificationsList archived={true} />,
32
+ },
33
+ ];
34
+
35
+ return <TabsContainer tabs={tabs} />;
36
+ }
37
+
38
+ export function NotificationsListContainer() {
39
+ return (
40
+ <NotificationErrorBoundary>
41
+ <NotificationsListContainerContent />
42
+ </NotificationErrorBoundary>
43
+ );
44
+ }
@@ -0,0 +1 @@
1
+ export * from "./NotificationsListContainer";
@@ -0,0 +1,5 @@
1
+ export * from "./common";
2
+ export * from "./containers";
3
+ export * from "./lists";
4
+ export * from "./modals";
5
+ export * from "./notifications";