mirror of
https://github.com/akveo/ngx-admin.git
synced 2025-12-16 15:40:11 +01:00
Profile creation part done.
This commit is contained in:
parent
39385049e5
commit
f75e93e3eb
10 changed files with 1000 additions and 486 deletions
|
|
@ -3,24 +3,37 @@
|
|||
<a (click)="toggleSidebar()" href="#" class="sidebar-toggle">
|
||||
<nb-icon icon="menu-2-outline"></nb-icon>
|
||||
</a>
|
||||
<a class="logo" href="#" (click)="navigateHome()"><span><img src="assets/images/thread.png" alt="My Logo"></span>Resume Tailor</a>
|
||||
<a class="logo" href="#" (click)="navigateHome()"
|
||||
><span><img src="assets/images/thread.png" alt="My Logo" /></span>Resume
|
||||
Tailor</a
|
||||
>
|
||||
</div>
|
||||
<div class="spc"> </div>
|
||||
<nb-select [selected]="currentTheme" (selectedChange)="changeTheme($event)" status="primary">
|
||||
<nb-option *ngFor="let theme of themes" [value]="theme.value"> {{ theme.name }}</nb-option>
|
||||
<div class="spc"></div>
|
||||
<nb-select
|
||||
[selected]="currentTheme"
|
||||
(selectedChange)="changeTheme($event)"
|
||||
status="primary"
|
||||
>
|
||||
<nb-option *ngFor="let theme of themes" [value]="theme.value">
|
||||
{{ theme.name }}</nb-option
|
||||
>
|
||||
</nb-select>
|
||||
</div>
|
||||
|
||||
<div class="header-container">
|
||||
<nb-actions size="small">
|
||||
|
||||
<nb-action class="control-item">
|
||||
<nb-search type="rotate-layout"></nb-search>
|
||||
</nb-action>
|
||||
<nb-action class="control-item" icon="email-outline"></nb-action>
|
||||
<nb-action class="control-item" icon="bell-outline"></nb-action>
|
||||
<nb-action class="user-action" *nbIsGranted="['view', 'user']">
|
||||
<nb-user [nbContextMenu]="userMenu" [onlyPicture]="userPictureOnly" [name]="user?.name" [picture]="user?.picture">
|
||||
<nb-user
|
||||
[nbContextMenu]="userMenu"
|
||||
[onlyPicture]="userPictureOnly"
|
||||
[name]="user?.name"
|
||||
[picture]="user?.picture"
|
||||
>
|
||||
</nb-user>
|
||||
</nb-action>
|
||||
</nb-actions>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { NbMediaBreakpointsService, NbMenuService, NbSidebarService, NbThemeService } from '@nebular/theme';
|
||||
import { NbMediaBreakpointsService, NbMenuService, NbSidebarService, NbThemeService, NbMenuItem } from '@nebular/theme';
|
||||
|
||||
import { UserData } from '../../../@core/data/users';
|
||||
import { LayoutService } from '../../../@core/utils';
|
||||
import { map, takeUntil } from 'rxjs/operators';
|
||||
import { Subject } from 'rxjs';
|
||||
import { AuthService } from '../../../service/auth.service';
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-header',
|
||||
|
|
@ -26,14 +27,14 @@ export class HeaderComponent implements OnInit, OnDestroy {
|
|||
value: 'dark',
|
||||
name: 'Dark',
|
||||
},
|
||||
{
|
||||
value: 'cosmic',
|
||||
name: 'Cosmic',
|
||||
},
|
||||
{
|
||||
value: 'corporate',
|
||||
name: 'Corporate',
|
||||
},
|
||||
// {
|
||||
// value: 'cosmic',
|
||||
// name: 'Cosmic',
|
||||
// },
|
||||
// {
|
||||
// value: 'corporate',
|
||||
// name: 'Corporate',
|
||||
// },
|
||||
];
|
||||
|
||||
currentTheme = 'default';
|
||||
|
|
@ -45,7 +46,8 @@ export class HeaderComponent implements OnInit, OnDestroy {
|
|||
private themeService: NbThemeService,
|
||||
private userService: UserData,
|
||||
private layoutService: LayoutService,
|
||||
private breakpointService: NbMediaBreakpointsService) {
|
||||
private breakpointService: NbMediaBreakpointsService,
|
||||
private authService: AuthService) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
|
|
@ -69,6 +71,12 @@ export class HeaderComponent implements OnInit, OnDestroy {
|
|||
takeUntil(this.destroy$),
|
||||
)
|
||||
.subscribe(themeName => this.currentTheme = themeName);
|
||||
|
||||
this.menuService.onItemClick().subscribe((event: { item: NbMenuItem }) => {
|
||||
if (event.item.title === 'Log out') {
|
||||
this.logout();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
|
|
@ -91,4 +99,8 @@ export class HeaderComponent implements OnInit, OnDestroy {
|
|||
this.menuService.navigateHome();
|
||||
return false;
|
||||
}
|
||||
|
||||
logout(): void {
|
||||
this.authService.logout();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import {
|
|||
NbSidebarModule,
|
||||
NbToastrModule,
|
||||
NbWindowModule,
|
||||
NbCheckboxModule
|
||||
} from '@nebular/theme';
|
||||
import { environment } from '../environments/environment';
|
||||
import { CoreModule } from './@core/core.module';
|
||||
|
|
@ -41,6 +42,7 @@ import { AuthGuard } from './service/auth-guard.service';
|
|||
}),
|
||||
CoreModule.forRoot(),
|
||||
ThemeModule.forRoot(),
|
||||
NbCheckboxModule
|
||||
],
|
||||
providers: [
|
||||
AuthGuard
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { AccordionComponent } from './accordion/accordion.component';
|
|||
import { InfiniteListComponent } from './infinite-list/infinite-list.component';
|
||||
import { ListComponent } from './list/list.component';
|
||||
import { StepperComponent } from './stepper/stepper.component';
|
||||
import { ProfileComponent } from './stepper/profile/profile.component';
|
||||
|
||||
const routes: Routes = [{
|
||||
path: '',
|
||||
|
|
@ -16,6 +17,10 @@ const routes: Routes = [{
|
|||
path: 'stepper',
|
||||
component: StepperComponent,
|
||||
},
|
||||
{
|
||||
path: 'stepper/profile',
|
||||
component: ProfileComponent,
|
||||
},
|
||||
{
|
||||
path: 'list',
|
||||
component: ListComponent,
|
||||
|
|
|
|||
|
|
@ -1 +1,97 @@
|
|||
<p>profile works!</p>
|
||||
<nb-card>
|
||||
<nb-card-header>User Profile</nb-card-header>
|
||||
<nb-card-body>
|
||||
<div class="profile-details">
|
||||
<div class="personal-details">
|
||||
<h2>Personal Details</h2>
|
||||
<p><strong>Username:</strong> {{ userDetails.username }}</p>
|
||||
<p><strong>Email:</strong> {{ userDetails.email }}</p>
|
||||
<p><strong>Phone:</strong> {{ userDetails.phone }}</p>
|
||||
<p>
|
||||
<strong>Address:</strong> {{ userDetails.address1 }},
|
||||
{{ userDetails.address2 }}, {{ userDetails.city }},
|
||||
{{ userDetails.state }}, {{ userDetails.zip }}
|
||||
</p>
|
||||
<p>
|
||||
<strong>LinkedIn:</strong>
|
||||
<a href="{{ userDetails.linkedinLink }}" target="_blank">{{
|
||||
userDetails.linkedinLink
|
||||
}}</a>
|
||||
</p>
|
||||
<p>
|
||||
<strong>Portfolio:</strong>
|
||||
<a href="{{ userDetails.portfolioLink }}" target="_blank">{{
|
||||
userDetails.portfolioLink
|
||||
}}</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="professional-summary">
|
||||
<h2>Professional Summary</h2>
|
||||
<p>{{ userDetails.professionalSummary }}</p>
|
||||
</div>
|
||||
<div class="experience">
|
||||
<h2>Experience</h2>
|
||||
<ul>
|
||||
<li *ngFor="let exp of userExperiences">
|
||||
<p><strong>Position:</strong> {{ exp.position }}</p>
|
||||
<p><strong>Employer:</strong> {{ exp.employer }}</p>
|
||||
<p><strong>Location:</strong> {{ exp.location }}</p>
|
||||
<p><strong>Start Date:</strong> {{ exp.startDate }}</p>
|
||||
<p><strong>End Date:</strong> {{ exp.endDate }}</p>
|
||||
<p><strong>Description:</strong> {{ exp.description }}</p>
|
||||
<div *ngIf="exp.projects && exp.projects.length > 0">
|
||||
<p><strong>Projects:</strong></p>
|
||||
<ul>
|
||||
<li *ngFor="let project of exp.projects">
|
||||
<p><strong>Name:</strong> {{ project.name }}</p>
|
||||
<p><strong>Description:</strong> {{ project.description }}</p>
|
||||
<p>
|
||||
<strong>Link:</strong>
|
||||
<a href="{{ project.link }}" target="_blank">{{
|
||||
project.link
|
||||
}}</a>
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="education">
|
||||
<h2>Education</h2>
|
||||
<ul>
|
||||
<li *ngFor="let edu of userEducation">
|
||||
<p><strong>Degree Name:</strong> {{ edu.degreeName }}</p>
|
||||
<p><strong>School:</strong> {{ edu.school }}</p>
|
||||
<p><strong>Location:</strong> {{ edu.location }}</p>
|
||||
<p><strong>Major:</strong> {{ edu.major }}</p>
|
||||
<p><strong>Minor:</strong> {{ edu.minor }}</p>
|
||||
<p><strong>Start Date:</strong> {{ edu.startDate }}</p>
|
||||
<p><strong>End Date:</strong> {{ edu.endDate }}</p>
|
||||
<p><strong>Grade:</strong> {{ edu.grade }}</p>
|
||||
<p><strong>Description:</strong> {{ edu.description }}</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="certifications">
|
||||
<h2>Certifications</h2>
|
||||
<ul>
|
||||
<li *ngFor="let cert of userCertificates">
|
||||
<p><strong>Certificate Name:</strong> {{ cert.certificateName }}</p>
|
||||
<p><strong>Issuer:</strong> {{ cert.certificateIssuer }}</p>
|
||||
<p><strong>Year:</strong> {{ cert.certificateYear }}</p>
|
||||
<p><strong>Relevance:</strong> {{ cert.certificateRelevance }}</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="skills">
|
||||
<h2>Skills</h2>
|
||||
<ul>
|
||||
<li *ngFor="let skill of userSkills">
|
||||
<p><strong>Name:</strong> {{ skill.name }}</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nb-card-body>
|
||||
</nb-card>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,46 @@
|
|||
import { Component } from '@angular/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { UserAPI } from '../../../../service/api/user-api.service';
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-profile',
|
||||
templateUrl: './profile.component.html',
|
||||
styleUrls: ['./profile.component.scss']
|
||||
styleUrls: ['./profile.component.scss'],
|
||||
})
|
||||
export class ProfileComponent {
|
||||
export class ProfileComponent implements OnInit {
|
||||
userDetails: any = {};
|
||||
userExperiences: any[] = [];
|
||||
userEducation: any[] = [];
|
||||
userProjects: any[] = [];
|
||||
userSkills: any[] = [];
|
||||
userCertificates: any[] = [];
|
||||
// userResumes: any[] = [];
|
||||
// userCoverLetters: any[] = [];
|
||||
|
||||
constructor(private route: ActivatedRoute, private userAPI: UserAPI) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.route.queryParams.subscribe((params) => {
|
||||
const userId = params['userId']; // Get the userId from query params
|
||||
|
||||
if (userId) {
|
||||
this.userAPI.getUserDetails(userId).subscribe((response) => {
|
||||
if (response.success) {
|
||||
this.userDetails = response.data;
|
||||
this.userExperiences = this.userDetails.experiences || [];
|
||||
this.userEducation = this.userDetails.education || [];
|
||||
this.userProjects = this.userDetails.projects || [];
|
||||
this.userSkills = this.userDetails.skills || [];
|
||||
this.userCertificates = this.userDetails.certificates || [];
|
||||
// this.userResumes = this.userDetails.resumes || [];
|
||||
// this.userCoverLetters = this.userDetails.coverLetters || [];
|
||||
} else {
|
||||
console.error('Failed to retrieve user details:', response.message);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.error('User ID not found in query parameters.');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,8 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { Router, NavigationExtras } from '@angular/router';
|
||||
|
||||
import { UserAPI } from '../../../service/api/user-api.service';
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-stepper',
|
||||
|
|
@ -8,36 +11,117 @@ import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms
|
|||
})
|
||||
export class StepperComponent implements OnInit {
|
||||
|
||||
firstForm: UntypedFormGroup;
|
||||
secondForm: UntypedFormGroup;
|
||||
thirdForm: UntypedFormGroup;
|
||||
personalDetails: FormGroup;
|
||||
experience: FormGroup;
|
||||
project: FormGroup;
|
||||
education: FormGroup;
|
||||
certifications: FormGroup;
|
||||
skills: FormGroup;
|
||||
professionalSummary: FormGroup;
|
||||
userId: string
|
||||
|
||||
constructor(private fb: UntypedFormBuilder) {
|
||||
constructor(private fb: FormBuilder, private userAPI: UserAPI, private router: Router) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.firstForm = this.fb.group({
|
||||
firstCtrl: ['', Validators.required],
|
||||
this.personalDetails = this.fb.group({
|
||||
username: [''],
|
||||
email: [''],
|
||||
phone: [''],
|
||||
address1: [''],
|
||||
address2: [''],
|
||||
city: [''],
|
||||
state: [''],
|
||||
zip: [''],
|
||||
linkedinLink: [''],
|
||||
portfolioLink: [''],
|
||||
});
|
||||
|
||||
this.secondForm = this.fb.group({
|
||||
secondCtrl: ['', Validators.required],
|
||||
this.experience = this.fb.group({
|
||||
position: [''],
|
||||
employer: [''],
|
||||
location: [''],
|
||||
startDate: [''],
|
||||
endDate: [''],
|
||||
currentJob: [''],
|
||||
companyLink: [''],
|
||||
description: [''],
|
||||
});
|
||||
|
||||
this.thirdForm = this.fb.group({
|
||||
thirdCtrl: ['', Validators.required],
|
||||
this.project = this.fb.group({
|
||||
name: [''],
|
||||
link: [''],
|
||||
employer: [''],
|
||||
description: [''],
|
||||
startDate: [''],
|
||||
endDate: [''],
|
||||
});
|
||||
|
||||
this.education = this.fb.group({
|
||||
degreeName: [''],
|
||||
school: [''],
|
||||
location: [''],
|
||||
major: [''],
|
||||
minor: [''],
|
||||
startDate: [''],
|
||||
endDate: [''],
|
||||
grade: [''],
|
||||
description: [''],
|
||||
});
|
||||
|
||||
this.certifications = this.fb.group({
|
||||
name: [''],
|
||||
issuer: [''],
|
||||
startDate: [''],
|
||||
endDate: [''],
|
||||
description: [''],
|
||||
});
|
||||
|
||||
this.skills = this.fb.group({
|
||||
name: [''],
|
||||
});
|
||||
|
||||
this.professionalSummary = this.fb.group({
|
||||
professionalSummary: [''],
|
||||
});
|
||||
}
|
||||
|
||||
onFirstSubmit() {
|
||||
this.firstForm.markAsDirty();
|
||||
}
|
||||
async submitForms() {
|
||||
try {
|
||||
// Combine professional summary with personal details
|
||||
const personalDetailsWithSummary = {
|
||||
...this.personalDetails.value,
|
||||
professionalSummary: this.professionalSummary.value.professionalSummary,
|
||||
password: 'password',
|
||||
role: 'USER'
|
||||
};
|
||||
|
||||
onSecondSubmit() {
|
||||
this.secondForm.markAsDirty();
|
||||
}
|
||||
// Save personal details including professional summary
|
||||
const userDetailsResponse = await this.userAPI.saveUserDetails(personalDetailsWithSummary).toPromise();
|
||||
this.userId = userDetailsResponse.data.id;
|
||||
|
||||
onThirdSubmit() {
|
||||
this.thirdForm.markAsDirty();
|
||||
console.log(this.userId)
|
||||
|
||||
// Save other details using the obtained user ID
|
||||
await Promise.all([
|
||||
this.userAPI.saveExperience(this.experience.value, this.userId).toPromise(),
|
||||
this.userAPI.saveEducation(this.education.value, this.userId).toPromise(),
|
||||
this.userAPI.saveProjects(this.project.value, this.userId).toPromise(),
|
||||
this.userAPI.saveSkills(this.skills.value, this.userId).toPromise(),
|
||||
this.userAPI.saveCertifications(this.certifications.value, this.userId).toPromise()
|
||||
]);
|
||||
|
||||
|
||||
console.log("userID: ", this.userId)
|
||||
|
||||
// Navigate to the profile page
|
||||
const navigationExtras: NavigationExtras = {
|
||||
queryParams: { userId: this.userId }
|
||||
};
|
||||
this.router.navigateByUrl('/pages/layout/stepper/profile', navigationExtras);
|
||||
} catch (error) {
|
||||
console.error('Error occurred while saving user details:', error);
|
||||
// Handle error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
59
src/app/service/api/user-api.service.ts
Normal file
59
src/app/service/api/user-api.service.ts
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class UserAPI {
|
||||
|
||||
private baseUrl = 'http://localhost:8080/api';
|
||||
private token: string;
|
||||
|
||||
constructor(private http: HttpClient) {
|
||||
this.token = localStorage.getItem('accessToken');
|
||||
}
|
||||
|
||||
// Saving user details
|
||||
saveUserDetails(data: any): Observable<any> {
|
||||
const headers = new HttpHeaders().set('Authorization', `Bearer ${this.token}`);
|
||||
return this.http.post(`${this.baseUrl}/users`, data, { headers });
|
||||
}
|
||||
|
||||
// Get single user
|
||||
getUserDetails(userId: string): Observable<any> {
|
||||
console.log(userId)
|
||||
const headers = new HttpHeaders().set('Authorization', `Bearer ${this.token}`);
|
||||
return this.http.get<any>(`${this.baseUrl}/users/${userId}`, { headers });
|
||||
}
|
||||
|
||||
saveExperience(data: any, userId: string): Observable<any> {
|
||||
console.log(userId)
|
||||
const headers = new HttpHeaders().set('Authorization', `Bearer ${this.token}`);
|
||||
return this.http.post(`${this.baseUrl}/experiences?userId=${userId}`, data, { headers });
|
||||
}
|
||||
|
||||
saveEducation(data: any, userId: string): Observable<any> {
|
||||
console.log(userId)
|
||||
const headers = new HttpHeaders().set('Authorization', `Bearer ${this.token}`);
|
||||
return this.http.post(`${this.baseUrl}/education?userId=${userId}`, data, { headers });
|
||||
}
|
||||
|
||||
saveProjects(data: any, userId: string): Observable<any> {
|
||||
console.log(userId)
|
||||
const headers = new HttpHeaders().set('Authorization', `Bearer ${this.token}`);
|
||||
return this.http.post(`${this.baseUrl}/projects?userId=${userId}`, data, { headers });
|
||||
}
|
||||
|
||||
saveSkills(data: any, userId: string): Observable<any> {
|
||||
console.log(userId)
|
||||
const headers = new HttpHeaders().set('Authorization', `Bearer ${this.token}`);
|
||||
return this.http.post(`${this.baseUrl}/skills?userId=${userId}`, data, { headers });
|
||||
}
|
||||
|
||||
saveCertifications(data: any, userId: string): Observable<any> {
|
||||
console.log(userId)
|
||||
const headers = new HttpHeaders().set('Authorization', `Bearer ${this.token}`);
|
||||
return this.http.post(`${this.baseUrl}/certifications?userId=${userId}`, data, { headers });
|
||||
}
|
||||
}
|
||||
|
|
@ -22,7 +22,7 @@ export class AuthService {
|
|||
await this.fireAuth.signOut();
|
||||
localStorage.removeItem('accessToken');
|
||||
localStorage.removeItem('accessTokenExpiresIn');
|
||||
this.router.navigate(['dashboard'], { queryParams: { logout: true } });
|
||||
this.router.navigate(['auth/login'], { queryParams: { logout: true } });
|
||||
} catch (error: any) {
|
||||
throw error;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue