Skip to content

Commit 7825fbf

Browse files
committed
feat: update link to user profile
1 parent 3c52f68 commit 7825fbf

File tree

16 files changed

+101
-23
lines changed

16 files changed

+101
-23
lines changed

src/CoinyProject.Api/Controllers/UserController.cs

+14
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,19 @@ public async Task<IActionResult> GetUser([FromQuery] Guid? id)
3838
return NotFound(e.Message);
3939
}
4040
}
41+
42+
[HttpGet("{id}/name")]
43+
public async Task<IActionResult> GetUserName([FromRoute]Guid id)
44+
{
45+
try
46+
{
47+
var userName = await _userService.GetUserNameAsync(id);
48+
return Ok(userName);
49+
}
50+
catch (NotFoundException e)
51+
{
52+
return NotFound(e.Message);
53+
}
54+
}
4155

4256
}

src/CoinyProject.Application/Abstractions/Services/IUserService.cs

+1
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ public interface IUserService
66
{
77
Task<UserStatsGetDto> GetUserStatsAsync(Guid userId);
88
Task<UserStatsGetDto> GetCurrentUserStatsAsync();
9+
Task<UserNameGetDto> GetUserNameAsync(Guid userId);
910
}

src/CoinyProject.Application/Dto/Auth/LoginResponseDto.cs

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
public sealed class LoginResponseDto
44
{
5+
public Guid Id { get; set; }
56
public string Username { get; set; }
67
public string Email { get; set; }
78
public string Token { get; set; }

src/CoinyProject.Application/Services/AuthService.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ public async Task<LoginResponseDto> LoginAsync(LoginRequestDto login)
4747

4848
return new LoginResponseDto
4949
{
50+
Id = identityUser.Id,
5051
Username = identityUser.UserName,
51-
Email = login.EmailOrUsername,
52+
Email = identityUser.Email,
5253
Roles = roles.ToList(),
5354
Token = jwtToken
5455
};

src/CoinyProject.Application/Services/UserService.cs

+9
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,13 @@ public async Task<UserStatsGetDto> GetCurrentUserStatsAsync()
4040

4141
return await GetUserStatsAsync(currentUserId);
4242
}
43+
44+
public async Task<UserNameGetDto> GetUserNameAsync(Guid userId)
45+
{
46+
var album = await _unitOfWork.Users.GetByIdAsync(userId);
47+
if (album == null)
48+
throw new NotFoundException("Album not found.");
49+
50+
return _mapper.Map<UserNameGetDto>(album);
51+
}
4352
}

src/CoinyProject.Client/src/app/album/album-view/album-view.component.html

+9-3
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,18 @@ <h2 class="text-lg font-bold mb-2 truncate text-yellow-600">{{ album.name }}</h2
110110
<!-- Author section -->
111111
<div class="flex items-center mb-4">
112112
<span class="font-bold text-yellow-600">Author: </span>
113-
<a [routerLink]="['/profile', album.author.id]" class="ml-2 text-yellow-600 hover:underline">
113+
<!-- Conditional RouterLink -->
114+
<a
115+
[routerLink]="user?.id === album.author.id ? ['/profile'] : ['/profile', album.author.id]"
116+
[queryParams]="user?.id === album.author.id ? { my: true } : null"
117+
class="ml-2 text-yellow-600 hover:text-yellow-500 transition duration-300">
114118
{{ album.author.username }}
115119
</a>
116120
</div>
117-
</div>
118121

119-
</div>
122+
123+
124+
</div>
120125
</div>
121126
</div>
127+
</div>

src/CoinyProject.Client/src/app/album/album-view/album-view.component.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import {AlbumViewGetDto} from "./album-view-get.model";
44
import {DatePipe, NgClass, NgForOf} from "@angular/common";
55
import {FormsModule} from "@angular/forms";
66
import {ActivatedRoute, RouterLink} from "@angular/router";
7+
import {UserModel} from "../../services/user.model";
8+
import {AuthService} from "../../services/auth.service";
79

810
@Component({
911
selector: 'app-album-view',
@@ -30,9 +32,14 @@ export class AlbumViewComponent implements OnInit {
3032
userId: string | null = null;
3133
isCurrentUser: boolean = false;
3234

33-
constructor(private albumService: AlbumService, private route: ActivatedRoute) {}
35+
user: UserModel | undefined;
36+
37+
constructor(private authService:AuthService, private albumService: AlbumService, private route: ActivatedRoute) {}
3438

3539
ngOnInit(): void {
40+
this.authService.user().subscribe(user => {
41+
this.user = user;
42+
});
3643
// Отримання параметрів із маршруту або queryParams
3744
this.route.params.subscribe(params => {
3845
this.userId = params['id'] || null; // якщо передається userId

src/CoinyProject.Client/src/app/login/login-response.module.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export interface LoginResponseModel{
2+
id: string;
23
username: string;
34
email: string;
45
token: string;

src/CoinyProject.Client/src/app/login/login.component.ts

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export class LoginComponent {
3333
this.cookieService.set('Authorization', `Bearer ${response.token}`,
3434
undefined, '/', undefined, true, 'Strict');
3535
this.authService.setUser({
36+
id: response.id,
3637
username: response.username,
3738
email: response.email,
3839
roles: response.roles

src/CoinyProject.Client/src/app/register/register.component.ts

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ export class RegisterComponent {
5454
this.cookieService.set('Authorization', `Bearer ${response.token}`,
5555
undefined, '/', undefined, true, 'Strict');
5656
this.authService.setUser({
57+
id: response.id,
5758
username: response.username,
5859
email: response.email,
5960
roles: response.roles
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,44 @@
11
<div class="container mx-auto px-4 py-8">
22
<!-- Main Content Wrapper -->
3-
<div class="bg-pastel-red-light shadow-md rounded-lg p-4">
4-
<h3 class="text-lg font-bold mb-4">Колекціонування</h3>
5-
<h4 class="text-md font-bold mb-2">Нумізматика</h4>
6-
<ul class="space-y-2">
7-
<li><a href="#" class="text-blue-500 hover:underline">Золоті, платинові і паладієві монети</a></li>
8-
<li><a href="#" class="text-blue-500 hover:underline">Монети Київської Русі</a></li>
9-
<li><a href="#" class="text-blue-500 hover:underline">Монети Російської Імперії</a></li>
10-
<li><a href="#" class="text-blue-500 hover:underline">Монети Польщі</a></li>
11-
<li><a href="#" class="text-blue-500 hover:underline">Монети України</a></li>
12-
<li><a href="#" class="text-blue-500 hover:underline">Монети незалежних Держав Азії</a></li>
13-
<li><a href="#" class="text-blue-500 hover:underline">Монети античних держав</a></li>
14-
</ul>
15-
</div>
16-
</div>
3+
<div class="bg-yellow-50 shadow-lg rounded-lg p-6">
4+
<h3 class="text-xl font-bold mb-6 text-yellow-600">Колекціонування</h3>
5+
<h4 class="text-lg font-bold mb-4 text-yellow-600">Нумізматика</h4>
6+
<ul class="space-y-4">
7+
<li>
8+
<a href="#" class="text-gray-700 font-semibold transition-colors duration-300 hover:text-white hover:bg-yellow-500 rounded-md px-3 py-2 inline-block">
9+
Золоті, платинові і паладієві монети
10+
</a>
11+
</li>
12+
<li>
13+
<a href="#" class="text-gray-700 font-semibold transition-colors duration-300 hover:text-white hover:bg-yellow-500 rounded-md px-3 py-2 inline-block">
14+
Монети Київської Русі
15+
</a>
16+
</li>
17+
<li>
18+
<a href="#" class="text-gray-700 font-semibold transition-colors duration-300 hover:text-white hover:bg-yellow-500 rounded-md px-3 py-2 inline-block">
19+
Монети Російської Імперії
20+
</a>
21+
</li>
22+
<li>
23+
<a href="#" class="text-gray-700 font-semibold transition-colors duration-300 hover:text-white hover:bg-yellow-500 rounded-md px-3 py-2 inline-block">
24+
Монети Польщі
25+
</a>
26+
</li>
27+
<li>
28+
<a href="#" class="text-gray-700 font-semibold transition-colors duration-300 hover:text-white hover:bg-yellow-500 rounded-md px-3 py-2 inline-block">
29+
Монети України
30+
</a>
31+
</li>
32+
<li>
33+
<a href="#" class="text-gray-700 font-semibold transition-colors duration-300 hover:text-white hover:bg-yellow-500 rounded-md px-3 py-2 inline-block">
34+
Монети незалежних Держав Азії
35+
</a>
36+
</li>
37+
<li>
38+
<a href="#" class="text-gray-700 font-semibold transition-colors duration-300 hover:text-white hover:bg-yellow-500 rounded-md px-3 py-2 inline-block">
39+
Монети античних держав
40+
</a>
41+
</li>
42+
</ul>
43+
</div>
44+
</div>

src/CoinyProject.Client/src/app/services/auth.service.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {BehaviorSubject, Observable} from "rxjs";
44
import {RegisterDto} from "../register/register.module";
55
import {LoginRequestDto} from "../login/login-request.module";
66
import {CookieService} from "ngx-cookie-service";
7-
import {UserModel} from "./user.module";
7+
import {UserModel} from "./user.model";
88
import {LoginResponseModel} from "../login/login-response.module";
99

1010
@Injectable({
@@ -27,6 +27,7 @@ export class AuthService {
2727
}
2828

2929
setUser(user: UserModel): void {
30+
localStorage.setItem('user-id', user.id);
3031
localStorage.setItem('user-name', user.username);
3132
localStorage.setItem('user-email', user.email);
3233
localStorage.setItem('user-roles', user.roles.join());
@@ -43,12 +44,14 @@ export class AuthService {
4344
}
4445

4546
getUser(): UserModel | undefined {
47+
const id = localStorage.getItem('user-id');
4648
const username = localStorage.getItem('user-name');
4749
const email = localStorage.getItem('user-email');
4850
const roles = localStorage.getItem('user-roles');
4951

50-
if (username && email && roles) {
52+
if (id && username && email && roles) {
5153
return {
54+
id,
5255
username,
5356
email,
5457
roles: roles.split(',')

src/CoinyProject.Client/src/app/services/user.module.ts src/CoinyProject.Client/src/app/services/user.model.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export interface UserModel{
2+
id: string;
23
username: string;
34
email: string;
45
roles: string[];

src/CoinyProject.Client/src/app/services/user.service.ts

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Injectable } from '@angular/core';
22
import {Observable} from "rxjs";
33
import {UserStatsModel} from "../profile/stats/stats.module";
44
import {HttpClient, HttpParams} from "@angular/common/http";
5+
import {UsernameModel} from "./username.model";
56

67
@Injectable({
78
providedIn: 'root'
@@ -23,4 +24,7 @@ export class UserService {
2324
return this.http.get<UserStatsModel>(`${this.baseUrl}/stats`, {params} ); // Adjust the endpoint accordingly
2425
}
2526

27+
getUsernameById(id: string): Observable<UsernameModel> {
28+
return this.http.get<UsernameModel>(`${this.baseUrl}/${id}/name`);
29+
}
2630
}

src/CoinyProject.Client/src/app/top-bar/top-bar.component.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {Component, OnInit} from '@angular/core';
22
import {NgClass, NgForOf, NgIf, NgOptimizedImage} from "@angular/common";
33
import {Router, RouterLink} from "@angular/router";
4-
import {UserModel} from "../services/user.module";
4+
import {UserModel} from "../services/user.model";
55
import {AuthService} from "../services/auth.service";
66

77
@Component({

src/CoinyProject.Client/src/main.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ bootstrapApplication(AppComponent, {
1010
providers: [
1111
provideRouter(routes),
1212
importProvidersFrom(HttpClientModule),
13-
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }
13+
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
1414
]
1515
}).catch(err => console.error(err));

0 commit comments

Comments
 (0)