Remove auth page transition and add crossfade to the auth cards, change error messages, and fix auth buttons when showing reset page.

This commit is contained in:
Bradley Shellnut 2024-07-18 16:52:11 -07:00
parent ac8721d264
commit 70b4407637
11 changed files with 442 additions and 423 deletions

View file

@ -25,17 +25,17 @@
"devDependencies": {
"@melt-ui/pp": "^0.3.2",
"@melt-ui/svelte": "^0.83.0",
"@playwright/test": "^1.45.1",
"@playwright/test": "^1.45.2",
"@resvg/resvg-js": "^2.6.2",
"@sveltejs/adapter-auto": "^3.2.2",
"@sveltejs/enhanced-img": "^0.3.0",
"@sveltejs/kit": "^2.5.18",
"@sveltejs/vite-plugin-svelte": "^3.1.1",
"@types/cookie": "^0.6.0",
"@types/node": "^20.14.10",
"@types/node": "^20.14.11",
"@types/pg": "^8.11.6",
"@typescript-eslint/eslint-plugin": "^7.16.0",
"@typescript-eslint/parser": "^7.16.0",
"@typescript-eslint/eslint-plugin": "^7.16.1",
"@typescript-eslint/parser": "^7.16.1",
"autoprefixer": "^10.4.19",
"drizzle-kit": "^0.23.0",
"eslint": "^8.57.0",
@ -48,7 +48,7 @@
"postcss-load-config": "^5.1.0",
"postcss-preset-env": "^9.6.0",
"prettier": "^3.3.3",
"prettier-plugin-svelte": "^3.2.5",
"prettier-plugin-svelte": "^3.2.6",
"sass": "^1.77.8",
"satori": "^0.10.14",
"satori-html": "^0.3.2",
@ -60,7 +60,7 @@
"svelte-sequential-preprocessor": "^2.0.1",
"sveltekit-flash-message": "^2.4.4",
"sveltekit-rate-limiter": "^0.5.2",
"sveltekit-superforms": "^2.16.0",
"sveltekit-superforms": "^2.16.1",
"tailwindcss": "^3.4.6",
"ts-node": "^10.9.2",
"tslib": "^2.6.3",

View file

@ -31,7 +31,7 @@ importers:
version: 2.2.2
'@sveltejs/adapter-vercel':
specifier: ^5.4.1
version: 5.4.1(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))
version: 5.4.1(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))
'@types/feather-icons':
specifier: ^4.29.4
version: 4.29.4
@ -67,7 +67,7 @@ importers:
version: 4.29.2
formsnap:
specifier: ^1.0.1
version: 1.0.1(svelte@5.0.0-next.175)(sveltekit-superforms@2.16.0(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))(svelte@5.0.0-next.175))
version: 1.0.1(svelte@5.0.0-next.175)(sveltekit-superforms@2.16.1(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))(svelte@5.0.0-next.175))
html-entities:
specifier: ^2.5.2
version: 2.5.2
@ -118,10 +118,10 @@ importers:
version: 2.4.0
tailwind-variants:
specifier: ^0.2.1
version: 0.2.1(tailwindcss@3.4.6(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3)))
version: 0.2.1(tailwindcss@3.4.6(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))
tailwindcss-animate:
specifier: ^1.0.7
version: 1.0.7(tailwindcss@3.4.6(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3)))
version: 1.0.7(tailwindcss@3.4.6(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))
zod-to-json-schema:
specifier: ^3.23.1
version: 3.23.1(zod@3.23.8)
@ -133,38 +133,38 @@ importers:
specifier: ^0.83.0
version: 0.83.0(svelte@5.0.0-next.175)
'@playwright/test':
specifier: ^1.45.1
version: 1.45.1
specifier: ^1.45.2
version: 1.45.2
'@resvg/resvg-js':
specifier: ^2.6.2
version: 2.6.2
'@sveltejs/adapter-auto':
specifier: ^3.2.2
version: 3.2.2(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))
version: 3.2.2(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))
'@sveltejs/enhanced-img':
specifier: ^0.3.0
version: 0.3.0(rollup@4.18.1)(svelte@5.0.0-next.175)
'@sveltejs/kit':
specifier: ^2.5.18
version: 2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8))
version: 2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8))
'@sveltejs/vite-plugin-svelte':
specifier: ^3.1.1
version: 3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8))
version: 3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8))
'@types/cookie':
specifier: ^0.6.0
version: 0.6.0
'@types/node':
specifier: ^20.14.10
version: 20.14.10
specifier: ^20.14.11
version: 20.14.11
'@types/pg':
specifier: ^8.11.6
version: 8.11.6
'@typescript-eslint/eslint-plugin':
specifier: ^7.16.0
version: 7.16.0(@typescript-eslint/parser@7.16.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0)(typescript@5.5.3)
specifier: ^7.16.1
version: 7.16.1(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0)(typescript@5.5.3)
'@typescript-eslint/parser':
specifier: ^7.16.0
version: 7.16.0(eslint@8.57.0)(typescript@5.5.3)
specifier: ^7.16.1
version: 7.16.1(eslint@8.57.0)(typescript@5.5.3)
autoprefixer:
specifier: ^10.4.19
version: 10.4.19(postcss@8.4.39)
@ -179,7 +179,7 @@ importers:
version: 9.1.0(eslint@8.57.0)
eslint-plugin-svelte:
specifier: ^2.42.0
version: 2.42.0(eslint@8.57.0)(svelte@5.0.0-next.175)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))
version: 2.42.0(eslint@8.57.0)(svelte@5.0.0-next.175)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3))
just-clone:
specifier: ^6.2.0
version: 6.2.0
@ -202,8 +202,8 @@ importers:
specifier: ^3.3.3
version: 3.3.3
prettier-plugin-svelte:
specifier: ^3.2.5
version: 3.2.5(prettier@3.3.3)(svelte@5.0.0-next.175)
specifier: ^3.2.6
version: 3.2.6(prettier@3.3.3)(svelte@5.0.0-next.175)
sass:
specifier: ^1.77.8
version: 1.77.8
@ -233,19 +233,19 @@ importers:
version: 2.0.1
sveltekit-flash-message:
specifier: ^2.4.4
version: 2.4.4(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))(svelte@5.0.0-next.175)
version: 2.4.4(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))(svelte@5.0.0-next.175)
sveltekit-rate-limiter:
specifier: ^0.5.2
version: 0.5.2(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))
version: 0.5.2(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))
sveltekit-superforms:
specifier: ^2.16.0
version: 2.16.0(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))(svelte@5.0.0-next.175)
specifier: ^2.16.1
version: 2.16.1(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))(svelte@5.0.0-next.175)
tailwindcss:
specifier: ^3.4.6
version: 3.4.6(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))
version: 3.4.6(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3))
ts-node:
specifier: ^10.9.2
version: 10.9.2(@types/node@20.14.10)(typescript@5.5.3)
version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3)
tslib:
specifier: ^2.6.3
version: 2.6.3
@ -257,10 +257,10 @@ importers:
version: 5.5.3
vite:
specifier: ^5.3.4
version: 5.3.4(@types/node@20.14.10)(sass@1.77.8)
version: 5.3.4(@types/node@20.14.11)(sass@1.77.8)
vitest:
specifier: ^1.6.0
version: 1.6.0(@types/node@20.14.10)(sass@1.77.8)
version: 1.6.0(@types/node@20.14.11)(sass@1.77.8)
zod:
specifier: ^3.23.8
version: 3.23.8
@ -275,11 +275,11 @@ packages:
resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
engines: {node: '>=6.0.0'}
'@arktype/schema@0.1.13':
resolution: {integrity: sha512-qZjtCAKrnhsixDWsEGJtosWfi4bLpAg4OnnICVYTer/6v5hwlhsdYpYobTSJUc5eiBoI5Ai/kcNfYaQISshY2g==}
'@ark/schema@0.2.0':
resolution: {integrity: sha512-IkNWCSHdjaoemMXpps4uFHEAQzwJPbTAS8K2vcQpk90sa+eNBuPSVyB/81/Qyl1VYW0iX3ceGC5NL/OznQv1jg==}
'@arktype/util@0.0.48':
resolution: {integrity: sha512-U5FO5EUAJ4LoYtLSyAMmTf6CEVgslObfSQuua2zoK5Tv2FB3aESVQ3rdLfhuz+coRhlzlynbkmimyoQWwQT+aQ==}
'@ark/util@0.1.0':
resolution: {integrity: sha512-qCLYICQoCy3kEKDVwirQp8qvxhY7NJd8BhhoHaj1l3wCFAk9NUbcDsxAkPStZEMdPI/d7NcbGJe8SWZuRG2twQ==}
'@babel/runtime@7.24.8':
resolution: {integrity: sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==}
@ -1556,8 +1556,8 @@ packages:
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
engines: {node: '>=14'}
'@playwright/test@1.45.1':
resolution: {integrity: sha512-Wo1bWTzQvGA7LyKGIZc8nFSTFf2TkthGIFBR+QVNilvwouGzFd4PYukZe3rvf5PSqjHi1+1NyKSDZKcQWETzaA==}
'@playwright/test@1.45.2':
resolution: {integrity: sha512-JxG9eq92ET75EbVi3s+4sYbcG7q72ECeZNbdBlaMkGcNbiDQ4cAi8U2QP5oKkOx+1gpaiL1LDStmzCaEM1Z6fQ==}
engines: {node: '>=18'}
hasBin: true
@ -1911,8 +1911,8 @@ packages:
'@types/json-schema@7.0.15':
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
'@types/node@20.14.10':
resolution: {integrity: sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==}
'@types/node@20.14.11':
resolution: {integrity: sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==}
'@types/pg@8.11.6':
resolution: {integrity: sha512-/2WmmBXHLsfRqzfHW7BNZ8SbYzE8OSk7i3WjFYvfgRHj7S1xj+16Je5fUKv3lVdVzk/zn9TXOqf+avFCFIE0yQ==}
@ -1923,8 +1923,8 @@ packages:
'@types/validator@13.12.0':
resolution: {integrity: sha512-nH45Lk7oPIJ1RVOF6JgFI6Dy0QpHEzq4QecZhvguxYPDwT8c93prCMqAtiIttm39voZ+DDR+qkNnMpJmMBRqag==}
'@typescript-eslint/eslint-plugin@7.16.0':
resolution: {integrity: sha512-py1miT6iQpJcs1BiJjm54AMzeuMPBSPuKPlnT8HlfudbcS5rYeX5jajpLf3mrdRh9dA/Ec2FVUY0ifeVNDIhZw==}
'@typescript-eslint/eslint-plugin@7.16.1':
resolution: {integrity: sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies:
'@typescript-eslint/parser': ^7.0.0
@ -1934,8 +1934,8 @@ packages:
typescript:
optional: true
'@typescript-eslint/parser@7.16.0':
resolution: {integrity: sha512-ar9E+k7CU8rWi2e5ErzQiC93KKEFAXA2Kky0scAlPcxYblLt8+XZuHUZwlyfXILyQa95P6lQg+eZgh/dDs3+Vw==}
'@typescript-eslint/parser@7.16.1':
resolution: {integrity: sha512-u+1Qx86jfGQ5i4JjK33/FnawZRpsLxRnKzGE6EABZ40KxVT/vWsiZFEBBHjFOljmmV3MBYOHEKi0Jm9hbAOClA==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies:
eslint: ^8.56.0
@ -1944,12 +1944,12 @@ packages:
typescript:
optional: true
'@typescript-eslint/scope-manager@7.16.0':
resolution: {integrity: sha512-8gVv3kW6n01Q6TrI1cmTZ9YMFi3ucDT7i7aI5lEikk2ebk1AEjrwX8MDTdaX5D7fPXMBLvnsaa0IFTAu+jcfOw==}
'@typescript-eslint/scope-manager@7.16.1':
resolution: {integrity: sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==}
engines: {node: ^18.18.0 || >=20.0.0}
'@typescript-eslint/type-utils@7.16.0':
resolution: {integrity: sha512-j0fuUswUjDHfqV/UdW6mLtOQQseORqfdmoBNDFOqs9rvNVR2e+cmu6zJu/Ku4SDuqiJko6YnhwcL8x45r8Oqxg==}
'@typescript-eslint/type-utils@7.16.1':
resolution: {integrity: sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies:
eslint: ^8.56.0
@ -1958,12 +1958,12 @@ packages:
typescript:
optional: true
'@typescript-eslint/types@7.16.0':
resolution: {integrity: sha512-fecuH15Y+TzlUutvUl9Cc2XJxqdLr7+93SQIbcZfd4XRGGKoxyljK27b+kxKamjRkU7FYC6RrbSCg0ALcZn/xw==}
'@typescript-eslint/types@7.16.1':
resolution: {integrity: sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==}
engines: {node: ^18.18.0 || >=20.0.0}
'@typescript-eslint/typescript-estree@7.16.0':
resolution: {integrity: sha512-a5NTvk51ZndFuOLCh5OaJBELYc2O3Zqxfl3Js78VFE1zE46J2AaVuW+rEbVkQznjkmlzWsUI15BG5tQMixzZLw==}
'@typescript-eslint/typescript-estree@7.16.1':
resolution: {integrity: sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies:
typescript: '*'
@ -1971,14 +1971,14 @@ packages:
typescript:
optional: true
'@typescript-eslint/utils@7.16.0':
resolution: {integrity: sha512-PqP4kP3hb4r7Jav+NiRCntlVzhxBNWq6ZQ+zQwII1y/G/1gdIPeYDCKr2+dH6049yJQsWZiHU6RlwvIFBXXGNA==}
'@typescript-eslint/utils@7.16.1':
resolution: {integrity: sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies:
eslint: ^8.56.0
'@typescript-eslint/visitor-keys@7.16.0':
resolution: {integrity: sha512-rMo01uPy9C7XxG7AFsxa8zLnWXTF8N3PYclekWSrurvhwiw1eW88mrKiAYe6s53AUY57nTRz8dJsuuXdkAhzCg==}
'@typescript-eslint/visitor-keys@7.16.1':
resolution: {integrity: sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==}
engines: {node: ^18.18.0 || >=20.0.0}
'@ungap/structured-clone@1.2.0':
@ -2102,8 +2102,8 @@ packages:
aria-query@5.3.0:
resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==}
arktype@2.0.0-dev.21:
resolution: {integrity: sha512-dgHCjb3FK4BGvG2LuXqgdWXstbFmiYowSy0jiKnyk4KVcMT5DyIJ9d1nbQM3ztiAL3hIPmPdkmpfxUqR+BoOBQ==}
arktype@2.0.0-beta.0:
resolution: {integrity: sha512-fE3ssMiXjr/bLqFPzlDhRlXngdyHQreu7p7i8+dtcY1CA+f8WrVUcue6JxywhnqEJXPG4HOcIwQcC+q4VfeUMQ==}
array-union@2.1.0:
resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
@ -3345,13 +3345,13 @@ packages:
pkg-types@1.1.0:
resolution: {integrity: sha512-/RpmvKdxKf8uILTtoOhAgf30wYbP2Qw+L9p3Rvshx1JZVX+XQNZQFjlbmGHEGIm4CkVPlSn+NXmIM8+9oWQaSA==}
playwright-core@1.45.1:
resolution: {integrity: sha512-LF4CUUtrUu2TCpDw4mcrAIuYrEjVDfT1cHbJMfwnE2+1b8PZcFzPNgvZCvq2JfQ4aTjRCCHw5EJ2tmr2NSzdPg==}
playwright-core@1.45.2:
resolution: {integrity: sha512-ha175tAWb0dTK0X4orvBIqi3jGEt701SMxMhyujxNrgd8K0Uy5wMSwwcQHtyB4om7INUkfndx02XnQ2p6dvLDw==}
engines: {node: '>=18'}
hasBin: true
playwright@1.45.1:
resolution: {integrity: sha512-Hjrgae4kpSQBr98nhCj3IScxVeVUixqj+5oyif8TdIn2opTCPEzqAqNMeK42i3cWDCVu9MI+ZsGWw+gVR4ISBg==}
playwright@1.45.2:
resolution: {integrity: sha512-ReywF2t/0teRvNBpfIgh5e4wnrI/8Su8ssdo5XsQKpjxJj+jspm00jSoz9BTg91TT0c9HRjXO7LBNVrgYj9X0g==}
engines: {node: '>=18'}
hasBin: true
@ -3645,8 +3645,8 @@ packages:
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
engines: {node: '>= 0.8.0'}
prettier-plugin-svelte@3.2.5:
resolution: {integrity: sha512-vP/M/Goc8z4iVIvrwXwbrYVjJgA0Hf8PO1G4LBh/ocSt6vUP6sLvyu9F3ABEGr+dbKyxZjEKLkeFsWy/yYl0HQ==}
prettier-plugin-svelte@3.2.6:
resolution: {integrity: sha512-Y1XWLw7vXUQQZmgv1JAEiLcErqUniAF2wO7QJsw8BVMvpLET2dI5WpEIEJx1r11iHVdSMzQxivyfrH9On9t2IQ==}
peerDependencies:
prettier: ^3.0.0
svelte: ^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0
@ -3788,6 +3788,11 @@ packages:
engines: {node: '>=10'}
hasBin: true
semver@7.6.3:
resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==}
engines: {node: '>=10'}
hasBin: true
set-blocking@2.0.0:
resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
@ -4070,8 +4075,8 @@ packages:
peerDependencies:
'@sveltejs/kit': 1.x || 2.x
sveltekit-superforms@2.16.0:
resolution: {integrity: sha512-t5aZyMCXyahgvn7VAJ7l9S+wAv9YyMAZHYQ6gcGVZ6ecr4/DMMD2r3ajGCj1h1dWaMQ3w5zVw+SqHSAkbHsWVQ==}
sveltekit-superforms@2.16.1:
resolution: {integrity: sha512-RNBdN43xge/ADmc3s7+pfdnRGuZ9gZiqpX6VKAQCnCI+ICc5rrPv5idYbx4iuY1Ia0lRMAq1hP0x2oHaPjB+Kg==}
peerDependencies:
'@sveltejs/kit': 1.x || 2.x
svelte: 3.x || 4.x || >=5.0.0-next.51
@ -4435,12 +4440,12 @@ snapshots:
'@jridgewell/gen-mapping': 0.3.5
'@jridgewell/trace-mapping': 0.3.25
'@arktype/schema@0.1.13':
'@ark/schema@0.2.0':
dependencies:
'@arktype/util': 0.0.48
'@ark/util': 0.1.0
optional: true
'@arktype/util@0.0.48':
'@ark/util@0.1.0':
optional: true
'@babel/runtime@7.24.8':
@ -5409,9 +5414,9 @@ snapshots:
'@pkgjs/parseargs@0.11.0':
optional: true
'@playwright/test@1.45.1':
'@playwright/test@1.45.2':
dependencies:
playwright: 1.45.1
playwright: 1.45.2
'@polka/url@1.0.0-next.25': {}
@ -5604,14 +5609,14 @@ snapshots:
'@sodaru/yup-to-json-schema@2.0.1':
optional: true
'@sveltejs/adapter-auto@3.2.2(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))':
'@sveltejs/adapter-auto@3.2.2(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))':
dependencies:
'@sveltejs/kit': 2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8))
'@sveltejs/kit': 2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8))
import-meta-resolve: 4.1.0
'@sveltejs/adapter-vercel@5.4.1(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))':
'@sveltejs/adapter-vercel@5.4.1(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))':
dependencies:
'@sveltejs/kit': 2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8))
'@sveltejs/kit': 2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8))
'@vercel/nft': 0.27.2
esbuild: 0.21.5
transitivePeerDependencies:
@ -5627,9 +5632,9 @@ snapshots:
- rollup
- svelte
'@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8))':
'@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8))':
dependencies:
'@sveltejs/vite-plugin-svelte': 3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8))
'@sveltejs/vite-plugin-svelte': 3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8))
'@types/cookie': 0.6.0
cookie: 0.6.0
devalue: 5.0.0
@ -5643,28 +5648,28 @@ snapshots:
sirv: 2.0.4
svelte: 5.0.0-next.175
tiny-glob: 0.2.9
vite: 5.3.4(@types/node@20.14.10)(sass@1.77.8)
vite: 5.3.4(@types/node@20.14.11)(sass@1.77.8)
'@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8))':
'@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8))':
dependencies:
'@sveltejs/vite-plugin-svelte': 3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8))
'@sveltejs/vite-plugin-svelte': 3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8))
debug: 4.3.4
svelte: 5.0.0-next.175
vite: 5.3.4(@types/node@20.14.10)(sass@1.77.8)
vite: 5.3.4(@types/node@20.14.11)(sass@1.77.8)
transitivePeerDependencies:
- supports-color
'@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8))':
'@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8))':
dependencies:
'@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8))
'@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8))
debug: 4.3.4
deepmerge: 4.3.1
kleur: 4.1.5
magic-string: 0.30.10
svelte: 5.0.0-next.175
svelte-hmr: 0.16.0(svelte@5.0.0-next.175)
vite: 5.3.4(@types/node@20.14.10)(sass@1.77.8)
vitefu: 0.2.5(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8))
vite: 5.3.4(@types/node@20.14.11)(sass@1.77.8)
vitefu: 0.2.5(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8))
transitivePeerDependencies:
- supports-color
@ -5694,13 +5699,13 @@ snapshots:
'@types/json-schema@7.0.15':
optional: true
'@types/node@20.14.10':
'@types/node@20.14.11':
dependencies:
undici-types: 5.26.5
'@types/pg@8.11.6':
dependencies:
'@types/node': 20.14.10
'@types/node': 20.14.11
pg-protocol: 1.6.1
pg-types: 4.0.2
@ -5709,14 +5714,14 @@ snapshots:
'@types/validator@13.12.0':
optional: true
'@typescript-eslint/eslint-plugin@7.16.0(@typescript-eslint/parser@7.16.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0)(typescript@5.5.3)':
'@typescript-eslint/eslint-plugin@7.16.1(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0)(typescript@5.5.3)':
dependencies:
'@eslint-community/regexpp': 4.10.0
'@typescript-eslint/parser': 7.16.0(eslint@8.57.0)(typescript@5.5.3)
'@typescript-eslint/scope-manager': 7.16.0
'@typescript-eslint/type-utils': 7.16.0(eslint@8.57.0)(typescript@5.5.3)
'@typescript-eslint/utils': 7.16.0(eslint@8.57.0)(typescript@5.5.3)
'@typescript-eslint/visitor-keys': 7.16.0
'@typescript-eslint/parser': 7.16.1(eslint@8.57.0)(typescript@5.5.3)
'@typescript-eslint/scope-manager': 7.16.1
'@typescript-eslint/type-utils': 7.16.1(eslint@8.57.0)(typescript@5.5.3)
'@typescript-eslint/utils': 7.16.1(eslint@8.57.0)(typescript@5.5.3)
'@typescript-eslint/visitor-keys': 7.16.1
eslint: 8.57.0
graphemer: 1.4.0
ignore: 5.3.1
@ -5727,12 +5732,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/parser@7.16.0(eslint@8.57.0)(typescript@5.5.3)':
'@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.3)':
dependencies:
'@typescript-eslint/scope-manager': 7.16.0
'@typescript-eslint/types': 7.16.0
'@typescript-eslint/typescript-estree': 7.16.0(typescript@5.5.3)
'@typescript-eslint/visitor-keys': 7.16.0
'@typescript-eslint/scope-manager': 7.16.1
'@typescript-eslint/types': 7.16.1
'@typescript-eslint/typescript-estree': 7.16.1(typescript@5.5.3)
'@typescript-eslint/visitor-keys': 7.16.1
debug: 4.3.4
eslint: 8.57.0
optionalDependencies:
@ -5740,15 +5745,15 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/scope-manager@7.16.0':
'@typescript-eslint/scope-manager@7.16.1':
dependencies:
'@typescript-eslint/types': 7.16.0
'@typescript-eslint/visitor-keys': 7.16.0
'@typescript-eslint/types': 7.16.1
'@typescript-eslint/visitor-keys': 7.16.1
'@typescript-eslint/type-utils@7.16.0(eslint@8.57.0)(typescript@5.5.3)':
'@typescript-eslint/type-utils@7.16.1(eslint@8.57.0)(typescript@5.5.3)':
dependencies:
'@typescript-eslint/typescript-estree': 7.16.0(typescript@5.5.3)
'@typescript-eslint/utils': 7.16.0(eslint@8.57.0)(typescript@5.5.3)
'@typescript-eslint/typescript-estree': 7.16.1(typescript@5.5.3)
'@typescript-eslint/utils': 7.16.1(eslint@8.57.0)(typescript@5.5.3)
debug: 4.3.5
eslint: 8.57.0
ts-api-utils: 1.3.0(typescript@5.5.3)
@ -5757,37 +5762,37 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/types@7.16.0': {}
'@typescript-eslint/types@7.16.1': {}
'@typescript-eslint/typescript-estree@7.16.0(typescript@5.5.3)':
'@typescript-eslint/typescript-estree@7.16.1(typescript@5.5.3)':
dependencies:
'@typescript-eslint/types': 7.16.0
'@typescript-eslint/visitor-keys': 7.16.0
'@typescript-eslint/types': 7.16.1
'@typescript-eslint/visitor-keys': 7.16.1
debug: 4.3.4
globby: 11.1.0
is-glob: 4.0.3
minimatch: 9.0.5
semver: 7.6.2
semver: 7.6.3
ts-api-utils: 1.3.0(typescript@5.5.3)
optionalDependencies:
typescript: 5.5.3
transitivePeerDependencies:
- supports-color
'@typescript-eslint/utils@7.16.0(eslint@8.57.0)(typescript@5.5.3)':
'@typescript-eslint/utils@7.16.1(eslint@8.57.0)(typescript@5.5.3)':
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
'@typescript-eslint/scope-manager': 7.16.0
'@typescript-eslint/types': 7.16.0
'@typescript-eslint/typescript-estree': 7.16.0(typescript@5.5.3)
'@typescript-eslint/scope-manager': 7.16.1
'@typescript-eslint/types': 7.16.1
'@typescript-eslint/typescript-estree': 7.16.1(typescript@5.5.3)
eslint: 8.57.0
transitivePeerDependencies:
- supports-color
- typescript
'@typescript-eslint/visitor-keys@7.16.0':
'@typescript-eslint/visitor-keys@7.16.1':
dependencies:
'@typescript-eslint/types': 7.16.0
'@typescript-eslint/types': 7.16.1
eslint-visitor-keys: 3.4.3
'@ungap/structured-clone@1.2.0': {}
@ -5929,10 +5934,10 @@ snapshots:
dependencies:
dequal: 2.0.3
arktype@2.0.0-dev.21:
arktype@2.0.0-beta.0:
dependencies:
'@arktype/schema': 0.1.13
'@arktype/util': 0.0.48
'@ark/schema': 0.2.0
'@ark/util': 0.1.0
optional: true
array-union@2.1.0: {}
@ -6384,7 +6389,7 @@ snapshots:
dependencies:
eslint: 8.57.0
eslint-plugin-svelte@2.42.0(eslint@8.57.0)(svelte@5.0.0-next.175)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3)):
eslint-plugin-svelte@2.42.0(eslint@8.57.0)(svelte@5.0.0-next.175)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)):
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
'@jridgewell/sourcemap-codec': 1.4.15
@ -6393,7 +6398,7 @@ snapshots:
esutils: 2.0.3
known-css-properties: 0.34.0
postcss: 8.4.39
postcss-load-config: 3.1.4(postcss@8.4.39)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))
postcss-load-config: 3.1.4(postcss@8.4.39)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3))
postcss-safe-parser: 6.0.0(postcss@8.4.39)
postcss-selector-parser: 6.1.0
semver: 7.6.2
@ -6566,11 +6571,11 @@ snapshots:
cross-spawn: 7.0.3
signal-exit: 4.1.0
formsnap@1.0.1(svelte@5.0.0-next.175)(sveltekit-superforms@2.16.0(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))(svelte@5.0.0-next.175)):
formsnap@1.0.1(svelte@5.0.0-next.175)(sveltekit-superforms@2.16.1(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))(svelte@5.0.0-next.175)):
dependencies:
nanoid: 5.0.7
svelte: 5.0.0-next.175
sveltekit-superforms: 2.16.0(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))(svelte@5.0.0-next.175)
sveltekit-superforms: 2.16.1(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))(svelte@5.0.0-next.175)
fraction.js@4.3.7: {}
@ -7149,11 +7154,11 @@ snapshots:
mlly: 1.7.0
pathe: 1.1.2
playwright-core@1.45.1: {}
playwright-core@1.45.2: {}
playwright@1.45.1:
playwright@1.45.2:
dependencies:
playwright-core: 1.45.1
playwright-core: 1.45.2
optionalDependencies:
fsevents: 2.3.2
@ -7279,21 +7284,21 @@ snapshots:
'@csstools/utilities': 1.0.0(postcss@8.4.39)
postcss: 8.4.39
postcss-load-config@3.1.4(postcss@8.4.39)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3)):
postcss-load-config@3.1.4(postcss@8.4.39)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)):
dependencies:
lilconfig: 2.1.0
yaml: 1.10.2
optionalDependencies:
postcss: 8.4.39
ts-node: 10.9.2(@types/node@20.14.10)(typescript@5.5.3)
ts-node: 10.9.2(@types/node@20.14.11)(typescript@5.5.3)
postcss-load-config@4.0.2(postcss@8.4.39)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3)):
postcss-load-config@4.0.2(postcss@8.4.39)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)):
dependencies:
lilconfig: 3.1.1
yaml: 2.4.3
optionalDependencies:
postcss: 8.4.39
ts-node: 10.9.2(@types/node@20.14.10)(typescript@5.5.3)
ts-node: 10.9.2(@types/node@20.14.11)(typescript@5.5.3)
postcss-load-config@5.1.0(jiti@1.21.6)(postcss@8.4.39)(tsx@4.16.2):
dependencies:
@ -7470,7 +7475,7 @@ snapshots:
prelude-ls@1.2.1: {}
prettier-plugin-svelte@3.2.5(prettier@3.3.3)(svelte@5.0.0-next.175):
prettier-plugin-svelte@3.2.6(prettier@3.3.3)(svelte@5.0.0-next.175):
dependencies:
prettier: 3.3.3
svelte: 5.0.0-next.175
@ -7656,6 +7661,8 @@ snapshots:
semver@7.6.2: {}
semver@7.6.3: {}
set-blocking@2.0.0: {}
set-cookie-parser@2.6.0: {}
@ -7928,19 +7935,19 @@ snapshots:
magic-string: 0.30.10
zimmerframe: 1.1.2
sveltekit-flash-message@2.4.4(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))(svelte@5.0.0-next.175):
sveltekit-flash-message@2.4.4(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))(svelte@5.0.0-next.175):
dependencies:
'@sveltejs/kit': 2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8))
'@sveltejs/kit': 2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8))
svelte: 5.0.0-next.175
sveltekit-rate-limiter@0.5.2(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8))):
sveltekit-rate-limiter@0.5.2(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8))):
dependencies:
'@isaacs/ttlcache': 1.4.1
'@sveltejs/kit': 2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8))
'@sveltejs/kit': 2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8))
sveltekit-superforms@2.16.0(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))(svelte@5.0.0-next.175):
sveltekit-superforms@2.16.1(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))(svelte@5.0.0-next.175):
dependencies:
'@sveltejs/kit': 2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8))
'@sveltejs/kit': 2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)))(svelte@5.0.0-next.175)(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8))
devalue: 5.0.0
just-clone: 6.2.0
memoize-weak: 1.0.2
@ -7952,7 +7959,7 @@ snapshots:
'@sinclair/typebox': 0.32.34
'@sodaru/yup-to-json-schema': 2.0.1
'@vinejs/vine': 1.8.0
arktype: 2.0.0-dev.21
arktype: 2.0.0-beta.0
joi: 17.13.3
json-schema-to-ts: 3.1.0
superstruct: 2.0.2
@ -7965,16 +7972,16 @@ snapshots:
tailwind-merge@2.4.0: {}
tailwind-variants@0.2.1(tailwindcss@3.4.6(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))):
tailwind-variants@0.2.1(tailwindcss@3.4.6(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3))):
dependencies:
tailwind-merge: 2.4.0
tailwindcss: 3.4.6(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))
tailwindcss: 3.4.6(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3))
tailwindcss-animate@1.0.7(tailwindcss@3.4.6(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))):
tailwindcss-animate@1.0.7(tailwindcss@3.4.6(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3))):
dependencies:
tailwindcss: 3.4.6(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))
tailwindcss: 3.4.6(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3))
tailwindcss@3.4.6(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3)):
tailwindcss@3.4.6(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)):
dependencies:
'@alloc/quick-lru': 5.2.0
arg: 5.0.2
@ -7993,7 +8000,7 @@ snapshots:
postcss: 8.4.39
postcss-import: 15.1.0(postcss@8.4.39)
postcss-js: 4.0.1(postcss@8.4.39)
postcss-load-config: 4.0.2(postcss@8.4.39)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3))
postcss-load-config: 4.0.2(postcss@8.4.39)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3))
postcss-nested: 6.0.1(postcss@8.4.39)
postcss-selector-parser: 6.1.0
resolve: 1.22.8
@ -8058,14 +8065,14 @@ snapshots:
ts-interface-checker@0.1.13: {}
ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3):
ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3):
dependencies:
'@cspotcode/source-map-support': 0.8.1
'@tsconfig/node10': 1.0.11
'@tsconfig/node12': 1.0.11
'@tsconfig/node14': 1.0.3
'@tsconfig/node16': 1.0.4
'@types/node': 20.14.10
'@types/node': 20.14.11
acorn: 8.11.3
acorn-walk: 8.3.2
arg: 4.1.3
@ -8150,13 +8157,13 @@ snapshots:
transitivePeerDependencies:
- rollup
vite-node@1.6.0(@types/node@20.14.10)(sass@1.77.8):
vite-node@1.6.0(@types/node@20.14.11)(sass@1.77.8):
dependencies:
cac: 6.7.14
debug: 4.3.4
pathe: 1.1.2
picocolors: 1.0.0
vite: 5.3.4(@types/node@20.14.10)(sass@1.77.8)
vite: 5.3.4(@types/node@20.14.11)(sass@1.77.8)
transitivePeerDependencies:
- '@types/node'
- less
@ -8167,21 +8174,21 @@ snapshots:
- supports-color
- terser
vite@5.3.4(@types/node@20.14.10)(sass@1.77.8):
vite@5.3.4(@types/node@20.14.11)(sass@1.77.8):
dependencies:
esbuild: 0.21.5
postcss: 8.4.39
rollup: 4.17.2
optionalDependencies:
'@types/node': 20.14.10
'@types/node': 20.14.11
fsevents: 2.3.3
sass: 1.77.8
vitefu@0.2.5(vite@5.3.4(@types/node@20.14.10)(sass@1.77.8)):
vitefu@0.2.5(vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)):
optionalDependencies:
vite: 5.3.4(@types/node@20.14.10)(sass@1.77.8)
vite: 5.3.4(@types/node@20.14.11)(sass@1.77.8)
vitest@1.6.0(@types/node@20.14.10)(sass@1.77.8):
vitest@1.6.0(@types/node@20.14.11)(sass@1.77.8):
dependencies:
'@vitest/expect': 1.6.0
'@vitest/runner': 1.6.0
@ -8200,11 +8207,11 @@ snapshots:
strip-literal: 2.1.0
tinybench: 2.8.0
tinypool: 0.8.4
vite: 5.3.4(@types/node@20.14.10)(sass@1.77.8)
vite-node: 1.6.0(@types/node@20.14.10)(sass@1.77.8)
vite: 5.3.4(@types/node@20.14.11)(sass@1.77.8)
vite-node: 1.6.0(@types/node@20.14.11)(sass@1.77.8)
why-is-node-running: 2.2.2
optionalDependencies:
'@types/node': 20.14.10
'@types/node': 20.14.11
transitivePeerDependencies:
- less
- lightningcss

View file

@ -34,7 +34,7 @@
{#if transition.type === 'stagger'}
<div
class="stagger transition"
style:animation-duration="{transition.duration || 1 * 300}ms"
style:animation-duration="{transition.duration || 300}ms"
style:animation-delay="{transition.delay}ms"
>
<slot />

View file

@ -0,0 +1,12 @@
import { crossfade } from 'svelte/transition';
import { quintOut } from 'svelte/easing';
export const [send, receive] = crossfade({
duration: d => Math.sqrt(d * 200),
easing: quintOut,
// You can customize the fallBack if the element sizes are significantly different
fallback(node, params) {
return { duration: 600, easing: x => --x * x * x + 1 }; // Ease-out cubic
}
});

View file

@ -19,8 +19,8 @@ export const signInSchema = z.object({
username: z
.string()
.trim()
.min(3, { message: 'Username must be at least 3 characters' })
.max(50, { message: 'Username must be less than 50 characters' }),
.min(3, { message: 'Must be at least 3 characters' })
.max(50, { message: 'Must be less than 50 characters' }),
password: z.string({ required_error: 'Password is required' }).trim(),
});
@ -33,7 +33,7 @@ export const recoveryCodeSchema = z.object({
});
export const resetPasswordEmailSchema = z.object({
email: z.string().trim().max(64),
email: z.string().trim().max(64, { message: 'Email must be less than 64 characters' }),
});
export const resetPasswordTokenSchema = z.object({

View file

@ -26,8 +26,8 @@ export const userSchema = z.object({
username: z
.string()
.trim()
.min(3, { message: 'Username must be at least 3 characters' })
.max(50, { message: 'Username must be less than 50 characters' }),
.min(3, { message: 'Must be at least 3 characters' })
.max(50, { message: 'Must be less than 50 characters' }),
password: z.string({ required_error: 'Password is required' }).trim(),
confirm_password: z.string({ required_error: 'Confirm Password is required' }).trim(),
verified: z.boolean().default(false),

View file

@ -14,38 +14,24 @@
</div>
Bored Game
</a>
{#if $page.url.pathname === "/sign-up"}
<Button
href="/login"
variant="ghost"
class="auth-button"
>
Login
</Button>
{:else if $page.url.pathname === "/login"}
<Button
href="/sign-up"
variant="ghost"
class="auth-button"
>
Sign up
</Button>
{:else}
<div class="auth-buttons">
<div class="auth-buttons">
{#if $page.url.pathname !== "/login"}
<Button
href="/login"
variant="ghost"
>
Login
</Button>
{/if}
{#if $page.url.pathname !== "/sign-up"}
<Button
href="/sign-up"
variant="ghost"
>
Sign up
</Button>
</div>
{/if}
{/if}
</div>
<div class="auth-marketing">
<div
class="image"
@ -63,9 +49,7 @@
</div>
</div>
<div class="auth-form">
<Transition url={data.url} transition={{ type: 'page' }}>
{@render children()}
</Transition>
{@render children()}
</div>
</div>
@ -137,17 +121,6 @@
}
}
:global(.auth-button) {
position: absolute;
top: 1rem;
right: 1rem;
@media (min-width >= 768px) {
top: 2rem;
right: 2rem;
}
}
:global(.auth-buttons) {
position: absolute;
top: 1rem;

View file

@ -10,6 +10,7 @@
import { Input } from '$components/ui/input';
import { Button } from '$components/ui/button';
import * as Alert from "$components/ui/alert";
import { send, receive } from '$lib/utils/pageCrossfade';
import { boredState } from '$lib/stores/boredState.js';
let { data } = $props();
@ -41,24 +42,26 @@
<title>Bored Game | Login</title>
</svelte:head>
<Card.Root class="mx-auto mt-24 max-w-sm">
<Card.Header>
Log into your account
</Card.Header>
<Card.Content>
{@render usernamePasswordForm()}
<p class="px-8 py-4 text-center text-sm text-muted-foreground">
By clicking continue, you agree to our
<a href="/terms" class="underline underline-offset-4 hover:text-primary">
Terms of Use
</a>
and
<a href="/privacy" class="underline underline-offset-4 hover:text-primary">
Privacy Policy
</a>.
</p>
</Card.Content>
</Card.Root>
<div in:receive={{ key: 'auth-card' }} out:send={{ key: 'auth-card' }}>
<Card.Root class="mx-auto mt-24 max-w-sm">
<Card.Header>
<Card.Title class="text-2xl">Log into your account</Card.Title>
</Card.Header>
<Card.Content>
{@render usernamePasswordForm()}
<p class="px-8 py-4 text-center text-sm text-muted-foreground">
By clicking continue, you agree to our
<a href="/terms" class="underline underline-offset-4 hover:text-primary">
Terms of Use
</a>
and
<a href="/privacy" class="underline underline-offset-4 hover:text-primary">
Privacy Policy
</a>.
</p>
</Card.Content>
</Card.Root>
</div>
{#snippet usernamePasswordForm()}
<form method="POST" use:enhance>
@ -76,7 +79,7 @@
</Form.Control>
<Form.FieldErrors />
</Form.Field>
<div class="flex align-center justify-between">
<div class="grid grid-cols-2">
<Form.Button>Login</Form.Button>
<Button variant="link" class="text-secondary-foreground" href="/password/reset">Forgot Password?</Button>
</div>

View file

@ -1,41 +1,58 @@
import { fail, error, type Actions } from '@sveltejs/kit';
import { zod } from 'sveltekit-superforms/adapters';
import { setError, superValidate } from 'sveltekit-superforms/server';
import { redirect } from 'sveltekit-flash-message/server';
import type { PageServerLoad } from './$types';
import {resetPasswordEmailSchema, resetPasswordTokenSchema} from "$lib/validations/auth";
import {StatusCodes} from "$lib/constants/status-codes";
export const load: PageServerLoad = async (event) => {
return {
emailForm: await superValidate(zod(resetPasswordEmailSchema)),
tokenForm: await superValidate(zod(resetPasswordTokenSchema)),
};
};
export const actions = {
passwordReset: async ({ locals, request }) => {
const emailForm = await superValidate(request, zod(resetPasswordEmailSchema));
if (!emailForm.valid) {
return fail(StatusCodes.BAD_REQUEST, { emailForm });
}
const error = {};
// const { error } = await locals.api.iam.login.request.$post({ json: emailRegisterForm.data }).then(locals.parseApiResponse);
if (error) {
return setError(emailForm, 'email', error);
}
return { emailForm };
},
verifyToken: async ({ locals, request }) => {
const tokenForm = await superValidate(request, zod(resetPasswordTokenSchema));
if (!tokenForm.valid) {
return fail(StatusCodes.BAD_REQUEST, { tokenForm });
}
const error = {};
// const { error } = await locals.api.iam.login.verify.$post({ json: emailSignInForm.data }).then(locals.parseApiResponse)
if (error) {
return setError(tokenForm, 'token', error);
}
redirect(301, '/');
}
};
import { fail, error, type Actions } from '@sveltejs/kit';
import { zod } from 'sveltekit-superforms/adapters';
import { setError, superValidate } from 'sveltekit-superforms/server';
import { redirect } from 'sveltekit-flash-message/server';
import type { PageServerLoad } from './$types';
import {resetPasswordEmailSchema, resetPasswordTokenSchema} from "$lib/validations/auth";
import {StatusCodes} from "$lib/constants/status-codes";
import {userFullyAuthenticated} from "$lib/server/auth-utils";
export const load: PageServerLoad = async () => {
return {
emailForm: await superValidate(zod(resetPasswordEmailSchema)),
tokenForm: await superValidate(zod(resetPasswordTokenSchema)),
};
};
export const actions = {
passwordReset: async (event) => {
const { request, locals } = event;
const { user, session } = locals;
if (userFullyAuthenticated(user, session)) {
const message = { type: 'success', message: 'You are already signed in' } as const;
throw redirect('/', message, event);
}
const emailForm = await superValidate(request, zod(resetPasswordEmailSchema));
console.log('emailForm', emailForm);
if (!emailForm.valid) {
return fail(StatusCodes.BAD_REQUEST, { emailForm });
}
const error = {};
// const { error } = await locals.api.iam.login.request.$post({ json: emailRegisterForm.data }).then(locals.parseApiResponse);
if (error) {
return setError(emailForm, 'email', error);
}
return { emailForm };
},
verifyToken: async (event) => {
const { request, locals } = event;
const { user, session } = locals;
if (userFullyAuthenticated(user, session)) {
const message = { type: 'success', message: 'You are already signed in' } as const;
throw redirect('/', message, event);
}
const tokenForm = await superValidate(request, zod(resetPasswordTokenSchema));
if (!tokenForm.valid) {
return fail(StatusCodes.BAD_REQUEST, { tokenForm });
}
const error = {};
// const { error } = await locals.api.iam.login.verify.$post({ json: emailSignInForm.data }).then(locals.parseApiResponse)
if (error) {
return setError(tokenForm, 'token', error);
}
redirect(301, '/');
}
};

View file

@ -1,85 +1,89 @@
<script lang="ts">
import { Button } from "$lib/components/ui/button/index.js";
import * as Card from "$lib/components/ui/card/index.js";
import { Input } from "$lib/components/ui/input/index.js";
import { Label } from "$lib/components/ui/label/index.js";
import { superForm } from 'sveltekit-superforms';
import * as Form from '$lib/components/ui/form';
import { zodClient } from 'sveltekit-superforms/adapters';
import { resetPasswordEmailSchema, resetPasswordTokenSchema } from "$lib/validations/auth";
import PinInput from "$lib/components/pin-input.svelte";
const {data} = $props();
let showTokenVerification = $state(false);
const emailResetForm = superForm(data.emailForm, {
validators: zodClient(resetPasswordEmailSchema),
resetForm: false,
onUpdated: ({ form }) => {
if (form.valid) {
showTokenVerification = true;
$emailFormData.email = form.data.email;
}
}
});
const tokenVerificationForm = superForm(data.tokenForm, {
validators: zodClient(resetPasswordTokenSchema),
resetForm: false
});
const { form: emailFormData, enhance: emailRegisterEnhance } = emailResetForm;
const { form: tokenFormData, enhance: tokenEnhance } = tokenVerificationForm;
</script>
<Card.Root class="mx-auto mt-24 max-w-sm">
<Card.Header>
<Card.Title class="text-2xl">Reset Password</Card.Title>
<Card.Description>Enter your email to reset your password</Card.Description>
</Card.Header>
<Card.Content>
<div class="grid gap-4">
{#if showTokenVerification}
{@render tokenForm()}
{:else}
{@render emailForm()}
{/if}
</div>
</Card.Content>
</Card.Root>
{#snippet emailForm()}
<form method="POST" action="?/passwordReset" use:emailRegisterEnhance class="grid gap-4">
<Form.Field form={emailResetForm} name="email">
<Form.Control let:attrs>
<Form.Label>Email</Form.Label>
<Input
{...attrs}
type="email"
placeholder="you@awesome.com"
bind:value={$emailFormData.email}
/>
</Form.Control>
<Form.Description />
<Form.FieldErrors />
</Form.Field>
<Button type="submit" class="w-full">Continue with Email</Button>
</form>
{/snippet}
{#snippet tokenForm()}
<form method="POST" action="?/verifyToken" use:tokenEnhance class="space-y-4">
<input hidden value={$tokenFormData.resetToken} name="email" />
<Form.Field form={tokenVerificationForm} name="resetToken">
<Form.Control let:attrs>
<Form.Label />
<PinInput class="justify-evenly" {...attrs} bind:value={$tokenFormData.resetToken} />
</Form.Control>
<Form.Description />
<Form.FieldErrors />
</Form.Field>
<Button class="w-full" type="submit">Submit</Button>
</form>
<script lang="ts">
import { superForm } from 'sveltekit-superforms';
import { zodClient } from 'sveltekit-superforms/adapters';
import { Button } from "$lib/components/ui/button/index.js";
import * as Card from "$lib/components/ui/card/index.js";
import { Input } from "$lib/components/ui/input/index.js";
import { Label } from "$lib/components/ui/label/index.js";
import * as Form from '$lib/components/ui/form';
import { send, receive } from '$lib/utils/pageCrossfade';
import { resetPasswordEmailSchema, resetPasswordTokenSchema } from "$lib/validations/auth";
import PinInput from "$lib/components/pin-input.svelte";
const {data} = $props();
let showTokenVerification = $state(false);
const emailResetForm = superForm(data.emailForm, {
validators: zodClient(resetPasswordEmailSchema),
resetForm: false,
onUpdated: ({ form }) => {
console.log('form', form);
if (form.valid) {
showTokenVerification = true;
$emailFormData.email = form.data.email;
}
}
});
const tokenVerificationForm = superForm(data.tokenForm, {
validators: zodClient(resetPasswordTokenSchema),
resetForm: false
});
const { form: emailFormData, enhance: emailResetEnhance } = emailResetForm;
const { form: tokenFormData, enhance: tokenEnhance } = tokenVerificationForm;
</script>
<div out:send={{ key: 'auth-card' }} in:receive={{ key: 'auth-card' }}>
<Card.Root class="mx-auto max-w-sm">
<Card.Header>
<Card.Title class="text-2xl">Reset Password</Card.Title>
<Card.Description>Enter your email to reset your password</Card.Description>
</Card.Header>
<Card.Content>
<div class="grid gap-4">
{#if showTokenVerification}
{@render tokenForm()}
{:else}
{@render emailForm()}
{/if}
</div>
</Card.Content>
</Card.Root>
</div>
{#snippet emailForm()}
<form method="POST" action="?/passwordReset" use:emailResetEnhance class="grid gap-4">
<Form.Field form={emailResetForm} name="email">
<Form.Control let:attrs>
<Form.Label>Email</Form.Label>
<Input
{...attrs}
type="email"
placeholder="you@awesome.com"
bind:value={$emailFormData.email}
/>
</Form.Control>
<Form.Description />
<Form.FieldErrors />
</Form.Field>
<Button type="submit" class="w-full">Continue with Email</Button>
</form>
{/snippet}
{#snippet tokenForm()}
<form method="POST" action="?/verifyToken" use:tokenEnhance class="space-y-4">
<input hidden value={$tokenFormData.resetToken} name="email" />
<Form.Field form={tokenVerificationForm} name="resetToken">
<Form.Control let:attrs>
<Form.Label>Enter the token that was sent to your email</Form.Label>
<PinInput class="justify-evenly" {...attrs} bind:value={$tokenFormData.resetToken} />
</Form.Control>
<Form.Description />
<Form.FieldErrors />
</Form.Field>
<Button class="w-full" type="submit">Submit</Button>
</form>
{/snippet}

View file

@ -12,6 +12,7 @@
import * as Alert from '$lib/components/ui/alert';
import * as Card from '$lib/components/ui/card';
import * as Collapsible from '$lib/components/ui/collapsible';
import { send, receive } from '$lib/utils/pageCrossfade';
import { boredState } from '$lib/stores/boredState.js';
export let data;
@ -38,91 +39,93 @@
<title>Bored Game | Sign Up</title>
</svelte:head>
<Card.Root class="mx-auto mt-24 max-w-sm">
<Card.Header>
Signup for an account
</Card.Header>
<Card.Content>
<form method="POST" action="/sign-up" use:enhance>
<Label for="username">Username</Label>
<Input type="text" id="username" class={$errors.username && "outline outline-destructive"} name="username"
placeholder="Username" autocomplete="username" data-invalid={$errors.username} bind:value={$form.username} />
{#if $errors.username}
<p class="text-sm text-destructive">{$errors.username}</p>
{/if}
<Label for="password">Password</Label>
<Input type="password" id="password" class={$errors.password && "outline outline-destructive"} name="password"
placeholder="Password" autocomplete="new-password" data-invalid={$errors.password}
bind:value={$form.password} />
{#if $errors.password}
<p class="text-sm text-destructive">{$errors.password}</p>
{/if}
<Label for="confirm_password">Confirm Password</Label>
<Input type="password" id="confirm_password" class={$errors.confirm_password && "outline outline-destructive"}
name="confirm_password" placeholder="Confirm Password" autocomplete="new-password"
data-invalid={$errors.confirm_password} bind:value={$form.confirm_password} />
{#if $errors.confirm_password}
<p class="text-sm text-destructive">{$errors.confirm_password}</p>
{/if}
<Collapsible.Root bind:open={collapsibleOpen} class="grid w-full max-w-sm items-center gap-2.5">
<div>
Optional Fields:
<Collapsible.Trigger asChild let:builder>
<Button builders={[builder]} variant="ghost" size="sm" type="button" class="w-9 p-0">
<ChevronsUpDown class="h-4 w-4" />
<span class="sr-only">Toggle</span>
</Button>
</Collapsible.Trigger>
</div>
<Collapsible.Content>
<div transition:slide|global={{ delay: 10, duration: 150, easing: quintIn }}>
<Label for="email">Email</Label>
<Input type="email" id="email" class={$errors.email && "outline outline-destructive"} name="email"
placeholder="Email" autocomplete="email" data-invalid={$errors.email} bind:value={$form.email} />
{#if $errors.email}
<p class="text-sm text-destructive">{$errors.email}</p>
{/if}
<div in:receive={{ key: 'auth-card' }} out:send={{ key: 'auth-card' }}>
<Card.Root class="mx-auto mt-24 max-w-sm">
<Card.Header>
<Card.Title class="text-2xl">Signup for an account</Card.Title>
</Card.Header>
<Card.Content>
<form method="POST" action="/sign-up" use:enhance class="grid gap-2 mt-4">
<Label for="username">Username <small>(required)</small></Label>
<Input type="text" id="username" class={$errors.username && "outline outline-destructive"} name="username"
placeholder="Username" autocomplete="username" data-invalid={$errors.username} bind:value={$form.username} />
{#if $errors.username}
<p class="text-sm text-destructive">{$errors.username}</p>
{/if}
<Label for="password">Password <small>(required)</small></Label>
<Input type="password" id="password" class={$errors.password && "outline outline-destructive"} name="password"
placeholder="Password" autocomplete="new-password" data-invalid={$errors.password}
bind:value={$form.password} />
{#if $errors.password}
<p class="text-sm text-destructive">{$errors.password}</p>
{/if}
<Label for="confirm_password">Confirm Password <small>(required)</small></Label>
<Input type="password" id="confirm_password" class={$errors.confirm_password && "outline outline-destructive"}
name="confirm_password" placeholder="Confirm Password" autocomplete="new-password"
data-invalid={$errors.confirm_password} bind:value={$form.confirm_password} />
{#if $errors.confirm_password}
<p class="text-sm text-destructive">{$errors.confirm_password}</p>
{/if}
<Collapsible.Root bind:open={collapsibleOpen} class="grid w-full max-w-sm items-center gap-2.5">
<div>
Optional Fields:
<Collapsible.Trigger asChild let:builder>
<Button builders={[builder]} variant="ghost" size="sm" type="button" class="w-9 p-0">
<ChevronsUpDown class="h-4 w-4" />
<span class="sr-only">Toggle</span>
</Button>
</Collapsible.Trigger>
</div>
<Collapsible.Content>
<div transition:slide|global={{ delay: 10, duration: 150, easing: quintIn }}>
<Label for="email">Email</Label>
<Input type="email" id="email" class={$errors.email && "outline outline-destructive"} name="email"
placeholder="Email" autocomplete="email" data-invalid={$errors.email} bind:value={$form.email} />
{#if $errors.email}
<p class="text-sm text-destructive">{$errors.email}</p>
{/if}
</div>
</Collapsible.Content>
<Collapsible.Content>
<div transition:slide|global={{ delay: 10, duration: 150, easing: quintIn }}>
<Label for="firstName">First Name</Label>
<Input type="text" id="firstName" class={$errors.firstName && "outline outline-destructive"} name="firstName"
placeholder="First Name" autocomplete="given-name" data-invalid={$errors.firstName}
bind:value={$form.firstName} />
{#if $errors.firstName}
<p class="text-sm text-destructive">{$errors.firstName}</p>
{/if}
</div>
</Collapsible.Content>
<Collapsible.Content>
<div transition:slide|global={{ delay: 10, duration: 150, easing: quintIn }}>
<Label for="firstName">Last Name</Label>
<Input type="text" id="lastName" class={$errors.firstName && "outline outline-destructive"} name="lastName"
placeholder="Last Name" autocomplete="family-name" data-invalid={$errors.lastName}
bind:value={$form.lastName} />
{#if $errors.lastName}
<p class="text-sm text-destructive">{$errors.lastName}</p>
{/if}
</div>
</Collapsible.Content>
</Collapsible.Root>
<div class="grid grid-cols-2">
<Button type="submit">Signup</Button>
<Button variant="link" class="text-secondary-foreground" href="/">or Cancel</Button>
</div>
</Collapsible.Content>
<Collapsible.Content>
<div transition:slide|global={{ delay: 10, duration: 150, easing: quintIn }}>
<Label for="firstName">First Name</Label>
<Input type="text" id="firstName" class={$errors.firstName && "outline outline-destructive"} name="firstName"
placeholder="First Name" autocomplete="given-name" data-invalid={$errors.firstName}
bind:value={$form.firstName} />
{#if $errors.firstName}
<p class="text-sm text-destructive">{$errors.firstName}</p>
{/if}
</div>
</Collapsible.Content>
<Collapsible.Content>
<div transition:slide|global={{ delay: 10, duration: 150, easing: quintIn }}>
<Label for="firstName">Last Name</Label>
<Input type="text" id="lastName" class={$errors.firstName && "outline outline-destructive"} name="lastName"
placeholder="Last Name" autocomplete="family-name" data-invalid={$errors.lastName}
bind:value={$form.lastName} />
{#if $errors.lastName}
<p class="text-sm text-destructive">{$errors.lastName}</p>
{/if}
</div>
</Collapsible.Content>
</Collapsible.Root>
<div class="grid grid-cols-2">
<Button type="submit">Signup</Button>
<Button variant="link" class="text-secondary-foreground" href="/">or Cancel</Button>
</div>
{#if !$form.email}
<Alert.Root>
<Alert.Title level="h3">Heads up!</Alert.Title>
<Alert.Description>
Without an email address, you won't be able to reset your password. Submit only if you are sure. You can
always add this later.
</Alert.Description>
</Alert.Root>
{/if}
</form>
</Card.Content>
</Card.Root>
{#if !$form.email}
<Alert.Root>
<Alert.Title level="h3">Heads up!</Alert.Title>
<Alert.Description>
Without an email address, you won't be able to reset your password. Submit only if you are sure. You can
always add this later.
</Alert.Description>
</Alert.Root>
{/if}
</form>
</Card.Content>
</Card.Root>
</div>
<style lang="postcss">
.sign-up {