diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 1866296..8aa7b2c 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -22,6 +22,7 @@ }, "args": [ "build", + "--configuration=development", "--base-href=http://localhost:5000" ], "problemMatcher": "$msCompile" diff --git a/ToDo.yaml b/ToDo.yaml index e5128e5..9e59b7b 100755 --- a/ToDo.yaml +++ b/ToDo.yaml @@ -35,4 +35,10 @@ Task: Create a server table inside the auth database Point all requests after auth to the correct regional server. -> Currently only Mistox-West exists - CompanyConnect | need to lookup company before making a new one \ No newline at end of file + CompanyConnect | need to lookup company before making a new one + + Finish Auth setup + Make sure autorenew works + + Jobs/editor w/ Querystring JobID=# is not implimented yet + Company -> Edit employees not implimented yet \ No newline at end of file diff --git a/database/mistox.sql b/database/mistox.sql index 995ee57..4f83a81 100755 --- a/database/mistox.sql +++ b/database/mistox.sql @@ -1,25 +1,6 @@ CREATE DATABASE IF NOT EXISTS `boredcareers`; USE `boredcareers`; --- Account Section - -CREATE TABLE IF NOT EXISTS `Account` ( - `ID` int NOT NULL AUTO_INCREMENT, - `UserName` varchar(60) NOT NULL, - `Email` varchar(255) NOT NULL, - `EmailVerified` boolean DEFAULT 0, - `PasswordHash` char(60) DEFAULT NULL, - `FailedPasswordLock` boolean DEFAULT 0, - `PasswordAttempts` int(11) DEFAULT NULL, - `CurrentPasswordAttempts` int(11) DEFAULT NULL, - `Role` varchar(45) DEFAULT NULL, - `EmailToken` varchar(45) DEFAULT NULL, - `DataServer` varchar(200) DEFAULT NULL, - UNIQUE(`Email`), - UNIQUE(`UserName`), - PRIMARY KEY (`ID`) -) AUTO_INCREMENT=1; - -- Resume Section CREATE TABLE IF NOT EXISTS `Resume` ( diff --git a/src/Client/src/app/app.html b/src/Client/src/app/app.html index 70d5048..369369b 100644 --- a/src/Client/src/app/app.html +++ b/src/Client/src/app/app.html @@ -1,19 +1,24 @@
- HOME JOB BOARD RESUMES + COMPANIES
- +
+ + + + + - +
diff --git a/src/Client/src/app/app.routes.ts b/src/Client/src/app/app.routes.ts index 1a884a2..8331146 100644 --- a/src/Client/src/app/app.routes.ts +++ b/src/Client/src/app/app.routes.ts @@ -5,23 +5,29 @@ import { ContactComponent } from './pages/legal/contact/contact.component'; import { PrivacyComponent } from './pages/legal/privacy/privacy.component'; import { JobsComponent } from './pages/main/jobs/jobs.component'; import { ResumesComponent } from './pages/main/resumes/resumes.component'; -import { JobNewComponent } from './pages/main/jobs/new/jobnew.component'; -import { JobEditComponent } from './pages/main/jobs/edit/jobedit.component'; +import { JobEditorComponent } from './pages/main/jobs/editor/jobeditor.component'; import { CompanyConnectComponent } from './pages/main/company/connect/companyconnect.component'; +import { JobViewerComponent } from './pages/main/jobs/viewer/jobviewer.component'; +import { CompanyJobsComponent } from './pages/main/company/jobs/jobs.component'; +import { CompanyComponent } from './pages/main/company/company.component'; export const routes: Routes = [ // Home { path: "", component: HomeComponent }, + + // Resumes { path: "resumes", component: ResumesComponent }, // Jobs { path: "jobs", component: JobsComponent }, - { path: "jobs/new", component: JobNewComponent }, - { path: "jobs/edit", component: JobEditComponent }, + { path: "jobs/editor", component: JobEditorComponent }, + { path: "jobs/viewer", component: JobViewerComponent }, // Company + { path: "company", component: CompanyComponent }, { path: "company/connect", component: CompanyConnectComponent }, + { path: "company/jobs", component: CompanyJobsComponent }, // Legal { path: "about", component: AboutComponent }, diff --git a/src/Client/src/app/app.ts b/src/Client/src/app/app.ts index bcba189..7c72022 100644 --- a/src/Client/src/app/app.ts +++ b/src/Client/src/app/app.ts @@ -3,6 +3,7 @@ import { Router, RouterModule, RouterOutlet, ActivatedRoute } from '@angular/rou import { Authentication } from './services/Authentication'; import { CommonModule, Location } from '@angular/common'; import { HttpClient } from '@angular/common/http'; +import { isDevMode } from '@angular/core'; @Component({ selector: 'app-root', @@ -12,11 +13,16 @@ import { HttpClient } from '@angular/common/http'; }) export class App { - @ViewChild('homeLink') homeLink!: ElementRef; + @ViewChild('companiesLink') companiesLink!: ElementRef; @ViewChild('jobsLink') jobLink!: ElementRef; @ViewChild('resumesLink') resumeLink!: ElementRef; + devMode: boolean = false; + constructor( private http: HttpClient, public auth: Authentication, private router: Router, private route: ActivatedRoute, private location: Location){ + + this.devMode = isDevMode(); + this.route.queryParams.subscribe(params => { const loginToken = params['LoginToken']; @@ -43,7 +49,7 @@ export class App { } ngAfterViewInit(){ - let ViewLinks = [ this.homeLink, this.resumeLink, this.jobLink ]; + let ViewLinks = [ this.companiesLink, this.resumeLink, this.jobLink ]; ViewLinks.forEach(link => { if (new URL(link.nativeElement.href).pathname === new URL(window.location.href).pathname){ link.nativeElement.classList.add("active"); diff --git a/src/Client/src/app/models/Company.ts b/src/Client/src/app/models/Company.ts index 4ceca30..d0762ca 100644 --- a/src/Client/src/app/models/Company.ts +++ b/src/Client/src/app/models/Company.ts @@ -1,5 +1,5 @@ export class Company { - public id: number = 0; + public id: number = -1; public name: string = ""; public email: string = ""; public emailVerified: boolean = false; @@ -14,7 +14,7 @@ export class Company { } export class Employee { - public id: number = 0; + public id: number = -1; public accountID: number = 0; public company: Company = new Company; } \ No newline at end of file diff --git a/src/Client/src/app/models/JobListing.ts b/src/Client/src/app/models/JobListing.ts index 3aae717..18b9427 100644 --- a/src/Client/src/app/models/JobListing.ts +++ b/src/Client/src/app/models/JobListing.ts @@ -1,5 +1,5 @@ export class JobListing { - public id: number = 0; + public id: number = -1; public companyID: number = 0; public title: string = ""; public postalCode: string = ""; diff --git a/src/Client/src/app/models/Resume.ts b/src/Client/src/app/models/Resume.ts index ef68ba7..4ac970f 100644 --- a/src/Client/src/app/models/Resume.ts +++ b/src/Client/src/app/models/Resume.ts @@ -1,5 +1,5 @@ export class Resume { - public id: number = 0; + public id: number = -1; public accountID: number = 0; public name: string = ""; public field: string = ""; @@ -20,7 +20,7 @@ export class Resume { } export class ResumeExperience { - id: number = 0; + id: number = -1; resumeID: number = 0; jobTitle: string = ""; company: string = ""; @@ -35,14 +35,14 @@ export class ResumeExperience { } export class ResumeExperienceBullet { - id: number = 0; + id: number = -1; resumeID: number = 0; resumeExperienceID: number = 0; jobFunction: string = ""; } export class ResumeMilitary { - id: number = 0; + id: number = -1; resumeID: number = 0; country: string = ""; rank: string = ""; @@ -53,7 +53,7 @@ export class ResumeMilitary { } export class ResumeMilitaryBullet { - id: number = 0; + id: number = -1; resumeID: number = 0; resumeMilitaryID: number = 0; achievement: string = ""; @@ -61,7 +61,7 @@ export class ResumeMilitaryBullet { } export class ResumeEducation { - id: number = 0; + id: number = -1; resumeID: number = 0; degreeType: string = ""; degreeField: string = ""; @@ -76,21 +76,21 @@ export class ResumeEducation { } export class ResumeSkill { - id: number = 0; // PK - resumeID: number = 0; // FK + id: number = -1; + resumeID: number = 0; name: string = ""; description: string = ""; } export class ResumeLanguage { - id: number = 0; + id: number = -1; resumeID: number = 0; language: string = ""; proficiency: string = ""; } export class ResumeCertification { - id: number = 0; + id: number = -1; resumeID: number = 0; name: string = ""; verificationURL: string = ""; @@ -98,7 +98,7 @@ export class ResumeCertification { } export class ResumeProject { - id: number = 0; + id: number = -1; resumeID: number = 0; name: string = ""; url: string = ""; diff --git a/src/Client/src/app/pages/main/company/company.component.css b/src/Client/src/app/pages/main/company/company.component.css new file mode 100644 index 0000000..4263503 --- /dev/null +++ b/src/Client/src/app/pages/main/company/company.component.css @@ -0,0 +1,33 @@ +button { + height: 45px; + border-radius: 5px; + margin: 10px; + text-align: center; + padding: 15px 20px; + transition: 0.5s; + background-color: #00000000; + border: 1px solid var(--Mistox-Black); + color: var(--Mistox-Black); + text-decoration: none; + font: inherit; +} + + button:hover { + background-color: #00000044; + color: var(--Mistox-Light); + } + +.top-bar { + width: 100%; + height: 60px; +} + +.content-frame { + background-color: #3c3c3c; + width: calc(100% - 40px); + height: calc(100vh - 400px); + border-radius: 20px; + margin: 10px; + overflow: scroll; + padding: 10px; +} \ No newline at end of file diff --git a/src/Client/src/app/pages/main/company/company.component.html b/src/Client/src/app/pages/main/company/company.component.html new file mode 100644 index 0000000..f2be310 --- /dev/null +++ b/src/Client/src/app/pages/main/company/company.component.html @@ -0,0 +1,20 @@ +
+ + +
+
+
+

{{ Comp.name }}

+

{{ Comp.email }}

+

{{ Comp.emailVerified }}

+

{{ Comp.websiteURL }}

+

{{ Comp.logoURL }}

+

{{ Comp.phone }}

+

{{ Comp.postalCode }}

+

{{ Comp.country }}

+

{{ Comp.stateOrRegion }}

+

{{ Comp.city }}

+

{{ Comp.description }}

+ +
+
\ No newline at end of file diff --git a/src/Client/src/app/pages/main/company/company.component.ts b/src/Client/src/app/pages/main/company/company.component.ts new file mode 100644 index 0000000..dc8ee16 --- /dev/null +++ b/src/Client/src/app/pages/main/company/company.component.ts @@ -0,0 +1,46 @@ +import { Component } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { FormsModule } from '@angular/forms'; +import { Router, ActivatedRoute, RouterModule } from '@angular/router'; +import { Title } from '@angular/platform-browser'; +import { CommonModule } from '@angular/common'; +import { Authentication } from 'app/services/Authentication'; +import { Company, Employee } from 'app/models/Company'; + +@Component({ + selector: 'main-company', + templateUrl: './company.component.html', + styleUrls: [ './company.component.css' ], + imports: [ FormsModule, CommonModule, RouterModule ] +}) +export class CompanyComponent { + public ErrorMsg: string = ""; + + public Employers: Employee[] = []; + public Comp: Company | null = null; + + constructor( private http: HttpClient, private router: Router, private route: ActivatedRoute, private title: Title, public auth: Authentication ) { + this.title.setTitle("Companies | BoredCareers"); + http.get("api/employee/").subscribe({ + next: data => { + this.Employers = data; + }, + error: err => { + this.ErrorMsg = err.error; + } + }); + + }; + + changeSelectedCompany(companyID: number){ + this.http.get("api/company?CompanyID=" + companyID).subscribe({ + next: data => { + this.Comp = data; + }, + error: err => { + this.ErrorMsg = err.error; + } + }); + } + +} \ No newline at end of file diff --git a/src/Client/src/app/pages/main/company/jobs/jobs.component.css b/src/Client/src/app/pages/main/company/jobs/jobs.component.css new file mode 100644 index 0000000..6044df9 --- /dev/null +++ b/src/Client/src/app/pages/main/company/jobs/jobs.component.css @@ -0,0 +1,87 @@ +button { + width: 150px; + border-radius: 5px; + margin: 10px; + text-align: center; + padding: 15px 0; + transition: .5s; + background-color: #0000; + border: 1px solid var(--Mistox-White); + color: var(--Mistox-White); + text-decoration: none; +} + + button:hover { + background-color: #00000044; + color: var(--Mistox-Light); + } + +.full-width { + display: block; + width: 100%; + column-count: 2; +} + +.tile-frame { + display: grid; + grid-template-columns: repeat(4, 1fr); + column-gap: 20px; + padding: 20px; + width: calc(100% - 40px); +} + +.tile{ + background-color: var(--Mistox-Dark); + color: var(--Mistox-White); + break-inside: avoid; + padding: 20px; + border-radius: 20px; + margin-bottom: 20px; +} + +.jobs-frame { + width: 100%; + background-color: #8888; + border-top: 2px solid black; +} + +.post-job-frame { + display: flex; + justify-content: center; + padding: 10px 0; +} + +.tile-title { + text-align: center; + border-bottom: 1px solid; +} + +.tile-title h1 { + font-size: 40px; + margin: 5px 0; +} + +.tile-title h2 { + font-size: 14px; +} + +.tile-split { + columns: 2; + text-align: center; + padding: 10px 0; +} + +.tile-split h1 { + margin: 0; +} + +.tile-button { + display: flex; + width: 100%; + justify-content: center; +} + +.post-job-frame button { + border-color: var(--Mistox-Black); + color: var(--Mistox-Black); +} \ No newline at end of file diff --git a/src/Client/src/app/pages/main/company/jobs/jobs.component.html b/src/Client/src/app/pages/main/company/jobs/jobs.component.html new file mode 100644 index 0000000..70552be --- /dev/null +++ b/src/Client/src/app/pages/main/company/jobs/jobs.component.html @@ -0,0 +1,23 @@ +
+ +
+ +
+
+
+

{{ cur.title }}

+

{{ cur.jobType }}

+

Is Remote: {{ cur.remote }}

+

{{ cur.salaryMin }}

+

{{ cur.salaryMax }}

+

{{ cur.city }}

+

{{ cur.stateOrRegion }}

+

{{ cur.country }}

+

{{ cur.postalCode }}

+

Posted: {{ cur.createdTime }}

+

Modified: {{ cur.modifiedTime }}

+
+ + +
+
\ No newline at end of file diff --git a/src/Client/src/app/pages/main/jobs/edit/jobedit.component.ts b/src/Client/src/app/pages/main/company/jobs/jobs.component.ts similarity index 58% rename from src/Client/src/app/pages/main/jobs/edit/jobedit.component.ts rename to src/Client/src/app/pages/main/company/jobs/jobs.component.ts index 5b108a1..d81f192 100644 --- a/src/Client/src/app/pages/main/jobs/edit/jobedit.component.ts +++ b/src/Client/src/app/pages/main/company/jobs/jobs.component.ts @@ -8,35 +8,34 @@ import { JobListing } from 'app/models/JobListing'; import { Authentication } from 'app/services/Authentication'; @Component({ - selector: 'main-jobs-edit', - templateUrl: './jobedit.component.html', - styleUrls: [ './jobedit.component.css' ], + selector: 'main-company-jobs', + templateUrl: './jobs.component.html', + styleUrls: [ './jobs.component.css' ], imports: [ FormsModule, CommonModule, RouterModule ] }) -export class JobEditComponent { +export class CompanyJobsComponent { public MyJobListings: JobListing[] = []; - public JobListingPage: JobListing[] = []; public ErrorMsg: string = ""; - public Page: number = 1; - constructor( private http: HttpClient, private router: Router, private route: ActivatedRoute, private title: Title, public auth: Authentication ) { - this.title.setTitle("Jobs - edit | BoredCareers"); - - if (this.Page == 1){ - - } - - http.get("api/joblisting?PageQuantity=" + 10 + "&Page=" + 1).subscribe({ - next: data => { - this.JobListingPage = data; - }, - error: err => { - this.ErrorMsg = err.error; - } - }); + this.title.setTitle("Company - Jobs | BoredCareers"); + this.route.queryParams.subscribe(params => { + const companyID = params['CompanyID']; + if (companyID){ + http.get("api/joblisting/company?CompanyID=" + companyID).subscribe({ + next: data => { + this.MyJobListings = data; + }, + error: err => { + this.ErrorMsg = err.error; + } + }); + }else{ + router.navigate(["/company"]); + } + }); }; RemoveJobListing( JobListingID: number ){ diff --git a/src/Client/src/app/pages/main/jobs/edit/jobedit.component.css b/src/Client/src/app/pages/main/jobs/edit/jobedit.component.css deleted file mode 100644 index 9d97a2c..0000000 --- a/src/Client/src/app/pages/main/jobs/edit/jobedit.component.css +++ /dev/null @@ -1,12 +0,0 @@ -.tile-frame { - column-count: 4; - column-gap: 20px; - padding: 20px; - width: calc(100% - 40px); -} - -.tile{ - background-color: var(--Mistox-Dark)\); - height: 40px; - break-inside: avoid; -} \ No newline at end of file diff --git a/src/Client/src/app/pages/main/jobs/edit/jobedit.component.html b/src/Client/src/app/pages/main/jobs/edit/jobedit.component.html deleted file mode 100644 index 05e4dca..0000000 --- a/src/Client/src/app/pages/main/jobs/edit/jobedit.component.html +++ /dev/null @@ -1,16 +0,0 @@ -
-
-

{{ cur.title }}

-

{{ cur.jobType }}

-

Is Remote: {{ cur.remote }}

-

{{ cur.salaryMin }}

-

{{ cur.salaryMax }}

-

{{ cur.city }}

-

{{ cur.stateOrRegion }}

-

{{ cur.country }}

-

{{ cur.postalCode }}

-

{{ cur.description }}

-

Posted: {{ cur.createdTime }}

-

Modified: {{ cur.modifiedTime }}

-
-
\ No newline at end of file diff --git a/src/Client/src/app/pages/main/jobs/new/jobnew.component.css b/src/Client/src/app/pages/main/jobs/editor/jobeditor.component.css similarity index 100% rename from src/Client/src/app/pages/main/jobs/new/jobnew.component.css rename to src/Client/src/app/pages/main/jobs/editor/jobeditor.component.css diff --git a/src/Client/src/app/pages/main/jobs/new/jobnew.component.html b/src/Client/src/app/pages/main/jobs/editor/jobeditor.component.html similarity index 100% rename from src/Client/src/app/pages/main/jobs/new/jobnew.component.html rename to src/Client/src/app/pages/main/jobs/editor/jobeditor.component.html diff --git a/src/Client/src/app/pages/main/jobs/new/jobnew.component.ts b/src/Client/src/app/pages/main/jobs/editor/jobeditor.component.ts similarity index 91% rename from src/Client/src/app/pages/main/jobs/new/jobnew.component.ts rename to src/Client/src/app/pages/main/jobs/editor/jobeditor.component.ts index 62324e2..bd69aad 100644 --- a/src/Client/src/app/pages/main/jobs/new/jobnew.component.ts +++ b/src/Client/src/app/pages/main/jobs/editor/jobeditor.component.ts @@ -9,12 +9,12 @@ import { Authentication } from 'app/services/Authentication'; import { Company, Employee } from 'app/models/Company'; @Component({ - selector: 'main-jobs-new', - templateUrl: './jobnew.component.html', - styleUrls: [ './jobnew.component.css' ], + selector: 'main-jobs-editor', + templateUrl: './jobeditor.component.html', + styleUrls: [ './jobeditor.component.css' ], imports: [ FormsModule, CommonModule, RouterModule ] }) -export class JobNewComponent { +export class JobEditorComponent { @ViewChildren('step') formSteps!: QueryList>; currentStep: number = 0; @@ -26,7 +26,7 @@ export class JobNewComponent { public ErrorMsg: string = ""; constructor( private http: HttpClient, private router: Router, private route: ActivatedRoute, private title: Title, public auth: Authentication ) { - this.title.setTitle("Jobs - new | BoredCareers"); + this.title.setTitle("Jobs - Editor | BoredCareers"); this.http.get("api/employee").subscribe({ next: empOf => { diff --git a/src/Client/src/app/pages/main/jobs/jobs.component.html b/src/Client/src/app/pages/main/jobs/jobs.component.html index 5e5ab3d..f6bdacc 100644 --- a/src/Client/src/app/pages/main/jobs/jobs.component.html +++ b/src/Client/src/app/pages/main/jobs/jobs.component.html @@ -1,27 +1,3 @@ - -
-
-
-

{{ cur.title }}

-

{{ cur.jobType }}

-

Is Remote: {{ cur.remote }}

-

{{ cur.salaryMin }}

-

{{ cur.salaryMax }}

-

{{ cur.city }}

-

{{ cur.stateOrRegion }}

-

{{ cur.country }}

-

{{ cur.postalCode }}

-

Posted: {{ cur.createdTime }}

-

Modified: {{ cur.modifiedTime }}

-
- - -
-
- -
-
-
@@ -38,7 +14,7 @@

{{ cur.stateOrRegion }}

- +
\ No newline at end of file diff --git a/src/Client/src/app/pages/main/jobs/viewer/jobviewer.component.css b/src/Client/src/app/pages/main/jobs/viewer/jobviewer.component.css new file mode 100644 index 0000000..c357862 --- /dev/null +++ b/src/Client/src/app/pages/main/jobs/viewer/jobviewer.component.css @@ -0,0 +1,11 @@ +.job-frame { + +} + +.job-warning { + +} + +.job-details { + +} \ No newline at end of file diff --git a/src/Client/src/app/pages/main/jobs/viewer/jobviewer.component.html b/src/Client/src/app/pages/main/jobs/viewer/jobviewer.component.html new file mode 100644 index 0000000..a49aeb4 --- /dev/null +++ b/src/Client/src/app/pages/main/jobs/viewer/jobviewer.component.html @@ -0,0 +1,42 @@ +
+
+

{{ jobsCompany.name }}

+ +

{{ jobsCompany.email }}

+

{{ jobsCompany.websiteURL }}

+ +

{{ jobsCompany.logoURL }}

+

{{ jobsCompany.phone }}

+ +

{{ jobsCompany.city }}

+

{{ jobsCompany.stateOrRegion }}

+

{{ jobsCompany.country }}

+

{{ jobsCompany.postalCode }}

+ +

{{ jobsCompany.description }}

+
+
+ +
+

THIS JOB POSTING IS CLOSED

+
+ +

{{ selectedJob.title }}

+ +

{{ selectedJob.jobType }}

+

{{ selectedJob.remote }}

+ +

{{ selectedJob.salaryMin }}

+

{{ selectedJob.salaryMax }}

+ +

{{ selectedJob.city }}

+

{{ selectedJob.stateOrRegion }}

+

{{ selectedJob.country }}

+

{{ selectedJob.postalCode }}

+ +

{{ selectedJob.description }}

+ +

{{ selectedJob.createdTime }}

+

{{ selectedJob.modifiedTime }}

+
+
\ No newline at end of file diff --git a/src/Client/src/app/pages/main/jobs/viewer/jobviewer.component.ts b/src/Client/src/app/pages/main/jobs/viewer/jobviewer.component.ts new file mode 100644 index 0000000..1c922e5 --- /dev/null +++ b/src/Client/src/app/pages/main/jobs/viewer/jobviewer.component.ts @@ -0,0 +1,55 @@ +import { Component } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { FormsModule } from '@angular/forms'; +import { Router, ActivatedRoute, RouterModule } from '@angular/router'; +import { Title } from '@angular/platform-browser'; +import { CommonModule } from '@angular/common'; +import { Authentication } from 'app/services/Authentication'; +import { JobListing } from 'app/models/JobListing'; +import { Company } from 'app/models/Company'; + +@Component({ + selector: 'main-jobs-viewer', + templateUrl: './jobviewer.component.html', + styleUrls: [ './jobviewer.component.css' ], + imports: [ FormsModule, CommonModule, RouterModule ] +}) +export class JobViewerComponent { + + public selectedJob: JobListing | null = null; + public jobsCompany: Company | null = null; + public ErrorMsg: string = ""; + + constructor( private http: HttpClient, private router: Router, private route: ActivatedRoute, private title: Title, public auth: Authentication ) { + this.title.setTitle("Jobs - Viewer | BoredCareers"); + + this.route.queryParams.subscribe(params => { + const JobID = params['JobID']; + if (JobID){ + this.http.get( "api/joblisting/" + JobID ).subscribe({ + next: data => { + this.selectedJob = data; + this.http.get("api/company?CompanyID=" + this.selectedJob.companyID).subscribe({ + next: data => { + this.jobsCompany = data; + }, + error: err => { + this.ErrorMsg = err.ErrorMsg; + } + }) + }, + error: err => { + this.ErrorMsg = err.error; + } + }) + }else{ + router.navigate(["/"]); + } + if (this.selectedJob != null){ + + } + }); + + }; + +} \ No newline at end of file diff --git a/src/Client/src/app/pages/main/resumes/resumes.component.html b/src/Client/src/app/pages/main/resumes/resumes.component.html index 196d036..dad91d6 100644 --- a/src/Client/src/app/pages/main/resumes/resumes.component.html +++ b/src/Client/src/app/pages/main/resumes/resumes.component.html @@ -1,13 +1,4 @@ -
-
-

{{ cur.name }}

-

{{ cur.field }}

-

{{ cur.email }}

-

{{ cur.phoneNumber }}

-

{{ cur.city }}

-

{{ cur.stateOrRegion }}

-

{{ cur.country }}

-

{{ cur.postalCode }}

-

Active: {{ cur.isActive }}

-
+ +
+
\ No newline at end of file diff --git a/src/Client/src/app/pages/main/resumes/resumes.component.ts b/src/Client/src/app/pages/main/resumes/resumes.component.ts index 75cba38..4783dd1 100644 --- a/src/Client/src/app/pages/main/resumes/resumes.component.ts +++ b/src/Client/src/app/pages/main/resumes/resumes.component.ts @@ -1,24 +1,33 @@ import { Component } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { FormsModule } from '@angular/forms'; -import { Router, ActivatedRoute } from '@angular/router'; +import { Router, ActivatedRoute, RouterModule } from '@angular/router'; import { Title } from '@angular/platform-browser'; import { CommonModule } from '@angular/common'; import { Resume } from 'app/models/Resume'; +import { Authentication } from 'app/services/Authentication'; @Component({ selector: 'main-resumes', templateUrl: './resumes.component.html', styleUrls: [ './resumes.component.css' ], - imports: [ FormsModule, CommonModule ] + imports: [ FormsModule, CommonModule, RouterModule ] }) export class ResumesComponent { public ResumePage: Resume[] = []; - constructor( private http: HttpClient, private router: Router, private route: ActivatedRoute, private title: Title ) { + constructor( private http: HttpClient, private router: Router, private route: ActivatedRoute, private title: Title, public auth: Authentication ) { this.title.setTitle("Resumes | BoredCareers"); + this.http.get("api/resume").subscribe({ + next: data => { + this.ResumePage = data; + }, + error: err => { + console.log("Error fetching resumes: " + err.error); + } + }); }; } \ No newline at end of file diff --git a/src/Server/Controllers/JobListingController.cs b/src/Server/Controllers/JobListingController.cs index a6c36a6..63a6941 100644 --- a/src/Server/Controllers/JobListingController.cs +++ b/src/Server/Controllers/JobListingController.cs @@ -19,6 +19,18 @@ namespace BoredCareers.Controllers { return NotFound("Job listing not found"); } + [HttpGet("company")] + public async Task GetCompanysJobListings([FromQuery] int CompanyID) { + if (isLoggedIn()) { + if (await isLoggedInUserEmployeeOf(CompanyID)) { + JobListing[] jobListings = await _databaseService.GetJobListingFromCompany(CompanyID); + return Ok(jobListings); + } + return NotFound("You are not an employee of company"); + } + return NotFound("Not logged in"); + } + [HttpGet] public async Task GetJobListings(int Page = 1, int PageQuantity = 25) { JobListing[] jobListings = await _databaseService.GetJobListingPage(Page, PageQuantity); diff --git a/src/Server/Entities/Account.cs b/src/Server/Entities/Account.cs index a98ddd4..601a831 100644 --- a/src/Server/Entities/Account.cs +++ b/src/Server/Entities/Account.cs @@ -3,13 +3,7 @@ namespace BoredCareers.Entities { public int ID { get; set; } // PK public string UserName { get; set; } = ""; public string Email { get; set; } = ""; - public bool EmailVerified { get; set; } = false; - public string PasswordHash { get; set; } = ""; - public bool FailedPasswordLock { get; set; } = false; - public int PasswordAttempts { get; set; } = 5; - public int CurrentPasswordAttempts { get; set; } = 0; public string Role { get; set; } = "Generic"; - public string EmailToken { get; set; } = ""; public string DataServer { get; set; } = ""; } } \ No newline at end of file diff --git a/src/Server/Services/DatabaseService/Account.cs b/src/Server/Services/DatabaseService/Account.cs deleted file mode 100755 index 09d5cf8..0000000 --- a/src/Server/Services/DatabaseService/Account.cs +++ /dev/null @@ -1,160 +0,0 @@ -using BoredCareers.Entities; -using MySql.Data.MySqlClient; -using System.Data; -using System.Data.Common; - -namespace BoredCareers.Services.DatabaseService { - public partial class DatabaseService { - - public async Task GetAccount( string UserNameOrEmail ) { - Account? account = null; - using( MySqlConnection connection = GetConnection() ) { - connection.Open(); - string command = @" - SELECT * - FROM Account - WHERE UserName = @UorE OR Email = @UorE; - "; - - MySqlCommand cmd = new MySqlCommand(command, connection); - cmd.Parameters.AddWithValue("@UorE", UserNameOrEmail); - - using( DbDataReader reader = await cmd.ExecuteReaderAsync() ) { - while( await reader.ReadAsync() ) { - if( reader == null ) { break; } - int _id = reader.GetInt32("ID"); - string _username = reader.GetString("UserName"); - string _email = reader.GetString("Email"); - bool _emailVerified = reader.GetBoolean("EmailVerified"); - string _passwordhash = reader.GetString("PasswordHash"); - bool _failedpasswordlock = reader.GetBoolean( "FailedPasswordLock" ); - int _passwordattempts = reader.GetInt32( "PasswordAttempts" ); - int _curpasswordattempts = reader.GetInt32( "CurrentPasswordAttempts" ); - string _role = reader.GetString( "Role" ); - string _emailtoken = reader.GetString( "EmailToken" ); - string _dataserver = reader.GetString( "DataServer" ); - - account = new Account() { - ID = _id, - UserName = _username, - Email = _email, - EmailVerified = _emailVerified, - PasswordHash = _passwordhash, - CurrentPasswordAttempts = _curpasswordattempts, - PasswordAttempts = _passwordattempts, - EmailToken = _emailtoken, - FailedPasswordLock = _failedpasswordlock, - Role = _role, - DataServer = _dataserver - }; - } - } - } - return account; - } - - public async Task GetAccount( int AccountID ) { - Account? account = null; - using( MySqlConnection connection = GetConnection() ) { - connection.Open(); - string command = @" - SELECT * - FROM Account - WHERE ID = @ID; - "; - - MySqlCommand cmd = new MySqlCommand(command, connection); - cmd.Parameters.AddWithValue("@ID", AccountID); - - using( DbDataReader reader = await cmd.ExecuteReaderAsync() ) { - while( await reader.ReadAsync() ) { - if( reader == null ) { - break; - } - int _id = reader.GetInt32("ID"); - string _username = reader.GetString("UserName"); - string _email = reader.GetString("Email"); - bool _emailVerified = reader.GetBoolean("EmailVerified"); - string _passwordhash = reader.GetString("PasswordHash"); - bool _failedpasswordlock = reader.GetBoolean( "FailedPasswordLock" ); - int _passwordattempts = reader.GetInt32( "PasswordAttempts" ); - int _curpasswordattempts = reader.GetInt32( "CurrentPasswordAttempts" ); - string _role = reader.GetString( "Role" ); - string _emailtoken = reader.GetString( "EmailToken" ); - string _dataserver = reader.GetString("DataServer"); - - account = new Account() { - ID = _id, - UserName = _username, - Email = _email, - EmailVerified = _emailVerified, - PasswordHash = _passwordhash, - CurrentPasswordAttempts = _passwordattempts, - PasswordAttempts = _passwordattempts, - EmailToken = _emailtoken, - FailedPasswordLock = _failedpasswordlock, - Role = _role, - DataServer = _dataserver - }; - } - } - } - return account; - } - - public async Task SetAccount( Account Profile ) { - using( MySqlConnection connection = GetConnection() ) { - connection.Open(); - - string command = @" - INSERT INTO Account - (ID,UserName,Email,EmailVerified,PasswordHash,FailedPasswordLock,PasswordAttempts,CurrentPasswordAttempts,Role,EmailToken,DataServer) - VALUES - (@ID,@UserName,@Email,@EmailVerified,@PasswordHash,@FailedPasswordLock,@PasswordAttempts,@CurrentPasswordAttempts,@Role,@EmailToken,@DataServer) - ON DUPLICATE KEY UPDATE - UserName = @UserName, - Email = @Email, - EmailVerified = @EmailVerified, - PasswordHash = @PasswordHash, - FailedPasswordLock = @FailedPasswordLock, - PasswordAttempts = @PasswordAttempts, - CurrentPasswordAttempts = @CurrentPasswordAttempts, - Role = @Role, - EmailToken = @EmailToken, - DataServer = @DataServer; - "; - - MySqlCommand cmd = new MySqlCommand( command , connection); - cmd.Parameters.AddWithValue("@ID", Profile.ID); - cmd.Parameters.AddWithValue("@UserName", Profile.UserName); - cmd.Parameters.AddWithValue("@Email", Profile.Email); - cmd.Parameters.AddWithValue("@EmailVerified", Profile.EmailVerified); - cmd.Parameters.AddWithValue("@PasswordHash", Profile.PasswordHash); - cmd.Parameters.AddWithValue("@FailedPasswordLock", Profile.FailedPasswordLock); - cmd.Parameters.AddWithValue("@PasswordAttempts", Profile.PasswordAttempts); - cmd.Parameters.AddWithValue("@CurrentPasswordAttempts", Profile.CurrentPasswordAttempts); - cmd.Parameters.AddWithValue("@Role", Profile.Role); - cmd.Parameters.AddWithValue("@EmailToken", Profile.EmailToken); - cmd.Parameters.AddWithValue("@DataServer", Profile.DataServer); - - await cmd.ExecuteNonQueryAsync(); - } - } - - public async Task DeleteAccount( int AccountID ) { - using( MySqlConnection connection = GetConnection() ) { - MySqlCommand cmd; - connection.Open(); - - string command = @" - DELETE FROM Account WHERE ID = @ID; - "; - cmd = new MySqlCommand( command, connection ); - cmd.Parameters.AddWithValue("@ID", AccountID); - - await cmd.ExecuteNonQueryAsync(); - } - } - - } -} diff --git a/src/Server/Services/DatabaseService/JobListing.cs b/src/Server/Services/DatabaseService/JobListing.cs index 1b99c8b..434fde9 100644 --- a/src/Server/Services/DatabaseService/JobListing.cs +++ b/src/Server/Services/DatabaseService/JobListing.cs @@ -64,6 +64,61 @@ namespace BoredCareers.Services.DatabaseService { return joblistings.ToArray(); } + public async Task GetJobListingFromCompany(int CompanyID) { + List joblistings = new List(); ; + using (MySqlConnection connection = GetConnection()) { + connection.Open(); + string command = @" + SELECT * + FROM JobListing + WHERE CompanyID = @CompanyID; + "; + + MySqlCommand cmd = new MySqlCommand(command, connection); + cmd.Parameters.AddWithValue("@CompanyID", CompanyID); + + using (DbDataReader reader = await cmd.ExecuteReaderAsync()) { + while (await reader.ReadAsync()) { + if (reader == null) { break; } + int _id = reader.GetInt32("ID"); + int _companyid = reader.GetInt32("CompanyID"); + string _title = reader.GetString("Title"); + string _postalcode = reader.GetString("PostalCode"); + string _country = reader.GetString("Country"); + string _state = reader.GetString("StateOrRegion"); + string _city = reader.GetString("City"); + int _salarymin = reader.GetInt32("SalaryMin"); + int _salarymax = reader.GetInt32("SalaryMax"); + string _jobtype = reader.GetString("JobType"); + bool _remote = reader.GetBoolean("Remote"); + string _description = reader.GetString("Description"); + DateTime _createtime = reader.GetDateTime("CreatedTime"); + DateTime _modifiedtime = reader.GetDateTime("ModifiedTime"); + bool _isdeleted = reader.GetBoolean("IsDeleted"); + + joblistings.Add(new JobListing() { + ID = _id, + CompanyID = _companyid, + Title = _title, + PostalCode = _postalcode, + Country = _country, + StateOrRegion = _state, + City = _city, + SalaryMin = _salarymin, + SalaryMax = _salarymax, + JobType = _jobtype, + Remote = _remote, + Description = _description, + CreatedTime = _createtime, + ModifiedTime = _modifiedtime, + IsDeleted = _isdeleted + }); + } + } + } + return joblistings.ToArray(); + } + public async Task GetJobListing(int JobListingID) { JobListing? joblisting = null; using (MySqlConnection connection = GetConnection()) {