From d8a75383ab25f967381a5b643f8ac9829bec745d Mon Sep 17 00:00:00 2001 From: Innei Date: Thu, 15 Jun 2023 20:16:11 +0800 Subject: [PATCH] feat: support clerk Signed-off-by: Innei --- .env.template | 10 + next.config.mjs | 2 +- package.json | 1 + pnpm-lock.yaml | 420 ++++++++++- src/app.config.ts | 8 + src/app/error.tsx | 2 +- src/app/global-error.tsx | 2 +- src/app/layout.tsx | 29 +- src/app/page.tsx | 4 +- src/app/sign-in/[[...sign-in]]/page.tsx | 7 + src/app/sign-up/[[...sign-up]]/page.tsx | 7 + src/components/icons/user-arrow-left.tsx | 22 + src/components/layout/header/Header.tsx | 41 +- src/components/layout/header/UserAuth.tsx | 62 ++ .../ui/float-popover/FloatPopover.tsx | 11 +- src/i18n/cherk-cn.ts | 655 ++++++++++++++++++ src/styles/clerk.css | 209 ++++++ src/styles/index.css | 1 + tailwind.config.ts | 2 +- 19 files changed, 1425 insertions(+), 70 deletions(-) create mode 100644 src/app.config.ts create mode 100644 src/app/sign-in/[[...sign-in]]/page.tsx create mode 100644 src/app/sign-up/[[...sign-up]]/page.tsx create mode 100644 src/components/icons/user-arrow-left.tsx create mode 100644 src/components/layout/header/UserAuth.tsx create mode 100644 src/i18n/cherk-cn.ts create mode 100644 src/styles/clerk.css diff --git a/.env.template b/.env.template index 9e5ce44660..79dbd72284 100644 --- a/.env.template +++ b/.env.template @@ -4,3 +4,13 @@ NEXT_PUBLIC_GATEWAY_URL=http://127.0.0.1:2333/ # NEXT_PUBLIC_GATEWAY_URL=http://192.168.31.195:2333 NEXT_PUBLIC_API_URL=https://innei.ren/api/v2 NEXT_PUBLIC_GATEWAY_URL=https://api.innei.ren + +NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_cmVzb2x2ZWQtd2FydGhvZy0yNC5jbGVyay5hY2NvdW50cy5kZXYk + +## Clerk +CLERK_SECRET_KEY=sk_test_***********8 + +NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in +NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up +NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/ +NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/ diff --git a/next.config.mjs b/next.config.mjs index 3ea1f7dffe..59b8f7fa68 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -59,7 +59,7 @@ let nextConfig = { }, } -if (process.env.SENTRY === 'true' && isProd) { +if (env.SENTRY === 'true' && isProd) { // @ts-expect-error nextConfig = withSentryConfig( nextConfig, diff --git a/package.json b/package.json index 0b77fd9b24..1653aa563c 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "last 2 Firefox versions" ], "dependencies": { + "@clerk/nextjs": "4.21.1", "@floating-ui/react-dom": "2.0.1", "@formkit/auto-animate": "1.0.0-beta.6", "@headlessui/react": "1.7.15", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a76748faf1..d19c10c544 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,6 +5,9 @@ settings: excludeLinksFromLockfile: false dependencies: + '@clerk/nextjs': + specifier: 4.21.1 + version: 4.21.1(next@13.4.5)(react-dom@18.2.0)(react@18.2.0) '@floating-ui/react-dom': specifier: 2.0.1 version: 2.0.1(react-dom@18.2.0)(react@18.2.0) @@ -82,7 +85,7 @@ dependencies: version: 6.1.1 next: specifier: 13.4.5 - version: 13.4.5(@babel/core@7.22.5)(react-dom@18.2.0)(react@18.2.0) + version: 13.4.5(@babel/core@7.21.0)(react-dom@18.2.0)(react@18.2.0) next-themes: specifier: 0.2.1 version: 0.2.1(next@13.4.5)(react-dom@18.2.0)(react@18.2.0) @@ -317,7 +320,6 @@ packages: dependencies: '@jridgewell/gen-mapping': 0.1.1 '@jridgewell/trace-mapping': 0.3.17 - dev: true /@ampproject/remapping@2.2.1: resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} @@ -325,28 +327,29 @@ packages: dependencies: '@jridgewell/gen-mapping': 0.3.3 '@jridgewell/trace-mapping': 0.3.18 + dev: true /@babel/code-frame@7.21.4: resolution: {integrity: sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==} engines: {node: '>=6.9.0'} dependencies: '@babel/highlight': 7.18.6 - dev: true /@babel/code-frame@7.22.5: resolution: {integrity: sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==} engines: {node: '>=6.9.0'} dependencies: '@babel/highlight': 7.22.5 + dev: true /@babel/compat-data@7.21.7: resolution: {integrity: sha512-KYMqFYTaenzMK4yUtf4EW9wc4N9ef80FsbMtkwool5zpwl4YrT1SdWYSTRcT94KO4hannogdS+LxY7L+arP3gA==} engines: {node: '>=6.9.0'} - dev: true /@babel/compat-data@7.22.5: resolution: {integrity: sha512-4Jc/YuIaYqKnDDz892kPIledykKg12Aw1PYX5i/TY28anJtacvM1Rrr8wbieB9GfEJwlzqT0hUEao0CxEebiDA==} engines: {node: '>=6.9.0'} + dev: true /@babel/core@7.21.0: resolution: {integrity: sha512-PuxUbxcW6ZYe656yL3EAhpy7qXKq0DmYsrJLpbB8XrsCP9Nm+XCg9XFMb5vIDliPD7+U/+M+QJlH17XOcB7eXA==} @@ -369,7 +372,6 @@ packages: semver: 6.3.0 transitivePeerDependencies: - supports-color - dev: true /@babel/core@7.22.5: resolution: {integrity: sha512-SBuTAjg91A3eKOvD+bPEz3LlhHZRNu1nFOVts9lzDJTXshHTjII0BAtDS3Y2DAkdZdDKWVZGVwkDfc4Clxn1dg==} @@ -392,6 +394,7 @@ packages: semver: 6.3.0 transitivePeerDependencies: - supports-color + dev: true /@babel/generator@7.21.1: resolution: {integrity: sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA==} @@ -411,7 +414,6 @@ packages: '@jridgewell/gen-mapping': 0.3.2 '@jridgewell/trace-mapping': 0.3.17 jsesc: 2.5.2 - dev: true /@babel/generator@7.22.5: resolution: {integrity: sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA==} @@ -421,6 +423,7 @@ packages: '@jridgewell/gen-mapping': 0.3.3 '@jridgewell/trace-mapping': 0.3.18 jsesc: 2.5.2 + dev: true /@babel/helper-annotate-as-pure@7.18.6: resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==} @@ -441,7 +444,6 @@ packages: browserslist: 4.21.7 lru-cache: 5.1.1 semver: 6.3.0 - dev: true /@babel/helper-compilation-targets@7.22.5(@babel/core@7.22.5): resolution: {integrity: sha512-Ji+ywpHeuqxB8WDxraCiqR0xfhYjiDE/e6k7FuIaANnoOFxAHskHChz4vA1mJC9Lbm01s1PVAGhQY4FUKSkGZw==} @@ -455,6 +457,7 @@ packages: browserslist: 4.21.7 lru-cache: 5.1.1 semver: 6.3.0 + dev: true /@babel/helper-create-class-features-plugin@7.21.0(@babel/core@7.21.0): resolution: {integrity: sha512-Q8wNiMIdwsv5la5SPxNYzzkPnjgC0Sy0i7jLkVOCdllu/xcVNkr3TeZzbHBJrj+XXRqzX5uCyCoV9eu6xUG7KQ==} @@ -478,11 +481,11 @@ packages: /@babel/helper-environment-visitor@7.21.5: resolution: {integrity: sha512-IYl4gZ3ETsWocUWgsFZLM5i1BYx9SoemminVEXadgLBa9TdeorzgLKm8wWLA6J1N/kT3Kch8XIk1laNzYoHKvQ==} engines: {node: '>=6.9.0'} - dev: true /@babel/helper-environment-visitor@7.22.5: resolution: {integrity: sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==} engines: {node: '>=6.9.0'} + dev: true /@babel/helper-function-name@7.21.0: resolution: {integrity: sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==} @@ -490,7 +493,6 @@ packages: dependencies: '@babel/template': 7.20.7 '@babel/types': 7.21.5 - dev: true /@babel/helper-function-name@7.22.5: resolution: {integrity: sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==} @@ -498,19 +500,20 @@ packages: dependencies: '@babel/template': 7.22.5 '@babel/types': 7.22.5 + dev: true /@babel/helper-hoist-variables@7.18.6: resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.21.5 - dev: true /@babel/helper-hoist-variables@7.22.5: resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.22.5 + dev: true /@babel/helper-member-expression-to-functions@7.21.0: resolution: {integrity: sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q==} @@ -524,13 +527,13 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.21.5 - dev: true /@babel/helper-module-imports@7.22.5: resolution: {integrity: sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.22.5 + dev: true /@babel/helper-module-transforms@7.21.5: resolution: {integrity: sha512-bI2Z9zBGY2q5yMHoBvJ2a9iX3ZOAzJPm7Q8Yz6YeoUjU/Cvhmi2G4QyTNyPBqqXSgTjUxRg3L0xV45HvkNWWBw==} @@ -546,7 +549,6 @@ packages: '@babel/types': 7.21.5 transitivePeerDependencies: - supports-color - dev: true /@babel/helper-module-transforms@7.22.5: resolution: {integrity: sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw==} @@ -562,6 +564,7 @@ packages: '@babel/types': 7.22.5 transitivePeerDependencies: - supports-color + dev: true /@babel/helper-optimise-call-expression@7.18.6: resolution: {integrity: sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==} @@ -594,13 +597,13 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.21.5 - dev: true /@babel/helper-simple-access@7.22.5: resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.22.5 + dev: true /@babel/helper-skip-transparent-expression-wrappers@7.20.0: resolution: {integrity: sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==} @@ -614,40 +617,40 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.21.5 - dev: true /@babel/helper-split-export-declaration@7.22.5: resolution: {integrity: sha512-thqK5QFghPKWLhAV321lxF95yCg2K3Ob5yw+M3VHWfdia0IkPXUtoLH8x/6Fh486QUvzhb8YOWHChTVen2/PoQ==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.22.5 + dev: true /@babel/helper-string-parser@7.21.5: resolution: {integrity: sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==} engines: {node: '>=6.9.0'} - dev: true /@babel/helper-string-parser@7.22.5: resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} engines: {node: '>=6.9.0'} + dev: true /@babel/helper-validator-identifier@7.19.1: resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} engines: {node: '>=6.9.0'} - dev: true /@babel/helper-validator-identifier@7.22.5: resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==} engines: {node: '>=6.9.0'} + dev: true /@babel/helper-validator-option@7.21.0: resolution: {integrity: sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==} engines: {node: '>=6.9.0'} - dev: true /@babel/helper-validator-option@7.22.5: resolution: {integrity: sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==} engines: {node: '>=6.9.0'} + dev: true /@babel/helpers@7.21.5: resolution: {integrity: sha512-BSY+JSlHxOmGsPTydUkPf1MdMQ3M81x5xGCOVgWM3G8XH77sJ292Y2oqcp0CbbgxhqBuI46iUz1tT7hqP7EfgA==} @@ -658,7 +661,6 @@ packages: '@babel/types': 7.21.5 transitivePeerDependencies: - supports-color - dev: true /@babel/helpers@7.22.5: resolution: {integrity: sha512-pSXRmfE1vzcUIDFQcSGA5Mr+GxBV9oiRKDuDxXvWQQBCh8HoIjs/2DlDB7H8smac1IVrB9/xdXj2N3Wol9Cr+Q==} @@ -669,6 +671,7 @@ packages: '@babel/types': 7.22.5 transitivePeerDependencies: - supports-color + dev: true /@babel/highlight@7.18.6: resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} @@ -677,7 +680,6 @@ packages: '@babel/helper-validator-identifier': 7.19.1 chalk: 2.4.2 js-tokens: 4.0.0 - dev: true /@babel/highlight@7.22.5: resolution: {integrity: sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==} @@ -686,6 +688,7 @@ packages: '@babel/helper-validator-identifier': 7.22.5 chalk: 2.4.2 js-tokens: 4.0.0 + dev: true /@babel/parser@7.21.8: resolution: {integrity: sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA==} @@ -693,7 +696,6 @@ packages: hasBin: true dependencies: '@babel/types': 7.21.5 - dev: true /@babel/parser@7.22.5: resolution: {integrity: sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==} @@ -701,6 +703,7 @@ packages: hasBin: true dependencies: '@babel/types': 7.22.5 + dev: true /@babel/plugin-syntax-jsx@7.18.6(@babel/core@7.21.0): resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==} @@ -773,7 +776,6 @@ packages: '@babel/code-frame': 7.21.4 '@babel/parser': 7.21.8 '@babel/types': 7.21.5 - dev: true /@babel/template@7.22.5: resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==} @@ -782,6 +784,7 @@ packages: '@babel/code-frame': 7.22.5 '@babel/parser': 7.22.5 '@babel/types': 7.22.5 + dev: true /@babel/traverse@7.21.5: resolution: {integrity: sha512-AhQoI3YjWi6u/y/ntv7k48mcrCXmus0t79J9qPNlk/lAsFlCiJ047RmbfMOawySTHtywXhbXgpx/8nXMYd+oFw==} @@ -799,7 +802,6 @@ packages: globals: 11.12.0 transitivePeerDependencies: - supports-color - dev: true /@babel/traverse@7.22.5: resolution: {integrity: sha512-7DuIjPgERaNo6r+PZwItpjCZEa5vyw4eJGufeLxrPdBXBoLcCJCIasvK6pK/9DVNrLZTLFhUGqaC6X/PA007TQ==} @@ -817,6 +819,7 @@ packages: globals: 11.12.0 transitivePeerDependencies: - supports-color + dev: true /@babel/types@7.21.5: resolution: {integrity: sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q==} @@ -825,7 +828,6 @@ packages: '@babel/helper-string-parser': 7.21.5 '@babel/helper-validator-identifier': 7.19.1 to-fast-properties: 2.0.0 - dev: true /@babel/types@7.22.5: resolution: {integrity: sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==} @@ -834,6 +836,85 @@ packages: '@babel/helper-string-parser': 7.22.5 '@babel/helper-validator-identifier': 7.22.5 to-fast-properties: 2.0.0 + dev: true + + /@clerk/backend@0.23.0: + resolution: {integrity: sha512-2s8tRAL9nB+aQQUofrFCDGlz2Kv7pP+lR5CvQdMKTL9nPTlUBcvYFinjO3s6q3A7dwSk81erLKwYEXZEKA8R1w==} + engines: {node: '>=14'} + dependencies: + '@clerk/types': 3.42.0 + '@peculiar/webcrypto': 1.4.1 + '@types/node': 16.18.6 + deepmerge: 4.2.2 + node-fetch-native: 1.0.1 + snakecase-keys: 5.4.4 + tslib: 2.4.1 + dev: false + + /@clerk/clerk-react@4.20.0(react@18.2.0): + resolution: {integrity: sha512-3KiDycTHv+KzqS/If1un9dzJ5nrV32VPPVmNntjjZIWJDO7aJGy5v0+LiatSKMQbXGMVxuOmtZKHe3X7xkg+6g==} + engines: {node: '>=14'} + peerDependencies: + react: '>=16' + dependencies: + '@clerk/shared': 0.19.0(react@18.2.0) + '@clerk/types': 3.42.0 + react: 18.2.0 + swr: 1.3.0(react@18.2.0) + tslib: 2.4.1 + dev: false + + /@clerk/clerk-sdk-node@4.10.6: + resolution: {integrity: sha512-62nk65yRBXvuOv28eTAq3Gs/9b/+S3gQAVmyDO/67QqGETw+d5TAEUvFrOtLg/EyP7tpGQKthP8xeH2bii7OIg==} + engines: {node: '>=14'} + dependencies: + '@clerk/backend': 0.23.0 + '@clerk/types': 3.42.0 + '@types/cookies': 0.7.7 + '@types/express': 4.17.14 + '@types/node-fetch': 2.6.2 + camelcase-keys: 6.2.2 + cookie: 0.5.0 + snakecase-keys: 3.2.1 + tslib: 2.4.1 + dev: false + + /@clerk/nextjs@4.21.1(next@13.4.5)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-Kkx8rp48jm0kWrFhMtFUTolitA4PVd2OEjxanhfmzlIhYcnH2ji/8UnH8U/dG3BvFcSeRwM1QO9wM4RsdXIKQg==} + engines: {node: '>=14'} + peerDependencies: + next: '>=10' + react: ^17.0.2 || ^18.0.0-0 + react-dom: ^17.0.2 || ^18.0.0-0 + dependencies: + '@clerk/backend': 0.23.0 + '@clerk/clerk-react': 4.20.0(react@18.2.0) + '@clerk/clerk-sdk-node': 4.10.6 + '@clerk/types': 3.42.0 + next: 13.4.5(@babel/core@7.21.0)(react-dom@18.2.0)(react@18.2.0) + path-to-regexp: 6.2.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + tslib: 2.4.1 + dev: false + + /@clerk/shared@0.19.0(react@18.2.0): + resolution: {integrity: sha512-yTm3XZBVvRhnUY4ax6SiNc/vZ4/lfqgUl+DLBxRKaJtsWcijKEddOCmFUcSgCS0wu1QcyvwNZ4PUYkVq9UWcxg==} + peerDependencies: + react: '>=16' + dependencies: + glob-to-regexp: 0.4.1 + js-cookie: 3.0.1 + react: 18.2.0 + swr: 1.3.0(react@18.2.0) + dev: false + + /@clerk/types@3.42.0: + resolution: {integrity: sha512-wEiBJFT3/Itzmu3jQfHK4zCMTqiE4fUheB1fpYx8JE2q498wzjTEHpglgxl88c0tudtWomUKqXIMJnBBEVVZBg==} + engines: {node: '>=14'} + dependencies: + csstype: 3.1.1 + dev: false /@csstools/cascade-layer-name-parser@1.0.2(@csstools/css-parser-algorithms@2.2.0)(@csstools/css-tokenizer@2.1.1): resolution: {integrity: sha512-xm7Mgwej/wBfLoK0K5LfntmPJzoULayl1XZY9JYgQgT29JiqNw++sLnx95u5y9zCihblzkyaRYJrsRMhIBzRdg==} @@ -1781,7 +1862,6 @@ packages: dependencies: '@jridgewell/set-array': 1.1.2 '@jridgewell/sourcemap-codec': 1.4.14 - dev: true /@jridgewell/gen-mapping@0.3.2: resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==} @@ -1944,6 +2024,32 @@ packages: '@nodelib/fs.scandir': 2.1.5 fastq: 1.15.0 + /@peculiar/asn1-schema@2.3.6: + resolution: {integrity: sha512-izNRxPoaeJeg/AyH8hER6s+H7p4itk+03QCa4sbxI3lNdseQYCuxzgsuNK8bTXChtLTjpJz6NmXKA73qLa3rCA==} + dependencies: + asn1js: 3.0.5 + pvtsutils: 1.3.2 + tslib: 2.5.3 + dev: false + + /@peculiar/json-schema@1.1.12: + resolution: {integrity: sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==} + engines: {node: '>=8.0.0'} + dependencies: + tslib: 2.5.3 + dev: false + + /@peculiar/webcrypto@1.4.1: + resolution: {integrity: sha512-eK4C6WTNYxoI7JOabMoZICiyqRRtJB220bh0Mbj5RwRycleZf9BPyZoxsTvpP0FpmVS2aS13NKOuh5/tN3sIRw==} + engines: {node: '>=10.12.0'} + dependencies: + '@peculiar/asn1-schema': 2.3.6 + '@peculiar/json-schema': 1.1.12 + pvtsutils: 1.3.2 + tslib: 2.5.3 + webcrypto-core: 1.7.7 + dev: false + /@pkgjs/parseargs@0.11.0: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -2487,7 +2593,7 @@ packages: '@sentry/utils': 7.55.2 '@sentry/webpack-plugin': 1.20.0 chalk: 3.0.0 - next: 13.4.5(@babel/core@7.22.5)(react-dom@18.2.0)(react@18.2.0) + next: 13.4.5(@babel/core@7.21.0)(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 rollup: 2.78.0 stacktrace-parser: 0.1.10 @@ -2685,6 +2791,13 @@ packages: use-sync-external-store: 1.2.0(react@18.2.0) dev: false + /@types/body-parser@1.19.2: + resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==} + dependencies: + '@types/connect': 3.4.35 + '@types/node': 20.3.1 + dev: false + /@types/color-convert@2.0.0: resolution: {integrity: sha512-m7GG7IKKGuJUXvkZ1qqG3ChccdIM/qBBo913z+Xft0nKCX4hAU/IxKwZBU4cpRZ7GS5kV4vOblUkILtSShCPXQ==} dependencies: @@ -2701,6 +2814,21 @@ packages: '@types/color-convert': 2.0.0 dev: true + /@types/connect@3.4.35: + resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} + dependencies: + '@types/node': 20.3.1 + dev: false + + /@types/cookies@0.7.7: + resolution: {integrity: sha512-h7BcvPUogWbKCzBR2lY4oqaZbO3jXZksexYJVFvkrFeLgbZjQkU4x8pRq6eg2MHXQhY0McQdqmmsxRWlVAHooA==} + dependencies: + '@types/connect': 3.4.35 + '@types/express': 4.17.14 + '@types/keygrip': 1.0.2 + '@types/node': 20.3.1 + dev: false + /@types/debug@4.1.8: resolution: {integrity: sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ==} dependencies: @@ -2722,6 +2850,24 @@ packages: /@types/estree@1.0.1: resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==} + /@types/express-serve-static-core@4.17.35: + resolution: {integrity: sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==} + dependencies: + '@types/node': 20.3.1 + '@types/qs': 6.9.7 + '@types/range-parser': 1.2.4 + '@types/send': 0.17.1 + dev: false + + /@types/express@4.17.14: + resolution: {integrity: sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==} + dependencies: + '@types/body-parser': 1.19.2 + '@types/express-serve-static-core': 4.17.35 + '@types/qs': 6.9.7 + '@types/serve-static': 1.15.1 + dev: false + /@types/extend@3.0.1: resolution: {integrity: sha512-R1g/VyKFFI2HLC1QGAeTtCBWCo6n75l41OnsVYNbmKG+kempOESaodf6BeJyUM3Q0rKa/NQcTHbB2+66lNnxLw==} dev: false @@ -2764,6 +2910,10 @@ packages: resolution: {integrity: sha512-hz+S3nV6Mym5xPbT9fnO8dDhBFQguMYpY0Ipxv06JMi1ORgnEM4M1ymWDUhUNer3ElLmT583opRo4RzxKmh9jw==} dev: false + /@types/keygrip@1.0.2: + resolution: {integrity: sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==} + dev: false + /@types/lodash-es@4.17.7: resolution: {integrity: sha512-z0ptr6UI10VlU6l5MYhGwS4mC8DZyYer2mCoyysZtSF7p26zOX8UpbrV0YpNYLGS8K4PUFIyEr62IMFFjveSiQ==} dependencies: @@ -2784,6 +2934,14 @@ packages: '@types/unist': 2.0.6 dev: false + /@types/mime@1.3.2: + resolution: {integrity: sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==} + dev: false + + /@types/mime@3.0.1: + resolution: {integrity: sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==} + dev: false + /@types/minimist@1.2.2: resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==} dev: true @@ -2792,6 +2950,17 @@ packages: resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} dev: false + /@types/node-fetch@2.6.2: + resolution: {integrity: sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==} + dependencies: + '@types/node': 20.3.1 + form-data: 3.0.1 + dev: false + + /@types/node@16.18.6: + resolution: {integrity: sha512-vmYJF0REqDyyU0gviezF/KHq/fYaUbFhkcNbQCuPGFQj6VTbXuHZoxs/Y7mutWe73C8AC6l9fFu8mSYiBAqkGA==} + dev: false + /@types/node@18.16.18: resolution: {integrity: sha512-/aNaQZD0+iSBAGnvvN2Cx92HqE5sZCPZtx2TsK+4nvV23fFe09jVDvpArXr2j9DnYlzuU9WuoykDDc6wqvpNcw==} dev: true @@ -2822,6 +2991,14 @@ packages: resolution: {integrity: sha512-ZREFYlpUmPQJ0esjxoG1fMvB2HNaD3z+mjqdSosZvd3RalncI9NEur73P8ZJz4YQdL64CmV1w0RuqoRUlhQRBw==} dev: true + /@types/qs@6.9.7: + resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==} + dev: false + + /@types/range-parser@1.2.4: + resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==} + dev: false + /@types/react-dom@18.2.5: resolution: {integrity: sha512-sRQsOS/sCLnpQhR4DSKGTtWFE3FZjpQa86KPVbhUqdYMRZ9FEFcfAytKhR/vUG2rH1oFbOOej6cuD7MFSobDRQ==} dependencies: @@ -2845,6 +3022,20 @@ packages: resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==} dev: true + /@types/send@0.17.1: + resolution: {integrity: sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==} + dependencies: + '@types/mime': 1.3.2 + '@types/node': 20.3.1 + dev: false + + /@types/serve-static@1.15.1: + resolution: {integrity: sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==} + dependencies: + '@types/mime': 3.0.1 + '@types/node': 20.3.1 + dev: false + /@types/unist@2.0.6: resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==} dev: false @@ -3097,7 +3288,7 @@ packages: dependencies: '@vanilla-extract/webpack-plugin': 2.2.0(@types/node@20.3.1)(webpack@5.87.0) browserslist: 4.21.7 - next: 13.4.5(@babel/core@7.22.5)(react-dom@18.2.0)(react@18.2.0) + next: 13.4.5(@babel/core@7.21.0)(react-dom@18.2.0)(react@18.2.0) transitivePeerDependencies: - '@types/node' - less @@ -3402,6 +3593,15 @@ packages: get-intrinsic: 1.2.1 dev: true + /asn1js@3.0.5: + resolution: {integrity: sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==} + engines: {node: '>=12.0.0'} + dependencies: + pvtsutils: 1.3.2 + pvutils: 1.1.3 + tslib: 2.5.3 + dev: false + /astral-regex@2.0.0: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} @@ -3547,6 +3747,20 @@ packages: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} + /camelcase-keys@6.2.2: + resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==} + engines: {node: '>=8'} + dependencies: + camelcase: 5.3.1 + map-obj: 4.3.0 + quick-lru: 4.0.1 + dev: false + + /camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + dev: false + /caniuse-lite@1.0.30001497: resolution: {integrity: sha512-I4/duVK4wL6rAK/aKZl3HXB4g+lIZvaT4VLAn2rCgJ38jVLb0lv2Xug6QuqmxXFVRJMF74SPPWPJ/1Sdm3vCzw==} @@ -3747,6 +3961,11 @@ packages: engines: {node: '>= 0.6'} dev: false + /cookie@0.5.0: + resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} + engines: {node: '>= 0.6'} + dev: false + /copy-anything@3.0.5: resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} engines: {node: '>=12.13'} @@ -3838,6 +4057,10 @@ packages: engines: {node: '>=4'} hasBin: true + /csstype@3.1.1: + resolution: {integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==} + dev: false + /csstype@3.1.2: resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} @@ -3901,6 +4124,11 @@ packages: resolution: {integrity: sha512-Rn+RuwkmkDwCi2/oXOFS9Gsr5lJZu/yTGpK7wAaAIE75CC+LCGEZHpY6VQJa/RoJcrmaA/docWJZvYohlNkWPA==} dev: true + /deepmerge@4.2.2: + resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==} + engines: {node: '>=0.10.0'} + dev: false + /deepmerge@4.3.1: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} @@ -3971,6 +4199,13 @@ packages: esutils: 2.0.3 dev: true + /dot-case@3.0.4: + resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + dependencies: + no-case: 3.0.4 + tslib: 2.5.3 + dev: false + /dotenv@16.1.4: resolution: {integrity: sha512-m55RtE8AsPeJBpOIFKihEmqUcoVncQIwo7x9U8ZwLEZw9ZpXboz2c+rvog+jUaJvVrZ5kBOeYQBX5+8Aa/OZQw==} engines: {node: '>=12'} @@ -4593,6 +4828,15 @@ packages: signal-exit: 4.0.2 dev: true + /form-data@3.0.1: + resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: false + /form-data@4.0.0: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} engines: {node: '>= 6'} @@ -5435,6 +5679,11 @@ packages: engines: {node: '>=10'} dev: true + /js-cookie@3.0.1: + resolution: {integrity: sha512-+0rgsUXZu4ncpPxRL+lNEptWMOWl9etvPHc/koSRp6MPwpRYAhmk0dUG00J4bxVV3r9uUzfo24wW0knS07SKSw==} + engines: {node: '>=12'} + dev: false + /js-cookie@3.0.5: resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==} engines: {node: '>=14'} @@ -5733,6 +5982,12 @@ packages: dependencies: js-tokens: 4.0.0 + /lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + dependencies: + tslib: 2.5.3 + dev: false + /lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} dependencies: @@ -5760,6 +6015,11 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: false + /map-obj@4.3.0: + resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} + engines: {node: '>=8'} + dev: false + /map-stream@0.1.0: resolution: {integrity: sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==} dev: true @@ -6373,12 +6633,12 @@ packages: react: '*' react-dom: '*' dependencies: - next: 13.4.5(@babel/core@7.22.5)(react-dom@18.2.0)(react@18.2.0) + next: 13.4.5(@babel/core@7.21.0)(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /next@13.4.5(@babel/core@7.22.5)(react-dom@18.2.0)(react@18.2.0): + /next@13.4.5(@babel/core@7.21.0)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-pfNsRLVM9e5Y1/z02VakJRfD6hMQkr24FaN2xc9GbcZDBxoOgiNAViSg5cXwlWCoMhtm4U315D7XYhgOr96Q3Q==} engines: {node: '>=16.8.0'} hasBin: true @@ -6403,7 +6663,7 @@ packages: postcss: 8.4.14 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - styled-jsx: 5.1.1(@babel/core@7.22.5)(react@18.2.0) + styled-jsx: 5.1.1(@babel/core@7.21.0)(react@18.2.0) watchpack: 2.4.0 zod: 3.21.4 optionalDependencies: @@ -6420,6 +6680,13 @@ packages: - '@babel/core' - babel-plugin-macros + /no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + dependencies: + lower-case: 2.0.2 + tslib: 2.5.3 + dev: false + /node-domexception@1.0.0: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} @@ -6431,6 +6698,10 @@ packages: lodash: 4.17.21 dev: false + /node-fetch-native@1.0.1: + resolution: {integrity: sha512-VzW+TAk2wE4X9maiKMlT+GsPU4OMmR1U9CrHSmd3DFLn2IcZ9VJ6M6BBugGfYUnPCLSYxXdZy17M0BEJyhUTwg==} + dev: false + /node-fetch@2.6.11: resolution: {integrity: sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==} engines: {node: 4.x || >=6.0.0} @@ -6687,6 +6958,10 @@ packages: lru-cache: 9.1.2 minipass: 6.0.2 + /path-to-regexp@6.2.1: + resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==} + dev: false + /path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -7285,9 +7560,25 @@ packages: resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} engines: {node: '>=6'} + /pvtsutils@1.3.2: + resolution: {integrity: sha512-+Ipe2iNUyrZz+8K/2IOo+kKikdtfhRKzNpQbruF2URmqPtoqAs8g3xS7TJvFF2GcPXjh7DkqMnpVveRFq4PgEQ==} + dependencies: + tslib: 2.5.3 + dev: false + + /pvutils@1.1.3: + resolution: {integrity: sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==} + engines: {node: '>=6.0.0'} + dev: false + /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + /quick-lru@4.0.1: + resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} + engines: {node: '>=8'} + dev: false + /randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} dependencies: @@ -7864,6 +8155,30 @@ packages: is-fullwidth-code-point: 4.0.0 dev: true + /snake-case@3.0.4: + resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} + dependencies: + dot-case: 3.0.4 + tslib: 2.5.3 + dev: false + + /snakecase-keys@3.2.1: + resolution: {integrity: sha512-CjU5pyRfwOtaOITYv5C8DzpZ8XA/ieRsDpr93HI2r6e3YInC6moZpSQbmUtg8cTk58tq2x3jcG2gv+p1IZGmMA==} + engines: {node: '>=8'} + dependencies: + map-obj: 4.3.0 + to-snake-case: 1.0.0 + dev: false + + /snakecase-keys@5.4.4: + resolution: {integrity: sha512-YTywJG93yxwHLgrYLZjlC75moVEX04LZM4FHfihjHe1FCXm+QaLOFfSf535aXOAd0ArVQMWUAe8ZPm4VtWyXaA==} + engines: {node: '>=12'} + dependencies: + map-obj: 4.3.0 + snake-case: 3.0.4 + type-fest: 2.19.0 + dev: false + /socket.io-client@4.6.2: resolution: {integrity: sha512-OwWrMbbA8wSqhBAR0yoPK6EdQLERQAYjXb3A0zLpgxfM1ZGLKoxHx8gVmCHA6pcclRX5oA/zvQf7bghAS11jRA==} engines: {node: '>=10.0.0'} @@ -8052,7 +8367,7 @@ packages: inline-style-parser: 0.1.1 dev: false - /styled-jsx@5.1.1(@babel/core@7.22.5)(react@18.2.0): + /styled-jsx@5.1.1(@babel/core@7.21.0)(react@18.2.0): resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==} engines: {node: '>= 12.0.0'} peerDependencies: @@ -8065,7 +8380,7 @@ packages: babel-plugin-macros: optional: true dependencies: - '@babel/core': 7.22.5 + '@babel/core': 7.21.0 client-only: 0.0.1 react: 18.2.0 @@ -8111,6 +8426,14 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + /swr@1.3.0(react@18.2.0): + resolution: {integrity: sha512-dkghQrOl2ORX9HYrMDtPa7LTVHJjCTeZoB1dqTbnnEDlSvN8JEKpYIYurDfvbQFUUS8Cg8PceFVZNkW0KNNYPw==} + peerDependencies: + react: ^16.11.0 || ^17.0.0 || ^18.0.0 + dependencies: + react: 18.2.0 + dev: false + /tailwind-merge@1.13.1: resolution: {integrity: sha512-tRtRN22TDokGi2TuYSvuHQuuW6BJ/zlUEG+iYpAQ9i66msc/0eU/+HPccbPnNNH0mCPp0Ob8thaC8Uy9CxHitQ==} @@ -8241,12 +8564,28 @@ packages: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} + /to-no-case@1.0.2: + resolution: {integrity: sha512-Z3g735FxuZY8rodxV4gH7LxClE4H0hTIyHNIHdk+vpQxjLm0cwnKXq/OFVZ76SOQmto7txVcwSCwkU5kqp+FKg==} + dev: false + /to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} dependencies: is-number: 7.0.0 + /to-snake-case@1.0.0: + resolution: {integrity: sha512-joRpzBAk1Bhi2eGEYBjukEWHOe/IvclOkiJl3DtA91jV6NwQ3MwXA4FHYeqk8BNp/D8bmi9tcNbRu/SozP0jbQ==} + dependencies: + to-space-case: 1.0.0 + dev: false + + /to-space-case@1.0.0: + resolution: {integrity: sha512-rLdvwXZ39VOn1IxGL3V6ZstoTbwLRckQmn/U8ZDLuWwIXNpuZDhQ3AiRUlhTbOXFVE9C+dR51wM0CBDhk31VcA==} + dependencies: + to-no-case: 1.0.2 + dev: false + /totalist@1.1.0: resolution: {integrity: sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==} engines: {node: '>=6'} @@ -8290,6 +8629,10 @@ packages: /tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + /tslib@2.4.1: + resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==} + dev: false + /tslib@2.5.3: resolution: {integrity: sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==} @@ -8362,6 +8705,11 @@ packages: engines: {node: '>=8'} dev: false + /type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + dev: false + /typed-array-length@1.0.4: resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} dependencies: @@ -8704,6 +9052,16 @@ packages: engines: {node: '>= 8'} dev: true + /webcrypto-core@1.7.7: + resolution: {integrity: sha512-7FjigXNsBfopEj+5DV2nhNpfic2vumtjjgPmeDKk45z+MJwXKKfhPB7118Pfzrmh4jqOMST6Ch37iPAHoImg5g==} + dependencies: + '@peculiar/asn1-schema': 2.3.6 + '@peculiar/json-schema': 1.1.12 + asn1js: 3.0.5 + pvtsutils: 1.3.2 + tslib: 2.5.3 + dev: false + /webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} dev: false diff --git a/src/app.config.ts b/src/app.config.ts new file mode 100644 index 0000000000..6faecadfe4 --- /dev/null +++ b/src/app.config.ts @@ -0,0 +1,8 @@ +export const appConfig = { + site: { + url: + process.env.NODE_ENV === 'production' + ? 'https://innei.ren' + : 'http://localhost:2323', + }, +} diff --git a/src/app/error.tsx b/src/app/error.tsx index 5004bc5bc2..f153ee8a79 100644 --- a/src/app/error.tsx +++ b/src/app/error.tsx @@ -1,6 +1,6 @@ 'use client' -export default ({ error, reset }) => { +export default ({ error, reset }: any) => { return ( diff --git a/src/app/global-error.tsx b/src/app/global-error.tsx index 63c96d732b..1bca45f96d 100644 --- a/src/app/global-error.tsx +++ b/src/app/global-error.tsx @@ -3,7 +3,7 @@ import { useEffect } from 'react' // TODO next.js not implement for now -export default ({ error, reset }) => { +export default ({ error, reset }: any) => { useEffect(() => { console.log(error, reset) }, [error]) diff --git a/src/app/layout.tsx b/src/app/layout.tsx index ff835c1c79..f74d147e44 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -2,7 +2,10 @@ import '../styles/index.css' import { dehydrate } from '@tanstack/react-query' +import { ClerkProvider } from '@clerk/nextjs' + import { Root } from '~/components/layout/root/Root' +import { ClerkZhCN } from '~/i18n/cherk-cn' import { defineMetadata } from '~/lib/define-metadata' import { sansFont } from '~/lib/fonts' import { getQueryClient } from '~/utils/query-client.server' @@ -72,18 +75,20 @@ export default async function RootLayout(props: Props) { return true }, }) - + return ( - - - - - {children} - - - - + + + + + + {children} + + + + + ) } diff --git a/src/app/page.tsx b/src/app/page.tsx index 4473d41487..c93a0bce5f 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -4,6 +4,6 @@ import { useAggregationQuery } from '~/hooks/data/use-aggregation' export default function Home() { const { data } = useAggregationQuery() - // throw new Error() - return
{data?.user.avatar}
+ + return null } diff --git a/src/app/sign-in/[[...sign-in]]/page.tsx b/src/app/sign-in/[[...sign-in]]/page.tsx new file mode 100644 index 0000000000..d39d899cd8 --- /dev/null +++ b/src/app/sign-in/[[...sign-in]]/page.tsx @@ -0,0 +1,7 @@ +import React from 'react' + +import { SignIn } from '@clerk/nextjs' + +export default function Page() { + return +} diff --git a/src/app/sign-up/[[...sign-up]]/page.tsx b/src/app/sign-up/[[...sign-up]]/page.tsx new file mode 100644 index 0000000000..2e141b5b29 --- /dev/null +++ b/src/app/sign-up/[[...sign-up]]/page.tsx @@ -0,0 +1,7 @@ +import React from 'react' + +import { SignUp } from '@clerk/nextjs' + +export default function Page() { + return +} diff --git a/src/components/icons/user-arrow-left.tsx b/src/components/icons/user-arrow-left.tsx new file mode 100644 index 0000000000..319323d02d --- /dev/null +++ b/src/components/icons/user-arrow-left.tsx @@ -0,0 +1,22 @@ +import type { SVGAttributes } from 'react' + +export function UserArrowLeftIcon(props: SVGAttributes) { + return ( + + + + ) +} diff --git a/src/components/layout/header/Header.tsx b/src/components/layout/header/Header.tsx index 9782f9f984..5e07b37b4c 100644 --- a/src/components/layout/header/Header.tsx +++ b/src/components/layout/header/Header.tsx @@ -5,6 +5,7 @@ import { HeaderContent } from './HeaderContent' import { HeaderDataConfigureProvider } from './HeaderDataConfigureProvider' import { Logo } from './Logo' import { SiteOwnerAvatar } from './SiteOwnerAvatar' +import { UserAuth } from './UserAuth' export const Header = () => { return ( @@ -14,26 +15,26 @@ export const Header = () => { ) } -const MemoedHeader = memo(() => ( -
- -
-
- - -
-
-
- +const MemoedHeader = memo(() => { + return ( +
+ +
+
+ + +
+
+
+ +
+
+
+
- d -
-
- - Username
-
-
-)) + + ) +}) -MemoedHeader.displayName = 'HeaderInner' +MemoedHeader.displayName = 'MemoedHeader' diff --git a/src/components/layout/header/UserAuth.tsx b/src/components/layout/header/UserAuth.tsx new file mode 100644 index 0000000000..92fb928892 --- /dev/null +++ b/src/components/layout/header/UserAuth.tsx @@ -0,0 +1,62 @@ +'use client' + +import React from 'react' +import { AnimatePresence } from 'framer-motion' +import { usePathname } from 'next/navigation' + +import { + SignedIn, + SignedOut, + SignInButton, + UserButton, + useUser, +} from '@clerk/nextjs' + +import { appConfig } from '~/app.config' +import { UserArrowLeftIcon } from '~/components/icons/user-arrow-left' +import { FloatPopover } from '~/components/ui/float-popover' + +function url(path = '') { + return new URL(path, appConfig.site.url) +} + +export function UserAuth() { + console.log(useUser()) + const pathname = usePathname() + + return ( + + +
+ +
+
+ + + 登陆 + + +
+ ) +} + +const TriggerComponent = () => { + const pathname = usePathname() + return ( + + + + ) +} diff --git a/src/components/ui/float-popover/FloatPopover.tsx b/src/components/ui/float-popover/FloatPopover.tsx index f93a4c0ab7..7e797e7455 100644 --- a/src/components/ui/float-popover/FloatPopover.tsx +++ b/src/components/ui/float-popover/FloatPopover.tsx @@ -31,6 +31,11 @@ export const FloatPopover: FC< animate?: boolean as?: keyof HTMLElementTagNameMap + + /** + * @default popover + */ + type?: 'tooltip' | 'popover' }> & UseFloatingOptions > = (props) => { @@ -46,6 +51,7 @@ export const FloatPopover: FC< debug, animate = true, as: As = 'div', + type = 'popover', ...floatingProps } = props @@ -229,8 +235,11 @@ export const FloatPopover: FC< aria-modal="true" className={clsxm( 'bg-base-100 !shadow-out-sm focus:!shadow-out-sm focus-visible:!shadow-out-sm', - headless ? styles['headless'] : styles['popover-root'], + headless && styles['headless'], animate && styles['animate'], + type === 'tooltip' + ? `rounded-full bg-base-100 px-4 py-2 ${styles['headless']}` + : styles['popover-root'], popoverClassNames, )} ref={refs.setFloating} diff --git a/src/i18n/cherk-cn.ts b/src/i18n/cherk-cn.ts new file mode 100644 index 0000000000..f046e412a0 --- /dev/null +++ b/src/i18n/cherk-cn.ts @@ -0,0 +1,655 @@ +const welcomeText = '欢迎光临 {{applicationName}}' + +const commonTexts = { + signIn: { + phoneCode: { + title: '检查手机短信', + + subtitle: welcomeText, + formTitle: '验证码', + formSubtitle: '使用发送到您手机的验证码', + resendButton: '重新发送验证码', + }, + }, +} as const + +export const ClerkZhCN = { + locale: 'zh-CN', + socialButtonsBlockButton: '使用 {{provider|titleize}} 登录', + dividerText: '或者', + formFieldLabel__emailAddress: '电子邮件地址', + formFieldLabel__emailAddresses: '电子邮件地址', + formFieldLabel__phoneNumber: '电话号码', + formFieldLabel__username: '用户名', + formFieldLabel__emailAddress_phoneNumber: '电子邮件地址或电话号码', + formFieldLabel__emailAddress_username: '电子邮件地址或用户名', + formFieldLabel__phoneNumber_username: '电话号码或用户名', + formFieldLabel__emailAddress_phoneNumber_username: + '电子邮件地址、电话号码或用户名', + formFieldLabel__password: '密码', + formFieldLabel__currentPassword: '当前密码', + formFieldLabel__newPassword: '新密码', + formFieldLabel__confirmPassword: '确认密码', + formFieldLabel__signOutOfOtherSessions: '登出所有其他设备', + formFieldLabel__firstName: '名字', + formFieldLabel__lastName: '姓氏', + formFieldLabel__backupCode: '备用代码', + formFieldLabel__organizationName: '组织名称', + formFieldLabel__organizationSlug: 'URL 简称', + formFieldLabel__role: '角色', + formFieldInputPlaceholder__emailAddress: '', + formFieldInputPlaceholder__emailAddresses: + '输入或粘贴一个或多个电子邮件地址,用空格或逗号分隔', + formFieldInputPlaceholder__phoneNumber: '', + formFieldInputPlaceholder__username: '', + formFieldInputPlaceholder__emailAddress_phoneNumber: '', + formFieldInputPlaceholder__emailAddress_username: '', + formFieldInputPlaceholder__phoneNumber_username: '', + formFieldInputPlaceholder__emailAddress_phoneNumber_username: '', + formFieldInputPlaceholder__password: '', + formFieldInputPlaceholder__firstName: '', + formFieldInputPlaceholder__lastName: '', + formFieldInputPlaceholder__backupCode: '', + formFieldInputPlaceholder__organizationName: '', + formFieldInputPlaceholder__organizationSlug: '', + formFieldError__notMatchingPasswords: `密码不匹配。`, + formFieldError__matchingPasswords: '密码匹配。', + formFieldAction__forgotPassword: '忘记密码?', + formFieldHintText__optional: '选填', + formButtonPrimary: '继续', + signInEnterPasswordTitle: '输入您的密码', + backButton: '返回', + footerActionLink__useAnotherMethod: '使用另一种方法', + badge__primary: '主要', + badge__thisDevice: '此设备', + badge__userDevice: '用户设备', + badge__otherImpersonatorDevice: '其他模拟器设备', + badge__default: '默认', + badge__unverified: '未验证', + badge__requiresAction: '需要操作', + badge__you: '您', + footerPageLink__help: '帮助', + footerPageLink__privacy: '隐私', + footerPageLink__terms: '条款', + paginationButton__previous: '上一页', + paginationButton__next: '下一页', + paginationRowText__displaying: '显示', + paginationRowText__of: '的', + membershipRole__admin: '管理员', + membershipRole__basicMember: '成员', + membershipRole__guestMember: '访客', + signUp: { + start: { + title: '创建您的账户', + subtitle: welcomeText, + actionText: '已经有账户了?', + actionLink: '登录', + }, + emailLink: { + title: '验证您的电子邮件', + subtitle: welcomeText, + formTitle: '验证链接', + formSubtitle: '使用发送到您的电子邮件地址的验证链接', + resendButton: '重新发送链接', + verified: { + title: '成功注册', + }, + loading: { + title: '正在注册...', + }, + verifiedSwitchTab: { + title: '成功验证电子邮件', + subtitle: '返回新打开的标签页继续', + subtitleNewTab: '返回上一个标签页继续', + }, + }, + emailCode: { + title: '验证您的电子邮件', + subtitle: welcomeText, + formTitle: '验证码', + formSubtitle: '输入发送到您的电子邮件地址的验证码', + resendButton: '重新发送验证码', + }, + phoneCode: { + title: '验证您的电话', + subtitle: welcomeText, + formTitle: '验证码', + formSubtitle: '输入发送到您的电话号码的验证码', + resendButton: '重新发送验证码', + }, + continue: { + title: '填写缺少的字段', + subtitle: welcomeText, + actionText: '已经有账户了?', + actionLink: '登录', + }, + }, + signIn: { + start: { + title: '登录', + subtitle: welcomeText, + actionText: '还没有账户?', + actionLink: '注册', + actionLink__use_email: '使用电子邮件', + actionLink__use_phone: '使用电话', + actionLink__use_username: '使用用户名', + actionLink__use_email_username: '使用电子邮件或用户名', + }, + password: { + title: '输入您的密码', + subtitle: welcomeText, + actionLink: '使用其他方法', + }, + forgotPasswordAlternativeMethods: { + title: '忘记密码?', + label__alternativeMethods: '或者,使用其他方式登录。', + blockButton__resetPassword: '重置密码', + }, + forgotPassword: { + title_email: '查看您的电子邮件', + title_phone: '查看您的手机', + subtitle: '重置您的密码', + formTitle: '重置密码代码', + formSubtitle_email: '输入发送到您的电子邮件地址的代码', + formSubtitle_phone: '输入发送到您的电话号码的代码', + resendButton: '重新发送代码', + }, + resetPassword: { + title: '重置密码', + formButtonPrimary: '重置密码', + successMessage: '您的密码已成功更改。正在为您登录,请稍等。', + }, + resetPasswordMfa: { + detailsLabel: '我们需要验证您的身份才能重置您的密码。', + }, + emailCode: { + title: '查看您的电子邮件', + subtitle: welcomeText, + formTitle: '验证码', + formSubtitle: '输入发送到您的电子邮件地址的验证码', + resendButton: '重新发送验证码', + }, + emailLink: { + title: '查看您的电子邮件', + subtitle: welcomeText, + formTitle: '验证链接', + formSubtitle: '使用发送到您的电子邮件的验证链接', + resendButton: '重新发送链接', + unusedTab: { + title: '您可以关闭此标签页', + }, + verified: { + title: '成功登录', + subtitle: '即将为您重定向', + }, + verifiedSwitchTab: { + subtitle: '返回原始标签页继续', + titleNewTab: '在其他标签页上登录', + subtitleNewTab: '返回新打开的标签页继续', + }, + loading: { + title: '正在登录...', + subtitle: '即将为您重定向', + }, + failed: { + title: '此验证链接无效', + subtitle: '返回原始标签页继续。', + }, + expired: { + title: '此验证链接已过期', + subtitle: '返回原始标签页继续。', + }, + }, + phoneCode: { ...commonTexts.signIn.phoneCode }, + phoneCodeMfa: { ...commonTexts.signIn.phoneCode, subtitle: '' }, + totpMfa: { + title: '两步验证', + subtitle: '', + formTitle: '验证码', + formSubtitle: '输入您的验证应用程序生成的验证码', + }, + backupCodeMfa: { + title: '输入备用代码', + subtitle: welcomeText, + formTitle: '', + formSubtitle: '', + }, + alternativeMethods: { + title: '使用其他方法', + actionLink: '获取帮助', + blockButton__emailLink: '电子邮件链接到 {{identifier}}', + blockButton__emailCode: '电子邮件验证码到 {{identifier}}', + blockButton__phoneCode: '发送短信代码到 {{identifier}}', + blockButton__password: '使用您的密码登录', + blockButton__totp: '使用您的验证应用程序', + blockButton__backupCode: '使用备用代码', + getHelp: { + title: '获取帮助', + content: `如果您在登录账户时遇到困难,请给我们发送电子邮件,我们将尽快让您恢复访问。`, + blockButton__emailSupport: '邮件支持', + }, + }, + noAvailableMethods: { + title: '无法登录', + subtitle: '出现错误', + message: '无法继续登录。没有可用的身份验证因素。', + }, + }, + userProfile: { + mobileButton__menu: '菜单', + formButtonPrimary__continue: '继续', + formButtonPrimary__finish: '完成', + formButtonReset: '取消', + start: { + headerTitle__account: '账户', + headerTitle__security: '安全', + headerSubtitle__account: '管理您的账户信息', + headerSubtitle__security: '管理您的安全设置', + profileSection: { + title: '个人资料', + }, + usernameSection: { + title: '用户名', + primaryButton__changeUsername: '更改用户名', + primaryButton__setUsername: '设置用户名', + }, + emailAddressesSection: { + title: '电子邮件地址', + primaryButton: '添加电子邮件地址', + detailsTitle__primary: '主要电子邮件地址', + detailsSubtitle__primary: '此电子邮件地址是主要电子邮件地址', + detailsAction__primary: '完成验证', + detailsTitle__nonPrimary: '设为主要电子邮件地址', + detailsSubtitle__nonPrimary: + '将此电子邮件地址设为主要的,以接收关于您账户的通信。', + detailsAction__nonPrimary: '设为主要', + detailsTitle__unverified: '未验证的电子邮件地址', + detailsSubtitle__unverified: '此电子邮件地址尚未验证,功能可能受到限制', + detailsAction__unverified: '完成验证', + destructiveActionTitle: '移除', + destructiveActionSubtitle: '删除此电子邮件地址,并将其从您的账户中移除', + destructiveAction: '移除电子邮件地址', + }, + phoneNumbersSection: { + title: '电话号码', + primaryButton: '添加电话号码', + detailsTitle__primary: '主要电话号码', + detailsSubtitle__primary: '此电话号码是主要电话号码', + detailsAction__primary: '完成验证', + detailsTitle__nonPrimary: '设为主要电话号码', + detailsSubtitle__nonPrimary: + '将此电话号码设为主要的,以接收关于您账户的通信。', + detailsAction__nonPrimary: '设为主要', + detailsTitle__unverified: '未验证的电话号码', + detailsSubtitle__unverified: '此电话号码尚未验证,功能可能受到限制', + detailsAction__unverified: '完成验证', + destructiveActionTitle: '移除', + destructiveActionSubtitle: '删除此电话号码,并将其从您的账户中移除', + destructiveAction: '移除电话号码', + }, + connectedAccountsSection: { + title: '已连接的账户', + primaryButton: '连接账户', + title__conectionFailed: '重试失败的连接', + title__connectionFailed: '重试失败的连接', + title__reauthorize: '需要重新授权', + subtitle__reauthorize: + '所需的权限已更新,您可能会遇到功能限制。请重新授权此应用程序,以避免任何问题', + actionLabel__conectionFailed: '再试一次', + actionLabel__connectionFailed: '再试一次', + actionLabel__reauthorize: '立即授权', + destructiveActionTitle: '移除', + destructiveActionSubtitle: '从您的账户中移除此已连接的账户', + destructiveActionAccordionSubtitle: '移除已连接的账户', + }, + enterpriseAccountsSection: { + title: '企业账户', + }, + passwordSection: { + title: '密码', + primaryButton__changePassword: '更改密码', + primaryButton__setPassword: '设置密码', + }, + mfaSection: { + title: '两步验证', + primaryButton: '添加两步验证', + phoneCode: { + destructiveActionTitle: '移除', + destructiveActionSubtitle: '从两步验证方法中移除此电话号码', + destructiveActionLabel: '移除电话号码', + title__default: '默认因素', + title__setDefault: '设为默认因素', + subtitle__default: '登录时,此因素将被用作默认的两步验证方法。', + subtitle__setDefault: + '将此因素设为默认因素,登录时将使用它作为默认的两步验证方法。', + actionLabel__setDefault: '设为默认', + }, + backupCodes: { + headerTitle: '备份代码', + title__regenerate: '重新生成备份代码', + subtitle__regenerate: + '获取一套新的安全备份代码。之前的备份代码将被删除,无法使用。', + actionLabel__regenerate: '重新生成代码', + }, + totp: { + headerTitle: '验证器应用程序', + title: '默认因素', + subtitle: '登录时,此因素将被用作默认的两步验证方法。', + destructiveActionTitle: '移除', + destructiveActionSubtitle: '从两步验证方法中移除验证器应用程序', + destructiveActionLabel: '移除验证器应用程序', + }, + }, + + activeDevicesSection: { + title: '活动设备', + primaryButton: '活动设备', + detailsTitle: '当前设备', + detailsSubtitle: '这是你目前正在使用的设备', + destructiveActionTitle: '登出', + destructiveActionSubtitle: '从此设备上退出您的账户', + destructiveAction: '退出设备', + }, + web3WalletsSection: { + title: 'Web3 钱包', + primaryButton: 'Web3 钱包', + destructiveActionTitle: '移除', + destructiveActionSubtitle: '从您的账户中移除这个 Web3 钱包', + destructiveAction: '移除钱包', + }, + }, + profilePage: { + title: '更新个人资料', + imageFormTitle: '个人资料图片', + imageFormSubtitle: '上传图片', + imageFormDestructiveActionSubtitle: '移除图片', + fileDropAreaTitle: '拖拽文件到这里,或者...', + fileDropAreaAction: '选择文件', + fileDropAreaHint: '上传小于 10MB 的 JPG, PNG, GIF, 或 WEBP 格式的图片', + successMessage: '您的个人资料已更新。', + }, + usernamePage: { + title: '更新用户名', + successMessage: '您的用户名已更新。', + }, + emailAddressPage: { + title: '添加电子邮件地址', + emailCode: { + formHint: '一封含有验证码的邮件将会被发送到这个电子邮件地址。', + formTitle: '验证码', + formSubtitle: '输入发送到 {{identifier}} 的验证码', + resendButton: '重发验证码', + successMessage: '电子邮件 {{identifier}} 已被添加到您的账户。', + }, + emailLink: { + formHint: '一封含有验证链接的邮件将会被发送到这个电子邮件地址。', + formTitle: '验证链接', + formSubtitle: '点击发送到 {{identifier}} 的邮件中的验证链接', + resendButton: '重发链接', + successMessage: '电子邮件 {{identifier}} 已被添加到您的账户。', + }, + removeResource: { + title: '移除电子邮件地址', + messageLine1: '{{identifier}} 将从此账户中被移除。', + messageLine2: '您将无法使用这个电子邮件地址登录。', + successMessage: '电子邮件 {{emailAddress}} 已从您的账户中移除。', + }, + }, + phoneNumberPage: { + title: '添加电话号码', + successMessage: '{{identifier}} 已被添加到您的账户。', + infoText: '一条包含验证链接的短信将会发送到这个电话号码。', + infoText__secondary: '可能会产生信息和数据费用。', + removeResource: { + title: '移除电话号码', + messageLine1: '{{identifier}} 将从此账户中被移除。', + messageLine2: '您将无法使用这个电话号码登录。', + successMessage: '电话号码 {{phoneNumber}} 已从您的账户中移除。', + }, + }, + connectedAccountPage: { + title: '添加已连接的账户', + formHint: '选择一个供应商来连接您的账户。', + formHint__noAccounts: '没有可用的外部账户供应商。', + socialButtonsBlockButton: '连接 {{provider|titleize}} 账户', + successMessage: '供应商已被添加到您的账户', + removeResource: { + title: '移除已连接的账户', + messageLine1: '{{identifier}} 将从此账户中被移除。', + messageLine2: + '您将无法再使用这个已连接的账户,任何依赖的功能将不再工作。', + successMessage: '{{connectedAccount}} 已从您的账户中移除。', + }, + }, + web3WalletPage: { + title: '添加 web3 钱包', + subtitle__availableWallets: '选择一个 web3 钱包连接到您的账户。', + subtitle__unavailableWallets: '没有可用的 web3 钱包。', + successMessage: '钱包已被添加到您的账户。', + removeResource: { + title: '移除 web3 钱包', + messageLine1: '{{identifier}} 将从此账户中被移除。', + messageLine2: '您将无法使用这个 web3 钱包登录。', + successMessage: '{{web3Wallet}} 已从您的账户中移除。', + }, + }, + passwordPage: { + title: '设置密码', + changePasswordTitle: '更改密码', + successMessage: '您的密码已设置。', + changePasswordSuccessMessage: '您的密码已更新。', + sessionsSignedOutSuccessMessage: '所有其他设备已退出。', + }, + mfaPage: { + title: '添加两步验证', + formHint: '选择一个添加的方法。', + }, + mfaTOTPPage: { + title: '添加验证器应用程序', + verifyTitle: '验证代码', + verifySubtitle: '输入您的验证器生成的验证码', + successMessage: + '现在已启用两步验证。在登录时,您需要输入来自此验证器的验证码作为额外步骤。', + authenticatorApp: { + infoText__ableToScan: + '在您的验证器应用中设置一个新的登录方法,并扫描下面的二维码将其链接到您的账户。', + infoText__unableToScan: + '在验证器中设置一个新的登录方法,并输入下面提供的 Key。', + inputLabel__unableToScan1: + '确保启用了基于时间或一次性密码,然后完成链接您的账户。', + inputLabel__unableToScan2: + '或者,如果您的验证器支持 TOTP URIs,您也可以复制完整的 URI。', + buttonAbleToScan__nonPrimary: '扫描二维码', + buttonUnableToScan__nonPrimary: '不能扫描二维码?', + }, + removeResource: { + title: '移除两步验证', + messageLine1: '登录时,将不再需要来自此验证器的验证码。', + messageLine2: '您的账户可能不再安全。您确定要继续吗?', + successMessage: '已移除通过验证器应用程序的两步验证。', + }, + }, + mfaPhoneCodePage: { + title: '添加短信验证码验证', + primaryButton__addPhoneNumber: '添加电话号码', + subtitle__availablePhoneNumbers: + '选择一个电话号码来注册短信验证码两步验证。', + subtitle__unavailablePhoneNumbers: + '没有可用的电话号码来注册短信验证码两步验证。', + successMessage: + '现在已启用此电话号码的短信验证码两步验证。在登录时,您需要输入发送到这个电话号码的验证码作为额外步骤。', + removeResource: { + title: '移除两步验证', + messageLine1: '{{identifier}} 将不再在登录时接收验证代码。', + messageLine2: '您的账户可能不再安全。您确定要继续吗?', + successMessage: '已移除{{mfaPhoneCode}}的短信验证码两步验证', + }, + }, + backupCodePage: { + title: '添加备份代码验证', + title__codelist: '备份代码', + subtitle__codelist: '安全存储并保守秘密。', + infoText1: '将为此账户启用备份代码。', + infoText2: + '保密并安全存储备份代码。如果您怀疑它们已经泄露,您可以重新生成备份代码。', + successSubtitle: + '如果您失去了验证设备的访问权限,您可以使用其中之一登录您的账户。', + successMessage: + '现在已启用备份代码。如果您失去了验证设备的访问权限,您可以使用其中之一登录您的账户。每个代码只能使用一次。', + actionLabel__copy: '复制全部', + actionLabel__copied: '已复制!', + actionLabel__download: '下载 .txt', + actionLabel__print: '打印', + }, + }, + userButton: { + action__manageAccount: '管理账户', + action__signOut: '退出登录', + action__signOutAll: '退出所有账户', + action__addAccount: '添加账户', + }, + organizationSwitcher: { + personalWorkspace: '个人工作区', + notSelected: '未选择组织', + action__createOrganization: '创建组织', + action__manageOrganization: '管理组织', + }, + impersonationFab: { + title: '以 {{identifier}} 登录', + action__signOut: '退出登录', + }, + organizationProfile: { + start: { + headerTitle__members: '成员', + headerTitle__settings: '设置', + headerSubtitle__members: '查看并管理组织成员', + headerSubtitle__settings: '管理组织设置', + }, + profilePage: { + title: '组织简介', + subtitle: '管理组织简介', + successMessage: '组织已更新。', + dangerSection: { + title: '危险', + leaveOrganization: { + title: '离开组织', + messageLine1: + '您确定要离开此组织吗?您将失去对此组织及其应用程序的访问权限。', + messageLine2: '此操作是永久性的且无法撤销。', + successMessage: '您已离开了组织。', + }, + }, + }, + invitePage: { + title: '邀请成员', + subtitle: '邀请新成员加入此组织', + successMessage: '邀请成功发送', + detailsTitle__inviteFailed: '邀请无法发送。修复以下问题然后重试:', + formButtonPrimary__continue: '发送邀请', + }, + membersPage: { + detailsTitle__emptyRow: '没有可显示的成员', + action__invite: '邀请', + start: { + headerTitle__active: '活跃', + headerTitle__invited: '已邀请', + }, + activeMembersTab: { + tableHeader__user: '用户', + tableHeader__joined: '加入', + tableHeader__role: '角色', + tableHeader__actions: '', + menuAction__remove: '移除成员', + }, + invitedMembersTab: { + tableHeader__invited: '已邀请', + menuAction__revoke: '撤销邀请', + }, + }, + }, + createOrganization: { + title: '创建组织', + formButtonSubmit: '创建组织', + subtitle: '设置组织简介', + invitePage: { + formButtonReset: '跳过', + }, + }, + unstable__errors: { + form_identifier_not_found: '未找到该账号', + captcha_invalid: + '由于安全验证失败,注册未成功。请刷新页面重试或联系支持获取更多帮助。', + form_password_pwned: + '这个密码在数据泄露中被发现,不能使用,请换一个密码试试。', + form_username_invalid_length: '', + form_param_format_invalid: '', + form_password_length_too_short: '', + form_param_nil: '', + form_code_incorrect: '', + form_password_incorrect: '', + not_allowed_access: '', + form_identifier_exists: '', + form_password_validation_failed: '密码错误', + form_password_not_strong_enough: '您的密码强度不够。', + form_password_size_in_bytes_exceeded: + '您的密码超过了允许的最大字节数,请缩短它或去掉一些特殊字符。', + passwordComplexity: { + sentencePrefix: '您的密码必须包含', + minimumLength: '{{length}}个或更多字符', + maximumLength: '少于{{length}}个字符', + requireNumbers: '一个数字', + requireLowercase: '一个小写字母', + requireUppercase: '一个大写字母', + requireSpecialCharacter: '一个特殊字符', + }, + zxcvbn: { + notEnough: '您的密码强度不够。', + couldBeStronger: '您的密码可以用,但可以更强。试着添加更多字符。', + goodPassword: '泰酷辣,是一个优秀的密码。', + warnings: { + straightRow: '键盘上的直行键易被猜到。', + keyPattern: '短键盘模式易被猜到。', + simpleRepeat: '像"aaa"这样的重复字符易被猜到。', + extendedRepeat: '像"abcabcabc"这样的重复字符模式易被猜到。', + sequences: '像"abc"这样的常见字符序列易被猜到。', + recentYears: '近年来易被猜到。', + dates: '日期易被猜到。', + topTen: '这是一个大量使用的密码。', + topHundred: '这是一个频繁使用的密码。', + common: '这是一个常用的密码。', + similarToCommon: '这个密码和常用密码相似。', + wordByItself: '单个单词易被猜到。', + namesByThemselves: '单个名字或姓氏易被猜到。', + commonNames: '常见的名字和姓氏易被猜到。', + userInputs: '不应该有任何个人或页面相关的数据。', + pwned: '您的密码在互联网上的数据泄露中被暴露。', + }, + suggestions: { + l33t: '避免预测的字母替换,如"@"代替"a"。', + reverseWords: '避免常用词的反向拼写。', + allUppercase: '大写一些,但不是所有的字母。', + capitalization: '大写不仅仅是第一个字母。', + dates: '避免与你有关的日期和年份。', + recentYears: '避免近年来。', + associatedYears: '避免与你有关的年份。', + sequences: '避免常见字符序列。', + repeated: '避免重复的单词和字符。', + longerKeyboardPattern: '使用更长的键盘模式,并多次改变打字方向。', + anotherWord: '添加更不常见的更多单词。', + useWords: '使用多个单词,但避免常见短语。', + noNeed: '你可以创建强密码,而无需使用符号,数字或大写字母。', + pwned: '如果您在其他地方使用此密码,您应该更改它。', + }, + }, + }, + dates: { + previous6Days: + "上周{{ date | weekday('zh-CN','long') }} {{ date | timeString('zh-CN') }}", + lastDay: "昨天{{ date | timeString('zh-CN') }}", + sameDay: "今天{{ date | timeString('zh-CN') }}", + nextDay: "明天{{ date | timeString('zh-CN') }}", + next6Days: + "{{ date | weekday('zh-CN','long') }} {{ date | timeString('zh-CN') }}", + numeric: "{{ date | numeric('zh-CN') }}", + }, +} as const diff --git a/src/styles/clerk.css b/src/styles/clerk.css new file mode 100644 index 0000000000..8c7e7e8fe2 --- /dev/null +++ b/src/styles/clerk.css @@ -0,0 +1,209 @@ +.cl-card, +.cl-userButtonPopoverCard { + @apply border shadow-xl shadow-zinc-500/10 backdrop-blur-xl backdrop-saturate-150; + @apply border-zinc-200 bg-zinc-50/80 text-zinc-800; + @apply py-4; + --accent: theme('colors.zinc.900'); + --accentDark: theme('colors.zinc.800'); +} + +.cl-modalBackdrop { + @apply flex flex-col items-center justify-center bg-base-100/90; +} + +.cl-userButtonPopoverCard { + @apply w-64; +} + +.cl-userButtonPopoverActions { + @apply mt-1; +} + +.cl-userButtonPopoverFooter { + @apply hidden; +} + +.cl-userButtonPopoverCard .cl-userPreview { + @apply px-4; +} + +.cl-formFieldInput { + @apply bg-transparent text-zinc-800; +} + +.cl-userButtonPopoverActionButton { + @apply gap-1 px-2; +} + +.cl-footerActionLink, +.cl-formResendCodeLink { + @apply text-zinc-900 underline; +} + +.cl-formFieldHintText { + font-size: 12px; +} + +.cl-formButtonPrimary { + @apply bg-accent !text-white; + + &:hover { + @apply bg-accent-focus; + } +} + +.cl-formFieldLabelRow { + @apply mb-2; +} + +.cl-footer + div { + @apply hidden; +} + +.cl-userButtonPopoverCard { + @apply !pb-0; +} + +.cl-userButtonPopoverCard { + @apply overflow-hidden; +} + +.cl-userButtonPopoverActionButton:hover { + background: theme('colors.zinc.100'); +} + +.cl-logoBox { + @apply absolute -top-[30px] left-[50%] m-auto inline-block -translate-x-1/2; +} + +.cl-logoBox img { + @apply h-[60px] w-[60px] overflow-hidden rounded-full; +} + +[data-theme='dark'] { + .cl-userButtonPopoverActionButton:hover { + background: theme('colors.zinc.800'); + } + + .🔒, + .cl-formField p, + .cl-formField p[aria-live='polite'], + .cl-formFieldInputShowPasswordButton { + @apply text-zinc-400; + } + + .cl-card, + .cl-userButtonPopoverCard { + @apply border-zinc-800 bg-zinc-900/80 text-zinc-200 shadow-zinc-900/20; + } + + [class*='cl-internal-'] { + --accent: theme('colors.zinc.50'); + --accentDark: theme('colors.zinc.200'); + --border: hsla(0, 0%, 100%, 0.08); + --accentLightest: hsla(0, 0%, 100%, 0.04); + --accentLighter: hsla(0, 0%, 100%, 0.16); + --accentDarker: hsla(0, 0%, 100%, 0.64); + } + + .cl-profileSectionTitleText { + @apply text-zinc-100; + } + + .cl-breadcrumbsItem, + .cl-breadcrumbsItemDivider, + [data-localization-key], + .cl-fileDropAreaOuterBox *, + .cl-profileSectionContent__password p { + @apply text-zinc-400; + } + + .cl-navbarButton.cl-active { + @apply bg-zinc-400/10; + } + + .cl-navbar { + @apply border-zinc-800; + } + + .cl-userPreviewSecondaryIdentifier, + .cl-headerSubtitle, + .cl-profileSectionContent__activeDevices p { + @apply text-zinc-400; + } + + .cl-headerTitle, + .cl-socialButtonsBlockButton, + .cl-alternativeMethodsBlockButton, + .cl-userButtonPopoverActionButtonIcon, + .cl-userButtonPopoverActionButtonText { + @apply text-zinc-200; + } + + .cl-alternativeMethodsBlockButton + svg:not(.cl-alternativeMethodsBlockButtonArrow) { + @apply invert; + } + + .cl-socialButtonsBlockButton, + .cl-alternativeMethodsBlockButton { + @apply rounded-xl border-zinc-500/20; + } + + .cl-socialButtonsProviderIcon__github, + .cl-providerIcon__github { + @apply invert; + } + + .cl-dividerLine { + @apply bg-zinc-200/10; + } + + .cl-dividerText { + @apply text-zinc-500; + } + + .cl-formFieldAction { + @apply text-zinc-200 underline; + } + + .cl-formFieldLabel { + @apply text-zinc-400; + } + + .cl-formFieldInput, + .cl-identityPreview { + @apply border-zinc-800 bg-transparent text-zinc-200; + } + + .cl-footerActionText, + .cl-formHeaderSubtitle { + @apply text-zinc-400; + } + + .cl-footerActionLink, + .cl-formHeaderTitle, + .cl-formResendCodeLink { + @apply text-zinc-100; + } + + .cl-modalCloseButton { + @apply text-zinc-200; + } + + .cl-otpCodeFieldInput { + @apply border-zinc-700 text-zinc-200; + } + + .cl-formFieldSuccessText__password, + .cl-formFieldDirectionsText__password, + .cl-formFieldHintText__password, + .cl-formFieldInfoText__password, + .cl-identityPreviewText { + @apply text-zinc-400; + } + + .cl-identityPreviewEditButton { + @apply text-zinc-200; + } +} diff --git a/src/styles/index.css b/src/styles/index.css index 409b436fa3..232f6bf0dd 100644 --- a/src/styles/index.css +++ b/src/styles/index.css @@ -3,3 +3,4 @@ @import './uikit.css'; @import './scrollbar.css'; @import './print.css'; +@import './clerk.css'; diff --git a/tailwind.config.ts b/tailwind.config.ts index 95534cae07..1d4e33bd44 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -242,7 +242,7 @@ export default resolveConfig({ 'color-scheme': 'dark', primary: '#1f8f93', secondary: '#92bbff', - accent: '#1f8f93', + accent: '#39C5BB', neutral: UIKitColors.grey3.dark,