diff --git a/SystemKonkursow/4.2.1/angular/src/app/app-routing.module.ts b/SystemKonkursow/4.2.1/angular/src/app/app-routing.module.ts
index 47fd4cc..a293f03 100644
--- a/SystemKonkursow/4.2.1/angular/src/app/app-routing.module.ts
+++ b/SystemKonkursow/4.2.1/angular/src/app/app-routing.module.ts
@@ -3,6 +3,7 @@ import { RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { AppRouteGuard } from '@shared/auth/auth-route-guard';
import { HomeComponent } from './home/home.component';
+import { ProfileComponent } from './profile/profile.component';
import { AboutComponent } from './about/about.component';
import { UsersComponent } from './users/users.component';
import { TenantsComponent } from './tenants/tenants.component';
@@ -20,6 +21,7 @@ import { CompetitionCreateComponent } from '@app/competition-create/competition-
component: AppComponent,
children: [
{ path: 'home', component: HomeComponent, canActivate: [AppRouteGuard] },
+ { path: 'profile', component: ProfileComponent, canActivate: [AppRouteGuard] },
{ path: 'users', component: UsersComponent, data: { permission: 'Pages.Users' }, canActivate: [AppRouteGuard] },
{ path: 'roles', component: RolesComponent, data: { permission: 'Pages.Roles' }, canActivate: [AppRouteGuard] },
{ path: 'tenants', component: TenantsComponent, data: { permission: 'Pages.Tenants' }, canActivate: [AppRouteGuard] },
diff --git a/SystemKonkursow/4.2.1/angular/src/app/app.module.ts b/SystemKonkursow/4.2.1/angular/src/app/app.module.ts
index fbf7fee..3c115c5 100644
--- a/SystemKonkursow/4.2.1/angular/src/app/app.module.ts
+++ b/SystemKonkursow/4.2.1/angular/src/app/app.module.ts
@@ -16,6 +16,7 @@ import { ServiceProxyModule } from '@shared/service-proxies/service-proxy.module
import { SharedModule } from '@shared/shared.module';
import { HomeComponent } from '@app/home/home.component';
+import { ProfileComponent } from '@app/profile/profile.component';
import { AboutComponent } from '@app/about/about.component';
import { UsersComponent } from '@app/users/users.component';
import { CreateUserComponent } from '@app/users/create-user/create-user.component';
@@ -54,6 +55,7 @@ import {
declarations: [
AppComponent,
HomeComponent,
+ ProfileComponent,
AboutComponent,
TenantsComponent,
CreateTenantComponent,
diff --git a/SystemKonkursow/4.2.1/angular/src/app/layout/sidebar-nav.component.ts b/SystemKonkursow/4.2.1/angular/src/app/layout/sidebar-nav.component.ts
index 1c30dc2..91abeba 100644
--- a/SystemKonkursow/4.2.1/angular/src/app/layout/sidebar-nav.component.ts
+++ b/SystemKonkursow/4.2.1/angular/src/app/layout/sidebar-nav.component.ts
@@ -11,6 +11,7 @@ export class SideBarNavComponent extends AppComponentBase {
menuItems: MenuItem[] = [
new MenuItem(this.l("Strona domowa"), "", "home", "/app/home"),
+ new MenuItem(this.l("Profil"), "", "person", "/app/profile"),
new MenuItem(this.l("Konkursy"), "", "list", "/app/categories-list"),
new MenuItem(this.l("Dodaj konkurs"), "Pages.Create.Competition", "add", "/app/competition-create"),
diff --git a/SystemKonkursow/4.2.1/angular/src/app/layout/sidebar-user-area.component.html b/SystemKonkursow/4.2.1/angular/src/app/layout/sidebar-user-area.component.html
index edb3372..d8828ad 100644
--- a/SystemKonkursow/4.2.1/angular/src/app/layout/sidebar-user-area.component.html
+++ b/SystemKonkursow/4.2.1/angular/src/app/layout/sidebar-user-area.component.html
@@ -2,7 +2,7 @@
-
+
diff --git a/SystemKonkursow/4.2.1/angular/src/app/layout/topbar.component.html b/SystemKonkursow/4.2.1/angular/src/app/layout/topbar.component.html
index 5f2182e..7796d08 100644
--- a/SystemKonkursow/4.2.1/angular/src/app/layout/topbar.component.html
+++ b/SystemKonkursow/4.2.1/angular/src/app/layout/topbar.component.html
@@ -20,7 +20,8 @@
diff --git a/SystemKonkursow/4.2.1/angular/src/app/layout/topbar.component.ts b/SystemKonkursow/4.2.1/angular/src/app/layout/topbar.component.ts
index 427e92a..5eb8507 100644
--- a/SystemKonkursow/4.2.1/angular/src/app/layout/topbar.component.ts
+++ b/SystemKonkursow/4.2.1/angular/src/app/layout/topbar.component.ts
@@ -1,5 +1,6 @@
import { Component, Injector, ViewEncapsulation } from '@angular/core';
import { AppComponentBase } from '@shared/app-component-base';
+import { AppAuthService } from '@shared/auth/app-auth.service';
@Component({
templateUrl: './topbar.component.html',
@@ -11,8 +12,13 @@ export class TopBarComponent extends AppComponentBase {
public logoUrl: string = '/assets/images/logo.png';
constructor(
- injector: Injector
+ injector: Injector,
+ private _authService: AppAuthService
) {
super(injector);
}
+
+ logout(): void {
+ this._authService.logout();
+ }
}
\ No newline at end of file
diff --git a/SystemKonkursow/4.2.1/angular/src/app/profile/profile.component.css b/SystemKonkursow/4.2.1/angular/src/app/profile/profile.component.css
new file mode 100644
index 0000000..24e5a3e
--- /dev/null
+++ b/SystemKonkursow/4.2.1/angular/src/app/profile/profile.component.css
@@ -0,0 +1,3 @@
+h2 {
+ color: #771111;
+}
\ No newline at end of file
diff --git a/SystemKonkursow/4.2.1/angular/src/app/profile/profile.component.html b/SystemKonkursow/4.2.1/angular/src/app/profile/profile.component.html
new file mode 100644
index 0000000..16da2ff
--- /dev/null
+++ b/SystemKonkursow/4.2.1/angular/src/app/profile/profile.component.html
@@ -0,0 +1,58 @@
+
\ No newline at end of file
diff --git a/SystemKonkursow/4.2.1/angular/src/app/profile/profile.component.ts b/SystemKonkursow/4.2.1/angular/src/app/profile/profile.component.ts
new file mode 100644
index 0000000..cda0ae4
--- /dev/null
+++ b/SystemKonkursow/4.2.1/angular/src/app/profile/profile.component.ts
@@ -0,0 +1,70 @@
+import { Component, Injector, ElementRef, OnInit, OnDestroy, AfterViewInit, ViewChild } from '@angular/core';
+import { Router } from '@angular/router';
+import { UserProfileServiceProxy, UserProfileDto } from '@shared/service-proxies/service-proxies'
+import { AppComponentBase } from '@shared/app-component-base';
+import { accountModuleAnimation } from '@shared/animations/routerTransition';
+import { finalize } from 'rxjs/operators';
+import { Subscription } from 'rxjs/Rx';
+
+@Component({
+ templateUrl: './profile.component.html',
+ styleUrls: ['./profile.component.css'],
+ animations: [accountModuleAnimation()]
+})
+export class ProfileComponent extends AppComponentBase implements OnInit, OnDestroy, AfterViewInit {
+
+ @ViewChild('cardBody') cardBody: ElementRef;
+
+ public profileAreaId: string = 'profile-area';
+
+ public profile: UserProfileDto = new UserProfileDto();
+
+ private profileSubscription: Subscription;
+
+ public possibleClasses = [
+ {value: 1, viewValue: 'Klasa 1'},
+ {value: 2, viewValue: 'Klasa 2'},
+ {value: 3, viewValue: 'Klasa 3'},
+ {value: 4, viewValue: 'Klasa 4'},
+ {value: 5, viewValue: 'Klasa 5'},
+ {value: 6, viewValue: 'Klasa 6'},
+ {value: 7, viewValue: 'Klasa 7'},
+ {value: 8, viewValue: 'Klasa 8'}
+ ];
+
+ constructor(
+ injector: Injector,
+ private userProfileService: UserProfileServiceProxy,
+ private router: Router,
+ ) {
+ super(injector);
+ }
+
+ public ngAfterViewInit(): void {
+ }
+
+ public ngOnInit(): void {
+ this.setBusy(this.profileAreaId);
+
+ this.profileSubscription = this.userProfileService.getProfile()
+ .pipe(finalize(() => { this.clearBusy(this.profileAreaId); }))
+ .subscribe((result: UserProfileDto) => {
+ this.profile = result;
+ });
+ }
+
+ public ngOnDestroy(): void {
+ if (this.profileSubscription) {
+ this.profileSubscription.unsubscribe();
+ }
+ }
+
+ public saveProfile(): void {
+ this.profile.participantClass = +this.profile.participantClass;
+ this.userProfileService.updateProfile(this.profile)
+ .pipe(finalize(() => { this.router.navigate(['app/home']); }))
+ .subscribe(() => {
+ this.notify.success(this.l('Zapisano profil'));
+ });
+ }
+}
diff --git a/SystemKonkursow/4.2.1/angular/src/shared/service-proxies/service-proxies.ts b/SystemKonkursow/4.2.1/angular/src/shared/service-proxies/service-proxies.ts
index 72cfe72..54b5361 100644
--- a/SystemKonkursow/4.2.1/angular/src/shared/service-proxies/service-proxies.ts
+++ b/SystemKonkursow/4.2.1/angular/src/shared/service-proxies/service-proxies.ts
@@ -2065,6 +2065,122 @@ export class UserServiceProxy {
}
}
+@Injectable()
+export class UserProfileServiceProxy {
+ private http: HttpClient;
+ private baseUrl: string;
+ protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined;
+
+ constructor(@Inject(HttpClient) http: HttpClient, @Optional() @Inject(API_BASE_URL) baseUrl?: string) {
+ this.http = http;
+ this.baseUrl = baseUrl ? baseUrl : "";
+ }
+
+ /**
+ * @return Success
+ */
+ getProfile(): Observable {
+ let url_ = this.baseUrl + "/api/services/app/UserProfile/GetProfile";
+ url_ = url_.replace(/[?&]$/, "");
+
+ let options_ : any = {
+ observe: "response",
+ responseType: "blob",
+ headers: new HttpHeaders({
+ "Content-Type": "application/json",
+ "Accept": "application/json"
+ })
+ };
+
+ return this.http.request("get", url_, options_).pipe(_observableMergeMap((response_ : any) => {
+ return this.processGetProfile(response_);
+ })).pipe(_observableCatch((response_: any) => {
+ if (response_ instanceof HttpResponseBase) {
+ try {
+ return this.processGetProfile(response_);
+ } catch (e) {
+ return >_observableThrow(e);
+ }
+ } else
+ return >_observableThrow(response_);
+ }));
+ }
+
+ protected processGetProfile(response: HttpResponseBase): Observable {
+ const status = response.status;
+ const responseBlob =
+ response instanceof HttpResponse ? response.body :
+ (response).error instanceof Blob ? (response).error : undefined;
+
+ let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }};
+ if (status === 200) {
+ return blobToText(responseBlob).pipe(_observableMergeMap(_responseText => {
+ let result200: any = null;
+ let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
+ result200 = resultData200 ? UserProfileDto.fromJS(resultData200) : new UserProfileDto();
+ return _observableOf(result200);
+ }));
+ } else if (status !== 200 && status !== 204) {
+ return blobToText(responseBlob).pipe(_observableMergeMap(_responseText => {
+ return throwException("An unexpected server error occurred.", status, _responseText, _headers);
+ }));
+ }
+ return _observableOf(null);
+ }
+
+ /**
+ * @userProfile (optional)
+ * @return Success
+ */
+ updateProfile(userProfile: UserProfileDto | null | undefined): Observable {
+ let url_ = this.baseUrl + "/api/services/app/UserProfile/UpdateProfile";
+ url_ = url_.replace(/[?&]$/, "");
+
+ const content_ = JSON.stringify(userProfile);
+
+ let options_ : any = {
+ body: content_,
+ observe: "response",
+ responseType: "blob",
+ headers: new HttpHeaders({
+ "Content-Type": "application/json",
+ })
+ };
+
+ return this.http.request("put", url_, options_).pipe(_observableMergeMap((response_ : any) => {
+ return this.processUpdateProfile(response_);
+ })).pipe(_observableCatch((response_: any) => {
+ if (response_ instanceof HttpResponseBase) {
+ try {
+ return this.processUpdateProfile(response_);
+ } catch (e) {
+ return >_observableThrow(e);
+ }
+ } else
+ return >_observableThrow(response_);
+ }));
+ }
+
+ protected processUpdateProfile(response: HttpResponseBase): Observable {
+ const status = response.status;
+ const responseBlob =
+ response instanceof HttpResponse ? response.body :
+ (response).error instanceof Blob ? (response).error : undefined;
+
+ let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }};
+ if (status === 200) {
+ return blobToText(responseBlob).pipe(_observableMergeMap(_responseText => {
+ return _observableOf(null);
+ }));
+ } else if (status !== 200 && status !== 204) {
+ return blobToText(responseBlob).pipe(_observableMergeMap(_responseText => {
+ return throwException("An unexpected server error occurred.", status, _responseText, _headers);
+ }));
+ }
+ return _observableOf(null);
+ }
+}
+
export class IsTenantAvailableInput implements IIsTenantAvailableInput {
tenancyName: string;
@@ -4389,6 +4505,69 @@ export interface IPagedResultDtoOfUserDto {
items: UserDto[] | undefined;
}
+export class UserProfileDto implements IUserProfileDto {
+ name: string;
+ surname: string;
+ userName: string;
+ emailAddress: string;
+ participantClass: number;
+ id: number | undefined;
+
+ constructor(data?: IUserProfileDto) {
+ if (data) {
+ for (var property in data) {
+ if (data.hasOwnProperty(property))
+ (this)[property] = (data)[property];
+ }
+ }
+ }
+
+ init(data?: any) {
+ if (data) {
+ this.name = data["name"];
+ this.surname = data["surname"];
+ this.userName = data["userName"];
+ this.emailAddress = data["emailAddress"];
+ this.participantClass = data["participantClass"];
+ this.id = data["id"];
+ }
+ }
+
+ static fromJS(data: any): UserProfileDto {
+ data = typeof data === 'object' ? data : {};
+ let result = new UserProfileDto();
+ result.init(data);
+ return result;
+ }
+
+ toJSON(data?: any) {
+ data = typeof data === 'object' ? data : {};
+ data["name"] = this.name;
+ data["surname"] = this.surname;
+ data["userName"] = this.userName;
+ data["emailAddress"] = this.emailAddress;
+ data["participantClass"] = this.participantClass;
+ data["id"] = this.id;
+ return data;
+ }
+
+ clone(): UserProfileDto {
+ const json = this.toJSON();
+ let result = new UserProfileDto();
+ result.init(json);
+ return result;
+ }
+}
+
+export interface IUserProfileDto {
+ name: string;
+ surname: string;
+ userName: string;
+ emailAddress: string;
+ participantClass: number;
+ id: number | undefined;
+}
+
export enum IsTenantAvailableOutputState {
_1 = 1,
_2 = 2,
diff --git a/SystemKonkursow/4.2.1/angular/src/shared/service-proxies/service-proxy.module.ts b/SystemKonkursow/4.2.1/angular/src/shared/service-proxies/service-proxy.module.ts
index 5db6691..3c9a5e9 100644
--- a/SystemKonkursow/4.2.1/angular/src/shared/service-proxies/service-proxy.module.ts
+++ b/SystemKonkursow/4.2.1/angular/src/shared/service-proxies/service-proxy.module.ts
@@ -16,6 +16,7 @@ import * as ApiServiceProxies from './service-proxies';
ApiServiceProxies.CategoryServiceProxy,
ApiServiceProxies.CompetitionCategoryServiceProxy,
ApiServiceProxies.CompetitionServiceProxy,
+ ApiServiceProxies.UserProfileServiceProxy,
{ provide: HTTP_INTERCEPTORS, useClass: AbpHttpInterceptor, multi: true }
]
})
diff --git a/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.Application/UserProfile/Dto/UserProfileDto.cs b/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.Application/UserProfile/Dto/UserProfileDto.cs
new file mode 100644
index 0000000..a71c951
--- /dev/null
+++ b/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.Application/UserProfile/Dto/UserProfileDto.cs
@@ -0,0 +1,29 @@
+using Abp.Application.Services.Dto;
+using Abp.Authorization.Users;
+using System.ComponentModel.DataAnnotations;
+
+namespace SystemKonkursow.UserProfile.Dto
+{
+ public class UserProfileDto : EntityDto
+ {
+ [Required]
+ [StringLength(AbpUserBase.MaxNameLength)]
+ public string Name { get; set; }
+
+ [Required]
+ [StringLength(AbpUserBase.MaxSurnameLength)]
+ public string Surname { get; set; }
+
+ [Required]
+ [StringLength(AbpUserBase.MaxUserNameLength)]
+ public string UserName { get; set; }
+
+ [Required]
+ [EmailAddress]
+ [StringLength(AbpUserBase.MaxEmailAddressLength)]
+ public string EmailAddress { get; set; }
+
+ [Required]
+ public int ParticipantClass { get; set; }
+ }
+}
diff --git a/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.Application/UserProfile/Dto/UserProfileMapProfile.cs b/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.Application/UserProfile/Dto/UserProfileMapProfile.cs
new file mode 100644
index 0000000..1c1454d
--- /dev/null
+++ b/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.Application/UserProfile/Dto/UserProfileMapProfile.cs
@@ -0,0 +1,25 @@
+using AutoMapper;
+using SystemKonkursow.Authorization.Users;
+
+namespace SystemKonkursow.UserProfile.Dto
+{
+ public class UserProfileMapProfile : Profile
+ {
+ public UserProfileMapProfile()
+ {
+ CreateMap()
+ .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id))
+ .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Name))
+ .ForMember(dest => dest.Surname, opt => opt.MapFrom(src => src.Surname))
+ .ForMember(dest => dest.UserName, opt => opt.MapFrom(src => src.UserName))
+ .ForMember(dest => dest.EmailAddress, opt => opt.MapFrom(src => src.EmailAddress));
+
+ CreateMap()
+ .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id))
+ .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Name))
+ .ForMember(dest => dest.Surname, opt => opt.MapFrom(src => src.Surname))
+ .ForMember(dest => dest.UserName, opt => opt.MapFrom(src => src.UserName))
+ .ForMember(dest => dest.EmailAddress, opt => opt.MapFrom(src => src.EmailAddress));
+ }
+ }
+}
diff --git a/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.Application/UserProfile/UserProfileAppService.cs b/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.Application/UserProfile/UserProfileAppService.cs
new file mode 100644
index 0000000..f24a4d5
--- /dev/null
+++ b/SystemKonkursow/4.2.1/aspnet-core/src/SystemKonkursow.Application/UserProfile/UserProfileAppService.cs
@@ -0,0 +1,68 @@
+using Abp.Authorization;
+using Abp.Domain.Repositories;
+using Abp.Domain.Uow;
+using Microsoft.EntityFrameworkCore;
+using System.Threading.Tasks;
+using SystemKonkursow.Authorization.Users;
+using SystemKonkursow.UserProfile.Dto;
+
+namespace SystemKonkursow.UserProfile
+{
+ public class UserProfileAppService : SystemKonkursowAppServiceBase
+ {
+ private readonly UserManager _userManager;
+ private readonly IRepository _participantRepository;
+
+ public UserProfileAppService(UserManager userManager,
+ IRepository participantRepository)
+ {
+ _userManager = userManager;
+ _participantRepository = participantRepository;
+ }
+
+ [AbpAuthorize]
+ public async Task GetProfile()
+ {
+ var user = await GetCurrentUserAsync();
+
+ var mappedProfile = ObjectMapper.Map(user);
+
+ var isParticipant = await _userManager.IsParticipantUserAsync(user);
+
+ if (isParticipant)
+ {
+ var participant = await _participantRepository.GetAll()
+ .FirstOrDefaultAsync(t => t.UserId == user.Id);
+
+ mappedProfile.ParticipantClass = participant.ParticipantClass;
+ }
+ else
+ {
+ mappedProfile.ParticipantClass = 0;
+ }
+
+ return mappedProfile;
+ }
+
+ [AbpAuthorize]
+ [UnitOfWork]
+ public async Task UpdateProfile(UserProfileDto userProfile)
+ {
+ var user = await _userManager.GetUserByIdAsync(userProfile.Id);
+
+ ObjectMapper.Map(userProfile, user);
+ user.SetNormalizedNames();
+
+ CheckErrors(await _userManager.UpdateAsync(user));
+
+ if (userProfile.ParticipantClass != 0)
+ {
+ var participant = await _participantRepository.GetAll().FirstOrDefaultAsync(t => t.UserId == user.Id);
+
+ participant.ParticipantClass = userProfile.ParticipantClass;
+
+ await _participantRepository.UpdateAsync(participant);
+ }
+ }
+ }
+}