From c3e68e511fbd15ef5a65d9ba69f9cc92cc37a244 Mon Sep 17 00:00:00 2001 From: Aritra Chatterjee Date: Mon, 15 Jan 2024 21:53:35 +0530 Subject: [PATCH 01/34] fix: readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7b71a7fc..d36b93ab 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ data". If you access the app via http://localhost:3000/, you can interact with it with your wallet. You'll need to "Claim Airdrop" in order to get a deck to play with. -However, for testing, it's expected you'll the Anvil ("test ... junk" mnemonic) accounts. These come +However, for testing, it's expected you'll use the Anvil ("test ... junk" mnemonic) accounts. These come preloaded with local testnet ETH, and as part of our deploy script, we pre-airdrop a deck to accounts 0 and 1. From 61df2f5c75566b50cad3bab604ecfe40599a16ce Mon Sep 17 00:00:00 2001 From: Aritra Chatterjee Date: Wed, 17 Jan 2024 00:06:13 +0530 Subject: [PATCH 02/34] update packages --- packages/webapp/package.json | 9 +- pnpm-lock.yaml | 641 ++++++++++++++++++++++++++++------- 2 files changed, 523 insertions(+), 127 deletions(-) diff --git a/packages/webapp/package.json b/packages/webapp/package.json index 9aad494d..f9c07c9f 100644 --- a/packages/webapp/package.json +++ b/packages/webapp/package.json @@ -12,17 +12,25 @@ "@dnd-kit/sortable": "^7.0.2", "@dnd-kit/utilities": "^3.2.1", "@emotion/react": "^11.11.1", + "@radix-ui/react-dialog": "^1.0.5", + "@radix-ui/react-navigation-menu": "^1.1.4", + "@radix-ui/react-slot": "^1.0.2", "circomlibjs": "^0.1.7", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.0", "connectkit": "^1.5.3", "jotai": "^2.4.3", "jotai-devtools": "^0.7.0", "lodash": "^4.17.21", + "lucide-react": "^0.309.0", "next": "^13.5.6", "next-transpile-modules": "^10.0.1", "react": "18.2.0", "react-dom": "18.2.0", "react-icons": "^4.11.0", "snarkjs": "^0.7.1", + "tailwind-merge": "^2.2.0", + "tailwindcss-animate": "^1.0.7", "viem": "^1.16.6", "wagmi": "^1.4.5" }, @@ -39,7 +47,6 @@ "@wagmi/cli": "^1.5.2", "@welldone-software/why-did-you-render": "^7.0.1", "autoprefixer": "^10.4.16", - "daisyui": "^3.8.2", "eslint": "^8.52.0", "eslint-config-next": "^13.5.6", "postcss": "^8.4.31", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e64d13eb..40703447 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -75,9 +75,24 @@ importers: '@emotion/react': specifier: ^11.11.1 version: 11.11.1(@types/react@18.2.31)(react@18.2.0) + '@radix-ui/react-dialog': + specifier: ^1.0.5 + version: 1.0.5(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-navigation-menu': + specifier: ^1.1.4 + version: 1.1.4(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': + specifier: ^1.0.2 + version: 1.0.2(@types/react@18.2.31)(react@18.2.0) circomlibjs: specifier: ^0.1.7 version: 0.1.7 + class-variance-authority: + specifier: ^0.7.0 + version: 0.7.0 + clsx: + specifier: ^2.1.0 + version: 2.1.0 connectkit: specifier: ^1.5.3 version: 1.5.3(@babel/core@7.23.2)(react-dom@18.2.0)(react-is@18.2.0)(react@18.2.0)(viem@1.16.6)(wagmi@1.4.5) @@ -90,6 +105,9 @@ importers: lodash: specifier: ^4.17.21 version: 4.17.21 + lucide-react: + specifier: ^0.309.0 + version: 0.309.0(react@18.2.0) next: specifier: ^13.5.6 version: 13.5.6(@babel/core@7.23.2)(react-dom@18.2.0)(react@18.2.0) @@ -108,6 +126,12 @@ importers: snarkjs: specifier: ^0.7.1 version: 0.7.1 + tailwind-merge: + specifier: ^2.2.0 + version: 2.2.0 + tailwindcss-animate: + specifier: ^1.0.7 + version: 1.0.7(tailwindcss@3.3.3) viem: specifier: ^1.16.6 version: 1.16.6(typescript@5.2.2)(zod@3.22.4) @@ -151,9 +175,6 @@ importers: autoprefixer: specifier: ^10.4.16 version: 10.4.16(postcss@8.4.31) - daisyui: - specifier: ^3.8.2 - version: 3.8.2 eslint: specifier: ^8.52.0 version: 8.52.0 @@ -191,7 +212,6 @@ packages: /@alloc/quick-lru@5.2.0: resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} - dev: true /@ampproject/remapping@2.2.1: resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} @@ -303,7 +323,7 @@ packages: '@babel/core': 7.23.2 '@babel/helper-compilation-targets': 7.22.15 '@babel/helper-plugin-utils': 7.22.5 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) lodash.debounce: 4.0.8 resolve: 1.22.8 transitivePeerDependencies: @@ -1332,6 +1352,13 @@ packages: engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.14.0 + dev: false + + /@babel/runtime@7.23.8: + resolution: {integrity: sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.14.0 /@babel/template@7.22.15: resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} @@ -1420,7 +1447,7 @@ packages: chalk: 4.1.2 cypress: 12.17.4 dayjs: 1.11.10 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) execa: 4.1.0 globby: 11.0.4 istanbul-lib-coverage: 3.0.0 @@ -1489,7 +1516,7 @@ packages: '@babel/preset-env': 7.23.2(@babel/core@7.23.2) babel-loader: 9.1.3(@babel/core@7.23.2)(webpack@5.89.0) bluebird: 3.7.1 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) lodash: 4.17.21 webpack: 5.89.0 transitivePeerDependencies: @@ -1559,7 +1586,7 @@ packages: resolution: {integrity: sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==} dependencies: '@babel/helper-module-imports': 7.22.15 - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.8 '@emotion/hash': 0.9.1 '@emotion/memoize': 0.8.1 '@emotion/serialize': 1.1.2 @@ -2859,12 +2886,10 @@ packages: dependencies: '@nodelib/fs.stat': 2.0.5 run-parallel: 1.2.0 - dev: true /@nodelib/fs.stat@2.0.5: resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} engines: {node: '>= 8'} - dev: true /@nodelib/fs.walk@1.2.8: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} @@ -2872,7 +2897,6 @@ packages: dependencies: '@nodelib/fs.scandir': 2.1.5 fastq: 1.15.0 - dev: true /@openzeppelin/contracts@4.9.3: resolution: {integrity: sha512-He3LieZ1pP2TNt5JbkPA4PNT9WC3gOTOlDcFGJW4Le4QKqwmiNJCRt44APfxMxvq7OugU/cqYuPcSBzOw38DAg==} @@ -2889,13 +2913,43 @@ packages: /@radix-ui/number@1.0.0: resolution: {integrity: sha512-Ofwh/1HX69ZfJRiRBMTy7rgjAzHmwe4kW9C9Y99HTRUcYLUuVT0KESFj15rPjRgKJs20GPq8Bm5aEDJ8DuA3vA==} dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.8 dev: false /@radix-ui/primitive@1.0.0: resolution: {integrity: sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA==} dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.8 + dev: false + + /@radix-ui/primitive@1.0.1: + resolution: {integrity: sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==} + dependencies: + '@babel/runtime': 7.23.8 + dev: false + + /@radix-ui/react-collection@1.0.3(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.31)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.31)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.31)(react@18.2.0) + '@types/react': 18.2.31 + '@types/react-dom': 18.2.14 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) dev: false /@radix-ui/react-compose-refs@1.0.0(react@18.2.0): @@ -2903,7 +2957,21 @@ packages: peerDependencies: react: ^16.8 || ^17.0 || ^18.0 dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.8 + react: 18.2.0 + dev: false + + /@radix-ui/react-compose-refs@1.0.1(@types/react@18.2.31)(react@18.2.0): + resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@types/react': 18.2.31 react: 18.2.0 dev: false @@ -2912,51 +2980,288 @@ packages: peerDependencies: react: ^16.8 || ^17.0 || ^18.0 dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.8 react: 18.2.0 dev: false + /@radix-ui/react-context@1.0.1(@types/react@18.2.31)(react@18.2.0): + resolution: {integrity: sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@types/react': 18.2.31 + react: 18.2.0 + dev: false + + /@radix-ui/react-dialog@1.0.5(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.31)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.31)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.31)(react@18.2.0) + '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.31)(react@18.2.0) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.31)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.31)(react@18.2.0) + '@types/react': 18.2.31 + '@types/react-dom': 18.2.14 + aria-hidden: 1.2.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-remove-scroll: 2.5.5(@types/react@18.2.31)(react@18.2.0) + dev: false + /@radix-ui/react-direction@1.0.0(react@18.2.0): resolution: {integrity: sha512-2HV05lGUgYcA6xgLQ4BKPDmtL+QbIZYH5fCOTAOOcJ5O0QbWS3i9lKaurLzliYUDhORI2Qr3pyjhJh44lKA3rQ==} peerDependencies: react: ^16.8 || ^17.0 || ^18.0 dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.8 + react: 18.2.0 + dev: false + + /@radix-ui/react-direction@1.0.1(@types/react@18.2.31)(react@18.2.0): + resolution: {integrity: sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@types/react': 18.2.31 react: 18.2.0 dev: false + /@radix-ui/react-dismissable-layer@1.0.5(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.31)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.31)(react@18.2.0) + '@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@18.2.31)(react@18.2.0) + '@types/react': 18.2.31 + '@types/react-dom': 18.2.14 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-focus-guards@1.0.1(@types/react@18.2.31)(react@18.2.0): + resolution: {integrity: sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@types/react': 18.2.31 + react: 18.2.0 + dev: false + + /@radix-ui/react-focus-scope@1.0.4(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.31)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.31)(react@18.2.0) + '@types/react': 18.2.31 + '@types/react-dom': 18.2.14 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-id@1.0.1(@types/react@18.2.31)(react@18.2.0): + resolution: {integrity: sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.31)(react@18.2.0) + '@types/react': 18.2.31 + react: 18.2.0 + dev: false + + /@radix-ui/react-navigation-menu@1.1.4(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-Cc+seCS3PmWmjI51ufGG7zp1cAAIRqHVw7C9LOA2TZ+R4hG6rDvHcTqIsEEFLmZO3zNVH72jOOE7kKNy8W+RtA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.31)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.31)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.31)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.31)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.31)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.31)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.31)(react@18.2.0) + '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.31)(react@18.2.0) + '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.31 + '@types/react-dom': 18.2.14 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-portal@1.0.4(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.31 + '@types/react-dom': 18.2.14 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@radix-ui/react-presence@1.0.0(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-A+6XEvN01NfVWiKu38ybawfHsBjWum42MRPnEuqPsBZ4eV7e/7K321B5VgYMPv3Xx5An6o1/l9ZuDBgmcmWK3w==} peerDependencies: react: ^16.8 || ^17.0 || ^18.0 react-dom: ^16.8 || ^17.0 || ^18.0 dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.8 '@radix-ui/react-compose-refs': 1.0.0(react@18.2.0) '@radix-ui/react-use-layout-effect': 1.0.0(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false + /@radix-ui/react-presence@1.0.1(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.31)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.31)(react@18.2.0) + '@types/react': 18.2.31 + '@types/react-dom': 18.2.14 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@radix-ui/react-primitive@1.0.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-fHbmislWVkZaIdeF6GZxF0A/NH/3BjrGIYj+Ae6eTmTCr7EB0RQAAVEiqsXK6p3/JcRqVSBQoceZroj30Jj3XA==} peerDependencies: react: ^16.8 || ^17.0 || ^18.0 react-dom: ^16.8 || ^17.0 || ^18.0 dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.8 '@radix-ui/react-slot': 1.0.1(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false + /@radix-ui/react-primitive@1.0.3(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.31)(react@18.2.0) + '@types/react': 18.2.31 + '@types/react-dom': 18.2.14 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@radix-ui/react-scroll-area@1.0.2(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-k8VseTxI26kcKJaX0HPwkvlNBPTs56JRdYzcZ/vzrNUkDlvXBy8sMc7WvCpYzZkHgb+hd72VW9MqkqecGtuNgg==} peerDependencies: react: ^16.8 || ^17.0 || ^18.0 react-dom: ^16.8 || ^17.0 || ^18.0 dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.8 '@radix-ui/number': 1.0.0 '@radix-ui/primitive': 1.0.0 '@radix-ui/react-compose-refs': 1.0.0(react@18.2.0) @@ -2975,17 +3280,76 @@ packages: peerDependencies: react: ^16.8 || ^17.0 || ^18.0 dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.8 '@radix-ui/react-compose-refs': 1.0.0(react@18.2.0) react: 18.2.0 dev: false + /@radix-ui/react-slot@1.0.2(@types/react@18.2.31)(react@18.2.0): + resolution: {integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.31)(react@18.2.0) + '@types/react': 18.2.31 + react: 18.2.0 + dev: false + /@radix-ui/react-use-callback-ref@1.0.0(react@18.2.0): resolution: {integrity: sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg==} peerDependencies: react: ^16.8 || ^17.0 || ^18.0 dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.8 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.2.31)(react@18.2.0): + resolution: {integrity: sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@types/react': 18.2.31 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-controllable-state@1.0.1(@types/react@18.2.31)(react@18.2.0): + resolution: {integrity: sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.31)(react@18.2.0) + '@types/react': 18.2.31 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-escape-keydown@1.0.3(@types/react@18.2.31)(react@18.2.0): + resolution: {integrity: sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.31)(react@18.2.0) + '@types/react': 18.2.31 react: 18.2.0 dev: false @@ -2994,16 +3358,65 @@ packages: peerDependencies: react: ^16.8 || ^17.0 || ^18.0 dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.8 react: 18.2.0 dev: false + /@radix-ui/react-use-layout-effect@1.0.1(@types/react@18.2.31)(react@18.2.0): + resolution: {integrity: sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@types/react': 18.2.31 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-previous@1.0.1(@types/react@18.2.31)(react@18.2.0): + resolution: {integrity: sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@types/react': 18.2.31 + react: 18.2.0 + dev: false + + /@radix-ui/react-visually-hidden@1.0.3(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.31 + '@types/react-dom': 18.2.14 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@redux-devtools/extension@3.2.5(redux@4.2.1): resolution: {integrity: sha512-UhyDF7WmdnCrN1s++YC4sdQCo0z6YUnoB2eCh15nXDDq3QH1jDju1144UNRU6Nvi4inxhaIum4m9BXVYWVC1ng==} peerDependencies: redux: ^3.1.0 || ^4.0.0 dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.8 immutable: 4.3.4 redux: 4.2.1 dev: false @@ -3124,7 +3537,7 @@ packages: /@solana/web3.js@1.87.3: resolution: {integrity: sha512-WGLzTZpi00vP443qGK3gL+LZXQJwaWkh6bzNXYpMTCAH2Z102y3YbPWOoQzJUeRSZWSXKh7MFkA3vDMFlMvGZQ==} dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.8 '@noble/curves': 1.2.0 '@noble/hashes': 1.3.2 '@solana/buffer-layout': 4.0.1 @@ -3287,7 +3700,7 @@ packages: commander: 10.0.1 cypress: 12.17.4 cypress-wait-until: 1.7.2 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) dotenv: 16.3.1 dotenv-parse-variables: 2.0.0 download: 8.0.0 @@ -3359,7 +3772,7 @@ packages: peerDependencies: cypress: ^12.0.0 dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.8 '@testing-library/dom': 8.20.1 cypress: 12.17.4 dev: true @@ -3369,7 +3782,7 @@ packages: engines: {node: '>=10'} dependencies: '@babel/code-frame': 7.22.13 - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.8 '@types/aria-query': 4.2.2 aria-query: 4.2.2 chalk: 4.1.2 @@ -3383,7 +3796,7 @@ packages: engines: {node: '>=12'} dependencies: '@babel/code-frame': 7.22.13 - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.8 '@types/aria-query': 5.0.3 aria-query: 5.1.3 chalk: 4.1.2 @@ -3397,7 +3810,7 @@ packages: engines: {node: '>=14'} dependencies: '@babel/code-frame': 7.22.13 - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.8 '@types/aria-query': 5.0.3 aria-query: 5.1.3 chalk: 4.1.2 @@ -3413,7 +3826,7 @@ packages: react: ^18.0.0 react-dom: ^18.0.0 dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.8 '@testing-library/dom': 9.3.3 '@types/react-dom': 18.2.14 react: 18.2.0 @@ -3636,7 +4049,6 @@ packages: resolution: {integrity: sha512-V835xgdSVmyQmI1KLV2BEIUgqEuinxp9O4G6g3FqO/SqLac049E53aysv0oEFD2kHfejeKU+ZqL2bcFWj9gLAQ==} dependencies: '@types/react': 18.2.31 - dev: true /@types/react@18.2.31: resolution: {integrity: sha512-c2UnPv548q+5DFh03y8lEDeMfDwBn9G3dRwfkrxQMo/dOtRHUUO57k6pHvBIfH/VF4Nh+98mZ5aaSe+2echD5g==} @@ -4709,7 +5121,6 @@ packages: /any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} - dev: true /anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} @@ -4717,7 +5128,6 @@ packages: dependencies: normalize-path: 3.0.0 picomatch: 2.3.1 - dev: true /app-root-path@3.1.0: resolution: {integrity: sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==} @@ -4748,7 +5158,6 @@ packages: /arg@5.0.2: resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} - dev: true /argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} @@ -4771,7 +5180,7 @@ packages: resolution: {integrity: sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==} engines: {node: '>=6.0'} dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.8 '@babel/runtime-corejs3': 7.23.2 dev: true @@ -5082,7 +5491,7 @@ packages: resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} engines: {node: '>=10', npm: '>=6'} dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.8 cosmiconfig: 7.1.0 resolve: 1.22.8 dev: false @@ -5268,7 +5677,6 @@ packages: /binary-extensions@2.2.0: resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} engines: {node: '>=8'} - dev: true /bind-decorator@1.0.11: resolution: {integrity: sha512-yzkH0uog6Vv/vQ9+rhSKxecnqGUZHYncg7qS7voz3Q76+TAi1SGiOKk2mlOvusQnFz9Dc4BC/NMkeXu11YgjJg==} @@ -5391,7 +5799,6 @@ packages: engines: {node: '>=8'} dependencies: fill-range: 7.0.1 - dev: true /brorand@1.1.0: resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} @@ -5546,7 +5953,6 @@ packages: /camelcase-css@2.0.1: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} - dev: true /camelcase@5.3.1: resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} @@ -5652,7 +6058,6 @@ packages: readdirp: 3.6.0 optionalDependencies: fsevents: 2.3.3 - dev: true /chrome-trace-event@1.0.3: resolution: {integrity: sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==} @@ -5691,6 +6096,12 @@ packages: resolution: {integrity: sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==} dev: true + /class-variance-authority@0.7.0: + resolution: {integrity: sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==} + dependencies: + clsx: 2.0.0 + dev: false + /clean-css@4.2.4: resolution: {integrity: sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==} engines: {node: '>= 4.0'} @@ -5790,6 +6201,16 @@ packages: resolution: {integrity: sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==} engines: {node: '>=6'} + /clsx@2.0.0: + resolution: {integrity: sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==} + engines: {node: '>=6'} + dev: false + + /clsx@2.1.0: + resolution: {integrity: sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==} + engines: {node: '>=6'} + dev: false + /co@4.6.0: resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} @@ -5830,10 +6251,6 @@ packages: color-string: 1.9.1 dev: false - /colord@2.9.3: - resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} - dev: true - /colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} dev: true @@ -5860,7 +6277,6 @@ packages: /commander@4.1.1: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} - dev: true /commander@6.2.1: resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} @@ -6087,13 +6503,6 @@ packages: nth-check: 2.1.1 dev: true - /css-selector-tokenizer@0.8.0: - resolution: {integrity: sha512-Jd6Ig3/pe62/qe5SBPTN8h8LeUg/pT4lLgtavPf7updwwHpvFzxvOQBHYj2LZDMjUnBzgvIUSjRcf6oT5HzHFg==} - dependencies: - cssesc: 3.0.0 - fastparse: 1.1.2 - dev: true - /css-to-react-native@3.2.0: resolution: {integrity: sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==} dependencies: @@ -6111,7 +6520,6 @@ packages: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} hasBin: true - dev: true /csstype@3.0.9: resolution: {integrity: sha512-rpw6JPxK6Rfg1zLOYCSwle2GFOOsnjmDYDaBwEcwoOg4qlsIVCN789VkBZDJAGi4T07gI4YSutR43t9Zz4Lzuw==} @@ -6175,19 +6583,6 @@ packages: yauzl: 2.10.0 dev: true - /daisyui@3.8.2: - resolution: {integrity: sha512-Dxq4AzYPfUOhrqqs1wdKLE4GUVGc3mJf8asdY7AHoI5QVBgqItU3fsd1idpHDnOJNdaTHmZGo0jvQtXr5IOejw==} - engines: {node: '>=16.9.0'} - dependencies: - colord: 2.9.3 - css-selector-tokenizer: 0.8.0 - postcss: 8.4.31 - postcss-js: 4.0.1(postcss@8.4.31) - tailwindcss: 3.3.3 - transitivePeerDependencies: - - ts-node - dev: true - /damerau-levenshtein@1.0.8: resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} dev: true @@ -6479,7 +6874,6 @@ packages: /didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} - dev: true /diff-match-patch@1.0.5: resolution: {integrity: sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==} @@ -6502,7 +6896,6 @@ packages: /dlv@1.1.3: resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} - dev: true /dns-equal@1.0.0: resolution: {integrity: sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==} @@ -6582,7 +6975,7 @@ packages: resolution: {integrity: sha512-/Tezlx6xpDqR6zKg1V4vLCeQtHWiELhWoBz5A/E0+A1lXN9iIkNbbfc4THSymS0LQUo8F1PMiIwVG8ai/HrnSA==} engines: {node: '>= 8.3.0'} dependencies: - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) is-string-and-not-blank: 0.0.2 transitivePeerDependencies: - supports-color @@ -7029,7 +7422,7 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.8 aria-query: 5.3.0 array-includes: 3.1.7 array.prototype.flatmap: 1.3.2 @@ -7495,7 +7888,6 @@ packages: glob-parent: 5.1.2 merge2: 1.4.1 micromatch: 4.0.5 - dev: true /fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} @@ -7518,15 +7910,10 @@ packages: resolution: {integrity: sha512-r5ZDbgImvVWCP0lA/cGNgQcZqR+aYdFx3u+CtJqUE510pBUVGMn4ulL/iRTI4tACTYsNJ736uzFxEBXesPAktA==} dev: false - /fastparse@1.1.2: - resolution: {integrity: sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==} - dev: true - /fastq@1.15.0: resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} dependencies: reusify: 1.0.4 - dev: true /faye-websocket@0.11.4: resolution: {integrity: sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==} @@ -7639,7 +8026,6 @@ packages: engines: {node: '>=8'} dependencies: to-regex-range: 5.0.1 - dev: true /filter-obj@1.1.0: resolution: {integrity: sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==} @@ -7738,7 +8124,7 @@ packages: debug: optional: true dependencies: - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) dev: true /for-each@0.3.3: @@ -7870,7 +8256,6 @@ packages: /fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - dev: true /fsevents@2.3.2: resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} @@ -7885,7 +8270,6 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] requiresBuild: true - dev: true optional: true /function-bind@1.1.2: @@ -8013,14 +8397,12 @@ packages: engines: {node: '>= 6'} dependencies: is-glob: 4.0.3 - dev: true /glob-parent@6.0.2: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} dependencies: is-glob: 4.0.3 - dev: true /glob-to-regexp@0.4.1: resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} @@ -8034,7 +8416,6 @@ packages: minimatch: 3.1.2 once: 1.4.0 path-is-absolute: 1.0.1 - dev: true /glob@7.1.7: resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==} @@ -8514,7 +8895,6 @@ packages: dependencies: once: 1.4.0 wrappy: 1.0.2 - dev: true /inherits@2.0.3: resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} @@ -8601,7 +8981,6 @@ packages: engines: {node: '>=8'} dependencies: binary-extensions: 2.2.0 - dev: true /is-boolean-object@1.1.2: resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} @@ -8643,7 +9022,6 @@ packages: /is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} - dev: true /is-finalizationregistry@1.0.2: resolution: {integrity: sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==} @@ -8671,7 +9049,6 @@ packages: engines: {node: '>=0.10.0'} dependencies: is-extglob: 2.1.1 - dev: true /is-installed-globally@0.4.0: resolution: {integrity: sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==} @@ -8709,7 +9086,6 @@ packages: /is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} - dev: true /is-object@1.0.2: resolution: {integrity: sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==} @@ -8971,7 +9347,7 @@ packages: resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} engines: {node: '>=10'} dependencies: - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) istanbul-lib-coverage: 3.2.0 source-map: 0.6.1 transitivePeerDependencies: @@ -9462,7 +9838,6 @@ packages: /jiti@1.20.0: resolution: {integrity: sha512-3TV69ZbrvV6U5DfQimop50jE9Dl6J8O1ja1dvBbMba/sZ3YBEQqJ2VZRoQPVnhlzjNtU1vaXRZVrVjU4qtm8yA==} hasBin: true - dev: true /joi@17.11.0: resolution: {integrity: sha512-NgB+lZLNoqISVy1rZocE9PZI36bL/77ie924Ri43yEvi9GUUMPeyVIr8KdFTMUlby1p0PBYMk9spIxEUQYqrJQ==} @@ -9738,7 +10113,6 @@ packages: /lilconfig@2.1.0: resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} engines: {node: '>=10'} - dev: true /lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} @@ -9939,6 +10313,14 @@ packages: dependencies: yallist: 4.0.0 + /lucide-react@0.309.0(react@18.2.0): + resolution: {integrity: sha512-zNVPczuwFrCfksZH3zbd1UDE6/WYhYAdbe2k7CImVyPAkXLgIwbs6eXQ4loigqDnUFjyFYCI5jZ1y10Kqal0dg==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 + dependencies: + react: 18.2.0 + dev: false + /lz-string@1.5.0: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true @@ -10002,7 +10384,6 @@ packages: /merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - dev: true /methods@1.1.2: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} @@ -10015,7 +10396,6 @@ packages: dependencies: braces: 3.0.2 picomatch: 2.3.1 - dev: true /mime-db@1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} @@ -10109,7 +10489,6 @@ packages: any-promise: 1.3.0 object-assign: 4.1.1 thenify-all: 1.6.0 - dev: true /nanoassert@2.0.0: resolution: {integrity: sha512-7vO7n28+aYO4J+8w96AzhmU8G+Y/xpPDJz/se19ICsqj/momRbb9mh9ZUtkoJ5X3nTnPdhEJyc0qnM6yAsHBaA==} @@ -10243,7 +10622,6 @@ packages: /normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} - dev: true /normalize-range@0.1.2: resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} @@ -10318,12 +10696,10 @@ packages: /object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} - dev: true /object-hash@3.0.0: resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} engines: {node: '>= 6'} - dev: true /object-inspect@1.13.1: resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} @@ -10663,7 +11039,6 @@ packages: /path-is-absolute@1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} - dev: true /path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} @@ -10708,7 +11083,6 @@ packages: /pify@2.3.0: resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} engines: {node: '>=0.10.0'} - dev: true /pify@3.0.0: resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} @@ -10763,7 +11137,6 @@ packages: /pirates@4.0.6: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} - dev: true /pkg-dir@4.2.0: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} @@ -10823,7 +11196,6 @@ packages: postcss-value-parser: 4.2.0 read-cache: 1.0.0 resolve: 1.22.8 - dev: true /postcss-js@4.0.1(postcss@8.4.31): resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} @@ -10833,7 +11205,6 @@ packages: dependencies: camelcase-css: 2.0.1 postcss: 8.4.31 - dev: true /postcss-load-config@4.0.1(postcss@8.4.31): resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==} @@ -10850,7 +11221,6 @@ packages: lilconfig: 2.1.0 postcss: 8.4.31 yaml: 2.3.3 - dev: true /postcss-nested@6.0.1(postcss@8.4.31): resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==} @@ -10860,7 +11230,6 @@ packages: dependencies: postcss: 8.4.31 postcss-selector-parser: 6.0.13 - dev: true /postcss-selector-parser@6.0.13: resolution: {integrity: sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==} @@ -10868,7 +11237,6 @@ packages: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 - dev: true /postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} @@ -11103,7 +11471,6 @@ packages: /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - dev: true /quick-format-unescaped@4.0.4: resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} @@ -11140,7 +11507,7 @@ packages: /react-base16-styling@0.9.1: resolution: {integrity: sha512-1s0CY1zRBOQ5M3T61wetEpvQmsYSNtWEcdYzyZNxKa8t7oDvaOn9d21xrGezGAHFWLM7SHcktPuPTrvoqxSfKw==} dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.8 '@types/base16': 1.0.4 '@types/lodash': 4.14.200 base16: 1.0.0 @@ -11163,7 +11530,7 @@ packages: peerDependencies: react: '>=16.13.1' dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.8 react: 18.2.0 dev: false @@ -11191,7 +11558,7 @@ packages: '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 react: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.8 '@types/lodash': 4.14.200 '@types/react': 18.2.31 react: 18.2.0 @@ -11214,6 +11581,25 @@ packages: tslib: 2.6.2 dev: false + /react-remove-scroll@2.5.5(@types/react@18.2.31)(react@18.2.0): + resolution: {integrity: sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.31 + react: 18.2.0 + react-remove-scroll-bar: 2.3.4(@types/react@18.2.31)(react@18.2.0) + react-style-singleton: 2.2.1(@types/react@18.2.31)(react@18.2.0) + tslib: 2.6.2 + use-callback-ref: 1.3.0(@types/react@18.2.31)(react@18.2.0) + use-sidecar: 1.1.2(@types/react@18.2.31)(react@18.2.0) + dev: false + /react-remove-scroll@2.5.7(@types/react@18.2.31)(react@18.2.0): resolution: {integrity: sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==} engines: {node: '>=10'} @@ -11266,7 +11652,7 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.8 react: 18.2.0 use-composed-ref: 1.3.0(react@18.2.0) use-latest: 1.2.1(@types/react@18.2.31)(react@18.2.0) @@ -11305,7 +11691,6 @@ packages: resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} dependencies: pify: 2.3.0 - dev: true /readable-stream@2.3.8: resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} @@ -11332,7 +11717,6 @@ packages: engines: {node: '>=8.10.0'} dependencies: picomatch: 2.3.1 - dev: true /real-require@0.1.0: resolution: {integrity: sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==} @@ -11341,7 +11725,7 @@ packages: /redux@4.2.1: resolution: {integrity: sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==} dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.8 dev: false /reflect.getprototypeof@1.0.4: @@ -11377,7 +11761,7 @@ packages: /regenerator-transform@0.15.2: resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.8 dev: true /regexp.prototype.flags@1.5.1: @@ -11538,7 +11922,6 @@ packages: /reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - dev: true /rfdc@1.3.0: resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==} @@ -11554,7 +11937,7 @@ packages: /rpc-websockets@7.6.1: resolution: {integrity: sha512-MmRGaJJvxTHSRxYPjJJqcj2zWnCetw7YbYbKlD0Yc7qVw6PsZhRJg1MI3mpWlpBs+4zO+urlNfLl9zLsdOD/gA==} dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.8 eventemitter3: 4.0.7 uuid: 8.3.2 ws: 8.14.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) @@ -11566,7 +11949,6 @@ packages: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} dependencies: queue-microtask: 1.2.3 - dev: true /rxjs@6.6.7: resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==} @@ -11985,7 +12367,7 @@ packages: /spdy-transport@3.0.0: resolution: {integrity: sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==} dependencies: - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) detect-node: 2.1.0 hpack.js: 2.1.6 obuf: 1.1.2 @@ -11999,7 +12381,7 @@ packages: resolution: {integrity: sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==} engines: {node: '>=6.0.0'} dependencies: - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) handle-thing: 2.0.1 http-deceiver: 1.2.7 select-hose: 2.0.0 @@ -12296,7 +12678,6 @@ packages: mz: 2.7.0 pirates: 4.0.6 ts-interface-checker: 0.1.13 - dev: true /superstruct@0.14.2: resolution: {integrity: sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==} @@ -12343,6 +12724,20 @@ packages: strip-ansi: 6.0.1 dev: true + /tailwind-merge@2.2.0: + resolution: {integrity: sha512-SqqhhaL0T06SW59+JVNfAqKdqLs0497esifRrZ7jOaefP3o64fdFNDMrAQWZFMxTLJPiHVjRLUywT8uFz1xNWQ==} + dependencies: + '@babel/runtime': 7.23.8 + dev: false + + /tailwindcss-animate@1.0.7(tailwindcss@3.3.3): + resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders' + dependencies: + tailwindcss: 3.3.3 + dev: false + /tailwindcss@3.3.3: resolution: {integrity: sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==} engines: {node: '>=14.0.0'} @@ -12372,7 +12767,6 @@ packages: sucrase: 3.34.0 transitivePeerDependencies: - ts-node - dev: true /tapable@1.1.3: resolution: {integrity: sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==} @@ -12463,13 +12857,11 @@ packages: engines: {node: '>=0.8'} dependencies: thenify: 3.3.1 - dev: true /thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} dependencies: any-promise: 1.3.0 - dev: true /thread-stream@0.15.2: resolution: {integrity: sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA==} @@ -12521,7 +12913,6 @@ packages: engines: {node: '>=8.0'} dependencies: is-number: 7.0.0 - dev: true /toggle-selection@1.0.6: resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==} @@ -12566,7 +12957,6 @@ packages: /ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - dev: true /tsconfig-paths@3.14.2: resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==} @@ -13454,7 +13844,6 @@ packages: /yaml@2.3.3: resolution: {integrity: sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==} engines: {node: '>= 14'} - dev: true /yargs-parser@18.1.3: resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} From a409a0ad2491e932883058bc14e89ec8ce38a7e6 Mon Sep 17 00:00:00 2001 From: Aritra Chatterjee Date: Wed, 17 Jan 2024 00:06:37 +0530 Subject: [PATCH 03/34] add new font --- packages/webapp/public/font/BluuNext-Bold.otf | Bin 0 -> 33796 bytes packages/webapp/tailwind.config.cjs | 85 ++++++++++++++++-- 2 files changed, 76 insertions(+), 9 deletions(-) create mode 100644 packages/webapp/public/font/BluuNext-Bold.otf diff --git a/packages/webapp/public/font/BluuNext-Bold.otf b/packages/webapp/public/font/BluuNext-Bold.otf new file mode 100644 index 0000000000000000000000000000000000000000..36e6187d5e7c1f0eb97bfe9e0a43e709206509e8 GIT binary patch literal 33796 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 Date: Wed, 17 Jan 2024 00:07:01 +0530 Subject: [PATCH 04/34] add new spinner svg for loading state modals --- packages/webapp/public/img/spinner.svg | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 packages/webapp/public/img/spinner.svg diff --git a/packages/webapp/public/img/spinner.svg b/packages/webapp/public/img/spinner.svg new file mode 100644 index 00000000..604b2041 --- /dev/null +++ b/packages/webapp/public/img/spinner.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file From 632a45dc7e2e2eaab3129acd2e3ae3151e7e0c3e Mon Sep 17 00:00:00 2001 From: Aritra Chatterjee Date: Wed, 17 Jan 2024 00:07:43 +0530 Subject: [PATCH 05/34] shadcn component scripts + util func for classname merges --- packages/webapp/src/components/ui/button.tsx | 56 ++++++++ packages/webapp/src/components/ui/dialog.tsx | 122 +++++++++++++++++ packages/webapp/src/components/ui/input.tsx | 25 ++++ .../src/components/ui/navigation-menu.tsx | 128 ++++++++++++++++++ packages/webapp/src/utils/ui-utils.ts | 6 + 5 files changed, 337 insertions(+) create mode 100644 packages/webapp/src/components/ui/button.tsx create mode 100644 packages/webapp/src/components/ui/dialog.tsx create mode 100644 packages/webapp/src/components/ui/input.tsx create mode 100644 packages/webapp/src/components/ui/navigation-menu.tsx create mode 100644 packages/webapp/src/utils/ui-utils.ts diff --git a/packages/webapp/src/components/ui/button.tsx b/packages/webapp/src/components/ui/button.tsx new file mode 100644 index 00000000..a269a516 --- /dev/null +++ b/packages/webapp/src/components/ui/button.tsx @@ -0,0 +1,56 @@ +import * as React from "react" +import { Slot } from "@radix-ui/react-slot" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "../../utils/ui-utils" + +const buttonVariants = cva( + "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", + { + variants: { + variant: { + default: "bg-primary text-primary-foreground hover:bg-primary/90", + destructive: + "bg-destructive text-destructive-foreground hover:bg-destructive/90", + outline: + "border border-input bg-background hover:bg-accent hover:text-accent-foreground", + secondary: + "bg-secondary text-secondary-foreground hover:bg-secondary/80", + ghost: "hover:bg-accent hover:text-accent-foreground", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + default: "h-10 px-4 py-2", + sm: "h-9 rounded-md px-3", + lg: "h-11 rounded-md px-8", + icon: "h-10 w-10", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + } +) + +export interface ButtonProps + extends React.ButtonHTMLAttributes, + VariantProps { + asChild?: boolean +} + +const Button = React.forwardRef( + ({ className, variant, size, asChild = false, ...props }, ref) => { + const Comp = asChild ? Slot : "button" + return ( + + ) + } +) +Button.displayName = "Button" + +export { Button, buttonVariants } diff --git a/packages/webapp/src/components/ui/dialog.tsx b/packages/webapp/src/components/ui/dialog.tsx new file mode 100644 index 00000000..c18b7bbc --- /dev/null +++ b/packages/webapp/src/components/ui/dialog.tsx @@ -0,0 +1,122 @@ +"use client" + +import * as React from "react" +import * as DialogPrimitive from "@radix-ui/react-dialog" +import { X } from "lucide-react" + +import { cn } from "../../utils/ui-utils" + +const Dialog = DialogPrimitive.Root + +const DialogTrigger = DialogPrimitive.Trigger + +const DialogPortal = DialogPrimitive.Portal + +const DialogClose = DialogPrimitive.Close + +const DialogOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DialogOverlay.displayName = DialogPrimitive.Overlay.displayName + +const DialogContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + {children} + + + Close + + + +)) +DialogContent.displayName = DialogPrimitive.Content.displayName + +const DialogHeader = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +DialogHeader.displayName = "DialogHeader" + +const DialogFooter = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +DialogFooter.displayName = "DialogFooter" + +const DialogTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DialogTitle.displayName = DialogPrimitive.Title.displayName + +const DialogDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DialogDescription.displayName = DialogPrimitive.Description.displayName + +export { + Dialog, + DialogPortal, + DialogOverlay, + DialogClose, + DialogTrigger, + DialogContent, + DialogHeader, + DialogFooter, + DialogTitle, + DialogDescription, +} diff --git a/packages/webapp/src/components/ui/input.tsx b/packages/webapp/src/components/ui/input.tsx new file mode 100644 index 00000000..612f9eb2 --- /dev/null +++ b/packages/webapp/src/components/ui/input.tsx @@ -0,0 +1,25 @@ +import * as React from "react" + +import { cn } from "../../utils/ui-utils" + +export interface InputProps + extends React.InputHTMLAttributes {} + +const Input = React.forwardRef( + ({ className, type, ...props }, ref) => { + return ( + + ) + } +) +Input.displayName = "Input" + +export { Input } diff --git a/packages/webapp/src/components/ui/navigation-menu.tsx b/packages/webapp/src/components/ui/navigation-menu.tsx new file mode 100644 index 00000000..4f322964 --- /dev/null +++ b/packages/webapp/src/components/ui/navigation-menu.tsx @@ -0,0 +1,128 @@ +import * as React from "react" +import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu" +import { cva } from "class-variance-authority" +import { ChevronDown } from "lucide-react" + +import { cn } from "../../utils/ui-utils" + +const NavigationMenu = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + {children} + + +)) +NavigationMenu.displayName = NavigationMenuPrimitive.Root.displayName + +const NavigationMenuList = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName + +const NavigationMenuItem = NavigationMenuPrimitive.Item + +const navigationMenuTriggerStyle = cva( + "group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50" +) + +const NavigationMenuTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + {children}{" "} + +)) +NavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger.displayName + +const NavigationMenuContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +NavigationMenuContent.displayName = NavigationMenuPrimitive.Content.displayName + +const NavigationMenuLink = NavigationMenuPrimitive.Link + +const NavigationMenuViewport = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( +
+ +
+)) +NavigationMenuViewport.displayName = + NavigationMenuPrimitive.Viewport.displayName + +const NavigationMenuIndicator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +
+ +)) +NavigationMenuIndicator.displayName = + NavigationMenuPrimitive.Indicator.displayName + +export { + navigationMenuTriggerStyle, + NavigationMenu, + NavigationMenuList, + NavigationMenuItem, + NavigationMenuContent, + NavigationMenuTrigger, + NavigationMenuLink, + NavigationMenuIndicator, + NavigationMenuViewport, +} diff --git a/packages/webapp/src/utils/ui-utils.ts b/packages/webapp/src/utils/ui-utils.ts new file mode 100644 index 00000000..d084ccad --- /dev/null +++ b/packages/webapp/src/utils/ui-utils.ts @@ -0,0 +1,6 @@ +import { type ClassValue, clsx } from "clsx" +import { twMerge } from "tailwind-merge" + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)) +} From 1260dde29e353c6c93e2b7df2a3617de19b23b5e Mon Sep 17 00:00:00 2001 From: Aritra Chatterjee Date: Wed, 17 Jan 2024 00:08:15 +0530 Subject: [PATCH 06/34] recreate `coffee` theme from daisy UI within global styles --- packages/webapp/src/styles/globals.css | 84 +++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 2 deletions(-) diff --git a/packages/webapp/src/styles/globals.css b/packages/webapp/src/styles/globals.css index b2d88e6c..74a98850 100644 --- a/packages/webapp/src/styles/globals.css +++ b/packages/webapp/src/styles/globals.css @@ -6,6 +6,14 @@ body { @apply overflow-y-hidden; } +@font-face { + font-family: "fable"; + src: url("/font/BluuNext-Bold.otf") format("opentype"); + font-weight: normal; + font-style: normal; + font-display: swap; +} + @layer utilities { @layer responsive { /* Hide scrollbar for Chrome, Safari, and Opera */ @@ -13,11 +21,83 @@ body { display: none; } - /* Hide scrollbar for IE, Edge, and Firefox */ .no-scrollbar { -ms-overflow-style: none; /* IE and Edge */ scrollbar-width: none; /* Firefox */ } } -} \ No newline at end of file +} + +@layer base { + :root { + --background: 305 19% 11%; + --foreground: 182 6% 83%; + + --card: 0 0% 100%; + --card-foreground: 0 0% 3.9%; + + --popover: 0 0% 100%; + --popover-foreground: 0 0% 3.9%; + + --primary: 30 67% 51%; + --primary-foreground: 28 35% 13%; + + --secondary: 182 25% 13%; + --secondary-foreground: 182 6% 83%; + + --muted: 0 0% 96.1%; + --muted-foreground: 0 0% 45.1%; + + --accent: 0 0% 96.1%; + --accent-foreground: 0 0% 9%; + + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 0 0% 98%; + + --border: 0 0% 89.8%; + --input: 0 0% 89.8%; + --ring: 0 0% 3.9%; + + --radius: 0.5rem; + } + + .dark { + --background: 0 0% 3.9%; + --foreground: 0 0% 98%; + + --card: 0 0% 3.9%; + --card-foreground: 0 0% 98%; + + --popover: 0 0% 3.9%; + --popover-foreground: 0 0% 98%; + + --primary: 0 0% 98%; + --primary-foreground: 0 0% 9%; + + --secondary: 0 0% 14.9%; + --secondary-foreground: 0 0% 98%; + + --muted: 0 0% 14.9%; + --muted-foreground: 0 0% 63.9%; + + --accent: 0 0% 14.9%; + --accent-foreground: 0 0% 98%; + + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 0 0% 98%; + + --border: 0 0% 14.9%; + --input: 0 0% 14.9%; + --ring: 0 0% 83.1%; + } +} + +@layer base { + * { + @apply border-border; + } + body { + @apply bg-background text-foreground; + } +} From 4f17825df41ae6ac6f273a45bfa687996c914b30 Mon Sep 17 00:00:00 2001 From: Aritra Chatterjee Date: Wed, 17 Jan 2024 00:13:16 +0530 Subject: [PATCH 07/34] redo navbar --- packages/webapp/src/components/navbar.tsx | 56 ++++++++++++++--------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/packages/webapp/src/components/navbar.tsx b/packages/webapp/src/components/navbar.tsx index 7959ae18..2b7fe738 100644 --- a/packages/webapp/src/components/navbar.tsx +++ b/packages/webapp/src/components/navbar.tsx @@ -1,30 +1,44 @@ import Link from "next/link" +import { useRouter } from "next/router" import { ConnectKitButton } from "connectkit" +import { Button } from "./ui/button" +import { + NavigationMenu, + NavigationMenuList, + NavigationMenuItem, +} from "./ui/navigation-menu" export const Navbar = () => { + const router = useRouter() + return ( -
-
- - 0x - FABLE - -
-
-
    -
  • - + + + + + + + + + + + + {router.pathname !== "/collection" && ( + COLLECTION -
  • -
  • - -
  • -
-
-
+ )} + + + + + + ) } From 8e30831dcec214c7faa7892d5fdf1dd2359412fb Mon Sep 17 00:00:00 2001 From: Aritra Chatterjee Date: Wed, 17 Jan 2024 00:16:05 +0530 Subject: [PATCH 08/34] relocate `loadingModal`, update imports --- packages/webapp/src/actions/drawCard.ts | 2 +- packages/webapp/src/actions/joinGame.ts | 2 +- packages/webapp/src/actions/playCard.ts | 2 +- packages/webapp/src/components/hand.tsx | 2 +- .../{lib => modals}/loadingModal.tsx | 79 ++++++++++++------- 5 files changed, 55 insertions(+), 32 deletions(-) rename packages/webapp/src/components/{lib => modals}/loadingModal.tsx (64%) diff --git a/packages/webapp/src/actions/drawCard.ts b/packages/webapp/src/actions/drawCard.ts index 0a87655c..f1bf42b5 100644 --- a/packages/webapp/src/actions/drawCard.ts +++ b/packages/webapp/src/actions/drawCard.ts @@ -25,7 +25,7 @@ import { FAKE_PROOF, proveInWorker, SHOULD_GENERATE_PROOFS } from "src/utils/zkp import { bigintToHexString } from "src/utils/js-utils" import { mimcHash } from "src/utils/hashing" import { DRAW_CARD_PROOF_TIMEOUT } from "src/constants" -import { CancellationHandler } from "src/components/lib/loadingModal" +import { CancellationHandler } from "src/components/modals/loadingModal" import { checkFresh, freshWrap } from "src/store/checkFresh" // ================================================================================================= diff --git a/packages/webapp/src/actions/joinGame.ts b/packages/webapp/src/actions/joinGame.ts index 59928434..13497062 100644 --- a/packages/webapp/src/actions/joinGame.ts +++ b/packages/webapp/src/actions/joinGame.ts @@ -43,7 +43,7 @@ import { import { NUM_CARDS_FOR_PROOF } from "src/game/constants" import { packCards } from "src/game/fableProofs" import { DRAW_HAND_PROOF_TIMEOUT } from "src/constants" -import { CancellationHandler } from "src/components/lib/loadingModal" +import { CancellationHandler } from "src/components/modals/loadingModal" import { checkFresh, freshWrap } from "src/store/checkFresh" import { getPlayerHand } from "src/store/derive" diff --git a/packages/webapp/src/actions/playCard.ts b/packages/webapp/src/actions/playCard.ts index 792e7def..1e0e7f13 100644 --- a/packages/webapp/src/actions/playCard.ts +++ b/packages/webapp/src/actions/playCard.ts @@ -24,7 +24,7 @@ import { FAKE_PROOF, proveInWorker, SHOULD_GENERATE_PROOFS } from "src/utils/zkp import { bigintToHexString } from "src/utils/js-utils" import { mimcHash } from "src/utils/hashing" import { PLAY_CARD_PROOF_TIMEOUT } from "src/constants" -import { CancellationHandler } from "src/components/lib/loadingModal" +import { CancellationHandler } from "src/components/modals/loadingModal" import { checkFresh, freshWrap } from "src/store/checkFresh" // ================================================================================================= diff --git a/packages/webapp/src/components/hand.tsx b/packages/webapp/src/components/hand.tsx index 3b73387e..eaa2dcad 100644 --- a/packages/webapp/src/components/hand.tsx +++ b/packages/webapp/src/components/hand.tsx @@ -9,7 +9,7 @@ import { import { CardPlacement } from "src/store/types" import CardContainer from "./cards/cardContainer" import { convertBigIntArrayToStringArray } from "src/utils/js-utils" -import { CancellationHandler } from "src/components/lib/loadingModal" +import { CancellationHandler } from "src/components/modals/loadingModal" const Hand = ({ cards, diff --git a/packages/webapp/src/components/lib/loadingModal.tsx b/packages/webapp/src/components/modals/loadingModal.tsx similarity index 64% rename from packages/webapp/src/components/lib/loadingModal.tsx rename to packages/webapp/src/components/modals/loadingModal.tsx index 90a13a32..b0a7f615 100644 --- a/packages/webapp/src/components/lib/loadingModal.tsx +++ b/packages/webapp/src/components/modals/loadingModal.tsx @@ -1,7 +1,13 @@ import { ReactNode, useCallback } from "react" -import { ModalTitle, Spinner } from "src/components/lib/modalElements" -import { Modal, ModalController } from "src/components/lib/modal" +import { Spinner } from "src/components/lib/modalElements" +import { + Dialog, + DialogDescription, + DialogTitle, + DialogContent, +} from "../ui/dialog" +import { Button } from "../ui/button" // ================================================================================================= @@ -22,28 +28,27 @@ export class CancellationHandler { /** Deregister a callback. */ deregister = (callback: () => void) => { - this.callbacks = this.callbacks.filter(cb => cb !== callback) + this.callbacks = this.callbacks.filter((cb) => cb !== callback) } /** Call all registered callbacks. */ cancel = () => { - this.callbacks.forEach(cb => cb()) + this.callbacks.forEach((cb) => cb()) } } // ================================================================================================= export type LoadingModalProps = { - ctrl?: ModalController /** Whether the modal can be dismissed via a cancel button. */ cancellable?: boolean /** A string that is displayed as the title of the modal. */ - loading: string|null + loading: string | null /** * A way to change the loading string. It's assumed that when this is set to null, the modal will * be dismissed. */ - setLoading: (_: string|null) => void + setLoading: (_: string | null) => void /** * A cancellation handler that can be used to register callbacks to be called when the modal is * cancelled via its "cancel" button. @@ -59,13 +64,16 @@ export type LoadingModalProps = { * it wraps {@link LoadingModalContent}. * * The display of this modal should be controlled via conditional rendering in the parent component, - * bsed on whether the loading state is populated or not. + * based on whether the loading state is populated or not. */ -export const LoadingModal = (props: LoadingModalProps & { ctrl: ModalController }) => { - - return - - +export const LoadingModal = (props: LoadingModalProps) => { + return ( + + + + + + ) } // ================================================================================================= @@ -77,24 +85,39 @@ export const LoadingModal = (props: LoadingModalProps & { ctrl: ModalController * The display of this content should be controlled via conditional rendering in the parent or * grandparent, depending on whether the loading state is populated or not. */ -export const LoadingModalContent = - ({ cancellable = true, loading, setLoading, cancellationHandler, children }: LoadingModalProps) => { - +export const LoadingModalContent = ({ + cancellable = true, + loading, + setLoading, + cancellationHandler, + children, +}: LoadingModalProps) => { const cancel = useCallback(() => { setLoading(null) cancellationHandler?.cancel() }, [setLoading, cancellationHandler]) - - return <> - {loading} - {children} - - {cancellable &&
- -
} - + console.log("...i", loading) + + return ( + <> + {loading} + + {children} + + {cancellable && ( +
+ +
+ )} +
+ + ) } -// ================================================================================================= \ No newline at end of file +// ================================================================================================= From f85417c90f37dba9f12f729c8ee699465ff58b0a Mon Sep 17 00:00:00 2001 From: Aritra Chatterjee Date: Wed, 17 Jan 2024 00:17:44 +0530 Subject: [PATCH 09/34] redo common modal elements --- .../src/components/lib/modalElements.tsx | 47 ++++++++++++------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/packages/webapp/src/components/lib/modalElements.tsx b/packages/webapp/src/components/lib/modalElements.tsx index 93df4a29..bd05d7fd 100644 --- a/packages/webapp/src/components/lib/modalElements.tsx +++ b/packages/webapp/src/components/lib/modalElements.tsx @@ -1,28 +1,39 @@ // ================================================================================================= - -import { PropsWithChildren } from "react" - -export const ModalTitle = ({ children }: PropsWithChildren) => { - return

{children}

-} - -// ------------------------------------------------------------------------------------------------- +import Image from "next/image" +import { Button } from "src/components/ui/button" export const Spinner = () => { - return
- -
+ return ( +
+ loading +
+ ) } // ------------------------------------------------------------------------------------------------- -export const ModalMenuButton = ({ display, label }: { display: () => void, label: string}) => { - return +export const ModalMenuButton = ({ + display, + label, +}: { + display: () => void + label: string +}) => { + return ( + + ) } -// ================================================================================================= \ No newline at end of file +// ================================================================================================= From a1b5aa4e3d6758e4e130c036c6db9442758b1238 Mon Sep 17 00:00:00 2001 From: Aritra Chatterjee Date: Wed, 17 Jan 2024 00:18:33 +0530 Subject: [PATCH 10/34] preload font into `_app` before render --- packages/webapp/src/pages/_app.tsx | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/packages/webapp/src/pages/_app.tsx b/packages/webapp/src/pages/_app.tsx index 0e1cdde6..896350f6 100644 --- a/packages/webapp/src/pages/_app.tsx +++ b/packages/webapp/src/pages/_app.tsx @@ -36,6 +36,13 @@ const MyApp: AppType = ({ Component, pageProps }) => { 0xFable + @@ -58,7 +65,7 @@ export default MyApp */ const ComponentWrapper = ({ Component, - pageProps + pageProps, }: { Component: ComponentType pageProps: any @@ -86,11 +93,13 @@ const ComponentWrapper = ({ // function from `utils/navigate.ts` instead of `router.push`. } - return <> - - {/* Global error modal for errors that don't have obvious in-flow resolutions. */} - {isHydrated && errorConfig && } - + return ( + <> + + {/* Global error modal for errors that don't have obvious in-flow resolutions. */} + {isHydrated && errorConfig && } + + ) } -// ================================================================================================= \ No newline at end of file +// ================================================================================================= From 470ce60e281d970e4bca9467bd253f7ba40171f4 Mon Sep 17 00:00:00 2001 From: Aritra Chatterjee Date: Wed, 17 Jan 2024 00:31:17 +0530 Subject: [PATCH 11/34] update pages with new components --- .../src/hooks/useCancellationHandler.ts | 2 +- packages/webapp/src/hooks/useDragEvents.ts | 2 +- packages/webapp/src/pages/index.tsx | 83 +++++++------- packages/webapp/src/pages/play.tsx | 102 +++++++++--------- 4 files changed, 101 insertions(+), 88 deletions(-) diff --git a/packages/webapp/src/hooks/useCancellationHandler.ts b/packages/webapp/src/hooks/useCancellationHandler.ts index 2ca760d3..e5daa5ba 100644 --- a/packages/webapp/src/hooks/useCancellationHandler.ts +++ b/packages/webapp/src/hooks/useCancellationHandler.ts @@ -4,7 +4,7 @@ * @module hooks/useCancellationHandler */ -import { CancellationHandler } from "src/components/lib/loadingModal" +import { CancellationHandler } from "src/components/modals/loadingModal" import { useEffect, useRef } from "react" // ================================================================================================= diff --git a/packages/webapp/src/hooks/useDragEvents.ts b/packages/webapp/src/hooks/useDragEvents.ts index 1b6678e1..8157725e 100644 --- a/packages/webapp/src/hooks/useDragEvents.ts +++ b/packages/webapp/src/hooks/useDragEvents.ts @@ -3,7 +3,7 @@ import * as store from "src/store/hooks" import { CardPlacement } from "src/store/types" import { useCallback } from "react" import { extractCardID } from "src/utils/js-utils" -import { CancellationHandler } from "src/components/lib/loadingModal" +import { CancellationHandler } from "src/components/modals/loadingModal" import { playCard } from "src/actions/playCard" function useDragEvents( diff --git a/packages/webapp/src/pages/index.tsx b/packages/webapp/src/pages/index.tsx index c802ffe5..81774740 100644 --- a/packages/webapp/src/pages/index.tsx +++ b/packages/webapp/src/pages/index.tsx @@ -10,12 +10,13 @@ import { MintDeckModal } from "src/components/modals/mintDeckModal" import { useGameInGame } from "src/generated" import { FablePage } from "src/pages/_app" import { useGameID } from "src/store/hooks" +import { Button } from "src/components/ui/button" const Home: FablePage = ({ isHydrated }) => { const { address } = useAccount() const { setOpen } = useModal() const { chain: usedChain } = useNetwork() - const [ _gameID, setGameID ] = useGameID() + const [_gameID, setGameID] = useGameID() // Refresh game ID and put it in the store. // noinspection JSDeprecatedSymbols @@ -23,54 +24,64 @@ const Home: FablePage = ({ isHydrated }) => { address: deployment.Game, args: [address as Address], enabled: !!address, - onSuccess: gameID => { + onSuccess: (gameID) => { // 0 means we're not in a game if (gameID !== 0n) setGameID(gameID) - } + }, }) - const chainSupported = chains.some(chain => chain.id === usedChain?.id) + const chainSupported = chains.some((chain) => chain.id === usedChain?.id) // These three states are mutually exclusive. One of them is always true. const notConnected = !isHydrated || !address const isRightNetwork = !notConnected && chainSupported const isWrongNetwork = !notConnected && !chainSupported - return <> -
-
-

- 0xFABLE -

+ return ( + <> +
+
+

+ 0xFABLE +

- {notConnected && -
- -
- } + {notConnected && ( +
+ +
+ )} - {isWrongNetwork && } + {isWrongNetwork && } - {isRightNetwork && <> -
- - - - - Collection → - -
+ {isRightNetwork && ( + <> +
+ + + + + + +
- - } -
-
- + + + )} +
+
+ + ) } -export default Home \ No newline at end of file +export default Home diff --git a/packages/webapp/src/pages/play.tsx b/packages/webapp/src/pages/play.tsx index 9c2614e5..42e92213 100644 --- a/packages/webapp/src/pages/play.tsx +++ b/packages/webapp/src/pages/play.tsx @@ -1,8 +1,7 @@ import { useCallback, useEffect, useState } from "react" import Hand from "src/components/hand" -import { LoadingModal } from "src/components/lib/loadingModal" -import { useModalController } from "src/components/lib/modal" +import { LoadingModal } from "src/components/modals/loadingModal" import { GameEndedModal } from "src/components/modals/gameEndedModal" import { Navbar } from "src/components/navbar" import * as store from "src/store/hooks" @@ -38,6 +37,7 @@ import PlayerBoard from "src/components/playerBoard" import { createPortal } from "react-dom" import useDragEvents from "src/hooks/useDragEvents" import CardContainer from "src/components/cards/cardContainer" +import { Button } from "src/components/ui/button" const Play: FablePage = ({ isHydrated }) => { const [ gameID, setGameID ] = store.useGameID() @@ -53,8 +53,8 @@ const Play: FablePage = ({ isHydrated }) => { useEffect(visitBoard, [visitBoard, hasVisitedBoard]) const [ loading, setLoading ] = useState(null) - const [ hideResults, setHideResults ] = useState(false) - const [ concedeCompleted, setConcedeCompleted ] = useState(false) + const [ hideResults, setHideResults ] = useState(false) + const [ concedeCompleted, setConcedeCompleted ] = useState(false) const gameData = store.useGameData() const [ activeId, setActiveId ] = useState(null) @@ -100,63 +100,65 @@ const Play: FablePage = ({ isHydrated }) => { if (ended) setLoading(null) }, [ended]) - const missingData = gameID === null|| playerAddress === null || gameData === null + const missingData = gameID === null || playerAddress === null || gameData === null const cantTakeActions = missingData || currentPlayer(gameData) !== playerAddress const cancellationHandler = useCancellationHandler(loading) const cantDrawCard = cantTakeActions || gameData.currentStep !== GameStep.DRAW const doDrawCard = useCallback( () => drawCard({ - gameID: gameID!, - playerAddress: playerAddress!, - setLoading, - cancellationHandler - }), + gameID: gameID!, + playerAddress: playerAddress!, + setLoading, + cancellationHandler + }), [gameID, playerAddress, setLoading, cancellationHandler]) const cantEndTurn = cantTakeActions || !isEndingTurn(gameData.currentStep) const doEndTurn = useCallback( () => endTurn({ - gameID: gameID!, - playerAddress: playerAddress!, - setLoading, - }), + gameID: gameID!, + playerAddress: playerAddress!, + setLoading, + }), [gameID, playerAddress, setLoading]) const cantConcede = missingData const doConcede = useCallback( () => concede({ - gameID: gameID!, - playerAddress: playerAddress!, - setLoading, - onSuccess: () => setConcedeCompleted(true), - }), + gameID: gameID!, + playerAddress: playerAddress!, + setLoading, + onSuccess: () => setConcedeCompleted(true), + }), [gameID, playerAddress]) const doHideResults = useCallback(() => setHideResults(true), [setHideResults]) - const doShowResults = useCallback(() => setHideResults(false), [setHideResults]) + const doShowResults = useCallback(() => setHideResults(false), [setHideResults]) useEffect(() => { if (gameID !== null && playerAddress !== null && !privateInfo) { setError({ title: "Hand information is missing", - message: "Keep playing on the device where you started the game, and do not clear your " - + "browser data while a game is in progress.", + message: + "Keep playing on the device where you started the game, and do not clear your " + + "browser data while a game is in progress.", buttons: [DISMISS_BUTTON, { text: "Concede", onClick: () => { - void doConcede!() - setError(null) - } - }] + void doConcede!() + setError(null) + }, + }, + ], }) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [privateInfo]) - const ctrl = useModalController({ displayed: true, closeable: false }) - // dnd setup - const { - handleDragStart, handleDragEnd, handleDragCancel - } = useDragEvents(setActiveId, setLoading, cancellationHandler) + const { handleDragStart, handleDragEnd, handleDragCancel } = useDragEvents( + setActiveId, + setLoading, + cancellationHandler + ) const sensors = useSensors( // waits for a drag of 20 pixels before the UX assumes a card is being played useSensor(MouseSensor, { activationConstraint: { distance: 20 } }) @@ -183,15 +185,11 @@ const Play: FablePage = ({ isHydrated }) => { modal, which can happen when we learn the game has ended because of a data refresh that precedes the inclusion confirmation. */} {loading && !ended && ( - + )} {gameID === 0n && ( - + )} {ended && !hideResults && ( @@ -215,41 +213,45 @@ const Play: FablePage = ({ isHydrated }) => { {!ended && ( <> - + - + - + )} {/* TODO avoid the bump by grouping buttons in a container that is translated, then no need for the translation here and the important */} {ended && ( <> - + )} @@ -274,4 +276,4 @@ const Play: FablePage = ({ isHydrated }) => { ) } -export default Play \ No newline at end of file +export default Play From 9acbcf9c36c2d24cdec11bbdcec9a520b7a3b14c Mon Sep 17 00:00:00 2001 From: Aritra Chatterjee Date: Wed, 17 Jan 2024 00:32:33 +0530 Subject: [PATCH 12/34] update `MintDeckModal` --- .../src/components/modals/mintDeckModal.tsx | 103 +++++++++++------- 1 file changed, 66 insertions(+), 37 deletions(-) diff --git a/packages/webapp/src/components/modals/mintDeckModal.tsx b/packages/webapp/src/components/modals/mintDeckModal.tsx index fa1fbf9a..ddd60395 100644 --- a/packages/webapp/src/components/modals/mintDeckModal.tsx +++ b/packages/webapp/src/components/modals/mintDeckModal.tsx @@ -1,64 +1,93 @@ import { useState } from "react" -import { ModalMenuButton, ModalTitle } from "src/components/lib/modalElements" import { useDeckAirdropWrite } from "src/hooks/useFableWrite" -import { Modal, ModalController, useModalController } from "src/components/lib/modal" -import { LoadingModalContent } from "src/components/lib/loadingModal" +import { LoadingModalContent } from "src/components/modals/loadingModal" +import { + Dialog, + DialogContent, + DialogDescription, + DialogTitle, + DialogTrigger, +} from "../ui/dialog" +import { Button } from "../ui/button" // ================================================================================================= export const MintDeckModal = ({ callback = () => {} }) => { - const ctrl = useModalController({ loaded: false }) - - return <> - - - - - + return ( + + + + + + + + + ) } // ================================================================================================= -const MintDeckModalContent = ({ ctrl, callback }: { ctrl: ModalController, callback: () => void}) => { - const [ loading, setLoading ] = useState(null) - const [ success, setSuccess ] = useState(false) +const MintDeckModalContent = ({ callback }: { callback: () => void }) => { + const [loading, setLoading] = useState(null) + const [success, setSuccess] = useState(false) const { write: claim } = useDeckAirdropWrite({ functionName: "claimAirdrop", enabled: true, setLoading, onSuccess() { - ctrl.display() callback?.() setSuccess(true) - } + }, }) // ----------------------------------------------------------------------------------------------- - if (loading) return + if (loading) + return - return <> - {!success && <> - Minting Deck... -

- Mint a deck of cards to play the game with your friends. -

-
- -
- } - {success && <> - Deck Minted Successfully -

- Go enjoy the game! -

- } - + return ( + <> + {!success && ( + <> + + Minting Deck... + + +

+ Mint a deck of cards to play the game with your friends. +

+
+ +
+
+ + )} + {success && ( + <> + + Deck Minted Successfully + + +

Go enjoy the game!

+
+ + )} + + ) } // ================================================================================================= - From 5b66baf623ae6b9af21560383d089a9a25efbc39 Mon Sep 17 00:00:00 2001 From: Aritra Chatterjee Date: Wed, 17 Jan 2024 00:33:45 +0530 Subject: [PATCH 13/34] update modals with `Dialog` component --- .../src/components/modals/gameEndedModal.tsx | 57 ++++++++++++------- .../components/modals/globalErrorModal.tsx | 41 +++++++------ .../modals/inGameMenuModalContent.tsx | 44 +++++++++----- 3 files changed, 92 insertions(+), 50 deletions(-) diff --git a/packages/webapp/src/components/modals/gameEndedModal.tsx b/packages/webapp/src/components/modals/gameEndedModal.tsx index cbb6c53a..969f18bb 100644 --- a/packages/webapp/src/components/modals/gameEndedModal.tsx +++ b/packages/webapp/src/components/modals/gameEndedModal.tsx @@ -1,21 +1,30 @@ import { useRouter } from "next/router" -import { useCallback } from "react" +import { useCallback, useState } from "react" -import { ModalTitle } from "src/components/lib/modalElements" import { useGameData, useGameID } from "src/store/hooks" -import { Modal, useModalController } from "src/components/lib/modal" import { navigate } from "src/utils/navigate" +import { + Dialog, + DialogDescription, + DialogTitle, + DialogContent, +} from "../ui/dialog" +import { Button } from "../ui/button" /** * This modal is displayed in the "/play" page, when the game ends. It can be dismissed if the * player wishes to view the final state of the game board, after which he can still go back * to the menu through a button on the game board. */ -export const GameEndedModal = ({ closeCallback }: { closeCallback: () => void }) => { - const ctrl = useModalController({ displayed: true, closeable: false }) +export const GameEndedModal = ({ + closeCallback, +}: { + closeCallback: () => void +}) => { const router = useRouter() const [ , setGameID ] = useGameID() const gameData = useGameData() + const [open, isOpen] = useState(true) const exitToMenu = useCallback(() => { setGameID(null) @@ -23,20 +32,28 @@ export const GameEndedModal = ({ closeCallback }: { closeCallback: () => void }) }, [router, setGameID]) const viewGame = useCallback(() => { - ctrl.close() + isOpen(false) closeCallback() - }, [closeCallback, ctrl]) + }, [closeCallback]) - return - Game Ended -

Winner: {gameData?.players[gameData.livePlayers[0]]}

-
- - -
-
-} \ No newline at end of file + return ( + + + Game Ended + +

+ Winner: {gameData?.players[gameData.livePlayers[0]]} +

+
+ + +
+
+
+
+ ) +} diff --git a/packages/webapp/src/components/modals/globalErrorModal.tsx b/packages/webapp/src/components/modals/globalErrorModal.tsx index 5942a51c..e5cc2a00 100644 --- a/packages/webapp/src/components/modals/globalErrorModal.tsx +++ b/packages/webapp/src/components/modals/globalErrorModal.tsx @@ -1,28 +1,37 @@ -import { ModalTitle } from "src/components/lib/modalElements" -import { Modal, useModalController } from "src/components/lib/modal" import { ErrorConfig } from "src/store/types" +import { + Dialog, + DialogContent, + DialogTitle, +} from "../ui/dialog" +import { Button } from "../ui/button" + /** * A modal displayed globally (setup in _app.tsx) whenever the errorConfig state is set to non-null. * This modal can be dismissed by setting the errorConfig state to null. */ export const GlobalErrorModal = ({ config }: { config: ErrorConfig }) => { - const ctrl = useModalController({ displayed: true, closeable: false, displayedOnError: true }) - // Maybe in the future we might want to store the error somewhere and make it surfaceable in the // UI. This is good practice as it lets the user figure out what happened. Really not a priority // at the moment, and the error should be systematically logged to the console instead, for // debugging purposes. - return - {config.title} - {config.message !== "" &&

{config.message}

} -
- {config.buttons.map((button, i) => - - )} -
-
-} \ No newline at end of file + return ( + + {config.title} + + {config.message !== "" && ( +

{config.message}

+ )} +
+ {config.buttons.map((button, i) => ( + + ))} +
+
+
+ ) +} diff --git a/packages/webapp/src/components/modals/inGameMenuModalContent.tsx b/packages/webapp/src/components/modals/inGameMenuModalContent.tsx index 740a57d1..df1115f9 100644 --- a/packages/webapp/src/components/modals/inGameMenuModalContent.tsx +++ b/packages/webapp/src/components/modals/inGameMenuModalContent.tsx @@ -1,6 +1,7 @@ import Link from "next/link" -import { ModalTitle } from "src/components/lib/modalElements" +import { DialogDescription, DialogTitle } from "../ui/dialog" +import { Button } from "../ui/button" /** * This modal content is shared by both the {@link CreateGameModal} (for the game creator) and the @@ -9,16 +10,31 @@ import { ModalTitle } from "src/components/lib/modalElements" * * @param {{concede}} concede - The function to call to concede the game. */ -export const InGameMenuModalContent = ({ concede }: { concede?: () => void }) => { - return <> - Game in progress! -
- - Return to Game - - -
- -} \ No newline at end of file +export const InGameMenuModalContent = ({ + concede, +}: { + concede?: () => void +}) => { + return ( + <> + Game in progress! + +
+ + + + +
+
+ + ) +} From 5b657ce0d46d3ba8de668f7ed99e88e69aac84e6 Mon Sep 17 00:00:00 2001 From: Aritra Chatterjee Date: Wed, 17 Jan 2024 00:56:25 +0530 Subject: [PATCH 14/34] update navbar style --- packages/webapp/src/components/navbar.tsx | 20 +++++++++---------- .../src/components/ui/navigation-menu.tsx | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/webapp/src/components/navbar.tsx b/packages/webapp/src/components/navbar.tsx index 2b7fe738..7a763e8e 100644 --- a/packages/webapp/src/components/navbar.tsx +++ b/packages/webapp/src/components/navbar.tsx @@ -1,5 +1,4 @@ import Link from "next/link" -import { useRouter } from "next/router" import { ConnectKitButton } from "connectkit" import { Button } from "./ui/button" import { @@ -9,10 +8,8 @@ import { } from "./ui/navigation-menu" export const Navbar = () => { - const router = useRouter() - return ( - + @@ -27,13 +24,16 @@ export const Navbar = () => { - + - {router.pathname !== "/collection" && ( - - COLLECTION - - )} + + + diff --git a/packages/webapp/src/components/ui/navigation-menu.tsx b/packages/webapp/src/components/ui/navigation-menu.tsx index 4f322964..b145e13d 100644 --- a/packages/webapp/src/components/ui/navigation-menu.tsx +++ b/packages/webapp/src/components/ui/navigation-menu.tsx @@ -12,7 +12,7 @@ const NavigationMenu = React.forwardRef< Date: Wed, 17 Jan 2024 00:57:43 +0530 Subject: [PATCH 15/34] refactor `JoinGameModal` --- .../src/components/modals/joinGameModal.tsx | 118 +++++++++++------- 1 file changed, 70 insertions(+), 48 deletions(-) diff --git a/packages/webapp/src/components/modals/joinGameModal.tsx b/packages/webapp/src/components/modals/joinGameModal.tsx index 24080c48..ff855778 100644 --- a/packages/webapp/src/components/modals/joinGameModal.tsx +++ b/packages/webapp/src/components/modals/joinGameModal.tsx @@ -1,13 +1,12 @@ import debounce from "lodash/debounce" import { useRouter } from "next/router" import React, { useEffect, useMemo, useState } from "react" -import { ModalMenuButton, ModalTitle, Spinner } from "src/components/lib/modalElements" +import { Spinner } from "src/components/lib/modalElements" import { InGameMenuModalContent } from "src/components/modals/inGameMenuModalContent" import * as store from "src/store/hooks" import { isStringPositiveInteger, parseBigIntOrNull } from "src/utils/js-utils" -import { Modal, ModalController, useModalController } from "src/components/lib/modal" -import { LoadingModalContent } from "src/components/lib/loadingModal" +import { LoadingModalContent } from "src/components/modals/loadingModal" import { joinGame, reportInconsistentGameState } from "src/actions" import { setError } from "src/store/write" import { GameStatus } from "src/store/types" @@ -15,30 +14,41 @@ import { navigate } from "src/utils/navigate" import { useCancellationHandler } from "src/hooks/useCancellationHandler" import { concede } from "src/actions/concede" +import { + Dialog, + DialogContent, + DialogDescription, + DialogTitle, + DialogTrigger, +} from "../ui/dialog" +import { Button } from "../ui/button" +import { Input } from "../ui/input" + // ================================================================================================= export const JoinGameModal = () => { const isGameJoiner = store.useIsGameJoiner() - const ctrl = useModalController({ loaded: isGameJoiner }) - useEffect(() => { - // If we're on the home page and we have joined a game we didn't create, this modal - // should be displayed. - if (isGameJoiner && !ctrl.displayed) - ctrl.display() - }, [isGameJoiner, ctrl, ctrl.displayed]) - - return <> - - - - - + return ( + + + + + + + + + ) } // ================================================================================================= -const JoinGameModalContent = ({ ctrl }: { ctrl: ModalController }) => { +const JoinGameModalContent = () => { const [ gameID, setGameID ] = store.useGameID() const playerAddress = store.usePlayerAddress() const gameStatus = store.useGameStatus() @@ -58,11 +68,6 @@ const JoinGameModalContent = ({ ctrl }: { ctrl: ModalController }) => { void navigate(router, "/play") }, [hasVisitedBoard, router, started]) - // The modal can't be closed in the normal way when in a loading state. - useEffect(() => { - ctrl.closeableAndSurroundCloseable = loading === null - }, [ctrl, loading]) - const cancellationHandler = useCancellationHandler(loading) const join = async () => { @@ -98,7 +103,6 @@ const JoinGameModalContent = ({ ctrl }: { ctrl: ModalController }) => { setLoading, onSuccess: () => { setGameID(null) - ctrl.close() } }) @@ -121,29 +125,47 @@ const JoinGameModalContent = ({ ctrl }: { ctrl: ModalController }) => { if (started) return - return <> - {joined && <> - Waiting for other player... - - } - {!joined && <> - Joining Game... -

Enter the game ID you want to join.

- - - } - + return ( + <> + {joined && ( + <> + + Waiting for other player... + + + + )} + {!joined && ( + <> + + Joining Game... + + +

+ Enter the game ID you want to join. +

+
+ + +
+
+ + )} + + ) } -// ================================================================================================= \ No newline at end of file +// ================================================================================================= From 40bafa2e2af03c9c7f9bf7fd0e4a2b4cc5d020c9 Mon Sep 17 00:00:00 2001 From: Aritra Chatterjee Date: Wed, 17 Jan 2024 01:01:47 +0530 Subject: [PATCH 16/34] add default open state for `JoinGameModal` --- packages/webapp/src/components/modals/joinGameModal.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/webapp/src/components/modals/joinGameModal.tsx b/packages/webapp/src/components/modals/joinGameModal.tsx index ff855778..2002bee8 100644 --- a/packages/webapp/src/components/modals/joinGameModal.tsx +++ b/packages/webapp/src/components/modals/joinGameModal.tsx @@ -30,8 +30,8 @@ export const JoinGameModal = () => { const isGameJoiner = store.useIsGameJoiner() return ( - - + + + + + + + + ) } // ================================================================================================= -const CreateGameModalContent = ({ ctrl }: { ctrl: ModalController }) => { - +const CreateGameModalContent = () => { const playerAddress = store.usePlayerAddress() const [ gameID, setGameID ] = store.useGameID() const gameStatus = store.useGameStatus() @@ -55,16 +62,9 @@ const CreateGameModalContent = ({ ctrl }: { ctrl: ModalController }) => { const joined = gameStatus >= GameStatus.HAND_DRAWN || drawCompleted const started = gameStatus >= GameStatus.STARTED && gameStatus < GameStatus.ENDED - // If the game is created, the modal can't be closed in the normal way, same if loading. - useEffect(() => { - // React forces us to use an effect, can't update a component state in another component. - ctrl.closeableAndSurroundCloseable = !created && loading === null - }, [created, loading, ctrl]) - // Load game board game once the game start, unless we've visited it for this game already. useEffect(() => { - if (!hasVisitedBoard && started) - void navigate(router, "/play") + if (!hasVisitedBoard && started) void navigate(router, "/play") }, [hasVisitedBoard, router, started]) // ----------------------------------------------------------------------------------------------- @@ -121,7 +121,6 @@ const CreateGameModalContent = ({ ctrl }: { ctrl: ModalController }) => { setLoading, onSuccess() { setGameID(null) - ctrl.close() } }) @@ -132,10 +131,9 @@ const CreateGameModalContent = ({ ctrl }: { ctrl: ModalController }) => { setLoading, onSuccess: () => { setGameID(null) - ctrl.close() } }), - [gameID, playerAddress, setGameID, ctrl]) + [gameID, playerAddress, setGameID]) // ----------------------------------------------------------------------------------------------- @@ -146,43 +144,81 @@ const CreateGameModalContent = ({ ctrl }: { ctrl: ModalController }) => { cancellationHandler={cancellationHandler} /> - if (!created) return <> - Create Game -

- Once a game is created, you can invite your friends to join with the game ID. -

-
- -
- - - if (created && !started) return <> - {joined ? "Waiting for other player..." : "Game Created"} -

- Share the following code to invite players to battle: -

-

- {`${gameID}`} -

- {!joined &&
- - -
} - {joined &&
- - {!allPlayersJoined && } -
} - + if (!created) + return ( + <> + Create Game + +

+ Once a game is created, you can invite your friends to join with the + game ID. +

+
+ +
+
+ + ) + + if (created && !started) + return ( + <> + + {joined ? "Waiting for other player..." : "Game Created"} + + +

+ Share the following code to invite players to battle: +

+

+ {`${gameID}`} +

+ {!joined && ( +
+ + +
+ )} + {joined && ( +
+ + {!allPlayersJoined && ( + + )} +
+ )} +
+ + ) if (started) return } -// ================================================================================================= \ No newline at end of file +// ================================================================================================= From 571853d957bbd0596ba1569384e48f00b1776afe Mon Sep 17 00:00:00 2001 From: Aritra Chatterjee Date: Wed, 17 Jan 2024 01:09:43 +0530 Subject: [PATCH 18/34] add missing type --- packages/webapp/src/pages/_app.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/webapp/src/pages/_app.tsx b/packages/webapp/src/pages/_app.tsx index 40569a43..113df2bd 100644 --- a/packages/webapp/src/pages/_app.tsx +++ b/packages/webapp/src/pages/_app.tsx @@ -19,6 +19,7 @@ import { useErrorConfig } from "src/store/hooks" import "src/styles/globals.css" import { useRouter } from "next/router" import { ComponentType, useEffect } from "react" +import { Deck } from "src/store/types" // ================================================================================================= From 9746d73308e9fa16527f9cca8b1d666c49ac52e0 Mon Sep 17 00:00:00 2001 From: Aritra Chatterjee Date: Thu, 18 Jan 2024 15:20:57 +0530 Subject: [PATCH 19/34] remove log statement --- packages/webapp/src/components/modals/loadingModal.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/webapp/src/components/modals/loadingModal.tsx b/packages/webapp/src/components/modals/loadingModal.tsx index b0a7f615..f041c862 100644 --- a/packages/webapp/src/components/modals/loadingModal.tsx +++ b/packages/webapp/src/components/modals/loadingModal.tsx @@ -96,7 +96,6 @@ export const LoadingModalContent = ({ setLoading(null) cancellationHandler?.cancel() }, [setLoading, cancellationHandler]) - console.log("...i", loading) return ( <> From 0a17342c864aee11fc123aaa7af1b42e7977518b Mon Sep 17 00:00:00 2001 From: Aritra Chatterjee Date: Thu, 18 Jan 2024 15:32:46 +0530 Subject: [PATCH 20/34] remove extra parent and parentheses --- packages/webapp/src/pages/index.tsx | 92 ++++++++++++++--------------- 1 file changed, 45 insertions(+), 47 deletions(-) diff --git a/packages/webapp/src/pages/index.tsx b/packages/webapp/src/pages/index.tsx index 331ae55f..6837a9bf 100644 --- a/packages/webapp/src/pages/index.tsx +++ b/packages/webapp/src/pages/index.tsx @@ -38,57 +38,55 @@ const Home: FablePage = ({ isHydrated }) => { const isWrongNetwork = !notConnected && !chainSupported return ( - <> -
-
-

- 0xFABLE -

+
+
+

+ 0xFABLE +

- {notConnected && ( -
- -
- )} + {notConnected && ( +
+ +
+ )} - {isWrongNetwork && } + {isWrongNetwork && } - {isRightNetwork && ( - <> -
- - - - - - - - - -
+ {isRightNetwork && ( + <> +
+ + + + + + + + + +
- - - )} -
-
- + + + )} +
+
) } From 6294819514420394cef3498af09c1d650bd02f1f Mon Sep 17 00:00:00 2001 From: Aritra Chatterjee Date: Thu, 18 Jan 2024 17:20:14 +0530 Subject: [PATCH 21/34] add references for new components --- packages/webapp/src/components/ui/button.tsx | 1 + packages/webapp/src/components/ui/dialog.tsx | 1 + packages/webapp/src/components/ui/input.tsx | 1 + packages/webapp/src/components/ui/navigation-menu.tsx | 1 + 4 files changed, 4 insertions(+) diff --git a/packages/webapp/src/components/ui/button.tsx b/packages/webapp/src/components/ui/button.tsx index a269a516..b52baa62 100644 --- a/packages/webapp/src/components/ui/button.tsx +++ b/packages/webapp/src/components/ui/button.tsx @@ -4,6 +4,7 @@ import { cva, type VariantProps } from "class-variance-authority" import { cn } from "../../utils/ui-utils" +// ref: https://ui.shadcn.com/docs/components/button const buttonVariants = cva( "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", { diff --git a/packages/webapp/src/components/ui/dialog.tsx b/packages/webapp/src/components/ui/dialog.tsx index c18b7bbc..6e5dc7e6 100644 --- a/packages/webapp/src/components/ui/dialog.tsx +++ b/packages/webapp/src/components/ui/dialog.tsx @@ -14,6 +14,7 @@ const DialogPortal = DialogPrimitive.Portal const DialogClose = DialogPrimitive.Close +// ref: https://ui.shadcn.com/docs/components/dialog const DialogOverlay = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef diff --git a/packages/webapp/src/components/ui/input.tsx b/packages/webapp/src/components/ui/input.tsx index 612f9eb2..6f6b1302 100644 --- a/packages/webapp/src/components/ui/input.tsx +++ b/packages/webapp/src/components/ui/input.tsx @@ -5,6 +5,7 @@ import { cn } from "../../utils/ui-utils" export interface InputProps extends React.InputHTMLAttributes {} +// ref: https://ui.shadcn.com/docs/components/input const Input = React.forwardRef( ({ className, type, ...props }, ref) => { return ( diff --git a/packages/webapp/src/components/ui/navigation-menu.tsx b/packages/webapp/src/components/ui/navigation-menu.tsx index b145e13d..b8f2d6d7 100644 --- a/packages/webapp/src/components/ui/navigation-menu.tsx +++ b/packages/webapp/src/components/ui/navigation-menu.tsx @@ -5,6 +5,7 @@ import { ChevronDown } from "lucide-react" import { cn } from "../../utils/ui-utils" +// ref: https://ui.shadcn.com/docs/components/navigation-menu const NavigationMenu = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef From e77c5c0fd03dd538ab151840fd6a609a2a2a6b43 Mon Sep 17 00:00:00 2001 From: Aritra Chatterjee Date: Thu, 18 Jan 2024 17:22:05 +0530 Subject: [PATCH 22/34] added docs ref --- packages/webapp/src/pages/_app.tsx | 4 ++-- packages/webapp/src/styles/globals.css | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/webapp/src/pages/_app.tsx b/packages/webapp/src/pages/_app.tsx index 113df2bd..1204b2d4 100644 --- a/packages/webapp/src/pages/_app.tsx +++ b/packages/webapp/src/pages/_app.tsx @@ -39,8 +39,8 @@ const MyApp: AppType = ({ Component, pageProps }) => { 0xFable Date: Thu, 18 Jan 2024 18:43:17 +0530 Subject: [PATCH 23/34] use absoute imports for ui components --- packages/webapp/src/components/modals/createGameModal.tsx | 4 ++-- packages/webapp/src/components/modals/gameEndedModal.tsx | 4 ++-- packages/webapp/src/components/modals/globalErrorModal.tsx | 2 +- .../webapp/src/components/modals/inGameMenuModalContent.tsx | 2 +- packages/webapp/src/components/modals/joinGameModal.tsx | 4 ++-- packages/webapp/src/components/modals/loadingModal.tsx | 4 ++-- packages/webapp/src/components/modals/mintDeckModal.tsx | 4 ++-- packages/webapp/src/components/navbar.tsx | 2 +- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/webapp/src/components/modals/createGameModal.tsx b/packages/webapp/src/components/modals/createGameModal.tsx index f30470ee..0184ddf9 100644 --- a/packages/webapp/src/components/modals/createGameModal.tsx +++ b/packages/webapp/src/components/modals/createGameModal.tsx @@ -19,8 +19,8 @@ import { DialogDescription, DialogTitle, DialogTrigger, -} from "../ui/dialog" -import { Button } from "../ui/button" +} from "src/components/ui/dialog" +import { Button } from "src/components/ui/button" // ================================================================================================= diff --git a/packages/webapp/src/components/modals/gameEndedModal.tsx b/packages/webapp/src/components/modals/gameEndedModal.tsx index 969f18bb..9a977283 100644 --- a/packages/webapp/src/components/modals/gameEndedModal.tsx +++ b/packages/webapp/src/components/modals/gameEndedModal.tsx @@ -8,8 +8,8 @@ import { DialogDescription, DialogTitle, DialogContent, -} from "../ui/dialog" -import { Button } from "../ui/button" +} from "src/components/ui/dialog" +import { Button } from "src/components/ui/button" /** * This modal is displayed in the "/play" page, when the game ends. It can be dismissed if the diff --git a/packages/webapp/src/components/modals/globalErrorModal.tsx b/packages/webapp/src/components/modals/globalErrorModal.tsx index e5cc2a00..e030fe9a 100644 --- a/packages/webapp/src/components/modals/globalErrorModal.tsx +++ b/packages/webapp/src/components/modals/globalErrorModal.tsx @@ -5,7 +5,7 @@ import { DialogContent, DialogTitle, } from "../ui/dialog" -import { Button } from "../ui/button" +import { Button } from "src/components/ui/button" /** * A modal displayed globally (setup in _app.tsx) whenever the errorConfig state is set to non-null. diff --git a/packages/webapp/src/components/modals/inGameMenuModalContent.tsx b/packages/webapp/src/components/modals/inGameMenuModalContent.tsx index df1115f9..c22c6a05 100644 --- a/packages/webapp/src/components/modals/inGameMenuModalContent.tsx +++ b/packages/webapp/src/components/modals/inGameMenuModalContent.tsx @@ -1,7 +1,7 @@ import Link from "next/link" import { DialogDescription, DialogTitle } from "../ui/dialog" -import { Button } from "../ui/button" +import { Button } from "src/components/ui/button" /** * This modal content is shared by both the {@link CreateGameModal} (for the game creator) and the diff --git a/packages/webapp/src/components/modals/joinGameModal.tsx b/packages/webapp/src/components/modals/joinGameModal.tsx index 2002bee8..eda6314b 100644 --- a/packages/webapp/src/components/modals/joinGameModal.tsx +++ b/packages/webapp/src/components/modals/joinGameModal.tsx @@ -21,8 +21,8 @@ import { DialogTitle, DialogTrigger, } from "../ui/dialog" -import { Button } from "../ui/button" -import { Input } from "../ui/input" +import { Button } from "src/components/ui/button" +import { Input } from "src/components/ui/input" // ================================================================================================= diff --git a/packages/webapp/src/components/modals/loadingModal.tsx b/packages/webapp/src/components/modals/loadingModal.tsx index f041c862..32f2feb9 100644 --- a/packages/webapp/src/components/modals/loadingModal.tsx +++ b/packages/webapp/src/components/modals/loadingModal.tsx @@ -6,8 +6,8 @@ import { DialogDescription, DialogTitle, DialogContent, -} from "../ui/dialog" -import { Button } from "../ui/button" +} from "src/components/ui/dialog" +import { Button } from "src/components/ui/button" // ================================================================================================= diff --git a/packages/webapp/src/components/modals/mintDeckModal.tsx b/packages/webapp/src/components/modals/mintDeckModal.tsx index ddd60395..64685137 100644 --- a/packages/webapp/src/components/modals/mintDeckModal.tsx +++ b/packages/webapp/src/components/modals/mintDeckModal.tsx @@ -8,8 +8,8 @@ import { DialogDescription, DialogTitle, DialogTrigger, -} from "../ui/dialog" -import { Button } from "../ui/button" +} from "src/components/ui/dialog" +import { Button } from "src/components/ui/button" // ================================================================================================= diff --git a/packages/webapp/src/components/navbar.tsx b/packages/webapp/src/components/navbar.tsx index 7a763e8e..42a79811 100644 --- a/packages/webapp/src/components/navbar.tsx +++ b/packages/webapp/src/components/navbar.tsx @@ -5,7 +5,7 @@ import { NavigationMenu, NavigationMenuList, NavigationMenuItem, -} from "./ui/navigation-menu" +} from "src/components/ui/navigation-menu" export const Navbar = () => { return ( From 7bb1ab8e2422fbbd0606b2fd05245df0f88c34a3 Mon Sep 17 00:00:00 2001 From: Aritra Chatterjee Date: Thu, 18 Jan 2024 18:45:01 +0530 Subject: [PATCH 24/34] add docstring for util function --- packages/webapp/src/utils/ui-utils.ts | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/packages/webapp/src/utils/ui-utils.ts b/packages/webapp/src/utils/ui-utils.ts index d084ccad..20d6ed64 100644 --- a/packages/webapp/src/utils/ui-utils.ts +++ b/packages/webapp/src/utils/ui-utils.ts @@ -1,6 +1,26 @@ import { type ClassValue, clsx } from "clsx" import { twMerge } from "tailwind-merge" +/** + * Combines and deduplicates class names using `clsx` and `tailwind-merge`. + * + * This function takes any number of class value inputs, combines them into + * a single string of class names using `clsx`, and then deduplicates + * any Tailwind CSS classes using `tailwind-merge`. This is useful for + * dynamically generating a class string in React components, especially when + * dealing with conditional class names or combining classes from different sources. + * + * @param inputs - An array of class value inputs. Each input can be a string, + * an array, or an object with class names as keys and boolean values as values + * to conditionally include classes. + * + * @returns A string of combined and deduplicated class names. + * + * @example + * cn('text-center', 'py-2', { 'bg-red-500': isError }, ['hover:bg-blue-500']) + * // Returns a string of class names, e.g., 'text-center py-2 bg-red-500 hover:bg-blue-500' + */ export function cn(...inputs: ClassValue[]) { - return twMerge(clsx(inputs)) + return twMerge(clsx(inputs)); } + From 554e92b86c8165c909be354aac0fe307dd0faa2e Mon Sep 17 00:00:00 2001 From: Aritra Chatterjee Date: Thu, 18 Jan 2024 20:20:03 +0530 Subject: [PATCH 25/34] improve code readability --- .../src/components/lib/modalElements.tsx | 6 +--- .../src/components/modals/createGameModal.tsx | 32 +++---------------- .../modals/inGameMenuModalContent.tsx | 7 +--- .../src/components/modals/joinGameModal.tsx | 12 ++----- .../src/components/modals/loadingModal.tsx | 6 +--- .../src/components/modals/mintDeckModal.tsx | 12 ++----- packages/webapp/src/components/navbar.tsx | 10 ++---- packages/webapp/src/pages/index.tsx | 16 ++-------- packages/webapp/src/pages/play.tsx | 24 +++----------- 9 files changed, 21 insertions(+), 104 deletions(-) diff --git a/packages/webapp/src/components/lib/modalElements.tsx b/packages/webapp/src/components/lib/modalElements.tsx index bd05d7fd..4d88a8f1 100644 --- a/packages/webapp/src/components/lib/modalElements.tsx +++ b/packages/webapp/src/components/lib/modalElements.tsx @@ -26,11 +26,7 @@ export const ModalMenuButton = ({ label: string }) => { return ( - ) diff --git a/packages/webapp/src/components/modals/createGameModal.tsx b/packages/webapp/src/components/modals/createGameModal.tsx index 0184ddf9..92f4e7ca 100644 --- a/packages/webapp/src/components/modals/createGameModal.tsx +++ b/packages/webapp/src/components/modals/createGameModal.tsx @@ -31,10 +31,7 @@ export const CreateGameModal = () => { // If we're on the home page and we're the game creator, this modal should be displayed. - @@ -154,12 +151,7 @@ const CreateGameModalContent = () => { game ID.

-
@@ -182,19 +174,10 @@ const CreateGameModalContent = () => {

{!joined && (
- -
@@ -203,12 +186,7 @@ const CreateGameModalContent = () => {
{!allPlayersJoined && ( - )} diff --git a/packages/webapp/src/components/modals/inGameMenuModalContent.tsx b/packages/webapp/src/components/modals/inGameMenuModalContent.tsx index c22c6a05..85e94577 100644 --- a/packages/webapp/src/components/modals/inGameMenuModalContent.tsx +++ b/packages/webapp/src/components/modals/inGameMenuModalContent.tsx @@ -25,12 +25,7 @@ export const InGameMenuModalContent = ({ Return to Game -
diff --git a/packages/webapp/src/components/modals/joinGameModal.tsx b/packages/webapp/src/components/modals/joinGameModal.tsx index eda6314b..e867a4cb 100644 --- a/packages/webapp/src/components/modals/joinGameModal.tsx +++ b/packages/webapp/src/components/modals/joinGameModal.tsx @@ -32,10 +32,7 @@ export const JoinGameModal = () => { return ( - @@ -152,12 +149,7 @@ const JoinGameModalContent = () => { onChange={handleInputChange} className="mr-2 w-full max-w-xs text-white placeholder-gray-500 font-mono" /> -
diff --git a/packages/webapp/src/components/modals/loadingModal.tsx b/packages/webapp/src/components/modals/loadingModal.tsx index 32f2feb9..27daee50 100644 --- a/packages/webapp/src/components/modals/loadingModal.tsx +++ b/packages/webapp/src/components/modals/loadingModal.tsx @@ -105,11 +105,7 @@ export const LoadingModalContent = ({ {cancellable && (
-
diff --git a/packages/webapp/src/components/modals/mintDeckModal.tsx b/packages/webapp/src/components/modals/mintDeckModal.tsx index 64685137..f1dace7f 100644 --- a/packages/webapp/src/components/modals/mintDeckModal.tsx +++ b/packages/webapp/src/components/modals/mintDeckModal.tsx @@ -17,10 +17,7 @@ export const MintDeckModal = ({ callback = () => {} }) => { return ( - @@ -64,12 +61,7 @@ const MintDeckModalContent = ({ callback }: { callback: () => void }) => { Mint a deck of cards to play the game with your friends.

-
diff --git a/packages/webapp/src/components/navbar.tsx b/packages/webapp/src/components/navbar.tsx index 42a79811..e786e5fe 100644 --- a/packages/webapp/src/components/navbar.tsx +++ b/packages/webapp/src/components/navbar.tsx @@ -13,10 +13,7 @@ export const Navbar = () => { - @@ -27,10 +24,7 @@ export const Navbar = () => { - diff --git a/packages/webapp/src/pages/index.tsx b/packages/webapp/src/pages/index.tsx index 6837a9bf..5e6a6533 100644 --- a/packages/webapp/src/pages/index.tsx +++ b/packages/webapp/src/pages/index.tsx @@ -46,11 +46,7 @@ const Home: FablePage = ({ isHydrated }) => { {notConnected && (
-
@@ -65,18 +61,12 @@ const Home: FablePage = ({ isHydrated }) => { - - diff --git a/packages/webapp/src/pages/play.tsx b/packages/webapp/src/pages/play.tsx index 42e92213..216ad5ff 100644 --- a/packages/webapp/src/pages/play.tsx +++ b/packages/webapp/src/pages/play.tsx @@ -213,30 +213,18 @@ const Play: FablePage = ({ isHydrated }) => { {!ended && ( <> - - - @@ -245,11 +233,7 @@ const Play: FablePage = ({ isHydrated }) => { {/* TODO avoid the bump by grouping buttons in a container that is translated, then no need for the translation here and the important */} {ended && ( <> - From 978f2a1429586f25d623e87ae22c0a47bb1c0ed2 Mon Sep 17 00:00:00 2001 From: Aritra Chatterjee Date: Sun, 21 Jan 2024 19:48:57 +0530 Subject: [PATCH 26/34] use absolute imports for components --- packages/webapp/src/components/ui/button.tsx | 2 +- packages/webapp/src/components/ui/dialog.tsx | 2 +- packages/webapp/src/components/ui/input.tsx | 2 +- packages/webapp/src/components/ui/navigation-menu.tsx | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/webapp/src/components/ui/button.tsx b/packages/webapp/src/components/ui/button.tsx index b52baa62..9d853c9d 100644 --- a/packages/webapp/src/components/ui/button.tsx +++ b/packages/webapp/src/components/ui/button.tsx @@ -2,7 +2,7 @@ import * as React from "react" import { Slot } from "@radix-ui/react-slot" import { cva, type VariantProps } from "class-variance-authority" -import { cn } from "../../utils/ui-utils" +import { cn } from "src/utils/ui-utils" // ref: https://ui.shadcn.com/docs/components/button const buttonVariants = cva( diff --git a/packages/webapp/src/components/ui/dialog.tsx b/packages/webapp/src/components/ui/dialog.tsx index 6e5dc7e6..8895104e 100644 --- a/packages/webapp/src/components/ui/dialog.tsx +++ b/packages/webapp/src/components/ui/dialog.tsx @@ -4,7 +4,7 @@ import * as React from "react" import * as DialogPrimitive from "@radix-ui/react-dialog" import { X } from "lucide-react" -import { cn } from "../../utils/ui-utils" +import { cn } from "src/utils/ui-utils" const Dialog = DialogPrimitive.Root diff --git a/packages/webapp/src/components/ui/input.tsx b/packages/webapp/src/components/ui/input.tsx index 6f6b1302..6199bbe9 100644 --- a/packages/webapp/src/components/ui/input.tsx +++ b/packages/webapp/src/components/ui/input.tsx @@ -1,6 +1,6 @@ import * as React from "react" -import { cn } from "../../utils/ui-utils" +import { cn } from "src/utils/ui-utils" export interface InputProps extends React.InputHTMLAttributes {} diff --git a/packages/webapp/src/components/ui/navigation-menu.tsx b/packages/webapp/src/components/ui/navigation-menu.tsx index b8f2d6d7..89de10d3 100644 --- a/packages/webapp/src/components/ui/navigation-menu.tsx +++ b/packages/webapp/src/components/ui/navigation-menu.tsx @@ -3,7 +3,7 @@ import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu" import { cva } from "class-variance-authority" import { ChevronDown } from "lucide-react" -import { cn } from "../../utils/ui-utils" +import { cn } from "src/utils/ui-utils" // ref: https://ui.shadcn.com/docs/components/navigation-menu const NavigationMenu = React.forwardRef< From 1d39ac120a06646747cccb27282c108b1ac4ceea Mon Sep 17 00:00:00 2001 From: Aritra Chatterjee Date: Sun, 21 Jan 2024 19:52:16 +0530 Subject: [PATCH 27/34] define open/close behaviour for `joinGameModal` --- .../src/components/modals/joinGameModal.tsx | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/packages/webapp/src/components/modals/joinGameModal.tsx b/packages/webapp/src/components/modals/joinGameModal.tsx index e867a4cb..4a0d2b7a 100644 --- a/packages/webapp/src/components/modals/joinGameModal.tsx +++ b/packages/webapp/src/components/modals/joinGameModal.tsx @@ -24,9 +24,15 @@ import { import { Button } from "src/components/ui/button" import { Input } from "src/components/ui/input" +interface JoinGameModalContentProps { + loading: string | null; + setLoading: React.Dispatch>; +} + // ================================================================================================= export const JoinGameModal = () => { + const [ loading, setLoading ] = useState(null) const isGameJoiner = store.useIsGameJoiner() return ( @@ -36,8 +42,14 @@ export const JoinGameModal = () => { Join Game → - - + { if (loading) event.preventDefault(); }} + onCloseAutoFocus={(event) => { if (loading) event.preventDefault(); }} + // prevent modal from closing if esc key is pressed and loading is populated + onKeyDown={(event) => { if(loading && event.key == 'Escape') event.preventDefault(); }} + > +
) @@ -45,13 +57,13 @@ export const JoinGameModal = () => { // ================================================================================================= -const JoinGameModalContent = () => { +const JoinGameModalContent: React.FC = ({ loading, setLoading }) => { const [ gameID, setGameID ] = store.useGameID() const playerAddress = store.usePlayerAddress() const gameStatus = store.useGameStatus() const [ hasVisitedBoard ] = store.useHasVisitedBoard() const [ inputGameID, setInputGameID ] = useState(null) - const [ loading, setLoading ] = useState(null) + const [ drawCompleted, setDrawCompleted ] = useState(false) const router = useRouter() From 97d7a39f8bdc3d164fde85bcf13b023e09251b37 Mon Sep 17 00:00:00 2001 From: Aritra Chatterjee Date: Sun, 21 Jan 2024 20:04:47 +0530 Subject: [PATCH 28/34] define open/close behaviour for `CreateGameModal` --- .../src/components/modals/createGameModal.tsx | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/packages/webapp/src/components/modals/createGameModal.tsx b/packages/webapp/src/components/modals/createGameModal.tsx index 92f4e7ca..46cff8cf 100644 --- a/packages/webapp/src/components/modals/createGameModal.tsx +++ b/packages/webapp/src/components/modals/createGameModal.tsx @@ -22,10 +22,20 @@ import { } from "src/components/ui/dialog" import { Button } from "src/components/ui/button" +interface CreateGameModalContentProps { + loading: string|null; + setLoading: React.Dispatch>; + gameStatus: GameStatus +} + // ================================================================================================= export const CreateGameModal = () => { + const [ loading, setLoading ] = useState< string|null >(null); const isGameCreator = store.useIsGameCreator() + const gameStatus = store.useGameStatus() + + const preventSurroundClick = gameStatus >= GameStatus.CREATED && loading; // created and loading return ( // If we're on the home page and we're the game creator, this modal should be displayed. @@ -35,22 +45,26 @@ export const CreateGameModal = () => { Create Game → - - - + { if (preventSurroundClick) event.preventDefault(); }} + onCloseAutoFocus={(event) => { if (preventSurroundClick) event.preventDefault(); }} + // prevent modal from closing if esc key is pressed and loading is populated + onKeyDown={(event) => { if(preventSurroundClick && event.key == 'Escape') event.preventDefault(); }} + > + + ) } // ================================================================================================= -const CreateGameModalContent = () => { +const CreateGameModalContent: React.FC = ({ loading, setLoading, gameStatus }) => { const playerAddress = store.usePlayerAddress() const [ gameID, setGameID ] = store.useGameID() - const gameStatus = store.useGameStatus() const allPlayersJoined = store.useAllPlayersJoined() const [ hasVisitedBoard ] = store.useHasVisitedBoard() - const [ loading, setLoading ] = useState(null) const [ drawCompleted, setDrawCompleted ] = useState(false) const router = useRouter() @@ -130,7 +144,7 @@ const CreateGameModalContent = () => { setGameID(null) } }), - [gameID, playerAddress, setGameID]) + [gameID, playerAddress, setGameID, setLoading]) // ----------------------------------------------------------------------------------------------- From 6dd18e0ac0806ea221fcc71b20dcd32499d29996 Mon Sep 17 00:00:00 2001 From: Aritra Chatterjee Date: Fri, 26 Jan 2024 00:49:20 +0530 Subject: [PATCH 29/34] update event handlers for dialog components --- .../src/components/modals/createGameModal.tsx | 14 +++++------- .../src/components/modals/joinGameModal.tsx | 7 +++--- .../src/components/modals/mintDeckModal.tsx | 22 ++++++++++++++----- packages/webapp/tailwind.config.cjs | 3 --- 4 files changed, 26 insertions(+), 20 deletions(-) diff --git a/packages/webapp/src/components/modals/createGameModal.tsx b/packages/webapp/src/components/modals/createGameModal.tsx index 46cff8cf..df5b6ab7 100644 --- a/packages/webapp/src/components/modals/createGameModal.tsx +++ b/packages/webapp/src/components/modals/createGameModal.tsx @@ -24,19 +24,18 @@ import { Button } from "src/components/ui/button" interface CreateGameModalContentProps { loading: string|null; - setLoading: React.Dispatch>; + setLoading: React.Dispatch>; gameStatus: GameStatus } // ================================================================================================= export const CreateGameModal = () => { - const [ loading, setLoading ] = useState< string|null >(null); + const [ loading, setLoading ] = useState(null); const isGameCreator = store.useIsGameCreator() const gameStatus = store.useGameStatus() - const preventSurroundClick = gameStatus >= GameStatus.CREATED && loading; // created and loading - + const isSurroundCloseable = loading !== null || (gameStatus >= GameStatus.CREATED) // state is loading or game is in created state return ( // If we're on the home page and we're the game creator, this modal should be displayed. @@ -47,13 +46,12 @@ export const CreateGameModal = () => { { if (preventSurroundClick) event.preventDefault(); }} - onCloseAutoFocus={(event) => { if (preventSurroundClick) event.preventDefault(); }} + onInteractOutside={(e) => isSurroundCloseable ? e.preventDefault() : null} // prevent modal from closing if esc key is pressed and loading is populated - onKeyDown={(event) => { if(preventSurroundClick && event.key == 'Escape') event.preventDefault(); }} + onEscapeKeyDown={(e) => isSurroundCloseable ? e.preventDefault() : null} > - + ) } diff --git a/packages/webapp/src/components/modals/joinGameModal.tsx b/packages/webapp/src/components/modals/joinGameModal.tsx index 4a0d2b7a..909ae4f8 100644 --- a/packages/webapp/src/components/modals/joinGameModal.tsx +++ b/packages/webapp/src/components/modals/joinGameModal.tsx @@ -44,12 +44,11 @@ export const JoinGameModal = () => { { if (loading) event.preventDefault(); }} - onCloseAutoFocus={(event) => { if (loading) event.preventDefault(); }} + onInteractOutside={(e) => loading !== null ? e.preventDefault() : null} // prevent modal from closing if esc key is pressed and loading is populated - onKeyDown={(event) => { if(loading && event.key == 'Escape') event.preventDefault(); }} + onEscapeKeyDown={(e) => loading !== null ? e.preventDefault() : null} > - + ) diff --git a/packages/webapp/src/components/modals/mintDeckModal.tsx b/packages/webapp/src/components/modals/mintDeckModal.tsx index f1dace7f..5b3fbba3 100644 --- a/packages/webapp/src/components/modals/mintDeckModal.tsx +++ b/packages/webapp/src/components/modals/mintDeckModal.tsx @@ -11,9 +11,17 @@ import { } from "src/components/ui/dialog" import { Button } from "src/components/ui/button" +interface MintDeckModalContentProps { + loading: string | null; + setLoading: React.Dispatch>; + callback: () => void +} + // ================================================================================================= export const MintDeckModal = ({ callback = () => {} }) => { + const [ loading, setLoading ] = useState(null) + return ( @@ -21,8 +29,13 @@ export const MintDeckModal = ({ callback = () => {} }) => { Mint Deck → - - + loading !== null ? e.preventDefault() : null} + // prevent modal from closing if esc key is pressed and loading is populated + onEscapeKeyDown={(e) => loading !== null ? e.preventDefault() : null} + > + ) @@ -30,9 +43,8 @@ export const MintDeckModal = ({ callback = () => {} }) => { // ================================================================================================= -const MintDeckModalContent = ({ callback }: { callback: () => void }) => { - const [loading, setLoading] = useState(null) - const [success, setSuccess] = useState(false) +const MintDeckModalContent: React.FC = ({ loading, setLoading, callback }) => { + const [ success, setSuccess ] = useState(false) const { write: claim } = useDeckAirdropWrite({ functionName: "claimAirdrop", diff --git a/packages/webapp/tailwind.config.cjs b/packages/webapp/tailwind.config.cjs index 63ef7672..04eb984a 100644 --- a/packages/webapp/tailwind.config.cjs +++ b/packages/webapp/tailwind.config.cjs @@ -2,9 +2,6 @@ module.exports = { // darkMode: ["class"], content: [ - "./pages/**/*.{ts,tsx}", - "./components/**/*.{ts,tsx}", - "./app/**/*.{ts,tsx}", "./src/**/*.{ts,tsx}", ], prefix: "", From 429286360dd928e575568e9aa708c620badca022 Mon Sep 17 00:00:00 2001 From: Aritra Chatterjee Date: Fri, 26 Jan 2024 00:49:35 +0530 Subject: [PATCH 30/34] fix: typo --- packages/webapp/src/hooks/useChainWrite.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/webapp/src/hooks/useChainWrite.ts b/packages/webapp/src/hooks/useChainWrite.ts index e1fd67b5..73ffa0e3 100644 --- a/packages/webapp/src/hooks/useChainWrite.ts +++ b/packages/webapp/src/hooks/useChainWrite.ts @@ -103,7 +103,7 @@ export function useChainWrite(_params: UseWriteParams): UseWriteResult { } = completeParams(_params) // TODO(norswap): It could be good to include some generic error handling / preprocessing here. - // This will require disantangling what can happen when and what to do about it. + // This will require disentangling what can happen when and what to do about it. // cf. https://twitter.com/norswap/status/1640409794409316361 const config = prepare From eb5989bef52a8d5f32963e8003fddaec3ad2f89a Mon Sep 17 00:00:00 2001 From: Aritra Chatterjee Date: Sat, 27 Jan 2024 20:31:49 +0530 Subject: [PATCH 31/34] abstract keyclick handlers, add prop to `dialog` component --- .../src/components/modals/createGameModal.tsx | 9 ++------ .../src/components/modals/joinGameModal.tsx | 16 ++++++-------- .../src/components/modals/mintDeckModal.tsx | 7 +----- packages/webapp/src/components/ui/dialog.tsx | 22 ++++++++++++++----- 4 files changed, 26 insertions(+), 28 deletions(-) diff --git a/packages/webapp/src/components/modals/createGameModal.tsx b/packages/webapp/src/components/modals/createGameModal.tsx index df5b6ab7..c52fe1fa 100644 --- a/packages/webapp/src/components/modals/createGameModal.tsx +++ b/packages/webapp/src/components/modals/createGameModal.tsx @@ -35,7 +35,7 @@ export const CreateGameModal = () => { const isGameCreator = store.useIsGameCreator() const gameStatus = store.useGameStatus() - const isSurroundCloseable = loading !== null || (gameStatus >= GameStatus.CREATED) // state is loading or game is in created state + const canCloseExternally = loading == null && gameStatus < GameStatus.CREATED return ( // If we're on the home page and we're the game creator, this modal should be displayed. @@ -44,12 +44,7 @@ export const CreateGameModal = () => { Create Game → - isSurroundCloseable ? e.preventDefault() : null} - // prevent modal from closing if esc key is pressed and loading is populated - onEscapeKeyDown={(e) => isSurroundCloseable ? e.preventDefault() : null} - > + diff --git a/packages/webapp/src/components/modals/joinGameModal.tsx b/packages/webapp/src/components/modals/joinGameModal.tsx index 909ae4f8..68d67a62 100644 --- a/packages/webapp/src/components/modals/joinGameModal.tsx +++ b/packages/webapp/src/components/modals/joinGameModal.tsx @@ -27,6 +27,7 @@ import { Input } from "src/components/ui/input" interface JoinGameModalContentProps { loading: string | null; setLoading: React.Dispatch>; + gameStatus: GameStatus } // ================================================================================================= @@ -34,6 +35,9 @@ interface JoinGameModalContentProps { export const JoinGameModal = () => { const [ loading, setLoading ] = useState(null) const isGameJoiner = store.useIsGameJoiner() + const gameStatus = store.useGameStatus() + + const canCloseExternally = loading == null && gameStatus < GameStatus.JOINED return ( @@ -42,13 +46,8 @@ export const JoinGameModal = () => { Join Game → - loading !== null ? e.preventDefault() : null} - // prevent modal from closing if esc key is pressed and loading is populated - onEscapeKeyDown={(e) => loading !== null ? e.preventDefault() : null} - > - + + ) @@ -56,10 +55,9 @@ export const JoinGameModal = () => { // ================================================================================================= -const JoinGameModalContent: React.FC = ({ loading, setLoading }) => { +const JoinGameModalContent: React.FC = ({ loading, setLoading, gameStatus }) => { const [ gameID, setGameID ] = store.useGameID() const playerAddress = store.usePlayerAddress() - const gameStatus = store.useGameStatus() const [ hasVisitedBoard ] = store.useHasVisitedBoard() const [ inputGameID, setInputGameID ] = useState(null) diff --git a/packages/webapp/src/components/modals/mintDeckModal.tsx b/packages/webapp/src/components/modals/mintDeckModal.tsx index 5b3fbba3..67b7fbac 100644 --- a/packages/webapp/src/components/modals/mintDeckModal.tsx +++ b/packages/webapp/src/components/modals/mintDeckModal.tsx @@ -29,12 +29,7 @@ export const MintDeckModal = ({ callback = () => {} }) => { Mint Deck → - loading !== null ? e.preventDefault() : null} - // prevent modal from closing if esc key is pressed and loading is populated - onEscapeKeyDown={(e) => loading !== null ? e.preventDefault() : null} - > + diff --git a/packages/webapp/src/components/ui/dialog.tsx b/packages/webapp/src/components/ui/dialog.tsx index 8895104e..0c99dd46 100644 --- a/packages/webapp/src/components/ui/dialog.tsx +++ b/packages/webapp/src/components/ui/dialog.tsx @@ -30,10 +30,16 @@ const DialogOverlay = React.forwardRef< )) DialogOverlay.displayName = DialogPrimitive.Overlay.displayName + +interface CustomDialogContentProps extends React.ComponentPropsWithoutRef { + // extend the existing type definition to allow for an additional prop + canCloseExternally?: boolean; +} + const DialogContent = React.forwardRef< React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, children, ...props }, ref) => ( + CustomDialogContentProps +>(({ className, children, canCloseExternally = true, ...props }, ref) => ( !canCloseExternally ? e.preventDefault() : null} + onEscapeKeyDown={(e) => !canCloseExternally ? e.preventDefault() : null} {...props} > {children} - - - Close - + {canCloseExternally && ( + + + Close + + )} )) From 1f364bbed23e0cf387b7500332886b6592afa97e Mon Sep 17 00:00:00 2001 From: Aritra Chatterjee Date: Wed, 31 Jan 2024 20:54:53 +0530 Subject: [PATCH 32/34] remove font preload, use state variable for modal default opens --- .../webapp/src/components/modals/createGameModal.tsx | 10 +++++++++- .../webapp/src/components/modals/joinGameModal.tsx | 10 +++++++++- packages/webapp/src/pages/_app.tsx | 1 - 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/packages/webapp/src/components/modals/createGameModal.tsx b/packages/webapp/src/components/modals/createGameModal.tsx index c52fe1fa..de68ea3a 100644 --- a/packages/webapp/src/components/modals/createGameModal.tsx +++ b/packages/webapp/src/components/modals/createGameModal.tsx @@ -31,14 +31,22 @@ interface CreateGameModalContentProps { // ================================================================================================= export const CreateGameModal = () => { + const [ open, setOpen ] = useState(false); const [ loading, setLoading ] = useState(null); const isGameCreator = store.useIsGameCreator() const gameStatus = store.useGameStatus() + useEffect(() => { + // If we're on the home page and we're the game creator, this modal should be displayed. + if (isGameCreator && !open) + setOpen(true) + }, [isGameCreator, open]) + + const canCloseExternally = loading == null && gameStatus < GameStatus.CREATED return ( // If we're on the home page and we're the game creator, this modal should be displayed. - +