diff --git a/package.json b/package.json index f376e84..b9da9b0 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ }, "dependencies": { "@hookform/resolvers": "^3.9.1", - "@polinetwork/backend": "^0.12.1", + "@polinetwork/backend": "^0.14.0", "@radix-ui/react-alert-dialog": "^1.1.3", "@radix-ui/react-avatar": "^1.1.1", "@radix-ui/react-collapsible": "^1.1.1", @@ -27,19 +27,20 @@ "@radix-ui/react-separator": "^1.1.0", "@radix-ui/react-slot": "^1.1.0", "@radix-ui/react-tooltip": "^1.1.4", - "@t3-oss/env-nextjs": "^0.10.1", - "@tanstack/react-query": "^5.90.12", + "@t3-oss/env-nextjs": "^0.13.10", + "@tanstack/react-query": "^5.90.19", "@tanstack/react-table": "^8.21.2", "@trpc/client": "11.5.1", "@trpc/next": "11.5.1", "@trpc/react-query": "11.5.1", "@trpc/tanstack-react-query": "11.5.1", + "better-auth": "^1.4.15", "babel-plugin-react-compiler": "1.0.0", - "better-auth": "^1.3.15", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.1.1", "geist": "^1.3.0", + "input-otp": "^1.4.2", "lucide-react": "^0.525.0", "next": "^15.5.9", "next-themes": "^0.4.4", @@ -53,7 +54,7 @@ "tailwind-merge": "^3.0.1", "tailwind-scrollbar": "^4.0.2", "tailwindcss-animate": "^1.0.7", - "zod": "^3.23.3" + "zod": "^4.3.5" }, "devDependencies": { "@biomejs/biome": "2.3.10", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b76ea6c..afcba2c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,8 +12,8 @@ importers: specifier: ^3.9.1 version: 3.10.0(react-hook-form@7.55.0(react@18.3.1)) '@polinetwork/backend': - specifier: ^0.12.1 - version: 0.12.1 + specifier: ^0.14.0 + version: 0.14.0 '@radix-ui/react-alert-dialog': specifier: ^1.1.3 version: 1.1.6(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -51,11 +51,11 @@ importers: specifier: ^1.1.4 version: 1.1.8(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@t3-oss/env-nextjs': - specifier: ^0.10.1 - version: 0.10.1(typescript@5.7.3)(zod@3.24.2) + specifier: ^0.13.10 + version: 0.13.10(typescript@5.7.3)(zod@4.3.5) '@tanstack/react-query': - specifier: ^5.90.12 - version: 5.90.12(react@18.3.1) + specifier: ^5.90.19 + version: 5.90.19(react@18.3.1) '@tanstack/react-table': specifier: ^8.21.2 version: 8.21.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -64,19 +64,19 @@ importers: version: 11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3) '@trpc/next': specifier: 11.5.1 - version: 11.5.1(@tanstack/react-query@5.90.12(react@18.3.1))(@trpc/client@11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3))(@trpc/react-query@11.5.1(@tanstack/react-query@5.90.12(react@18.3.1))(@trpc/client@11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3))(@trpc/server@11.5.1(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3))(@trpc/server@11.5.1(typescript@5.7.3))(next@15.5.9(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3) + version: 11.5.1(@tanstack/react-query@5.90.19(react@18.3.1))(@trpc/client@11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3))(@trpc/react-query@11.5.1(@tanstack/react-query@5.90.19(react@18.3.1))(@trpc/client@11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3))(@trpc/server@11.5.1(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3))(@trpc/server@11.5.1(typescript@5.7.3))(next@15.5.9(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3) '@trpc/react-query': specifier: 11.5.1 - version: 11.5.1(@tanstack/react-query@5.90.12(react@18.3.1))(@trpc/client@11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3))(@trpc/server@11.5.1(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3) + version: 11.5.1(@tanstack/react-query@5.90.19(react@18.3.1))(@trpc/client@11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3))(@trpc/server@11.5.1(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3) '@trpc/tanstack-react-query': specifier: 11.5.1 - version: 11.5.1(@tanstack/react-query@5.90.12(react@18.3.1))(@trpc/client@11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3))(@trpc/server@11.5.1(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3) + version: 11.5.1(@tanstack/react-query@5.90.19(react@18.3.1))(@trpc/client@11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3))(@trpc/server@11.5.1(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3) babel-plugin-react-compiler: specifier: 1.0.0 version: 1.0.0 better-auth: - specifier: ^1.3.15 - version: 1.3.15(next@15.5.9(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^1.4.15 + version: 1.4.15(next@15.5.9(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -89,6 +89,9 @@ importers: geist: specifier: ^1.3.0 version: 1.3.1(next@15.5.9(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + input-otp: + specifier: ^1.4.2 + version: 1.4.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) lucide-react: specifier: ^0.525.0 version: 0.525.0(react@18.3.1) @@ -129,8 +132,8 @@ importers: specifier: ^1.0.7 version: 1.0.7(tailwindcss@4.1.4) zod: - specifier: ^3.23.3 - version: 3.24.2 + specifier: ^4.3.5 + version: 4.3.5 devDependencies: '@biomejs/biome': specifier: 2.3.10 @@ -178,6 +181,21 @@ packages: resolution: {integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==} engines: {node: '>=6.9.0'} + '@better-auth/core@1.4.15': + resolution: {integrity: sha512-uAvq8YA7SaS7v+TrvH/Kwt7LAJihzUqB3FX8VweDsqu3gn5t51M+Bve+V1vVWR9qBAtC6cN68V6b+scxZxDY4A==} + peerDependencies: + '@better-auth/utils': 0.3.0 + '@better-fetch/fetch': 1.1.21 + better-call: 1.1.8 + jose: ^6.1.0 + kysely: ^0.28.5 + nanostores: ^1.0.1 + + '@better-auth/telemetry@1.4.15': + resolution: {integrity: sha512-7NW/2PS4RN85rv+ozpAezP/kSLPZeWkxqcA6RA/CFXqWp2YR2e5q5E6Hym1qBgVBkoAQa3lWFdX3b+jEs+vvrQ==} + peerDependencies: + '@better-auth/core': 1.4.15 + '@better-auth/utils@0.3.0': resolution: {integrity: sha512-W+Adw6ZA6mgvnSnhOki270rwJ42t4XzSK6YWGF//BbVXL6SwCLWfyzBc1lN2m/4RM28KubdBKQ4X5VMoLRNPQw==} @@ -237,8 +255,8 @@ packages: cpu: [x64] os: [win32] - '@emnapi/runtime@1.7.1': - resolution: {integrity: sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==} + '@emnapi/runtime@1.8.1': + resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==} '@floating-ui/core@1.6.9': resolution: {integrity: sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==} @@ -255,9 +273,6 @@ packages: '@floating-ui/utils@0.2.9': resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==} - '@hexagon/base64@1.1.28': - resolution: {integrity: sha512-lhqDEAvWixy3bZ+UOYbPwUbBkwBq5C1LAJ/xPC8Oi+lL54oyakv/npbA0aU2hgCsx/1NUd4IBvV03+aUBWxerw==} - '@hookform/resolvers@3.10.0': resolution: {integrity: sha512-79Dv+3mDF7i+2ajj7SkypSKHhl1cbln1OGavqrsF7p6mbUv11xpqpacPsGDCTRvCSjEEIez2ef1NveSVL3b0Ag==} peerDependencies: @@ -400,9 +415,6 @@ packages: cpu: [x64] os: [win32] - '@levischuck/tiny-cbor@0.2.11': - resolution: {integrity: sha512-llBRm4dT4Z89aRsm6u2oEZ8tfwL/2l6BwpZ7JcyieouniDECM5AqNgr/y08zalEIvW3RSK4upYyybDcmjXqAow==} - '@next/env@15.5.9': resolution: {integrity: sha512-4GlTZ+EJM7WaW2HEZcyU317tIQDjkQIyENDLxYJfSWlfqguN+dHkZgyQTV/7ykvobU7yEH5gKvreNrH4B6QgIg==} @@ -462,45 +474,8 @@ packages: resolution: {integrity: sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw==} engines: {node: '>= 20.19.0'} - '@peculiar/asn1-android@2.6.0': - resolution: {integrity: sha512-cBRCKtYPF7vJGN76/yG8VbxRcHLPF3HnkoHhKOZeHpoVtbMYfY9ROKtH3DtYUY9m8uI1Mh47PRhHf2hSK3xcSQ==} - - '@peculiar/asn1-cms@2.6.0': - resolution: {integrity: sha512-2uZqP+ggSncESeUF/9Su8rWqGclEfEiz1SyU02WX5fUONFfkjzS2Z/F1Li0ofSmf4JqYXIOdCAZqIXAIBAT1OA==} - - '@peculiar/asn1-csr@2.6.0': - resolution: {integrity: sha512-BeWIu5VpTIhfRysfEp73SGbwjjoLL/JWXhJ/9mo4vXnz3tRGm+NGm3KNcRzQ9VMVqwYS2RHlolz21svzRXIHPQ==} - - '@peculiar/asn1-ecc@2.6.0': - resolution: {integrity: sha512-FF3LMGq6SfAOwUG2sKpPXblibn6XnEIKa+SryvUl5Pik+WR9rmRA3OCiwz8R3lVXnYnyRkSZsSLdml8H3UiOcw==} - - '@peculiar/asn1-pfx@2.6.0': - resolution: {integrity: sha512-rtUvtf+tyKGgokHHmZzeUojRZJYPxoD/jaN1+VAB4kKR7tXrnDCA/RAWXAIhMJJC+7W27IIRGe9djvxKgsldCQ==} - - '@peculiar/asn1-pkcs8@2.6.0': - resolution: {integrity: sha512-KyQ4D8G/NrS7Fw3XCJrngxmjwO/3htnA0lL9gDICvEQ+GJ+EPFqldcJQTwPIdvx98Tua+WjkdKHSC0/Km7T+lA==} - - '@peculiar/asn1-pkcs9@2.6.0': - resolution: {integrity: sha512-b78OQ6OciW0aqZxdzliXGYHASeCvvw5caqidbpQRYW2mBtXIX2WhofNXTEe7NyxTb0P6J62kAAWLwn0HuMF1Fw==} - - '@peculiar/asn1-rsa@2.6.0': - resolution: {integrity: sha512-Nu4C19tsrTsCp9fDrH+sdcOKoVfdfoQQ7S3VqjJU6vedR7tY3RLkQ5oguOIB3zFW33USDUuYZnPEQYySlgha4w==} - - '@peculiar/asn1-schema@2.6.0': - resolution: {integrity: sha512-xNLYLBFTBKkCzEZIw842BxytQQATQv+lDTCEMZ8C196iJcJJMBUZxrhSTxLaohMyKK8QlzRNTRkUmanucnDSqg==} - - '@peculiar/asn1-x509-attr@2.6.0': - resolution: {integrity: sha512-MuIAXFX3/dc8gmoZBkwJWxUWOSvG4MMDntXhrOZpJVMkYX+MYc/rUAU2uJOved9iJEoiUx7//3D8oG83a78UJA==} - - '@peculiar/asn1-x509@2.6.0': - resolution: {integrity: sha512-uzYbPEpoQiBoTq0/+jZtpM6Gq6zADBx+JNFP3yqRgziWBxQ/Dt/HcuvRfm9zJTPdRcBqPNdaRHTVwpyiq6iNMA==} - - '@peculiar/x509@1.14.2': - resolution: {integrity: sha512-r2w1Hg6pODDs0zfAKHkSS5HLkOLSeburtcgwvlLLWWCixw+MmW3U6kD5ddyvc2Y2YdbGuVwCF2S2ASoU1cFAag==} - engines: {node: '>=22.0.0'} - - '@polinetwork/backend@0.12.1': - resolution: {integrity: sha512-ZKDYjPIo/Y+CXoHK+LOW+8AvUAFCiBpP/yTYrwFQKX4/o3z6uSc33wyHGVOv8+HrqiBz0QZly9vzrO9sMukQEA==} + '@polinetwork/backend@0.14.0': + resolution: {integrity: sha512-VSkSLetxprjPu38WFK580uQ3VBtflM4Srz+D32ONtL0u9SUjixSq5lNwPXcQmGqiByrV3RIA3Z2WBJY2A9Lk4w==} engines: {node: '>=24.8.0', pnpm: '>=10.17.1'} '@radix-ui/number@1.1.0': @@ -1042,33 +1017,45 @@ packages: '@radix-ui/rect@1.1.0': resolution: {integrity: sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==} - '@simplewebauthn/browser@13.2.2': - resolution: {integrity: sha512-FNW1oLQpTJyqG5kkDg5ZsotvWgmBaC6jCHR7Ej0qUNep36Wl9tj2eZu7J5rP+uhXgHaLk+QQ3lqcw2vS5MX1IA==} - - '@simplewebauthn/server@13.2.2': - resolution: {integrity: sha512-HcWLW28yTMGXpwE9VLx9J+N2KEUaELadLrkPEEI9tpI5la70xNEVEsu/C+m3u7uoq4FulLqZQhgBCzR9IZhFpA==} - engines: {node: '>=20.0.0'} + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} '@swc/helpers@0.5.15': resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} - '@t3-oss/env-core@0.10.1': - resolution: {integrity: sha512-GcKZiCfWks5CTxhezn9k5zWX3sMDIYf6Kaxy2Gx9YEQftFcz8hDRN56hcbylyAO3t4jQnQ5ifLawINsNgCDpOg==} + '@t3-oss/env-core@0.13.10': + resolution: {integrity: sha512-NNFfdlJ+HmPHkLi2HKy7nwuat9SIYOxei9K10lO2YlcSObDILY7mHZNSHsieIM3A0/5OOzw/P/b+yLvPdaG52g==} peerDependencies: + arktype: ^2.1.0 typescript: '>=5.0.0' - zod: ^3.0.0 + valibot: ^1.0.0-beta.7 || ^1.0.0 + zod: ^3.24.0 || ^4.0.0 peerDependenciesMeta: + arktype: + optional: true typescript: optional: true + valibot: + optional: true + zod: + optional: true - '@t3-oss/env-nextjs@0.10.1': - resolution: {integrity: sha512-iy2qqJLnFh1RjEWno2ZeyTu0ufomkXruUsOZludzDIroUabVvHsrSjtkHqwHp1/pgPUzN3yBRHMILW162X7x2Q==} + '@t3-oss/env-nextjs@0.13.10': + resolution: {integrity: sha512-JfSA2WXOnvcc/uMdp31paMsfbYhhdvLLRxlwvrnlPE9bwM/n0Z+Qb9xRv48nPpvfMhOrkrTYw1I5Yc06WIKBJQ==} peerDependencies: + arktype: ^2.1.0 typescript: '>=5.0.0' - zod: ^3.0.0 + valibot: ^1.0.0-beta.7 || ^1.0.0 + zod: ^3.24.0 || ^4.0.0 peerDependenciesMeta: + arktype: + optional: true typescript: optional: true + valibot: + optional: true + zod: + optional: true '@tailwindcss/node@4.1.4': resolution: {integrity: sha512-MT5118zaiO6x6hNA04OWInuAiP1YISXql8Z+/Y8iisV5nuhM8VXlyhRuqc2PEviPszcXI66W44bCIk500Oolhw==} @@ -1158,11 +1145,11 @@ packages: '@tailwindcss/postcss@4.1.4': resolution: {integrity: sha512-bjV6sqycCEa+AQSt2Kr7wpGF1bOZJ5wsqnLEkqSbM/JEHxx/yhMH8wHmdkPyApF9xhHeMSwnnkDUUMMM/hYnXw==} - '@tanstack/query-core@5.90.12': - resolution: {integrity: sha512-T1/8t5DhV/SisWjDnaiU2drl6ySvsHj1bHBCWNXd+/T+Hh1cf6JodyEYMd5sgwm+b/mETT4EV3H+zCVczCU5hg==} + '@tanstack/query-core@5.90.19': + resolution: {integrity: sha512-GLW5sjPVIvH491VV1ufddnfldyVB+teCnpPIvweEfkpRx7CfUmUGhoh9cdcUKBh/KwVxk22aNEDxeTsvmyB/WA==} - '@tanstack/react-query@5.90.12': - resolution: {integrity: sha512-graRZspg7EoEaw0a8faiUASCyJrqjKPdqJ9EwuDRUF9mEYJ1YPczI9H+/agJ0mOJkPCJDk0lsz5QTrLZ/jQ2rg==} + '@tanstack/react-query@5.90.19': + resolution: {integrity: sha512-qTZRZ4QyTzQc+M0IzrbKHxSeISUmRB3RPGmao5bT+sI6ayxSRhn0FXEnT5Hg3as8SBFcRosrXXRFB+yAcxVxJQ==} peerDependencies: react: ^18 || ^19 @@ -1246,31 +1233,58 @@ packages: resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==} engines: {node: '>=10'} - asn1js@3.0.7: - resolution: {integrity: sha512-uLvq6KJu04qoQM6gvBfKFjlh6Gl0vOKQuR5cJMDHQkmwfMOQeN3F3SHCv9SNYSL+CRoHvOGFfllDlVz03GQjvQ==} - engines: {node: '>=12.0.0'} - babel-plugin-react-compiler@1.0.0: resolution: {integrity: sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw==} - better-auth@1.3.15: - resolution: {integrity: sha512-l6WWy3WlopAb1sFJdiN0JZd7LmqWbW9nfxNaGn56tjkpYM6e/EeMmSo4TLdlQNh4Y5szAZzZt/fvuG3NefFoag==} + better-auth@1.4.15: + resolution: {integrity: sha512-XZr4GnFPbjvf8wip8AAjTrpGNn3Sba600zT+DgsR3NNCMWCt9aD8+nuRah6BHwHWnVP1nfnby07tPmti72SRBw==} peerDependencies: '@lynx-js/react': '*' + '@prisma/client': ^5.0.0 || ^6.0.0 || ^7.0.0 '@sveltejs/kit': ^2.0.0 - next: ^14.0.0 || ^15.0.0 + '@tanstack/react-start': ^1.0.0 + '@tanstack/solid-start': ^1.0.0 + better-sqlite3: ^12.0.0 + drizzle-kit: '>=0.31.4' + drizzle-orm: '>=0.41.0' + mongodb: ^6.0.0 || ^7.0.0 + mysql2: ^3.0.0 + next: ^14.0.0 || ^15.0.0 || ^16.0.0 + pg: ^8.0.0 + prisma: ^5.0.0 || ^6.0.0 || ^7.0.0 react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 solid-js: ^1.0.0 svelte: ^4.0.0 || ^5.0.0 + vitest: ^2.0.0 || ^3.0.0 || ^4.0.0 vue: ^3.0.0 peerDependenciesMeta: '@lynx-js/react': optional: true + '@prisma/client': + optional: true '@sveltejs/kit': optional: true + '@tanstack/react-start': + optional: true + '@tanstack/solid-start': + optional: true + better-sqlite3: + optional: true + drizzle-kit: + optional: true + drizzle-orm: + optional: true + mongodb: + optional: true + mysql2: + optional: true next: optional: true + pg: + optional: true + prisma: + optional: true react: optional: true react-dom: @@ -1279,14 +1293,21 @@ packages: optional: true svelte: optional: true + vitest: + optional: true vue: optional: true - better-call@1.0.19: - resolution: {integrity: sha512-sI3GcA1SCVa3H+CDHl8W8qzhlrckwXOTKhqq3OOPXjgn5aTOMIqGY34zLY/pHA6tRRMjTUC3lz5Mi7EbDA24Kw==} + better-call@1.1.8: + resolution: {integrity: sha512-XMQ2rs6FNXasGNfMjzbyroSwKwYbZ/T3IxruSS6U2MJRsSYh3wYtG3o6H00ZlKZ/C/UPOAD97tqgQJNsxyeTXw==} + peerDependencies: + zod: ^4.0.0 + peerDependenciesMeta: + zod: + optional: true - caniuse-lite@1.0.30001759: - resolution: {integrity: sha512-Pzfx9fOKoKvevQf8oCXoyNRQ5QyxJj+3O0Rqx2V5oxT61KGx8+n6hV/IUyJeifUci2clnmmKVpvtiqRzgiWjSw==} + caniuse-lite@1.0.30001706: + resolution: {integrity: sha512-3ZczoTApMAZwPKYWmwVbQMFpXBDds3/0VciVoUwPUbldlYyVLmRVuRs/PcUZtHpbLRpzzDvrvnFuREsGt6lUug==} class-variance-authority@0.7.1: resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} @@ -1341,6 +1362,12 @@ packages: graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + input-otp@1.4.2: + resolution: {integrity: sha512-l3jWwYNvrEa6NTCt7BECfCm48GvwuZzkoeG3gBL2w4CHeOXW3eKFmf9UNYkNfYc3mxMrthMnxjIE07MT0zLBQA==} + peerDependencies: + react: ^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc + is-what@4.1.16: resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} engines: {node: '>=12.13'} @@ -1355,8 +1382,8 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - kysely@0.28.9: - resolution: {integrity: sha512-3BeXMoiOhpOwu62CiVpO6lxfq4eS6KMYfQdMsN/2kUCRNuF2YiEr7u0HLHaQU+O4Xu8YXE3bHVkwaQ85i72EuA==} + kysely@0.28.10: + resolution: {integrity: sha512-ksNxfzIW77OcZ+QWSAPC7yDqUSaIVwkTWnTPNiIy//vifNbwsSgQ57OkkncHxxpcBHM3LRfLAZVEh7kjq5twVA==} engines: {node: '>=20.0.0'} lightningcss-darwin-arm64@1.29.2: @@ -1493,13 +1520,6 @@ packages: peerDependencies: react: '>=16.0.0' - pvtsutils@1.3.6: - resolution: {integrity: sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==} - - pvutils@1.1.5: - resolution: {integrity: sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==} - engines: {node: '>=16.0.0'} - react-dom@18.3.1: resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} peerDependencies: @@ -1545,11 +1565,8 @@ packages: resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} - reflect-metadata@0.2.2: - resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} - - rou3@0.5.1: - resolution: {integrity: sha512-OXMmJ3zRk2xeXFGfA3K+EOPHC5u7RDFG7lIOx0X1pdnhUkI8MdVrbV+sNsD80ElpUZ+MRHdyxPnFthq9VHs8uQ==} + rou3@0.7.12: + resolution: {integrity: sha512-iFE4hLDuloSWcD7mjdCDhx2bKcIsYbtOTpfH5MHHLSKMOUyjqQXTeZVa289uuwEGEKFoE/BAPbhaU4B774nceg==} scheduler@0.23.2: resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} @@ -1617,24 +1634,14 @@ packages: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} - tslib@1.14.1: - resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - tsyringe@4.10.0: - resolution: {integrity: sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==} - engines: {node: '>= 6.0.0'} - typescript@5.7.3: resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==} engines: {node: '>=14.17'} hasBin: true - uncrypto@0.1.3: - resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} - undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} @@ -1658,11 +1665,8 @@ packages: '@types/react': optional: true - zod@3.24.2: - resolution: {integrity: sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==} - - zod@4.2.1: - resolution: {integrity: sha512-0wZ1IRqGGhMP76gLqz8EyfBXKk0J2qo2+H3fi4mcUP/KtTocoX08nmIAHl1Z2kJIZbZee8KOpBCSNPRgauucjw==} + zod@4.3.5: + resolution: {integrity: sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==} snapshots: @@ -1677,6 +1681,23 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 + '@better-auth/core@1.4.15(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.5))(jose@6.1.3)(kysely@0.28.10)(nanostores@1.1.0)': + dependencies: + '@better-auth/utils': 0.3.0 + '@better-fetch/fetch': 1.1.21 + '@standard-schema/spec': 1.1.0 + better-call: 1.1.8(zod@4.3.5) + jose: 6.1.3 + kysely: 0.28.10 + nanostores: 1.1.0 + zod: 4.3.5 + + '@better-auth/telemetry@1.4.15(@better-auth/core@1.4.15(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.5))(jose@6.1.3)(kysely@0.28.10)(nanostores@1.1.0))': + dependencies: + '@better-auth/core': 1.4.15(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.5))(jose@6.1.3)(kysely@0.28.10)(nanostores@1.1.0) + '@better-auth/utils': 0.3.0 + '@better-fetch/fetch': 1.1.21 + '@better-auth/utils@0.3.0': {} '@better-fetch/fetch@1.1.21': {} @@ -1716,7 +1737,7 @@ snapshots: '@biomejs/cli-win32-x64@2.3.10': optional: true - '@emnapi/runtime@1.7.1': + '@emnapi/runtime@1.8.1': dependencies: tslib: 2.8.1 optional: true @@ -1738,8 +1759,6 @@ snapshots: '@floating-ui/utils@0.2.9': {} - '@hexagon/base64@1.1.28': {} - '@hookform/resolvers@3.10.0(react-hook-form@7.55.0(react@18.3.1))': dependencies: react-hook-form: 7.55.0(react@18.3.1) @@ -1829,7 +1848,7 @@ snapshots: '@img/sharp-wasm32@0.34.5': dependencies: - '@emnapi/runtime': 1.7.1 + '@emnapi/runtime': 1.8.1 optional: true '@img/sharp-win32-arm64@0.34.5': @@ -1841,8 +1860,6 @@ snapshots: '@img/sharp-win32-x64@0.34.5': optional: true - '@levischuck/tiny-cbor@0.2.11': {} - '@next/env@15.5.9': {} '@next/swc-darwin-arm64@15.5.7': @@ -1873,103 +1890,7 @@ snapshots: '@noble/hashes@2.0.1': {} - '@peculiar/asn1-android@2.6.0': - dependencies: - '@peculiar/asn1-schema': 2.6.0 - asn1js: 3.0.7 - tslib: 2.8.1 - - '@peculiar/asn1-cms@2.6.0': - dependencies: - '@peculiar/asn1-schema': 2.6.0 - '@peculiar/asn1-x509': 2.6.0 - '@peculiar/asn1-x509-attr': 2.6.0 - asn1js: 3.0.7 - tslib: 2.8.1 - - '@peculiar/asn1-csr@2.6.0': - dependencies: - '@peculiar/asn1-schema': 2.6.0 - '@peculiar/asn1-x509': 2.6.0 - asn1js: 3.0.7 - tslib: 2.8.1 - - '@peculiar/asn1-ecc@2.6.0': - dependencies: - '@peculiar/asn1-schema': 2.6.0 - '@peculiar/asn1-x509': 2.6.0 - asn1js: 3.0.7 - tslib: 2.8.1 - - '@peculiar/asn1-pfx@2.6.0': - dependencies: - '@peculiar/asn1-cms': 2.6.0 - '@peculiar/asn1-pkcs8': 2.6.0 - '@peculiar/asn1-rsa': 2.6.0 - '@peculiar/asn1-schema': 2.6.0 - asn1js: 3.0.7 - tslib: 2.8.1 - - '@peculiar/asn1-pkcs8@2.6.0': - dependencies: - '@peculiar/asn1-schema': 2.6.0 - '@peculiar/asn1-x509': 2.6.0 - asn1js: 3.0.7 - tslib: 2.8.1 - - '@peculiar/asn1-pkcs9@2.6.0': - dependencies: - '@peculiar/asn1-cms': 2.6.0 - '@peculiar/asn1-pfx': 2.6.0 - '@peculiar/asn1-pkcs8': 2.6.0 - '@peculiar/asn1-schema': 2.6.0 - '@peculiar/asn1-x509': 2.6.0 - '@peculiar/asn1-x509-attr': 2.6.0 - asn1js: 3.0.7 - tslib: 2.8.1 - - '@peculiar/asn1-rsa@2.6.0': - dependencies: - '@peculiar/asn1-schema': 2.6.0 - '@peculiar/asn1-x509': 2.6.0 - asn1js: 3.0.7 - tslib: 2.8.1 - - '@peculiar/asn1-schema@2.6.0': - dependencies: - asn1js: 3.0.7 - pvtsutils: 1.3.6 - tslib: 2.8.1 - - '@peculiar/asn1-x509-attr@2.6.0': - dependencies: - '@peculiar/asn1-schema': 2.6.0 - '@peculiar/asn1-x509': 2.6.0 - asn1js: 3.0.7 - tslib: 2.8.1 - - '@peculiar/asn1-x509@2.6.0': - dependencies: - '@peculiar/asn1-schema': 2.6.0 - asn1js: 3.0.7 - pvtsutils: 1.3.6 - tslib: 2.8.1 - - '@peculiar/x509@1.14.2': - dependencies: - '@peculiar/asn1-cms': 2.6.0 - '@peculiar/asn1-csr': 2.6.0 - '@peculiar/asn1-ecc': 2.6.0 - '@peculiar/asn1-pkcs9': 2.6.0 - '@peculiar/asn1-rsa': 2.6.0 - '@peculiar/asn1-schema': 2.6.0 - '@peculiar/asn1-x509': 2.6.0 - pvtsutils: 1.3.6 - reflect-metadata: 0.2.2 - tslib: 2.8.1 - tsyringe: 4.10.0 - - '@polinetwork/backend@0.12.1': {} + '@polinetwork/backend@0.14.0': {} '@radix-ui/number@1.1.0': {} @@ -2489,35 +2410,23 @@ snapshots: '@radix-ui/rect@1.1.0': {} - '@simplewebauthn/browser@13.2.2': {} - - '@simplewebauthn/server@13.2.2': - dependencies: - '@hexagon/base64': 1.1.28 - '@levischuck/tiny-cbor': 0.2.11 - '@peculiar/asn1-android': 2.6.0 - '@peculiar/asn1-ecc': 2.6.0 - '@peculiar/asn1-rsa': 2.6.0 - '@peculiar/asn1-schema': 2.6.0 - '@peculiar/asn1-x509': 2.6.0 - '@peculiar/x509': 1.14.2 + '@standard-schema/spec@1.1.0': {} '@swc/helpers@0.5.15': dependencies: tslib: 2.8.1 - '@t3-oss/env-core@0.10.1(typescript@5.7.3)(zod@3.24.2)': - dependencies: - zod: 3.24.2 + '@t3-oss/env-core@0.13.10(typescript@5.7.3)(zod@4.3.5)': optionalDependencies: typescript: 5.7.3 + zod: 4.3.5 - '@t3-oss/env-nextjs@0.10.1(typescript@5.7.3)(zod@3.24.2)': + '@t3-oss/env-nextjs@0.13.10(typescript@5.7.3)(zod@4.3.5)': dependencies: - '@t3-oss/env-core': 0.10.1(typescript@5.7.3)(zod@3.24.2) - zod: 3.24.2 + '@t3-oss/env-core': 0.13.10(typescript@5.7.3)(zod@4.3.5) optionalDependencies: typescript: 5.7.3 + zod: 4.3.5 '@tailwindcss/node@4.1.4': dependencies: @@ -2585,11 +2494,11 @@ snapshots: postcss: 8.5.2 tailwindcss: 4.1.4 - '@tanstack/query-core@5.90.12': {} + '@tanstack/query-core@5.90.19': {} - '@tanstack/react-query@5.90.12(react@18.3.1)': + '@tanstack/react-query@5.90.19(react@18.3.1)': dependencies: - '@tanstack/query-core': 5.90.12 + '@tanstack/query-core': 5.90.19 react: 18.3.1 '@tanstack/react-table@8.21.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': @@ -2605,7 +2514,7 @@ snapshots: '@trpc/server': 11.5.1(typescript@5.7.3) typescript: 5.7.3 - '@trpc/next@11.5.1(@tanstack/react-query@5.90.12(react@18.3.1))(@trpc/client@11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3))(@trpc/react-query@11.5.1(@tanstack/react-query@5.90.12(react@18.3.1))(@trpc/client@11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3))(@trpc/server@11.5.1(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3))(@trpc/server@11.5.1(typescript@5.7.3))(next@15.5.9(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)': + '@trpc/next@11.5.1(@tanstack/react-query@5.90.19(react@18.3.1))(@trpc/client@11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3))(@trpc/react-query@11.5.1(@tanstack/react-query@5.90.19(react@18.3.1))(@trpc/client@11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3))(@trpc/server@11.5.1(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3))(@trpc/server@11.5.1(typescript@5.7.3))(next@15.5.9(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)': dependencies: '@trpc/client': 11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3) '@trpc/server': 11.5.1(typescript@5.7.3) @@ -2614,12 +2523,12 @@ snapshots: react-dom: 18.3.1(react@18.3.1) typescript: 5.7.3 optionalDependencies: - '@tanstack/react-query': 5.90.12(react@18.3.1) - '@trpc/react-query': 11.5.1(@tanstack/react-query@5.90.12(react@18.3.1))(@trpc/client@11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3))(@trpc/server@11.5.1(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3) + '@tanstack/react-query': 5.90.19(react@18.3.1) + '@trpc/react-query': 11.5.1(@tanstack/react-query@5.90.19(react@18.3.1))(@trpc/client@11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3))(@trpc/server@11.5.1(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3) - '@trpc/react-query@11.5.1(@tanstack/react-query@5.90.12(react@18.3.1))(@trpc/client@11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3))(@trpc/server@11.5.1(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)': + '@trpc/react-query@11.5.1(@tanstack/react-query@5.90.19(react@18.3.1))(@trpc/client@11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3))(@trpc/server@11.5.1(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)': dependencies: - '@tanstack/react-query': 5.90.12(react@18.3.1) + '@tanstack/react-query': 5.90.19(react@18.3.1) '@trpc/client': 11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3) '@trpc/server': 11.5.1(typescript@5.7.3) react: 18.3.1 @@ -2630,9 +2539,9 @@ snapshots: dependencies: typescript: 5.7.3 - '@trpc/tanstack-react-query@11.5.1(@tanstack/react-query@5.90.12(react@18.3.1))(@trpc/client@11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3))(@trpc/server@11.5.1(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)': + '@trpc/tanstack-react-query@11.5.1(@tanstack/react-query@5.90.19(react@18.3.1))(@trpc/client@11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3))(@trpc/server@11.5.1(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)': dependencies: - '@tanstack/react-query': 5.90.12(react@18.3.1) + '@tanstack/react-query': 5.90.19(react@18.3.1) '@trpc/client': 11.5.1(@trpc/server@11.5.1(typescript@5.7.3))(typescript@5.7.3) '@trpc/server': 11.5.1(typescript@5.7.3) react: 18.3.1 @@ -2660,44 +2569,39 @@ snapshots: dependencies: tslib: 2.8.1 - asn1js@3.0.7: - dependencies: - pvtsutils: 1.3.6 - pvutils: 1.1.5 - tslib: 2.8.1 - babel-plugin-react-compiler@1.0.0: dependencies: '@babel/types': 7.28.2 - better-auth@1.3.15(next@15.5.9(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + better-auth@1.4.15(next@15.5.9(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: + '@better-auth/core': 1.4.15(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.5))(jose@6.1.3)(kysely@0.28.10)(nanostores@1.1.0) + '@better-auth/telemetry': 1.4.15(@better-auth/core@1.4.15(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.5))(jose@6.1.3)(kysely@0.28.10)(nanostores@1.1.0)) '@better-auth/utils': 0.3.0 '@better-fetch/fetch': 1.1.21 '@noble/ciphers': 2.1.1 '@noble/hashes': 2.0.1 - '@simplewebauthn/browser': 13.2.2 - '@simplewebauthn/server': 13.2.2 - better-call: 1.0.19 + better-call: 1.1.8(zod@4.3.5) defu: 6.1.4 jose: 6.1.3 - kysely: 0.28.9 + kysely: 0.28.10 nanostores: 1.1.0 - zod: 4.2.1 + zod: 4.3.5 optionalDependencies: next: 15.5.9(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - better-call@1.0.19: + better-call@1.1.8(zod@4.3.5): dependencies: '@better-auth/utils': 0.3.0 '@better-fetch/fetch': 1.1.21 - rou3: 0.5.1 + rou3: 0.7.12 set-cookie-parser: 2.7.1 - uncrypto: 0.1.3 + optionalDependencies: + zod: 4.3.5 - caniuse-lite@1.0.30001759: {} + caniuse-lite@1.0.30001706: {} class-variance-authority@0.7.1: dependencies: @@ -2747,6 +2651,11 @@ snapshots: graceful-fs@4.2.11: {} + input-otp@1.4.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + is-what@4.1.16: {} jiti@2.4.2: {} @@ -2755,7 +2664,7 @@ snapshots: js-tokens@4.0.0: {} - kysely@0.28.9: {} + kysely@0.28.10: {} lightningcss-darwin-arm64@1.29.2: optional: true @@ -2825,7 +2734,7 @@ snapshots: dependencies: '@next/env': 15.5.9 '@swc/helpers': 0.5.15 - caniuse-lite: 1.0.30001759 + caniuse-lite: 1.0.30001706 postcss: 8.4.31 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -2867,12 +2776,6 @@ snapshots: clsx: 2.1.1 react: 18.3.1 - pvtsutils@1.3.6: - dependencies: - tslib: 2.8.1 - - pvutils@1.1.5: {} - react-dom@18.3.1(react@18.3.1): dependencies: loose-envify: 1.4.0 @@ -2914,9 +2817,7 @@ snapshots: dependencies: loose-envify: 1.4.0 - reflect-metadata@0.2.2: {} - - rou3@0.5.1: {} + rou3@0.7.12: {} scheduler@0.23.2: dependencies: @@ -2994,18 +2895,10 @@ snapshots: tapable@2.2.1: {} - tslib@1.14.1: {} - tslib@2.8.1: {} - tsyringe@4.10.0: - dependencies: - tslib: 1.14.1 - typescript@5.7.3: {} - uncrypto@0.1.3: {} - undici-types@6.19.8: {} use-callback-ref@1.3.3(@types/react@18.3.18)(react@18.3.1): @@ -3023,6 +2916,4 @@ snapshots: optionalDependencies: '@types/react': 18.3.18 - zod@3.24.2: {} - - zod@4.2.1: {} + zod@4.3.5: {} diff --git a/src/app/dashboard/(active)/account/page.tsx b/src/app/dashboard/(active)/account/page.tsx index 3c7a989..7ee6670 100644 --- a/src/app/dashboard/(active)/account/page.tsx +++ b/src/app/dashboard/(active)/account/page.tsx @@ -1,6 +1,8 @@ +import { CircleAlert, UserIcon } from "lucide-react" import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar" import { getInitials } from "@/lib/utils" import { getServerSession } from "@/server/auth" +import { SetName } from "./set-name" import { Telegram } from "./telegram" export default async function Account() { @@ -16,14 +18,24 @@ export default async function Account() {
{user.image && } - {getInitials(user.name)} + + {user.name ? getInitials(user.name) : } + -
-

{user.name}

-

{user.email}

-
-

Telegram:

+
+
+ {!user.name && } + Name: + {user.name ?

{user.name}

: } +
+ +
+ Email: +

{user.email}

+
+
+ Telegram:
diff --git a/src/app/dashboard/(active)/account/set-name.tsx b/src/app/dashboard/(active)/account/set-name.tsx new file mode 100644 index 0000000..70c6fb8 --- /dev/null +++ b/src/app/dashboard/(active)/account/set-name.tsx @@ -0,0 +1,66 @@ +"use client" + +import { useRouter } from "next/navigation" +import { type FormEvent, useState } from "react" +import { Button } from "@/components/ui/button" +import { + Dialog, + DialogClose, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog" +import { Input } from "@/components/ui/input" +import { Label } from "@/components/ui/label" +import { auth } from "@/lib/auth" + +export function SetName({ initialName }: { initialName?: string }) { + const router = useRouter() + const [name, setName] = useState(initialName ?? "") + const [open, setOpen] = useState(false) + + async function handleUpdate(e: FormEvent) { + e.preventDefault() + await auth.updateUser({ name }) + setOpen(false) + router.refresh() + } + + return ( + + + + + + + Set your name + Make changes to your profile here. Click save when you're done. + +
+
+
+ + setName(e.target.value)} + /> +
+
+ + + + + + +
+
+
+ ) +} diff --git a/src/app/dashboard/(active)/account/telegram.tsx b/src/app/dashboard/(active)/account/telegram.tsx index eb32aaa..f5261e1 100644 --- a/src/app/dashboard/(active)/account/telegram.tsx +++ b/src/app/dashboard/(active)/account/telegram.tsx @@ -20,7 +20,7 @@ function ShowTelegram({ username, userId }: { username: string; userId: number } <> @{username} {!isLoading && data?.roles?.length && ( - (roles: {data.roles.join(" ")}) + (roles: {data.roles.join(", ")}) )} ) diff --git a/src/app/dashboard/(active)/complete-profile.tsx b/src/app/dashboard/(active)/complete-profile.tsx new file mode 100644 index 0000000..8de2c3f --- /dev/null +++ b/src/app/dashboard/(active)/complete-profile.tsx @@ -0,0 +1,20 @@ +"use client" + +import type { User } from "better-auth" +import { UserRoundPenIcon } from "lucide-react" +import Link from "next/link" +import { Button } from "@/components/ui/button" + +export function CompleteProfile({ user }: { user: User }) { + return ( + !user.name && ( +
+ +

Your profile is incomplete, please enter the missing information.

+ + + +
+ ) + ) +} diff --git a/src/app/dashboard/(active)/page.tsx b/src/app/dashboard/(active)/page.tsx index a2c31d5..649e2de 100644 --- a/src/app/dashboard/(active)/page.tsx +++ b/src/app/dashboard/(active)/page.tsx @@ -1,10 +1,12 @@ import { getServerSession } from "@/server/auth" +import { CompleteProfile } from "./complete-profile" export default async function AdminHome() { - const session = await getServerSession() + const { data: session } = await getServerSession() return ( session && (
+

Home

) diff --git a/src/app/dashboard/layout.tsx b/src/app/dashboard/layout.tsx index ab88eec..f5e9888 100644 --- a/src/app/dashboard/layout.tsx +++ b/src/app/dashboard/layout.tsx @@ -1,6 +1,6 @@ import { redirect } from "next/navigation" -import { Header } from "@/components/header" import { SidebarProvider } from "@/components/ui/sidebar" +import { getQueryClient, trpc } from "@/lib/trpc/server" import { getServerSession } from "@/server/auth" export default async function AdminLayout({ children }: { children: React.ReactNode }) { @@ -8,10 +8,15 @@ export default async function AdminLayout({ children }: { children: React.ReactN // console.log(session) if (!session.data) redirect("/login") - return ( -
-
- {children} -
- ) + const tgId = session.data.user.telegramId + if (!tgId) redirect("/onboarding/link") + // if (session?.user.role === USER_ROLE.INACTIVE) ; + // if (session?.user.role === USER_ROLE.DISABLED) redirect("/dashboard/disabled"); + + const qc = getQueryClient() + const { roles } = await qc.fetchQuery(trpc.tg.permissions.getRoles.queryOptions({ userId: tgId })) + if (!roles || roles.length === 0) redirect("/onboarding/no-role") + if (roles.includes("creator")) redirect("/onboarding/unauthorized") + + return {children} } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 24266fb..985c474 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,7 +1,7 @@ import { GeistSans } from "geist/font/sans" import type { Metadata } from "next" import "@/index.css" -import { HEADER_HEIGHT } from "@/components/header" +import { HEADER_HEIGHT, Header } from "@/components/header" import { ThemeProvider } from "@/components/theme-provider" import { Toaster } from "@/components/ui/sonner" import { TooltipProvider } from "@/components/ui/tooltip" @@ -37,8 +37,13 @@ export default function RootLayout({ children }: Readonly<{ children: React.Reac disableTransitionOnChange > - {children} - + +
+
+ {children} +
+
+
diff --git a/src/app/login/can-i-access.tsx b/src/app/login/can-i-access.tsx index 2d19242..c95bc4c 100644 --- a/src/app/login/can-i-access.tsx +++ b/src/app/login/can-i-access.tsx @@ -34,8 +34,8 @@ export function CanIAccess() { className="place-self-center justify-self-center" />
-

1. Login with GitHub

-

(provider might change)

+

1. Login with email

+

We send an OTP to your email

@@ -49,7 +49,7 @@ export function CanIAccess() { className="place-self-center justify-self-center" />
-

2. Link your Telegram account

+

2. Link your Telegram account

This allows to verify your role

diff --git a/src/app/login/layout.tsx b/src/app/login/layout.tsx deleted file mode 100644 index 1dbd119..0000000 --- a/src/app/login/layout.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { Header } from "@/components/header" - -export default function Layout({ children }: { children: React.ReactNode }) { - return ( -
-
- {children} -
- ) -} diff --git a/src/app/login/github.tsx b/src/app/login/login-button.tsx similarity index 51% rename from src/app/login/github.tsx rename to src/app/login/login-button.tsx index cd49106..51c6226 100644 --- a/src/app/login/github.tsx +++ b/src/app/login/login-button.tsx @@ -1,36 +1,18 @@ "use client" import { LogInIcon } from "lucide-react" -import Image from "next/image" +import Link from "next/link" import { Card, CardContent } from "@/components/ui/card" -import { signIn } from "@/lib/auth" -export function Github({ callbackURL }: { callbackURL: string }) { +export function LoginButton() { return ( - + ) } diff --git a/src/app/login/login-form.tsx b/src/app/login/login-form.tsx new file mode 100644 index 0000000..aae38a4 --- /dev/null +++ b/src/app/login/login-form.tsx @@ -0,0 +1,176 @@ +"use client" + +import { Loader2 } from "lucide-react" +import { useRouter } from "next/navigation" +import { useState } from "react" +import { toast } from "sonner" +import { Button } from "@/components/ui/button" +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" +import { Input } from "@/components/ui/input" +import { InputOTP, InputOTPGroup, InputOTPSlot } from "@/components/ui/input-otp" +import { Label } from "@/components/ui/label" +import { auth } from "@/lib/auth" + +export default function LoginForm() { + const [email, setEmail] = useState("") + const [sent, setSent] = useState(false) + + return ( +
+ {!sent ? ( + setEmail(v)} onSend={() => setSent(true)} /> + ) : ( + + )} +
+ ) +} + +function EmailCard({ + email, + onChange, + onSend, +}: { + email: string + onChange: (value: string) => void + onSend: () => void +}) { + const [loading, setLoading] = useState(false) + + async function sendOtp() { + const { data, error } = await auth.emailOtp.sendVerificationOtp({ + type: "sign-in", + email, + fetchOptions: { + onRequest: () => { + setLoading(true) + }, + onResponse: () => { + setLoading(false) + }, + }, + }) + + if (data?.success) { + onSend() + toast.success("OTP sent via email!") + return + } + + toast.error("There was an unexpected error") + console.error({ error }) + } + + return ( + + + Sign In + + Enter your email below to login to your account + + + +
{ + e.preventDefault() + await sendOtp() + }} + > +
+ + { + onChange(e.target.value) + }} + value={email} + /> +
+ +
+
+
+ ) +} + +function OTPCard({ email }: { email: string }) { + const router = useRouter() + const [loading, setLoading] = useState(false) + const [otp, setOtp] = useState("") + + async function verifyOtp() { + const { data, error } = await auth.signIn.emailOtp({ + email, + otp, + fetchOptions: { + onRequest: () => { + setLoading(true) + }, + onResponse: () => { + setLoading(false) + }, + }, + }) + + if (data) { + toast.success("Successfully logged in!") + return router.replace("/dashboard") + } + + if (error.code === "INVALID_OTP") toast.error("You entered an invalid OTP") + else { + toast.error("There was an unexpected error") + console.error({ error }) + } + } + return ( + + + Sign In + Enter the OTP we sent to your email + + +
{ + e.preventDefault() + await verifyOtp() + }} + > +
+ + setOtp(v)} + autoComplete="off" + data-1p-ignore + data-lpignore="true" + data-protonpass-ignore="true" + type="text" + > + + + + + + + + + +
+ +
+
+
+ ) +} diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx index 3f1c260..e701bc7 100644 --- a/src/app/login/page.tsx +++ b/src/app/login/page.tsx @@ -1,22 +1,14 @@ import { redirect } from "next/navigation" -import { getBaseUrl } from "@/lib/utils" import { getServerSession } from "@/server/auth" -import { CanIAccess } from "./can-i-access" -import { Github } from "./github" -import { WhatIs } from "./what-is" +import LoginForm from "./login-form" -export default async function SignInPage({ searchParams }: { searchParams: Promise<{ callbackUrl?: string }> }) { - const { callbackUrl } = await searchParams - const callbackURL = `${getBaseUrl()}${callbackUrl ?? "/login/success"}` - - const session = await getServerSession() - if (session.data?.user) redirect("/login/success") +export default async function Page() { + const { data: session } = await getServerSession() + if (session) return redirect("/dashboard") return ( -
- - - +
+
) } diff --git a/src/app/login/success/page.tsx b/src/app/login/success/page.tsx deleted file mode 100644 index 6a98518..0000000 --- a/src/app/login/success/page.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { redirect } from "next/navigation" -import { getQueryClient, trpc } from "@/lib/trpc/server" -import { getServerSession } from "@/server/auth" - -export default async function LoginSuccess() { - const session = await getServerSession() - if (!session.data) redirect("/login") - - const tgId = session.data.user.telegramId - if (!tgId) redirect("/onboarding/link") - // if (session?.user.role === USER_ROLE.INACTIVE) ; - // if (session?.user.role === USER_ROLE.DISABLED) redirect("/dashboard/disabled"); - - const qc = getQueryClient() - const { roles } = await qc.fetchQuery(trpc.tg.permissions.getRoles.queryOptions({ userId: tgId })) - if (!roles || roles.length === 0) redirect("/onboarding/no-role") - if (roles.includes("creator")) redirect("/onboarding/unauthorized") - return redirect("/dashboard") -} diff --git a/src/app/onboarding/layout.tsx b/src/app/onboarding/layout.tsx index 1dbd119..baf33f4 100644 --- a/src/app/onboarding/layout.tsx +++ b/src/app/onboarding/layout.tsx @@ -1,9 +1,6 @@ -import { Header } from "@/components/header" - export default function Layout({ children }: { children: React.ReactNode }) { return (
-
{children}
) diff --git a/src/app/onboarding/link/logout.tsx b/src/app/onboarding/link/logout.tsx new file mode 100644 index 0000000..8cca84f --- /dev/null +++ b/src/app/onboarding/link/logout.tsx @@ -0,0 +1,32 @@ +"use client" + +import { useRouter } from "next/navigation" +import { toast } from "sonner" +import { auth } from "../../../lib/auth" + +export function Logout({ email }: { email: string }) { + const router = useRouter() + + async function handleLogout() { + const { data, error } = await auth.signOut() + if (data?.success || !error) { + toast.success("Successfully logged out") + return router.replace("/") + } + + toast.error("There was an unexpected error") + console.error({ error }) + } + + return ( +
+

+ Logged in as {email} +

+ Wrong account?{" "} + +
+ ) +} diff --git a/src/app/onboarding/link/page.tsx b/src/app/onboarding/link/page.tsx index 3ecddad..64cf606 100644 --- a/src/app/onboarding/link/page.tsx +++ b/src/app/onboarding/link/page.tsx @@ -4,13 +4,14 @@ import loginSvg2 from "@/assets/svg/login-2.svg" import { Card } from "@/components/ui/card" import { env } from "@/env" import { getServerSession } from "@/server/auth" +import { Logout } from "./logout" import { TelegramLink } from "./telegram" const BOT_USERNAME = env.NODE_ENV === "production" ? "pn_ts_dev_bot" : "pn_ts_devlocal_bot" export default async function OnboardingLink() { - const { data } = await getServerSession() - if (data?.user.telegramId) redirect("/login/success") + const { data: session } = await getServerSession() + if (!session || session.user.telegramId) redirect("/dashboard") return (
@@ -29,6 +30,8 @@ export default async function OnboardingLink() {

+
+ ) diff --git a/src/app/onboarding/link/telegram.tsx b/src/app/onboarding/link/telegram.tsx index d22526f..2d97f5a 100644 --- a/src/app/onboarding/link/telegram.tsx +++ b/src/app/onboarding/link/telegram.tsx @@ -34,11 +34,11 @@ export function TelegramLink({ botUsername }: { botUsername: string }) { const handleComplete = useCallback(() => { setSuccess(true) - refetch() + void refetch() remove() setTimeout(() => { - router.push("/login/success") + router.push("/dashboard") }, 5000) }, [router, refetch, remove]) @@ -51,8 +51,7 @@ export function TelegramLink({ botUsername }: { botUsername: string }) { }) if (res.error) return console.error("custom error", res.error) - if (res.data instanceof APIError) return console.error("better-auth APIError", res.data) - if (!("code" in res.data) || !("ttl" in res.data)) return console.error("unexpected response", res.data) + setExpired(false) update({ code: res.data.code, diff --git a/src/app/onboarding/no-role/page.tsx b/src/app/onboarding/no-role/page.tsx new file mode 100644 index 0000000..c890e55 --- /dev/null +++ b/src/app/onboarding/no-role/page.tsx @@ -0,0 +1,39 @@ +import Image from "next/image" +import { redirect } from "next/navigation" +import loginSvg2 from "@/assets/svg/login-2.svg" +import { Card } from "@/components/ui/card" +import { getQueryClient, trpc } from "@/lib/trpc/server" +import { getServerSession } from "@/server/auth" +import { Logout } from "../link/logout" + +export default async function OnboardingNoRole() { + const { data: session } = await getServerSession() + if (!session) redirect("/login") + if (!session.user.telegramId) redirect("/onboarding/link") + + const qc = getQueryClient() + const { roles } = await qc.fetchQuery(trpc.tg.permissions.getRoles.queryOptions({ userId: session.user.telegramId })) + if (roles?.includes("creator")) redirect("/onboarding/unauthorized") + if (roles && roles.length > 0) redirect("/dashboard") + + return ( +
+ +
+ insert credentials +
+

Your account is not enabled

+

Please contact an IT member

+
+
+ + +
+
+ ) +} diff --git a/src/app/page.tsx b/src/app/page.tsx index 272d077..eda2643 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,5 +1,18 @@ import { redirect } from "next/navigation" +import { getServerSession } from "@/server/auth" +import { CanIAccess } from "./login/can-i-access" +import { LoginButton } from "./login/login-button" +import { WhatIs } from "./login/what-is" export default async function IndexPage() { - return redirect("/login") + const session = await getServerSession() + if (session.data?.user) redirect("/dashboard") + + return ( +
+ + + +
+ ) } diff --git a/src/components/header.tsx b/src/components/header.tsx index 377d038..47c5bb0 100644 --- a/src/components/header.tsx +++ b/src/components/header.tsx @@ -11,7 +11,7 @@ export async function Header() { return (
- +
@@ -30,9 +27,11 @@ export function NavUser({ user }: { user: User }) { size="lg" className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground cursor-pointer" > - + - {getInitials(user.name)} + + {user.name ? getInitials(user.name) : } +
{user.name} @@ -43,23 +42,10 @@ export function NavUser({ user }: { user: User }) { - -
- - - {getInitials(user.name)} - -
- {user.name} - {user.email} -
-
-
- @@ -67,23 +53,17 @@ export function NavUser({ user }: { user: User }) { Account - {/* - - - Notifications + { + await signOut() + router.replace("/login") + }} + > + + Log out - */} - - { - await signOut() - redirect("/login") - }} - > - - Log out -
diff --git a/src/components/ui/alert.tsx b/src/components/ui/alert.tsx index 95d41e5..62a69c3 100644 --- a/src/components/ui/alert.tsx +++ b/src/components/ui/alert.tsx @@ -1,26 +1,23 @@ -import * as React from "react"; -import { cva, type VariantProps } from "class-variance-authority"; +import * as React from "react" +import { cva, type VariantProps } from "class-variance-authority" -import { cn } from "@/lib/utils"; +import { cn } from "@/lib/utils" const alertVariants = cva( - "relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7", + "relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground", { variants: { variant: { - default: "bg-background text-foreground", + default: "bg-sidebar text-foreground", destructive: "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive", - warning: - "bg-amber-300/20 text-amber-600 [&>svg]:text-amber-600 border-amber-600/50 dark:border-amber-300/50 dark:text-amber-300 dark:[&>svg]:text-amber-300", - info: "bg-blue-300/20 text-blue-600 [&>svg]:text-blue-600 border-blue-600/50 dark:border-blue-300/50 dark:bg-blue-900/30 dark:text-blue-300 dark:[&>svg]:text-blue-300", }, }, defaultVariants: { variant: "default", }, - }, -); + } +) const Alert = React.forwardRef< HTMLDivElement, @@ -32,8 +29,8 @@ const Alert = React.forwardRef< className={cn(alertVariants({ variant }), className)} {...props} /> -)); -Alert.displayName = "Alert"; +)) +Alert.displayName = "Alert" const AlertTitle = React.forwardRef< HTMLParagraphElement, @@ -41,14 +38,11 @@ const AlertTitle = React.forwardRef< >(({ className, ...props }, ref) => (
-)); -AlertTitle.displayName = "AlertTitle"; +)) +AlertTitle.displayName = "AlertTitle" const AlertDescription = React.forwardRef< HTMLParagraphElement, @@ -59,7 +53,7 @@ const AlertDescription = React.forwardRef< className={cn("text-sm [&_p]:leading-relaxed", className)} {...props} /> -)); -AlertDescription.displayName = "AlertDescription"; +)) +AlertDescription.displayName = "AlertDescription" -export { Alert, AlertTitle, AlertDescription }; +export { Alert, AlertTitle, AlertDescription } diff --git a/src/components/ui/dropdown-menu.tsx b/src/components/ui/dropdown-menu.tsx index 2078c54..028b1f5 100644 --- a/src/components/ui/dropdown-menu.tsx +++ b/src/components/ui/dropdown-menu.tsx @@ -163,7 +163,7 @@ const DropdownMenuSeparator = React.forwardRef< >(({ className, ...props }, ref) => ( )); diff --git a/src/components/ui/input-otp.tsx b/src/components/ui/input-otp.tsx new file mode 100644 index 0000000..1580a9c --- /dev/null +++ b/src/components/ui/input-otp.tsx @@ -0,0 +1,71 @@ +"use client"; + +import * as React from "react"; +import { OTPInput, OTPInputContext } from "input-otp"; +import { Dot } from "lucide-react"; + +import { cn } from "@/lib/utils"; + +const InputOTP = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, containerClassName, ...props }, ref) => ( + +)); +InputOTP.displayName = "InputOTP"; + +const InputOTPGroup = React.forwardRef< + React.ElementRef<"div">, + React.ComponentPropsWithoutRef<"div"> +>(({ className, ...props }, ref) => ( +
+)); +InputOTPGroup.displayName = "InputOTPGroup"; + +const InputOTPSlot = React.forwardRef< + React.ElementRef<"div">, + React.ComponentPropsWithoutRef<"div"> & { index: number } +>(({ index, className, ...props }, ref) => { + const inputOTPContext = React.useContext(OTPInputContext); + const { char, hasFakeCaret, isActive } = inputOTPContext.slots[index]!; + + return ( +
+ {char} + {hasFakeCaret && ( +
+
+
+ )} +
+ ); +}); +InputOTPSlot.displayName = "InputOTPSlot"; + +const InputOTPSeparator = React.forwardRef< + React.ElementRef<"div">, + React.ComponentPropsWithoutRef<"div"> +>(({ ...props }, ref) => ( +
+ +
+)); +InputOTPSeparator.displayName = "InputOTPSeparator"; + +export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator }; diff --git a/src/components/ui/sidebar.tsx b/src/components/ui/sidebar.tsx index 870909e..050e3d5 100644 --- a/src/components/ui/sidebar.tsx +++ b/src/components/ui/sidebar.tsx @@ -469,7 +469,7 @@ const SidebarGroupAction = React.forwardRef< ref={ref} data-sidebar="group-action" className={cn( - "text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0", + "text-sidebar-foreground ring-sidebar-ring hover:bg-accent/40 hover:text-sidebar-accent-foreground absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0", // Increases the hit area of the button on mobile. "after:absolute after:-inset-2 md:after:hidden", "group-data-[collapsible=icon]:hidden", @@ -521,13 +521,13 @@ const SidebarMenuItem = React.forwardRef< SidebarMenuItem.displayName = "SidebarMenuItem"; const sidebarMenuButtonVariants = cva( - "peer/menu-button cursor-pointer flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0", + "peer/menu-button cursor-pointer flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] hover:bg-accent/40 hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0", { variants: { variant: { - default: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground", + default: "hover:bg-accent/40 hover:text-sidebar-accent-foreground", outline: - "bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]", + "bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-accent/40 hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]", }, size: { default: "h-8 text-sm", @@ -615,7 +615,7 @@ const SidebarMenuAction = React.forwardRef< ref={ref} data-sidebar="menu-action" className={cn( - "text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground peer-hover/menu-button:text-sidebar-accent-foreground absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0", + "text-sidebar-foreground ring-sidebar-ring hover:bg-accent/40 hover:text-sidebar-accent-foreground peer-hover/menu-button:text-sidebar-accent-foreground absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0", // Increases the hit area of the button on mobile. "after:absolute after:-inset-2 md:after:hidden", "peer-data-[size=sm]/menu-button:top-1", @@ -731,7 +731,7 @@ const SidebarMenuSubButton = React.forwardRef< data-size={size} data-active={isActive} className={cn( - "text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 outline-hidden focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0", + "text-sidebar-foreground ring-sidebar-ring hover:bg-accent/40 hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 outline-hidden focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0", "data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground", size === "sm" && "text-xs", size === "md" && "text-sm", diff --git a/src/components/user-card.tsx b/src/components/user-card.tsx index f0f4e29..4210b26 100644 --- a/src/components/user-card.tsx +++ b/src/components/user-card.tsx @@ -1,6 +1,6 @@ "use client" import type { User } from "better-auth" -import { type LucideIcon, XIcon } from "lucide-react" +import { type LucideIcon, UserIcon, XIcon } from "lucide-react" import { useTransition } from "react" import { getInitials } from "@/lib/utils" import { Avatar, AvatarFallback, AvatarImage } from "./ui/avatar" @@ -19,7 +19,7 @@ export function UserCard({ user, icon: Icon = XIcon, buttonAction }: Props) {
{user.image && } - {getInitials(user.name)} + {user.name ? getInitials(user.name) : }

{user.name}

{user.email}

diff --git a/src/lib/auth.ts b/src/lib/auth.ts index 0bec6c5..bac714a 100644 --- a/src/lib/auth.ts +++ b/src/lib/auth.ts @@ -1,5 +1,7 @@ import { AUTH_PATH, type TelegramPlugin } from "@polinetwork/backend" import type { BetterAuthClientPlugin } from "better-auth" +import { emailOTPClient } from "better-auth/client/plugins" +import { nextCookies } from "better-auth/next-js" import { createAuthClient } from "better-auth/react" import { getBaseUrl } from "./utils" @@ -13,7 +15,7 @@ const telegramPlugin = () => { export const auth = createAuthClient({ baseURL: getBaseUrl(), basePath: AUTH_PATH, - plugins: [telegramPlugin()], + plugins: [telegramPlugin(), emailOTPClient(), nextCookies()], }) export const { signIn, signOut, getSession, useSession } = auth diff --git a/src/lib/trpc/client.tsx b/src/lib/trpc/client.tsx index dea0d35..c4d0ba1 100644 --- a/src/lib/trpc/client.tsx +++ b/src/lib/trpc/client.tsx @@ -6,7 +6,7 @@ import { QueryClientProvider } from "@tanstack/react-query" import { createTRPCClient, httpBatchLink } from "@trpc/client" import { createTRPCContext } from "@trpc/tanstack-react-query" import { useState } from "react" -import superjson from "superjson" +import SuperJSON from "superjson" import { getBaseUrl } from "../utils" import { makeQueryClient } from "./query-client" export const { TRPCProvider, useTRPC } = createTRPCContext() @@ -40,8 +40,8 @@ export function TRPCReactProvider( createTRPCClient({ links: [ httpBatchLink({ - transformer: superjson, url, + transformer: SuperJSON, }), ], })