mirror of
https://github.com/umami-software/umami.git
synced 2026-02-12 00:27:11 +01:00
Panels redesign.
This commit is contained in:
parent
7886c3f393
commit
f5bc3dc6c2
58 changed files with 530 additions and 733 deletions
|
|
@ -107,7 +107,7 @@
|
||||||
"lucide-react": "^0.475.0",
|
"lucide-react": "^0.475.0",
|
||||||
"maxmind": "^4.3.24",
|
"maxmind": "^4.3.24",
|
||||||
"md5": "^2.3.0",
|
"md5": "^2.3.0",
|
||||||
"next": "15.2.2",
|
"next": "15.2.4",
|
||||||
"node-fetch": "^3.3.2",
|
"node-fetch": "^3.3.2",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"prisma": "6.5.0",
|
"prisma": "6.5.0",
|
||||||
|
|
@ -139,9 +139,8 @@
|
||||||
"@rollup/plugin-terser": "^0.4.4",
|
"@rollup/plugin-terser": "^0.4.4",
|
||||||
"@svgr/cli": "^8.1.0",
|
"@svgr/cli": "^8.1.0",
|
||||||
"@svgr/rollup": "^8.1.0",
|
"@svgr/rollup": "^8.1.0",
|
||||||
"@svgr/webpack": "^8.1.0",
|
|
||||||
"@types/jest": "^29.5.14",
|
"@types/jest": "^29.5.14",
|
||||||
"@types/node": "^22.13.8",
|
"@types/node": "^22.13.11",
|
||||||
"@types/react": "^19.0.10",
|
"@types/react": "^19.0.10",
|
||||||
"@types/react-dom": "^19.0.4",
|
"@types/react-dom": "^19.0.4",
|
||||||
"@types/react-window": "^1.8.8",
|
"@types/react-window": "^1.8.8",
|
||||||
|
|
|
||||||
255
pnpm-lock.yaml
generated
255
pnpm-lock.yaml
generated
|
|
@ -132,8 +132,8 @@ importers:
|
||||||
specifier: ^2.3.0
|
specifier: ^2.3.0
|
||||||
version: 2.3.0
|
version: 2.3.0
|
||||||
next:
|
next:
|
||||||
specifier: 15.2.2
|
specifier: 15.2.4
|
||||||
version: 15.2.2(@babel/core@7.26.9)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
version: 15.2.4(@babel/core@7.26.9)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||||
node-fetch:
|
node-fetch:
|
||||||
specifier: ^3.3.2
|
specifier: ^3.3.2
|
||||||
version: 3.3.2
|
version: 3.3.2
|
||||||
|
|
@ -194,7 +194,7 @@ importers:
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@formatjs/cli':
|
'@formatjs/cli':
|
||||||
specifier: ^4.8.4
|
specifier: ^4.8.4
|
||||||
version: 4.8.4(ts-jest@29.2.6(@babel/core@7.26.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.9))(esbuild@0.25.1)(jest@29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2)))(typescript@5.8.2))
|
version: 4.8.4(ts-jest@29.2.6(@babel/core@7.26.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.9))(esbuild@0.25.1)(jest@29.7.0(@types/node@22.13.11)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2)))(typescript@5.8.2))
|
||||||
'@netlify/plugin-nextjs':
|
'@netlify/plugin-nextjs':
|
||||||
specifier: ^5.10.0
|
specifier: ^5.10.0
|
||||||
version: 5.10.0
|
version: 5.10.0
|
||||||
|
|
@ -222,15 +222,12 @@ importers:
|
||||||
'@svgr/rollup':
|
'@svgr/rollup':
|
||||||
specifier: ^8.1.0
|
specifier: ^8.1.0
|
||||||
version: 8.1.0(rollup@3.29.5)(typescript@5.8.2)
|
version: 8.1.0(rollup@3.29.5)(typescript@5.8.2)
|
||||||
'@svgr/webpack':
|
|
||||||
specifier: ^8.1.0
|
|
||||||
version: 8.1.0(typescript@5.8.2)
|
|
||||||
'@types/jest':
|
'@types/jest':
|
||||||
specifier: ^29.5.14
|
specifier: ^29.5.14
|
||||||
version: 29.5.14
|
version: 29.5.14
|
||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^22.13.8
|
specifier: ^22.13.11
|
||||||
version: 22.13.9
|
version: 22.13.11
|
||||||
'@types/react':
|
'@types/react':
|
||||||
specifier: ^19.0.10
|
specifier: ^19.0.10
|
||||||
version: 19.0.10
|
version: 19.0.10
|
||||||
|
|
@ -278,19 +275,19 @@ importers:
|
||||||
version: 2.31.0(@typescript-eslint/parser@8.26.1(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-typescript@3.8.3)(eslint@8.57.1)
|
version: 2.31.0(@typescript-eslint/parser@8.26.1(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-typescript@3.8.3)(eslint@8.57.1)
|
||||||
eslint-plugin-jest:
|
eslint-plugin-jest:
|
||||||
specifier: ^27.9.0
|
specifier: ^27.9.0
|
||||||
version: 27.9.0(@typescript-eslint/eslint-plugin@8.26.1(@typescript-eslint/parser@8.26.1(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(jest@29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2)))(typescript@5.8.2)
|
version: 27.9.0(@typescript-eslint/eslint-plugin@8.26.1(@typescript-eslint/parser@8.26.1(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(jest@29.7.0(@types/node@22.13.11)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2)))(typescript@5.8.2)
|
||||||
eslint-plugin-prettier:
|
eslint-plugin-prettier:
|
||||||
specifier: ^4.2.1
|
specifier: ^4.2.1
|
||||||
version: 4.2.1(eslint-config-prettier@8.10.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.8.8)
|
version: 4.2.1(eslint-config-prettier@8.10.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.8.8)
|
||||||
extract-react-intl-messages:
|
extract-react-intl-messages:
|
||||||
specifier: ^4.1.1
|
specifier: ^4.1.1
|
||||||
version: 4.1.1(ts-jest@29.2.6(@babel/core@7.26.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.9))(esbuild@0.25.1)(jest@29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2)))(typescript@5.8.2))
|
version: 4.1.1(ts-jest@29.2.6(@babel/core@7.26.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.9))(esbuild@0.25.1)(jest@29.7.0(@types/node@22.13.11)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2)))(typescript@5.8.2))
|
||||||
husky:
|
husky:
|
||||||
specifier: ^8.0.3
|
specifier: ^8.0.3
|
||||||
version: 8.0.3
|
version: 8.0.3
|
||||||
jest:
|
jest:
|
||||||
specifier: ^29.7.0
|
specifier: ^29.7.0
|
||||||
version: 29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2))
|
version: 29.7.0(@types/node@22.13.11)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2))
|
||||||
lint-staged:
|
lint-staged:
|
||||||
specifier: ^14.0.1
|
specifier: ^14.0.1
|
||||||
version: 14.0.1(enquirer@2.4.1)
|
version: 14.0.1(enquirer@2.4.1)
|
||||||
|
|
@ -335,7 +332,7 @@ importers:
|
||||||
version: 6.1.2(rollup@3.29.5)
|
version: 6.1.2(rollup@3.29.5)
|
||||||
rollup-plugin-postcss:
|
rollup-plugin-postcss:
|
||||||
specifier: ^4.0.2
|
specifier: ^4.0.2
|
||||||
version: 4.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2))
|
version: 4.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2))
|
||||||
stylelint:
|
stylelint:
|
||||||
specifier: ^15.11.0
|
specifier: ^15.11.0
|
||||||
version: 15.11.0(typescript@5.8.2)
|
version: 15.11.0(typescript@5.8.2)
|
||||||
|
|
@ -353,10 +350,10 @@ importers:
|
||||||
version: 6.2.1
|
version: 6.2.1
|
||||||
ts-jest:
|
ts-jest:
|
||||||
specifier: ^29.2.6
|
specifier: ^29.2.6
|
||||||
version: 29.2.6(@babel/core@7.26.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.9))(esbuild@0.25.1)(jest@29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2)))(typescript@5.8.2)
|
version: 29.2.6(@babel/core@7.26.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.9))(esbuild@0.25.1)(jest@29.7.0(@types/node@22.13.11)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2)))(typescript@5.8.2)
|
||||||
ts-node:
|
ts-node:
|
||||||
specifier: ^10.9.2
|
specifier: ^10.9.2
|
||||||
version: 10.9.2(@types/node@22.13.9)(typescript@5.8.2)
|
version: 10.9.2(@types/node@22.13.11)(typescript@5.8.2)
|
||||||
typescript:
|
typescript:
|
||||||
specifier: ^5.8.2
|
specifier: ^5.8.2
|
||||||
version: 5.8.2
|
version: 5.8.2
|
||||||
|
|
@ -1812,56 +1809,56 @@ packages:
|
||||||
resolution: {integrity: sha512-h2ugfCAQRhp6NIYABW+20AvVkrM/ReuELBfgkH+5DALfrKrsQXYeS1YPZi9y4bCfNFj8Zxdhu4DtuVFDiUONiA==}
|
resolution: {integrity: sha512-h2ugfCAQRhp6NIYABW+20AvVkrM/ReuELBfgkH+5DALfrKrsQXYeS1YPZi9y4bCfNFj8Zxdhu4DtuVFDiUONiA==}
|
||||||
engines: {node: '>=18.0.0'}
|
engines: {node: '>=18.0.0'}
|
||||||
|
|
||||||
'@next/env@15.2.2':
|
'@next/env@15.2.4':
|
||||||
resolution: {integrity: sha512-yWgopCfA9XDR8ZH3taB5nRKtKJ1Q5fYsTOuYkzIIoS8TJ0UAUKAGF73JnGszbjk2ufAQDj6mDdgsJAFx5CLtYQ==}
|
resolution: {integrity: sha512-+SFtMgoiYP3WoSswuNmxJOCwi06TdWE733D+WPjpXIe4LXGULwEaofiiAy6kbS0+XjM5xF5n3lKuBwN2SnqD9g==}
|
||||||
|
|
||||||
'@next/eslint-plugin-next@14.2.24':
|
'@next/eslint-plugin-next@14.2.24':
|
||||||
resolution: {integrity: sha512-FDL3qs+5DML0AJz56DCVr+KnFYivxeAX73En8QbPw9GjJZ6zbfvqDy+HrarHFzbsIASn7y8y5ySJ/lllSruNVQ==}
|
resolution: {integrity: sha512-FDL3qs+5DML0AJz56DCVr+KnFYivxeAX73En8QbPw9GjJZ6zbfvqDy+HrarHFzbsIASn7y8y5ySJ/lllSruNVQ==}
|
||||||
|
|
||||||
'@next/swc-darwin-arm64@15.2.2':
|
'@next/swc-darwin-arm64@15.2.4':
|
||||||
resolution: {integrity: sha512-HNBRnz+bkZ+KfyOExpUxTMR0Ow8nkkcE6IlsdEa9W/rI7gefud19+Sn1xYKwB9pdCdxIP1lPru/ZfjfA+iT8pw==}
|
resolution: {integrity: sha512-1AnMfs655ipJEDC/FHkSr0r3lXBgpqKo4K1kiwfUf3iE68rDFXZ1TtHdMvf7D0hMItgDZ7Vuq3JgNMbt/+3bYw==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
|
|
||||||
'@next/swc-darwin-x64@15.2.2':
|
'@next/swc-darwin-x64@15.2.4':
|
||||||
resolution: {integrity: sha512-mJOUwp7al63tDpLpEFpKwwg5jwvtL1lhRW2fI1Aog0nYCPAhxbJsaZKdoVyPZCy8MYf/iQVNDuk/+i29iLCzIA==}
|
resolution: {integrity: sha512-3qK2zb5EwCwxnO2HeO+TRqCubeI/NgCe+kL5dTJlPldV/uwCnUgC7VbEzgmxbfrkbjehL4H9BPztWOEtsoMwew==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
|
|
||||||
'@next/swc-linux-arm64-gnu@15.2.2':
|
'@next/swc-linux-arm64-gnu@15.2.4':
|
||||||
resolution: {integrity: sha512-5ZZ0Zwy3SgMr7MfWtRE7cQWVssfOvxYfD9O7XHM7KM4nrf5EOeqwq67ZXDgo86LVmffgsu5tPO57EeFKRnrfSQ==}
|
resolution: {integrity: sha512-HFN6GKUcrTWvem8AZN7tT95zPb0GUGv9v0d0iyuTb303vbXkkbHDp/DxufB04jNVD+IN9yHy7y/6Mqq0h0YVaQ==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@next/swc-linux-arm64-musl@15.2.2':
|
'@next/swc-linux-arm64-musl@15.2.4':
|
||||||
resolution: {integrity: sha512-cgKWBuFMLlJ4TWcFHl1KOaVVUAF8vy4qEvX5KsNd0Yj5mhu989QFCq1WjuaEbv/tO1ZpsQI6h/0YR8bLwEi+nA==}
|
resolution: {integrity: sha512-Oioa0SORWLwi35/kVB8aCk5Uq+5/ZIumMK1kJV+jSdazFm2NzPDztsefzdmzzpx5oGCJ6FkUC7vkaUseNTStNA==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@next/swc-linux-x64-gnu@15.2.2':
|
'@next/swc-linux-x64-gnu@15.2.4':
|
||||||
resolution: {integrity: sha512-c3kWSOSsVL8rcNBBfOq1+/j2PKs2nsMwJUV4icUxRgGBwUOfppeh7YhN5s79enBQFU+8xRgVatFkhHU1QW7yUA==}
|
resolution: {integrity: sha512-yb5WTRaHdkgOqFOZiu6rHV1fAEK0flVpaIN2HB6kxHVSy/dIajWbThS7qON3W9/SNOH2JWkVCyulgGYekMePuw==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@next/swc-linux-x64-musl@15.2.2':
|
'@next/swc-linux-x64-musl@15.2.4':
|
||||||
resolution: {integrity: sha512-PXTW9PLTxdNlVYgPJ0equojcq1kNu5NtwcNjRjHAB+/sdoKZ+X8FBu70fdJFadkxFIGekQTyRvPMFF+SOJaQjw==}
|
resolution: {integrity: sha512-Dcdv/ix6srhkM25fgXiyOieFUkz+fOYkHlydWCtB0xMST6X9XYI3yPDKBZt1xuhOytONsIFJFB08xXYsxUwJLw==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@next/swc-win32-arm64-msvc@15.2.2':
|
'@next/swc-win32-arm64-msvc@15.2.4':
|
||||||
resolution: {integrity: sha512-nG644Es5llSGEcTaXhnGWR/aThM/hIaz0jx4MDg4gWC8GfTCp8eDBWZ77CVuv2ha/uL9Ce+nPTfYkSLG67/sHg==}
|
resolution: {integrity: sha512-dW0i7eukvDxtIhCYkMrZNQfNicPDExt2jPb9AZPpL7cfyUo7QSNl1DjsHjmmKp6qNAqUESyT8YFl/Aw91cNJJg==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
|
|
||||||
'@next/swc-win32-x64-msvc@15.2.2':
|
'@next/swc-win32-x64-msvc@15.2.4':
|
||||||
resolution: {integrity: sha512-52nWy65S/R6/kejz3jpvHAjZDPKIbEQu4x9jDBzmB9jJfuOy5rspjKu4u77+fI4M/WzLXrrQd57hlFGzz1ubcQ==}
|
resolution: {integrity: sha512-SbnWkJmkS7Xl3kre8SdMF6F/XDh1DTFEhp0jRTj/uB8iPKoU2bb2NDfcu+iifv1+mxQEd1g2vvSxcZbXSKyWiQ==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
|
|
@ -2730,10 +2727,6 @@ packages:
|
||||||
resolution: {integrity: sha512-0XR1poYvPQoPpmfDYLEqUGu5ePAQ4pdgN3VFsZBNAeze7qubVpsIY1o1R6PZpKep/DKu33GSm2NhwpCLkMs2Cw==}
|
resolution: {integrity: sha512-0XR1poYvPQoPpmfDYLEqUGu5ePAQ4pdgN3VFsZBNAeze7qubVpsIY1o1R6PZpKep/DKu33GSm2NhwpCLkMs2Cw==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
|
|
||||||
'@svgr/webpack@8.1.0':
|
|
||||||
resolution: {integrity: sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==}
|
|
||||||
engines: {node: '>=14'}
|
|
||||||
|
|
||||||
'@swc/counter@0.1.3':
|
'@swc/counter@0.1.3':
|
||||||
resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==}
|
resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==}
|
||||||
|
|
||||||
|
|
@ -2828,8 +2821,8 @@ packages:
|
||||||
'@types/node@14.18.63':
|
'@types/node@14.18.63':
|
||||||
resolution: {integrity: sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==}
|
resolution: {integrity: sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==}
|
||||||
|
|
||||||
'@types/node@22.13.9':
|
'@types/node@22.13.11':
|
||||||
resolution: {integrity: sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw==}
|
resolution: {integrity: sha512-iEUCUJoU0i3VnrCmgoWCXttklWcvoCIx4jzcP22fioIVSdTmjgoEvmAO/QPw6TcS9k5FrNgn4w7q5lGOd1CT5g==}
|
||||||
|
|
||||||
'@types/normalize-package-data@2.4.4':
|
'@types/normalize-package-data@2.4.4':
|
||||||
resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==}
|
resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==}
|
||||||
|
|
@ -3324,8 +3317,8 @@ packages:
|
||||||
caniuse-lite@1.0.30001702:
|
caniuse-lite@1.0.30001702:
|
||||||
resolution: {integrity: sha512-LoPe/D7zioC0REI5W73PeR1e1MLCipRGq/VkovJnd6Df+QVqT+vT33OXCp8QUd7kA7RZrHWxb1B36OQKI/0gOA==}
|
resolution: {integrity: sha512-LoPe/D7zioC0REI5W73PeR1e1MLCipRGq/VkovJnd6Df+QVqT+vT33OXCp8QUd7kA7RZrHWxb1B36OQKI/0gOA==}
|
||||||
|
|
||||||
caniuse-lite@1.0.30001705:
|
caniuse-lite@1.0.30001707:
|
||||||
resolution: {integrity: sha512-S0uyMMiYvA7CxNgomYBwwwPUnWzFD83f3B1ce5jHUfHTH//QL6hHsreI8RVC5606R4ssqravelYO5TU6t8sEyg==}
|
resolution: {integrity: sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw==}
|
||||||
|
|
||||||
caseless@0.12.0:
|
caseless@0.12.0:
|
||||||
resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==}
|
resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==}
|
||||||
|
|
@ -5420,8 +5413,8 @@ packages:
|
||||||
ms@2.1.3:
|
ms@2.1.3:
|
||||||
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
||||||
|
|
||||||
nanoid@3.3.10:
|
nanoid@3.3.11:
|
||||||
resolution: {integrity: sha512-vSJJTG+t/dIKAUhUDw/dLdZ9s//5OxcHqLaDWWrW4Cdq7o6tdLIczUkMXt2MBNmk6sJRZBZRXVixs7URY1CmIg==}
|
resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
|
||||||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
|
@ -5433,8 +5426,8 @@ packages:
|
||||||
natural-compare@1.4.0:
|
natural-compare@1.4.0:
|
||||||
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
|
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
|
||||||
|
|
||||||
next@15.2.2:
|
next@15.2.4:
|
||||||
resolution: {integrity: sha512-dgp8Kcx5XZRjMw2KNwBtUzhngRaURPioxoNIVl5BOyJbhi9CUgEtKDO7fx5wh8Z8vOVX1nYZ9meawJoRrlASYA==}
|
resolution: {integrity: sha512-VwL+LAaPSxEkd3lU2xWbgEOtrM8oedmyhBqaVNmgKB+GvZlCy9rgaEc+y2on0wv+l0oSFqLtYD6dcC1eAedUaQ==}
|
||||||
engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0}
|
engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
|
@ -8482,10 +8475,10 @@ snapshots:
|
||||||
|
|
||||||
'@fontsource/jetbrains-mono@5.2.5': {}
|
'@fontsource/jetbrains-mono@5.2.5': {}
|
||||||
|
|
||||||
'@formatjs/cli@4.8.4(ts-jest@29.2.6(@babel/core@7.26.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.9))(esbuild@0.25.1)(jest@29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2)))(typescript@5.8.2))':
|
'@formatjs/cli@4.8.4(ts-jest@29.2.6(@babel/core@7.26.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.9))(esbuild@0.25.1)(jest@29.7.0(@types/node@22.13.11)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2)))(typescript@5.8.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@formatjs/icu-messageformat-parser': 2.1.0
|
'@formatjs/icu-messageformat-parser': 2.1.0
|
||||||
'@formatjs/ts-transformer': 3.9.4(ts-jest@29.2.6(@babel/core@7.26.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.9))(esbuild@0.25.1)(jest@29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2)))(typescript@5.8.2))
|
'@formatjs/ts-transformer': 3.9.4(ts-jest@29.2.6(@babel/core@7.26.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.9))(esbuild@0.25.1)(jest@29.7.0(@types/node@22.13.11)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2)))(typescript@5.8.2))
|
||||||
'@types/estree': 0.0.50
|
'@types/estree': 0.0.50
|
||||||
'@types/fs-extra': 9.0.13
|
'@types/fs-extra': 9.0.13
|
||||||
'@types/json-stable-stringify': 1.2.0
|
'@types/json-stable-stringify': 1.2.0
|
||||||
|
|
@ -8572,15 +8565,15 @@ snapshots:
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
typescript: 5.8.2
|
typescript: 5.8.2
|
||||||
|
|
||||||
'@formatjs/ts-transformer@2.13.0(ts-jest@29.2.6(@babel/core@7.26.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.9))(esbuild@0.25.1)(jest@29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2)))(typescript@5.8.2))':
|
'@formatjs/ts-transformer@2.13.0(ts-jest@29.2.6(@babel/core@7.26.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.9))(esbuild@0.25.1)(jest@29.7.0(@types/node@22.13.11)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2)))(typescript@5.8.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
intl-messageformat-parser: 6.1.2
|
intl-messageformat-parser: 6.1.2
|
||||||
tslib: 2.8.1
|
tslib: 2.8.1
|
||||||
typescript: 4.9.5
|
typescript: 4.9.5
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
ts-jest: 29.2.6(@babel/core@7.26.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.9))(esbuild@0.25.1)(jest@29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2)))(typescript@5.8.2)
|
ts-jest: 29.2.6(@babel/core@7.26.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.9))(esbuild@0.25.1)(jest@29.7.0(@types/node@22.13.11)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2)))(typescript@5.8.2)
|
||||||
|
|
||||||
'@formatjs/ts-transformer@3.9.4(ts-jest@29.2.6(@babel/core@7.26.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.9))(esbuild@0.25.1)(jest@29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2)))(typescript@5.8.2))':
|
'@formatjs/ts-transformer@3.9.4(ts-jest@29.2.6(@babel/core@7.26.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.9))(esbuild@0.25.1)(jest@29.7.0(@types/node@22.13.11)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2)))(typescript@5.8.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@formatjs/icu-messageformat-parser': 2.1.0
|
'@formatjs/icu-messageformat-parser': 2.1.0
|
||||||
'@types/node': 14.18.63
|
'@types/node': 14.18.63
|
||||||
|
|
@ -8588,7 +8581,7 @@ snapshots:
|
||||||
tslib: 2.8.1
|
tslib: 2.8.1
|
||||||
typescript: 4.9.5
|
typescript: 4.9.5
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
ts-jest: 29.2.6(@babel/core@7.26.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.9))(esbuild@0.25.1)(jest@29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2)))(typescript@5.8.2)
|
ts-jest: 29.2.6(@babel/core@7.26.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.9))(esbuild@0.25.1)(jest@29.7.0(@types/node@22.13.11)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2)))(typescript@5.8.2)
|
||||||
|
|
||||||
'@hello-pangea/dnd@18.0.1(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
'@hello-pangea/dnd@18.0.1(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -8728,27 +8721,27 @@ snapshots:
|
||||||
'@jest/console@29.7.0':
|
'@jest/console@29.7.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@jest/types': 29.6.3
|
'@jest/types': 29.6.3
|
||||||
'@types/node': 22.13.9
|
'@types/node': 22.13.11
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
jest-message-util: 29.7.0
|
jest-message-util: 29.7.0
|
||||||
jest-util: 29.7.0
|
jest-util: 29.7.0
|
||||||
slash: 3.0.0
|
slash: 3.0.0
|
||||||
|
|
||||||
'@jest/core@29.7.0(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2))':
|
'@jest/core@29.7.0(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@jest/console': 29.7.0
|
'@jest/console': 29.7.0
|
||||||
'@jest/reporters': 29.7.0
|
'@jest/reporters': 29.7.0
|
||||||
'@jest/test-result': 29.7.0
|
'@jest/test-result': 29.7.0
|
||||||
'@jest/transform': 29.7.0
|
'@jest/transform': 29.7.0
|
||||||
'@jest/types': 29.6.3
|
'@jest/types': 29.6.3
|
||||||
'@types/node': 22.13.9
|
'@types/node': 22.13.11
|
||||||
ansi-escapes: 4.3.2
|
ansi-escapes: 4.3.2
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
ci-info: 3.9.0
|
ci-info: 3.9.0
|
||||||
exit: 0.1.2
|
exit: 0.1.2
|
||||||
graceful-fs: 4.2.11
|
graceful-fs: 4.2.11
|
||||||
jest-changed-files: 29.7.0
|
jest-changed-files: 29.7.0
|
||||||
jest-config: 29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2))
|
jest-config: 29.7.0(@types/node@22.13.11)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2))
|
||||||
jest-haste-map: 29.7.0
|
jest-haste-map: 29.7.0
|
||||||
jest-message-util: 29.7.0
|
jest-message-util: 29.7.0
|
||||||
jest-regex-util: 29.6.3
|
jest-regex-util: 29.6.3
|
||||||
|
|
@ -8773,7 +8766,7 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@jest/fake-timers': 29.7.0
|
'@jest/fake-timers': 29.7.0
|
||||||
'@jest/types': 29.6.3
|
'@jest/types': 29.6.3
|
||||||
'@types/node': 22.13.9
|
'@types/node': 22.13.11
|
||||||
jest-mock: 29.7.0
|
jest-mock: 29.7.0
|
||||||
|
|
||||||
'@jest/expect-utils@29.7.0':
|
'@jest/expect-utils@29.7.0':
|
||||||
|
|
@ -8791,7 +8784,7 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@jest/types': 29.6.3
|
'@jest/types': 29.6.3
|
||||||
'@sinonjs/fake-timers': 10.3.0
|
'@sinonjs/fake-timers': 10.3.0
|
||||||
'@types/node': 22.13.9
|
'@types/node': 22.13.11
|
||||||
jest-message-util: 29.7.0
|
jest-message-util: 29.7.0
|
||||||
jest-mock: 29.7.0
|
jest-mock: 29.7.0
|
||||||
jest-util: 29.7.0
|
jest-util: 29.7.0
|
||||||
|
|
@ -8813,7 +8806,7 @@ snapshots:
|
||||||
'@jest/transform': 29.7.0
|
'@jest/transform': 29.7.0
|
||||||
'@jest/types': 29.6.3
|
'@jest/types': 29.6.3
|
||||||
'@jridgewell/trace-mapping': 0.3.25
|
'@jridgewell/trace-mapping': 0.3.25
|
||||||
'@types/node': 22.13.9
|
'@types/node': 22.13.11
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
collect-v8-coverage: 1.0.2
|
collect-v8-coverage: 1.0.2
|
||||||
exit: 0.1.2
|
exit: 0.1.2
|
||||||
|
|
@ -8883,7 +8876,7 @@ snapshots:
|
||||||
'@jest/schemas': 29.6.3
|
'@jest/schemas': 29.6.3
|
||||||
'@types/istanbul-lib-coverage': 2.0.6
|
'@types/istanbul-lib-coverage': 2.0.6
|
||||||
'@types/istanbul-reports': 3.0.4
|
'@types/istanbul-reports': 3.0.4
|
||||||
'@types/node': 22.13.9
|
'@types/node': 22.13.11
|
||||||
'@types/yargs': 17.0.33
|
'@types/yargs': 17.0.33
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
|
|
||||||
|
|
@ -8918,34 +8911,34 @@ snapshots:
|
||||||
|
|
||||||
'@netlify/plugin-nextjs@5.10.0': {}
|
'@netlify/plugin-nextjs@5.10.0': {}
|
||||||
|
|
||||||
'@next/env@15.2.2': {}
|
'@next/env@15.2.4': {}
|
||||||
|
|
||||||
'@next/eslint-plugin-next@14.2.24':
|
'@next/eslint-plugin-next@14.2.24':
|
||||||
dependencies:
|
dependencies:
|
||||||
glob: 10.3.10
|
glob: 10.3.10
|
||||||
|
|
||||||
'@next/swc-darwin-arm64@15.2.2':
|
'@next/swc-darwin-arm64@15.2.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@next/swc-darwin-x64@15.2.2':
|
'@next/swc-darwin-x64@15.2.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@next/swc-linux-arm64-gnu@15.2.2':
|
'@next/swc-linux-arm64-gnu@15.2.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@next/swc-linux-arm64-musl@15.2.2':
|
'@next/swc-linux-arm64-musl@15.2.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@next/swc-linux-x64-gnu@15.2.2':
|
'@next/swc-linux-x64-gnu@15.2.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@next/swc-linux-x64-musl@15.2.2':
|
'@next/swc-linux-x64-musl@15.2.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@next/swc-win32-arm64-msvc@15.2.2':
|
'@next/swc-win32-arm64-msvc@15.2.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@next/swc-win32-x64-msvc@15.2.2':
|
'@next/swc-win32-x64-msvc@15.2.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@nodelib/fs.scandir@2.1.5':
|
'@nodelib/fs.scandir@2.1.5':
|
||||||
|
|
@ -10287,20 +10280,6 @@ snapshots:
|
||||||
- supports-color
|
- supports-color
|
||||||
- typescript
|
- typescript
|
||||||
|
|
||||||
'@svgr/webpack@8.1.0(typescript@5.8.2)':
|
|
||||||
dependencies:
|
|
||||||
'@babel/core': 7.26.9
|
|
||||||
'@babel/plugin-transform-react-constant-elements': 7.25.9(@babel/core@7.26.9)
|
|
||||||
'@babel/preset-env': 7.26.9(@babel/core@7.26.9)
|
|
||||||
'@babel/preset-react': 7.26.3(@babel/core@7.26.9)
|
|
||||||
'@babel/preset-typescript': 7.26.0(@babel/core@7.26.9)
|
|
||||||
'@svgr/core': 8.1.0(typescript@5.8.2)
|
|
||||||
'@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.8.2))
|
|
||||||
'@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@5.8.2))(typescript@5.8.2)
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- supports-color
|
|
||||||
- typescript
|
|
||||||
|
|
||||||
'@swc/counter@0.1.3': {}
|
'@swc/counter@0.1.3': {}
|
||||||
|
|
||||||
'@swc/helpers@0.5.15':
|
'@swc/helpers@0.5.15':
|
||||||
|
|
@ -10351,20 +10330,20 @@ snapshots:
|
||||||
|
|
||||||
'@types/fs-extra@8.1.5':
|
'@types/fs-extra@8.1.5':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 22.13.9
|
'@types/node': 22.13.11
|
||||||
|
|
||||||
'@types/fs-extra@9.0.13':
|
'@types/fs-extra@9.0.13':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 22.13.9
|
'@types/node': 22.13.11
|
||||||
|
|
||||||
'@types/glob@7.2.0':
|
'@types/glob@7.2.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/minimatch': 5.1.2
|
'@types/minimatch': 5.1.2
|
||||||
'@types/node': 22.13.9
|
'@types/node': 22.13.11
|
||||||
|
|
||||||
'@types/graceful-fs@4.1.9':
|
'@types/graceful-fs@4.1.9':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 22.13.9
|
'@types/node': 22.13.11
|
||||||
|
|
||||||
'@types/hoist-non-react-statics@3.3.6':
|
'@types/hoist-non-react-statics@3.3.6':
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -10400,7 +10379,7 @@ snapshots:
|
||||||
|
|
||||||
'@types/node@14.18.63': {}
|
'@types/node@14.18.63': {}
|
||||||
|
|
||||||
'@types/node@22.13.9':
|
'@types/node@22.13.11':
|
||||||
dependencies:
|
dependencies:
|
||||||
undici-types: 6.20.0
|
undici-types: 6.20.0
|
||||||
|
|
||||||
|
|
@ -10442,7 +10421,7 @@ snapshots:
|
||||||
|
|
||||||
'@types/yauzl@2.10.3':
|
'@types/yauzl@2.10.3':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 22.13.9
|
'@types/node': 22.13.11
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@typescript-eslint/eslint-plugin@8.26.1(@typescript-eslint/parser@8.26.1(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2)':
|
'@typescript-eslint/eslint-plugin@8.26.1(@typescript-eslint/parser@8.26.1(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2)':
|
||||||
|
|
@ -10581,7 +10560,7 @@ snapshots:
|
||||||
glob: 10.3.10
|
glob: 10.3.10
|
||||||
highlight.js: 11.11.1
|
highlight.js: 11.11.1
|
||||||
lucide-react: 0.479.0(react@19.0.0)
|
lucide-react: 0.479.0(react@19.0.0)
|
||||||
next: 15.2.2(@babel/core@7.26.9)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
next: 15.2.4(@babel/core@7.26.9)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||||
react: 19.0.0
|
react: 19.0.0
|
||||||
react-aria-components: 1.7.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
react-aria-components: 1.7.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||||
react-dom: 19.0.0(react@19.0.0)
|
react-dom: 19.0.0(react@19.0.0)
|
||||||
|
|
@ -10903,12 +10882,12 @@ snapshots:
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
babel-plugin-react-intl@7.9.4(ts-jest@29.2.6(@babel/core@7.26.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.9))(esbuild@0.25.1)(jest@29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2)))(typescript@5.8.2)):
|
babel-plugin-react-intl@7.9.4(ts-jest@29.2.6(@babel/core@7.26.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.9))(esbuild@0.25.1)(jest@29.7.0(@types/node@22.13.11)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2)))(typescript@5.8.2)):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.26.9
|
'@babel/core': 7.26.9
|
||||||
'@babel/helper-plugin-utils': 7.26.5
|
'@babel/helper-plugin-utils': 7.26.5
|
||||||
'@babel/types': 7.26.9
|
'@babel/types': 7.26.9
|
||||||
'@formatjs/ts-transformer': 2.13.0(ts-jest@29.2.6(@babel/core@7.26.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.9))(esbuild@0.25.1)(jest@29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2)))(typescript@5.8.2))
|
'@formatjs/ts-transformer': 2.13.0(ts-jest@29.2.6(@babel/core@7.26.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.9))(esbuild@0.25.1)(jest@29.7.0(@types/node@22.13.11)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2)))(typescript@5.8.2))
|
||||||
'@types/babel__core': 7.20.5
|
'@types/babel__core': 7.20.5
|
||||||
'@types/fs-extra': 9.0.13
|
'@types/fs-extra': 9.0.13
|
||||||
'@types/schema-utils': 2.4.0
|
'@types/schema-utils': 2.4.0
|
||||||
|
|
@ -11046,13 +11025,13 @@ snapshots:
|
||||||
caniuse-api@3.0.0:
|
caniuse-api@3.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
browserslist: 4.24.4
|
browserslist: 4.24.4
|
||||||
caniuse-lite: 1.0.30001702
|
caniuse-lite: 1.0.30001707
|
||||||
lodash.memoize: 4.1.2
|
lodash.memoize: 4.1.2
|
||||||
lodash.uniq: 4.5.0
|
lodash.uniq: 4.5.0
|
||||||
|
|
||||||
caniuse-lite@1.0.30001702: {}
|
caniuse-lite@1.0.30001702: {}
|
||||||
|
|
||||||
caniuse-lite@1.0.30001705: {}
|
caniuse-lite@1.0.30001707: {}
|
||||||
|
|
||||||
caseless@0.12.0: {}
|
caseless@0.12.0: {}
|
||||||
|
|
||||||
|
|
@ -11214,13 +11193,13 @@ snapshots:
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
typescript: 5.8.2
|
typescript: 5.8.2
|
||||||
|
|
||||||
create-jest@29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2)):
|
create-jest@29.7.0(@types/node@22.13.11)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2)):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@jest/types': 29.6.3
|
'@jest/types': 29.6.3
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
exit: 0.1.2
|
exit: 0.1.2
|
||||||
graceful-fs: 4.2.11
|
graceful-fs: 4.2.11
|
||||||
jest-config: 29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2))
|
jest-config: 29.7.0(@types/node@22.13.11)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2))
|
||||||
jest-util: 29.7.0
|
jest-util: 29.7.0
|
||||||
prompts: 2.4.2
|
prompts: 2.4.2
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
|
@ -11924,13 +11903,13 @@ snapshots:
|
||||||
- eslint-import-resolver-webpack
|
- eslint-import-resolver-webpack
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@8.26.1(@typescript-eslint/parser@8.26.1(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(jest@29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2)))(typescript@5.8.2):
|
eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@8.26.1(@typescript-eslint/parser@8.26.1(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(jest@29.7.0(@types/node@22.13.11)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2)))(typescript@5.8.2):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.8.2)
|
'@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.8.2)
|
||||||
eslint: 8.57.1
|
eslint: 8.57.1
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@typescript-eslint/eslint-plugin': 8.26.1(@typescript-eslint/parser@8.26.1(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2)
|
'@typescript-eslint/eslint-plugin': 8.26.1(@typescript-eslint/parser@8.26.1(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2)
|
||||||
jest: 29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2))
|
jest: 29.7.0(@types/node@22.13.11)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2))
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
- typescript
|
- typescript
|
||||||
|
|
@ -12133,10 +12112,10 @@ snapshots:
|
||||||
|
|
||||||
extend@3.0.2: {}
|
extend@3.0.2: {}
|
||||||
|
|
||||||
extract-react-intl-messages@4.1.1(ts-jest@29.2.6(@babel/core@7.26.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.9))(esbuild@0.25.1)(jest@29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2)))(typescript@5.8.2)):
|
extract-react-intl-messages@4.1.1(ts-jest@29.2.6(@babel/core@7.26.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.9))(esbuild@0.25.1)(jest@29.7.0(@types/node@22.13.11)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2)))(typescript@5.8.2)):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.26.9
|
'@babel/core': 7.26.9
|
||||||
babel-plugin-react-intl: 7.9.4(ts-jest@29.2.6(@babel/core@7.26.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.9))(esbuild@0.25.1)(jest@29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2)))(typescript@5.8.2))
|
babel-plugin-react-intl: 7.9.4(ts-jest@29.2.6(@babel/core@7.26.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.9))(esbuild@0.25.1)(jest@29.7.0(@types/node@22.13.11)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2)))(typescript@5.8.2))
|
||||||
flat: 5.0.2
|
flat: 5.0.2
|
||||||
glob: 7.2.3
|
glob: 7.2.3
|
||||||
js-yaml: 3.14.1
|
js-yaml: 3.14.1
|
||||||
|
|
@ -12831,7 +12810,7 @@ snapshots:
|
||||||
'@jest/expect': 29.7.0
|
'@jest/expect': 29.7.0
|
||||||
'@jest/test-result': 29.7.0
|
'@jest/test-result': 29.7.0
|
||||||
'@jest/types': 29.6.3
|
'@jest/types': 29.6.3
|
||||||
'@types/node': 22.13.9
|
'@types/node': 22.13.11
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
co: 4.6.0
|
co: 4.6.0
|
||||||
dedent: 1.5.3
|
dedent: 1.5.3
|
||||||
|
|
@ -12851,16 +12830,16 @@ snapshots:
|
||||||
- babel-plugin-macros
|
- babel-plugin-macros
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
jest-cli@29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2)):
|
jest-cli@29.7.0(@types/node@22.13.11)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2)):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@jest/core': 29.7.0(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2))
|
'@jest/core': 29.7.0(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2))
|
||||||
'@jest/test-result': 29.7.0
|
'@jest/test-result': 29.7.0
|
||||||
'@jest/types': 29.6.3
|
'@jest/types': 29.6.3
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
create-jest: 29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2))
|
create-jest: 29.7.0(@types/node@22.13.11)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2))
|
||||||
exit: 0.1.2
|
exit: 0.1.2
|
||||||
import-local: 3.2.0
|
import-local: 3.2.0
|
||||||
jest-config: 29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2))
|
jest-config: 29.7.0(@types/node@22.13.11)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2))
|
||||||
jest-util: 29.7.0
|
jest-util: 29.7.0
|
||||||
jest-validate: 29.7.0
|
jest-validate: 29.7.0
|
||||||
yargs: 17.7.2
|
yargs: 17.7.2
|
||||||
|
|
@ -12870,7 +12849,7 @@ snapshots:
|
||||||
- supports-color
|
- supports-color
|
||||||
- ts-node
|
- ts-node
|
||||||
|
|
||||||
jest-config@29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2)):
|
jest-config@29.7.0(@types/node@22.13.11)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2)):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.26.9
|
'@babel/core': 7.26.9
|
||||||
'@jest/test-sequencer': 29.7.0
|
'@jest/test-sequencer': 29.7.0
|
||||||
|
|
@ -12895,8 +12874,8 @@ snapshots:
|
||||||
slash: 3.0.0
|
slash: 3.0.0
|
||||||
strip-json-comments: 3.1.1
|
strip-json-comments: 3.1.1
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/node': 22.13.9
|
'@types/node': 22.13.11
|
||||||
ts-node: 10.9.2(@types/node@22.13.9)(typescript@5.8.2)
|
ts-node: 10.9.2(@types/node@22.13.11)(typescript@5.8.2)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- babel-plugin-macros
|
- babel-plugin-macros
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
@ -12925,7 +12904,7 @@ snapshots:
|
||||||
'@jest/environment': 29.7.0
|
'@jest/environment': 29.7.0
|
||||||
'@jest/fake-timers': 29.7.0
|
'@jest/fake-timers': 29.7.0
|
||||||
'@jest/types': 29.6.3
|
'@jest/types': 29.6.3
|
||||||
'@types/node': 22.13.9
|
'@types/node': 22.13.11
|
||||||
jest-mock: 29.7.0
|
jest-mock: 29.7.0
|
||||||
jest-util: 29.7.0
|
jest-util: 29.7.0
|
||||||
|
|
||||||
|
|
@ -12935,7 +12914,7 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@jest/types': 29.6.3
|
'@jest/types': 29.6.3
|
||||||
'@types/graceful-fs': 4.1.9
|
'@types/graceful-fs': 4.1.9
|
||||||
'@types/node': 22.13.9
|
'@types/node': 22.13.11
|
||||||
anymatch: 3.1.3
|
anymatch: 3.1.3
|
||||||
fb-watchman: 2.0.2
|
fb-watchman: 2.0.2
|
||||||
graceful-fs: 4.2.11
|
graceful-fs: 4.2.11
|
||||||
|
|
@ -12974,7 +12953,7 @@ snapshots:
|
||||||
jest-mock@29.7.0:
|
jest-mock@29.7.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@jest/types': 29.6.3
|
'@jest/types': 29.6.3
|
||||||
'@types/node': 22.13.9
|
'@types/node': 22.13.11
|
||||||
jest-util: 29.7.0
|
jest-util: 29.7.0
|
||||||
|
|
||||||
jest-pnp-resolver@1.2.3(jest-resolve@29.7.0):
|
jest-pnp-resolver@1.2.3(jest-resolve@29.7.0):
|
||||||
|
|
@ -13009,7 +12988,7 @@ snapshots:
|
||||||
'@jest/test-result': 29.7.0
|
'@jest/test-result': 29.7.0
|
||||||
'@jest/transform': 29.7.0
|
'@jest/transform': 29.7.0
|
||||||
'@jest/types': 29.6.3
|
'@jest/types': 29.6.3
|
||||||
'@types/node': 22.13.9
|
'@types/node': 22.13.11
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
emittery: 0.13.1
|
emittery: 0.13.1
|
||||||
graceful-fs: 4.2.11
|
graceful-fs: 4.2.11
|
||||||
|
|
@ -13037,7 +13016,7 @@ snapshots:
|
||||||
'@jest/test-result': 29.7.0
|
'@jest/test-result': 29.7.0
|
||||||
'@jest/transform': 29.7.0
|
'@jest/transform': 29.7.0
|
||||||
'@jest/types': 29.6.3
|
'@jest/types': 29.6.3
|
||||||
'@types/node': 22.13.9
|
'@types/node': 22.13.11
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
cjs-module-lexer: 1.4.3
|
cjs-module-lexer: 1.4.3
|
||||||
collect-v8-coverage: 1.0.2
|
collect-v8-coverage: 1.0.2
|
||||||
|
|
@ -13083,7 +13062,7 @@ snapshots:
|
||||||
jest-util@29.7.0:
|
jest-util@29.7.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@jest/types': 29.6.3
|
'@jest/types': 29.6.3
|
||||||
'@types/node': 22.13.9
|
'@types/node': 22.13.11
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
ci-info: 3.9.0
|
ci-info: 3.9.0
|
||||||
graceful-fs: 4.2.11
|
graceful-fs: 4.2.11
|
||||||
|
|
@ -13102,7 +13081,7 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@jest/test-result': 29.7.0
|
'@jest/test-result': 29.7.0
|
||||||
'@jest/types': 29.6.3
|
'@jest/types': 29.6.3
|
||||||
'@types/node': 22.13.9
|
'@types/node': 22.13.11
|
||||||
ansi-escapes: 4.3.2
|
ansi-escapes: 4.3.2
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
emittery: 0.13.1
|
emittery: 0.13.1
|
||||||
|
|
@ -13111,17 +13090,17 @@ snapshots:
|
||||||
|
|
||||||
jest-worker@29.7.0:
|
jest-worker@29.7.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 22.13.9
|
'@types/node': 22.13.11
|
||||||
jest-util: 29.7.0
|
jest-util: 29.7.0
|
||||||
merge-stream: 2.0.0
|
merge-stream: 2.0.0
|
||||||
supports-color: 8.1.1
|
supports-color: 8.1.1
|
||||||
|
|
||||||
jest@29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2)):
|
jest@29.7.0(@types/node@22.13.11)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2)):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@jest/core': 29.7.0(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2))
|
'@jest/core': 29.7.0(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2))
|
||||||
'@jest/types': 29.6.3
|
'@jest/types': 29.6.3
|
||||||
import-local: 3.2.0
|
import-local: 3.2.0
|
||||||
jest-cli: 29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2))
|
jest-cli: 29.7.0(@types/node@22.13.11)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2))
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@types/node'
|
- '@types/node'
|
||||||
- babel-plugin-macros
|
- babel-plugin-macros
|
||||||
|
|
@ -13559,32 +13538,32 @@ snapshots:
|
||||||
|
|
||||||
ms@2.1.3: {}
|
ms@2.1.3: {}
|
||||||
|
|
||||||
nanoid@3.3.10: {}
|
nanoid@3.3.11: {}
|
||||||
|
|
||||||
nanoid@3.3.8: {}
|
nanoid@3.3.8: {}
|
||||||
|
|
||||||
natural-compare@1.4.0: {}
|
natural-compare@1.4.0: {}
|
||||||
|
|
||||||
next@15.2.2(@babel/core@7.26.9)(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
|
next@15.2.4(@babel/core@7.26.9)(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@next/env': 15.2.2
|
'@next/env': 15.2.4
|
||||||
'@swc/counter': 0.1.3
|
'@swc/counter': 0.1.3
|
||||||
'@swc/helpers': 0.5.15
|
'@swc/helpers': 0.5.15
|
||||||
busboy: 1.6.0
|
busboy: 1.6.0
|
||||||
caniuse-lite: 1.0.30001705
|
caniuse-lite: 1.0.30001707
|
||||||
postcss: 8.4.31
|
postcss: 8.4.31
|
||||||
react: 19.0.0
|
react: 19.0.0
|
||||||
react-dom: 19.0.0(react@19.0.0)
|
react-dom: 19.0.0(react@19.0.0)
|
||||||
styled-jsx: 5.1.6(@babel/core@7.26.9)(react@19.0.0)
|
styled-jsx: 5.1.6(@babel/core@7.26.9)(react@19.0.0)
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@next/swc-darwin-arm64': 15.2.2
|
'@next/swc-darwin-arm64': 15.2.4
|
||||||
'@next/swc-darwin-x64': 15.2.2
|
'@next/swc-darwin-x64': 15.2.4
|
||||||
'@next/swc-linux-arm64-gnu': 15.2.2
|
'@next/swc-linux-arm64-gnu': 15.2.4
|
||||||
'@next/swc-linux-arm64-musl': 15.2.2
|
'@next/swc-linux-arm64-musl': 15.2.4
|
||||||
'@next/swc-linux-x64-gnu': 15.2.2
|
'@next/swc-linux-x64-gnu': 15.2.4
|
||||||
'@next/swc-linux-x64-musl': 15.2.2
|
'@next/swc-linux-x64-musl': 15.2.4
|
||||||
'@next/swc-win32-arm64-msvc': 15.2.2
|
'@next/swc-win32-arm64-msvc': 15.2.4
|
||||||
'@next/swc-win32-x64-msvc': 15.2.2
|
'@next/swc-win32-x64-msvc': 15.2.4
|
||||||
sharp: 0.33.5
|
sharp: 0.33.5
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@babel/core'
|
- '@babel/core'
|
||||||
|
|
@ -13959,13 +13938,13 @@ snapshots:
|
||||||
postcss: 8.5.3
|
postcss: 8.5.3
|
||||||
postcss-value-parser: 4.2.0
|
postcss-value-parser: 4.2.0
|
||||||
|
|
||||||
postcss-load-config@3.1.4(postcss@8.5.3)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2)):
|
postcss-load-config@3.1.4(postcss@8.5.3)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2)):
|
||||||
dependencies:
|
dependencies:
|
||||||
lilconfig: 2.1.0
|
lilconfig: 2.1.0
|
||||||
yaml: 1.10.2
|
yaml: 1.10.2
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
postcss: 8.5.3
|
postcss: 8.5.3
|
||||||
ts-node: 10.9.2(@types/node@22.13.9)(typescript@5.8.2)
|
ts-node: 10.9.2(@types/node@22.13.11)(typescript@5.8.2)
|
||||||
|
|
||||||
postcss-logical@5.0.4(postcss@8.5.3):
|
postcss-logical@5.0.4(postcss@8.5.3):
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -14239,7 +14218,7 @@ snapshots:
|
||||||
|
|
||||||
postcss@8.4.31:
|
postcss@8.4.31:
|
||||||
dependencies:
|
dependencies:
|
||||||
nanoid: 3.3.10
|
nanoid: 3.3.11
|
||||||
picocolors: 1.1.1
|
picocolors: 1.1.1
|
||||||
source-map-js: 1.2.1
|
source-map-js: 1.2.1
|
||||||
|
|
||||||
|
|
@ -14703,7 +14682,7 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
rollup: 3.29.5
|
rollup: 3.29.5
|
||||||
|
|
||||||
rollup-plugin-postcss@4.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2)):
|
rollup-plugin-postcss@4.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2)):
|
||||||
dependencies:
|
dependencies:
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
concat-with-sourcemaps: 1.1.0
|
concat-with-sourcemaps: 1.1.0
|
||||||
|
|
@ -14712,7 +14691,7 @@ snapshots:
|
||||||
p-queue: 6.6.2
|
p-queue: 6.6.2
|
||||||
pify: 5.0.0
|
pify: 5.0.0
|
||||||
postcss: 8.5.3
|
postcss: 8.5.3
|
||||||
postcss-load-config: 3.1.4(postcss@8.5.3)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2))
|
postcss-load-config: 3.1.4(postcss@8.5.3)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2))
|
||||||
postcss-modules: 4.3.1(postcss@8.5.3)
|
postcss-modules: 4.3.1(postcss@8.5.3)
|
||||||
promise.series: 0.2.0
|
promise.series: 0.2.0
|
||||||
resolve: 1.22.10
|
resolve: 1.22.10
|
||||||
|
|
@ -15294,12 +15273,12 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
typescript: 5.8.2
|
typescript: 5.8.2
|
||||||
|
|
||||||
ts-jest@29.2.6(@babel/core@7.26.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.9))(esbuild@0.25.1)(jest@29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2)))(typescript@5.8.2):
|
ts-jest@29.2.6(@babel/core@7.26.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.9))(esbuild@0.25.1)(jest@29.7.0(@types/node@22.13.11)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2)))(typescript@5.8.2):
|
||||||
dependencies:
|
dependencies:
|
||||||
bs-logger: 0.2.6
|
bs-logger: 0.2.6
|
||||||
ejs: 3.1.10
|
ejs: 3.1.10
|
||||||
fast-json-stable-stringify: 2.1.0
|
fast-json-stable-stringify: 2.1.0
|
||||||
jest: 29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2))
|
jest: 29.7.0(@types/node@22.13.11)(ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2))
|
||||||
jest-util: 29.7.0
|
jest-util: 29.7.0
|
||||||
json5: 2.2.3
|
json5: 2.2.3
|
||||||
lodash.memoize: 4.1.2
|
lodash.memoize: 4.1.2
|
||||||
|
|
@ -15314,14 +15293,14 @@ snapshots:
|
||||||
babel-jest: 29.7.0(@babel/core@7.26.9)
|
babel-jest: 29.7.0(@babel/core@7.26.9)
|
||||||
esbuild: 0.25.1
|
esbuild: 0.25.1
|
||||||
|
|
||||||
ts-node@10.9.2(@types/node@22.13.9)(typescript@5.8.2):
|
ts-node@10.9.2(@types/node@22.13.11)(typescript@5.8.2):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@cspotcode/source-map-support': 0.8.1
|
'@cspotcode/source-map-support': 0.8.1
|
||||||
'@tsconfig/node10': 1.0.11
|
'@tsconfig/node10': 1.0.11
|
||||||
'@tsconfig/node12': 1.0.11
|
'@tsconfig/node12': 1.0.11
|
||||||
'@tsconfig/node14': 1.0.3
|
'@tsconfig/node14': 1.0.3
|
||||||
'@tsconfig/node16': 1.0.4
|
'@tsconfig/node16': 1.0.4
|
||||||
'@types/node': 22.13.9
|
'@types/node': 22.13.11
|
||||||
acorn: 8.14.0
|
acorn: 8.14.0
|
||||||
acorn-walk: 8.3.4
|
acorn-walk: 8.3.4
|
||||||
arg: 4.1.3
|
arg: 4.1.3
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ export function MenuBar(props: RowProps) {
|
||||||
paddingY="3"
|
paddingY="3"
|
||||||
paddingX="3"
|
paddingX="3"
|
||||||
paddingRight="5"
|
paddingRight="5"
|
||||||
backgroundColor="1"
|
|
||||||
>
|
>
|
||||||
<Row>
|
<Row>
|
||||||
<Button onPress={() => setCollapsed(!isCollapsed)} variant="quiet">
|
<Button onPress={() => setCollapsed(!isCollapsed)} variant="quiet">
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ export function DateRangeSetting() {
|
||||||
const handleReset = () => saveDateRange(DEFAULT_DATE_RANGE);
|
const handleReset = () => saveDateRange(DEFAULT_DATE_RANGE);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flexbox gap={10} width={300}>
|
<Flexbox gap="3" width="300px">
|
||||||
<DateFilter
|
<DateFilter
|
||||||
className={styles.field}
|
className={styles.field}
|
||||||
value={value}
|
value={value}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { Button, Select, ListItem, Flexbox } from '@umami/react-zen';
|
import { Button, Select, ListItem, Row } from '@umami/react-zen';
|
||||||
import { useLocale, useMessages } from '@/components/hooks';
|
import { useLocale, useMessages } from '@/components/hooks';
|
||||||
import { DEFAULT_LOCALE } from '@/lib/constants';
|
import { DEFAULT_LOCALE } from '@/lib/constants';
|
||||||
import { languages } from '@/lib/lang';
|
import { languages } from '@/lib/lang';
|
||||||
|
|
@ -26,7 +26,7 @@ export function LanguageSetting() {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flexbox gap={10}>
|
<Row gap="3">
|
||||||
<Select
|
<Select
|
||||||
value={locale}
|
value={locale}
|
||||||
onChange={val => saveLocale(val as string)}
|
onChange={val => saveLocale(val as string)}
|
||||||
|
|
@ -43,6 +43,6 @@ export function LanguageSetting() {
|
||||||
{!items.length && <ListItem></ListItem>}
|
{!items.length && <ListItem></ListItem>}
|
||||||
</Select>
|
</Select>
|
||||||
<Button onPress={handleReset}>{formatMessage(labels.reset)}</Button>
|
<Button onPress={handleReset}>{formatMessage(labels.reset)}</Button>
|
||||||
</Flexbox>
|
</Row>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,5 +4,5 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.active {
|
.active {
|
||||||
border: 2px solid var(--primary400);
|
border: 2px solid var(--primary-color);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ export function FieldFilterEditForm({
|
||||||
<Column>
|
<Column>
|
||||||
<Row className={styles.filter}>
|
<Row className={styles.filter}>
|
||||||
<Label>{label}</Label>
|
<Label>{label}</Label>
|
||||||
<Flexbox gap={10}>
|
<Flexbox gap="3">
|
||||||
{allowFilterSelect && (
|
{allowFilterSelect && (
|
||||||
<Select
|
<Select
|
||||||
className={styles.dropdown}
|
className={styles.dropdown}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
--journey-line-color: var(--base600);
|
--journey-line-color: var(--base600);
|
||||||
--journey-active-color: var(--primary400);
|
--journey-active-color: var(--primary-color);
|
||||||
--journey-faded-color: var(--base300);
|
--journey-faded-color: var(--base300);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -108,7 +108,7 @@
|
||||||
|
|
||||||
.node.active {
|
.node.active {
|
||||||
color: var(--light50);
|
color: var(--light50);
|
||||||
background: var(--primary400);
|
background: var(--primary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.node.selected .count {
|
.node.selected .count {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { BarChart } from '@/components/charts/BarChart';
|
||||||
import { PieChart } from '@/components/charts/PieChart';
|
import { PieChart } from '@/components/charts/PieChart';
|
||||||
import { TypeIcon } from '@/components/common/TypeIcon';
|
import { TypeIcon } from '@/components/common/TypeIcon';
|
||||||
import { useCountryNames, useLocale, useMessages } from '@/components/hooks';
|
import { useCountryNames, useLocale, useMessages } from '@/components/hooks';
|
||||||
import { GridRow } from '@/components/layout/Grid';
|
import { GridRow } from '@/components/layout/GridRow';
|
||||||
import { ListTable } from '@/components/metrics/ListTable';
|
import { ListTable } from '@/components/metrics/ListTable';
|
||||||
import { MetricCard } from '@/components/metrics/MetricCard';
|
import { MetricCard } from '@/components/metrics/MetricCard';
|
||||||
import { MetricsBar } from '@/components/metrics/MetricsBar';
|
import { MetricsBar } from '@/components/metrics/MetricsBar';
|
||||||
|
|
@ -133,7 +133,7 @@ export function RevenueView({ isLoading }: RevenueViewProps) {
|
||||||
renderXLabel={renderDateLabels(dateRange?.unit, locale)}
|
renderXLabel={renderDateLabels(dateRange?.unit, locale)}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
/>
|
/>
|
||||||
<GridRow columns="two">
|
<GridRow layout="two">
|
||||||
<ListTable
|
<ListTable
|
||||||
metric={formatMessage(labels.country)}
|
metric={formatMessage(labels.country)}
|
||||||
data={data?.country.map(({ name, value }) => ({
|
data={data?.country.map(({ name, value }) => ({
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
'use client';
|
'use client';
|
||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
|
import { Grid, Column } from '@umami/react-zen';
|
||||||
import { useLoginQuery, useMessages } from '@/components/hooks';
|
import { useLoginQuery, useMessages } from '@/components/hooks';
|
||||||
import { MenuLayout } from '@/components/layout/MenuLayout';
|
import { SideBar } from '@/components/layout/SideBar';
|
||||||
|
|
||||||
export function SettingsLayout({ children }: { children: ReactNode }) {
|
export function SettingsLayout({ children }: { children: ReactNode }) {
|
||||||
const { user } = useLoginQuery();
|
const { user } = useLoginQuery();
|
||||||
|
|
@ -21,5 +22,10 @@ export function SettingsLayout({ children }: { children: ReactNode }) {
|
||||||
},
|
},
|
||||||
].filter(n => n);
|
].filter(n => n);
|
||||||
|
|
||||||
return <MenuLayout items={items}>{children}</MenuLayout>;
|
return (
|
||||||
|
<Grid>
|
||||||
|
<SideBar items={items} />
|
||||||
|
<Column>{children}</Column>
|
||||||
|
</Grid>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
'use client';
|
'use client';
|
||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
import { useMessages, useNavigation } from '@/components/hooks';
|
import { useMessages, useNavigation } from '@/components/hooks';
|
||||||
import { MenuLayout } from '@/components/layout/MenuLayout';
|
import { Grid, Column } from '@umami/react-zen';
|
||||||
|
import { SideBar } from '@/components/layout/SideBar';
|
||||||
|
|
||||||
export function TeamSettingsLayout({ children }: { children: ReactNode }) {
|
export function TeamSettingsLayout({ children }: { children: ReactNode }) {
|
||||||
const { formatMessage, labels } = useMessages();
|
const { formatMessage, labels } = useMessages();
|
||||||
|
|
@ -25,5 +26,10 @@ export function TeamSettingsLayout({ children }: { children: ReactNode }) {
|
||||||
},
|
},
|
||||||
].filter(n => n);
|
].filter(n => n);
|
||||||
|
|
||||||
return <MenuLayout items={items}>{children}</MenuLayout>;
|
return (
|
||||||
|
<Grid>
|
||||||
|
<SideBar items={items} />
|
||||||
|
<Column>{children}</Column>
|
||||||
|
</Grid>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,17 @@
|
||||||
'use client';
|
'use client';
|
||||||
import { usePathname } from 'next/navigation';
|
import { Column } from '@umami/react-zen';
|
||||||
|
import { Panel } from '@/components/layout/Panel';
|
||||||
import { FilterTags } from '@/components/metrics/FilterTags';
|
import { FilterTags } from '@/components/metrics/FilterTags';
|
||||||
import { useNavigation } from '@/components/hooks';
|
import { useNavigation } from '@/components/hooks';
|
||||||
|
import { FILTER_COLUMNS } from '@/lib/constants';
|
||||||
import { WebsiteChart } from './WebsiteChart';
|
import { WebsiteChart } from './WebsiteChart';
|
||||||
import { WebsiteExpandedView } from './WebsiteExpandedView';
|
import { WebsiteExpandedView } from './WebsiteExpandedView';
|
||||||
import { WebsiteHeader } from './WebsiteHeader';
|
import { WebsiteHeader } from './WebsiteHeader';
|
||||||
import { WebsiteMetricsBar } from './WebsiteMetricsBar';
|
import { WebsiteMetricsBar } from './WebsiteMetricsBar';
|
||||||
import { WebsiteTableView } from './WebsiteTableView';
|
import { WebsiteTableView } from './WebsiteTableView';
|
||||||
import { FILTER_COLUMNS } from '@/lib/constants';
|
|
||||||
|
|
||||||
export function WebsiteDetailsPage({ websiteId }: { websiteId: string }) {
|
export function WebsiteDetailsPage({ websiteId }: { websiteId: string }) {
|
||||||
const pathname = usePathname();
|
|
||||||
const { query } = useNavigation();
|
const { query } = useNavigation();
|
||||||
|
|
||||||
const showLinks = !pathname.includes('/share/');
|
|
||||||
const { view } = query;
|
const { view } = query;
|
||||||
|
|
||||||
const params = Object.keys(query).reduce((obj, key) => {
|
const params = Object.keys(query).reduce((obj, key) => {
|
||||||
|
|
@ -24,13 +22,15 @@ export function WebsiteDetailsPage({ websiteId }: { websiteId: string }) {
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Column gap="3">
|
||||||
<WebsiteHeader websiteId={websiteId} showLinks={showLinks} />
|
<WebsiteHeader websiteId={websiteId} />
|
||||||
<FilterTags websiteId={websiteId} params={params} />
|
<FilterTags websiteId={websiteId} params={params} />
|
||||||
<WebsiteMetricsBar websiteId={websiteId} showFilter={true} showChange={true} sticky={true} />
|
<WebsiteMetricsBar websiteId={websiteId} showFilter={true} showChange={true} />
|
||||||
<WebsiteChart websiteId={websiteId} />
|
<Panel>
|
||||||
|
<WebsiteChart websiteId={websiteId} />
|
||||||
|
</Panel>
|
||||||
{!view && <WebsiteTableView websiteId={websiteId} />}
|
{!view && <WebsiteTableView websiteId={websiteId} />}
|
||||||
{view && <WebsiteExpandedView websiteId={websiteId} />}
|
{view && <WebsiteExpandedView websiteId={websiteId} />}
|
||||||
</>
|
</Column>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { Icon, Icons, Text, Grid, Column } from '@umami/react-zen';
|
import { Icon, Icons, Text, Grid, Column } from '@umami/react-zen';
|
||||||
import { LinkButton } from '@/components/common/LinkButton';
|
import { LinkButton } from '@/components/common/LinkButton';
|
||||||
import { useMessages, useNavigation } from '@/components/hooks';
|
import { useMessages, useNavigation } from '@/components/hooks';
|
||||||
import { MenuNav } from '@/components/layout/MenuNav';
|
import { SideBar } from '@/components/layout/SideBar';
|
||||||
import { BrowsersTable } from '@/components/metrics/BrowsersTable';
|
import { BrowsersTable } from '@/components/metrics/BrowsersTable';
|
||||||
import { CitiesTable } from '@/components/metrics/CitiesTable';
|
import { CitiesTable } from '@/components/metrics/CitiesTable';
|
||||||
import { CountriesTable } from '@/components/metrics/CountriesTable';
|
import { CountriesTable } from '@/components/metrics/CountriesTable';
|
||||||
|
|
@ -133,15 +133,8 @@ export function WebsiteExpandedView({
|
||||||
|
|
||||||
const DetailsComponent = views[view] || (() => null);
|
const DetailsComponent = views[view] || (() => null);
|
||||||
|
|
||||||
/*
|
|
||||||
const handleChange = (view: any) => {
|
|
||||||
router.push(renderUrl({ view }));
|
|
||||||
};
|
|
||||||
|
|
||||||
const renderValue = (value: string) => items.find(({ key }) => key === value)?.label;
|
|
||||||
*/
|
|
||||||
return (
|
return (
|
||||||
<Grid columns="auto 1fr" gap="6">
|
<Grid columns="auto 1fr" gap="6" marginTop="6">
|
||||||
<Column gap="6" width="200px">
|
<Column gap="6" width="200px">
|
||||||
<LinkButton href={renderUrl({ view: undefined })} variant="quiet" scroll={false}>
|
<LinkButton href={renderUrl({ view: undefined })} variant="quiet" scroll={false}>
|
||||||
<Icon rotate={180}>
|
<Icon rotate={180}>
|
||||||
|
|
@ -149,7 +142,7 @@ export function WebsiteExpandedView({
|
||||||
</Icon>
|
</Icon>
|
||||||
<Text>{formatMessage(labels.back)}</Text>
|
<Text>{formatMessage(labels.back)}</Text>
|
||||||
</LinkButton>
|
</LinkButton>
|
||||||
<MenuNav items={items} selectedKey={view} />
|
<SideBar items={items} selectedKey={view} />
|
||||||
</Column>
|
</Column>
|
||||||
<Column>
|
<Column>
|
||||||
<DetailsComponent
|
<DetailsComponent
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
import { Row, Heading } from '@umami/react-zen';
|
import { Row, Heading } from '@umami/react-zen';
|
||||||
import { Favicon } from '@/components/common/Favicon';
|
import { Favicon } from '@/components/common/Favicon';
|
||||||
import { useWebsiteQuery } from '@/components/hooks';
|
|
||||||
import { ActiveUsers } from '@/components/metrics/ActiveUsers';
|
import { ActiveUsers } from '@/components/metrics/ActiveUsers';
|
||||||
import { WebsiteTabs } from '@/app/(main)/websites/[websiteId]/WebsiteTabs';
|
import { WebsiteTabs } from '@/app/(main)/websites/[websiteId]/WebsiteTabs';
|
||||||
|
import { useWebsite } from '@/components/hooks/useWebsite';
|
||||||
|
|
||||||
export function WebsiteHeader({
|
export function WebsiteHeader({
|
||||||
websiteId,
|
websiteId,
|
||||||
|
|
@ -12,7 +12,7 @@ export function WebsiteHeader({
|
||||||
websiteId: string;
|
websiteId: string;
|
||||||
children?: ReactNode;
|
children?: ReactNode;
|
||||||
}) {
|
}) {
|
||||||
const { data: website } = useWebsiteQuery(websiteId);
|
const website = useWebsite();
|
||||||
const { name, domain } = website || {};
|
const { name, domain } = website || {};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { Grid, GridRow } from '@/components/layout/Grid';
|
import { Grid } from '@umami/react-zen';
|
||||||
|
import { Panel } from '@/components/layout/Panel';
|
||||||
import { PagesTable } from '@/components/metrics/PagesTable';
|
import { PagesTable } from '@/components/metrics/PagesTable';
|
||||||
import { ReferrersTable } from '@/components/metrics/ReferrersTable';
|
import { ReferrersTable } from '@/components/metrics/ReferrersTable';
|
||||||
import { BrowsersTable } from '@/components/metrics/BrowsersTable';
|
import { BrowsersTable } from '@/components/metrics/BrowsersTable';
|
||||||
|
|
@ -19,25 +20,43 @@ export function WebsiteTableView({ websiteId }: { websiteId: string }) {
|
||||||
const isSharePage = pathname.includes('/share/');
|
const isSharePage = pathname.includes('/share/');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid>
|
<Grid gap="3">
|
||||||
<GridRow columns="two">
|
<Grid gap="3" columns="repeat(auto-fill, minmax(500px, 1fr))">
|
||||||
<PagesTable {...tableProps} />
|
<Panel>
|
||||||
<ReferrersTable {...tableProps} />
|
<PagesTable {...tableProps} />
|
||||||
</GridRow>
|
</Panel>
|
||||||
<GridRow columns="three">
|
<Panel>
|
||||||
<BrowsersTable {...tableProps} />
|
<ReferrersTable {...tableProps} />
|
||||||
<OSTable {...tableProps} />
|
</Panel>
|
||||||
<DevicesTable {...tableProps} />
|
</Grid>
|
||||||
</GridRow>
|
<Grid gap="3" columns="repeat(auto-fill, minmax(400px, 1fr))">
|
||||||
<GridRow columns="two-one">
|
<Panel>
|
||||||
<WorldMap websiteId={websiteId} />
|
<BrowsersTable {...tableProps} />
|
||||||
<CountriesTable {...tableProps} />
|
</Panel>
|
||||||
</GridRow>
|
<Panel>
|
||||||
|
<OSTable {...tableProps} />
|
||||||
|
</Panel>
|
||||||
|
<Panel>
|
||||||
|
<DevicesTable {...tableProps} />
|
||||||
|
</Panel>
|
||||||
|
</Grid>
|
||||||
|
<Grid gap="3" columns="2fr 1fr">
|
||||||
|
<Panel padding="0">
|
||||||
|
<WorldMap websiteId={websiteId} />
|
||||||
|
</Panel>
|
||||||
|
<Panel>
|
||||||
|
<CountriesTable {...tableProps} />
|
||||||
|
</Panel>
|
||||||
|
</Grid>
|
||||||
{isSharePage && (
|
{isSharePage && (
|
||||||
<GridRow columns="one-two">
|
<Grid gap="3">
|
||||||
<EventsTable {...tableProps} />
|
<Panel>
|
||||||
<EventsChart websiteId={websiteId} />
|
<EventsTable {...tableProps} />
|
||||||
</GridRow>
|
</Panel>
|
||||||
|
<Panel>
|
||||||
|
<EventsChart websiteId={websiteId} />
|
||||||
|
</Panel>
|
||||||
|
</Grid>
|
||||||
)}
|
)}
|
||||||
</Grid>
|
</Grid>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -4,47 +4,57 @@ import { useMessages, useNavigation } from '@/components/hooks';
|
||||||
|
|
||||||
export function WebsiteTabs({ websiteId }: { websiteId: string }) {
|
export function WebsiteTabs({ websiteId }: { websiteId: string }) {
|
||||||
const { formatMessage, labels } = useMessages();
|
const { formatMessage, labels } = useMessages();
|
||||||
const { renderTeamUrl } = useNavigation();
|
const { pathname, renderTeamUrl } = useNavigation();
|
||||||
|
|
||||||
const links = [
|
const links = [
|
||||||
{
|
{
|
||||||
|
id: 'overview',
|
||||||
label: formatMessage(labels.overview),
|
label: formatMessage(labels.overview),
|
||||||
icon: <Icons.Overview />,
|
icon: <Icons.Overview />,
|
||||||
path: '',
|
path: '',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
id: 'events',
|
||||||
label: formatMessage(labels.events),
|
label: formatMessage(labels.events),
|
||||||
icon: <Icons.Lightning />,
|
icon: <Icons.Lightning />,
|
||||||
path: '/events',
|
path: '/events',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
id: 'sessions',
|
||||||
label: formatMessage(labels.sessions),
|
label: formatMessage(labels.sessions),
|
||||||
icon: <Icons.User />,
|
icon: <Icons.User />,
|
||||||
path: '/sessions',
|
path: '/sessions',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
id: 'realtime',
|
||||||
label: formatMessage(labels.realtime),
|
label: formatMessage(labels.realtime),
|
||||||
icon: <Icons.Clock />,
|
icon: <Icons.Clock />,
|
||||||
path: '/realtime',
|
path: '/realtime',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
id: 'compare',
|
||||||
label: formatMessage(labels.compare),
|
label: formatMessage(labels.compare),
|
||||||
icon: <Icons.Compare />,
|
icon: <Icons.Compare />,
|
||||||
path: '/compare',
|
path: '/compare',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
id: 'reports',
|
||||||
label: formatMessage(labels.reports),
|
label: formatMessage(labels.reports),
|
||||||
icon: <Icons.Reports />,
|
icon: <Icons.Reports />,
|
||||||
path: '/reports',
|
path: '/reports',
|
||||||
},
|
},
|
||||||
].map((link, index) => ({ ...link, id: index }));
|
];
|
||||||
|
|
||||||
|
const selectedKey = links
|
||||||
|
? links.find(({ path }) => path && pathname.endsWith(path))?.id
|
||||||
|
: 'overview';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tabs>
|
<Tabs selectedKey={selectedKey}>
|
||||||
<TabList items={links}>
|
<TabList items={links}>
|
||||||
{({ label, icon, path }) => {
|
{({ id, label, icon, path }) => {
|
||||||
return (
|
return (
|
||||||
<Tab key={path} href={renderTeamUrl(`/websites/${websiteId}/${path}`)}>
|
<Tab id={id} href={renderTeamUrl(`/websites/${websiteId}/${path}`)}>
|
||||||
<Row gap="3" alignItems="center">
|
<Row gap="3" alignItems="center">
|
||||||
<Icon fillColor="currentColor">{icon}</Icon>
|
<Icon fillColor="currentColor">{icon}</Icon>
|
||||||
<Text>{label}</Text>
|
<Text>{label}</Text>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
import { Grid } from '@umami/react-zen';
|
||||||
|
import { Panel } from '@/components/layout/Panel';
|
||||||
import { WebsiteHeader } from '../WebsiteHeader';
|
import { WebsiteHeader } from '../WebsiteHeader';
|
||||||
import { WebsiteMetricsBar } from '../WebsiteMetricsBar';
|
import { WebsiteMetricsBar } from '../WebsiteMetricsBar';
|
||||||
import { FilterTags } from '@/components/metrics/FilterTags';
|
import { FilterTags } from '@/components/metrics/FilterTags';
|
||||||
|
|
@ -18,12 +20,16 @@ export function WebsiteComparePage({ websiteId }) {
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Grid gap="3">
|
||||||
<WebsiteHeader websiteId={websiteId} />
|
<WebsiteHeader websiteId={websiteId} />
|
||||||
<FilterTags websiteId={websiteId} params={params} />
|
<FilterTags websiteId={websiteId} params={params} />
|
||||||
<WebsiteMetricsBar websiteId={websiteId} compareMode={true} showFilter={true} />
|
<WebsiteMetricsBar websiteId={websiteId} compareMode={true} showFilter={true} />
|
||||||
<WebsiteChart websiteId={websiteId} compareMode={true} />
|
<Panel>
|
||||||
<WebsiteCompareTables websiteId={websiteId} />
|
<WebsiteChart websiteId={websiteId} compareMode={true} />
|
||||||
</>
|
</Panel>
|
||||||
|
<Panel>
|
||||||
|
<WebsiteCompareTables websiteId={websiteId} />
|
||||||
|
</Panel>
|
||||||
|
</Grid>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
|
import { Grid, Heading, Column } from '@umami/react-zen';
|
||||||
import { useDateRange, useMessages, useNavigation } from '@/components/hooks';
|
import { useDateRange, useMessages, useNavigation } from '@/components/hooks';
|
||||||
import { Grid, GridRow } from '@/components/layout/Grid';
|
import { SideBar } from '@/components/layout/SideBar';
|
||||||
import { MenuNav } from '@/components/layout/MenuNav';
|
|
||||||
import { BrowsersTable } from '@/components/metrics/BrowsersTable';
|
import { BrowsersTable } from '@/components/metrics/BrowsersTable';
|
||||||
import { ChangeLabel } from '@/components/metrics/ChangeLabel';
|
import { ChangeLabel } from '@/components/metrics/ChangeLabel';
|
||||||
import { CitiesTable } from '@/components/metrics/CitiesTable';
|
import { CitiesTable } from '@/components/metrics/CitiesTable';
|
||||||
|
|
@ -20,7 +20,6 @@ import { getCompareDate } from '@/lib/date';
|
||||||
import { formatNumber } from '@/lib/format';
|
import { formatNumber } from '@/lib/format';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useWebsites } from '@/store/websites';
|
import { useWebsites } from '@/store/websites';
|
||||||
import styles from './WebsiteCompareTables.module.css';
|
|
||||||
|
|
||||||
const views = {
|
const views = {
|
||||||
url: PagesTable,
|
url: PagesTable,
|
||||||
|
|
@ -143,29 +142,22 @@ export function WebsiteCompareTables({ websiteId }: { websiteId: string }) {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid className={styles.container}>
|
<Grid columns="300px 1fr 1fr" gap="3">
|
||||||
<GridRow columns="compare">
|
<SideBar items={items} selectedKey={view} />
|
||||||
<MenuNav className={styles.nav} items={items} selectedKey={view} shallow={true} />
|
<Column>
|
||||||
<div>
|
<Heading>{formatMessage(labels.previous)}</Heading>
|
||||||
<div className={styles.title}>{formatMessage(labels.previous)}</div>
|
<Component
|
||||||
<Component
|
websiteId={websiteId}
|
||||||
websiteId={websiteId}
|
limit={20}
|
||||||
limit={20}
|
showMore={false}
|
||||||
showMore={false}
|
onDataLoad={setData}
|
||||||
onDataLoad={setData}
|
params={params}
|
||||||
params={params}
|
/>
|
||||||
/>
|
</Column>
|
||||||
</div>
|
<Column>
|
||||||
<div>
|
<Heading> {formatMessage(labels.current)}</Heading>
|
||||||
<div className={styles.title}> {formatMessage(labels.current)}</div>
|
<Component websiteId={websiteId} limit={20} showMore={false} renderChange={renderChange} />
|
||||||
<Component
|
</Column>
|
||||||
websiteId={websiteId}
|
|
||||||
limit={20}
|
|
||||||
showMore={false}
|
|
||||||
renderChange={renderChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</GridRow>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
.link:hover {
|
.link:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: var(--primary400);
|
color: var(--primary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
import { TabList, Tab, Tabs, TabPanel, Grid } from '@umami/react-zen';
|
||||||
|
import { useState } from 'react';
|
||||||
import { WebsiteHeader } from '../WebsiteHeader';
|
import { WebsiteHeader } from '../WebsiteHeader';
|
||||||
import { EventsDataTable } from './EventsDataTable';
|
import { EventsDataTable } from './EventsDataTable';
|
||||||
import { EventsMetricsBar } from './EventsMetricsBar';
|
import { EventsMetricsBar } from './EventsMetricsBar';
|
||||||
|
import { Panel } from '@/components/layout/Panel';
|
||||||
import { EventsChart } from '@/components/metrics/EventsChart';
|
import { EventsChart } from '@/components/metrics/EventsChart';
|
||||||
import { GridRow } from '@/components/layout/Grid';
|
import { GridRow } from '@/components/layout/GridRow';
|
||||||
import { MetricsTable } from '@/components/metrics/MetricsTable';
|
import { MetricsTable } from '@/components/metrics/MetricsTable';
|
||||||
import { useMessages } from '@/components/hooks';
|
import { useMessages } from '@/components/hooks';
|
||||||
import { TabList, Tab, Tabs } from '@umami/react-zen';
|
|
||||||
import { useState } from 'react';
|
|
||||||
import { EventProperties } from './EventProperties';
|
import { EventProperties } from './EventProperties';
|
||||||
|
|
||||||
export function EventsPage({ websiteId }) {
|
export function EventsPage({ websiteId }) {
|
||||||
|
|
@ -15,32 +16,36 @@ export function EventsPage({ websiteId }) {
|
||||||
const { formatMessage, labels } = useMessages();
|
const { formatMessage, labels } = useMessages();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Grid gap="3">
|
||||||
<WebsiteHeader websiteId={websiteId} />
|
<WebsiteHeader websiteId={websiteId} />
|
||||||
<EventsMetricsBar websiteId={websiteId} />
|
<EventsMetricsBar websiteId={websiteId} />
|
||||||
<GridRow columns="two-one">
|
<GridRow layout="two-one">
|
||||||
<EventsChart websiteId={websiteId} />
|
<Panel>
|
||||||
<MetricsTable
|
<EventsChart websiteId={websiteId} />
|
||||||
websiteId={websiteId}
|
</Panel>
|
||||||
type="event"
|
<Panel>
|
||||||
title={formatMessage(labels.events)}
|
<MetricsTable
|
||||||
metric={formatMessage(labels.actions)}
|
websiteId={websiteId}
|
||||||
/>
|
type="event"
|
||||||
|
title={formatMessage(labels.events)}
|
||||||
|
metric={formatMessage(labels.actions)}
|
||||||
|
/>
|
||||||
|
</Panel>
|
||||||
</GridRow>
|
</GridRow>
|
||||||
<div>
|
<Panel marginY="6">
|
||||||
<Tabs
|
<Tabs selectedKey={tab} onSelectionChange={(value: any) => setTab(value)}>
|
||||||
selectedKey={tab}
|
|
||||||
onSelectionChange={(value: any) => setTab(value)}
|
|
||||||
style={{ marginBottom: 30 }}
|
|
||||||
>
|
|
||||||
<TabList>
|
<TabList>
|
||||||
<Tab key="activity">{formatMessage(labels.activity)}</Tab>
|
<Tab id="activity">{formatMessage(labels.activity)}</Tab>
|
||||||
<Tab key="properties">{formatMessage(labels.properties)}</Tab>
|
<Tab id="properties">{formatMessage(labels.properties)}</Tab>
|
||||||
</TabList>
|
</TabList>
|
||||||
|
<TabPanel id="activity">
|
||||||
|
<EventsDataTable websiteId={websiteId} />
|
||||||
|
</TabPanel>
|
||||||
|
<TabPanel id="properties">
|
||||||
|
<EventProperties websiteId={websiteId} />
|
||||||
|
</TabPanel>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
{tab === 'activity' && <EventsDataTable websiteId={websiteId} />}
|
</Panel>
|
||||||
{tab === 'properties' && <EventProperties websiteId={websiteId} />}
|
</Grid>
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.row .link:hover {
|
.row .link:hover {
|
||||||
color: var(--primary400);
|
color: var(--primary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.search {
|
.search {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
'use client';
|
'use client';
|
||||||
import { firstBy } from 'thenby';
|
import { firstBy } from 'thenby';
|
||||||
import { Grid, GridRow } from '@/components/layout/Grid';
|
import { Grid } from '@umami/react-zen';
|
||||||
|
import { GridRow } from '@/components/layout/GridRow';
|
||||||
import { Page } from '@/components/layout/Page';
|
import { Page } from '@/components/layout/Page';
|
||||||
|
import { Panel } from '@/components/layout/Panel';
|
||||||
import { RealtimeChart } from '@/components/metrics/RealtimeChart';
|
import { RealtimeChart } from '@/components/metrics/RealtimeChart';
|
||||||
import { WorldMap } from '@/components/metrics/WorldMap';
|
import { WorldMap } from '@/components/metrics/WorldMap';
|
||||||
import { useRealtimeQuery } from '@/components/hooks';
|
import { useRealtimeQuery } from '@/components/hooks';
|
||||||
|
|
@ -26,20 +28,28 @@ export function WebsiteRealtimePage({ websiteId }) {
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Grid gap="3">
|
||||||
<WebsiteHeader websiteId={websiteId} />
|
<WebsiteHeader websiteId={websiteId} />
|
||||||
<RealtimeHeader data={data} />
|
<RealtimeHeader data={data} />
|
||||||
<RealtimeChart data={data} unit="minute" />
|
<Panel>
|
||||||
<Grid>
|
<RealtimeChart data={data} unit="minute" />
|
||||||
<GridRow columns="one-two">
|
</Panel>
|
||||||
|
<GridRow layout="one-two">
|
||||||
|
<Panel>
|
||||||
<RealtimeUrls data={data} />
|
<RealtimeUrls data={data} />
|
||||||
|
</Panel>
|
||||||
|
<Panel>
|
||||||
<RealtimeLog data={data} />
|
<RealtimeLog data={data} />
|
||||||
</GridRow>
|
</Panel>
|
||||||
<GridRow columns="one-two">
|
</GridRow>
|
||||||
|
<GridRow layout="one-two">
|
||||||
|
<Panel>
|
||||||
<RealtimeCountries data={countries} />
|
<RealtimeCountries data={countries} />
|
||||||
|
</Panel>
|
||||||
|
<Panel padding="0">
|
||||||
<WorldMap data={countries} />
|
<WorldMap data={countries} />
|
||||||
</GridRow>
|
</Panel>
|
||||||
</Grid>
|
</GridRow>
|
||||||
</>
|
</Grid>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
.link:hover {
|
.link:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: var(--primary400);
|
color: var(--primary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,12 @@ import { SessionsDataTable } from './SessionsDataTable';
|
||||||
import { SessionsMetricsBar } from './SessionsMetricsBar';
|
import { SessionsMetricsBar } from './SessionsMetricsBar';
|
||||||
import { SessionProperties } from './SessionProperties';
|
import { SessionProperties } from './SessionProperties';
|
||||||
import { WorldMap } from '@/components/metrics/WorldMap';
|
import { WorldMap } from '@/components/metrics/WorldMap';
|
||||||
import { GridRow } from '@/components/layout/Grid';
|
import { GridRow } from '@/components/layout/GridRow';
|
||||||
import { TabList, Tab, Tabs } from '@umami/react-zen';
|
import { TabList, Tab, Tabs, TabPanel } from '@umami/react-zen';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useMessages } from '@/components/hooks';
|
import { useMessages } from '@/components/hooks';
|
||||||
import { SessionsWeekly } from './SessionsWeekly';
|
import { SessionsWeekly } from './SessionsWeekly';
|
||||||
|
import { Panel } from '@/components/layout/Panel';
|
||||||
|
|
||||||
export function SessionsPage({ websiteId }) {
|
export function SessionsPage({ websiteId }) {
|
||||||
const [tab, setTab] = useState('activity');
|
const [tab, setTab] = useState('activity');
|
||||||
|
|
@ -18,22 +19,28 @@ export function SessionsPage({ websiteId }) {
|
||||||
<>
|
<>
|
||||||
<WebsiteHeader websiteId={websiteId} />
|
<WebsiteHeader websiteId={websiteId} />
|
||||||
<SessionsMetricsBar websiteId={websiteId} />
|
<SessionsMetricsBar websiteId={websiteId} />
|
||||||
<GridRow columns="two-one">
|
<GridRow layout="two-one">
|
||||||
<WorldMap websiteId={websiteId} />
|
<Panel padding="0">
|
||||||
<SessionsWeekly websiteId={websiteId} />
|
<WorldMap websiteId={websiteId} />
|
||||||
|
</Panel>
|
||||||
|
<Panel>
|
||||||
|
<SessionsWeekly websiteId={websiteId} />
|
||||||
|
</Panel>
|
||||||
</GridRow>
|
</GridRow>
|
||||||
<Tabs
|
<Panel marginY="6">
|
||||||
selectedKey={tab}
|
<Tabs selectedKey={tab} onSelectionChange={(value: any) => setTab(value)}>
|
||||||
onSelectionChange={(value: any) => setTab(value)}
|
<TabList>
|
||||||
style={{ marginBottom: 30 }}
|
<Tab id="activity">{formatMessage(labels.activity)}</Tab>
|
||||||
>
|
<Tab id="properties">{formatMessage(labels.properties)}</Tab>
|
||||||
<TabList>
|
</TabList>
|
||||||
<Tab key="activity">{formatMessage(labels.activity)}</Tab>
|
<TabPanel id="activity">
|
||||||
<Tab key="properties">{formatMessage(labels.properties)}</Tab>
|
<SessionsDataTable websiteId={websiteId} />
|
||||||
</TabList>
|
</TabPanel>
|
||||||
</Tabs>
|
<TabPanel id="properties">
|
||||||
{tab === 'activity' && <SessionsDataTable websiteId={websiteId} />}
|
<SessionProperties websiteId={websiteId} />
|
||||||
{tab === 'properties' && <SessionProperties websiteId={websiteId} />}
|
</TabPanel>
|
||||||
|
</Tabs>
|
||||||
|
</Panel>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
.cell {
|
.cell {
|
||||||
display: flex;
|
display: flex;
|
||||||
background-color: var(--base75);
|
background-color: var(--base-color-2);
|
||||||
width: 20px;
|
width: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
|
|
@ -31,12 +31,12 @@
|
||||||
|
|
||||||
.hour {
|
.hour {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: var(--font-color300);
|
color: var(--font-color);
|
||||||
height: 20px;
|
height: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.block {
|
.block {
|
||||||
background-color: var(--primary400);
|
background-color: var(--primary-color);
|
||||||
width: 20px;
|
width: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { LoadingPanel } from '@/components/common/LoadingPanel';
|
||||||
import { getDayOfWeekAsDate } from '@/lib/date';
|
import { getDayOfWeekAsDate } from '@/lib/date';
|
||||||
import styles from './SessionsWeekly.module.css';
|
import styles from './SessionsWeekly.module.css';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { Tooltip, TooltipTrigger } from '@umami/react-zen';
|
import { Focusable, Tooltip, TooltipTrigger } from '@umami/react-zen';
|
||||||
|
|
||||||
export function SessionsWeekly({ websiteId }: { websiteId: string }) {
|
export function SessionsWeekly({ websiteId }: { websiteId: string }) {
|
||||||
const { data, ...props } = useWebsiteSessionsWeeklyQuery(websiteId);
|
const { data, ...props } = useWebsiteSessionsWeeklyQuery(websiteId);
|
||||||
|
|
@ -67,12 +67,16 @@ export function SessionsWeekly({ websiteId }: { websiteId: string }) {
|
||||||
return (
|
return (
|
||||||
<div key={j} className={classNames(styles.cell)}>
|
<div key={j} className={classNames(styles.cell)}>
|
||||||
{hour > 0 && (
|
{hour > 0 && (
|
||||||
<TooltipTrigger>
|
<TooltipTrigger delay={0}>
|
||||||
<div
|
<Focusable>
|
||||||
className={styles.block}
|
<div
|
||||||
style={{ opacity: pct, transform: `scale(${pct})` }}
|
className={styles.block}
|
||||||
/>
|
style={{ opacity: pct, transform: `scale(${pct})` }}
|
||||||
<Tooltip>{`${formatMessage(labels.visitors)}: ${hour}`}</Tooltip>
|
/>
|
||||||
|
</Focusable>
|
||||||
|
<Tooltip placement="right">{`${formatMessage(
|
||||||
|
labels.visitors,
|
||||||
|
)}: ${hour}`}</Tooltip>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { TextOverflow } from '@umami/react-zen';
|
import { Text } from '@umami/react-zen';
|
||||||
import { useMessages, useSessionDataQuery } from '@/components/hooks';
|
import { useMessages, useSessionDataQuery } from '@/components/hooks';
|
||||||
import { Empty } from '@/components/common/Empty';
|
import { Empty } from '@/components/common/Empty';
|
||||||
import { DATA_TYPES } from '@/lib/constants';
|
import { DATA_TYPES } from '@/lib/constants';
|
||||||
|
|
@ -19,7 +19,7 @@ export function SessionData({ websiteId, sessionId }: { websiteId: string; sessi
|
||||||
<div key={dataKey}>
|
<div key={dataKey}>
|
||||||
<div className={styles.label}>
|
<div className={styles.label}>
|
||||||
<div className={styles.name}>
|
<div className={styles.name}>
|
||||||
<TextOverflow>{dataKey}</TextOverflow>
|
<Text>{dataKey}</Text>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.type}>{DATA_TYPES[dataType]}</div>
|
<div className={styles.type}>{DATA_TYPES[dataType]}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
import { Grid, Row, Column } from '@umami/react-zen';
|
||||||
import { Avatar } from '@/components/common/Avatar';
|
import { Avatar } from '@/components/common/Avatar';
|
||||||
import { LoadingPanel } from '@/components/common/LoadingPanel';
|
import { LoadingPanel } from '@/components/common/LoadingPanel';
|
||||||
import { useWebsiteSessionQuery } from '@/components/hooks';
|
import { useWebsiteSessionQuery } from '@/components/hooks';
|
||||||
import { WebsiteHeader } from '../../WebsiteHeader';
|
import { WebsiteHeader } from '@/app/(main)/websites/[websiteId]/WebsiteHeader';
|
||||||
import { SessionActivity } from './SessionActivity';
|
import { SessionActivity } from './SessionActivity';
|
||||||
import { SessionData } from './SessionData';
|
import { SessionData } from './SessionData';
|
||||||
import styles from './SessionDetailsPage.module.css';
|
|
||||||
import { SessionInfo } from './SessionInfo';
|
import { SessionInfo } from './SessionInfo';
|
||||||
import { SessionStats } from './SessionStats';
|
import { SessionStats } from './SessionStats';
|
||||||
|
|
||||||
|
|
@ -21,12 +21,17 @@ export function SessionDetailsPage({
|
||||||
return (
|
return (
|
||||||
<LoadingPanel {...query} loadingIcon="spinner" data={data}>
|
<LoadingPanel {...query} loadingIcon="spinner" data={data}>
|
||||||
<WebsiteHeader websiteId={websiteId} />
|
<WebsiteHeader websiteId={websiteId} />
|
||||||
<div className={styles.page}>
|
<Grid
|
||||||
<div className={styles.sidebar}>
|
gap="9"
|
||||||
<Avatar seed={data?.id} />
|
columns={{ xs: '1fr', sm: '1fr', md: '1fr 1fr', lg: '1fr 2fr 1fr', xl: '1fr 2fr 1fr' }}
|
||||||
|
>
|
||||||
|
<Column gap="6" maxWidth="200px">
|
||||||
|
<Row justifyContent="center">
|
||||||
|
<Avatar seed={data?.id} size={128} />
|
||||||
|
</Row>
|
||||||
<SessionInfo data={data} />
|
<SessionInfo data={data} />
|
||||||
</div>
|
</Column>
|
||||||
<div className={styles.content}>
|
<Column gap="6">
|
||||||
<SessionStats data={data} />
|
<SessionStats data={data} />
|
||||||
<SessionActivity
|
<SessionActivity
|
||||||
websiteId={websiteId}
|
websiteId={websiteId}
|
||||||
|
|
@ -34,11 +39,11 @@ export function SessionDetailsPage({
|
||||||
startDate={data?.firstAt}
|
startDate={data?.firstAt}
|
||||||
endDate={data?.lastAt}
|
endDate={data?.lastAt}
|
||||||
/>
|
/>
|
||||||
</div>
|
</Column>
|
||||||
<div className={styles.data}>
|
<Column gap="6">
|
||||||
<SessionData websiteId={websiteId} sessionId={sessionId} />
|
<SessionData websiteId={websiteId} sessionId={sessionId} />
|
||||||
</div>
|
</Column>
|
||||||
</div>
|
</Grid>
|
||||||
</LoadingPanel>
|
</LoadingPanel>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
|
import { Icon, TextField, Column, Row, Label, Box, Text } from '@umami/react-zen';
|
||||||
import { useFormat, useLocale, useMessages, useRegionNames, useTimezone } from '@/components/hooks';
|
import { useFormat, useLocale, useMessages, useRegionNames, useTimezone } from '@/components/hooks';
|
||||||
import { TypeIcon } from '@/components/common/TypeIcon';
|
import { TypeIcon } from '@/components/common/TypeIcon';
|
||||||
import { Icon, CopyIcon } from '@umami/react-zen';
|
|
||||||
import { Icons } from '@/components/icons';
|
import { Icons } from '@/components/icons';
|
||||||
import styles from './SessionInfo.module.css';
|
|
||||||
|
|
||||||
export function SessionInfo({ data }) {
|
export function SessionInfo({ data }) {
|
||||||
const { locale } = useLocale();
|
const { locale } = useLocale();
|
||||||
|
|
@ -12,59 +11,73 @@ export function SessionInfo({ data }) {
|
||||||
const { getRegionName } = useRegionNames(locale);
|
const { getRegionName } = useRegionNames(locale);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.info}>
|
<Column gap="6">
|
||||||
<dl>
|
<Box>
|
||||||
<dt>ID</dt>
|
<Label>ID</Label>
|
||||||
<dd>
|
<TextField value={data?.id} allowCopy />
|
||||||
{data?.id} <CopyIcon value={data?.id} />
|
</Box>
|
||||||
</dd>
|
|
||||||
|
|
||||||
<dt>{formatMessage(labels.lastSeen)}</dt>
|
<Box>
|
||||||
<dd>{formatTimezoneDate(data?.lastAt, 'PPPPpp')}</dd>
|
<Label>{formatMessage(labels.lastSeen)}</Label>
|
||||||
|
<Row>{formatTimezoneDate(data?.lastAt, 'PPPPpp')}</Row>
|
||||||
|
</Box>
|
||||||
|
|
||||||
<dt>{formatMessage(labels.firstSeen)}</dt>
|
<Box>
|
||||||
<dd>{formatTimezoneDate(data?.firstAt, 'PPPPpp')}</dd>
|
<Label>{formatMessage(labels.firstSeen)}</Label>
|
||||||
|
<Row>{formatTimezoneDate(data?.firstAt, 'PPPPpp')}</Row>
|
||||||
|
</Box>
|
||||||
|
|
||||||
<dt>{formatMessage(labels.country)}</dt>
|
<Box>
|
||||||
<dd>
|
<Label>{formatMessage(labels.country)}</Label>
|
||||||
|
<Row gap="3">
|
||||||
<TypeIcon type="country" value={data?.country} />
|
<TypeIcon type="country" value={data?.country} />
|
||||||
{formatValue(data?.country, 'country')}
|
<Text>{formatValue(data?.country, 'country')}</Text>
|
||||||
</dd>
|
</Row>
|
||||||
|
</Box>
|
||||||
|
|
||||||
<dt>{formatMessage(labels.region)}</dt>
|
<Box>
|
||||||
<dd>
|
<Label>{formatMessage(labels.region)}</Label>
|
||||||
|
<Row gap="3">
|
||||||
<Icon>
|
<Icon>
|
||||||
<Icons.Location />
|
<Icons.Location />
|
||||||
</Icon>
|
</Icon>
|
||||||
{getRegionName(data?.subdivision1)}
|
<Text>{getRegionName(data?.subdivision1)}</Text>
|
||||||
</dd>
|
</Row>
|
||||||
|
</Box>
|
||||||
|
|
||||||
<dt>{formatMessage(labels.city)}</dt>
|
<Box>
|
||||||
<dd>
|
<Label>{formatMessage(labels.city)}</Label>
|
||||||
|
<Row gap="3">
|
||||||
<Icon>
|
<Icon>
|
||||||
<Icons.Location />
|
<Icons.Location />
|
||||||
</Icon>
|
</Icon>
|
||||||
{data?.city}
|
<Text>{data?.city}</Text>
|
||||||
</dd>
|
</Row>
|
||||||
|
</Box>
|
||||||
|
|
||||||
<dt>{formatMessage(labels.os)}</dt>
|
<Box>
|
||||||
<dd>
|
<Label>{formatMessage(labels.os)}</Label>
|
||||||
|
<Row gap="3">
|
||||||
<TypeIcon type="os" value={data?.os?.toLowerCase()?.replaceAll(/\W/g, '-')} />
|
<TypeIcon type="os" value={data?.os?.toLowerCase()?.replaceAll(/\W/g, '-')} />
|
||||||
{formatValue(data?.os, 'os')}
|
<Text>{formatValue(data?.os, 'os')}</Text>
|
||||||
</dd>
|
</Row>
|
||||||
|
</Box>
|
||||||
|
|
||||||
<dt>{formatMessage(labels.device)}</dt>
|
<Box>
|
||||||
<dd>
|
<Label>{formatMessage(labels.device)}</Label>
|
||||||
|
<Row gap="3">
|
||||||
<TypeIcon type="device" value={data?.device} />
|
<TypeIcon type="device" value={data?.device} />
|
||||||
{formatValue(data?.device, 'device')}
|
<Text>{formatValue(data?.device, 'device')}</Text>
|
||||||
</dd>
|
</Row>
|
||||||
|
</Box>
|
||||||
|
|
||||||
<dt>{formatMessage(labels.browser)}</dt>
|
<Box>
|
||||||
<dd>
|
<Label>{formatMessage(labels.browser)}</Label>
|
||||||
|
<Row gap="3">
|
||||||
<TypeIcon type="browser" value={data?.browser} />
|
<TypeIcon type="browser" value={data?.browser} />
|
||||||
{formatValue(data?.browser, 'browser')}
|
<Text>{formatValue(data?.browser, 'browser')}</Text>
|
||||||
</dd>
|
</Row>
|
||||||
</dl>
|
</Box>
|
||||||
</div>
|
</Column>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,5 +17,5 @@ export function Avatar({ seed, size = 128, ...props }: { seed: string; size?: nu
|
||||||
}).toDataUri();
|
}).toDataUri();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return <img src={avatar} alt="Avatar" style={{ borderRadius: '100%' }} />;
|
return <img src={avatar} alt="Avatar" style={{ borderRadius: '100%', width: size }} />;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ import { Loading, SearchField, Row, Column } from '@umami/react-zen';
|
||||||
import { useMessages, useNavigation } from '@/components/hooks';
|
import { useMessages, useNavigation } from '@/components/hooks';
|
||||||
import { Empty } from '@/components/common/Empty';
|
import { Empty } from '@/components/common/Empty';
|
||||||
import { Pager } from '@/components/common/Pager';
|
import { Pager } from '@/components/common/Pager';
|
||||||
import { Panel } from '@/components/layout/Panel';
|
|
||||||
import { LoadingPanel } from '@/components/common/LoadingPanel';
|
import { LoadingPanel } from '@/components/common/LoadingPanel';
|
||||||
import { PagedQueryResult } from '@/lib/types';
|
import { PagedQueryResult } from '@/lib/types';
|
||||||
|
|
||||||
|
|
@ -60,14 +59,12 @@ export function DataGrid({
|
||||||
</Row>
|
</Row>
|
||||||
)}
|
)}
|
||||||
<LoadingPanel data={data} isLoading={isLoading} isFetched={isFetched} error={error}>
|
<LoadingPanel data={data} isLoading={isLoading} isFetched={isFetched} error={error}>
|
||||||
<Panel>
|
<Column>
|
||||||
<Column>
|
{hasData ? (typeof children === 'function' ? children(result) : children) : null}
|
||||||
{hasData ? (typeof children === 'function' ? children(result) : children) : null}
|
{isLoading && <Loading position="page" />}
|
||||||
{isLoading && <Loading position="page" />}
|
{!isLoading && !hasData && !search && (renderEmpty ? renderEmpty() : <Empty />)}
|
||||||
{!isLoading && !hasData && !search && (renderEmpty ? renderEmpty() : <Empty />)}
|
{!isLoading && noResults && <Empty message={formatMessage(messages.noResultsFound)} />}
|
||||||
{!isLoading && noResults && <Empty message={formatMessage(messages.noResultsFound)} />}
|
</Column>
|
||||||
</Column>
|
|
||||||
</Panel>
|
|
||||||
{allowPaging && hasData && (
|
{allowPaging && hasData && (
|
||||||
<Row marginTop="6">
|
<Row marginTop="6">
|
||||||
<Pager page={page} pageSize={pageSize} count={count} onPageChange={handlePageChange} />
|
<Pager page={page} pageSize={pageSize} count={count} onPageChange={handlePageChange} />
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
.button.primary {
|
.button.primary {
|
||||||
color: var(--light50);
|
color: var(--light50);
|
||||||
background: var(--primary400);
|
background: var(--primary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.button.primary:hover {
|
.button.primary:hover {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
|
import { Row } from '@umami/react-zen';
|
||||||
|
|
||||||
export function TypeIcon({
|
export function TypeIcon({
|
||||||
type,
|
type,
|
||||||
|
|
@ -10,7 +11,7 @@ export function TypeIcon({
|
||||||
children?: ReactNode;
|
children?: ReactNode;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<>
|
<Row gap="3" alignItems="center">
|
||||||
<img
|
<img
|
||||||
src={`${process.env.basePath || ''}/images/${type}/${value
|
src={`${process.env.basePath || ''}/images/${type}/${value
|
||||||
?.replaceAll(' ', '-')
|
?.replaceAll(' ', '-')
|
||||||
|
|
@ -23,6 +24,6 @@ export function TypeIcon({
|
||||||
height={type === 'country' ? undefined : 16}
|
height={type === 'country' ? undefined : 16}
|
||||||
/>
|
/>
|
||||||
{children}
|
{children}
|
||||||
</>
|
</Row>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1
src/components/declarations.d.ts
vendored
1
src/components/declarations.d.ts
vendored
|
|
@ -1,4 +1,5 @@
|
||||||
declare module '*.css';
|
declare module '*.css';
|
||||||
declare module '*.svg';
|
declare module '*.svg';
|
||||||
declare module '*.json';
|
declare module '*.json';
|
||||||
|
declare module 'react-simple-maps';
|
||||||
declare module 'uuid';
|
declare module 'uuid';
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ export function useNavigation() {
|
||||||
const params = useSearchParams();
|
const params = useSearchParams();
|
||||||
const [, teamId] = pathname.match(/^\/teams\/([a-f0-9-]+)/) || [];
|
const [, teamId] = pathname.match(/^\/teams\/([a-f0-9-]+)/) || [];
|
||||||
|
|
||||||
const query = useMemo(() => {
|
const query = useMemo<{ [key: string]: any }>(() => {
|
||||||
const obj = {};
|
const obj = {};
|
||||||
|
|
||||||
for (const [key, value] of params.entries()) {
|
for (const [key, value] of params.entries()) {
|
||||||
|
|
|
||||||
8
src/components/hooks/useWebsite.ts
Normal file
8
src/components/hooks/useWebsite.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
import { WebsiteContext } from '@/app/(main)/websites/[websiteId]/WebsiteProvider';
|
||||||
|
import { useContext } from 'react';
|
||||||
|
|
||||||
|
export function useWebsite() {
|
||||||
|
const website = useContext(WebsiteContext);
|
||||||
|
|
||||||
|
return website;
|
||||||
|
}
|
||||||
|
|
@ -5,8 +5,6 @@ import { DatePickerForm } from '@/components/metrics/DatePickerForm';
|
||||||
import { useLocale, useMessages } from '@/components/hooks';
|
import { useLocale, useMessages } from '@/components/hooks';
|
||||||
import { Icons } from '@/components/icons';
|
import { Icons } from '@/components/icons';
|
||||||
import { formatDate } from '@/lib/date';
|
import { formatDate } from '@/lib/date';
|
||||||
import styles from './DateFilter.module.css';
|
|
||||||
import classNames from 'classnames';
|
|
||||||
|
|
||||||
export interface DateFilterProps {
|
export interface DateFilterProps {
|
||||||
value: string;
|
value: string;
|
||||||
|
|
@ -23,11 +21,8 @@ export function DateFilter({
|
||||||
startDate,
|
startDate,
|
||||||
endDate,
|
endDate,
|
||||||
value,
|
value,
|
||||||
offset = 0,
|
|
||||||
className,
|
|
||||||
onChange,
|
onChange,
|
||||||
showAllTime = false,
|
showAllTime = false,
|
||||||
alignment = 'end',
|
|
||||||
}: DateFilterProps) {
|
}: DateFilterProps) {
|
||||||
const { formatMessage, labels } = useMessages();
|
const { formatMessage, labels } = useMessages();
|
||||||
const [showPicker, setShowPicker] = useState(false);
|
const [showPicker, setShowPicker] = useState(false);
|
||||||
|
|
@ -38,19 +33,19 @@ export function DateFilter({
|
||||||
label: formatMessage(labels.lastHours, { x: 24 }),
|
label: formatMessage(labels.lastHours, { x: 24 }),
|
||||||
value: '24hour',
|
value: '24hour',
|
||||||
},
|
},
|
||||||
{ divider: true },
|
|
||||||
{
|
{
|
||||||
label: formatMessage(labels.thisWeek),
|
label: formatMessage(labels.thisWeek),
|
||||||
value: '0week',
|
value: '0week',
|
||||||
|
divider: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: formatMessage(labels.lastDays, { x: 7 }),
|
label: formatMessage(labels.lastDays, { x: 7 }),
|
||||||
value: '7day',
|
value: '7day',
|
||||||
},
|
},
|
||||||
{ divider: true },
|
|
||||||
{
|
{
|
||||||
label: formatMessage(labels.thisMonth),
|
label: formatMessage(labels.thisMonth),
|
||||||
value: '0month',
|
value: '0month',
|
||||||
|
divider: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: formatMessage(labels.lastDays, { x: 30 }),
|
label: formatMessage(labels.lastDays, { x: 30 }),
|
||||||
|
|
@ -60,25 +55,25 @@ export function DateFilter({
|
||||||
label: formatMessage(labels.lastDays, { x: 90 }),
|
label: formatMessage(labels.lastDays, { x: 90 }),
|
||||||
value: '90day',
|
value: '90day',
|
||||||
},
|
},
|
||||||
{ divider: true },
|
|
||||||
{ label: formatMessage(labels.thisYear), value: '0year' },
|
{ label: formatMessage(labels.thisYear), value: '0year' },
|
||||||
{
|
{
|
||||||
label: formatMessage(labels.lastMonths, { x: 6 }),
|
label: formatMessage(labels.lastMonths, { x: 6 }),
|
||||||
value: '6month',
|
value: '6month',
|
||||||
|
divider: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: formatMessage(labels.lastMonths, { x: 12 }),
|
label: formatMessage(labels.lastMonths, { x: 12 }),
|
||||||
value: '12month',
|
value: '12month',
|
||||||
},
|
},
|
||||||
{ divider: true },
|
|
||||||
showAllTime && {
|
showAllTime && {
|
||||||
label: formatMessage(labels.allTime),
|
label: formatMessage(labels.allTime),
|
||||||
value: 'all',
|
value: 'all',
|
||||||
|
divider: true,
|
||||||
},
|
},
|
||||||
{ divider: true },
|
|
||||||
{
|
{
|
||||||
label: formatMessage(labels.customRange),
|
label: formatMessage(labels.customRange),
|
||||||
value: 'custom',
|
value: 'custom',
|
||||||
|
divider: true,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
.filter(n => n)
|
.filter(n => n)
|
||||||
|
|
@ -97,50 +92,21 @@ export function DateFilter({
|
||||||
onChange(value.toString());
|
onChange(value.toString());
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
const handleClose = () => setShowPicker(false);
|
|
||||||
|
|
||||||
const renderValue = (value: string) => {
|
|
||||||
const { unit } = parseDateValue(value) || {};
|
|
||||||
|
|
||||||
if (offset && unit === 'year') {
|
|
||||||
return formatDate(startDate, 'yyyy', locale);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset && unit === 'month') {
|
|
||||||
return formatDate(startDate, 'MMMM yyyy', locale);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value.startsWith('range') || offset) {
|
|
||||||
return (
|
|
||||||
<CustomRange
|
|
||||||
startDate={startDate}
|
|
||||||
endDate={endDate}
|
|
||||||
unit={unit}
|
|
||||||
onClick={() => handleChange('custom')}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return options.find(e => e.value === value)?.label;
|
|
||||||
};*/
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Select
|
<Select
|
||||||
className={classNames(className, styles.dropdown)}
|
|
||||||
items={options}
|
|
||||||
value={value}
|
value={value}
|
||||||
placeholder={formatMessage(labels.selectDate)}
|
placeholder={formatMessage(labels.selectDate)}
|
||||||
onSelectionChange={handleChange}
|
onSelectionChange={handleChange}
|
||||||
>
|
>
|
||||||
{({ label, value, divider }: any) => {
|
{options.map(({ label, value, divider }: any) => {
|
||||||
if (divider) {
|
return (
|
||||||
return <ListSeparator />;
|
<>
|
||||||
}
|
{divider && <ListSeparator />}
|
||||||
|
<ListItem id={value}>{label}</ListItem>
|
||||||
return <ListItem id={value}>{label}</ListItem>;
|
</>
|
||||||
}}
|
);
|
||||||
|
})}
|
||||||
</Select>
|
</Select>
|
||||||
{showPicker && (
|
{showPicker && (
|
||||||
<Modal isOpen={true}>
|
<Modal isOpen={true}>
|
||||||
|
|
@ -160,7 +126,7 @@ export function DateFilter({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const CustomRange = ({ startDate, endDate, unit, onClick }) => {
|
export const CustomRange = ({ startDate, endDate, unit, onClick }) => {
|
||||||
const { locale } = useLocale();
|
const { locale } = useLocale();
|
||||||
|
|
||||||
const monthFormat = unit === 'month';
|
const monthFormat = unit === 'month';
|
||||||
|
|
|
||||||
|
|
@ -1,76 +0,0 @@
|
||||||
.grid {
|
|
||||||
display: grid;
|
|
||||||
}
|
|
||||||
|
|
||||||
.row {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(6, 1fr);
|
|
||||||
border-top: 1px solid var(--base300);
|
|
||||||
}
|
|
||||||
|
|
||||||
.row.compare {
|
|
||||||
grid-template-columns: max-content 1fr 1fr;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col {
|
|
||||||
padding: 20px;
|
|
||||||
min-height: 430px;
|
|
||||||
border-inline-start: 1px solid var(--base300);
|
|
||||||
}
|
|
||||||
|
|
||||||
.col:first-child {
|
|
||||||
border-inline-start: 0;
|
|
||||||
padding-inline-start: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col:last-child {
|
|
||||||
padding-inline-end: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col.one {
|
|
||||||
grid-column: span 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col.two {
|
|
||||||
grid-column: span 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col.three {
|
|
||||||
grid-column: span 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col.two-one:first-child {
|
|
||||||
grid-column: span 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col.two-one:last-child {
|
|
||||||
grid-column: span 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col.one-two:first-child {
|
|
||||||
grid-column: span 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col.one-two:last-child {
|
|
||||||
grid-column: span 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 992px) {
|
|
||||||
.row {
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.row > .col {
|
|
||||||
border-top: 1px solid var(--base300);
|
|
||||||
border-inline-start: 0;
|
|
||||||
border-inline-end: 0;
|
|
||||||
padding: 20px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col.two,
|
|
||||||
.col.three,
|
|
||||||
.col.one-two,
|
|
||||||
.col.two-one {
|
|
||||||
grid-column: span 6 !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
import { CSSProperties } from 'react';
|
|
||||||
import classNames from 'classnames';
|
|
||||||
import { mapChildren } from '@/lib/react';
|
|
||||||
// eslint-disable-next-line css-modules/no-unused-class
|
|
||||||
import styles from './Grid.module.css';
|
|
||||||
|
|
||||||
export interface GridProps {
|
|
||||||
className?: string;
|
|
||||||
style?: CSSProperties;
|
|
||||||
children?: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Grid({ className, style, children }: GridProps) {
|
|
||||||
return (
|
|
||||||
<div className={classNames(styles.grid, className)} style={style}>
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function GridRow(props: {
|
|
||||||
[x: string]: any;
|
|
||||||
columns?: 'one' | 'two' | 'three' | 'one-two' | 'two-one' | 'compare';
|
|
||||||
className?: string;
|
|
||||||
children?: any;
|
|
||||||
}) {
|
|
||||||
const { columns = 'two', className, children, ...otherProps } = props;
|
|
||||||
return (
|
|
||||||
<div {...otherProps} className={classNames(styles.row, className, { [styles[columns]]: true })}>
|
|
||||||
{mapChildren(children, child => {
|
|
||||||
return <div className={classNames(styles.col, { [styles[columns]]: true })}>{child}</div>;
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
23
src/components/layout/GridRow.tsx
Normal file
23
src/components/layout/GridRow.tsx
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { Grid } from '@umami/react-zen';
|
||||||
|
|
||||||
|
const LAYOUTS = {
|
||||||
|
one: { columns: '1fr' },
|
||||||
|
two: { columns: { xs: '1fr', sm: '1fr', md: '1fr 1fr', lg: '1fr 1fr' } },
|
||||||
|
three: { columns: { xs: '1fr', sm: '1fr', md: '1fr 1fr 1fr', lg: '1fr 2fr' } },
|
||||||
|
'one-two': { columns: { xs: '1fr', sm: '1fr', md: '1fr 2fr', lg: '1fr 2fr' } },
|
||||||
|
'two-one': { columns: { xs: '1fr', sm: '1fr', md: '2fr 1fr', lg: '2fr 1fr', xl: '2fr 1fr' } },
|
||||||
|
};
|
||||||
|
|
||||||
|
export function GridRow(props: {
|
||||||
|
[x: string]: any;
|
||||||
|
layout?: 'one' | 'two' | 'three' | 'one-two' | 'two-one' | 'compare';
|
||||||
|
className?: string;
|
||||||
|
children?: any;
|
||||||
|
}) {
|
||||||
|
const { layout = 'two', children, ...otherProps } = props;
|
||||||
|
return (
|
||||||
|
<Grid gap="3" {...LAYOUTS[layout]} {...otherProps}>
|
||||||
|
{children}
|
||||||
|
</Grid>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
.layout {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: max-content 1fr;
|
|
||||||
gap: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu {
|
|
||||||
width: 240px;
|
|
||||||
padding-top: 34px;
|
|
||||||
padding-inline-end: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
min-height: 50vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 992px) {
|
|
||||||
.layout {
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
import { ReactNode } from 'react';
|
|
||||||
import { Grid, Column } from '@umami/react-zen';
|
|
||||||
import { MenuNav } from '@/components/layout/MenuNav';
|
|
||||||
|
|
||||||
export function MenuLayout({ items = [], children }: { items: any[]; children: ReactNode }) {
|
|
||||||
const cloudMode = !!process.env.cloudMode;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Grid columns="auto 1fr" gap="5">
|
|
||||||
{!cloudMode && (
|
|
||||||
<Column width="240px">
|
|
||||||
<MenuNav items={items} shallow={true} />
|
|
||||||
</Column>
|
|
||||||
)}
|
|
||||||
<Column>{children}</Column>
|
|
||||||
</Grid>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
.menu {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.item a {
|
|
||||||
color: var(--font-color100);
|
|
||||||
flex: 1;
|
|
||||||
padding: var(--size300) var(--size600);
|
|
||||||
}
|
|
||||||
|
|
||||||
.item {
|
|
||||||
padding: 0;
|
|
||||||
border-radius: var(--border-radius);
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected {
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
import { Column, Button, Text, List, ListItem } from '@umami/react-zen';
|
|
||||||
import Link from 'next/link';
|
|
||||||
|
|
||||||
export interface MenuNavProps {
|
|
||||||
items: any[];
|
|
||||||
selectedKey?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function MenuNav({ items, selectedKey }: MenuNavProps) {
|
|
||||||
return (
|
|
||||||
<List>
|
|
||||||
{items.map(({ key, label, url }) => {
|
|
||||||
return (
|
|
||||||
<ListItem key={key} href={url}>
|
|
||||||
<Text weight={key === selectedKey ? 'bold' : 'regular'}>{label}</Text>
|
|
||||||
</ListItem>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</List>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function MenuNav2({ items, selectedKey }: MenuNavProps) {
|
|
||||||
return (
|
|
||||||
<Column gap="3" alignItems="flex-start" justifyContent="stretch">
|
|
||||||
{items.map(({ key, label, url }) => {
|
|
||||||
return (
|
|
||||||
<Button key={key} style={{ width: '100%' }} asChild>
|
|
||||||
<Link href={url}>
|
|
||||||
<Text weight={key === selectedKey ? 'bold' : 'regular'}>{label}</Text>
|
|
||||||
</Link>
|
|
||||||
</Button>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Column>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -25,17 +25,7 @@ export function Page({
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Column
|
<Column {...props} width="100%" maxWidth="1320px" margin="auto" paddingBottom="9">
|
||||||
{...props}
|
|
||||||
gridColumn="2 / 3"
|
|
||||||
gridRow="2 / 3"
|
|
||||||
marginRight="6"
|
|
||||||
marginBottom="6"
|
|
||||||
width="100%"
|
|
||||||
maxWidth="1320px"
|
|
||||||
minHeight="600px"
|
|
||||||
margin="auto"
|
|
||||||
>
|
|
||||||
{children}
|
{children}
|
||||||
</Column>
|
</Column>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ export function PageHeader({
|
||||||
children?: ReactNode;
|
children?: ReactNode;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<Row justifyContent="space-between" alignItems="center" paddingBottom="6">
|
<Row justifyContent="space-between" alignItems="center">
|
||||||
<Row gap="3">
|
<Row gap="3">
|
||||||
{icon && <Icon size="lg">{icon}</Icon>}
|
{icon && <Icon size="lg">{icon}</Icon>}
|
||||||
{title && <Heading>{title}</Heading>}
|
{title && <Heading>{title}</Heading>}
|
||||||
|
|
|
||||||
|
|
@ -2,5 +2,14 @@ import { Box } from '@umami/react-zen';
|
||||||
import type { BoxProps } from '@umami/react-zen/Box';
|
import type { BoxProps } from '@umami/react-zen/Box';
|
||||||
|
|
||||||
export function Panel(props: BoxProps) {
|
export function Panel(props: BoxProps) {
|
||||||
return <Box padding="6" borderSize="1" borderRadius="3" backgroundColor="solid" {...props} />;
|
return (
|
||||||
|
<Box
|
||||||
|
padding="6"
|
||||||
|
borderSize="1"
|
||||||
|
borderRadius="3"
|
||||||
|
backgroundColor="solid"
|
||||||
|
shadow="4"
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
20
src/components/layout/SideBar.tsx
Normal file
20
src/components/layout/SideBar.tsx
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
import { Text, List, ListItem } from '@umami/react-zen';
|
||||||
|
|
||||||
|
export interface MenuNavProps {
|
||||||
|
items: any[];
|
||||||
|
selectedKey?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SideBar({ items, selectedKey }: MenuNavProps) {
|
||||||
|
return (
|
||||||
|
<List>
|
||||||
|
{items.map(({ key, label, url }) => {
|
||||||
|
return (
|
||||||
|
<ListItem key={key} href={url}>
|
||||||
|
<Text weight={key === selectedKey ? 'bold' : 'regular'}>{label}</Text>
|
||||||
|
</ListItem>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</List>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -2,8 +2,7 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
font-size: 13px;
|
font-size: 12px;
|
||||||
font-weight: 700;
|
|
||||||
padding: 0.1em 0.5em;
|
padding: 0.1em 0.5em;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
color: var(--base500);
|
color: var(--base500);
|
||||||
|
|
@ -11,16 +10,16 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.positive {
|
.positive {
|
||||||
color: var(--green700);
|
color: var(--success-color);
|
||||||
background: var(--green100);
|
background: color-mix(in srgb, var(--success-color), var(--background-color) 85%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.negative {
|
.negative {
|
||||||
color: var(--red700);
|
color: var(--danger-color);
|
||||||
background: var(--red100);
|
background: color-mix(in srgb, var(--danger-color), var(--background-color) 85%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.neutral {
|
.neutral {
|
||||||
color: var(--base700);
|
color: var(--font-color-muted);
|
||||||
background: var(--base100);
|
background: var(--base-color-2);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.row:hover {
|
.row:hover {
|
||||||
background-color: var(--base75);
|
background-color: var(--base-color-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
|
|
@ -60,7 +60,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.label a:hover {
|
.label a:hover {
|
||||||
color: var(--primary400);
|
color: var(--primary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.label:empty {
|
.label:empty {
|
||||||
|
|
@ -83,8 +83,8 @@
|
||||||
.percent {
|
.percent {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 50px;
|
width: 50px;
|
||||||
color: var(--base600);
|
color: var(--base-color-9);
|
||||||
border-inline-start: 1px solid var(--base600);
|
border-inline-start: 1px solid var(--base-color-9);
|
||||||
padding-inline-start: 10px;
|
padding-inline-start: 10px;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
@ -95,7 +95,7 @@
|
||||||
left: 0;
|
left: 0;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
opacity: 0.1;
|
opacity: 0.1;
|
||||||
background: var(--primary400);
|
background: var(--primary-color);
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { ReactNode } from 'react';
|
||||||
import { FixedSizeList } from 'react-window';
|
import { FixedSizeList } from 'react-window';
|
||||||
import { useSpring, config } from '@react-spring/web';
|
import { useSpring, config } from '@react-spring/web';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
@ -6,7 +7,6 @@ import { Empty } from '@/components/common/Empty';
|
||||||
import { formatLongNumber } from '@/lib/format';
|
import { formatLongNumber } from '@/lib/format';
|
||||||
import { useMessages } from '@/components/hooks';
|
import { useMessages } from '@/components/hooks';
|
||||||
import styles from './ListTable.module.css';
|
import styles from './ListTable.module.css';
|
||||||
import { ReactNode } from 'react';
|
|
||||||
|
|
||||||
const ITEM_SIZE = 30;
|
const ITEM_SIZE = 30;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
.container {
|
|
||||||
position: relative;
|
|
||||||
min-height: 430px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.actions {
|
|
||||||
display: flex;
|
|
||||||
gap: 20px;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search {
|
|
||||||
max-width: 300px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 992px) {
|
|
||||||
.container {
|
|
||||||
min-height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.actions {
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search {
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { ReactNode, useMemo, useState } from 'react';
|
import { ReactNode, useMemo, useState } from 'react';
|
||||||
import { Loading, Icon, Text, SearchField, Row } from '@umami/react-zen';
|
import { Loading, Icon, Text, SearchField, Row, Column } from '@umami/react-zen';
|
||||||
import { ErrorMessage } from '@/components/common/ErrorMessage';
|
import { ErrorMessage } from '@/components/common/ErrorMessage';
|
||||||
import { LinkButton } from '@/components/common/LinkButton';
|
import { LinkButton } from '@/components/common/LinkButton';
|
||||||
import { DEFAULT_ANIMATION_DURATION } from '@/lib/constants';
|
import { DEFAULT_ANIMATION_DURATION } from '@/lib/constants';
|
||||||
|
|
@ -7,8 +7,6 @@ import { percentFilter } from '@/lib/filters';
|
||||||
import { useNavigation, useWebsiteMetricsQuery, useMessages, useFormat } from '@/components/hooks';
|
import { useNavigation, useWebsiteMetricsQuery, useMessages, useFormat } from '@/components/hooks';
|
||||||
import { Icons } from '@/components/icons';
|
import { Icons } from '@/components/icons';
|
||||||
import { ListTable, ListTableProps } from './ListTable';
|
import { ListTable, ListTableProps } from './ListTable';
|
||||||
import styles from './MetricsTable.module.css';
|
|
||||||
import { Panel } from '@/components/layout/Panel';
|
|
||||||
|
|
||||||
export interface MetricsTableProps extends ListTableProps {
|
export interface MetricsTableProps extends ListTableProps {
|
||||||
websiteId: string;
|
websiteId: string;
|
||||||
|
|
@ -85,20 +83,12 @@ export function MetricsTable({
|
||||||
}, [data, dataFilter, search, limit, formatValue, type]);
|
}, [data, dataFilter, search, limit, formatValue, type]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Panel>
|
<Column gap="3" justifyContent="space-between">
|
||||||
{error && <ErrorMessage />}
|
{error && <ErrorMessage />}
|
||||||
<div className={styles.actions}>
|
<Row alignItems="center" justifyContent="space-between">
|
||||||
{allowSearch && (
|
{allowSearch && <SearchField value={search} onSearch={setSearch} delay={300} />}
|
||||||
<SearchField
|
|
||||||
className={styles.search}
|
|
||||||
value={search}
|
|
||||||
onSearch={setSearch}
|
|
||||||
delay={300}
|
|
||||||
autoFocus={true}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</Row>
|
||||||
{data && !error && (
|
{data && !error && (
|
||||||
<ListTable {...(props as ListTableProps)} data={filteredData} className={className} />
|
<ListTable {...(props as ListTableProps)} data={filteredData} className={className} />
|
||||||
)}
|
)}
|
||||||
|
|
@ -113,6 +103,6 @@ export function MetricsTable({
|
||||||
</LinkButton>
|
</LinkButton>
|
||||||
)}
|
)}
|
||||||
</Row>
|
</Row>
|
||||||
</Panel>
|
</Column>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ import { useMemo } from 'react';
|
||||||
import { BarChart, BarChartProps } from '@/components/charts/BarChart';
|
import { BarChart, BarChartProps } from '@/components/charts/BarChart';
|
||||||
import { useLocale, useTheme, useMessages } from '@/components/hooks';
|
import { useLocale, useTheme, useMessages } from '@/components/hooks';
|
||||||
import { renderDateLabels } from '@/lib/charts';
|
import { renderDateLabels } from '@/lib/charts';
|
||||||
import { Panel } from '@/components/layout/Panel';
|
|
||||||
|
|
||||||
export interface PageviewsChartProps extends BarChartProps {
|
export interface PageviewsChartProps extends BarChartProps {
|
||||||
data: {
|
data: {
|
||||||
|
|
@ -77,15 +76,13 @@ export function PageviewsChart({
|
||||||
}, [data, locale]);
|
}, [data, locale]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Panel>
|
<BarChart
|
||||||
<BarChart
|
{...props}
|
||||||
{...props}
|
data={chartData}
|
||||||
data={chartData}
|
unit={unit}
|
||||||
unit={unit}
|
isLoading={isLoading}
|
||||||
isLoading={isLoading}
|
isAllTime={isAllTime}
|
||||||
isAllTime={isAllTime}
|
renderXLabel={renderDateLabels(unit, locale)}
|
||||||
renderXLabel={renderDateLabels(unit, locale)}
|
/>
|
||||||
/>
|
|
||||||
</Panel>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
.param {
|
.param {
|
||||||
padding: 0 8px;
|
padding: 0 8px;
|
||||||
color: var(--primary400);
|
color: var(--primary-color);
|
||||||
background: var(--blue100);
|
background: var(--blue100);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ export function ReferrersTable({ allowFilter, ...props }: ReferrersTableProps) {
|
||||||
return `(${formatMessage(labels.other)})`;
|
return `(${formatMessage(labels.other)})`;
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<Flexbox alignItems="center" gap={10}>
|
<Flexbox alignItems="center" gap="3">
|
||||||
<Favicon domain={referrer} />
|
<Favicon domain={referrer} />
|
||||||
{GROUPED_DOMAINS.find(({ domain }) => domain === referrer)?.name}
|
{GROUPED_DOMAINS.find(({ domain }) => domain === referrer)?.name}
|
||||||
</Flexbox>
|
</Flexbox>
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,20 @@
|
||||||
|
import { FloatingTooltip, Column } from '@umami/react-zen';
|
||||||
import { useState, useMemo, HTMLAttributes } from 'react';
|
import { useState, useMemo, HTMLAttributes } from 'react';
|
||||||
import { ComposableMap, Geographies, Geography, ZoomableGroup } from 'react-simple-maps';
|
import { ComposableMap, Geographies, Geography, ZoomableGroup } from 'react-simple-maps';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { colord } from 'colord';
|
import { colord } from 'colord';
|
||||||
import { ISO_COUNTRIES, MAP_FILE } from '@/lib/constants';
|
import { ISO_COUNTRIES, MAP_FILE } from '@/lib/constants';
|
||||||
import { useDateRange, useTheme, useWebsiteMetricsQuery } from '@/components/hooks';
|
import {
|
||||||
import { useCountryNames } from '@/components/hooks';
|
useDateRange,
|
||||||
import { useLocale } from '@/components/hooks';
|
useTheme,
|
||||||
import { useMessages } from '@/components/hooks';
|
useWebsiteMetricsQuery,
|
||||||
|
useCountryNames,
|
||||||
|
useLocale,
|
||||||
|
useMessages,
|
||||||
|
} from '@/components/hooks';
|
||||||
import { formatLongNumber } from '@/lib/format';
|
import { formatLongNumber } from '@/lib/format';
|
||||||
import { percentFilter } from '@/lib/filters';
|
import { percentFilter } from '@/lib/filters';
|
||||||
import styles from './WorldMap.module.css';
|
import styles from './WorldMap.module.css';
|
||||||
import { FloatingTooltip } from '@umami/react-zen';
|
|
||||||
|
|
||||||
export function WorldMap({
|
export function WorldMap({
|
||||||
websiteId,
|
websiteId,
|
||||||
|
|
@ -70,7 +74,7 @@ export function WorldMap({
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<Column
|
||||||
{...props}
|
{...props}
|
||||||
className={classNames(styles.container, className)}
|
className={classNames(styles.container, className)}
|
||||||
data-tip=""
|
data-tip=""
|
||||||
|
|
@ -105,6 +109,6 @@ export function WorldMap({
|
||||||
</ZoomableGroup>
|
</ZoomableGroup>
|
||||||
</ComposableMap>
|
</ComposableMap>
|
||||||
{tooltip && <FloatingTooltip>{tooltip}</FloatingTooltip>}
|
{tooltip && <FloatingTooltip>{tooltip}</FloatingTooltip>}
|
||||||
</div>
|
</Column>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,6 @@ a:hover {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
svg {
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
shape-rendering: geometricPrecision;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar {
|
::-webkit-scrollbar {
|
||||||
width: 15px;
|
width: 15px;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue