Skip to content

Commit

Permalink
feat: 🎸 add updateUserById api and fix ui
Browse files Browse the repository at this point in the history
  • Loading branch information
yeukfei02 committed Jan 2, 2023
1 parent 849a952 commit 2c33875
Show file tree
Hide file tree
Showing 8 changed files with 158 additions and 12 deletions.
7 changes: 7 additions & 0 deletions apps/api/src/user/dto/updateUserById.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { UserRole } from '@prisma/client';

export class UpdateUserByIdDto {
name: string;
email: string;
userRole: UserRole;
}
15 changes: 15 additions & 0 deletions apps/api/src/user/interface/updateUserById.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { UserRole } from '@prisma/client';

export interface UpdateUserByIdRes {
message: string;
user: UserRes;
}

export interface UserRes {
id: string;
name: string;
email: string;
created_at: Date;
updated_at: Date;
userRoles: UserRole[];
}
29 changes: 29 additions & 0 deletions apps/api/src/user/user.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import jwt from 'jsonwebtoken';
import { SignupDto } from './dto/signup.dto';
import { LoginDto } from './dto/login.dto';
import { ChangePasswordDto } from './dto/changePassword.dto';
import { UpdateUserByIdDto } from './dto/updateUserById.dto';
import { SignupRes } from './interface/signup.interface';
import { LoginRes } from './interface/login.interface';
import { GetNormalUsersRes } from './interface/getNormalUsers.interface';
import { GetUserByIdRes } from './interface/getUserById.interface';
import { ChangePasswordRes } from './interface/changePassword.interface';
import { UpdateUserByIdRes } from './interface/updateUserById.interface';

@Controller('users')
export class UserController {
Expand Down Expand Up @@ -98,6 +100,33 @@ export class UserController {
return response;
}

@Patch('/:id')
async updateUserById(
@Param('id') id: string,
@Body() updateUserByIdDto: UpdateUserByIdDto
): Promise<UpdateUserByIdRes> {
let response: UpdateUserByIdRes;

const name = updateUserByIdDto.name;
const email = updateUserByIdDto.email;
const userRole = updateUserByIdDto.userRole;

const user = await this.userService.updateUserById(
id,
name,
email,
userRole
);
if (user) {
response = {
message: 'update user by id',
user: user,
};
}

return response;
}

@Patch('/:id/changePassword')
async changePassword(
@Param('id') id: string,
Expand Down
19 changes: 19 additions & 0 deletions apps/api/src/user/user.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,25 @@ export class UserRepository {
return user;
}

async updateUserById(
id: string,
name: string,
email: string,
userRole: UserRole
) {
const user = await this.prisma.user.update({
where: {
id: id,
},
data: {
name: name,
email: email,
userRoles: [userRole],
},
});
return user;
}

async changePassword(id: string, password: string) {
const salt = bcrypt.genSaltSync(10);

Expand Down
28 changes: 28 additions & 0 deletions apps/api/src/user/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,34 @@ export class UserService {
return user;
}

async updateUserById(
id: string,
name: string,
email: string,
userRole: UserRole
) {
let user = null;

const userFromDB = await this.userRepository.updateUserById(
id,
name,
email,
userRole
);
if (userFromDB) {
user = {
id: userFromDB.id,
name: userFromDB.name,
email: userFromDB.email,
created_at: userFromDB.created_at,
updated_at: userFromDB.updated_at,
userRoles: userFromDB.userRoles,
};
}

return user;
}

async changePassword(id: string, password: string) {
let user = null;

Expand Down
42 changes: 35 additions & 7 deletions apps/web/src/components/profile/Profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,19 @@ import MenuItem from '@mui/material/MenuItem';
import FormControl from '@mui/material/FormControl';
import Select, { SelectChangeEvent } from '@mui/material/Select';
import { User, UserRole } from '@prisma/client';
import * as userService from '../../services/userService';
import CustomBreadcrumbs from '../customBreadcrumbs/CustomBreadcrumbs';
import CustomSnackBar from '../customSnackBar/CustomSnackBar';
import * as userService from '../../services/userService';

function Profile() {
const [user, setUser] = useState<User>();

const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [userRoles, setUserRoles] = useState<UserRole>(UserRole.NORMAL_USER);
const [userRole, setUserRole] = useState<UserRole>(UserRole.NORMAL_USER);

const [snackbarText, setSnackbarText] = useState('');
const [snackbarOpen, setSnackbarOpen] = useState(false);

useEffect(() => {
getUserById();
Expand All @@ -37,7 +41,7 @@ function Profile() {
setUser(responseData.user);
setName(responseData.user.name);
setEmail(responseData.user.email);
setUserRoles(responseData.user.userRoles);
setUserRole(responseData.user.userRoles[0]);
}
}
}
Expand All @@ -56,11 +60,29 @@ function Profile() {
};

const handleUserRolesChange = (event: SelectChangeEvent) => {
setUserRoles(event.target.value as UserRole);
setUserRole(event.target.value as UserRole);
};

const handleUpdateUserClick = () => {
console.log('update user api');
const handleUpdateUserClick = async () => {
const token = localStorage.getItem('token');
if (token && user && name && email && userRole) {
const response = await userService.updateUserById(
token,
user.id,
name,
email,
userRole
);
console.log('response = ', response);

if (response) {
const responseData = response.data;
if (responseData) {
setSnackbarOpen(true);
setSnackbarText('Update user by id');
}
}
}
};

const renderProfileView = () => {
Expand Down Expand Up @@ -107,7 +129,7 @@ function Profile() {
<Select
labelId="demo-simple-select-helper-label"
id="demo-simple-select-helper"
value={userRoles}
value={userRole}
label="User Roles"
onChange={handleUserRolesChange}
>
Expand Down Expand Up @@ -142,6 +164,12 @@ function Profile() {
</div>

{renderProfileView()}

<CustomSnackBar
type={snackbarText}
open={snackbarOpen}
setOpen={setSnackbarOpen}
/>
</>
);
}
Expand Down
10 changes: 5 additions & 5 deletions apps/web/src/components/signup/signup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ function Signup() {
const navigate = useNavigate();
const [open, setOpen] = useState(false);

const [userRoles, setUserRoles] = useState<UserRole>(UserRole.NORMAL_USER);
const [userRole, setUserRole] = useState<UserRole>(UserRole.NORMAL_USER);

const handleUserRolesChange = (event: SelectChangeEvent) => {
setUserRoles(event.target.value as UserRole);
setUserRole(event.target.value as UserRole);
};

const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
Expand All @@ -56,15 +56,15 @@ function Signup() {
const name = data.get('name');
const email = data.get('email');
const password = data.get('password');
if (name && email && password && userRoles) {
if (name && email && password && userRole) {
const nameStr = name as string;
const emailStr = email as string;
const passwordStr = password as string;
const response = await userService.signup(
nameStr,
emailStr,
passwordStr,
[userRoles]
[userRole]
);
console.log('response = ', response);

Expand Down Expand Up @@ -161,7 +161,7 @@ function Signup() {
<Select
labelId="demo-simple-select-helper-label"
id="demo-simple-select-helper"
value={userRoles}
value={userRole}
label="User Roles"
onChange={handleUserRolesChange}
>
Expand Down
20 changes: 20 additions & 0 deletions apps/web/src/services/userService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,26 @@ export const getUserById = async (token: string, id: string) => {
return response;
};

export const updateUserById = async (
token: string,
id: string,
name: string,
email: string,
userRole: UserRole
) => {
const data = {
name: name,
email: email,
userRole: userRole,
};
const response = await axios.patch(`${rootUrl}/users/${id}`, data, {
headers: {
Authorization: `Bearer ${token}`,
},
});
return response;
};

export const changePassword = async (
token: string,
id: string,
Expand Down

0 comments on commit 2c33875

Please sign in to comment.