Skip to content

Commit 633eea1

Browse files
committed
feat: add username check in handlesubmit and username get api call
1 parent 9e3ea65 commit 633eea1

2 files changed

Lines changed: 20 additions & 17 deletions

File tree

apps/api/src/users/users.controller.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@ export class UsersController {
4040
return this.usersService.findById(id, { ability });
4141
}
4242

43+
@ApiOperation({ summary: 'Get User by Username' })
44+
@Get('/Check-Username/:username')
45+
@RouteAccess({ action: 'read', subject: 'User' })
46+
findByUsername(@Param('username') username: string, @CurrentUser('ability') ability: AppAbility) {
47+
return this.usersService.findByUsername(username, { ability });
48+
}
49+
4350
@ApiOperation({ summary: 'Update User' })
4451
@Patch(':id')
4552
@RouteAccess({ action: 'update', subject: 'User' })

apps/web/src/routes/_app/admin/users/create.tsx

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
import { estimatePasswordStrength } from '@douglasneuroinformatics/libpasswd';
44
import { Form, Heading } from '@douglasneuroinformatics/libui/components';
5+
import type { FormProps } from '@douglasneuroinformatics/libui/components';
56
import { useTranslation } from '@douglasneuroinformatics/libui/hooks';
67
import { $BasePermissionLevel, $CreateUserData } from '@opendatacapture/schemas/user';
7-
import type { CreateUserData, User } from '@opendatacapture/schemas/user';
8+
import type { CreateUserData } from '@opendatacapture/schemas/user';
89
import { createFileRoute, useNavigate } from '@tanstack/react-router';
910
import axios from 'axios';
1011
import { z } from 'zod/v4';
@@ -13,19 +14,26 @@ import { PageHeader } from '@/components/PageHeader';
1314
import { useCreateUserMutation } from '@/hooks/useCreateUserMutation';
1415
import { groupsQueryOptions, useGroupsQuery } from '@/hooks/useGroupsQuery';
1516

16-
const RouteComponent = async () => {
17+
const RouteComponent = () => {
1718
const { t } = useTranslation();
1819
const navigate = useNavigate();
1920
const groupsQuery = useGroupsQuery();
2021
const createUserMutation = useCreateUserMutation();
2122

22-
const handleSubmit = (data: CreateUserData) => {
23+
const handleSubmit: FormProps<any>['onSubmit'] = async (data: CreateUserData) => {
24+
// check if username exists
25+
26+
const exisitingUsername = await axios.get(`/v1/users/check-username/${encodeURIComponent(data.username)}`);
27+
if (exisitingUsername) {
28+
return { success: false, errorMessage: t('common.usernameExists') };
29+
}
30+
2331
createUserMutation.mutate({ data });
32+
2433
void navigate({ to: '..' });
34+
return { success: true };
2535
};
2636

27-
const existingUsers = await axios.get(`/v1/users`);
28-
2937
return (
3038
<div>
3139
<PageHeader>
@@ -158,18 +166,6 @@ const RouteComponent = async () => {
158166
path: ['confirmPassword']
159167
});
160168
}
161-
162-
if (existingUsers.data) {
163-
const usersList = existingUsers.data as Omit<User, 'hashedpassword'>[];
164-
165-
if (usersList.some((usersList) => usersList.username === ctx.value.username))
166-
ctx.issues.push({
167-
code: 'custom',
168-
input: ctx.value.username,
169-
message: t('common.usernameExists'),
170-
path: ['username']
171-
});
172-
}
173169
})}
174170
onSubmit={(data) => handleSubmit({ ...data, groupIds: Array.from(data.groupIds ?? []) })}
175171
/>

0 commit comments

Comments
 (0)