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,