diff --git a/package.json b/package.json
index 007839a8..ddc1e700 100644
--- a/package.json
+++ b/package.json
@@ -81,11 +81,11 @@
"@prisma/extension-read-replicas": "^0.4.1",
"@react-spring/web": "^9.7.3",
"@svgr/cli": "^8.1.0",
- "@tanstack/react-query": "^5.83.0",
+ "@tanstack/react-query": "^5.85.5",
"@umami/react-zen": "^0.164.0",
"@umami/redis-client": "^0.27.0",
"bcryptjs": "^3.0.2",
- "chalk": "^5.4.1",
+ "chalk": "^5.6.0",
"chart.js": "^4.5.0",
"chartjs-adapter-date-fns": "^3.0.0",
"classnames": "^2.3.1",
@@ -136,7 +136,7 @@
},
"devDependencies": {
"@formatjs/cli": "^4.2.29",
- "@netlify/plugin-nextjs": "^5.11.6",
+ "@netlify/plugin-nextjs": "^5.12.1",
"@rollup/plugin-alias": "^5.0.0",
"@rollup/plugin-commonjs": "^25.0.4",
"@rollup/plugin-json": "^6.0.0",
@@ -145,17 +145,17 @@
"@rollup/plugin-terser": "^0.4.4",
"@types/jest": "^29.5.14",
"@types/node": "^22.16.5",
- "@types/react": "^19.1.9",
+ "@types/react": "^19.1.11",
"@types/react-dom": "^19.1.7",
"@types/react-window": "^1.8.8",
- "@typescript-eslint/eslint-plugin": "^8.38.0",
- "@typescript-eslint/parser": "^8.38.0",
+ "@typescript-eslint/eslint-plugin": "^8.40.0",
+ "@typescript-eslint/parser": "^8.40.0",
"babel-plugin-react-compiler": "19.1.0-rc.2",
"cross-env": "^7.0.3",
"cypress": "^13.6.6",
"esbuild": "^0.25.8",
"eslint": "^8.33.0",
- "eslint-config-next": "^14.2.30",
+ "eslint-config-next": "^14.2.32",
"eslint-config-prettier": "^10.1.8",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-plugin-css-modules": "^2.12.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 2db2f044..5a6c1128 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -25,7 +25,7 @@ importers:
version: 4.5.15
'@hello-pangea/dnd':
specifier: ^17.0.0
- version: 17.0.0(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
+ version: 17.0.0(@types/react@19.1.11)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
'@prisma/adapter-pg':
specifier: ^6.14.0
version: 6.14.0
@@ -42,11 +42,11 @@ importers:
specifier: ^8.1.0
version: 8.1.0(typescript@5.9.2)
'@tanstack/react-query':
- specifier: ^5.83.0
- version: 5.85.3(react@19.1.1)
+ specifier: ^5.85.5
+ version: 5.85.5(react@19.1.1)
'@umami/react-zen':
specifier: ^0.164.0
- version: 0.164.0(@babel/core@7.28.3)(@types/react@19.1.10)(babel-plugin-react-compiler@19.1.0-rc.2)(immer@9.0.21)(use-sync-external-store@1.5.0(react@19.1.1))
+ version: 0.164.0(@babel/core@7.28.3)(@types/react@19.1.11)(babel-plugin-react-compiler@19.1.0-rc.2)(immer@9.0.21)(use-sync-external-store@1.5.0(react@19.1.1))
'@umami/redis-client':
specifier: ^0.27.0
version: 0.27.0
@@ -54,8 +54,8 @@ importers:
specifier: ^3.0.2
version: 3.0.2
chalk:
- specifier: ^5.4.1
- version: 5.5.0
+ specifier: ^5.6.0
+ version: 5.6.0
chart.js:
specifier: ^4.5.0
version: 4.5.0
@@ -196,14 +196,14 @@ importers:
version: 3.25.76
zustand:
specifier: ^5.0.8
- version: 5.0.8(@types/react@19.1.10)(immer@9.0.21)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1))
+ version: 5.0.8(@types/react@19.1.11)(immer@9.0.21)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1))
devDependencies:
'@formatjs/cli':
specifier: ^4.2.29
version: 4.8.4(ts-jest@29.4.1(@babel/core@7.28.3)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.3))(esbuild@0.25.9)(jest-util@29.7.0)(jest@29.7.0(@types/node@22.17.2)(ts-node@10.9.2(@types/node@22.17.2)(typescript@5.9.2)))(typescript@5.9.2))
'@netlify/plugin-nextjs':
- specifier: ^5.11.6
- version: 5.12.0
+ specifier: ^5.12.1
+ version: 5.12.1
'@rollup/plugin-alias':
specifier: ^5.0.0
version: 5.1.1(rollup@3.29.5)
@@ -229,20 +229,20 @@ importers:
specifier: ^22.16.5
version: 22.17.2
'@types/react':
- specifier: ^19.1.9
- version: 19.1.10
+ specifier: ^19.1.11
+ version: 19.1.11
'@types/react-dom':
specifier: ^19.1.7
- version: 19.1.7(@types/react@19.1.10)
+ version: 19.1.7(@types/react@19.1.11)
'@types/react-window':
specifier: ^1.8.8
version: 1.8.8
'@typescript-eslint/eslint-plugin':
- specifier: ^8.38.0
- version: 8.39.1(@typescript-eslint/parser@8.39.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2)
+ specifier: ^8.40.0
+ version: 8.40.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2)
'@typescript-eslint/parser':
- specifier: ^8.38.0
- version: 8.39.1(eslint@8.57.1)(typescript@5.9.2)
+ specifier: ^8.40.0
+ version: 8.40.0(eslint@8.57.1)(typescript@5.9.2)
babel-plugin-react-compiler:
specifier: 19.1.0-rc.2
version: 19.1.0-rc.2
@@ -259,8 +259,8 @@ importers:
specifier: ^8.33.0
version: 8.57.1
eslint-config-next:
- specifier: ^14.2.30
- version: 14.2.31(eslint@8.57.1)(typescript@5.9.2)
+ specifier: ^14.2.32
+ version: 14.2.32(eslint@8.57.1)(typescript@5.9.2)
eslint-config-prettier:
specifier: ^10.1.8
version: 10.1.8(eslint@8.57.1)
@@ -275,10 +275,10 @@ importers:
version: 2.15.2(eslint@8.57.1)
eslint-plugin-import:
specifier: ^2.32.0
- version: 2.32.0(@typescript-eslint/parser@8.39.1(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1)
+ version: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1)
eslint-plugin-jest:
specifier: ^27.9.0
- version: 27.9.0(@typescript-eslint/eslint-plugin@8.39.1(@typescript-eslint/parser@8.39.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(jest@29.7.0(@types/node@22.17.2)(ts-node@10.9.2(@types/node@22.17.2)(typescript@5.9.2)))(typescript@5.9.2)
+ version: 27.9.0(@typescript-eslint/eslint-plugin@8.40.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(jest@29.7.0(@types/node@22.17.2)(ts-node@10.9.2(@types/node@22.17.2)(typescript@5.9.2)))(typescript@5.9.2)
eslint-plugin-prettier:
specifier: ^5.5.3
version: 5.5.4(eslint-config-prettier@10.1.8(eslint@8.57.1))(eslint@8.57.1)(prettier@3.6.2)
@@ -1378,15 +1378,15 @@ packages:
'@napi-rs/wasm-runtime@0.2.12':
resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==}
- '@netlify/plugin-nextjs@5.12.0':
- resolution: {integrity: sha512-SXQY/nCiSOSAZWNls/DQxrICldUR7PHSMUw2J2/ZejH1dk12Vwd3+SzSihHrRW9PNcErZkC2g3seM7bWZlvBRg==}
+ '@netlify/plugin-nextjs@5.12.1':
+ resolution: {integrity: sha512-b2Ic9NkNnnh0lKC/YWDZ2+HdLd/uYdBzLvLKYOkPyFt8KEszoC+Je3GRcwBeOLxaNtK8lji7YPIjtGz8K2sLVQ==}
engines: {node: '>=18.0.0'}
'@next/env@15.5.0':
resolution: {integrity: sha512-sDaprBAfzCQiOgo2pO+LhnV0Wt2wBgartjrr+dpcTORYVnnXD0gwhHhiiyIih9hQbq+JnbqH4odgcFWhqCGidw==}
- '@next/eslint-plugin-next@14.2.31':
- resolution: {integrity: sha512-ouaB+l8Cr/uzGxoGHUvd01OnfFTM8qM81Crw1AG0xoWDRN0DKLXyTWVe0FdAOHVBpGuXB87aufdRmrwzZDArIw==}
+ '@next/eslint-plugin-next@14.2.32':
+ resolution: {integrity: sha512-tyZMX8g4cWg/uPW4NxiJK13t62Pab47SKGJGVZJa6YtFwtfrXovH4j1n9tdpRdXW03PGQBugYEVGM7OhWfytdA==}
'@next/swc-darwin-arm64@15.5.0':
resolution: {integrity: sha512-v7Jj9iqC6enxIRBIScD/o0lH7QKvSxq2LM8UTyqJi+S2w2QzhMYjven4vgu/RzgsdtdbpkyCxBTzHl/gN5rTRg==}
@@ -2321,11 +2321,11 @@ packages:
'@swc/helpers@0.5.17':
resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==}
- '@tanstack/query-core@5.85.3':
- resolution: {integrity: sha512-9Ne4USX83nHmRuEYs78LW+3lFEEO2hBDHu7mrdIgAFx5Zcrs7ker3n/i8p4kf6OgKExmaDN5oR0efRD7i2J0DQ==}
+ '@tanstack/query-core@5.85.5':
+ resolution: {integrity: sha512-KO0WTob4JEApv69iYp1eGvfMSUkgw//IpMnq+//cORBzXf0smyRwPLrUvEe5qtAEGjwZTXrjxg+oJNP/C00t6w==}
- '@tanstack/react-query@5.85.3':
- resolution: {integrity: sha512-AqU8TvNh5GVIE8I+TUU0noryBRy7gOY0XhSayVXmOPll4UkZeLWKDwi0rtWOZbwLRCbyxorfJ5DIjDqE7GXpcQ==}
+ '@tanstack/react-query@5.85.5':
+ resolution: {integrity: sha512-/X4EFNcnPiSs8wM2v+b6DqS5mmGeuJQvxBglmDxl6ZQb5V26ouD2SJYAcC3VjbNwqhY2zjxVD15rDA5nGbMn3A==}
peerDependencies:
react: ^18 || ^19
@@ -2429,8 +2429,8 @@ packages:
'@types/react-window@1.8.8':
resolution: {integrity: sha512-8Ls660bHR1AUA2kuRvVG9D/4XpRC6wjAaPT9dil7Ckc76eP9TKWZwwmgfq8Q1LANX3QNDnoU4Zp48A3w+zK69Q==}
- '@types/react@19.1.10':
- resolution: {integrity: sha512-EhBeSYX0Y6ye8pNebpKrwFJq7BoQ8J5SO6NlvNwwHjSj6adXJViPQrKlsyPw7hLBLvckEMO1yxeGdR82YBBlDg==}
+ '@types/react@19.1.11':
+ resolution: {integrity: sha512-lr3jdBw/BGj49Eps7EvqlUaoeA0xpj3pc0RoJkHpYaCHkVK7i28dKyImLQb3JVlqs3aYSXf7qYuWOW/fgZnTXQ==}
'@types/resolve@1.20.2':
resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
@@ -2463,23 +2463,23 @@ packages:
'@types/yauzl@2.10.3':
resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==}
- '@typescript-eslint/eslint-plugin@8.39.1':
- resolution: {integrity: sha512-yYegZ5n3Yr6eOcqgj2nJH8cH/ZZgF+l0YIdKILSDjYFRjgYQMgv/lRjV5Z7Up04b9VYUondt8EPMqg7kTWgJ2g==}
+ '@typescript-eslint/eslint-plugin@8.40.0':
+ resolution: {integrity: sha512-w/EboPlBwnmOBtRbiOvzjD+wdiZdgFeo17lkltrtn7X37vagKKWJABvyfsJXTlHe6XBzugmYgd4A4nW+k8Mixw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
- '@typescript-eslint/parser': ^8.39.1
+ '@typescript-eslint/parser': ^8.40.0
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0'
- '@typescript-eslint/parser@8.39.1':
- resolution: {integrity: sha512-pUXGCuHnnKw6PyYq93lLRiZm3vjuslIy7tus1lIQTYVK9bL8XBgJnCWm8a0KcTtHC84Yya1Q6rtll+duSMj0dg==}
+ '@typescript-eslint/parser@8.40.0':
+ resolution: {integrity: sha512-jCNyAuXx8dr5KJMkecGmZ8KI61KBUhkCob+SD+C+I5+Y1FWI2Y3QmY4/cxMCC5WAsZqoEtEETVhUiUMIGCf6Bw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0'
- '@typescript-eslint/project-service@8.39.1':
- resolution: {integrity: sha512-8fZxek3ONTwBu9ptw5nCKqZOSkXshZB7uAxuFF0J/wTMkKydjXCzqqga7MlFMpHi9DoG4BadhmTkITBcg8Aybw==}
+ '@typescript-eslint/project-service@8.40.0':
+ resolution: {integrity: sha512-/A89vz7Wf5DEXsGVvcGdYKbVM9F7DyFXj52lNYUDS1L9yJfqjW/fIp5PgMuEJL/KeqVTe2QSbXAGUZljDUpArw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
@@ -2488,18 +2488,18 @@ packages:
resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
- '@typescript-eslint/scope-manager@8.39.1':
- resolution: {integrity: sha512-RkBKGBrjgskFGWuyUGz/EtD8AF/GW49S21J8dvMzpJitOF1slLEbbHnNEtAHtnDAnx8qDEdRrULRnWVx27wGBw==}
+ '@typescript-eslint/scope-manager@8.40.0':
+ resolution: {integrity: sha512-y9ObStCcdCiZKzwqsE8CcpyuVMwRouJbbSrNuThDpv16dFAj429IkM6LNb1dZ2m7hK5fHyzNcErZf7CEeKXR4w==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@typescript-eslint/tsconfig-utils@8.39.1':
- resolution: {integrity: sha512-ePUPGVtTMR8XMU2Hee8kD0Pu4NDE1CN9Q1sxGSGd/mbOtGZDM7pnhXNJnzW63zk/q+Z54zVzj44HtwXln5CvHA==}
+ '@typescript-eslint/tsconfig-utils@8.40.0':
+ resolution: {integrity: sha512-jtMytmUaG9d/9kqSl/W3E3xaWESo4hFDxAIHGVW/WKKtQhesnRIJSAJO6XckluuJ6KDB5woD1EiqknriCtAmcw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
- '@typescript-eslint/type-utils@8.39.1':
- resolution: {integrity: sha512-gu9/ahyatyAdQbKeHnhT4R+y3YLtqqHyvkfDxaBYk97EcbfChSJXyaJnIL3ygUv7OuZatePHmQvuH5ru0lnVeA==}
+ '@typescript-eslint/type-utils@8.40.0':
+ resolution: {integrity: sha512-eE60cK4KzAc6ZrzlJnflXdrMqOBaugeukWICO2rB0KNvwdIMaEaYiywwHMzA1qFpTxrLhN9Lp4E/00EgWcD3Ow==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
@@ -2509,8 +2509,8 @@ packages:
resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
- '@typescript-eslint/types@8.39.1':
- resolution: {integrity: sha512-7sPDKQQp+S11laqTrhHqeAbsCfMkwJMrV7oTDvtDds4mEofJYir414bYKUEb8YPUm9QL3U+8f6L6YExSoAGdQw==}
+ '@typescript-eslint/types@8.40.0':
+ resolution: {integrity: sha512-ETdbFlgbAmXHyFPwqUIYrfc12ArvpBhEVgGAxVYSwli26dn8Ko+lIo4Su9vI9ykTZdJn+vJprs/0eZU0YMAEQg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/typescript-estree@5.62.0':
@@ -2522,8 +2522,8 @@ packages:
typescript:
optional: true
- '@typescript-eslint/typescript-estree@8.39.1':
- resolution: {integrity: sha512-EKkpcPuIux48dddVDXyQBlKdeTPMmALqBUbEk38McWv0qVEZwOpVJBi7ugK5qVNgeuYjGNQxrrnoM/5+TI/BPw==}
+ '@typescript-eslint/typescript-estree@8.40.0':
+ resolution: {integrity: sha512-k1z9+GJReVVOkc1WfVKs1vBrR5MIKKbdAjDTPvIK3L8De6KbFfPFt6BKpdkdk7rZS2GtC/m6yI5MYX+UsuvVYQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
@@ -2534,8 +2534,8 @@ packages:
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
- '@typescript-eslint/utils@8.39.1':
- resolution: {integrity: sha512-VF5tZ2XnUSTuiqZFXCZfZs1cgkdd3O/sSYmdo2EpSyDlC86UM/8YytTmKnehOW3TGAlivqTDT6bS87B/GQ/jyg==}
+ '@typescript-eslint/utils@8.40.0':
+ resolution: {integrity: sha512-Cgzi2MXSZyAUOY+BFwGs17s7ad/7L+gKt6Y8rAVVWS+7o6wrjeFN4nVfTpbE25MNcxyJ+iYUXflbs2xR9h4UBg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
@@ -2545,8 +2545,8 @@ packages:
resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
- '@typescript-eslint/visitor-keys@8.39.1':
- resolution: {integrity: sha512-W8FQi6kEh2e8zVhQ0eeRnxdvIoOkAp/CPAahcNio6nO9dsIwb9b34z90KOlheoyuVf6LSOEdjlkxSkapNEc+4A==}
+ '@typescript-eslint/visitor-keys@8.40.0':
+ resolution: {integrity: sha512-8CZ47QwalyRjsypfwnbI3hKy5gJDPmrkLjkgMxhi0+DZZ2QNx2naS6/hWoVYUHU7LU2zleF68V9miaVZvhFfTA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@umami/react-zen@0.164.0':
@@ -2727,8 +2727,8 @@ packages:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
- ansi-regex@6.1.0:
- resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==}
+ ansi-regex@6.2.0:
+ resolution: {integrity: sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==}
engines: {node: '>=12'}
ansi-styles@3.2.1:
@@ -3023,8 +3023,8 @@ packages:
resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==}
engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
- chalk@5.5.0:
- resolution: {integrity: sha512-1tm8DTaJhPBG3bIkVeZt1iZM9GfSX2lzOeDVZH9R9ffRHpmHvxZ/QhgQH/aDTkswQVt+YHdXAdS/In/30OjCbg==}
+ chalk@5.6.0:
+ resolution: {integrity: sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ==}
engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
char-regex@1.0.2:
@@ -3678,8 +3678,8 @@ packages:
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
engines: {node: '>=10'}
- eslint-config-next@14.2.31:
- resolution: {integrity: sha512-sT32j4678je7SWstBM6l0kE2L+LSgAARDAxw8iloNhI4/8xwkdDesbrGCPaGWzQv+dD6f6adhB+eRSThpGkBdg==}
+ eslint-config-next@14.2.32:
+ resolution: {integrity: sha512-mP/NmYtDBsKlKIOBnH+CW+pYeyR3wBhE+26DAqQ0/aRtEBeTEjgY2wAFUugUELkTLmrX6PpuMSSTpOhz7j9kdQ==}
peerDependencies:
eslint: ^7.23.0 || ^8.0.0
typescript: '>=3.3.1'
@@ -7830,7 +7830,7 @@ snapshots:
optionalDependencies:
ts-jest: 29.4.1(@babel/core@7.28.3)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.3))(esbuild@0.25.9)(jest-util@29.7.0)(jest@29.7.0(@types/node@22.17.2)(ts-node@10.9.2(@types/node@22.17.2)(typescript@5.9.2)))(typescript@5.9.2)
- '@hello-pangea/dnd@17.0.0(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)':
+ '@hello-pangea/dnd@17.0.0(@types/react@19.1.11)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)':
dependencies:
'@babel/runtime': 7.28.3
css-box-model: 1.2.1
@@ -7838,7 +7838,7 @@ snapshots:
raf-schd: 4.0.3
react: 19.1.1
react-dom: 19.1.1(react@19.1.1)
- react-redux: 9.2.0(@types/react@19.1.10)(react@19.1.1)(redux@5.0.1)
+ react-redux: 9.2.0(@types/react@19.1.11)(react@19.1.1)(redux@5.0.1)
redux: 5.0.1
use-memo-one: 1.1.3(react@19.1.1)
transitivePeerDependencies:
@@ -8179,11 +8179,11 @@ snapshots:
'@tybys/wasm-util': 0.10.0
optional: true
- '@netlify/plugin-nextjs@5.12.0': {}
+ '@netlify/plugin-nextjs@5.12.1': {}
'@next/env@15.5.0': {}
- '@next/eslint-plugin-next@14.2.31':
+ '@next/eslint-plugin-next@14.2.32':
dependencies:
glob: 10.3.10
@@ -9570,11 +9570,11 @@ snapshots:
dependencies:
tslib: 2.8.1
- '@tanstack/query-core@5.85.3': {}
+ '@tanstack/query-core@5.85.5': {}
- '@tanstack/react-query@5.85.3(react@19.1.1)':
+ '@tanstack/react-query@5.85.5(react@19.1.1)':
dependencies:
- '@tanstack/query-core': 5.85.3
+ '@tanstack/query-core': 5.85.5
react: 19.1.1
'@trysound/sax@0.2.0': {}
@@ -9634,9 +9634,9 @@ snapshots:
dependencies:
'@types/node': 22.17.2
- '@types/hoist-non-react-statics@3.3.7(@types/react@19.1.10)':
+ '@types/hoist-non-react-statics@3.3.7(@types/react@19.1.11)':
dependencies:
- '@types/react': 19.1.10
+ '@types/react': 19.1.11
hoist-non-react-statics: 3.3.2
'@types/istanbul-lib-coverage@2.0.6': {}
@@ -9676,15 +9676,15 @@ snapshots:
'@types/normalize-package-data@2.4.4': {}
- '@types/react-dom@19.1.7(@types/react@19.1.10)':
+ '@types/react-dom@19.1.7(@types/react@19.1.11)':
dependencies:
- '@types/react': 19.1.10
+ '@types/react': 19.1.11
'@types/react-window@1.8.8':
dependencies:
- '@types/react': 19.1.10
+ '@types/react': 19.1.11
- '@types/react@19.1.10':
+ '@types/react@19.1.11':
dependencies:
csstype: 3.1.3
@@ -9715,14 +9715,14 @@ snapshots:
'@types/node': 22.17.2
optional: true
- '@typescript-eslint/eslint-plugin@8.39.1(@typescript-eslint/parser@8.39.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2)':
+ '@typescript-eslint/eslint-plugin@8.40.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2)':
dependencies:
'@eslint-community/regexpp': 4.12.1
- '@typescript-eslint/parser': 8.39.1(eslint@8.57.1)(typescript@5.9.2)
- '@typescript-eslint/scope-manager': 8.39.1
- '@typescript-eslint/type-utils': 8.39.1(eslint@8.57.1)(typescript@5.9.2)
- '@typescript-eslint/utils': 8.39.1(eslint@8.57.1)(typescript@5.9.2)
- '@typescript-eslint/visitor-keys': 8.39.1
+ '@typescript-eslint/parser': 8.40.0(eslint@8.57.1)(typescript@5.9.2)
+ '@typescript-eslint/scope-manager': 8.40.0
+ '@typescript-eslint/type-utils': 8.40.0(eslint@8.57.1)(typescript@5.9.2)
+ '@typescript-eslint/utils': 8.40.0(eslint@8.57.1)(typescript@5.9.2)
+ '@typescript-eslint/visitor-keys': 8.40.0
eslint: 8.57.1
graphemer: 1.4.0
ignore: 7.0.5
@@ -9732,22 +9732,22 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/parser@8.39.1(eslint@8.57.1)(typescript@5.9.2)':
+ '@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2)':
dependencies:
- '@typescript-eslint/scope-manager': 8.39.1
- '@typescript-eslint/types': 8.39.1
- '@typescript-eslint/typescript-estree': 8.39.1(typescript@5.9.2)
- '@typescript-eslint/visitor-keys': 8.39.1
+ '@typescript-eslint/scope-manager': 8.40.0
+ '@typescript-eslint/types': 8.40.0
+ '@typescript-eslint/typescript-estree': 8.40.0(typescript@5.9.2)
+ '@typescript-eslint/visitor-keys': 8.40.0
debug: 4.4.1(supports-color@8.1.1)
eslint: 8.57.1
typescript: 5.9.2
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/project-service@8.39.1(typescript@5.9.2)':
+ '@typescript-eslint/project-service@8.40.0(typescript@5.9.2)':
dependencies:
- '@typescript-eslint/tsconfig-utils': 8.39.1(typescript@5.9.2)
- '@typescript-eslint/types': 8.39.1
+ '@typescript-eslint/tsconfig-utils': 8.40.0(typescript@5.9.2)
+ '@typescript-eslint/types': 8.40.0
debug: 4.4.1(supports-color@8.1.1)
typescript: 5.9.2
transitivePeerDependencies:
@@ -9758,20 +9758,20 @@ snapshots:
'@typescript-eslint/types': 5.62.0
'@typescript-eslint/visitor-keys': 5.62.0
- '@typescript-eslint/scope-manager@8.39.1':
+ '@typescript-eslint/scope-manager@8.40.0':
dependencies:
- '@typescript-eslint/types': 8.39.1
- '@typescript-eslint/visitor-keys': 8.39.1
+ '@typescript-eslint/types': 8.40.0
+ '@typescript-eslint/visitor-keys': 8.40.0
- '@typescript-eslint/tsconfig-utils@8.39.1(typescript@5.9.2)':
+ '@typescript-eslint/tsconfig-utils@8.40.0(typescript@5.9.2)':
dependencies:
typescript: 5.9.2
- '@typescript-eslint/type-utils@8.39.1(eslint@8.57.1)(typescript@5.9.2)':
+ '@typescript-eslint/type-utils@8.40.0(eslint@8.57.1)(typescript@5.9.2)':
dependencies:
- '@typescript-eslint/types': 8.39.1
- '@typescript-eslint/typescript-estree': 8.39.1(typescript@5.9.2)
- '@typescript-eslint/utils': 8.39.1(eslint@8.57.1)(typescript@5.9.2)
+ '@typescript-eslint/types': 8.40.0
+ '@typescript-eslint/typescript-estree': 8.40.0(typescript@5.9.2)
+ '@typescript-eslint/utils': 8.40.0(eslint@8.57.1)(typescript@5.9.2)
debug: 4.4.1(supports-color@8.1.1)
eslint: 8.57.1
ts-api-utils: 2.1.0(typescript@5.9.2)
@@ -9781,7 +9781,7 @@ snapshots:
'@typescript-eslint/types@5.62.0': {}
- '@typescript-eslint/types@8.39.1': {}
+ '@typescript-eslint/types@8.40.0': {}
'@typescript-eslint/typescript-estree@5.62.0(typescript@5.9.2)':
dependencies:
@@ -9797,12 +9797,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/typescript-estree@8.39.1(typescript@5.9.2)':
+ '@typescript-eslint/typescript-estree@8.40.0(typescript@5.9.2)':
dependencies:
- '@typescript-eslint/project-service': 8.39.1(typescript@5.9.2)
- '@typescript-eslint/tsconfig-utils': 8.39.1(typescript@5.9.2)
- '@typescript-eslint/types': 8.39.1
- '@typescript-eslint/visitor-keys': 8.39.1
+ '@typescript-eslint/project-service': 8.40.0(typescript@5.9.2)
+ '@typescript-eslint/tsconfig-utils': 8.40.0(typescript@5.9.2)
+ '@typescript-eslint/types': 8.40.0
+ '@typescript-eslint/visitor-keys': 8.40.0
debug: 4.4.1(supports-color@8.1.1)
fast-glob: 3.3.3
is-glob: 4.0.3
@@ -9828,12 +9828,12 @@ snapshots:
- supports-color
- typescript
- '@typescript-eslint/utils@8.39.1(eslint@8.57.1)(typescript@5.9.2)':
+ '@typescript-eslint/utils@8.40.0(eslint@8.57.1)(typescript@5.9.2)':
dependencies:
'@eslint-community/eslint-utils': 4.7.0(eslint@8.57.1)
- '@typescript-eslint/scope-manager': 8.39.1
- '@typescript-eslint/types': 8.39.1
- '@typescript-eslint/typescript-estree': 8.39.1(typescript@5.9.2)
+ '@typescript-eslint/scope-manager': 8.40.0
+ '@typescript-eslint/types': 8.40.0
+ '@typescript-eslint/typescript-estree': 8.40.0(typescript@5.9.2)
eslint: 8.57.1
typescript: 5.9.2
transitivePeerDependencies:
@@ -9844,12 +9844,12 @@ snapshots:
'@typescript-eslint/types': 5.62.0
eslint-visitor-keys: 3.4.3
- '@typescript-eslint/visitor-keys@8.39.1':
+ '@typescript-eslint/visitor-keys@8.40.0':
dependencies:
- '@typescript-eslint/types': 8.39.1
+ '@typescript-eslint/types': 8.40.0
eslint-visitor-keys: 4.2.1
- '@umami/react-zen@0.164.0(@babel/core@7.28.3)(@types/react@19.1.10)(babel-plugin-react-compiler@19.1.0-rc.2)(immer@9.0.21)(use-sync-external-store@1.5.0(react@19.1.1))':
+ '@umami/react-zen@0.164.0(@babel/core@7.28.3)(@types/react@19.1.11)(babel-plugin-react-compiler@19.1.0-rc.2)(immer@9.0.21)(use-sync-external-store@1.5.0(react@19.1.1))':
dependencies:
'@fontsource/jetbrains-mono': 5.2.6
'@internationalized/date': 3.8.2
@@ -9866,7 +9866,7 @@ snapshots:
react-hook-form: 7.62.0(react@19.1.1)
react-icons: 5.5.0(react@19.1.1)
thenby: 1.3.4
- zustand: 5.0.8(@types/react@19.1.10)(immer@9.0.21)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1))
+ zustand: 5.0.8(@types/react@19.1.11)(immer@9.0.21)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1))
transitivePeerDependencies:
- '@babel/core'
- '@opentelemetry/api'
@@ -10045,7 +10045,7 @@ snapshots:
ansi-regex@5.0.1: {}
- ansi-regex@6.1.0: {}
+ ansi-regex@6.2.0: {}
ansi-styles@3.2.1:
dependencies:
@@ -10400,7 +10400,7 @@ snapshots:
chalk@5.3.0: {}
- chalk@5.5.0: {}
+ chalk@5.6.0: {}
char-regex@1.0.2: {}
@@ -11168,16 +11168,16 @@ snapshots:
escape-string-regexp@4.0.0: {}
- eslint-config-next@14.2.31(eslint@8.57.1)(typescript@5.9.2):
+ eslint-config-next@14.2.32(eslint@8.57.1)(typescript@5.9.2):
dependencies:
- '@next/eslint-plugin-next': 14.2.31
+ '@next/eslint-plugin-next': 14.2.32
'@rushstack/eslint-patch': 1.12.0
- '@typescript-eslint/eslint-plugin': 8.39.1(@typescript-eslint/parser@8.39.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2)
- '@typescript-eslint/parser': 8.39.1(eslint@8.57.1)(typescript@5.9.2)
+ '@typescript-eslint/eslint-plugin': 8.40.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2)
+ '@typescript-eslint/parser': 8.40.0(eslint@8.57.1)(typescript@5.9.2)
eslint: 8.57.1
eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.1)
- eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.39.1(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1)
+ eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1)
eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1)
eslint-plugin-react: 7.37.5(eslint@8.57.1)
eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.57.1)
@@ -11194,7 +11194,7 @@ snapshots:
eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.32.0):
dependencies:
- eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.39.1(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1)
+ eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1)
eslint-import-resolver-node@0.3.9:
dependencies:
@@ -11215,15 +11215,15 @@ snapshots:
tinyglobby: 0.2.14
unrs-resolver: 1.11.1
optionalDependencies:
- eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.39.1(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1)
+ eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1)
transitivePeerDependencies:
- supports-color
- eslint-module-utils@2.12.1(@typescript-eslint/parser@8.39.1(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1):
+ eslint-module-utils@2.12.1(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1):
dependencies:
debug: 3.2.7(supports-color@8.1.1)
optionalDependencies:
- '@typescript-eslint/parser': 8.39.1(eslint@8.57.1)(typescript@5.9.2)
+ '@typescript-eslint/parser': 8.40.0(eslint@8.57.1)(typescript@5.9.2)
eslint: 8.57.1
eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.1)
@@ -11241,7 +11241,7 @@ snapshots:
eslint: 8.57.1
globals: 13.24.0
- eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.39.1(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1):
+ eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1):
dependencies:
'@rtsao/scc': 1.1.0
array-includes: 3.1.9
@@ -11252,7 +11252,7 @@ snapshots:
doctrine: 2.1.0
eslint: 8.57.1
eslint-import-resolver-node: 0.3.9
- eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.39.1(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1)
+ eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1)
hasown: 2.0.2
is-core-module: 2.16.1
is-glob: 4.0.3
@@ -11264,18 +11264,18 @@ snapshots:
string.prototype.trimend: 1.0.9
tsconfig-paths: 3.15.0
optionalDependencies:
- '@typescript-eslint/parser': 8.39.1(eslint@8.57.1)(typescript@5.9.2)
+ '@typescript-eslint/parser': 8.40.0(eslint@8.57.1)(typescript@5.9.2)
transitivePeerDependencies:
- eslint-import-resolver-typescript
- eslint-import-resolver-webpack
- supports-color
- eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@8.39.1(@typescript-eslint/parser@8.39.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(jest@29.7.0(@types/node@22.17.2)(ts-node@10.9.2(@types/node@22.17.2)(typescript@5.9.2)))(typescript@5.9.2):
+ eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@8.40.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(jest@29.7.0(@types/node@22.17.2)(ts-node@10.9.2(@types/node@22.17.2)(typescript@5.9.2)))(typescript@5.9.2):
dependencies:
'@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.9.2)
eslint: 8.57.1
optionalDependencies:
- '@typescript-eslint/eslint-plugin': 8.39.1(@typescript-eslint/parser@8.39.1(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2)
+ '@typescript-eslint/eslint-plugin': 8.40.0(@typescript-eslint/parser@8.40.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2)
jest: 29.7.0(@types/node@22.17.2)(ts-node@10.9.2(@types/node@22.17.2)(typescript@5.9.2))
transitivePeerDependencies:
- supports-color
@@ -13899,8 +13899,8 @@ snapshots:
'@formatjs/ecma402-abstract': 2.3.4
'@formatjs/icu-messageformat-parser': 2.11.2
'@formatjs/intl': 3.1.6(typescript@5.9.2)
- '@types/hoist-non-react-statics': 3.3.7(@types/react@19.1.10)
- '@types/react': 19.1.10
+ '@types/hoist-non-react-statics': 3.3.7(@types/react@19.1.11)
+ '@types/react': 19.1.11
hoist-non-react-statics: 3.3.2
intl-messageformat: 10.7.16
react: 19.1.1
@@ -13912,13 +13912,13 @@ snapshots:
react-is@18.3.1: {}
- react-redux@9.2.0(@types/react@19.1.10)(react@19.1.1)(redux@5.0.1):
+ react-redux@9.2.0(@types/react@19.1.11)(react@19.1.1)(redux@5.0.1):
dependencies:
'@types/use-sync-external-store': 0.0.6
react: 19.1.1
use-sync-external-store: 1.5.0(react@19.1.1)
optionalDependencies:
- '@types/react': 19.1.10
+ '@types/react': 19.1.11
redux: 5.0.1
react-simple-maps@2.3.0(prop-types@15.8.1)(react-dom@19.1.1(react@19.1.1))(react@19.1.1):
@@ -14525,7 +14525,7 @@ snapshots:
strip-ansi@7.1.0:
dependencies:
- ansi-regex: 6.1.0
+ ansi-regex: 6.2.0
strip-bom@3.0.0: {}
@@ -15129,9 +15129,9 @@ snapshots:
zod@3.25.76: {}
- zustand@5.0.8(@types/react@19.1.10)(immer@9.0.21)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)):
+ zustand@5.0.8(@types/react@19.1.11)(immer@9.0.21)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)):
optionalDependencies:
- '@types/react': 19.1.10
+ '@types/react': 19.1.11
immer: 9.0.21
react: 19.1.1
use-sync-external-store: 1.5.0(react@19.1.1)
diff --git a/src/app/(main)/admin/users/UserAddForm.tsx b/src/app/(main)/admin/users/UserAddForm.tsx
index 626728cf..e02be0df 100644
--- a/src/app/(main)/admin/users/UserAddForm.tsx
+++ b/src/app/(main)/admin/users/UserAddForm.tsx
@@ -9,14 +9,11 @@ import {
PasswordField,
Button,
} from '@umami/react-zen';
-import { useApi, useMessages } from '@/components/hooks';
+import { useMessages, useUpdateQuery } from '@/components/hooks';
import { ROLES } from '@/lib/constants';
export function UserAddForm({ onSave, onClose }) {
- const { post, useMutation } = useApi();
- const { mutate, error, isPending } = useMutation({
- mutationFn: (data: any) => post(`/users`, data),
- });
+ const { mutate, error, isPending } = useUpdateQuery(`/users`);
const { formatMessage, labels } = useMessages();
const handleSubmit = async (data: any) => {
diff --git a/src/app/(main)/admin/users/UserDeleteForm.tsx b/src/app/(main)/admin/users/UserDeleteForm.tsx
index 620da1d1..f316dafe 100644
--- a/src/app/(main)/admin/users/UserDeleteForm.tsx
+++ b/src/app/(main)/admin/users/UserDeleteForm.tsx
@@ -1,5 +1,5 @@
import { AlertDialog, Row } from '@umami/react-zen';
-import { useApi, useMessages, useModified } from '@/components/hooks';
+import { useDeleteQuery, useMessages, useModified } from '@/components/hooks';
export function UserDeleteForm({
userId,
@@ -13,8 +13,7 @@ export function UserDeleteForm({
onClose?: () => void;
}) {
const { messages, labels, formatMessage } = useMessages();
- const { del, useMutation } = useApi();
- const { mutate } = useMutation({ mutationFn: () => del(`/users/${userId}`) });
+ const { mutate } = useDeleteQuery(`/users/${userId}`);
const { touch } = useModified();
const handleConfirm = async () => {
diff --git a/src/app/(main)/admin/users/[userId]/UserEditForm.tsx b/src/app/(main)/admin/users/[userId]/UserEditForm.tsx
index 52073459..b1134ccc 100644
--- a/src/app/(main)/admin/users/[userId]/UserEditForm.tsx
+++ b/src/app/(main)/admin/users/[userId]/UserEditForm.tsx
@@ -7,30 +7,16 @@ import {
TextField,
FormSubmitButton,
PasswordField,
- useToast,
} from '@umami/react-zen';
-import { useApi, useLoginQuery, useMessages, useModified, useUser } from '@/components/hooks';
+import { useLoginQuery, useMessages, useUpdateQuery, useUser } from '@/components/hooks';
import { ROLES } from '@/lib/constants';
export function UserEditForm({ userId, onSave }: { userId: string; onSave?: () => void }) {
const { formatMessage, labels, messages, getMessage } = useMessages();
- const { post, useMutation } = useApi();
const user = useUser();
const { user: login } = useLoginQuery();
- const { toast } = useToast();
- const { touch } = useModified();
- const { mutate, error } = useMutation({
- mutationFn: ({
- username,
- password,
- role,
- }: {
- username: string;
- password: string;
- role: string;
- }) => post(`/users/${userId}`, { username, password, role }),
- });
+ const { mutate, error, toast, touch } = useUpdateQuery(`/users/${userId}`);
const handleSubmit = async (data: any) => {
mutate(data, {
diff --git a/src/app/(main)/boards/BoardAddForm.tsx b/src/app/(main)/boards/BoardAddForm.tsx
index 075fac4f..fae3c70a 100644
--- a/src/app/(main)/boards/BoardAddForm.tsx
+++ b/src/app/(main)/boards/BoardAddForm.tsx
@@ -1,5 +1,5 @@
import { Form, FormField, FormSubmitButton, Row, TextField, Button } from '@umami/react-zen';
-import { useApi } from '@/components/hooks';
+import { useUpdateQuery } from '@/components/hooks';
import { DOMAIN_REGEX } from '@/lib/constants';
import { useMessages } from '@/components/hooks';
@@ -13,10 +13,7 @@ export function BoardAddForm({
onClose?: () => void;
}) {
const { formatMessage, labels, messages } = useMessages();
- const { post, useMutation } = useApi();
- const { mutate, error, isPending } = useMutation({
- mutationFn: (data: any) => post('/websites', { ...data, teamId }),
- });
+ const { mutate, error, isPending } = useUpdateQuery('/websites', { teamId });
const handleSubmit = async (data: any) => {
mutate(data, {
diff --git a/src/app/(main)/links/LinkDeleteButton.tsx b/src/app/(main)/links/LinkDeleteButton.tsx
index 276f4e8f..ba0eddbe 100644
--- a/src/app/(main)/links/LinkDeleteButton.tsx
+++ b/src/app/(main)/links/LinkDeleteButton.tsx
@@ -3,7 +3,7 @@ import { ActionButton } from '@/components/input/ActionButton';
import { Trash } from '@/components/icons';
import { ConfirmationForm } from '@/components/common/ConfirmationForm';
import { messages } from '@/components/messages';
-import { useApi, useMessages, useModified } from '@/components/hooks';
+import { useDeleteQuery, useMessages } from '@/components/hooks';
export function LinkDeleteButton({
linkId,
@@ -16,11 +16,7 @@ export function LinkDeleteButton({
onSave?: () => void;
}) {
const { formatMessage, labels } = useMessages();
- const { del, useMutation } = useApi();
- const { mutate, isPending, error } = useMutation({
- mutationFn: () => del(`/links/${linkId}`),
- });
- const { touch } = useModified();
+ const { mutate, isPending, error, touch } = useDeleteQuery(`/links/${linkId}`);
const handleConfirm = (close: () => void) => {
mutate(null, {
diff --git a/src/app/(main)/pixels/PixelDeleteButton.tsx b/src/app/(main)/pixels/PixelDeleteButton.tsx
index 70e2b1f6..6bbb514f 100644
--- a/src/app/(main)/pixels/PixelDeleteButton.tsx
+++ b/src/app/(main)/pixels/PixelDeleteButton.tsx
@@ -3,8 +3,7 @@ import { ActionButton } from '@/components/input/ActionButton';
import { Trash } from '@/components/icons';
import { ConfirmationForm } from '@/components/common/ConfirmationForm';
import { messages } from '@/components/messages';
-import { useApi, useMessages, useModified } from '@/components/hooks';
-
+import { useDeleteQuery, useMessages, useModified } from '@/components/hooks';
export function PixelDeleteButton({
pixelId,
name,
@@ -15,10 +14,7 @@ export function PixelDeleteButton({
onSave?: () => void;
}) {
const { formatMessage, labels } = useMessages();
- const { del, useMutation } = useApi();
- const { mutate, isPending, error } = useMutation({
- mutationFn: () => del(`/pixels/${pixelId}`),
- });
+ const { mutate, isPending, error } = useDeleteQuery(`/pixels/${pixelId}`);
const { touch } = useModified();
const handleConfirm = (close: () => void) => {
diff --git a/src/app/(main)/settings/profile/PasswordEditForm.tsx b/src/app/(main)/settings/profile/PasswordEditForm.tsx
index 8d8b6b56..c75840ae 100644
--- a/src/app/(main)/settings/profile/PasswordEditForm.tsx
+++ b/src/app/(main)/settings/profile/PasswordEditForm.tsx
@@ -6,14 +6,11 @@ import {
Button,
FormSubmitButton,
} from '@umami/react-zen';
-import { useApi, useMessages } from '@/components/hooks';
+import { useMessages, useUpdateQuery } from '@/components/hooks';
export function PasswordEditForm({ onSave, onClose }) {
const { formatMessage, labels, messages } = useMessages();
- const { post, useMutation } = useApi();
- const { mutate, error, isPending } = useMutation({
- mutationFn: (data: any) => post('/me/password', data),
- });
+ const { mutate, error, isPending } = useUpdateQuery('/me/password');
const handleSubmit = async (data: any) => {
mutate(data, {
diff --git a/src/app/(main)/teams/TeamAddForm.tsx b/src/app/(main)/teams/TeamAddForm.tsx
index 80fd0c62..1f80b2c2 100644
--- a/src/app/(main)/teams/TeamAddForm.tsx
+++ b/src/app/(main)/teams/TeamAddForm.tsx
@@ -1,4 +1,4 @@
-import { useApi, useMessages } from '@/components/hooks';
+import { useMessages, useUpdateQuery } from '@/components/hooks';
import {
Button,
Form,
@@ -10,10 +10,7 @@ import {
export function TeamAddForm({ onSave, onClose }: { onSave: () => void; onClose: () => void }) {
const { formatMessage, labels } = useMessages();
- const { post, useMutation } = useApi();
- const { mutate, error, isPending } = useMutation({
- mutationFn: (data: any) => post('/teams', data),
- });
+ const { mutate, error, isPending } = useUpdateQuery('/teams');
const handleSubmit = async (data: any) => {
mutate(data, {
diff --git a/src/app/(main)/teams/TeamJoinForm.tsx b/src/app/(main)/teams/TeamJoinForm.tsx
index 91ec5aaf..ca2e96ef 100644
--- a/src/app/(main)/teams/TeamJoinForm.tsx
+++ b/src/app/(main)/teams/TeamJoinForm.tsx
@@ -6,12 +6,11 @@ import {
Button,
FormSubmitButton,
} from '@umami/react-zen';
-import { useApi, useMessages, useModified } from '@/components/hooks';
+import { useMessages, useModified, useUpdateQuery } from '@/components/hooks';
export function TeamJoinForm({ onSave, onClose }: { onSave: () => void; onClose: () => void }) {
const { formatMessage, labels } = useMessages();
- const { post, useMutation } = useApi();
- const { mutate, error } = useMutation({ mutationFn: (data: any) => post('/teams/join', data) });
+ const { mutate, error } = useUpdateQuery('/teams/join');
const { touch } = useModified();
const handleSubmit = async (data: any) => {
diff --git a/src/app/(main)/teams/TeamLeaveForm.tsx b/src/app/(main)/teams/TeamLeaveForm.tsx
index 1923777f..0477ee1d 100644
--- a/src/app/(main)/teams/TeamLeaveForm.tsx
+++ b/src/app/(main)/teams/TeamLeaveForm.tsx
@@ -1,4 +1,4 @@
-import { useApi, useMessages, useModified } from '@/components/hooks';
+import { useDeleteQuery, useMessages, useModified } from '@/components/hooks';
import { ConfirmationForm } from '@/components/common/ConfirmationForm';
export function TeamLeaveForm({
@@ -15,10 +15,7 @@ export function TeamLeaveForm({
onClose: () => void;
}) {
const { formatMessage, labels, messages } = useMessages();
- const { del, useMutation } = useApi();
- const { mutate, error, isPending } = useMutation({
- mutationFn: () => del(`/teams/${teamId}/users/${userId}`),
- });
+ const { mutate, error, isPending } = useDeleteQuery(`/teams/${teamId}/users/${userId}`);
const { touch } = useModified();
const handleConfirm = async () => {
diff --git a/src/app/(main)/teams/[teamId]/TeamDeleteForm.tsx b/src/app/(main)/teams/[teamId]/TeamDeleteForm.tsx
index ef740d61..94c51d87 100644
--- a/src/app/(main)/teams/[teamId]/TeamDeleteForm.tsx
+++ b/src/app/(main)/teams/[teamId]/TeamDeleteForm.tsx
@@ -1,5 +1,5 @@
import { TypeConfirmationForm } from '@/components/common/TypeConfirmationForm';
-import { useApi, useMessages } from '@/components/hooks';
+import { useDeleteQuery, useMessages } from '@/components/hooks';
const CONFIRM_VALUE = 'DELETE';
@@ -13,14 +13,12 @@ export function TeamDeleteForm({
onClose?: () => void;
}) {
const { labels, formatMessage } = useMessages();
- const { del, useMutation } = useApi();
- const { mutate, error, isPending } = useMutation({
- mutationFn: () => del(`/teams/${teamId}`),
- });
+ const { mutate, error, isPending, touch } = useDeleteQuery(`/teams/${teamId}`);
const handleConfirm = async () => {
mutate(null, {
onSuccess: async () => {
+ touch('teams');
onSave?.();
onClose?.();
},
diff --git a/src/app/(main)/teams/[teamId]/TeamEditForm.tsx b/src/app/(main)/teams/[teamId]/TeamEditForm.tsx
index a7b3ff25..7be3e6a7 100644
--- a/src/app/(main)/teams/[teamId]/TeamEditForm.tsx
+++ b/src/app/(main)/teams/[teamId]/TeamEditForm.tsx
@@ -5,10 +5,9 @@ import {
FormSubmitButton,
TextField,
Button,
- useToast,
} from '@umami/react-zen';
import { getRandomChars } from '@/lib/crypto';
-import { useApi, useMessages, useModified, useTeam } from '@/components/hooks';
+import { useMessages, useTeam, useUpdateQuery } from '@/components/hooks';
const generateId = () => `team_${getRandomChars(16)}`;
@@ -23,20 +22,15 @@ export function TeamEditForm({
}) {
const team = useTeam();
const { formatMessage, labels, messages } = useMessages();
- const { post, useMutation } = useApi();
- const { toast } = useToast();
- const { touch } = useModified();
- const { mutate, error } = useMutation({
- mutationFn: (data: any) => post(`/teams/${teamId}`, data),
- });
+ const { mutate, error, isPending, touch, toast } = useUpdateQuery(`/teams/${teamId}`);
const handleSubmit = async (data: any) => {
mutate(data, {
onSuccess: async () => {
+ toast(formatMessage(messages.saved));
touch('teams');
touch(`teams:${teamId}`);
- toast(formatMessage(messages.saved));
onSave?.();
},
});
@@ -65,7 +59,9 @@ export function TeamEditForm({
- {formatMessage(labels.save)}
+
+ {formatMessage(labels.save)}
+
)}
>
diff --git a/src/app/(main)/teams/[teamId]/TeamMemberEditForm.tsx b/src/app/(main)/teams/[teamId]/TeamMemberEditForm.tsx
index 23abbe33..e2c264ab 100644
--- a/src/app/(main)/teams/[teamId]/TeamMemberEditForm.tsx
+++ b/src/app/(main)/teams/[teamId]/TeamMemberEditForm.tsx
@@ -1,4 +1,4 @@
-import { useApi, useMessages } from '@/components/hooks';
+import { useMessages, useUpdateQuery } from '@/components/hooks';
import { ROLES } from '@/lib/constants';
import {
Button,
@@ -23,10 +23,7 @@ export function TeamMemberEditForm({
onSave?: () => void;
onClose?: () => void;
}) {
- const { post, useMutation } = useApi();
- const { mutate, error, isPending } = useMutation({
- mutationFn: (data: any) => post(`/teams/${teamId}/users/${userId}`, data),
- });
+ const { mutate, error, isPending } = useUpdateQuery(`/teams/${teamId}/users/${userId}`);
const { formatMessage, labels } = useMessages();
const handleSubmit = async (data: any) => {
diff --git a/src/app/(main)/teams/[teamId]/TeamMemberRemoveButton.tsx b/src/app/(main)/teams/[teamId]/TeamMemberRemoveButton.tsx
index db2a1894..66d540b0 100644
--- a/src/app/(main)/teams/[teamId]/TeamMemberRemoveButton.tsx
+++ b/src/app/(main)/teams/[teamId]/TeamMemberRemoveButton.tsx
@@ -1,5 +1,5 @@
import { ConfirmationForm } from '@/components/common/ConfirmationForm';
-import { useApi, useMessages, useModified } from '@/components/hooks';
+import { useDeleteQuery, useMessages, useModified } from '@/components/hooks';
import { messages } from '@/components/messages';
import { Trash } from '@/components/icons';
import { Dialog } from '@umami/react-zen';
@@ -18,10 +18,7 @@ export function TeamMemberRemoveButton({
onSave?: () => void;
}) {
const { formatMessage, labels } = useMessages();
- const { del, useMutation } = useApi();
- const { mutate, isPending, error } = useMutation({
- mutationFn: () => del(`/teams/${teamId}/users/${userId}`),
- });
+ const { mutate, isPending, error } = useDeleteQuery(`/teams/${teamId}/users/${userId}`);
const { touch } = useModified();
const handleConfirm = (close: () => void) => {
diff --git a/src/app/(main)/teams/[teamId]/TeamWebsiteRemoveButton.tsx b/src/app/(main)/teams/[teamId]/TeamWebsiteRemoveButton.tsx
index 38f0252b..34e8184e 100644
--- a/src/app/(main)/teams/[teamId]/TeamWebsiteRemoveButton.tsx
+++ b/src/app/(main)/teams/[teamId]/TeamWebsiteRemoveButton.tsx
@@ -1,13 +1,10 @@
-import { useApi, useMessages } from '@/components/hooks';
+import { useDeleteQuery, useMessages } from '@/components/hooks';
import { Icon, LoadingButton, Text } from '@umami/react-zen';
import { Close } from '@/components/icons';
export function TeamWebsiteRemoveButton({ teamId, websiteId, onSave }) {
const { formatMessage, labels } = useMessages();
- const { del, useMutation } = useApi();
- const { mutate, isPending } = useMutation({
- mutationFn: () => del(`/teams/${teamId}/websites/${websiteId}`),
- });
+ const { mutate, isPending } = useDeleteQuery(`/teams/${teamId}/websites/${websiteId}`);
const handleRemoveTeamMember = async () => {
mutate(null, {
diff --git a/src/app/(main)/websites/WebsiteAddForm.tsx b/src/app/(main)/websites/WebsiteAddForm.tsx
index 91d4d846..e2be2563 100644
--- a/src/app/(main)/websites/WebsiteAddForm.tsx
+++ b/src/app/(main)/websites/WebsiteAddForm.tsx
@@ -1,5 +1,5 @@
import { Form, FormField, FormSubmitButton, Row, TextField, Button } from '@umami/react-zen';
-import { useApi } from '@/components/hooks';
+import { useUpdateQuery } from '@/components/hooks';
import { DOMAIN_REGEX } from '@/lib/constants';
import { useMessages } from '@/components/hooks';
@@ -13,10 +13,7 @@ export function WebsiteAddForm({
onClose?: () => void;
}) {
const { formatMessage, labels, messages } = useMessages();
- const { post, useMutation } = useApi();
- const { mutate, error, isPending } = useMutation({
- mutationFn: (data: any) => post('/websites', { ...data, teamId }),
- });
+ const { mutate, error, isPending } = useUpdateQuery('/websites', { teamId });
const handleSubmit = async (data: any) => {
mutate(data, {
diff --git a/src/app/(main)/websites/[websiteId]/(reports)/funnels/FunnelEditForm.tsx b/src/app/(main)/websites/[websiteId]/(reports)/funnels/FunnelEditForm.tsx
index 8c83b26f..c1dbde08 100644
--- a/src/app/(main)/websites/[websiteId]/(reports)/funnels/FunnelEditForm.tsx
+++ b/src/app/(main)/websites/[websiteId]/(reports)/funnels/FunnelEditForm.tsx
@@ -15,7 +15,7 @@ import {
Row,
Loading,
} from '@umami/react-zen';
-import { useApi, useMessages, useModified, useReportQuery } from '@/components/hooks';
+import { useMessages, useReportQuery, useUpdateQuery } from '@/components/hooks';
import { File, Lightning, Close, Plus } from '@/components/icons';
const FUNNEL_STEPS_MAX = 8;
@@ -32,12 +32,8 @@ export function FunnelEditForm({
onClose?: () => void;
}) {
const { formatMessage, labels } = useMessages();
- const { touch } = useModified();
- const { post, useMutation } = useApi();
const { data } = useReportQuery(id);
- const { mutate, error, isPending } = useMutation({
- mutationFn: (params: any) => post(`/reports${id ? `/${id}` : ''}`, params),
- });
+ const { mutate, error, isPending, touch } = useUpdateQuery(`/reports${id ? `/${id}` : ''}`);
const handleSubmit = async ({ name, ...parameters }) => {
mutate(
diff --git a/src/app/(main)/websites/[websiteId]/(reports)/goals/GoalEditForm.tsx b/src/app/(main)/websites/[websiteId]/(reports)/goals/GoalEditForm.tsx
index e1a3d97a..f8ff296f 100644
--- a/src/app/(main)/websites/[websiteId]/(reports)/goals/GoalEditForm.tsx
+++ b/src/app/(main)/websites/[websiteId]/(reports)/goals/GoalEditForm.tsx
@@ -12,7 +12,7 @@ import {
Icon,
Loading,
} from '@umami/react-zen';
-import { useApi, useMessages, useModified, useReportQuery } from '@/components/hooks';
+import { useMessages, useReportQuery, useUpdateQuery } from '@/components/hooks';
import { File, Lightning } from '@/components/icons';
export function GoalEditForm({
@@ -27,12 +27,9 @@ export function GoalEditForm({
onClose?: () => void;
}) {
const { formatMessage, labels } = useMessages();
- const { touch } = useModified();
- const { post, useMutation } = useApi();
+
const { data } = useReportQuery(id);
- const { mutate, error, isPending } = useMutation({
- mutationFn: (params: any) => post(`/reports${id ? `/${id}` : ''}`, params),
- });
+ const { mutate, error, isPending, touch } = useUpdateQuery(`/reports${id ? `/${id}` : ''}`);
const handleSubmit = async ({ name, ...parameters }) => {
mutate(
diff --git a/src/app/(main)/websites/[websiteId]/WebsiteNav.tsx b/src/app/(main)/websites/[websiteId]/WebsiteNav.tsx
index 7637a452..78d31ade 100644
--- a/src/app/(main)/websites/[websiteId]/WebsiteNav.tsx
+++ b/src/app/(main)/websites/[websiteId]/WebsiteNav.tsx
@@ -24,7 +24,11 @@ export function WebsiteNav({ websiteId }: { websiteId: string }) {
const { pathname, renderUrl, teamId } = useNavigation();
const renderPath = (path: string) =>
- renderUrl(`/websites/${websiteId}${path}`, { event: undefined });
+ renderUrl(`/websites/${websiteId}${path}`, {
+ event: undefined,
+ compare: undefined,
+ view: undefined,
+ });
const items = [
{
diff --git a/src/app/(main)/websites/[websiteId]/cohorts/CohortDeleteButton.tsx b/src/app/(main)/websites/[websiteId]/cohorts/CohortDeleteButton.tsx
index 043b51f9..9e56a875 100644
--- a/src/app/(main)/websites/[websiteId]/cohorts/CohortDeleteButton.tsx
+++ b/src/app/(main)/websites/[websiteId]/cohorts/CohortDeleteButton.tsx
@@ -3,7 +3,7 @@ import { ActionButton } from '@/components/input/ActionButton';
import { Trash } from '@/components/icons';
import { ConfirmationForm } from '@/components/common/ConfirmationForm';
import { messages } from '@/components/messages';
-import { useApi, useMessages, useModified } from '@/components/hooks';
+import { useDeleteQuery, useMessages } from '@/components/hooks';
export function CohortDeleteButton({
cohortId,
@@ -17,11 +17,9 @@ export function CohortDeleteButton({
onSave?: () => void;
}) {
const { formatMessage, labels } = useMessages();
- const { del, useMutation } = useApi();
- const { mutate, isPending, error } = useMutation({
- mutationFn: () => del(`/websites/${websiteId}/segments/${cohortId}`),
- });
- const { touch } = useModified();
+ const { mutate, isPending, error, touch } = useDeleteQuery(
+ `/websites/${websiteId}/segments/${cohortId}`,
+ );
const handleConfirm = (close: () => void) => {
mutate(null, {
diff --git a/src/app/(main)/websites/[websiteId]/cohorts/CohortEditForm.tsx b/src/app/(main)/websites/[websiteId]/cohorts/CohortEditForm.tsx
index 6b16a470..1a9f0d0b 100644
--- a/src/app/(main)/websites/[websiteId]/cohorts/CohortEditForm.tsx
+++ b/src/app/(main)/websites/[websiteId]/cohorts/CohortEditForm.tsx
@@ -11,7 +11,7 @@ import {
import { subMonths, endOfDay } from 'date-fns';
import { FieldFilters } from '@/components/input/FieldFilters';
import { useState } from 'react';
-import { useApi, useMessages, useModified, useWebsiteCohortQuery } from '@/components/hooks';
+import { useMessages, useUpdateQuery, useWebsiteCohortQuery } from '@/components/hooks';
import { filtersArrayToObject } from '@/lib/params';
export function CohortEditForm({
@@ -30,26 +30,25 @@ export function CohortEditForm({
onClose?: () => void;
}) {
const { data } = useWebsiteCohortQuery(websiteId, cohortId);
- const { formatMessage, labels } = useMessages();
+ const { formatMessage, labels, messages } = useMessages();
const [currentFilters, setCurrentFilters] = useState(filters);
- const { touch } = useModified();
const startDate = subMonths(endOfDay(new Date()), 6);
const endDate = endOfDay(new Date());
- const { post, useMutation } = useApi();
- const { mutate, error, isPending } = useMutation({
- mutationFn: (data: any) =>
- post(`/websites/${websiteId}/cohorts${cohortId ? `/${cohortId}` : ''}`, {
- ...data,
- type: 'cohort',
- }),
- });
+ const { mutate, error, isPending, touch, toast } = useUpdateQuery(
+ `/websites/${websiteId}/cohorts${cohortId ? `/${cohortId}` : ''}`,
+ {
+ ...data,
+ type: 'cohort',
+ },
+ );
const handleSubmit = async (data: any) => {
mutate(
{ ...data, parameters: filtersArrayToObject(currentFilters) },
{
onSuccess: async () => {
+ toast(formatMessage(messages.save));
touch('cohorts');
onSave?.();
onClose?.();
diff --git a/src/app/(main)/websites/[websiteId]/compare/CompareTables.tsx b/src/app/(main)/websites/[websiteId]/compare/CompareTables.tsx
index 7ba728b5..32f859fc 100644
--- a/src/app/(main)/websites/[websiteId]/compare/CompareTables.tsx
+++ b/src/app/(main)/websites/[websiteId]/compare/CompareTables.tsx
@@ -17,80 +17,98 @@ export function CompareTables({ websiteId }: { websiteId: string }) {
updateParams,
query: { view = 'path' },
} = useNavigation();
+ const { startDate, endDate } = getCompareDate(
+ dateCompare,
+ dateRange.startDate,
+ dateRange.endDate,
+ );
+
+ const params = {
+ startAt: startDate.getTime(),
+ endAt: endDate.getTime(),
+ };
+
+ const renderPath = (view: string) => {
+ return updateParams({ view });
+ };
const items = [
{
id: 'path',
label: formatMessage(labels.path),
- path: updateParams({ view: 'path' }),
+ path: renderPath('path'),
+ },
+ {
+ id: 'channel',
+ label: formatMessage(labels.channels),
+ path: renderPath('channel'),
},
{
id: 'referrer',
label: formatMessage(labels.referrers),
- path: updateParams({ view: 'referrer' }),
+ path: renderPath('referrer'),
},
{
id: 'browser',
label: formatMessage(labels.browsers),
- path: updateParams({ view: 'browser' }),
+ path: renderPath('browser'),
},
{
id: 'os',
label: formatMessage(labels.os),
- path: updateParams({ view: 'os' }),
+ path: renderPath('os'),
},
{
id: 'device',
label: formatMessage(labels.devices),
- path: updateParams({ view: 'device' }),
+ path: renderPath('device'),
},
{
id: 'country',
label: formatMessage(labels.countries),
- path: updateParams({ view: 'country' }),
+ path: renderPath('country'),
},
{
id: 'region',
label: formatMessage(labels.regions),
- path: updateParams({ view: 'region' }),
+ path: renderPath('region'),
},
{
id: 'city',
label: formatMessage(labels.cities),
- path: updateParams({ view: 'city' }),
+ path: renderPath('city'),
},
{
id: 'language',
label: formatMessage(labels.languages),
- path: updateParams({ view: 'language' }),
+ path: renderPath('language'),
},
{
id: 'screen',
label: formatMessage(labels.screens),
- path: updateParams({ view: 'screen' }),
+ path: renderPath('screen'),
},
{
id: 'event',
label: formatMessage(labels.events),
- path: updateParams({ view: 'event' }),
+ path: renderPath('event'),
},
{
id: 'hostname',
label: formatMessage(labels.hostname),
- path: updateParams({ view: 'hostname' }),
+ path: renderPath('hostname'),
},
{
id: 'tag',
label: formatMessage(labels.tags),
- path: updateParams({ view: 'tag' }),
+ path: renderPath('tag'),
},
];
- const renderChange = props => {
- const { label: x, count: y } = props;
- const prev = data.find(d => d.x === x)?.y;
- const value = y - prev;
- const change = Math.abs(((y - prev) / prev) * 100);
+ const renderChange = ({ label, count }) => {
+ const prev = data.find(d => d.x === label)?.y;
+ const value = count - prev;
+ const change = Math.abs(((count - prev) / prev) * 100);
return (
!isNaN(change) && (
@@ -101,19 +119,8 @@ export function CompareTables({ websiteId }: { websiteId: string }) {
);
};
- const handleChange = id => {
- router.push(updateParams({ view: id }));
- };
-
- const { startDate, endDate } = getCompareDate(
- dateCompare,
- dateRange.startDate,
- dateRange.endDate,
- );
-
- const params = {
- startAt: startDate.getTime(),
- endAt: endDate.getTime(),
+ const handleChange = (id: any) => {
+ router.push(renderPath(id));
};
return (
@@ -133,8 +140,8 @@ export function CompareTables({ websiteId }: { websiteId: string }) {
))}
-
-
+
+
{formatMessage(labels.previous)}
diff --git a/src/app/(main)/websites/[websiteId]/segments/SegmentDeleteButton.tsx b/src/app/(main)/websites/[websiteId]/segments/SegmentDeleteButton.tsx
index 3561af85..f212187b 100644
--- a/src/app/(main)/websites/[websiteId]/segments/SegmentDeleteButton.tsx
+++ b/src/app/(main)/websites/[websiteId]/segments/SegmentDeleteButton.tsx
@@ -3,7 +3,7 @@ import { ActionButton } from '@/components/input/ActionButton';
import { Trash } from '@/components/icons';
import { ConfirmationForm } from '@/components/common/ConfirmationForm';
import { messages } from '@/components/messages';
-import { useApi, useMessages, useModified } from '@/components/hooks';
+import { useDeleteQuery, useMessages } from '@/components/hooks';
export function SegmentDeleteButton({
segmentId,
@@ -17,11 +17,9 @@ export function SegmentDeleteButton({
onSave?: () => void;
}) {
const { formatMessage, labels } = useMessages();
- const { del, useMutation } = useApi();
- const { mutate, isPending, error } = useMutation({
- mutationFn: () => del(`/websites/${websiteId}/segments/${segmentId}`),
- });
- const { touch } = useModified();
+ const { mutate, isPending, error, touch } = useDeleteQuery(
+ `/websites/${websiteId}/segments/${segmentId}`,
+ );
const handleConfirm = (close: () => void) => {
mutate(null, {
diff --git a/src/app/(main)/websites/[websiteId]/settings/WebsiteDeleteForm.tsx b/src/app/(main)/websites/[websiteId]/settings/WebsiteDeleteForm.tsx
index b6e723d7..a123813d 100644
--- a/src/app/(main)/websites/[websiteId]/settings/WebsiteDeleteForm.tsx
+++ b/src/app/(main)/websites/[websiteId]/settings/WebsiteDeleteForm.tsx
@@ -1,4 +1,4 @@
-import { useApi, useMessages, useModified } from '@/components/hooks';
+import { useDeleteQuery, useMessages } from '@/components/hooks';
import { TypeConfirmationForm } from '@/components/common/TypeConfirmationForm';
const CONFIRM_VALUE = 'DELETE';
@@ -13,11 +13,7 @@ export function WebsiteDeleteForm({
onClose?: () => void;
}) {
const { formatMessage, labels } = useMessages();
- const { del, useMutation } = useApi();
- const { mutate, isPending, error } = useMutation({
- mutationFn: () => del(`/websites/${websiteId}`),
- });
- const { touch } = useModified();
+ const { mutate, isPending, error, touch } = useDeleteQuery(`/websites/${websiteId}`);
const handleConfirm = async () => {
mutate(null, {
diff --git a/src/app/(main)/websites/[websiteId]/settings/WebsiteEditForm.tsx b/src/app/(main)/websites/[websiteId]/settings/WebsiteEditForm.tsx
index 5beeaf70..9220e071 100644
--- a/src/app/(main)/websites/[websiteId]/settings/WebsiteEditForm.tsx
+++ b/src/app/(main)/websites/[websiteId]/settings/WebsiteEditForm.tsx
@@ -1,24 +1,11 @@
-import {
- FormSubmitButton,
- Form,
- FormField,
- FormButtons,
- TextField,
- useToast,
-} from '@umami/react-zen';
-import { useApi, useMessages, useModified, useWebsite } from '@/components/hooks';
+import { FormSubmitButton, Form, FormField, FormButtons, TextField } from '@umami/react-zen';
+import { useMessages, useUpdateQuery, useWebsite } from '@/components/hooks';
import { DOMAIN_REGEX } from '@/lib/constants';
export function WebsiteEditForm({ websiteId, onSave }: { websiteId: string; onSave?: () => void }) {
const website = useWebsite();
const { formatMessage, labels, messages } = useMessages();
- const { post, useMutation } = useApi();
- const { toast } = useToast();
- const { touch } = useModified();
-
- const { mutate, error } = useMutation({
- mutationFn: (data: any) => post(`/websites/${websiteId}`, data),
- });
+ const { mutate, error, touch, toast } = useUpdateQuery(`/websites/${websiteId}`);
const handleSubmit = async (data: any) => {
mutate(data, {
diff --git a/src/app/(main)/websites/[websiteId]/settings/WebsiteResetForm.tsx b/src/app/(main)/websites/[websiteId]/settings/WebsiteResetForm.tsx
index 89e93ad4..3c990ded 100644
--- a/src/app/(main)/websites/[websiteId]/settings/WebsiteResetForm.tsx
+++ b/src/app/(main)/websites/[websiteId]/settings/WebsiteResetForm.tsx
@@ -1,4 +1,4 @@
-import { useApi, useMessages } from '@/components/hooks';
+import { useMessages, useUpdateQuery } from '@/components/hooks';
import { TypeConfirmationForm } from '@/components/common/TypeConfirmationForm';
const CONFIRM_VALUE = 'RESET';
@@ -13,10 +13,7 @@ export function WebsiteResetForm({
onClose?: () => void;
}) {
const { formatMessage, labels } = useMessages();
- const { post, useMutation } = useApi();
- const { mutate, isPending, error } = useMutation({
- mutationFn: (data: any) => post(`/websites/${websiteId}/reset`, data),
- });
+ const { mutate, isPending, error } = useUpdateQuery(`/websites/${websiteId}/reset`);
const handleConfirm = async () => {
mutate(null, {
diff --git a/src/app/(main)/websites/[websiteId]/settings/WebsiteShareForm.tsx b/src/app/(main)/websites/[websiteId]/settings/WebsiteShareForm.tsx
index 4f3fe247..ef225d19 100644
--- a/src/app/(main)/websites/[websiteId]/settings/WebsiteShareForm.tsx
+++ b/src/app/(main)/websites/[websiteId]/settings/WebsiteShareForm.tsx
@@ -7,12 +7,11 @@ import {
FormSubmitButton,
Column,
Label,
- useToast,
Row,
} from '@umami/react-zen';
import { useState } from 'react';
import { getRandomChars } from '@/lib/crypto';
-import { useApi, useMessages, useModified } from '@/components/hooks';
+import { useMessages, useUpdateQuery } from '@/components/hooks';
const generateId = () => getRandomChars(16);
@@ -26,12 +25,7 @@ export interface WebsiteShareFormProps {
export function WebsiteShareForm({ websiteId, shareId, onSave, onClose }: WebsiteShareFormProps) {
const { formatMessage, labels, messages } = useMessages();
const [id, setId] = useState(shareId);
- const { post, useMutation } = useApi();
- const { mutate, error, isPending } = useMutation({
- mutationFn: (data: any) => post(`/websites/${websiteId}`, data),
- });
- const { touch } = useModified();
- const { toast } = useToast();
+ const { mutate, error, isPending, touch, toast } = useUpdateQuery(`/websites/${websiteId}`);
const url = `${window?.location.origin || ''}${process.env.basePath || ''}/share/${id}`;
diff --git a/src/app/login/LoginForm.tsx b/src/app/login/LoginForm.tsx
index 795f855a..6c732a06 100644
--- a/src/app/login/LoginForm.tsx
+++ b/src/app/login/LoginForm.tsx
@@ -10,7 +10,7 @@ import {
Heading,
} from '@umami/react-zen';
import { useRouter } from 'next/navigation';
-import { useApi, useMessages } from '@/components/hooks';
+import { useMessages, useUpdateQuery } from '@/components/hooks';
import { setUser } from '@/store/app';
import { setClientAuthToken } from '@/lib/client';
import { Logo } from '@/components/icons';
@@ -18,10 +18,7 @@ import { Logo } from '@/components/icons';
export function LoginForm() {
const { formatMessage, labels, getMessage } = useMessages();
const router = useRouter();
- const { post, useMutation } = useApi();
- const { mutate, error, isPending } = useMutation({
- mutationFn: (data: any) => post('/auth/login', data),
- });
+ const { mutate, error, isPending } = useUpdateQuery('/auth/login');
const handleSubmit = async (data: any) => {
mutate(data, {
diff --git a/src/components/hooks/queries/useDeleteQuery.ts b/src/components/hooks/queries/useDeleteQuery.ts
index db5e91d8..95e2c99a 100644
--- a/src/components/hooks/queries/useDeleteQuery.ts
+++ b/src/components/hooks/queries/useDeleteQuery.ts
@@ -2,10 +2,10 @@ import { useApi, useModified } from '@/components/hooks';
export function useDeleteQuery(path: string, params?: Record) {
const { del, useMutation } = useApi();
- const { mutate, isPending, error } = useMutation({
+ const query = useMutation({
mutationFn: () => del(path, params),
});
const { touch } = useModified();
- return { mutate, isPending, error, touch };
+ return { ...query, touch };
}
diff --git a/src/components/hooks/queries/useUpdateQuery.ts b/src/components/hooks/queries/useUpdateQuery.ts
index dd4e2247..ac280d8d 100644
--- a/src/components/hooks/queries/useUpdateQuery.ts
+++ b/src/components/hooks/queries/useUpdateQuery.ts
@@ -4,11 +4,11 @@ import { useToast } from '@umami/react-zen';
export function useUpdateQuery(path: string, params?: Record) {
const { post, useMutation } = useApi();
- const { mutate, isPending, error } = useMutation({
+ const query = useMutation({
mutationFn: (data: Record) => post(path, { ...data, ...params }),
});
const { touch } = useModified();
const { toast } = useToast();
- return { mutate, isPending, error, touch, toast };
+ return { ...query, touch, toast };
}
diff --git a/src/components/metrics/MetricsTable.tsx b/src/components/metrics/MetricsTable.tsx
index 6854f44e..fcf8e7b8 100644
--- a/src/components/metrics/MetricsTable.tsx
+++ b/src/components/metrics/MetricsTable.tsx
@@ -68,13 +68,7 @@ export function MetricsTable({
};
return (
-
+
{data && }
{showMore && limit && (
diff --git a/src/components/metrics/PageviewsChart.tsx b/src/components/metrics/PageviewsChart.tsx
index 155c1ff7..59c3ad05 100644
--- a/src/components/metrics/PageviewsChart.tsx
+++ b/src/components/metrics/PageviewsChart.tsx
@@ -31,6 +31,7 @@ export function PageviewsChart({ data, unit, minDate, maxDate, ...props }: Pagev
__id: new Date().getTime(),
datasets: [
{
+ type: data.compare ? 'line' : 'bar',
label: formatMessage(labels.visitors),
data: generateTimeSeries(data.sessions, minDate, maxDate, unit, dateLocale),
borderWidth: 1,
@@ -40,6 +41,7 @@ export function PageviewsChart({ data, unit, minDate, maxDate, ...props }: Pagev
order: 3,
},
{
+ type: data.compare ? 'line' : 'bar',
label: formatMessage(labels.views),
data: generateTimeSeries(data.pageviews, minDate, maxDate, unit, dateLocale),
barPercentage: 0.9,