Add Job Listing Skills to Job Listing

This commit is contained in:
2025-08-25 17:31:49 -07:00
parent 662d6f332c
commit e92e4c329f
11 changed files with 69 additions and 10 deletions
+2 -1
View File
@@ -12,9 +12,10 @@ Server:
Need to update notification email Need to update notification email
Create page to notify cx that their work email has been verified Create page to notify cx that their work email has been verified
Verify that each resume section belongs to the resume it was created for:
Client: Client:
jobs/editor: jobs/editor:
Job Listing Skills exists but isn't implimented in the UI
Want to add completed job listing preview at end of carosel Want to add completed job listing preview at end of carosel
Resume: Resume:
+1
View File
@@ -9,4 +9,5 @@ export class Application {
public hasBeenViewed: boolean = false; public hasBeenViewed: boolean = false;
public rating: number = 0; public rating: number = 0;
public notes: string = ""; public notes: string = "";
public trackUUID: string = crypto.randomUUID();
} }
+1
View File
@@ -13,4 +13,5 @@ export class Company {
public stateOrRegion: string = ""; public stateOrRegion: string = "";
public city: string = ""; public city: string = "";
public description: string = ""; public description: string = "";
public trackUUID: string = crypto.randomUUID();
} }
+1
View File
@@ -6,4 +6,5 @@ export class Employee {
public accountName: string = ""; public accountName: string = "";
public accountEmail: string = ""; public accountEmail: string = "";
public company: Company = new Company; public company: Company = new Company;
public trackUUID: string = crypto.randomUUID();
} }
+3 -1
View File
@@ -15,11 +15,13 @@ export class JobListing {
public createdTime: Date = new Date(); public createdTime: Date = new Date();
public modifiedTime: Date = new Date(); public modifiedTime: Date = new Date();
public isDeleted: boolean = false; public isDeleted: boolean = false;
public trackUUID: string = crypto.randomUUID();
} }
export class JobListingSkills { export class JobListingSkills {
public id: number | null = null; public id: number | null = null;
public jobListingID: number = 0; public jobListingID: number = 0;
public name: string = ""; public name: string = "";
public Description: string = ""; public description: string = "";
public trackUUID: string = crypto.randomUUID();
} }
@@ -91,6 +91,27 @@
</div> </div>
</div> </div>
<!-- Skills -->
<div #step class="sub-frame">
<div class="center">
<div class="content-frame">
<label>Skills</label>
<button type="button" (click)="addSkill()">+</button>
</div>
@for(skill of Listing.skills; track skill.trackUUID){
<div class="content-frame">
<input [name]="'skillname' + skill.trackUUID" [(ngModel)]="skill.name" type="text" />
<textarea [name]="'skilldescription' + skill.trackUUID" [(ngModel)]="skill.description" type="text"></textarea>
<button type="button" (click)="remSkill(skill)">-</button>
</div>
}
<div class="content-frame">
<button type="button" (click)="prevStep()">Back</button>
<button type="button" (click)="nextStep()">Next</button>
</div>
</div>
</div>
<!-- Description --> <!-- Description -->
<div #step class="sub-frame"> <div #step class="sub-frame">
<div class="center"> <div class="center">
@@ -4,7 +4,7 @@ import { FormsModule } from '@angular/forms';
import { Router, ActivatedRoute, RouterModule } from '@angular/router'; import { Router, ActivatedRoute, RouterModule } from '@angular/router';
import { Title } from '@angular/platform-browser'; import { Title } from '@angular/platform-browser';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { JobListing } from 'app/models/JobListing'; import { JobListing, JobListingSkills } from 'app/models/JobListing';
import { Authentication } from 'app/services/Authentication'; import { Authentication } from 'app/services/Authentication';
@Component({ @Component({
@@ -51,6 +51,9 @@ export class JobEditorComponent {
if (this.mode === "edit") { if (this.mode === "edit") {
this.http.get<JobListing>("api/joblisting/" + JobID).subscribe({ this.http.get<JobListing>("api/joblisting/" + JobID).subscribe({
next: data => { next: data => {
data.skills.forEach(element => {
element.trackUUID = crypto.randomUUID();
});
this.Listing = data; this.Listing = data;
}, },
error: err => { error: err => {
@@ -80,6 +83,20 @@ export class JobEditorComponent {
}); });
} }
addSkill(){
this.Listing.skills.push(new JobListingSkills);
}
remSkill(self: JobListingSkills){
for(let i=0; i<this.Listing.skills.length; i++){
let cur = this.Listing.skills[i];
if (cur.trackUUID === self.trackUUID){
this.Listing.skills.splice( i, 1 );
break;
}
}
}
nextStep(){ nextStep(){
this.currentStep += 1; this.currentStep += 1;
this.updateUI(); this.updateUI();
@@ -47,6 +47,16 @@
<h1>{{ selectedJob.country }}</h1> <h1>{{ selectedJob.country }}</h1>
<h1>{{ selectedJob.postalCode }}</h1> <h1>{{ selectedJob.postalCode }}</h1>
<div>
<h1>Required Skills</h1>
@for(skill of selectedJob.skills; track skill.trackUUID){
<div>
<h1>{{ skill.name }}</h1>
<h1>{{ skill.description }}</h1>
</div>
}
</div>
<h1>{{ selectedJob.description }}</h1> <h1>{{ selectedJob.description }}</h1>
</div> </div>
} }
@@ -75,11 +75,6 @@ export class ResumesEditorComponent {
}); });
} }
// Pagnation //
////////////////////////////////
////////////////////////////////
SubmitForm(resume: Resume){ SubmitForm(resume: Resume){
resume.accountID = this.auth.loggedInUser.id; resume.accountID = this.auth.loggedInUser.id;
this.http.post("api/resume", resume).subscribe({ this.http.post("api/resume", resume).subscribe({
@@ -228,6 +228,8 @@ namespace BoredCareers.Services.DatabaseService {
Description = @Description, Description = @Description,
ModifiedTime = @ModifiedTime, ModifiedTime = @ModifiedTime,
IsDeleted = @IsDeleted; IsDeleted = @IsDeleted;
SELECT LAST_INSERT_ID();
"; ";
MySqlCommand cmd = new MySqlCommand(command, connection); MySqlCommand cmd = new MySqlCommand(command, connection);
@@ -247,9 +249,17 @@ namespace BoredCareers.Services.DatabaseService {
cmd.Parameters.AddWithValue("@ModifiedTime", DateTime.UtcNow); cmd.Parameters.AddWithValue("@ModifiedTime", DateTime.UtcNow);
cmd.Parameters.AddWithValue("@IsDeleted", jobListing.IsDeleted); cmd.Parameters.AddWithValue("@IsDeleted", jobListing.IsDeleted);
await cmd.ExecuteNonQueryAsync(); object? result = await cmd.ExecuteScalarAsync();
int jobListingID = 0;
if (jobListing.ID != null && jobListing.ID != 0) {
jobListingID = Convert.ToInt32(jobListing.ID);
} else {
cmd.CommandText = "";
jobListingID = Convert.ToInt32(result);
}
foreach (JobListingSkill cur in jobListing.Skills) { foreach (JobListingSkill cur in jobListing.Skills) {
cur.JobListingID = jobListingID;
await SetJobListingSkills(cur); await SetJobListingSkills(cur);
} }
} }
@@ -43,7 +43,7 @@ namespace BoredCareers.Services.DatabaseService {
using( MySqlConnection connection = GetConnection() ) { using( MySqlConnection connection = GetConnection() ) {
await connection.OpenAsync(); await connection.OpenAsync();
string command = @" string command = @"
INSERT INTO JobListing INSERT INTO JobListingSkill
(ID,JobListingID,Name,Description) (ID,JobListingID,Name,Description)
VALUES VALUES
(@ID,@JobListingID,@Name,@Description) (@ID,@JobListingID,@Name,@Description)