Skip to content

Commit 3c06435

Browse files
authored
Merge pull request #452 from MangoInstantMessenger/settings-bugfix
Settings bugfix
2 parents 318b11f + 6cf77a0 commit 3c06435

16 files changed

Lines changed: 184 additions & 67 deletions

MangoAPI.BusinessLogic/ApiCommands/Users/UpdatePersonalInformationCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ public record UpdatePersonalInformationCommand(
1010
string LinkedIn,
1111
string Facebook,
1212
string Twitter)
13-
: IRequest<Result<ResponseBase>>;
13+
: IRequest<Result<UpdatePersonalInformationResponse>>;
Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,78 @@
1-
using System.Threading;
1+
using MangoAPI.Application.Interfaces;
2+
using MangoAPI.BusinessLogic.Models;
3+
using System.Threading;
24
using System.Threading.Tasks;
35
using MangoAPI.BusinessLogic.Responses;
46
using MangoAPI.Domain.Constants;
57
using MangoAPI.Infrastructure.Database;
68
using MediatR;
79
using Microsoft.EntityFrameworkCore;
10+
using System.Globalization;
811

912
namespace MangoAPI.BusinessLogic.ApiCommands.Users;
1013

1114
public class UpdatePersonalInformationCommandHandler
12-
: IRequestHandler<UpdatePersonalInformationCommand, Result<ResponseBase>>
15+
: IRequestHandler<UpdatePersonalInformationCommand, Result<UpdatePersonalInformationResponse>>
1316
{
1417
private readonly MangoDbContext dbContext;
15-
private readonly ResponseFactory<ResponseBase> responseFactory;
18+
private readonly ResponseFactory<UpdatePersonalInformationResponse> responseFactory;
19+
private readonly IBlobServiceSettings blobServiceSettings;
1620

1721
public UpdatePersonalInformationCommandHandler(
1822
MangoDbContext dbContext,
19-
ResponseFactory<ResponseBase> responseFactory)
23+
ResponseFactory<UpdatePersonalInformationResponse> responseFactory,
24+
IBlobServiceSettings blobServiceSettings)
2025
{
2126
this.dbContext = dbContext;
2227
this.responseFactory = responseFactory;
28+
this.blobServiceSettings = blobServiceSettings;
2329
}
2430

25-
public async Task<Result<ResponseBase>> Handle(
31+
public async Task<Result<UpdatePersonalInformationResponse>> Handle(
2632
UpdatePersonalInformationCommand request,
2733
CancellationToken cancellationToken)
2834
{
29-
var personalInformation = await dbContext.PersonalInformation
30-
.FirstOrDefaultAsync(
31-
entity => entity.UserId == request.UserId,
32-
cancellationToken);
35+
var user = await dbContext.Users.AsNoTracking()
36+
.Include(x => x.PersonalInformation)
37+
.FirstOrDefaultAsync(x => x.Id == request.UserId, cancellationToken);
3338

34-
if (personalInformation == null)
39+
if (user == null)
3540
{
3641
const string errorMessage = ResponseMessageCodes.UserNotFound;
3742
var details = ResponseMessageCodes.ErrorDictionary[errorMessage];
3843

3944
return responseFactory.ConflictResponse(errorMessage, details);
4045
}
4146

42-
personalInformation.UpdateSocialInformation(
47+
user.PersonalInformation.UpdateSocialInformation(
4348
request.Facebook,
4449
request.Twitter,
4550
request.Instagram,
4651
request.LinkedIn);
4752

48-
dbContext.PersonalInformation.Update(personalInformation);
53+
dbContext.PersonalInformation.Update(user.PersonalInformation);
4954

5055
await dbContext.SaveChangesAsync(cancellationToken);
5156

52-
return responseFactory.SuccessResponse(ResponseBase.SuccessResponse);
57+
var userDto = new User
58+
{
59+
UserId = user.Id,
60+
DisplayName = user.DisplayName,
61+
DisplayNameColour = user.DisplayNameColour,
62+
Address = user.Address,
63+
Birthday = user.Birthday?.ToString("yyyy-MM-dd", CultureInfo.CurrentCulture),
64+
Website = user.Website,
65+
Facebook = user.PersonalInformation.Facebook,
66+
Twitter = user.PersonalInformation.Twitter,
67+
Instagram = user.PersonalInformation.Instagram,
68+
LinkedIn = user.PersonalInformation.LinkedIn,
69+
Username = user.Username,
70+
Bio = user.Bio,
71+
PictureUrl = $"{blobServiceSettings.MangoBlobAccess}/{user.ImageFileName}",
72+
};
73+
74+
var response = UpdatePersonalInformationResponse.FromSuccess(userDto);
75+
76+
return responseFactory.SuccessResponse(response);
5377
}
5478
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using MangoAPI.BusinessLogic.Models;
2+
using MangoAPI.BusinessLogic.Responses;
3+
using MangoAPI.Domain.Constants;
4+
5+
namespace MangoAPI.BusinessLogic.ApiCommands.Users;
6+
7+
public record UpdatePersonalInformationResponse : ResponseBase
8+
{
9+
public User User { get; init; }
10+
11+
public static UpdatePersonalInformationResponse FromSuccess(User user)
12+
{
13+
var response = new UpdatePersonalInformationResponse
14+
{
15+
Message = ResponseMessageCodes.Success, Success = true, User = user,
16+
};
17+
18+
return response;
19+
}
20+
}

MangoAPI.BusinessLogic/ApiCommands/Users/UpdateUserAccountInfoCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ public record UpdateUserAccountInfoCommand(
1212
string Bio,
1313
string Address,
1414
DateTime? Birthday)
15-
: IRequest<Result<ResponseBase>>;
15+
: IRequest<Result<UpdateUserAccountInfoResponse>>;

MangoAPI.BusinessLogic/ApiCommands/Users/UpdateUserAccountInfoCommandHandler.cs

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using System.Linq;
1+
using MangoAPI.Application.Interfaces;
2+
using MangoAPI.BusinessLogic.Models;
3+
using System.Linq;
24
using System.Threading;
35
using System.Threading.Tasks;
46
using MangoAPI.BusinessLogic.Responses;
@@ -7,28 +9,34 @@
79
using MangoAPI.Infrastructure.Database;
810
using MediatR;
911
using Microsoft.EntityFrameworkCore;
12+
using System.Globalization;
1013

1114
namespace MangoAPI.BusinessLogic.ApiCommands.Users;
1215

1316
public class
14-
UpdateUserAccountInfoCommandHandler : IRequestHandler<UpdateUserAccountInfoCommand, Result<ResponseBase>>
17+
UpdateUserAccountInfoCommandHandler : IRequestHandler<UpdateUserAccountInfoCommand,
18+
Result<UpdateUserAccountInfoResponse>>
1519
{
1620
private readonly MangoDbContext dbContext;
17-
private readonly ResponseFactory<ResponseBase> responseFactory;
21+
private readonly ResponseFactory<UpdateUserAccountInfoResponse> responseFactory;
22+
private readonly IBlobServiceSettings blobServiceSettings;
1823

1924
public UpdateUserAccountInfoCommandHandler(
2025
MangoDbContext dbContext,
21-
ResponseFactory<ResponseBase> responseFactory)
26+
ResponseFactory<UpdateUserAccountInfoResponse> responseFactory,
27+
IBlobServiceSettings blobServiceSettings)
2228
{
2329
this.dbContext = dbContext;
2430
this.responseFactory = responseFactory;
31+
this.blobServiceSettings = blobServiceSettings;
2532
}
2633

27-
public async Task<Result<ResponseBase>> Handle(
34+
public async Task<Result<UpdateUserAccountInfoResponse>> Handle(
2835
UpdateUserAccountInfoCommand request,
2936
CancellationToken cancellationToken)
3037
{
3138
var user = await dbContext.Users
39+
.Include(x => x.PersonalInformation)
3240
.FirstOrDefaultAsync(x => x.Id == request.UserId, cancellationToken);
3341

3442
if (user is null)
@@ -71,6 +79,26 @@ public async Task<Result<ResponseBase>> Handle(
7179

7280
await dbContext.SaveChangesAsync(cancellationToken);
7381

74-
return responseFactory.SuccessResponse(ResponseBase.SuccessResponse);
82+
var userDto = new User
83+
{
84+
UserId = user.Id,
85+
DisplayName = user.DisplayName,
86+
DisplayNameColour = user.DisplayNameColour,
87+
Address = user.Address,
88+
Birthday = user.Birthday?.ToString("yyyy-MM-dd", CultureInfo.CurrentCulture),
89+
Website = user.Website,
90+
Facebook = user.PersonalInformation?.Facebook,
91+
Twitter = user.PersonalInformation?.Twitter,
92+
Instagram = user.PersonalInformation?.Instagram,
93+
LinkedIn = user.PersonalInformation?.LinkedIn,
94+
Username = user.Username,
95+
Bio = user.Bio,
96+
PictureUrl = $"{blobServiceSettings.MangoBlobAccess}/{user.ImageFileName}",
97+
};
98+
99+
var response = UpdateUserAccountInfoResponse.FromSuccess(userDto);
100+
var result = responseFactory.SuccessResponse(response);
101+
102+
return result;
75103
}
76104
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using MangoAPI.BusinessLogic.Models;
2+
using MangoAPI.BusinessLogic.Responses;
3+
using MangoAPI.Domain.Constants;
4+
5+
namespace MangoAPI.BusinessLogic.ApiCommands.Users;
6+
7+
public record UpdateUserAccountInfoResponse : ResponseBase
8+
{
9+
public User User { get; init; }
10+
11+
public static UpdateUserAccountInfoResponse FromSuccess(User user)
12+
{
13+
var response = new UpdateUserAccountInfoResponse
14+
{
15+
Message = ResponseMessageCodes.Success, Success = true, User = user,
16+
};
17+
18+
return response;
19+
}
20+
}

MangoAPI.Client/src/app/components/settings/settings.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ <h5 class="mb-2">Avatar</h5>
312312
</div>
313313
<div class="profile-form-footer gap-fix">
314314
<button class="button-dark" (click)="clearProfilePictureFile()">Reset</button>
315-
<button class="button-orange" (click)="onSaveChangesUpdateProfilePictureClick()">
315+
<button class="button-orange" (click)="onSaveProfilePictureClick()">
316316
Save Changes
317317
</button>
318318
</div>

MangoAPI.Client/src/app/components/settings/settings.component.ts

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import { GetUserResponse } from '../../types/responses/GetUserResponse';
1919
import { GetAppInfoResponse } from '../../types/responses/GetAppInfoResponse';
2020
import { BaseResponse } from '../../types/responses/BaseResponse';
2121
import { SettingsHelper } from './settings.helper';
22+
import { UpdatePersonalInformationResponse } from '../../types/responses/UpdatePersonalInformationResponse';
23+
import { UpdateUserAccountInfoResponse } from '../../types/responses/UpdateUserAccountInfoResponse';
2224

2325
@Component({
2426
selector: 'app-settings',
@@ -63,8 +65,6 @@ export class SettingsComponent implements OnInit {
6365

6466
const getUserInfoResponse = await firstValueFrom<GetUserResponse>(getUserInfoSub$);
6567

66-
// console.log(JSON.stringify(getUserInfoResponse.user));
67-
6868
this.currentUser = getUserInfoResponse.user;
6969

7070
this.currentUserForUpdating = { ...getUserInfoResponse.user };
@@ -106,14 +106,31 @@ export class SettingsComponent implements OnInit {
106106

107107
const updateUserInfoSub$ = this._usersService.updateUserAccountInformation(command);
108108

109-
const response = await firstValueFrom<BaseResponse>(updateUserInfoSub$);
109+
const response = await firstValueFrom<UpdateUserAccountInfoResponse>(updateUserInfoSub$);
110+
111+
this.currentUser = response.user;
112+
113+
alert(response.message);
114+
}
115+
116+
async onSavePersonalInformationClick() {
117+
const command: UpdatePersonalInformationCommand = {
118+
facebook: this.currentUserForUpdating.facebook,
119+
twitter: this.currentUserForUpdating.twitter,
120+
instagram: this.currentUserForUpdating.instagram,
121+
linkedIn: this.currentUserForUpdating.linkedIn
122+
};
123+
124+
const saveSocialsSub$ = this._usersService.updateUserSocials(command);
125+
126+
const response = await firstValueFrom<UpdatePersonalInformationResponse>(saveSocialsSub$);
110127

111-
this.currentUser = { ...this.currentUserForUpdating };
128+
this.currentUser = response.user;
112129

113130
alert(response.message);
114131
}
115132

116-
async onSaveChangesUpdateProfilePictureClick() {
133+
async onSaveProfilePictureClick() {
117134
const tokens = this._tokensService.getTokens();
118135

119136
if (!tokens) {
@@ -131,19 +148,24 @@ export class SettingsComponent implements OnInit {
131148
const file = this.file as File;
132149
formData.append('pictureFile', file);
133150

134-
const updateProfileImage$ = this._usersService.updateProfilePicture(formData);
151+
try {
152+
const updateProfileImage$ = this._usersService.updateProfilePicture(formData);
135153

136-
const result = await firstValueFrom<UpdateProfilePictureResponse>(updateProfileImage$);
154+
const result = await firstValueFrom<UpdateProfilePictureResponse>(updateProfileImage$);
137155

138-
alert(result.message);
156+
alert(result.message);
139157

140-
this.currentUser.pictureUrl = result.newUserPictureUrl;
158+
this.currentUser.pictureUrl = result.newUserPictureUrl;
141159

142-
tokens.userProfilePictureUrl = result.newUserPictureUrl;
160+
tokens.userProfilePictureUrl = result.newUserPictureUrl;
143161

144-
this._tokensService.setTokens(tokens);
162+
this._tokensService.setTokens(tokens);
145163

146-
this.clearProfilePictureFile();
164+
this.clearProfilePictureFile();
165+
} catch (e) {
166+
this._errorNotificationService.notifyOnError(e);
167+
this.clearProfilePictureFile();
168+
}
147169
}
148170

149171
async onSaveChangesChangePasswordClick() {
@@ -174,21 +196,6 @@ export class SettingsComponent implements OnInit {
174196
alert(response.message);
175197
}
176198

177-
async onSavePersonalInformationClick() {
178-
const command: UpdatePersonalInformationCommand = {
179-
facebook: this.currentUserForUpdating.facebook,
180-
twitter: this.currentUserForUpdating.twitter,
181-
instagram: this.currentUserForUpdating.instagram,
182-
linkedIn: this.currentUserForUpdating.linkedIn
183-
};
184-
185-
const saveSocialsSub$ = this._usersService.updateUserSocials(command);
186-
187-
const response = await firstValueFrom<BaseResponse>(saveSocialsSub$);
188-
189-
alert(response.message);
190-
}
191-
192199
onUpdateProfilePictureChange(event: any): void {
193200
const file: File = event.currentTarget.files[0];
194201

MangoAPI.Client/src/app/services/api/users.service.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import { ChangePasswordCommand } from '../../types/requests/ChangePasswordComman
1111
import { UpdateProfilePictureResponse } from '../../types/responses/UpdateProfilePictureResponse';
1212
import { TokensResponse } from 'src/app/types/responses/TokensResponse';
1313
import ApiBaseService from './api-base.service';
14+
import { UpdatePersonalInformationResponse } from '../../types/responses/UpdatePersonalInformationResponse';
15+
import { UpdateUserAccountInfoResponse } from '../../types/responses/UpdateUserAccountInfoResponse';
1416

1517
@Injectable({
1618
providedIn: 'root'
@@ -25,8 +27,13 @@ export class UsersService extends ApiBaseService {
2527
}
2628

2729
// PUT /api/users/socials
28-
updateUserSocials(request: UpdatePersonalInformationCommand): Observable<BaseResponse> {
29-
return this.httpClient.put<BaseResponse>(this.baseUrl + this.usersRoute + 'socials/', request);
30+
updateUserSocials(
31+
request: UpdatePersonalInformationCommand
32+
): Observable<UpdatePersonalInformationResponse> {
33+
return this.httpClient.put<UpdatePersonalInformationResponse>(
34+
this.baseUrl + this.usersRoute + 'socials/',
35+
request
36+
);
3037
}
3138

3239
// GET /api/users/{userId}
@@ -40,8 +47,10 @@ export class UsersService extends ApiBaseService {
4047
}
4148

4249
// PUT /api/users/account
43-
updateUserAccountInformation(request: UpdateAccountInformationCommand): Observable<BaseResponse> {
44-
return this.httpClient.put<SearchContactsResponse>(
50+
updateUserAccountInformation(
51+
request: UpdateAccountInformationCommand
52+
): Observable<UpdateUserAccountInfoResponse> {
53+
return this.httpClient.put<UpdateUserAccountInfoResponse>(
4554
this.baseUrl + this.usersRoute + 'account/',
4655
request
4756
);
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { BaseResponse } from './BaseResponse';
2+
import { User } from '../models/User';
3+
4+
export interface UpdatePersonalInformationResponse extends BaseResponse {
5+
user: User;
6+
}

0 commit comments

Comments
 (0)