Allow saving username when it is the same as your current username. Fixing message on success.

This commit is contained in:
Bradley Shellnut 2025-01-07 16:44:36 -08:00
parent c5e310bf95
commit e74756abf0
4 changed files with 67 additions and 52 deletions

View file

@ -70,7 +70,6 @@ export class UsersController extends Controller {
} }
}) })
.put('/me/profile', authState('session'), zValidator('json', updateProfileDto), async (c) => { .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')); await this.usersService.update(c.var.session.userId, c.req.valid('json'));
const user = await this.usersRepository.findOneByIdOrThrow(c.var.session.userId); const user = await this.usersRepository.findOneByIdOrThrow(c.var.session.userId);
return c.json(user); return c.json(user);

View file

@ -25,13 +25,19 @@ export class UsersService {
) {} ) {}
async update(userId: string, updateUserDto: UpdateProfileDto) { async update(userId: string, updateUserDto: UpdateProfileDto) {
let key: string | null = null; // let key: string | null = null;
if (updateUserDto?.avatar) { // if (updateUserDto?.avatar) {
const response = await this.storageService.upload({ file: updateUserDto.avatar }); // const response = await this.storageService.upload({ file: updateUserDto.avatar });
key = response?.key; // key = response?.key;
// }
const currentUser = await this.usersRepository.findOneByIdOrThrow(userId);
if (currentUser?.username !== updateUserDto?.username) {
const existingUserWithUsername = await this.usersRepository.findOneByUsername(updateUserDto.username);
if (existingUserWithUsername) {
throw BadRequest('Username already exists');
}
} }
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: null, 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) {

View file

@ -51,9 +51,15 @@ export const actions: Actions = {
const { error } = await locals.api.users.me.profile.$put({ json: form.data }).then(locals.parseApiResponse); const { error } = await locals.api.users.me.profile.$put({ json: form.data }).then(locals.parseApiResponse);
if (error) { if (error) {
return setError(form, 'username', error); console.log('error', error);
return setError(form, 'username', error.message);
} }
return message(form, { text: 'Profile updated', type: 'success' }); const profileUpdatedMessage = {
type: 'success',
message: 'Profile updated! 🎊',
};
return message(form, profileUpdatedMessage);
}, },
}; };

View file

@ -1,17 +1,21 @@
<script lang="ts"> <script lang="ts">
import * as Card from '$lib/components/ui/card'; import * as Card from "$lib/components/ui/card";
import * as Form from '$lib/components/ui/form'; import * as Form from "$lib/components/ui/form";
import { Input } from '$lib/components/ui/input'; import { Input } from "$lib/components/ui/input";
import { updateProfileDto, type UpdateProfileDto } from '$lib/dtos/settings/profile/update-profile.dto.js'; import { updateProfileDto, type UpdateProfileDto } from "$lib/dtos/settings/profile/update-profile.dto.js";
import { fileProxy, superForm } from 'sveltekit-superforms/client'; import { fileProxy, superForm } from "sveltekit-superforms/client";
import { zodClient } from 'sveltekit-superforms/adapters'; import { zodClient } from "sveltekit-superforms/adapters";
import * as flashModule from "sveltekit-flash-message/client";
const { updateProfileForm }: { updateProfileForm: UpdateProfileDto } = $props(); const { updateProfileForm }: { updateProfileForm: UpdateProfileDto } = $props();
const sf_update_profile = superForm(updateProfileForm, { const sf_update_profile = superForm(updateProfileForm, {
validators: zodClient(updateProfileDto), validators: zodClient(updateProfileDto),
resetForm: false, resetForm: false,
syncFlashMessage: true,
flashMessage: {
module: flashModule,
},
}); });
const { const {
@ -20,7 +24,7 @@
submit: updateProfileFormSubmit, submit: updateProfileFormSubmit,
} = sf_update_profile; } = sf_update_profile;
const avatar = fileProxy(updateProfileFormData, 'avatar') const avatar = fileProxy(updateProfileFormData, "avatar");
</script> </script>
<svelte:head> <svelte:head>
@ -32,40 +36,40 @@
<Card.Title>Update Profile</Card.Title> <Card.Title>Update Profile</Card.Title>
</Card.Header> </Card.Header>
<Card.Content> <Card.Content>
<form method="POST" action="?/updateProfile" use:updateProfileEnhance> <form method="POST" action="?/updateProfile" use:updateProfileEnhance>
<h3>Your Profile</h3> <h3>Your Profile</h3>
<hr class="!border-t-2 mt-2 mb-6" /> <hr class="!border-t-2 mt-2 mb-6" />
<Form.Field form={sf_update_profile} name="username"> <Form.Field form={sf_update_profile} name="username">
<Form.Control> <Form.Control>
{#snippet children({ props })} {#snippet children({ props })}
<Form.Label for="username">Username</Form.Label> <Form.Label for="username">Username</Form.Label>
<Input autocomplete="username" {...props} bind:value={$updateProfileFormData.username} /> <Input autocomplete="username" {...props} bind:value={$updateProfileFormData.username} />
{/snippet} {/snippet}
</Form.Control> </Form.Control>
<Form.Description /> <Form.Description />
<Form.FieldErrors /> <Form.FieldErrors />
</Form.Field> </Form.Field>
<Form.Field form={sf_update_profile} name="first_name"> <Form.Field form={sf_update_profile} name="first_name">
<Form.Control> <Form.Control>
{#snippet children({ props })} {#snippet children({ props })}
<Form.Label for="first_name">First Name</Form.Label> <Form.Label for="first_name">First Name</Form.Label>
<Input {...props} bind:value={$updateProfileFormData.first_name} /> <Input {...props} bind:value={$updateProfileFormData.first_name} />
{/snippet} {/snippet}
</Form.Control> </Form.Control>
<Form.Description /> <Form.Description />
<Form.FieldErrors /> <Form.FieldErrors />
</Form.Field> </Form.Field>
<Form.Field form={sf_update_profile} name="last_name"> <Form.Field form={sf_update_profile} name="last_name">
<Form.Control> <Form.Control>
{#snippet children({ props })} {#snippet children({ props })}
<Form.Label for="last_name">Last Name</Form.Label> <Form.Label for="last_name">Last Name</Form.Label>
<Input {...props} bind:value={$updateProfileFormData.last_name} /> <Input {...props} bind:value={$updateProfileFormData.last_name} />
{/snippet} {/snippet}
</Form.Control> </Form.Control>
<Form.Description /> <Form.Description />
<Form.FieldErrors /> <Form.FieldErrors />
</Form.Field> </Form.Field>
<!-- <Form.Field form={sf_update_profile} name="avatar"> <!-- <Form.Field form={sf_update_profile} name="avatar">
<Form.Control> <Form.Control>
{#snippet children({ props })} {#snippet children({ props })}
<Form.Label for="avatar">Avatar</Form.Label> <Form.Label for="avatar">Avatar</Form.Label>
@ -75,7 +79,7 @@
<Form.Description /> <Form.Description />
<Form.FieldErrors /> <Form.FieldErrors />
</Form.Field> --> </Form.Field> -->
</form> </form>
</Card.Content> </Card.Content>
<Card.Footer class="border-t px-6 py-4"> <Card.Footer class="border-t px-6 py-4">
<Form.Button onclick={() => updateProfileFormSubmit()}>Update Profile</Form.Button> <Form.Button onclick={() => updateProfileFormSubmit()}>Update Profile</Form.Button>