mirror of
https://github.com/BradNut/AdelieStack
synced 2025-09-08 17:40:20 +00:00
Adding profile update for username, firstname, and lastname.
This commit is contained in:
parent
da0df78c05
commit
c5e310bf95
14 changed files with 268 additions and 50 deletions
|
|
@ -40,7 +40,7 @@
|
||||||
"@storybook/test": "^8.4.7",
|
"@storybook/test": "^8.4.7",
|
||||||
"@sveltejs/adapter-node": "^5.2.9",
|
"@sveltejs/adapter-node": "^5.2.9",
|
||||||
"@sveltejs/enhanced-img": "^0.4.4",
|
"@sveltejs/enhanced-img": "^0.4.4",
|
||||||
"@sveltejs/kit": "^2.15.1",
|
"@sveltejs/kit": "^2.15.2",
|
||||||
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
||||||
"@types/cookie": "^1.0.0",
|
"@types/cookie": "^1.0.0",
|
||||||
"@types/node": "^22.10.5",
|
"@types/node": "^22.10.5",
|
||||||
|
|
@ -63,7 +63,7 @@
|
||||||
"svelte-preprocess": "^6.0.3",
|
"svelte-preprocess": "^6.0.3",
|
||||||
"svelte-sequential-preprocessor": "^2.0.2",
|
"svelte-sequential-preprocessor": "^2.0.2",
|
||||||
"svelte-sonner": "^0.3.28",
|
"svelte-sonner": "^0.3.28",
|
||||||
"sveltekit-flash-message": "^2.4.4",
|
"sveltekit-flash-message": "^2.4.5",
|
||||||
"sveltekit-superforms": "^2.22.1",
|
"sveltekit-superforms": "^2.22.1",
|
||||||
"tailwind-merge": "^2.6.0",
|
"tailwind-merge": "^2.6.0",
|
||||||
"tailwind-variants": "^0.3.0",
|
"tailwind-variants": "^0.3.0",
|
||||||
|
|
@ -92,8 +92,8 @@
|
||||||
"@oslojs/webauthn": "^1.0.0",
|
"@oslojs/webauthn": "^1.0.0",
|
||||||
"@scalar/hono-api-reference": "^0.5.162",
|
"@scalar/hono-api-reference": "^0.5.162",
|
||||||
"@tailwindcss/container-queries": "^0.1.1",
|
"@tailwindcss/container-queries": "^0.1.1",
|
||||||
"@tailwindcss/forms": "^0.5.9",
|
"@tailwindcss/forms": "^0.5.10",
|
||||||
"@tailwindcss/typography": "^0.5.15",
|
"@tailwindcss/typography": "^0.5.16",
|
||||||
"arctic": "^3.1.0",
|
"arctic": "^3.1.0",
|
||||||
"argon2": "^0.41.1",
|
"argon2": "^0.41.1",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ importers:
|
||||||
version: 0.4.2(hono@4.6.16)(zod@3.24.1)
|
version: 0.4.2(hono@4.6.16)(zod@3.24.1)
|
||||||
'@inlang/paraglide-sveltekit':
|
'@inlang/paraglide-sveltekit':
|
||||||
specifier: ^0.15.4
|
specifier: ^0.15.4
|
||||||
version: 0.15.4(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))
|
version: 0.15.4(@sveltejs/kit@2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))
|
||||||
'@internationalized/date':
|
'@internationalized/date':
|
||||||
specifier: ^3.5.5
|
specifier: ^3.5.5
|
||||||
version: 3.6.0
|
version: 3.6.0
|
||||||
|
|
@ -54,11 +54,11 @@ importers:
|
||||||
specifier: ^0.1.1
|
specifier: ^0.1.1
|
||||||
version: 0.1.1(tailwindcss@3.4.17)
|
version: 0.1.1(tailwindcss@3.4.17)
|
||||||
'@tailwindcss/forms':
|
'@tailwindcss/forms':
|
||||||
specifier: ^0.5.9
|
specifier: ^0.5.10
|
||||||
version: 0.5.9(tailwindcss@3.4.17)
|
version: 0.5.10(tailwindcss@3.4.17)
|
||||||
'@tailwindcss/typography':
|
'@tailwindcss/typography':
|
||||||
specifier: ^0.5.15
|
specifier: ^0.5.16
|
||||||
version: 0.5.15(tailwindcss@3.4.17)
|
version: 0.5.16(tailwindcss@3.4.17)
|
||||||
arctic:
|
arctic:
|
||||||
specifier: ^3.1.0
|
specifier: ^3.1.0
|
||||||
version: 3.1.0
|
version: 3.1.0
|
||||||
|
|
@ -170,13 +170,13 @@ importers:
|
||||||
version: 8.4.7(storybook@8.4.7)
|
version: 8.4.7(storybook@8.4.7)
|
||||||
'@sveltejs/adapter-node':
|
'@sveltejs/adapter-node':
|
||||||
specifier: ^5.2.9
|
specifier: ^5.2.9
|
||||||
version: 5.2.11(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))
|
version: 5.2.11(@sveltejs/kit@2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))
|
||||||
'@sveltejs/enhanced-img':
|
'@sveltejs/enhanced-img':
|
||||||
specifier: ^0.4.4
|
specifier: ^0.4.4
|
||||||
version: 0.4.4(rollup@4.29.1)(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
|
version: 0.4.4(rollup@4.29.1)(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
|
||||||
'@sveltejs/kit':
|
'@sveltejs/kit':
|
||||||
specifier: ^2.15.1
|
specifier: ^2.15.2
|
||||||
version: 2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
|
version: 2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
|
||||||
'@sveltejs/vite-plugin-svelte':
|
'@sveltejs/vite-plugin-svelte':
|
||||||
specifier: ^5.0.3
|
specifier: ^5.0.3
|
||||||
version: 5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
|
version: 5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
|
||||||
|
|
@ -212,7 +212,7 @@ importers:
|
||||||
version: 0.30.1
|
version: 0.30.1
|
||||||
formsnap:
|
formsnap:
|
||||||
specifier: ^2.0.0
|
specifier: ^2.0.0
|
||||||
version: 2.0.0(svelte@5.16.5)(sveltekit-superforms@2.22.1(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.16.5)(typescript@5.7.2))
|
version: 2.0.0(svelte@5.16.5)(sveltekit-superforms@2.22.1(@sveltejs/kit@2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.16.5)(typescript@5.7.2))
|
||||||
lucide-svelte:
|
lucide-svelte:
|
||||||
specifier: ^0.469.0
|
specifier: ^0.469.0
|
||||||
version: 0.469.0(svelte@5.16.5)
|
version: 0.469.0(svelte@5.16.5)
|
||||||
|
|
@ -241,11 +241,11 @@ importers:
|
||||||
specifier: ^0.3.28
|
specifier: ^0.3.28
|
||||||
version: 0.3.28(svelte@5.16.5)
|
version: 0.3.28(svelte@5.16.5)
|
||||||
sveltekit-flash-message:
|
sveltekit-flash-message:
|
||||||
specifier: ^2.4.4
|
specifier: ^2.4.5
|
||||||
version: 2.4.4(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)
|
version: 2.4.5(@sveltejs/kit@2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)
|
||||||
sveltekit-superforms:
|
sveltekit-superforms:
|
||||||
specifier: ^2.22.1
|
specifier: ^2.22.1
|
||||||
version: 2.22.1(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.16.5)(typescript@5.7.2)
|
version: 2.22.1(@sveltejs/kit@2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.16.5)(typescript@5.7.2)
|
||||||
tailwind-merge:
|
tailwind-merge:
|
||||||
specifier: ^2.6.0
|
specifier: ^2.6.0
|
||||||
version: 2.6.0
|
version: 2.6.0
|
||||||
|
|
@ -2206,8 +2206,8 @@ packages:
|
||||||
svelte: ^5.0.0
|
svelte: ^5.0.0
|
||||||
vite: '>= 5.0.0'
|
vite: '>= 5.0.0'
|
||||||
|
|
||||||
'@sveltejs/kit@2.15.1':
|
'@sveltejs/kit@2.15.2':
|
||||||
resolution: {integrity: sha512-8t7D3hQHbUDMiaQ2RVnjJJ/+Ur4Fn/tkeySJCsHtX346Q9cp3LAnav8xXdfuqYNJwpUGX0x3BqF1uvbmXQw93A==}
|
resolution: {integrity: sha512-p208T1kdM6zd8k4YXIUM60pLWQ8dZqehXSiqn4NulXHyHibX53uIAL2xtNL8GjxX2IVPqPRT978MwVYhCKExdQ==}
|
||||||
engines: {node: '>=18.13'}
|
engines: {node: '>=18.13'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
|
@ -2238,15 +2238,15 @@ packages:
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
tailwindcss: '>=3.2.0'
|
tailwindcss: '>=3.2.0'
|
||||||
|
|
||||||
'@tailwindcss/forms@0.5.9':
|
'@tailwindcss/forms@0.5.10':
|
||||||
resolution: {integrity: sha512-tM4XVr2+UVTxXJzey9Twx48c1gcxFStqn1pQz0tRsX8o3DvxhN5oY5pvyAbUx7VTaZxpej4Zzvc6h+1RJBzpIg==}
|
resolution: {integrity: sha512-utI1ONF6uf/pPNO68kmN1b8rEwNXv3czukalo8VtJH8ksIkZXr3Q3VYudZLkCsDd4Wku120uF02hYK25XGPorw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20'
|
tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1'
|
||||||
|
|
||||||
'@tailwindcss/typography@0.5.15':
|
'@tailwindcss/typography@0.5.16':
|
||||||
resolution: {integrity: sha512-AqhlCXl+8grUz8uqExv5OTtgpjuVIwFTSXTrh8y9/pw6q2ek7fJ+Y8ZEVw7EB2DCcuCOtEjf9w3+J3rzts01uA==}
|
resolution: {integrity: sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
tailwindcss: '>=3.0.0 || insiders || >=4.0.0-alpha.20'
|
tailwindcss: '>=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1'
|
||||||
|
|
||||||
'@testing-library/dom@10.4.0':
|
'@testing-library/dom@10.4.0':
|
||||||
resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==}
|
resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==}
|
||||||
|
|
@ -4724,8 +4724,8 @@ packages:
|
||||||
resolution: {integrity: sha512-sWJRa4qOfRdSORSVw9GhfDEwsbsYsegnDzBevUCF6k/Eis/QqCu9lJ6I0+d/E2wOWCjOhlcJ3+jl/Iur+5mmCw==}
|
resolution: {integrity: sha512-sWJRa4qOfRdSORSVw9GhfDEwsbsYsegnDzBevUCF6k/Eis/QqCu9lJ6I0+d/E2wOWCjOhlcJ3+jl/Iur+5mmCw==}
|
||||||
engines: {node: '>=10.0.0'}
|
engines: {node: '>=10.0.0'}
|
||||||
|
|
||||||
sveltekit-flash-message@2.4.4:
|
sveltekit-flash-message@2.4.5:
|
||||||
resolution: {integrity: sha512-CFN03chH/FMEJcBZ/8zKm7RqGee/pwb57Spbbx8QCQPhe7N9ofZHd9iYV2vVy4E9glBo/oQ1IG7VQje6L092wg==}
|
resolution: {integrity: sha512-CPJwgZbXkPs7Tsl8vK81d6FPqWO4NiuwAkx57zaOIuhDu9wSq0V4rc4TuRtVwWTjOmHwnXClRana+WCXwKHOFQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@sveltejs/kit': 1.x || 2.x
|
'@sveltejs/kit': 1.x || 2.x
|
||||||
svelte: 3.x || 4.x || >=5.0.0-next.51
|
svelte: 3.x || 4.x || >=5.0.0-next.51
|
||||||
|
|
@ -5964,12 +5964,12 @@ snapshots:
|
||||||
- debug
|
- debug
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@inlang/paraglide-sveltekit@0.15.4(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))':
|
'@inlang/paraglide-sveltekit@0.15.4(@sveltejs/kit@2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@inlang/paraglide-js': 1.11.7
|
'@inlang/paraglide-js': 1.11.7
|
||||||
'@inlang/paraglide-vite': 1.3.4
|
'@inlang/paraglide-vite': 1.3.4
|
||||||
'@lix-js/client': 2.2.1
|
'@lix-js/client': 2.2.1
|
||||||
'@sveltejs/kit': 2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
|
'@sveltejs/kit': 2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
|
||||||
commander: 12.1.0
|
commander: 12.1.0
|
||||||
dedent: 1.5.1
|
dedent: 1.5.1
|
||||||
devalue: 4.3.3
|
devalue: 4.3.3
|
||||||
|
|
@ -6851,12 +6851,12 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
storybook: 8.4.7
|
storybook: 8.4.7
|
||||||
|
|
||||||
'@sveltejs/adapter-node@5.2.11(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))':
|
'@sveltejs/adapter-node@5.2.11(@sveltejs/kit@2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@rollup/plugin-commonjs': 28.0.2(rollup@4.29.1)
|
'@rollup/plugin-commonjs': 28.0.2(rollup@4.29.1)
|
||||||
'@rollup/plugin-json': 6.1.0(rollup@4.29.1)
|
'@rollup/plugin-json': 6.1.0(rollup@4.29.1)
|
||||||
'@rollup/plugin-node-resolve': 16.0.0(rollup@4.29.1)
|
'@rollup/plugin-node-resolve': 16.0.0(rollup@4.29.1)
|
||||||
'@sveltejs/kit': 2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
|
'@sveltejs/kit': 2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
|
||||||
rollup: 4.29.1
|
rollup: 4.29.1
|
||||||
|
|
||||||
'@sveltejs/enhanced-img@0.4.4(rollup@4.29.1)(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))':
|
'@sveltejs/enhanced-img@0.4.4(rollup@4.29.1)(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))':
|
||||||
|
|
@ -6871,7 +6871,7 @@ snapshots:
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- rollup
|
- rollup
|
||||||
|
|
||||||
'@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))':
|
'@sveltejs/kit@2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
|
'@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
|
||||||
'@types/cookie': 0.6.0
|
'@types/cookie': 0.6.0
|
||||||
|
|
@ -6919,12 +6919,12 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
tailwindcss: 3.4.17
|
tailwindcss: 3.4.17
|
||||||
|
|
||||||
'@tailwindcss/forms@0.5.9(tailwindcss@3.4.17)':
|
'@tailwindcss/forms@0.5.10(tailwindcss@3.4.17)':
|
||||||
dependencies:
|
dependencies:
|
||||||
mini-svg-data-uri: 1.4.4
|
mini-svg-data-uri: 1.4.4
|
||||||
tailwindcss: 3.4.17
|
tailwindcss: 3.4.17
|
||||||
|
|
||||||
'@tailwindcss/typography@0.5.15(tailwindcss@3.4.17)':
|
'@tailwindcss/typography@0.5.16(tailwindcss@3.4.17)':
|
||||||
dependencies:
|
dependencies:
|
||||||
lodash.castarray: 4.4.0
|
lodash.castarray: 4.4.0
|
||||||
lodash.isplainobject: 4.0.6
|
lodash.isplainobject: 4.0.6
|
||||||
|
|
@ -8070,11 +8070,11 @@ snapshots:
|
||||||
combined-stream: 1.0.8
|
combined-stream: 1.0.8
|
||||||
mime-types: 2.1.35
|
mime-types: 2.1.35
|
||||||
|
|
||||||
formsnap@2.0.0(svelte@5.16.5)(sveltekit-superforms@2.22.1(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.16.5)(typescript@5.7.2)):
|
formsnap@2.0.0(svelte@5.16.5)(sveltekit-superforms@2.22.1(@sveltejs/kit@2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.16.5)(typescript@5.7.2)):
|
||||||
dependencies:
|
dependencies:
|
||||||
svelte: 5.16.5
|
svelte: 5.16.5
|
||||||
svelte-toolbelt: 0.5.0(svelte@5.16.5)
|
svelte-toolbelt: 0.5.0(svelte@5.16.5)
|
||||||
sveltekit-superforms: 2.22.1(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.16.5)(typescript@5.7.2)
|
sveltekit-superforms: 2.22.1(@sveltejs/kit@2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.16.5)(typescript@5.7.2)
|
||||||
|
|
||||||
forwarded@0.2.0: {}
|
forwarded@0.2.0: {}
|
||||||
|
|
||||||
|
|
@ -9452,14 +9452,14 @@ snapshots:
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
sveltekit-flash-message@2.4.4(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5):
|
sveltekit-flash-message@2.4.5(@sveltejs/kit@2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@sveltejs/kit': 2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
|
'@sveltejs/kit': 2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
|
||||||
svelte: 5.16.5
|
svelte: 5.16.5
|
||||||
|
|
||||||
sveltekit-superforms@2.22.1(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.16.5)(typescript@5.7.2):
|
sveltekit-superforms@2.22.1(@sveltejs/kit@2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.16.5)(typescript@5.7.2):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@sveltejs/kit': 2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
|
'@sveltejs/kit': 2.15.2(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.5)(vite@6.0.7(@types/node@22.10.5)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
|
||||||
devalue: 5.1.1
|
devalue: 5.1.1
|
||||||
memoize-weak: 1.0.2
|
memoize-weak: 1.0.2
|
||||||
svelte: 5.16.5
|
svelte: 5.16.5
|
||||||
|
|
|
||||||
22
src/lib/dtos/settings/profile/update-profile.dto.ts
Normal file
22
src/lib/dtos/settings/profile/update-profile.dto.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
const MAX_UPLOAD_SIZE = 1024 * 1024 * 3; // 3MB
|
||||||
|
const ACCEPTED_FILE_TYPES = ['image/jpeg', 'image/jpg', 'image/png', 'image/webp'];
|
||||||
|
|
||||||
|
export const updateProfileDto = z.object({
|
||||||
|
first_name: z
|
||||||
|
.string()
|
||||||
|
.trim()
|
||||||
|
.min(1, { message: 'Must be at least 1 characters' })
|
||||||
|
.max(50, { message: 'Must be less than 50 characters' })
|
||||||
|
.optional(),
|
||||||
|
last_name: z
|
||||||
|
.string()
|
||||||
|
.trim()
|
||||||
|
.min(1, { message: 'Must be at least 1 characters' })
|
||||||
|
.max(50, { message: 'Must be less than 50 characters' })
|
||||||
|
.optional(),
|
||||||
|
username: z.string().trim().min(3, { message: 'Must be at least 3 characters' }).max(50, { message: 'Must be less than 50 characters' }),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type UpdateProfileDto = z.infer<typeof updateProfileDto>;
|
||||||
|
|
@ -3,7 +3,9 @@ import { userDto } from './user.dto';
|
||||||
|
|
||||||
export const updateUserDto = userDto
|
export const updateUserDto = userDto
|
||||||
.pick({
|
.pick({
|
||||||
avatar: true
|
avatar: true,
|
||||||
|
first_name: true,
|
||||||
|
last_name: true
|
||||||
})
|
})
|
||||||
.optional();
|
.optional();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,9 @@ const ACCEPTED_FILE_TYPES = ['image/jpeg', 'image/jpg', 'image/png', 'image/webp
|
||||||
export const userDto = z.object({
|
export const userDto = z.object({
|
||||||
id: z.string(),
|
id: z.string(),
|
||||||
email: z.string().email(),
|
email: z.string().email(),
|
||||||
|
first_name: z.string().trim().min(1, { message: 'Must be at least 1 characters' }).max(50, { message: 'Must be less than 50 characters' }),
|
||||||
|
last_name: z.string().trim().min(1, { message: 'Must be at least 1 characters' }).max(50, { message: 'Must be less than 50 characters' }),
|
||||||
|
username: z.string().trim().min(3, { message: 'Must be at least 3 characters' }).max(50, { message: 'Must be less than 50 characters' }),
|
||||||
avatar: z
|
avatar: z
|
||||||
.instanceof(File)
|
.instanceof(File)
|
||||||
.optional()
|
.optional()
|
||||||
|
|
|
||||||
|
|
@ -36,4 +36,8 @@ export class UserRolesRepository {
|
||||||
async delete(id: string, db = this.drizzle.db) {
|
async delete(id: string, db = this.drizzle.db) {
|
||||||
return db.delete(user_roles_table).where(eq(user_roles_table.id, id)).returning().then(takeFirstOrThrow);
|
return db.delete(user_roles_table).where(eq(user_roles_table.id, id)).returning().then(takeFirstOrThrow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async deleteAllByUserId(userId: string, db = this.drizzle.db) {
|
||||||
|
return db.delete(user_roles_table).where(eq(user_roles_table.user_id, userId));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,4 +48,13 @@ export class UserRolesService {
|
||||||
trx,
|
trx,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async removeAllRolesFromUser(userId: string, trx: Transaction | null = null) {
|
||||||
|
if (!trx) {
|
||||||
|
return this.userRolesRepository.deleteAllByUserId(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.userRolesRepository.deleteAllByUserId(userId, trx);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import { rateLimit } from '../common/middleware/rate-limit.middleware';
|
||||||
import { changePasswordDto } from '$lib/dtos/settings/password/change-password.dto';
|
import { changePasswordDto } from '$lib/dtos/settings/password/change-password.dto';
|
||||||
import { StatusCodes } from '$lib/constants/status-codes';
|
import { StatusCodes } from '$lib/constants/status-codes';
|
||||||
import { SessionsService } from '../iam/sessions/sessions.service';
|
import { SessionsService } from '../iam/sessions/sessions.service';
|
||||||
|
import { updateProfileDto } from '$lib/dtos/settings/profile/update-profile.dto';
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class UsersController extends Controller {
|
export class UsersController extends Controller {
|
||||||
|
|
@ -67,6 +68,18 @@ export class UsersController extends Controller {
|
||||||
console.error('Error updating password', error);
|
console.error('Error updating password', error);
|
||||||
return c.json({ error: 'Unable to update password' }, StatusCodes.INTERNAL_SERVER_ERROR);
|
return c.json({ error: 'Unable to update password' }, StatusCodes.INTERNAL_SERVER_ERROR);
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
.put('/me/profile', authState('session'), zValidator('json', updateProfileDto), async (c) => {
|
||||||
|
c.var.logger.debug(`Update profile: ${JSON.stringify(c.req.valid('json'))}`);
|
||||||
|
await this.usersService.update(c.var.session.userId, c.req.valid('json'));
|
||||||
|
const user = await this.usersRepository.findOneByIdOrThrow(c.var.session.userId);
|
||||||
|
return c.json(user);
|
||||||
|
})
|
||||||
|
.delete('/me', authState('session'), async (c) => {
|
||||||
|
await this.usersService.delete(c.var.session.userId);
|
||||||
|
await this.sessionsService.invalidateSession('');
|
||||||
|
this.sessionsService.deleteSessionCookie();
|
||||||
|
return c.json({ message: 'User deleted' });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import { DrizzleRepository } from '../common/factories/drizzle-repository.factor
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
/* Types */
|
/* Types */
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
type Create = Pick<InferSelectModel<typeof users_table>, 'avatar' | 'email' | 'username'>;
|
type Create = Pick<InferSelectModel<typeof users_table>, 'avatar' | 'email' | 'username' | 'first_name' | 'last_name'>;
|
||||||
type Update = Partial<Create>;
|
type Update = Partial<Create>;
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
@ -38,7 +38,9 @@ export class UsersRepository extends DrizzleRepository {
|
||||||
|
|
||||||
async findOneByIdOrThrow(id: string, db = this.drizzle.db) {
|
async findOneByIdOrThrow(id: string, db = this.drizzle.db) {
|
||||||
const user = await this.findOneById(id, db);
|
const user = await this.findOneById(id, db);
|
||||||
if (!user) throw NotFound('User not found');
|
if (!user) {
|
||||||
|
throw NotFound('User not found');
|
||||||
|
}
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,27 +9,33 @@ import { UsersRepository } from './users.repository';
|
||||||
import { UserRolesService } from './user_roles.service';
|
import { UserRolesService } from './user_roles.service';
|
||||||
import { RoleName } from '../roles/tables/roles.table';
|
import { RoleName } from '../roles/tables/roles.table';
|
||||||
import { BadRequest } from '../common/utils/exceptions';
|
import { BadRequest } from '../common/utils/exceptions';
|
||||||
|
import { LoggerService } from '../common/services/logger.service';
|
||||||
|
import type { UpdateProfileDto } from '$lib/dtos/settings/profile/update-profile.dto';
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class UsersService {
|
export class UsersService {
|
||||||
constructor(
|
constructor(
|
||||||
private drizzleService = inject(DrizzleService),
|
private drizzleService = inject(DrizzleService),
|
||||||
private credentialsRepository = inject(CredentialsRepository),
|
private credentialsRepository = inject(CredentialsRepository),
|
||||||
|
private loggerService = inject(LoggerService),
|
||||||
private usersRepository = inject(UsersRepository),
|
private usersRepository = inject(UsersRepository),
|
||||||
private userRoleService = inject(UserRolesService),
|
private userRoleService = inject(UserRolesService),
|
||||||
private storageService = inject(StorageService),
|
private storageService = inject(StorageService),
|
||||||
private tokenService = inject(TokensService)
|
private tokenService = inject(TokensService)
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async update(userId: string, updateUserDto: UpdateUserDto) {
|
async update(userId: string, updateUserDto: UpdateProfileDto) {
|
||||||
|
let key: string | null = null;
|
||||||
if (updateUserDto?.avatar) {
|
if (updateUserDto?.avatar) {
|
||||||
const { key } = await this.storageService.upload({ file: updateUserDto.avatar });
|
const response = await this.storageService.upload({ file: updateUserDto.avatar });
|
||||||
await this.usersRepository.update(userId, { avatar: key });
|
key = response?.key;
|
||||||
}
|
}
|
||||||
|
this.loggerService.log.info(`Updating user ${userId}, with avatar: ${key}, first_name: ${updateUserDto?.first_name}, last_name: ${updateUserDto?.last_name}`);
|
||||||
|
await this.usersRepository.update(userId, { avatar: key, first_name: updateUserDto?.first_name ?? '', last_name: updateUserDto?.last_name ?? '' });
|
||||||
}
|
}
|
||||||
|
|
||||||
async createEmail(email: string) {
|
async createEmail(email: string) {
|
||||||
return this.usersRepository.create({ avatar: null, email, username: email });
|
return this.usersRepository.create({ avatar: null, email, username: email, first_name: '', last_name: '' });
|
||||||
}
|
}
|
||||||
|
|
||||||
async createWithPassword(username: string, password: string, email?: string | undefined) {
|
async createWithPassword(username: string, password: string, email?: string | undefined) {
|
||||||
|
|
@ -46,7 +52,7 @@ export class UsersService {
|
||||||
|
|
||||||
return await this.drizzleService.db.transaction(async (trx) => {
|
return await this.drizzleService.db.transaction(async (trx) => {
|
||||||
const createdUser = await this.usersRepository.create(
|
const createdUser = await this.usersRepository.create(
|
||||||
{ username, email: email || '', avatar: null },
|
{ username, email: email || '', avatar: null, first_name: '', last_name: '' },
|
||||||
trx,
|
trx,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -104,4 +110,12 @@ export class UsersService {
|
||||||
const { password } = data;
|
const { password } = data;
|
||||||
return this.tokenService.verifyHashedToken(password, credential.secret_data);
|
return this.tokenService.verifyHashedToken(password, credential.secret_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async delete(userId: string) {
|
||||||
|
return await this.drizzleService.db.transaction(async (trx) => {
|
||||||
|
const deletedUser = await this.usersRepository.delete(userId, trx);
|
||||||
|
// await this.userRoleService.removeAllRolesFromUser(userId, trx);
|
||||||
|
return deletedUser;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/state';
|
||||||
import { cn } from '@/utils/ui';
|
import { cn } from '@/utils/ui';
|
||||||
|
|
||||||
let { children } = $props();
|
let { children } = $props();
|
||||||
|
|
@ -17,11 +17,11 @@
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
href="/settings"
|
href="/settings"
|
||||||
class={cn($page.url.pathname === '/settings' && 'font-semibold text-primary')}>Profile</a
|
class={cn(page.url.pathname === '/settings' && 'font-semibold text-primary')}>Profile</a
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
href="/settings/account"
|
href="/settings/account"
|
||||||
class={cn($page.url.pathname === '/settings/account' && 'font-semibold text-primary')}
|
class={cn(page.url.pathname === '/settings/account' && 'font-semibold text-primary')}
|
||||||
>Account</a
|
>Account</a
|
||||||
>
|
>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
|
||||||
59
src/routes/(app)/(protected)/settings/+page.server.ts
Normal file
59
src/routes/(app)/(protected)/settings/+page.server.ts
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
import { notSignedInMessage } from '$lib/utils/flashMessages';
|
||||||
|
import { redirect } from 'sveltekit-flash-message/server';
|
||||||
|
import type { PageServerLoad } from './$types';
|
||||||
|
import { fail, message, setError, superValidate } from 'sveltekit-superforms/server';
|
||||||
|
import { zod } from 'sveltekit-superforms/adapters';
|
||||||
|
import { updateProfileDto } from '$lib/dtos/settings/profile/update-profile.dto';
|
||||||
|
import type { Actions } from '@sveltejs/kit';
|
||||||
|
|
||||||
|
export const load: PageServerLoad = async (event) => {
|
||||||
|
const { parent } = event;
|
||||||
|
const { authedUser } = await parent();
|
||||||
|
|
||||||
|
console.log('authedUser', authedUser);
|
||||||
|
|
||||||
|
if (!authedUser) {
|
||||||
|
throw redirect(302, '/login', notSignedInMessage, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateProfileForm = await superValidate(zod(updateProfileDto), {
|
||||||
|
defaults: {
|
||||||
|
first_name: authedUser?.first_name ?? '',
|
||||||
|
last_name: authedUser?.last_name ?? '',
|
||||||
|
username: authedUser?.username ?? '',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
updateProfileForm,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const actions: Actions = {
|
||||||
|
updateProfile: async (event) => {
|
||||||
|
const { locals } = event;
|
||||||
|
const authedUser = await locals.getAuthedUser();
|
||||||
|
|
||||||
|
if (!authedUser) {
|
||||||
|
throw redirect(302, '/login', notSignedInMessage, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
const form = await superValidate(event, zod(updateProfileDto));
|
||||||
|
|
||||||
|
if (!form.valid) {
|
||||||
|
return fail(400, {
|
||||||
|
form,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('form data', form.data);
|
||||||
|
|
||||||
|
const { error } = await locals.api.users.me.profile.$put({ json: form.data }).then(locals.parseApiResponse);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
return setError(form, 'username', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return message(form, { text: 'Profile updated', type: 'success' });
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
<script>
|
||||||
|
import UpdateProfileCard from './update-profile-card.svelte';
|
||||||
|
|
||||||
|
let { data } = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<UpdateProfileCard updateProfileForm={data.updateProfileForm} />
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import * as Card from '$lib/components/ui/card';
|
||||||
|
import * as Form from '$lib/components/ui/form';
|
||||||
|
import { Input } from '$lib/components/ui/input';
|
||||||
|
import { updateProfileDto, type UpdateProfileDto } from '$lib/dtos/settings/profile/update-profile.dto.js';
|
||||||
|
import { fileProxy, superForm } from 'sveltekit-superforms/client';
|
||||||
|
import { zodClient } from 'sveltekit-superforms/adapters';
|
||||||
|
|
||||||
|
|
||||||
|
const { updateProfileForm }: { updateProfileForm: UpdateProfileDto } = $props();
|
||||||
|
|
||||||
|
const sf_update_profile = superForm(updateProfileForm, {
|
||||||
|
validators: zodClient(updateProfileDto),
|
||||||
|
resetForm: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const {
|
||||||
|
form: updateProfileFormData,
|
||||||
|
enhance: updateProfileEnhance,
|
||||||
|
submit: updateProfileFormSubmit,
|
||||||
|
} = sf_update_profile;
|
||||||
|
|
||||||
|
const avatar = fileProxy(updateProfileFormData, 'avatar')
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>Acme | Settings</title>
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<Card.Root>
|
||||||
|
<Card.Header>
|
||||||
|
<Card.Title>Update Profile</Card.Title>
|
||||||
|
</Card.Header>
|
||||||
|
<Card.Content>
|
||||||
|
<form method="POST" action="?/updateProfile" use:updateProfileEnhance>
|
||||||
|
<h3>Your Profile</h3>
|
||||||
|
<hr class="!border-t-2 mt-2 mb-6" />
|
||||||
|
<Form.Field form={sf_update_profile} name="username">
|
||||||
|
<Form.Control>
|
||||||
|
{#snippet children({ props })}
|
||||||
|
<Form.Label for="username">Username</Form.Label>
|
||||||
|
<Input autocomplete="username" {...props} bind:value={$updateProfileFormData.username} />
|
||||||
|
{/snippet}
|
||||||
|
</Form.Control>
|
||||||
|
<Form.Description />
|
||||||
|
<Form.FieldErrors />
|
||||||
|
</Form.Field>
|
||||||
|
<Form.Field form={sf_update_profile} name="first_name">
|
||||||
|
<Form.Control>
|
||||||
|
{#snippet children({ props })}
|
||||||
|
<Form.Label for="first_name">First Name</Form.Label>
|
||||||
|
<Input {...props} bind:value={$updateProfileFormData.first_name} />
|
||||||
|
{/snippet}
|
||||||
|
</Form.Control>
|
||||||
|
<Form.Description />
|
||||||
|
<Form.FieldErrors />
|
||||||
|
</Form.Field>
|
||||||
|
<Form.Field form={sf_update_profile} name="last_name">
|
||||||
|
<Form.Control>
|
||||||
|
{#snippet children({ props })}
|
||||||
|
<Form.Label for="last_name">Last Name</Form.Label>
|
||||||
|
<Input {...props} bind:value={$updateProfileFormData.last_name} />
|
||||||
|
{/snippet}
|
||||||
|
</Form.Control>
|
||||||
|
<Form.Description />
|
||||||
|
<Form.FieldErrors />
|
||||||
|
</Form.Field>
|
||||||
|
<!-- <Form.Field form={sf_update_profile} name="avatar">
|
||||||
|
<Form.Control>
|
||||||
|
{#snippet children({ props })}
|
||||||
|
<Form.Label for="avatar">Avatar</Form.Label>
|
||||||
|
<Input type="file" accept="image/png, image/jpg, image/jpeg, image/webp" name="avatar" enctype="multipart/form-data" bind:files={$avatar} />
|
||||||
|
{/snippet}
|
||||||
|
</Form.Control>
|
||||||
|
<Form.Description />
|
||||||
|
<Form.FieldErrors />
|
||||||
|
</Form.Field> -->
|
||||||
|
</form>
|
||||||
|
</Card.Content>
|
||||||
|
<Card.Footer class="border-t px-6 py-4">
|
||||||
|
<Form.Button onclick={() => updateProfileFormSubmit()}>Update Profile</Form.Button>
|
||||||
|
</Card.Footer>
|
||||||
|
</Card.Root>
|
||||||
Loading…
Reference in a new issue