From 06d430d21c95097bb7ad374e49f71a1cfc231c32 Mon Sep 17 00:00:00 2001 From: ghazall-ag Date: Wed, 5 Nov 2025 18:20:45 +0330 Subject: [PATCH] fix(roles): handle errors properly in edit role API --- node_modules/.vite/deps/_metadata.json | 26 +- node_modules/.vite/deps/zustand_middleware.js | 479 ++++++++++++++++++ .../.vite/deps/zustand_middleware.js.map | 7 + src/components/Sidebar.jsx | 2 + package.json => src/package.json | 0 src/pages/Login.jsx | 6 +- src/pages/Roles.jsx | 99 ++-- src/pages/Users.jsx | 7 + src/services/api.js | 78 ++- src/store/authStore.js | 21 +- 10 files changed, 644 insertions(+), 81 deletions(-) create mode 100644 node_modules/.vite/deps/zustand_middleware.js create mode 100644 node_modules/.vite/deps/zustand_middleware.js.map rename package.json => src/package.json (100%) create mode 100644 src/pages/Users.jsx diff --git a/node_modules/.vite/deps/_metadata.json b/node_modules/.vite/deps/_metadata.json index c3cb136..3639a1f 100644 --- a/node_modules/.vite/deps/_metadata.json +++ b/node_modules/.vite/deps/_metadata.json @@ -1,59 +1,65 @@ { "hash": "ff6fda40", - "browserHash": "b50068b3", + "browserHash": "c03c03c2", "optimized": { "react/jsx-runtime": { "src": "../../react/jsx-runtime.js", "file": "react_jsx-runtime.js", - "fileHash": "ddd613d5", + "fileHash": "e8b04feb", "needsInterop": true }, "react/jsx-dev-runtime": { "src": "../../react/jsx-dev-runtime.js", "file": "react_jsx-dev-runtime.js", - "fileHash": "db7123d4", + "fileHash": "778d2d19", "needsInterop": true }, "react": { "src": "../../react/index.js", "file": "react.js", - "fileHash": "f0784960", + "fileHash": "9085912a", "needsInterop": true }, "axios": { "src": "../../axios/index.js", "file": "axios.js", - "fileHash": "b9f81ab8", + "fileHash": "387f77ed", "needsInterop": false }, "lucide-react": { "src": "../../lucide-react/dist/esm/lucide-react.mjs", "file": "lucide-react.js", - "fileHash": "a5656c81", + "fileHash": "63623648", "needsInterop": false }, "react-dom/client": { "src": "../../react-dom/client.js", "file": "react-dom_client.js", - "fileHash": "ae58904b", + "fileHash": "993544a9", "needsInterop": true }, "react-router-dom": { "src": "../../react-router-dom/dist/index.js", "file": "react-router-dom.js", - "fileHash": "420348ee", + "fileHash": "d3f984dc", "needsInterop": false }, "recharts": { "src": "../../recharts/es6/index.js", "file": "recharts.js", - "fileHash": "dafddd35", + "fileHash": "e1665e3e", "needsInterop": false }, "zustand": { "src": "../../zustand/esm/index.mjs", "file": "zustand.js", - "fileHash": "f2ee525b", + "fileHash": "8be28924", + "needsInterop": false + }, + "zustand/middleware": { + "src": "../../zustand/esm/middleware.mjs", + "file": "zustand_middleware.js", + "fileHash": "936c3138", "needsInterop": false } }, diff --git a/node_modules/.vite/deps/zustand_middleware.js b/node_modules/.vite/deps/zustand_middleware.js new file mode 100644 index 0000000..37e9fe5 --- /dev/null +++ b/node_modules/.vite/deps/zustand_middleware.js @@ -0,0 +1,479 @@ +import "./chunk-5WWUZCGV.js"; + +// node_modules/zustand/esm/middleware.mjs +var reduxImpl = (reducer, initial) => (set, _get, api) => { + api.dispatch = (action) => { + set((state) => reducer(state, action), false, action); + return action; + }; + api.dispatchFromDevtools = true; + return { dispatch: (...args) => api.dispatch(...args), ...initial }; +}; +var redux = reduxImpl; +var trackedConnections = /* @__PURE__ */ new Map(); +var getTrackedConnectionState = (name) => { + const api = trackedConnections.get(name); + if (!api) + return {}; + return Object.fromEntries( + Object.entries(api.stores).map(([key, api2]) => [key, api2.getState()]) + ); +}; +var extractConnectionInformation = (store, extensionConnector, options) => { + if (store === void 0) { + return { + type: "untracked", + connection: extensionConnector.connect(options) + }; + } + const existingConnection = trackedConnections.get(options.name); + if (existingConnection) { + return { type: "tracked", store, ...existingConnection }; + } + const newConnection = { + connection: extensionConnector.connect(options), + stores: {} + }; + trackedConnections.set(options.name, newConnection); + return { type: "tracked", store, ...newConnection }; +}; +var removeStoreFromTrackedConnections = (name, store) => { + if (store === void 0) + return; + const connectionInfo = trackedConnections.get(name); + if (!connectionInfo) + return; + delete connectionInfo.stores[store]; + if (Object.keys(connectionInfo.stores).length === 0) { + trackedConnections.delete(name); + } +}; +var findCallerName = (stack) => { + var _a, _b; + if (!stack) + return void 0; + const traceLines = stack.split("\n"); + const apiSetStateLineIndex = traceLines.findIndex( + (traceLine) => traceLine.includes("api.setState") + ); + if (apiSetStateLineIndex < 0) + return void 0; + const callerLine = ((_a = traceLines[apiSetStateLineIndex + 1]) == null ? void 0 : _a.trim()) || ""; + return (_b = /.+ (.+) .+/.exec(callerLine)) == null ? void 0 : _b[1]; +}; +var devtoolsImpl = (fn, devtoolsOptions = {}) => (set, get, api) => { + const { enabled, anonymousActionType, store, ...options } = devtoolsOptions; + let extensionConnector; + try { + extensionConnector = (enabled != null ? enabled : (import.meta.env ? import.meta.env.MODE : void 0) !== "production") && window.__REDUX_DEVTOOLS_EXTENSION__; + } catch (e) { + } + if (!extensionConnector) { + return fn(set, get, api); + } + const { connection, ...connectionInformation } = extractConnectionInformation(store, extensionConnector, options); + let isRecording = true; + api.setState = (state, replace, nameOrAction) => { + const r = set(state, replace); + if (!isRecording) + return r; + const action = nameOrAction === void 0 ? { + type: anonymousActionType || findCallerName(new Error().stack) || "anonymous" + } : typeof nameOrAction === "string" ? { type: nameOrAction } : nameOrAction; + if (store === void 0) { + connection == null ? void 0 : connection.send(action, get()); + return r; + } + connection == null ? void 0 : connection.send( + { + ...action, + type: `${store}/${action.type}` + }, + { + ...getTrackedConnectionState(options.name), + [store]: api.getState() + } + ); + return r; + }; + api.devtools = { + cleanup: () => { + if (connection && typeof connection.unsubscribe === "function") { + connection.unsubscribe(); + } + removeStoreFromTrackedConnections(options.name, store); + } + }; + const setStateFromDevtools = (...a) => { + const originalIsRecording = isRecording; + isRecording = false; + set(...a); + isRecording = originalIsRecording; + }; + const initialState = fn(api.setState, get, api); + if (connectionInformation.type === "untracked") { + connection == null ? void 0 : connection.init(initialState); + } else { + connectionInformation.stores[connectionInformation.store] = api; + connection == null ? void 0 : connection.init( + Object.fromEntries( + Object.entries(connectionInformation.stores).map(([key, store2]) => [ + key, + key === connectionInformation.store ? initialState : store2.getState() + ]) + ) + ); + } + if (api.dispatchFromDevtools && typeof api.dispatch === "function") { + let didWarnAboutReservedActionType = false; + const originalDispatch = api.dispatch; + api.dispatch = (...args) => { + if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production" && args[0].type === "__setState" && !didWarnAboutReservedActionType) { + console.warn( + '[zustand devtools middleware] "__setState" action type is reserved to set state from the devtools. Avoid using it.' + ); + didWarnAboutReservedActionType = true; + } + originalDispatch(...args); + }; + } + connection.subscribe((message) => { + var _a; + switch (message.type) { + case "ACTION": + if (typeof message.payload !== "string") { + console.error( + "[zustand devtools middleware] Unsupported action format" + ); + return; + } + return parseJsonThen( + message.payload, + (action) => { + if (action.type === "__setState") { + if (store === void 0) { + setStateFromDevtools(action.state); + return; + } + if (Object.keys(action.state).length !== 1) { + console.error( + ` + [zustand devtools middleware] Unsupported __setState action format. + When using 'store' option in devtools(), the 'state' should have only one key, which is a value of 'store' that was passed in devtools(), + and value of this only key should be a state object. Example: { "type": "__setState", "state": { "abc123Store": { "foo": "bar" } } } + ` + ); + } + const stateFromDevtools = action.state[store]; + if (stateFromDevtools === void 0 || stateFromDevtools === null) { + return; + } + if (JSON.stringify(api.getState()) !== JSON.stringify(stateFromDevtools)) { + setStateFromDevtools(stateFromDevtools); + } + return; + } + if (!api.dispatchFromDevtools) + return; + if (typeof api.dispatch !== "function") + return; + api.dispatch(action); + } + ); + case "DISPATCH": + switch (message.payload.type) { + case "RESET": + setStateFromDevtools(initialState); + if (store === void 0) { + return connection == null ? void 0 : connection.init(api.getState()); + } + return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name)); + case "COMMIT": + if (store === void 0) { + connection == null ? void 0 : connection.init(api.getState()); + return; + } + return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name)); + case "ROLLBACK": + return parseJsonThen(message.state, (state) => { + if (store === void 0) { + setStateFromDevtools(state); + connection == null ? void 0 : connection.init(api.getState()); + return; + } + setStateFromDevtools(state[store]); + connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name)); + }); + case "JUMP_TO_STATE": + case "JUMP_TO_ACTION": + return parseJsonThen(message.state, (state) => { + if (store === void 0) { + setStateFromDevtools(state); + return; + } + if (JSON.stringify(api.getState()) !== JSON.stringify(state[store])) { + setStateFromDevtools(state[store]); + } + }); + case "IMPORT_STATE": { + const { nextLiftedState } = message.payload; + const lastComputedState = (_a = nextLiftedState.computedStates.slice(-1)[0]) == null ? void 0 : _a.state; + if (!lastComputedState) + return; + if (store === void 0) { + setStateFromDevtools(lastComputedState); + } else { + setStateFromDevtools(lastComputedState[store]); + } + connection == null ? void 0 : connection.send( + null, + // FIXME no-any + nextLiftedState + ); + return; + } + case "PAUSE_RECORDING": + return isRecording = !isRecording; + } + return; + } + }); + return initialState; +}; +var devtools = devtoolsImpl; +var parseJsonThen = (stringified, fn) => { + let parsed; + try { + parsed = JSON.parse(stringified); + } catch (e) { + console.error( + "[zustand devtools middleware] Could not parse the received json", + e + ); + } + if (parsed !== void 0) + fn(parsed); +}; +var subscribeWithSelectorImpl = (fn) => (set, get, api) => { + const origSubscribe = api.subscribe; + api.subscribe = (selector, optListener, options) => { + let listener = selector; + if (optListener) { + const equalityFn = (options == null ? void 0 : options.equalityFn) || Object.is; + let currentSlice = selector(api.getState()); + listener = (state) => { + const nextSlice = selector(state); + if (!equalityFn(currentSlice, nextSlice)) { + const previousSlice = currentSlice; + optListener(currentSlice = nextSlice, previousSlice); + } + }; + if (options == null ? void 0 : options.fireImmediately) { + optListener(currentSlice, currentSlice); + } + } + return origSubscribe(listener); + }; + const initialState = fn(set, get, api); + return initialState; +}; +var subscribeWithSelector = subscribeWithSelectorImpl; +function combine(initialState, create) { + return (...args) => Object.assign({}, initialState, create(...args)); +} +function createJSONStorage(getStorage, options) { + let storage; + try { + storage = getStorage(); + } catch (e) { + return; + } + const persistStorage = { + getItem: (name) => { + var _a; + const parse = (str2) => { + if (str2 === null) { + return null; + } + return JSON.parse(str2, options == null ? void 0 : options.reviver); + }; + const str = (_a = storage.getItem(name)) != null ? _a : null; + if (str instanceof Promise) { + return str.then(parse); + } + return parse(str); + }, + setItem: (name, newValue) => storage.setItem(name, JSON.stringify(newValue, options == null ? void 0 : options.replacer)), + removeItem: (name) => storage.removeItem(name) + }; + return persistStorage; +} +var toThenable = (fn) => (input) => { + try { + const result = fn(input); + if (result instanceof Promise) { + return result; + } + return { + then(onFulfilled) { + return toThenable(onFulfilled)(result); + }, + catch(_onRejected) { + return this; + } + }; + } catch (e) { + return { + then(_onFulfilled) { + return this; + }, + catch(onRejected) { + return toThenable(onRejected)(e); + } + }; + } +}; +var persistImpl = (config, baseOptions) => (set, get, api) => { + let options = { + storage: createJSONStorage(() => localStorage), + partialize: (state) => state, + version: 0, + merge: (persistedState, currentState) => ({ + ...currentState, + ...persistedState + }), + ...baseOptions + }; + let hasHydrated = false; + const hydrationListeners = /* @__PURE__ */ new Set(); + const finishHydrationListeners = /* @__PURE__ */ new Set(); + let storage = options.storage; + if (!storage) { + return config( + (...args) => { + console.warn( + `[zustand persist middleware] Unable to update item '${options.name}', the given storage is currently unavailable.` + ); + set(...args); + }, + get, + api + ); + } + const setItem = () => { + const state = options.partialize({ ...get() }); + return storage.setItem(options.name, { + state, + version: options.version + }); + }; + const savedSetState = api.setState; + api.setState = (state, replace) => { + savedSetState(state, replace); + return setItem(); + }; + const configResult = config( + (...args) => { + set(...args); + return setItem(); + }, + get, + api + ); + api.getInitialState = () => configResult; + let stateFromStorage; + const hydrate = () => { + var _a, _b; + if (!storage) + return; + hasHydrated = false; + hydrationListeners.forEach((cb) => { + var _a2; + return cb((_a2 = get()) != null ? _a2 : configResult); + }); + const postRehydrationCallback = ((_b = options.onRehydrateStorage) == null ? void 0 : _b.call(options, (_a = get()) != null ? _a : configResult)) || void 0; + return toThenable(storage.getItem.bind(storage))(options.name).then((deserializedStorageValue) => { + if (deserializedStorageValue) { + if (typeof deserializedStorageValue.version === "number" && deserializedStorageValue.version !== options.version) { + if (options.migrate) { + const migration = options.migrate( + deserializedStorageValue.state, + deserializedStorageValue.version + ); + if (migration instanceof Promise) { + return migration.then((result) => [true, result]); + } + return [true, migration]; + } + console.error( + `State loaded from storage couldn't be migrated since no migrate function was provided` + ); + } else { + return [false, deserializedStorageValue.state]; + } + } + return [false, void 0]; + }).then((migrationResult) => { + var _a2; + const [migrated, migratedState] = migrationResult; + stateFromStorage = options.merge( + migratedState, + (_a2 = get()) != null ? _a2 : configResult + ); + set(stateFromStorage, true); + if (migrated) { + return setItem(); + } + }).then(() => { + postRehydrationCallback == null ? void 0 : postRehydrationCallback(stateFromStorage, void 0); + stateFromStorage = get(); + hasHydrated = true; + finishHydrationListeners.forEach((cb) => cb(stateFromStorage)); + }).catch((e) => { + postRehydrationCallback == null ? void 0 : postRehydrationCallback(void 0, e); + }); + }; + api.persist = { + setOptions: (newOptions) => { + options = { + ...options, + ...newOptions + }; + if (newOptions.storage) { + storage = newOptions.storage; + } + }, + clearStorage: () => { + storage == null ? void 0 : storage.removeItem(options.name); + }, + getOptions: () => options, + rehydrate: () => hydrate(), + hasHydrated: () => hasHydrated, + onHydrate: (cb) => { + hydrationListeners.add(cb); + return () => { + hydrationListeners.delete(cb); + }; + }, + onFinishHydration: (cb) => { + finishHydrationListeners.add(cb); + return () => { + finishHydrationListeners.delete(cb); + }; + } + }; + if (!options.skipHydration) { + hydrate(); + } + return stateFromStorage || configResult; +}; +var persist = persistImpl; +export { + combine, + createJSONStorage, + devtools, + persist, + redux, + subscribeWithSelector +}; +//# sourceMappingURL=zustand_middleware.js.map diff --git a/node_modules/.vite/deps/zustand_middleware.js.map b/node_modules/.vite/deps/zustand_middleware.js.map new file mode 100644 index 0000000..18e9735 --- /dev/null +++ b/node_modules/.vite/deps/zustand_middleware.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["../../zustand/esm/middleware.mjs"], + "sourcesContent": ["const reduxImpl = (reducer, initial) => (set, _get, api) => {\n api.dispatch = (action) => {\n set((state) => reducer(state, action), false, action);\n return action;\n };\n api.dispatchFromDevtools = true;\n return { dispatch: (...args) => api.dispatch(...args), ...initial };\n};\nconst redux = reduxImpl;\n\nconst trackedConnections = /* @__PURE__ */ new Map();\nconst getTrackedConnectionState = (name) => {\n const api = trackedConnections.get(name);\n if (!api) return {};\n return Object.fromEntries(\n Object.entries(api.stores).map(([key, api2]) => [key, api2.getState()])\n );\n};\nconst extractConnectionInformation = (store, extensionConnector, options) => {\n if (store === void 0) {\n return {\n type: \"untracked\",\n connection: extensionConnector.connect(options)\n };\n }\n const existingConnection = trackedConnections.get(options.name);\n if (existingConnection) {\n return { type: \"tracked\", store, ...existingConnection };\n }\n const newConnection = {\n connection: extensionConnector.connect(options),\n stores: {}\n };\n trackedConnections.set(options.name, newConnection);\n return { type: \"tracked\", store, ...newConnection };\n};\nconst removeStoreFromTrackedConnections = (name, store) => {\n if (store === void 0) return;\n const connectionInfo = trackedConnections.get(name);\n if (!connectionInfo) return;\n delete connectionInfo.stores[store];\n if (Object.keys(connectionInfo.stores).length === 0) {\n trackedConnections.delete(name);\n }\n};\nconst findCallerName = (stack) => {\n var _a, _b;\n if (!stack) return void 0;\n const traceLines = stack.split(\"\\n\");\n const apiSetStateLineIndex = traceLines.findIndex(\n (traceLine) => traceLine.includes(\"api.setState\")\n );\n if (apiSetStateLineIndex < 0) return void 0;\n const callerLine = ((_a = traceLines[apiSetStateLineIndex + 1]) == null ? void 0 : _a.trim()) || \"\";\n return (_b = /.+ (.+) .+/.exec(callerLine)) == null ? void 0 : _b[1];\n};\nconst devtoolsImpl = (fn, devtoolsOptions = {}) => (set, get, api) => {\n const { enabled, anonymousActionType, store, ...options } = devtoolsOptions;\n let extensionConnector;\n try {\n extensionConnector = (enabled != null ? enabled : (import.meta.env ? import.meta.env.MODE : void 0) !== \"production\") && window.__REDUX_DEVTOOLS_EXTENSION__;\n } catch (e) {\n }\n if (!extensionConnector) {\n return fn(set, get, api);\n }\n const { connection, ...connectionInformation } = extractConnectionInformation(store, extensionConnector, options);\n let isRecording = true;\n api.setState = ((state, replace, nameOrAction) => {\n const r = set(state, replace);\n if (!isRecording) return r;\n const action = nameOrAction === void 0 ? {\n type: anonymousActionType || findCallerName(new Error().stack) || \"anonymous\"\n } : typeof nameOrAction === \"string\" ? { type: nameOrAction } : nameOrAction;\n if (store === void 0) {\n connection == null ? void 0 : connection.send(action, get());\n return r;\n }\n connection == null ? void 0 : connection.send(\n {\n ...action,\n type: `${store}/${action.type}`\n },\n {\n ...getTrackedConnectionState(options.name),\n [store]: api.getState()\n }\n );\n return r;\n });\n api.devtools = {\n cleanup: () => {\n if (connection && typeof connection.unsubscribe === \"function\") {\n connection.unsubscribe();\n }\n removeStoreFromTrackedConnections(options.name, store);\n }\n };\n const setStateFromDevtools = (...a) => {\n const originalIsRecording = isRecording;\n isRecording = false;\n set(...a);\n isRecording = originalIsRecording;\n };\n const initialState = fn(api.setState, get, api);\n if (connectionInformation.type === \"untracked\") {\n connection == null ? void 0 : connection.init(initialState);\n } else {\n connectionInformation.stores[connectionInformation.store] = api;\n connection == null ? void 0 : connection.init(\n Object.fromEntries(\n Object.entries(connectionInformation.stores).map(([key, store2]) => [\n key,\n key === connectionInformation.store ? initialState : store2.getState()\n ])\n )\n );\n }\n if (api.dispatchFromDevtools && typeof api.dispatch === \"function\") {\n let didWarnAboutReservedActionType = false;\n const originalDispatch = api.dispatch;\n api.dispatch = (...args) => {\n if ((import.meta.env ? import.meta.env.MODE : void 0) !== \"production\" && args[0].type === \"__setState\" && !didWarnAboutReservedActionType) {\n console.warn(\n '[zustand devtools middleware] \"__setState\" action type is reserved to set state from the devtools. Avoid using it.'\n );\n didWarnAboutReservedActionType = true;\n }\n originalDispatch(...args);\n };\n }\n connection.subscribe((message) => {\n var _a;\n switch (message.type) {\n case \"ACTION\":\n if (typeof message.payload !== \"string\") {\n console.error(\n \"[zustand devtools middleware] Unsupported action format\"\n );\n return;\n }\n return parseJsonThen(\n message.payload,\n (action) => {\n if (action.type === \"__setState\") {\n if (store === void 0) {\n setStateFromDevtools(action.state);\n return;\n }\n if (Object.keys(action.state).length !== 1) {\n console.error(\n `\n [zustand devtools middleware] Unsupported __setState action format.\n When using 'store' option in devtools(), the 'state' should have only one key, which is a value of 'store' that was passed in devtools(),\n and value of this only key should be a state object. Example: { \"type\": \"__setState\", \"state\": { \"abc123Store\": { \"foo\": \"bar\" } } }\n `\n );\n }\n const stateFromDevtools = action.state[store];\n if (stateFromDevtools === void 0 || stateFromDevtools === null) {\n return;\n }\n if (JSON.stringify(api.getState()) !== JSON.stringify(stateFromDevtools)) {\n setStateFromDevtools(stateFromDevtools);\n }\n return;\n }\n if (!api.dispatchFromDevtools) return;\n if (typeof api.dispatch !== \"function\") return;\n api.dispatch(action);\n }\n );\n case \"DISPATCH\":\n switch (message.payload.type) {\n case \"RESET\":\n setStateFromDevtools(initialState);\n if (store === void 0) {\n return connection == null ? void 0 : connection.init(api.getState());\n }\n return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n case \"COMMIT\":\n if (store === void 0) {\n connection == null ? void 0 : connection.init(api.getState());\n return;\n }\n return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n case \"ROLLBACK\":\n return parseJsonThen(message.state, (state) => {\n if (store === void 0) {\n setStateFromDevtools(state);\n connection == null ? void 0 : connection.init(api.getState());\n return;\n }\n setStateFromDevtools(state[store]);\n connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n });\n case \"JUMP_TO_STATE\":\n case \"JUMP_TO_ACTION\":\n return parseJsonThen(message.state, (state) => {\n if (store === void 0) {\n setStateFromDevtools(state);\n return;\n }\n if (JSON.stringify(api.getState()) !== JSON.stringify(state[store])) {\n setStateFromDevtools(state[store]);\n }\n });\n case \"IMPORT_STATE\": {\n const { nextLiftedState } = message.payload;\n const lastComputedState = (_a = nextLiftedState.computedStates.slice(-1)[0]) == null ? void 0 : _a.state;\n if (!lastComputedState) return;\n if (store === void 0) {\n setStateFromDevtools(lastComputedState);\n } else {\n setStateFromDevtools(lastComputedState[store]);\n }\n connection == null ? void 0 : connection.send(\n null,\n // FIXME no-any\n nextLiftedState\n );\n return;\n }\n case \"PAUSE_RECORDING\":\n return isRecording = !isRecording;\n }\n return;\n }\n });\n return initialState;\n};\nconst devtools = devtoolsImpl;\nconst parseJsonThen = (stringified, fn) => {\n let parsed;\n try {\n parsed = JSON.parse(stringified);\n } catch (e) {\n console.error(\n \"[zustand devtools middleware] Could not parse the received json\",\n e\n );\n }\n if (parsed !== void 0) fn(parsed);\n};\n\nconst subscribeWithSelectorImpl = (fn) => (set, get, api) => {\n const origSubscribe = api.subscribe;\n api.subscribe = ((selector, optListener, options) => {\n let listener = selector;\n if (optListener) {\n const equalityFn = (options == null ? void 0 : options.equalityFn) || Object.is;\n let currentSlice = selector(api.getState());\n listener = (state) => {\n const nextSlice = selector(state);\n if (!equalityFn(currentSlice, nextSlice)) {\n const previousSlice = currentSlice;\n optListener(currentSlice = nextSlice, previousSlice);\n }\n };\n if (options == null ? void 0 : options.fireImmediately) {\n optListener(currentSlice, currentSlice);\n }\n }\n return origSubscribe(listener);\n });\n const initialState = fn(set, get, api);\n return initialState;\n};\nconst subscribeWithSelector = subscribeWithSelectorImpl;\n\nfunction combine(initialState, create) {\n return (...args) => Object.assign({}, initialState, create(...args));\n}\n\nfunction createJSONStorage(getStorage, options) {\n let storage;\n try {\n storage = getStorage();\n } catch (e) {\n return;\n }\n const persistStorage = {\n getItem: (name) => {\n var _a;\n const parse = (str2) => {\n if (str2 === null) {\n return null;\n }\n return JSON.parse(str2, options == null ? void 0 : options.reviver);\n };\n const str = (_a = storage.getItem(name)) != null ? _a : null;\n if (str instanceof Promise) {\n return str.then(parse);\n }\n return parse(str);\n },\n setItem: (name, newValue) => storage.setItem(name, JSON.stringify(newValue, options == null ? void 0 : options.replacer)),\n removeItem: (name) => storage.removeItem(name)\n };\n return persistStorage;\n}\nconst toThenable = (fn) => (input) => {\n try {\n const result = fn(input);\n if (result instanceof Promise) {\n return result;\n }\n return {\n then(onFulfilled) {\n return toThenable(onFulfilled)(result);\n },\n catch(_onRejected) {\n return this;\n }\n };\n } catch (e) {\n return {\n then(_onFulfilled) {\n return this;\n },\n catch(onRejected) {\n return toThenable(onRejected)(e);\n }\n };\n }\n};\nconst persistImpl = (config, baseOptions) => (set, get, api) => {\n let options = {\n storage: createJSONStorage(() => localStorage),\n partialize: (state) => state,\n version: 0,\n merge: (persistedState, currentState) => ({\n ...currentState,\n ...persistedState\n }),\n ...baseOptions\n };\n let hasHydrated = false;\n const hydrationListeners = /* @__PURE__ */ new Set();\n const finishHydrationListeners = /* @__PURE__ */ new Set();\n let storage = options.storage;\n if (!storage) {\n return config(\n (...args) => {\n console.warn(\n `[zustand persist middleware] Unable to update item '${options.name}', the given storage is currently unavailable.`\n );\n set(...args);\n },\n get,\n api\n );\n }\n const setItem = () => {\n const state = options.partialize({ ...get() });\n return storage.setItem(options.name, {\n state,\n version: options.version\n });\n };\n const savedSetState = api.setState;\n api.setState = (state, replace) => {\n savedSetState(state, replace);\n return setItem();\n };\n const configResult = config(\n (...args) => {\n set(...args);\n return setItem();\n },\n get,\n api\n );\n api.getInitialState = () => configResult;\n let stateFromStorage;\n const hydrate = () => {\n var _a, _b;\n if (!storage) return;\n hasHydrated = false;\n hydrationListeners.forEach((cb) => {\n var _a2;\n return cb((_a2 = get()) != null ? _a2 : configResult);\n });\n const postRehydrationCallback = ((_b = options.onRehydrateStorage) == null ? void 0 : _b.call(options, (_a = get()) != null ? _a : configResult)) || void 0;\n return toThenable(storage.getItem.bind(storage))(options.name).then((deserializedStorageValue) => {\n if (deserializedStorageValue) {\n if (typeof deserializedStorageValue.version === \"number\" && deserializedStorageValue.version !== options.version) {\n if (options.migrate) {\n const migration = options.migrate(\n deserializedStorageValue.state,\n deserializedStorageValue.version\n );\n if (migration instanceof Promise) {\n return migration.then((result) => [true, result]);\n }\n return [true, migration];\n }\n console.error(\n `State loaded from storage couldn't be migrated since no migrate function was provided`\n );\n } else {\n return [false, deserializedStorageValue.state];\n }\n }\n return [false, void 0];\n }).then((migrationResult) => {\n var _a2;\n const [migrated, migratedState] = migrationResult;\n stateFromStorage = options.merge(\n migratedState,\n (_a2 = get()) != null ? _a2 : configResult\n );\n set(stateFromStorage, true);\n if (migrated) {\n return setItem();\n }\n }).then(() => {\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(stateFromStorage, void 0);\n stateFromStorage = get();\n hasHydrated = true;\n finishHydrationListeners.forEach((cb) => cb(stateFromStorage));\n }).catch((e) => {\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(void 0, e);\n });\n };\n api.persist = {\n setOptions: (newOptions) => {\n options = {\n ...options,\n ...newOptions\n };\n if (newOptions.storage) {\n storage = newOptions.storage;\n }\n },\n clearStorage: () => {\n storage == null ? void 0 : storage.removeItem(options.name);\n },\n getOptions: () => options,\n rehydrate: () => hydrate(),\n hasHydrated: () => hasHydrated,\n onHydrate: (cb) => {\n hydrationListeners.add(cb);\n return () => {\n hydrationListeners.delete(cb);\n };\n },\n onFinishHydration: (cb) => {\n finishHydrationListeners.add(cb);\n return () => {\n finishHydrationListeners.delete(cb);\n };\n }\n };\n if (!options.skipHydration) {\n hydrate();\n }\n return stateFromStorage || configResult;\n};\nconst persist = persistImpl;\n\nexport { combine, createJSONStorage, devtools, persist, redux, subscribeWithSelector };\n"], + "mappings": "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", + "names": [] +} diff --git a/src/components/Sidebar.jsx b/src/components/Sidebar.jsx index 05e76e2..4673459 100644 --- a/src/components/Sidebar.jsx +++ b/src/components/Sidebar.jsx @@ -6,6 +6,7 @@ import { Settings, Menu, X, + Users, Shield } from 'lucide-react'; @@ -14,6 +15,7 @@ const Sidebar = ({ isOpen, onToggle }) => { { name: 'Dashboard', href: '/', icon: LayoutDashboard }, { name: 'Transactions', href: '/transactions', icon: CreditCard }, { name: 'Roles', href: '/roles', icon: Shield }, + { name: 'Users', href: '/users', icon: Users }, { name: 'Settings', href: '/settings', icon: Settings }, ]; diff --git a/package.json b/src/package.json similarity index 100% rename from package.json rename to src/package.json diff --git a/src/pages/Login.jsx b/src/pages/Login.jsx index fa42bd3..7968ea4 100644 --- a/src/pages/Login.jsx +++ b/src/pages/Login.jsx @@ -44,7 +44,7 @@ const Login = () => {

- Payment Admin Panel + Khalij pay Admin Panel

Sign in to your account @@ -136,9 +136,7 @@ const Login = () => {

- - Demo Credentials - +
diff --git a/src/pages/Roles.jsx b/src/pages/Roles.jsx index e973b36..86ba164 100644 --- a/src/pages/Roles.jsx +++ b/src/pages/Roles.jsx @@ -1,6 +1,6 @@ import React, { useEffect, useMemo, useState } from 'react'; import DataTable from '../components/DataTable'; -import { rolesAPI } from '../services/api'; +import { rolesAPI, listPermissions } from '../services/api'; import { Plus, Trash2, Search, Pencil } from 'lucide-react'; const Roles = () => { @@ -9,25 +9,13 @@ const Roles = () => { const [error, setError] = useState(''); const [name, setName] = useState(''); const [permissionsInput, setPermissionsInput] = useState(''); - const [userType, setUserType] = useState(''); const [nameFilter, setNameFilter] = useState(''); const [isModalOpen, setIsModalOpen] = useState(false); const [isEditModalOpen, setIsEditModalOpen] = useState(false); const [editingRole, setEditingRole] = useState(null); const [selectedPermissions, setSelectedPermissions] = useState([]); - const permissionOptions = [ - 'Administrator', - 'UserManagement', - 'AddUser', - 'EditUser', - 'UserPasswordManagement', - 'UserRoleManagement', - 'RoleManagement', - 'AddRole', - 'EditRole', - 'DeleteRole', - ]; + const [permissionOptions, setPermissionOptions] = useState([]); const fetchRoles = async (q = '') => { try { @@ -43,6 +31,14 @@ const Roles = () => { useEffect(() => { fetchRoles(); + (async () => { + try { + const perms = await listPermissions(); + setPermissionOptions(Array.isArray(perms) ? perms : []); + } catch (_) { + setPermissionOptions([]); + } + })(); }, []); const onAddRole = async (e) => { @@ -52,10 +48,9 @@ const Roles = () => { ? selectedPermissions : permissionsInput.split(',').map(p => p.trim()).filter(Boolean); try { - await rolesAPI.create({ name: name.trim(), permissions: perms, userType: userType.trim() }); + await rolesAPI.create({ name: name.trim(), permissions: perms }); setName(''); setPermissionsInput(''); - setUserType(''); setSelectedPermissions([]); await fetchRoles(nameFilter); setIsModalOpen(false); @@ -72,7 +67,6 @@ const Roles = () => { const openEdit = (role) => { setEditingRole(role); setName(role.name || ''); - setUserType(role.userType || ''); setSelectedPermissions(Array.isArray(role.permissions) ? role.permissions : []); setPermissionsInput(''); setIsEditModalOpen(true); @@ -85,13 +79,12 @@ const Roles = () => { ? selectedPermissions : permissionsInput.split(',').map(p => p.trim()).filter(Boolean); try { - await rolesAPI.update(editingRole.id, { name: name.trim(), permissions: perms, userType: userType.trim() }); + await rolesAPI.update(editingRole.id, { name: name.trim(), permissions: perms }); await fetchRoles(nameFilter); setIsEditModalOpen(false); setEditingRole(null); setName(''); setPermissionsInput(''); - setUserType(''); setSelectedPermissions([]); } catch (_) { setError('Failed to update role'); @@ -103,7 +96,7 @@ const Roles = () => { { key: 'permissions', header: 'Permissions', render: (val) => Array.isArray(val) ? val.join(', ') : '' }, { key: 'userType', header: 'User Type' }, { key: 'actions', header: 'Actions', render: (_val, row) => ( -
+
@@ -201,16 +201,8 @@ const Roles = () => { />
-
- - setUserType(e.target.value)} - className="w-full px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-primary-500" - placeholder="e.g., internal or external" - /> -
-
+ +
@@ -294,16 +293,8 @@ const Roles = () => { />
-
- - setUserType(e.target.value)} - className="w-full px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-primary-500" - placeholder="e.g., internal or external" - /> -
-
+ +