portfolio-admin/src/app/admin/resume/resume.ts

217 lines
6.7 KiB
TypeScript

import { Component, inject, OnInit, OnDestroy } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MatDialog, MatDialogModule } from '@angular/material/dialog';
import { DynamicPopupComponent } from '../../shared/dynamic-popup/dynamic-popup';
import { DynamicFormConfig } from '../../shared/dynamic-form/dynamic-form-config';
import { AdminQuery } from '../state/admin.query';
import { AdminStateService } from '../state/admin-state.service';
import { Subject, takeUntil } from 'rxjs';
import { IAcademic } from '../models/academic.model';
import { IExperience } from '../models/experience.model';
import { ISkill } from '../models/skill.model';
import { ICertification } from '../models/certification.model';
@Component({
selector: 'app-resume',
templateUrl: './resume.html',
styleUrl: './resume.scss',
imports: [CommonModule, MatDialogModule]
})
export class Resume implements OnInit, OnDestroy {
private dialog = inject(MatDialog);
private adminQuery = inject(AdminQuery);
private adminState = inject(AdminStateService);
private destroy$ = new Subject<void>();
resume$ = this.adminQuery.resume$;
loading$ = this.adminQuery.resumeLoading$;
ngOnInit(): void {
if (!this.adminQuery.getResume()) {
this.adminState.loadResume()
.pipe(takeUntil(this.destroy$))
.subscribe();
}
}
openEditEducation(): void {
const resume = this.adminQuery.getResume();
const config: DynamicFormConfig = {
title: 'Edit Education',
submitLabel: 'Save',
api: {
save: '/api/v1/admin/UpsertAcademics',
method: 'POST',
bodyKey: 'academics'
},
fields: [
{
name: 'academics',
label: 'Education',
type: 'array',
itemConfig: [
{ name: 'academicId', label: 'ID', type: 'hidden' },
{ name: 'degree', label: 'Degree', type: 'text', required: true },
{ name: 'degreeSpecialization', label: 'Specialization', type: 'text' },
{ name: 'institution', label: 'Institution', type: 'text', required: true },
{ name: 'startYear', label: 'Start Year', type: 'year' },
{ name: 'endYear', label: 'End Year', type: 'year' }
]
}
]
};
const data = { academics: resume?.academics ?? [] };
const ref = this.dialog.open(DynamicPopupComponent, {
data: { config, data },
panelClass: 'dark-popup-panel'
});
ref.afterClosed()
.pipe(takeUntil(this.destroy$))
.subscribe((res: IAcademic[] | null) => {
if (res) {
this.adminState.updateResume({ ...resume!, academics: res });
}
});
}
openEditExperience(): void {
const resume = this.adminQuery.getResume();
const config: DynamicFormConfig = {
title: 'Edit Experience',
submitLabel: 'Save',
api: {
save: '/api/v1/admin/UpsertExperiences',
method: 'POST',
bodyKey: 'experiences'
},
fields: [
{
name: 'experiences',
label: 'Experiences',
type: 'array',
itemConfig: [
{ name: 'experienceId', label: 'ID', type: 'hidden' },
{ name: 'title', label: 'Job Title', type: 'text', required: true },
{ name: 'company', label: 'Company', type: 'text', required: true },
{ name: 'location', label: 'Location', type: 'text' },
{ name: 'description', label: 'Description', type: 'textarea' },
{ name: 'startDate', label: 'Start Date', type: 'date', required: true },
{ name: 'endDate', label: 'End Date', type: 'date' }
]
}
]
};
const data = { experiences: resume?.experiences ?? [] };
const ref = this.dialog.open(DynamicPopupComponent, {
data: { config, data },
panelClass: 'dark-popup-panel'
});
ref.afterClosed()
.pipe(takeUntil(this.destroy$))
.subscribe((res: IExperience[] | null) => {
if (res) {
this.adminState.updateResume({ ...resume!, experiences: res });
}
});
}
openEditSkills(): void {
const resume = this.adminQuery.getResume();
const config: DynamicFormConfig = {
title: 'Edit Skills',
submitLabel: 'Save',
api: {
save: '/api/v1/admin/UpsertSkills',
method: 'POST',
bodyKey: 'skills'
},
fields: [
{
name: 'skills',
label: 'Skills',
type: 'array',
itemConfig: [
{ name: 'skillId', label: 'ID', type: 'hidden' },
{ name: 'name', label: 'Skill Name', type: 'text', required: true },
{ name: 'description', label: 'Description', type: 'text' },
{ name: 'proficiencyLevel', label: 'Proficiency (%)', type: 'number', required: true }
]
}
]
};
const data = { skills: resume?.skills ?? [] };
const ref = this.dialog.open(DynamicPopupComponent, {
data: { config, data },
panelClass: 'dark-popup-panel'
});
ref.afterClosed()
.pipe(takeUntil(this.destroy$))
.subscribe((res: ISkill[] | null) => {
if (res) {
this.adminState.updateResume({ ...resume!, skills: res });
}
});
}
openEditCertifications(): void {
const resume = this.adminQuery.getResume();
const config: DynamicFormConfig = {
title: 'Edit Certifications',
submitLabel: 'Save',
api: {
save: '/api/v1/admin/UpsertCertifications',
method: 'POST',
bodyKey: 'certifications'
},
fields: [
{
name: 'certifications',
label: 'Certifications',
type: 'array',
itemConfig: [
{ name: 'certificationId', label: 'ID', type: 'hidden' },
{ name: 'certificationName', label: 'Certification Name', type: 'text', required: true },
{ name: 'issuingOrganization', label: 'Issuing Organization', type: 'text', required: true },
{ name: 'certificationLink', label: 'Link', type: 'text', placeholder: 'https://...' },
{ name: 'issueDate', label: 'Issue Date', type: 'date' },
{ name: 'expiryDate', label: 'Expiry Date', type: 'date' }
]
}
]
};
const data = { certifications: resume?.certifications ?? [] };
const ref = this.dialog.open(DynamicPopupComponent, {
data: { config, data },
panelClass: 'dark-popup-panel'
});
ref.afterClosed()
.pipe(takeUntil(this.destroy$))
.subscribe((res: ICertification[] | null) => {
if (res) {
this.adminState.updateResume({ ...resume!, certifications: res });
}
});
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
}