Converted mutation queries.

This commit is contained in:
Mike Cao 2025-08-24 15:20:19 -07:00
parent 3f167e05ba
commit 0f9669f886
34 changed files with 259 additions and 350 deletions

View file

@ -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",

258
pnpm-lock.yaml generated
View file

@ -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)

View file

@ -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) => {

View file

@ -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 () => {

View file

@ -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, {

View file

@ -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, {

View file

@ -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, {

View file

@ -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) => {

View file

@ -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, {

View file

@ -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, {

View file

@ -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) => {

View file

@ -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 () => {

View file

@ -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?.();
},

View file

@ -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({
<Button onPress={() => setValue('accessCode', generateId(), { shouldDirty: true })}>
{formatMessage(labels.regenerate)}
</Button>
<FormSubmitButton variant="primary">{formatMessage(labels.save)}</FormSubmitButton>
<FormSubmitButton variant="primary" isPending={isPending}>
{formatMessage(labels.save)}
</FormSubmitButton>
</FormButtons>
)}
</>

View file

@ -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) => {

View file

@ -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) => {

View file

@ -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, {

View file

@ -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, {

View file

@ -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(

View file

@ -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(

View file

@ -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 = [
{

View file

@ -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, {

View file

@ -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?.();

View file

@ -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 }) {
))}
</Select>
</Row>
<Panel>
<Grid columns={{ xs: '1fr', lg: '1fr 1fr' }} gap="6">
<Panel minHeight="300px">
<Grid columns={{ xs: '1fr', lg: '1fr 1fr' }} gap="6" height="100%">
<Column gap="6">
<Row alignItems="center" justifyContent="space-between">
<Heading size="2">{formatMessage(labels.previous)}</Heading>

View file

@ -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, {

View file

@ -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, {

View file

@ -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, {

View file

@ -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, {

View file

@ -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}`;

View file

@ -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, {

View file

@ -2,10 +2,10 @@ import { useApi, useModified } from '@/components/hooks';
export function useDeleteQuery(path: string, params?: Record<string, any>) {
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 };
}

View file

@ -4,11 +4,11 @@ import { useToast } from '@umami/react-zen';
export function useUpdateQuery(path: string, params?: Record<string, any>) {
const { post, useMutation } = useApi();
const { mutate, isPending, error } = useMutation({
const query = useMutation({
mutationFn: (data: Record<string, any>) => post(path, { ...data, ...params }),
});
const { touch } = useModified();
const { toast } = useToast();
return { mutate, isPending, error, touch, toast };
return { ...query, touch, toast };
}

View file

@ -68,13 +68,7 @@ export function MetricsTable({
};
return (
<LoadingPanel
data={data}
isFetching={isFetching}
isLoading={isLoading}
error={error}
height="100%"
>
<LoadingPanel data={data} isFetching={isFetching} isLoading={isLoading} error={error}>
{data && <ListTable {...props} data={filteredData} renderLabel={renderLabel} />}
{showMore && limit && (
<Row justifyContent="center">

View file

@ -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,