Merge pull request 'working' (#8) from working into main
Docker Build and Release Upload / build (push) Successful in 1m21s
Docker Build and Release Upload / build (push) Successful in 1m21s
Reviewed-on: #8
This commit was merged in pull request #8.
This commit is contained in:
Vendored
+1
@@ -22,6 +22,7 @@
|
|||||||
},
|
},
|
||||||
"args": [
|
"args": [
|
||||||
"build",
|
"build",
|
||||||
|
"--configuration=development",
|
||||||
"--base-href=http://localhost:5000"
|
"--base-href=http://localhost:5000"
|
||||||
],
|
],
|
||||||
"problemMatcher": "$msCompile"
|
"problemMatcher": "$msCompile"
|
||||||
|
|||||||
@@ -36,3 +36,9 @@ Task:
|
|||||||
Point all requests after auth to the correct regional server. -> Currently only Mistox-West exists
|
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
|
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
|
||||||
@@ -1,25 +1,6 @@
|
|||||||
CREATE DATABASE IF NOT EXISTS `boredcareers`;
|
CREATE DATABASE IF NOT EXISTS `boredcareers`;
|
||||||
USE `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
|
-- Resume Section
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `Resume` (
|
CREATE TABLE IF NOT EXISTS `Resume` (
|
||||||
|
|||||||
@@ -1,19 +1,24 @@
|
|||||||
<div class="top-bar">
|
<div class="top-bar">
|
||||||
<div class="top-bar-buttons">
|
<div class="top-bar-buttons">
|
||||||
<a #homeLink class="nav-button" routerLink="">HOME</a>
|
|
||||||
<a #jobsLink class="nav-button" routerLink="/jobs">JOB BOARD</a>
|
<a #jobsLink class="nav-button" routerLink="/jobs">JOB BOARD</a>
|
||||||
<a #resumesLink class="nav-button" routerLink="/resumes">RESUMES</a>
|
<a #resumesLink class="nav-button" routerLink="/resumes">RESUMES</a>
|
||||||
|
<a #companiesLink class="nav-button" routerLink="/company">COMPANIES</a>
|
||||||
</div>
|
</div>
|
||||||
<a class="top-bar-logo" routerLink="">
|
<a class="top-bar-logo" routerLink="">
|
||||||
<img class="top-bar-logo" style="margin: 0;" src="img/logo-full.png" />
|
<img class="top-bar-logo" style="margin: 0;" src="img/logo-full.png" />
|
||||||
</a>
|
</a>
|
||||||
<div *ngIf="auth.isLoggedIn" class="top-bar-buttons flex-right">
|
<div *ngIf="auth.isLoggedIn" class="top-bar-buttons flex-right">
|
||||||
<a class="nav-button nav-button-login" routerLink="/account/settings"><span>{{ auth.loggedInUser.userName.toUpperCase() }}</span></a>
|
<a class="nav-button nav-button-login" href="https://auth.mistox.com/"><span>{{ auth.loggedInUser.userName.toUpperCase() }}</span></a>
|
||||||
<a class="nav-button nav-button-login" href="/api/account/logout"><span>LOGOUT</span></a>
|
<a class="nav-button nav-button-login" href="/api/account/logout"><span>LOGOUT</span></a>
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="!auth.isLoggedIn" class="top-bar-buttons flex-right">
|
<div *ngIf="!auth.isLoggedIn" class="top-bar-buttons flex-right">
|
||||||
|
|
||||||
|
<!-- Testing Login -->
|
||||||
|
<a *ngIf="devMode" class="nav-button nav-button-login" href="https://auth.mistox.com/account/login?returnURL=http://localhost:5000/"><span>Testing Login</span></a>
|
||||||
|
<!-- Testing Login -->
|
||||||
|
|
||||||
<a class="nav-button nav-button-login" href="https://auth.mistox.com/account/login?returnURL=https://boredcareers.com/"><span>LOGIN</span></a>
|
<a class="nav-button nav-button-login" href="https://auth.mistox.com/account/login?returnURL=https://boredcareers.com/"><span>LOGIN</span></a>
|
||||||
<a class="nav-button nav-button-login" routerLink="/account/register"><span>REGISTER</span></a>
|
<a class="nav-button nav-button-login" href="https://auth.mistox.com/account/register?returnURL=https://boredcareers.com/"><span>REGISTER</span></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
|||||||
@@ -5,23 +5,29 @@ import { ContactComponent } from './pages/legal/contact/contact.component';
|
|||||||
import { PrivacyComponent } from './pages/legal/privacy/privacy.component';
|
import { PrivacyComponent } from './pages/legal/privacy/privacy.component';
|
||||||
import { JobsComponent } from './pages/main/jobs/jobs.component';
|
import { JobsComponent } from './pages/main/jobs/jobs.component';
|
||||||
import { ResumesComponent } from './pages/main/resumes/resumes.component';
|
import { ResumesComponent } from './pages/main/resumes/resumes.component';
|
||||||
import { JobNewComponent } from './pages/main/jobs/new/jobnew.component';
|
import { JobEditorComponent } from './pages/main/jobs/editor/jobeditor.component';
|
||||||
import { JobEditComponent } from './pages/main/jobs/edit/jobedit.component';
|
|
||||||
import { CompanyConnectComponent } from './pages/main/company/connect/companyconnect.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 = [
|
export const routes: Routes = [
|
||||||
|
|
||||||
// Home
|
// Home
|
||||||
{ path: "", component: HomeComponent },
|
{ path: "", component: HomeComponent },
|
||||||
|
|
||||||
|
// Resumes
|
||||||
{ path: "resumes", component: ResumesComponent },
|
{ path: "resumes", component: ResumesComponent },
|
||||||
|
|
||||||
// Jobs
|
// Jobs
|
||||||
{ path: "jobs", component: JobsComponent },
|
{ path: "jobs", component: JobsComponent },
|
||||||
{ path: "jobs/new", component: JobNewComponent },
|
{ path: "jobs/editor", component: JobEditorComponent },
|
||||||
{ path: "jobs/edit", component: JobEditComponent },
|
{ path: "jobs/viewer", component: JobViewerComponent },
|
||||||
|
|
||||||
// Company
|
// Company
|
||||||
|
{ path: "company", component: CompanyComponent },
|
||||||
{ path: "company/connect", component: CompanyConnectComponent },
|
{ path: "company/connect", component: CompanyConnectComponent },
|
||||||
|
{ path: "company/jobs", component: CompanyJobsComponent },
|
||||||
|
|
||||||
// Legal
|
// Legal
|
||||||
{ path: "about", component: AboutComponent },
|
{ path: "about", component: AboutComponent },
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { Router, RouterModule, RouterOutlet, ActivatedRoute } from '@angular/rou
|
|||||||
import { Authentication } from './services/Authentication';
|
import { Authentication } from './services/Authentication';
|
||||||
import { CommonModule, Location } from '@angular/common';
|
import { CommonModule, Location } from '@angular/common';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
|
import { isDevMode } from '@angular/core';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
@@ -12,11 +13,16 @@ import { HttpClient } from '@angular/common/http';
|
|||||||
})
|
})
|
||||||
export class App {
|
export class App {
|
||||||
|
|
||||||
@ViewChild('homeLink') homeLink!: ElementRef<HTMLAnchorElement>;
|
@ViewChild('companiesLink') companiesLink!: ElementRef<HTMLAnchorElement>;
|
||||||
@ViewChild('jobsLink') jobLink!: ElementRef<HTMLAnchorElement>;
|
@ViewChild('jobsLink') jobLink!: ElementRef<HTMLAnchorElement>;
|
||||||
@ViewChild('resumesLink') resumeLink!: ElementRef<HTMLAnchorElement>;
|
@ViewChild('resumesLink') resumeLink!: ElementRef<HTMLAnchorElement>;
|
||||||
|
|
||||||
|
devMode: boolean = false;
|
||||||
|
|
||||||
constructor( private http: HttpClient, public auth: Authentication, private router: Router, private route: ActivatedRoute, private location: Location){
|
constructor( private http: HttpClient, public auth: Authentication, private router: Router, private route: ActivatedRoute, private location: Location){
|
||||||
|
|
||||||
|
this.devMode = isDevMode();
|
||||||
|
|
||||||
this.route.queryParams.subscribe(params => {
|
this.route.queryParams.subscribe(params => {
|
||||||
|
|
||||||
const loginToken = params['LoginToken'];
|
const loginToken = params['LoginToken'];
|
||||||
@@ -43,7 +49,7 @@ export class App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngAfterViewInit(){
|
ngAfterViewInit(){
|
||||||
let ViewLinks = [ this.homeLink, this.resumeLink, this.jobLink ];
|
let ViewLinks = [ this.companiesLink, this.resumeLink, this.jobLink ];
|
||||||
ViewLinks.forEach(link => {
|
ViewLinks.forEach(link => {
|
||||||
if (new URL(link.nativeElement.href).pathname === new URL(window.location.href).pathname){
|
if (new URL(link.nativeElement.href).pathname === new URL(window.location.href).pathname){
|
||||||
link.nativeElement.classList.add("active");
|
link.nativeElement.classList.add("active");
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export class Company {
|
export class Company {
|
||||||
public id: number = 0;
|
public id: number = -1;
|
||||||
public name: string = "";
|
public name: string = "";
|
||||||
public email: string = "";
|
public email: string = "";
|
||||||
public emailVerified: boolean = false;
|
public emailVerified: boolean = false;
|
||||||
@@ -14,7 +14,7 @@ export class Company {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class Employee {
|
export class Employee {
|
||||||
public id: number = 0;
|
public id: number = -1;
|
||||||
public accountID: number = 0;
|
public accountID: number = 0;
|
||||||
public company: Company = new Company;
|
public company: Company = new Company;
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
export class JobListing {
|
export class JobListing {
|
||||||
public id: number = 0;
|
public id: number = -1;
|
||||||
public companyID: number = 0;
|
public companyID: number = 0;
|
||||||
public title: string = "";
|
public title: string = "";
|
||||||
public postalCode: string = "";
|
public postalCode: string = "";
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export class Resume {
|
export class Resume {
|
||||||
public id: number = 0;
|
public id: number = -1;
|
||||||
public accountID: number = 0;
|
public accountID: number = 0;
|
||||||
public name: string = "";
|
public name: string = "";
|
||||||
public field: string = "";
|
public field: string = "";
|
||||||
@@ -20,7 +20,7 @@ export class Resume {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class ResumeExperience {
|
export class ResumeExperience {
|
||||||
id: number = 0;
|
id: number = -1;
|
||||||
resumeID: number = 0;
|
resumeID: number = 0;
|
||||||
jobTitle: string = "";
|
jobTitle: string = "";
|
||||||
company: string = "";
|
company: string = "";
|
||||||
@@ -35,14 +35,14 @@ export class ResumeExperience {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class ResumeExperienceBullet {
|
export class ResumeExperienceBullet {
|
||||||
id: number = 0;
|
id: number = -1;
|
||||||
resumeID: number = 0;
|
resumeID: number = 0;
|
||||||
resumeExperienceID: number = 0;
|
resumeExperienceID: number = 0;
|
||||||
jobFunction: string = "";
|
jobFunction: string = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ResumeMilitary {
|
export class ResumeMilitary {
|
||||||
id: number = 0;
|
id: number = -1;
|
||||||
resumeID: number = 0;
|
resumeID: number = 0;
|
||||||
country: string = "";
|
country: string = "";
|
||||||
rank: string = "";
|
rank: string = "";
|
||||||
@@ -53,7 +53,7 @@ export class ResumeMilitary {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class ResumeMilitaryBullet {
|
export class ResumeMilitaryBullet {
|
||||||
id: number = 0;
|
id: number = -1;
|
||||||
resumeID: number = 0;
|
resumeID: number = 0;
|
||||||
resumeMilitaryID: number = 0;
|
resumeMilitaryID: number = 0;
|
||||||
achievement: string = "";
|
achievement: string = "";
|
||||||
@@ -61,7 +61,7 @@ export class ResumeMilitaryBullet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class ResumeEducation {
|
export class ResumeEducation {
|
||||||
id: number = 0;
|
id: number = -1;
|
||||||
resumeID: number = 0;
|
resumeID: number = 0;
|
||||||
degreeType: string = "";
|
degreeType: string = "";
|
||||||
degreeField: string = "";
|
degreeField: string = "";
|
||||||
@@ -76,21 +76,21 @@ export class ResumeEducation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class ResumeSkill {
|
export class ResumeSkill {
|
||||||
id: number = 0; // PK
|
id: number = -1;
|
||||||
resumeID: number = 0; // FK
|
resumeID: number = 0;
|
||||||
name: string = "";
|
name: string = "";
|
||||||
description: string = "";
|
description: string = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ResumeLanguage {
|
export class ResumeLanguage {
|
||||||
id: number = 0;
|
id: number = -1;
|
||||||
resumeID: number = 0;
|
resumeID: number = 0;
|
||||||
language: string = "";
|
language: string = "";
|
||||||
proficiency: string = "";
|
proficiency: string = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ResumeCertification {
|
export class ResumeCertification {
|
||||||
id: number = 0;
|
id: number = -1;
|
||||||
resumeID: number = 0;
|
resumeID: number = 0;
|
||||||
name: string = "";
|
name: string = "";
|
||||||
verificationURL: string = "";
|
verificationURL: string = "";
|
||||||
@@ -98,7 +98,7 @@ export class ResumeCertification {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class ResumeProject {
|
export class ResumeProject {
|
||||||
id: number = 0;
|
id: number = -1;
|
||||||
resumeID: number = 0;
|
resumeID: number = 0;
|
||||||
name: string = "";
|
name: string = "";
|
||||||
url: string = "";
|
url: string = "";
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<div class="top-bar">
|
||||||
|
<button *ngFor="let company of Employers" (click)="changeSelectedCompany(company.company.id)">{{ company.company.name.toUpperCase() }}</button>
|
||||||
|
<button routerLink="/company/connect" >CONNECT A COMPANY</button>
|
||||||
|
</div>
|
||||||
|
<div class="content-frame">
|
||||||
|
<div *ngIf="Comp != null">
|
||||||
|
<h1>{{ Comp.name }}</h1>
|
||||||
|
<h1>{{ Comp.email }}</h1>
|
||||||
|
<h1>{{ Comp.emailVerified }}</h1>
|
||||||
|
<h1>{{ Comp.websiteURL }}</h1>
|
||||||
|
<h1>{{ Comp.logoURL }}</h1>
|
||||||
|
<h1>{{ Comp.phone }}</h1>
|
||||||
|
<h1>{{ Comp.postalCode }}</h1>
|
||||||
|
<h1>{{ Comp.country }}</h1>
|
||||||
|
<h1>{{ Comp.stateOrRegion }}</h1>
|
||||||
|
<h1>{{ Comp.city }}</h1>
|
||||||
|
<h1>{{ Comp.description }}</h1>
|
||||||
|
<button routerLink="/company/jobs" [queryParams]="{ CompanyID: Comp.id }" >ACTIVE JOB LISTINGS</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -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<Employee[]>("api/employee/").subscribe({
|
||||||
|
next: data => {
|
||||||
|
this.Employers = data;
|
||||||
|
},
|
||||||
|
error: err => {
|
||||||
|
this.ErrorMsg = err.error;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
changeSelectedCompany(companyID: number){
|
||||||
|
this.http.get<Company>("api/company?CompanyID=" + companyID).subscribe({
|
||||||
|
next: data => {
|
||||||
|
this.Comp = data;
|
||||||
|
},
|
||||||
|
error: err => {
|
||||||
|
this.ErrorMsg = err.error;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<div class="post-job-frame">
|
||||||
|
<button [routerLink]="['/jobs/editor']">POST JOB</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div *ngIf="auth.isLoggedIn" class="jobs-frame">
|
||||||
|
<div class="posted-jobs-frame" *ngFor="let cur of MyJobListings">
|
||||||
|
<div class="tile">
|
||||||
|
<h1>{{ cur.title }}</h1>
|
||||||
|
<h1>{{ cur.jobType }}</h1>
|
||||||
|
<h1>Is Remote: {{ cur.remote }}</h1>
|
||||||
|
<h1>{{ cur.salaryMin }}</h1>
|
||||||
|
<h1>{{ cur.salaryMax }}</h1>
|
||||||
|
<h1>{{ cur.city }}</h1>
|
||||||
|
<h1>{{ cur.stateOrRegion }}</h1>
|
||||||
|
<h1>{{ cur.country }}</h1>
|
||||||
|
<h1>{{ cur.postalCode }}</h1>
|
||||||
|
<h1>Posted: {{ cur.createdTime }}</h1>
|
||||||
|
<h1>Modified: {{ cur.modifiedTime }}</h1>
|
||||||
|
</div>
|
||||||
|
<button [routerLink]="['/jobs/editor']" [queryParams]="{ JobID: cur.id }" >EDIT</button>
|
||||||
|
<button (click)="RemoveJobListing(cur.id)">DELETE</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
+14
-15
@@ -8,35 +8,34 @@ import { JobListing } from 'app/models/JobListing';
|
|||||||
import { Authentication } from 'app/services/Authentication';
|
import { Authentication } from 'app/services/Authentication';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'main-jobs-edit',
|
selector: 'main-company-jobs',
|
||||||
templateUrl: './jobedit.component.html',
|
templateUrl: './jobs.component.html',
|
||||||
styleUrls: [ './jobedit.component.css' ],
|
styleUrls: [ './jobs.component.css' ],
|
||||||
imports: [ FormsModule, CommonModule, RouterModule ]
|
imports: [ FormsModule, CommonModule, RouterModule ]
|
||||||
})
|
})
|
||||||
export class JobEditComponent {
|
export class CompanyJobsComponent {
|
||||||
|
|
||||||
public MyJobListings: JobListing[] = [];
|
public MyJobListings: JobListing[] = [];
|
||||||
public JobListingPage: JobListing[] = [];
|
|
||||||
public ErrorMsg: string = "";
|
public ErrorMsg: string = "";
|
||||||
|
|
||||||
public Page: number = 1;
|
|
||||||
|
|
||||||
constructor( private http: HttpClient, private router: Router, private route: ActivatedRoute, private title: Title, public auth: Authentication ) {
|
constructor( private http: HttpClient, private router: Router, private route: ActivatedRoute, private title: Title, public auth: Authentication ) {
|
||||||
this.title.setTitle("Jobs - edit | BoredCareers");
|
this.title.setTitle("Company - Jobs | BoredCareers");
|
||||||
|
|
||||||
if (this.Page == 1){
|
this.route.queryParams.subscribe(params => {
|
||||||
|
const companyID = params['CompanyID'];
|
||||||
}
|
if (companyID){
|
||||||
|
http.get<JobListing[]>("api/joblisting/company?CompanyID=" + companyID).subscribe({
|
||||||
http.get<JobListing[]>("api/joblisting?PageQuantity=" + 10 + "&Page=" + 1).subscribe({
|
|
||||||
next: data => {
|
next: data => {
|
||||||
this.JobListingPage = data;
|
this.MyJobListings = data;
|
||||||
},
|
},
|
||||||
error: err => {
|
error: err => {
|
||||||
this.ErrorMsg = err.error;
|
this.ErrorMsg = err.error;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}else{
|
||||||
|
router.navigate(["/company"]);
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
RemoveJobListing( JobListingID: number ){
|
RemoveJobListing( JobListingID: number ){
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
<div class="tile-frame" *ngFor="let cur of JobListingPage">
|
|
||||||
<div class="tile">
|
|
||||||
<h1>{{ cur.title }}</h1>
|
|
||||||
<h1>{{ cur.jobType }}</h1>
|
|
||||||
<h1>Is Remote: {{ cur.remote }}</h1>
|
|
||||||
<h1>{{ cur.salaryMin }}</h1>
|
|
||||||
<h1>{{ cur.salaryMax }}</h1>
|
|
||||||
<h1>{{ cur.city }}</h1>
|
|
||||||
<h1>{{ cur.stateOrRegion }}</h1>
|
|
||||||
<h1>{{ cur.country }}</h1>
|
|
||||||
<h1>{{ cur.postalCode }}</h1>
|
|
||||||
<h1>{{ cur.description }}</h1>
|
|
||||||
<h1>Posted: {{ cur.createdTime }}</h1>
|
|
||||||
<h1>Modified: {{ cur.modifiedTime }}</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
+5
-5
@@ -9,12 +9,12 @@ import { Authentication } from 'app/services/Authentication';
|
|||||||
import { Company, Employee } from 'app/models/Company';
|
import { Company, Employee } from 'app/models/Company';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'main-jobs-new',
|
selector: 'main-jobs-editor',
|
||||||
templateUrl: './jobnew.component.html',
|
templateUrl: './jobeditor.component.html',
|
||||||
styleUrls: [ './jobnew.component.css' ],
|
styleUrls: [ './jobeditor.component.css' ],
|
||||||
imports: [ FormsModule, CommonModule, RouterModule ]
|
imports: [ FormsModule, CommonModule, RouterModule ]
|
||||||
})
|
})
|
||||||
export class JobNewComponent {
|
export class JobEditorComponent {
|
||||||
|
|
||||||
@ViewChildren('step') formSteps!: QueryList<ElementRef<HTMLDivElement>>;
|
@ViewChildren('step') formSteps!: QueryList<ElementRef<HTMLDivElement>>;
|
||||||
currentStep: number = 0;
|
currentStep: number = 0;
|
||||||
@@ -26,7 +26,7 @@ export class JobNewComponent {
|
|||||||
public ErrorMsg: string = "";
|
public ErrorMsg: string = "";
|
||||||
|
|
||||||
constructor( private http: HttpClient, private router: Router, private route: ActivatedRoute, private title: Title, public auth: Authentication ) {
|
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<Employee[]>("api/employee").subscribe({
|
this.http.get<Employee[]>("api/employee").subscribe({
|
||||||
next: empOf => {
|
next: empOf => {
|
||||||
@@ -1,27 +1,3 @@
|
|||||||
<!-- My Jobs -->
|
|
||||||
<div *ngIf="auth.isLoggedIn" class="jobs-frame">
|
|
||||||
<div class="posted-jobs-frame" *ngFor="let cur of MyJobListings">
|
|
||||||
<div class="tile">
|
|
||||||
<h1>{{ cur.title }}</h1>
|
|
||||||
<h1>{{ cur.jobType }}</h1>
|
|
||||||
<h1>Is Remote: {{ cur.remote }}</h1>
|
|
||||||
<h1>{{ cur.salaryMin }}</h1>
|
|
||||||
<h1>{{ cur.salaryMax }}</h1>
|
|
||||||
<h1>{{ cur.city }}</h1>
|
|
||||||
<h1>{{ cur.stateOrRegion }}</h1>
|
|
||||||
<h1>{{ cur.country }}</h1>
|
|
||||||
<h1>{{ cur.postalCode }}</h1>
|
|
||||||
<h1>Posted: {{ cur.createdTime }}</h1>
|
|
||||||
<h1>Modified: {{ cur.modifiedTime }}</h1>
|
|
||||||
</div>
|
|
||||||
<button [routerLink]="['/jobs/edit']" [queryParams]="{ JobID: cur.id }" >EDIT</button>
|
|
||||||
<button (click)="RemoveJobListing(cur.id)">DELETE</button>
|
|
||||||
</div>
|
|
||||||
<div class="post-job-frame">
|
|
||||||
<button [routerLink]="['/jobs/new']">POST JOB</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Avaliable Jobs -->
|
<!-- Avaliable Jobs -->
|
||||||
<div class="tile-frame" *ngFor="let cur of JobListingPage">
|
<div class="tile-frame" *ngFor="let cur of JobListingPage">
|
||||||
<div class="tile">
|
<div class="tile">
|
||||||
@@ -38,7 +14,7 @@
|
|||||||
<h1>{{ cur.stateOrRegion }}</h1>
|
<h1>{{ cur.stateOrRegion }}</h1>
|
||||||
</div>
|
</div>
|
||||||
<div class="tile-button">
|
<div class="tile-button">
|
||||||
<button [routerLink]="['/jobs/new']">VIEW LISTING</button>
|
<button [routerLink]="['/jobs/viewer']" [queryParams]="{ JobID: cur.id }" >VIEW LISTING</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
.job-frame {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.job-warning {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.job-details {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
<div class="job-frame">
|
||||||
|
<div class="company-details" *ngIf="jobsCompany != null" >
|
||||||
|
<h1>{{ jobsCompany.name }}</h1>
|
||||||
|
|
||||||
|
<h1>{{ jobsCompany.email }}</h1>
|
||||||
|
<h1>{{ jobsCompany.websiteURL }}</h1>
|
||||||
|
|
||||||
|
<h1>{{ jobsCompany.logoURL }}</h1>
|
||||||
|
<h1>{{ jobsCompany.phone }}</h1>
|
||||||
|
|
||||||
|
<h1>{{ jobsCompany.city }}</h1>
|
||||||
|
<h1>{{ jobsCompany.stateOrRegion }}</h1>
|
||||||
|
<h1>{{ jobsCompany.country }}</h1>
|
||||||
|
<h1>{{ jobsCompany.postalCode }}</h1>
|
||||||
|
|
||||||
|
<h1>{{ jobsCompany.description }}</h1>
|
||||||
|
</div>
|
||||||
|
<div class="job-details" *ngIf="selectedJob != null" >
|
||||||
|
|
||||||
|
<div class="job-warning" *ngIf="selectedJob.isDeleted" >
|
||||||
|
<h2>THIS JOB POSTING IS CLOSED</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h1>{{ selectedJob.title }}</h1>
|
||||||
|
|
||||||
|
<h1>{{ selectedJob.jobType }}</h1>
|
||||||
|
<h1>{{ selectedJob.remote }}</h1>
|
||||||
|
|
||||||
|
<h1>{{ selectedJob.salaryMin }}</h1>
|
||||||
|
<h1>{{ selectedJob.salaryMax }}</h1>
|
||||||
|
|
||||||
|
<h1>{{ selectedJob.city }}</h1>
|
||||||
|
<h1>{{ selectedJob.stateOrRegion }}</h1>
|
||||||
|
<h1>{{ selectedJob.country }}</h1>
|
||||||
|
<h1>{{ selectedJob.postalCode }}</h1>
|
||||||
|
|
||||||
|
<h1>{{ selectedJob.description }}</h1>
|
||||||
|
|
||||||
|
<h1>{{ selectedJob.createdTime }}</h1>
|
||||||
|
<h1>{{ selectedJob.modifiedTime }}</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -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<JobListing>( "api/joblisting/" + JobID ).subscribe({
|
||||||
|
next: data => {
|
||||||
|
this.selectedJob = data;
|
||||||
|
this.http.get<Company>("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){
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,13 +1,4 @@
|
|||||||
<div class="tile-frame" *ngFor="let cur of ResumePage">
|
<!-- My Resumes -->
|
||||||
<div class="tile">
|
<div *ngIf="auth.isLoggedIn" class="jobs-frame">
|
||||||
<h1>{{ cur.name }}</h1>
|
|
||||||
<h1>{{ cur.field }}</h1>
|
|
||||||
<h1>{{ cur.email }}</h1>
|
|
||||||
<h1>{{ cur.phoneNumber }}</h1>
|
|
||||||
<h1>{{ cur.city }}</h1>
|
|
||||||
<h1>{{ cur.stateOrRegion }}</h1>
|
|
||||||
<h1>{{ cur.country }}</h1>
|
|
||||||
<h1>{{ cur.postalCode }}</h1>
|
|
||||||
<h1>Active: {{ cur.isActive }}</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
@@ -1,24 +1,33 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { FormsModule } from '@angular/forms';
|
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 { Title } from '@angular/platform-browser';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { Resume } from 'app/models/Resume';
|
import { Resume } from 'app/models/Resume';
|
||||||
|
import { Authentication } from 'app/services/Authentication';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'main-resumes',
|
selector: 'main-resumes',
|
||||||
templateUrl: './resumes.component.html',
|
templateUrl: './resumes.component.html',
|
||||||
styleUrls: [ './resumes.component.css' ],
|
styleUrls: [ './resumes.component.css' ],
|
||||||
imports: [ FormsModule, CommonModule ]
|
imports: [ FormsModule, CommonModule, RouterModule ]
|
||||||
})
|
})
|
||||||
export class ResumesComponent {
|
export class ResumesComponent {
|
||||||
|
|
||||||
public ResumePage: Resume[] = [];
|
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.title.setTitle("Resumes | BoredCareers");
|
||||||
|
|
||||||
|
this.http.get<Resume[]>("api/resume").subscribe({
|
||||||
|
next: data => {
|
||||||
|
this.ResumePage = data;
|
||||||
|
},
|
||||||
|
error: err => {
|
||||||
|
console.log("Error fetching resumes: " + err.error);
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -19,6 +19,18 @@ namespace BoredCareers.Controllers {
|
|||||||
return NotFound("Job listing not found");
|
return NotFound("Job listing not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet("company")]
|
||||||
|
public async Task<IActionResult> 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]
|
[HttpGet]
|
||||||
public async Task<IActionResult> GetJobListings(int Page = 1, int PageQuantity = 25) {
|
public async Task<IActionResult> GetJobListings(int Page = 1, int PageQuantity = 25) {
|
||||||
JobListing[] jobListings = await _databaseService.GetJobListingPage(Page, PageQuantity);
|
JobListing[] jobListings = await _databaseService.GetJobListingPage(Page, PageQuantity);
|
||||||
|
|||||||
@@ -3,13 +3,7 @@ namespace BoredCareers.Entities {
|
|||||||
public int ID { get; set; } // PK
|
public int ID { get; set; } // PK
|
||||||
public string UserName { get; set; } = "";
|
public string UserName { get; set; } = "";
|
||||||
public string Email { 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 Role { get; set; } = "Generic";
|
||||||
public string EmailToken { get; set; } = "";
|
|
||||||
public string DataServer { get; set; } = "";
|
public string DataServer { get; set; } = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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<Account?> 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<Account?> 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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -64,6 +64,61 @@ namespace BoredCareers.Services.DatabaseService {
|
|||||||
return joblistings.ToArray();
|
return joblistings.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<JobListing[]> GetJobListingFromCompany(int CompanyID) {
|
||||||
|
List<JobListing> joblistings = new List<JobListing>(); ;
|
||||||
|
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<JobListing?> GetJobListing(int JobListingID) {
|
public async Task<JobListing?> GetJobListing(int JobListingID) {
|
||||||
JobListing? joblisting = null;
|
JobListing? joblisting = null;
|
||||||
using (MySqlConnection connection = GetConnection()) {
|
using (MySqlConnection connection = GetConnection()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user