@mui-toolpad-extended-tuni/users 3.0.0

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.
package/README.md ADDED
@@ -0,0 +1,136 @@
1
+ # @mui-toolpad-extended-tuni/users
2
+
3
+ Users microservice extension for MUI Toolpad Extended TUNI. This package provides user management functionality, user authentication, user settings, and user-related components.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @mui-toolpad-extended-tuni/users
9
+ ```
10
+
11
+ **Note**: This package requires `mui-toolpad-extended-tuni@^3.0.0` as a peer dependency.
12
+
13
+ ## Peer Dependencies
14
+
15
+ - `mui-toolpad-extended-tuni@^3.0.0`
16
+ - `react@^19.0.0`
17
+ - `react-dom@^19.0.0`
18
+ - `react-router-dom@^7.0.0`
19
+ - `@mui/material@^7.0.0`
20
+ - `@mui/icons-material@^7.0.0`
21
+ - `@emotion/react@^11.0.0`
22
+ - `@emotion/styled@^11.0.0`
23
+ - `axios@^1.7.0`
24
+ - `zustand@^4.5.0`
25
+
26
+ ## Usage
27
+
28
+ ### Basic Setup
29
+
30
+ The users microservice automatically configures the UserBus when imported:
31
+
32
+ ```tsx
33
+ import { BrowserRouter } from 'react-router-dom';
34
+ import { LMSProvider, Microservices } from 'mui-toolpad-extended-tuni';
35
+ import { UserMicroservice } from '@mui-toolpad-extended-tuni/users';
36
+
37
+ function App() {
38
+ return (
39
+ <BrowserRouter>
40
+ <LMSProvider>
41
+ <Microservices>
42
+ <UserMicroservice />
43
+ {/* Other microservices */}
44
+ </Microservices>
45
+ </LMSProvider>
46
+ </BrowserRouter>
47
+ );
48
+ }
49
+ ```
50
+
51
+ ### Using User Store
52
+
53
+ ```tsx
54
+ import { useUserStore } from '@mui-toolpad-extended-tuni/users';
55
+
56
+ function MyComponent() {
57
+ const { user, users, getUser, getUsers, updateUser } = useUserStore();
58
+
59
+ useEffect(() => {
60
+ getUser();
61
+ getUsers();
62
+ }, [getUser, getUsers]);
63
+
64
+ return (
65
+ <div>
66
+ {user && <div>Welcome, {user.name}</div>}
67
+ </div>
68
+ );
69
+ }
70
+ ```
71
+
72
+ ### User Settings Component
73
+
74
+ ```tsx
75
+ import { UserSettings } from '@mui-toolpad-extended-tuni/users';
76
+
77
+ function SettingsPage() {
78
+ return <UserSettings />;
79
+ }
80
+ ```
81
+
82
+ ### User Manager
83
+
84
+ ```tsx
85
+ import { UserManager } from '@mui-toolpad-extended-tuni/users';
86
+
87
+ function App() {
88
+ return (
89
+ <>
90
+ <UserManager />
91
+ {/* Rest of your app */}
92
+ </>
93
+ );
94
+ }
95
+ ```
96
+
97
+ ## Exports
98
+
99
+ ### Components
100
+ - `UserMicroservice` - Main microservice component
101
+ - `UserManager` - User manager component (syncs navigation filters)
102
+ - `UserSettings` - User settings form component
103
+ - `UserEventPublisher` - Publishes user events to EventBus
104
+
105
+ ### Store
106
+ - `useUserStore` - Zustand store for user management
107
+
108
+ ### Configuration
109
+ - `configureUserBus` - Configures UserBus with store methods (called automatically)
110
+
111
+ ### Types
112
+ - `UserData` - User data type (re-exported from main package)
113
+ - `PlatformRole` - Platform role type (re-exported from main package)
114
+ - `navigationTypes` - Navigation types (re-exported from main package)
115
+ - `gender` - Gender type (re-exported from main package)
116
+ - `userId` - User ID type (re-exported from main package)
117
+
118
+ ## Features
119
+
120
+ - User management and CRUD operations
121
+ - User authentication and session handling
122
+ - User preferences management
123
+ - User settings UI
124
+ - UserBus integration (automatic configuration)
125
+ - User event publishing
126
+ - Course user management
127
+ - GDPR consent handling
128
+ - Data retention settings
129
+
130
+ ## UserBus Integration
131
+
132
+ This package automatically configures the UserBus from the main package when imported. The UserBus provides a centralized way for other microservices to interact with user data without direct dependencies.
133
+
134
+ ## License
135
+
136
+ MIT
@@ -0,0 +1,22 @@
1
+ /** @format */
2
+ /**
3
+ * UserSettings Component
4
+ *
5
+ * @version 3.0.0
6
+ * @breaking-changes
7
+ * - Enhanced layout with responsive design patterns
8
+ * - Added platform role management with admin-only access
9
+ * - Improved image handling with multi-size support
10
+ * - Added validation for platform roles
11
+ * - Enhanced styling consistency with theme integration
12
+ * - Removed fixed height constraints for better content flow
13
+ *
14
+ * Provides interface for:
15
+ * - Managing user profile information
16
+ * - Configuring privacy settings
17
+ * - Managing platform roles (admin only)
18
+ * - Setting data retention preferences
19
+ * - Managing notification preferences
20
+ */
21
+ declare const UserSettings: () => import("react/jsx-runtime").JSX.Element | null;
22
+ export default UserSettings;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * UserEventPublisher publishes user state changes to the UserBus.
3
+ * This component converts user store changes to user events and publishes them.
4
+ * It maintains separation by only knowing about users and the UserBus API.
5
+ */
6
+ declare const UserEventPublisher: React.FC;
7
+ export default UserEventPublisher;
@@ -0,0 +1,2 @@
1
+ /** @format */
2
+ export declare const UserManager: () => null;
@@ -0,0 +1,34 @@
1
+ import { default as React, ReactNode } from 'react';
2
+ interface UserMicroserviceProps {
3
+ children?: ReactNode;
4
+ }
5
+ /**
6
+ * UserMicroservice Component
7
+ *
8
+ * @version 1.0.0
9
+ *
10
+ * Self-contained microservice that handles all user-related functionality:
11
+ * - User lifecycle management (via UserManager)
12
+ * - User state change publishing to UserBus (via UserEventPublisher)
13
+ * - User data synchronization with navigation filters
14
+ *
15
+ * Other modules should subscribe to UserBus (via hooks like useCurrentUser, useUserActions)
16
+ * to react to user changes. Direct useUserStore access is only allowed within the Users
17
+ * module itself, in Events/UserBus for delegation, and in DevTools components.
18
+ *
19
+ * This component should be used in App.tsx, not LMSProvider.tsx, to maintain
20
+ * proper separation of concerns and avoid tight coupling.
21
+ *
22
+ * @example
23
+ * ```tsx
24
+ * <Microservices>
25
+ * <UserMicroservice />
26
+ * <CalendarMicroservice />
27
+ * <CourseMicroservice>
28
+ * <EduTest />
29
+ * </CourseMicroservice>
30
+ * </Microservices>
31
+ * ```
32
+ */
33
+ declare const UserMicroservice: React.FC<UserMicroserviceProps>;
34
+ export default UserMicroservice;
@@ -0,0 +1,6 @@
1
+ /** @format */
2
+ /**
3
+ * Configure UserBus with store methods from useUserStore.
4
+ * This should be called once when the users package is initialized.
5
+ */
6
+ export declare function configureUserBus(): void;
package/dist/index.cjs ADDED
@@ -0,0 +1,54 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const T=require("mui-toolpad-extended-tuni"),j=require("react");function Te(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var k={exports:{}},B={},x={exports:{}},Y={};/**
2
+ * @license React
3
+ * use-sync-external-store-shim.production.js
4
+ *
5
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
6
+ *
7
+ * This source code is licensed under the MIT license found in the
8
+ * LICENSE file in the root directory of this source tree.
9
+ */var se;function Re(){if(se)return Y;se=1;var t=j;function r(l,f){return l===f&&(l!==0||1/l===1/f)||l!==l&&f!==f}var n=typeof Object.is=="function"?Object.is:r,a=t.useState,s=t.useEffect,d=t.useLayoutEffect,v=t.useDebugValue;function O(l,f){var o=f(),u=a({inst:{value:o,getSnapshot:f}}),c=u[0].inst,S=u[1];return d(function(){c.value=o,c.getSnapshot=f,R(c)&&S({inst:c})},[l,o,f]),s(function(){return R(c)&&S({inst:c}),l(function(){R(c)&&S({inst:c})})},[l]),v(o),o}function R(l){var f=l.getSnapshot;l=l.value;try{var o=f();return!n(l,o)}catch{return!0}}function m(l,f){return f()}var p=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?m:O;return Y.useSyncExternalStore=t.useSyncExternalStore!==void 0?t.useSyncExternalStore:p,Y}var q={};/**
10
+ * @license React
11
+ * use-sync-external-store-shim.development.js
12
+ *
13
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
14
+ *
15
+ * This source code is licensed under the MIT license found in the
16
+ * LICENSE file in the root directory of this source tree.
17
+ */var ie;function we(){return ie||(ie=1,process.env.NODE_ENV!=="production"&&function(){function t(o,u){return o===u&&(o!==0||1/o===1/u)||o!==o&&u!==u}function r(o,u){p||s.startTransition===void 0||(p=!0,console.error("You are using an outdated, pre-release alpha of React 18 that does not support useSyncExternalStore. The use-sync-external-store shim will not work correctly. Upgrade to a newer pre-release."));var c=u();if(!l){var S=u();d(c,S)||(console.error("The result of getSnapshot should be cached to avoid an infinite loop"),l=!0)}S=v({inst:{value:c,getSnapshot:u}});var h=S[0].inst,w=S[1];return R(function(){h.value=c,h.getSnapshot=u,n(h)&&w({inst:h})},[o,c,u]),O(function(){return n(h)&&w({inst:h}),o(function(){n(h)&&w({inst:h})})},[o]),m(c),c}function n(o){var u=o.getSnapshot;o=o.value;try{var c=u();return!d(o,c)}catch{return!0}}function a(o,u){return u()}typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart=="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());var s=j,d=typeof Object.is=="function"?Object.is:t,v=s.useState,O=s.useEffect,R=s.useLayoutEffect,m=s.useDebugValue,p=!1,l=!1,f=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?a:r;q.useSyncExternalStore=s.useSyncExternalStore!==void 0?s.useSyncExternalStore:f,typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop=="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error())}()),q}var ue;function ge(){return ue||(ue=1,process.env.NODE_ENV==="production"?x.exports=Re():x.exports=we()),x.exports}/**
18
+ * @license React
19
+ * use-sync-external-store-shim/with-selector.production.js
20
+ *
21
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
22
+ *
23
+ * This source code is licensed under the MIT license found in the
24
+ * LICENSE file in the root directory of this source tree.
25
+ */var ce;function Ae(){if(ce)return B;ce=1;var t=j,r=ge();function n(m,p){return m===p&&(m!==0||1/m===1/p)||m!==m&&p!==p}var a=typeof Object.is=="function"?Object.is:n,s=r.useSyncExternalStore,d=t.useRef,v=t.useEffect,O=t.useMemo,R=t.useDebugValue;return B.useSyncExternalStoreWithSelector=function(m,p,l,f,o){var u=d(null);if(u.current===null){var c={hasValue:!1,value:null};u.current=c}else c=u.current;u=O(function(){function h(g){if(!w){if(w=!0,A=g,g=f(g),o!==void 0&&c.hasValue){var b=c.value;if(o(b,g))return C=b}return C=g}if(b=C,a(A,g))return b;var U=f(g);return o!==void 0&&o(b,U)?(A=g,b):(A=g,C=U)}var w=!1,A,C,N=l===void 0?null:l;return[function(){return h(p())},N===null?void 0:function(){return h(N())}]},[p,l,f,o]);var S=s(m,u[0],u[1]);return v(function(){c.hasValue=!0,c.value=S},[S]),R(S),S},B}var z={};/**
26
+ * @license React
27
+ * use-sync-external-store-shim/with-selector.development.js
28
+ *
29
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
30
+ *
31
+ * This source code is licensed under the MIT license found in the
32
+ * LICENSE file in the root directory of this source tree.
33
+ */var le;function Ce(){return le||(le=1,process.env.NODE_ENV!=="production"&&function(){function t(m,p){return m===p&&(m!==0||1/m===1/p)||m!==m&&p!==p}typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart=="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());var r=j,n=ge(),a=typeof Object.is=="function"?Object.is:t,s=n.useSyncExternalStore,d=r.useRef,v=r.useEffect,O=r.useMemo,R=r.useDebugValue;z.useSyncExternalStoreWithSelector=function(m,p,l,f,o){var u=d(null);if(u.current===null){var c={hasValue:!1,value:null};u.current=c}else c=u.current;u=O(function(){function h(g){if(!w){if(w=!0,A=g,g=f(g),o!==void 0&&c.hasValue){var b=c.value;if(o(b,g))return C=b}return C=g}if(b=C,a(A,g))return b;var U=f(g);return o!==void 0&&o(b,U)?(A=g,b):(A=g,C=U)}var w=!1,A,C,N=l===void 0?null:l;return[function(){return h(p())},N===null?void 0:function(){return h(N())}]},[p,l,f,o]);var S=s(m,u[0],u[1]);return v(function(){c.hasValue=!0,c.value=S},[S]),R(S),S},typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop=="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error())}()),z}var fe;function je(){return fe||(fe=1,process.env.NODE_ENV==="production"?k.exports=Ae():k.exports=Ce()),k.exports}var Ne=je();const Ue=Te(Ne),De={},de=t=>{let r;const n=new Set,a=(p,l)=>{const f=typeof p=="function"?p(r):p;if(!Object.is(f,r)){const o=r;r=l??(typeof f!="object"||f===null)?f:Object.assign({},r,f),n.forEach(u=>u(r,o))}},s=()=>r,R={setState:a,getState:s,getInitialState:()=>m,subscribe:p=>(n.add(p),()=>n.delete(p)),destroy:()=>{(De?"production":void 0)!=="production"&&console.warn("[DEPRECATED] The `destroy` method will be unsupported in a future version. Instead use unsubscribe function returned by subscribe. Everything will be garbage-collected if store is garbage-collected."),n.clear()}},m=r=t(a,s,R);return R},Le=t=>t?de(t):de,{useDebugValue:Ie}=j,{useSyncExternalStoreWithSelector:Pe}=Ue,ke=t=>t;function xe(t,r=ke,n){const a=Pe(t.subscribe,t.getState,t.getServerState||t.getInitialState,r,n);return Ie(a),a}const pe=(t,r)=>{const n=Le(t),a=(s,d=r)=>xe(n,s,d);return Object.assign(a,n),a},Ve=(t,r)=>t?pe(t,r):pe,Me=async()=>{try{const t=await T.axios.get("api/users/current/");return T.convertObjectKeysToCamelCase(t.data)}catch(t){throw console.error("Error getting current user",t),t}},me=async t=>{try{const r=await T.axios.get(`api/users/${t?`?course_id=${t}`:""}`);if(!Array.isArray(r.data))throw new Error("Invalid response data");return r.data.map(n=>T.convertObjectKeysToCamelCase(n))}catch(r){throw console.error("Error getting users",r),r}},We=async t=>{var r,n;try{if(!(t!=null&&t.id))throw new Error("Cannot update user: user.id is undefined");const a=T.convertObjectKeysToUnderscore(t),s=await T.axios.put(`api/users/${t.id}/`,a);if(!s.data)throw new Error("No data received from server");const d=T.convertObjectKeysToCamelCase(s.data);return(n=(r=t.image)==null?void 0:r.large)!=null&&n.startsWith("data:image")&&(d.image={...t.image,...d.image}),d}catch(a){throw console.error("Error updating user:",a),a}},Ge=async()=>{try{await T.axios.post("/auth/lti_logout/")}catch(t){throw console.error("Error logging out user",t),t}},H="/static/images/student.png",K="/static/images/teacher.png",X="/static/images/guest.png",Z="/static/images/admin.png",Q=[{id:"1",name:"Teacher User",email:"teacher@edu.com",image:{large:K,medium:K,thumbnail:K},privacySettings:{allowAnalytics:!1,allowPersonalization:!1,allowCommunications:!1,allowThirdPartySharing:!1},gdprConsent:{accepted:!0,acceptedDate:new Date().toISOString(),lastUpdated:new Date().toISOString()},dataRetention:{deleteAccountAfterInactivity:365,deleteDataAfterAccountDeletion:30},preferences:{navigationType:"direct",visibleCourseLists:{isStudent:!0,isStudentOld:!0,isTeacher:!0,isTeacherOld:!0,available:!0},lastVisitedCourses:[],visibleNavigation:["Courses"]},platformRoles:["creator","moderator"]},{id:"2",name:"Student User",email:"student@edu.com",image:{large:H,medium:H,thumbnail:H},privacySettings:{allowAnalytics:!1,allowPersonalization:!1,allowCommunications:!1,allowThirdPartySharing:!1},gdprConsent:{accepted:!0,acceptedDate:new Date().toISOString(),lastUpdated:new Date().toISOString()},dataRetention:{deleteAccountAfterInactivity:365,deleteDataAfterAccountDeletion:30},preferences:{navigationType:"direct",visibleCourseLists:{isStudent:!0,isStudentOld:!0,isTeacher:!0,isTeacherOld:!0,available:!0},lastVisitedCourses:[],visibleNavigation:["Courses"]},platformRoles:["user"]},{id:"3",name:"Guest User",email:"",image:{large:X,medium:X,thumbnail:X},privacySettings:{allowAnalytics:!1,allowPersonalization:!1,allowCommunications:!1,allowThirdPartySharing:!1},gdprConsent:{accepted:!0,acceptedDate:new Date().toISOString(),lastUpdated:new Date().toISOString()},dataRetention:{deleteAccountAfterInactivity:365,deleteDataAfterAccountDeletion:30},preferences:{navigationType:"direct",visibleCourseLists:{isStudent:!0,isStudentOld:!0,isTeacher:!0,isTeacherOld:!0,available:!0},lastVisitedCourses:[],visibleNavigation:["Courses"]},platformRoles:["user"]},{id:"4",name:"Admin User",email:"admin@edu.com",image:{large:Z,medium:Z,thumbnail:Z},privacySettings:{allowAnalytics:!1,allowPersonalization:!1,allowCommunications:!1,allowThirdPartySharing:!1},gdprConsent:{accepted:!0,acceptedDate:new Date().toISOString(),lastUpdated:new Date().toISOString()},dataRetention:{deleteAccountAfterInactivity:365,deleteDataAfterAccountDeletion:30},preferences:{navigationType:"direct",visibleCourseLists:{isStudent:!0,isStudentOld:!0,isTeacher:!0,isTeacherOld:!0,available:!0},lastVisitedCourses:[],visibleNavigation:["Courses"]},platformRoles:["creator","moderator"]}],Ee=Ve(t=>({fetchState:"idle",user:null,userToUpdate:null,testUsers:Q,users:[],courseUsers:[],setUserToUpdate:r=>t({userToUpdate:r}),setTestUsers:r=>t({testUsers:r}),setUser:r=>t({user:r}),getUser:async()=>{try{t({fetchState:"loading"}),t({testUsers:Q});const r=await Me();r&&t({user:{...r},fetchState:"idle",testUsers:Q.filter(n=>n.id!==r.id)})}catch(r){console.error("Error getting user",r),t({fetchState:"error"})}},getUsers:async()=>{try{t({fetchState:"loading"});const r=await me();t(r?{users:r,fetchState:"idle"}:{fetchState:"error"})}catch{t({fetchState:"error"})}},fetchCourseUsers:async r=>{try{t({fetchState:"loading"});const n=await me(r);t({courseUsers:n,fetchState:"idle"})}catch{t({fetchState:"error"})}},clearUser:()=>t({user:null}),logout:async()=>{try{return await Ge(),t({user:null}),Promise.resolve()}catch(r){return Promise.reject(r)}},updateUser:async r=>{try{t({fetchState:"loading"});const n=await We(r);return t(a=>{var d;return{fetchState:"idle",userToUpdate:n,user:((d=a.user)==null?void 0:d.id)===n.id?n:a.user}}),Promise.resolve(n)}catch(n){return console.error("Failed to update user:",n),t({fetchState:"error"}),Promise.reject(n)}}}));var V={exports:{}},L={};/**
34
+ * @license React
35
+ * react-jsx-runtime.production.js
36
+ *
37
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
38
+ *
39
+ * This source code is licensed under the MIT license found in the
40
+ * LICENSE file in the root directory of this source tree.
41
+ */var Se;function Je(){if(Se)return L;Se=1;var t=Symbol.for("react.transitional.element"),r=Symbol.for("react.fragment");function n(a,s,d){var v=null;if(d!==void 0&&(v=""+d),s.key!==void 0&&(v=""+s.key),"key"in s){d={};for(var O in s)O!=="key"&&(d[O]=s[O])}else d=s;return s=d.ref,{$$typeof:t,type:a,key:v,ref:s!==void 0?s:null,props:d}}return L.Fragment=r,L.jsx=n,L.jsxs=n,L}var I={};/**
42
+ * @license React
43
+ * react-jsx-runtime.development.js
44
+ *
45
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
46
+ *
47
+ * This source code is licensed under the MIT license found in the
48
+ * LICENSE file in the root directory of this source tree.
49
+ */var ve;function $e(){return ve||(ve=1,process.env.NODE_ENV!=="production"&&function(){function t(e){if(e==null)return null;if(typeof e=="function")return e.$$typeof===Oe?null:e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case S:return"Fragment";case w:return"Profiler";case h:return"StrictMode";case g:return"Suspense";case b:return"SuspenseList";case ye:return"Activity"}if(typeof e=="object")switch(typeof e.tag=="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),e.$$typeof){case c:return"Portal";case C:return e.displayName||"Context";case A:return(e._context.displayName||"Context")+".Consumer";case N:var i=e.render;return e=e.displayName,e||(e=i.displayName||i.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case U:return i=e.displayName||null,i!==null?i:t(e.type)||"Memo";case W:i=e._payload,e=e._init;try{return t(e(i))}catch{}}return null}function r(e){return""+e}function n(e){try{r(e);var i=!1}catch{i=!0}if(i){i=console;var _=i.error,E=typeof Symbol=="function"&&Symbol.toStringTag&&e[Symbol.toStringTag]||e.constructor.name||"Object";return _.call(i,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",E),r(e)}}function a(e){if(e===S)return"<>";if(typeof e=="object"&&e!==null&&e.$$typeof===W)return"<...>";try{var i=t(e);return i?"<"+i+">":"<...>"}catch{return"<...>"}}function s(){var e=G.A;return e===null?null:e.getOwner()}function d(){return Error("react-stack-top-frame")}function v(e){if(ee.call(e,"key")){var i=Object.getOwnPropertyDescriptor(e,"key").get;if(i&&i.isReactWarning)return!1}return e.key!==void 0}function O(e,i){function _(){te||(te=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",i))}_.isReactWarning=!0,Object.defineProperty(e,"key",{get:_,configurable:!0})}function R(){var e=t(this.type);return re[e]||(re[e]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),e=this.props.ref,e!==void 0?e:null}function m(e,i,_,E,P,$){var y=_.ref;return e={$$typeof:u,type:e,key:i,props:_,_owner:E},(y!==void 0?y:null)!==null?Object.defineProperty(e,"ref",{enumerable:!1,get:R}):Object.defineProperty(e,"ref",{enumerable:!1,value:null}),e._store={},Object.defineProperty(e._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(e,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(e,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:P}),Object.defineProperty(e,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:$}),Object.freeze&&(Object.freeze(e.props),Object.freeze(e)),e}function p(e,i,_,E,P,$){var y=i.children;if(y!==void 0)if(E)if(he(y)){for(E=0;E<y.length;E++)l(y[E]);Object.freeze&&Object.freeze(y)}else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else l(y);if(ee.call(i,"key")){y=t(e);var D=Object.keys(i).filter(function(be){return be!=="key"});E=0<D.length?"{key: someKey, "+D.join(": ..., ")+": ...}":"{key: someKey}",oe[y+E]||(D=0<D.length?"{"+D.join(": ..., ")+": ...}":"{}",console.error(`A props object containing a "key" prop is being spread into JSX:
50
+ let props = %s;
51
+ <%s {...props} />
52
+ React keys must be passed directly to JSX without using spread:
53
+ let props = %s;
54
+ <%s key={someKey} {...props} />`,E,y,D,y),oe[y+E]=!0)}if(y=null,_!==void 0&&(n(_),y=""+_),v(i)&&(n(i.key),y=""+i.key),"key"in i){_={};for(var F in i)F!=="key"&&(_[F]=i[F])}else _=i;return y&&O(_,typeof e=="function"?e.displayName||e.name||"Unknown":e),m(e,y,_,s(),P,$)}function l(e){f(e)?e._store&&(e._store.validated=1):typeof e=="object"&&e!==null&&e.$$typeof===W&&(e._payload.status==="fulfilled"?f(e._payload.value)&&e._payload.value._store&&(e._payload.value._store.validated=1):e._store&&(e._store.validated=1))}function f(e){return typeof e=="object"&&e!==null&&e.$$typeof===u}var o=j,u=Symbol.for("react.transitional.element"),c=Symbol.for("react.portal"),S=Symbol.for("react.fragment"),h=Symbol.for("react.strict_mode"),w=Symbol.for("react.profiler"),A=Symbol.for("react.consumer"),C=Symbol.for("react.context"),N=Symbol.for("react.forward_ref"),g=Symbol.for("react.suspense"),b=Symbol.for("react.suspense_list"),U=Symbol.for("react.memo"),W=Symbol.for("react.lazy"),ye=Symbol.for("react.activity"),Oe=Symbol.for("react.client.reference"),G=o.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,ee=Object.prototype.hasOwnProperty,he=Array.isArray,J=console.createTask?console.createTask:function(){return null};o={react_stack_bottom_frame:function(e){return e()}};var te,re={},ne=o.react_stack_bottom_frame.bind(o,d)(),ae=J(a(d)),oe={};I.Fragment=S,I.jsx=function(e,i,_){var E=1e4>G.recentlyCreatedOwnerStacks++;return p(e,i,_,!1,E?Error("react-stack-top-frame"):ne,E?J(a(e)):ae)},I.jsxs=function(e,i,_){var E=1e4>G.recentlyCreatedOwnerStacks++;return p(e,i,_,!0,E?Error("react-stack-top-frame"):ne,E?J(a(e)):ae)}}()),I}var _e;function Fe(){return _e||(_e=1,process.env.NODE_ENV==="production"?V.exports=Je():V.exports=$e()),V.exports}var M=Fe();const Be=()=>(T.useSyncNavigationFilters(),null),Ye=()=>{const{user:t}=Ee(),r=j.useRef(null);return j.useEffect(()=>{T.userBus.initializeFromStore()},[]),j.useEffect(()=>{const n=t,a=r.current;if(n&&!a){const s={type:"user:loggedIn",user:n,timestamp:new Date().toISOString()};T.userBus.publish(s)}else if(!n&&a){const s={type:"user:loggedOut",user:null,timestamp:new Date().toISOString()};T.userBus.publish(s)}else if(n&&a&&n.id===a.id){const s=JSON.stringify(n.preferences)!==JSON.stringify(a.preferences);if(s){const v=[];n.preferences.navigationType!==a.preferences.navigationType&&v.push("navigationType"),JSON.stringify(n.preferences.visibleCourseLists)!==JSON.stringify(a.preferences.visibleCourseLists)&&v.push("visibleCourseLists"),JSON.stringify(n.preferences.visibleNavigation)!==JSON.stringify(a.preferences.visibleNavigation)&&v.push("visibleNavigation"),JSON.stringify(n.preferences.lastVisitedCourses)!==JSON.stringify(a.preferences.lastVisitedCourses)&&v.push("lastVisitedCourses");const O={type:"user:preferencesChanged",user:n,timestamp:new Date().toISOString(),metadata:{changedPreferences:v}};T.userBus.publish(O)}if((n.name!==a.name||n.email!==a.email||JSON.stringify(n.privacySettings)!==JSON.stringify(a.privacySettings)||JSON.stringify(n.gdprConsent)!==JSON.stringify(a.gdprConsent)||JSON.stringify(n.dataRetention)!==JSON.stringify(a.dataRetention)||JSON.stringify(n.platformRoles)!==JSON.stringify(a.platformRoles))&&!s){const v={type:"user:updated",user:n,timestamp:new Date().toISOString(),metadata:{previousUser:a}};T.userBus.publish(v)}}r.current=n},[t]),null},qe=({children:t})=>M.jsxs(M.Fragment,{children:[M.jsx(Be,{}),M.jsx(Ye,{}),t]});Object.defineProperty(exports,"userBus",{enumerable:!0,get:()=>T.userBus});exports.UserMicroservice=qe;exports.useUserStore=Ee;
@@ -0,0 +1,5 @@
1
+ import { userBus } from 'mui-toolpad-extended-tuni';
2
+ export { default as UserMicroservice } from './UserMicroservice';
3
+ export { useUserStore } from './store/useUserStore';
4
+ export { userBus };
5
+ export type { UserData, PlatformRole, userId, navigationTypes, gender } from './store/useUserStore';