Merge pull request 'UI' (#4) from UI into main
Docker Build and Release Upload / build (push) Successful in 1m26s
Docker Build and Release Upload / build (push) Successful in 1m26s
Reviewed-on: #4
This commit was merged in pull request #4.
This commit is contained in:
@@ -2,10 +2,17 @@ Server:
|
||||
Emails:
|
||||
Dont follow theme of website
|
||||
|
||||
When a company is created:
|
||||
Send email -> verify ownership of the email
|
||||
|
||||
Need to timeout email reset tokens:
|
||||
|
||||
Client:
|
||||
|
||||
jobs/new:
|
||||
When remote job is check'd it still asks for location information
|
||||
Want to add Required skills to help with filtering
|
||||
Need to fix some UI bugs.
|
||||
Want to add completed job listing preview at end of carosel
|
||||
|
||||
database:
|
||||
Add Applied Jobs Table
|
||||
+6
-6
@@ -205,14 +205,14 @@ INSERT INTO Account (
|
||||
DataServer
|
||||
) VALUES (
|
||||
1,
|
||||
`admin`,
|
||||
`admin@mistox.com`,
|
||||
'admin',
|
||||
'admin@mistox.com',
|
||||
1,
|
||||
`$2a$11$0UeWLLqTXe3FG161QVuI0OQJ9rulspUpMG581DI6KSzDXBbFKd00S`,
|
||||
'$2a$11$0UeWLLqTXe3FG161QVuI0OQJ9rulspUpMG581DI6KSzDXBbFKd00S',
|
||||
0,
|
||||
5,
|
||||
0,
|
||||
`Admin`,
|
||||
``,
|
||||
``
|
||||
'Admin',
|
||||
'',
|
||||
''
|
||||
);
|
||||
@@ -93,5 +93,8 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"cli": {
|
||||
"analytics": false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<div class="top-bar">
|
||||
<div class="top-bar-buttons">
|
||||
<a #homeLink class="nav-button" href="">HOME</a>
|
||||
<a #companiesLink class="nav-button" href="/companies">COMPANIES</a>
|
||||
<a #jobsLink class="nav-button" href="/jobs">JOB BOARD</a>
|
||||
<a #resumesLink class="nav-button" href="/resumes">RESUMES</a>
|
||||
</div>
|
||||
<a class="top-bar-logo" href="">
|
||||
<img class="top-bar-logo" style="margin: 0;" src="img/logo-full.png" />
|
||||
@@ -23,6 +23,7 @@
|
||||
<div class="bottom-bar-buttons bottom-bar-float">
|
||||
<a class="nav-button-bottom bottom-bar-padding" href="/contact">CONTACT</a>
|
||||
<a class="nav-button-bottom bottom-bar-padding" href="/privacy">PRIVACY</a>
|
||||
<a class="nav-button-bottom bottom-bar-padding" href="/about">ABOUT</a>
|
||||
</div>
|
||||
<a class="bottom-bar-logo" href="https://mistox.com">
|
||||
<img src="img/mistox-logo.png" />
|
||||
|
||||
@@ -2,19 +2,34 @@ import { Routes } from '@angular/router';
|
||||
import { ForgotPasswordComponent } from './pages/account/forgotpassword/forgotpassword.component';
|
||||
import { LoginComponent } from './pages/account/login/login.component';
|
||||
import { RegisterComponent } from './pages/account/register/register.component';
|
||||
import { MistComponent } from './pages/project/mist/mist.component';
|
||||
import { CatalogComponent } from './pages/store/catalog/catalog.component';
|
||||
import { AboutComponent } from './pages/legal/about/about.component';
|
||||
import { SettingsComponent } from './pages/account/settings/settings.component';
|
||||
import { LogoutComponent } from './pages/account/logout/logout.component';
|
||||
import { ResetPasswordComponent } from './pages/account/resetpassword/resetpassword.component';
|
||||
import { VerifyEmailComponent } from './pages/account/verifyemail/verifyemail.component';
|
||||
import { NewItemComponent } from './pages/store/admin/newitem/new.component';
|
||||
import { EditItemComponent } from './pages/store/admin/edititem/edit.component';
|
||||
import { HomeComponent } from './pages/home/home.component';
|
||||
import { HomeComponent } from './pages/main/home/home.component';
|
||||
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 { CompanyConnectComponent } from './pages/main/company/connect/companyconnect.component';
|
||||
|
||||
export const routes: Routes = [
|
||||
|
||||
// Home
|
||||
{ path: "", component: HomeComponent },
|
||||
{ path: "resumes", component: ResumesComponent },
|
||||
|
||||
// Jobs
|
||||
{ path: "jobs", component: JobsComponent },
|
||||
{ path: "jobs/new", component: JobNewComponent },
|
||||
{ path: "jobs/edit", component: JobEditComponent },
|
||||
|
||||
// Company
|
||||
{ path: "company/connect", component: CompanyConnectComponent },
|
||||
|
||||
// Account stuff
|
||||
{ path: "account/forgotpassword", component: ForgotPasswordComponent },
|
||||
{ path: "account/resetpassword", component: ResetPasswordComponent },
|
||||
@@ -24,18 +39,8 @@ export const routes: Routes = [
|
||||
{ path: "account/register", component: RegisterComponent },
|
||||
{ path: "account/settings", component: SettingsComponent },
|
||||
|
||||
{ path: "", component: HomeComponent },
|
||||
|
||||
// Projects
|
||||
{ path: "project/mist", component: MistComponent },
|
||||
|
||||
// Store
|
||||
{ path: "store/catalog", component: CatalogComponent },
|
||||
|
||||
// AdminPages
|
||||
{ path: "store/admin/new", component: NewItemComponent },
|
||||
{ path: "store/admin/edit", component: EditItemComponent },
|
||||
|
||||
// Legal
|
||||
{ path: "about", component: AboutComponent },
|
||||
{ path: "contact", component: ContactComponent },
|
||||
{ path: "privacy", component: PrivacyComponent }
|
||||
]
|
||||
@@ -12,13 +12,13 @@ import { CommonModule } from '@angular/common';
|
||||
export class App {
|
||||
|
||||
@ViewChild('homeLink') homeLink!: ElementRef<HTMLAnchorElement>;
|
||||
@ViewChild('companiesLink') companyLink!: ElementRef<HTMLAnchorElement>;
|
||||
@ViewChild('jobsLink') jobLink!: ElementRef<HTMLAnchorElement>;
|
||||
@ViewChild('resumesLink') resumeLink!: ElementRef<HTMLAnchorElement>;
|
||||
|
||||
constructor(public auth: Authentication, private router: Router){}
|
||||
|
||||
ngAfterViewInit(){
|
||||
let ViewLinks = [ this.homeLink, this.companyLink, this.jobLink ];
|
||||
let ViewLinks = [ this.homeLink, 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");
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
import { WebSiteData } from "./WebsiteData";
|
||||
|
||||
export class Account {
|
||||
public id: number = -1;
|
||||
public id: number = 0;
|
||||
public userName: string = "";
|
||||
public email: string = "";
|
||||
public emailVerified: boolean = false;
|
||||
public passwordHash: string = "";
|
||||
public siteData: WebSiteData = new WebSiteData();
|
||||
public error: string = "";
|
||||
|
||||
constructor(init?: Partial<Account>) {
|
||||
Object.assign(this, init);
|
||||
}
|
||||
public failedPasswordLock: boolean = false;
|
||||
public passwordAttempts: number = 5;
|
||||
public currentPasswordAttempts: number = 0;
|
||||
public role: string = "Generic";
|
||||
public emailToken: string = "";
|
||||
public dataServer: string = "";
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
export class Company {
|
||||
public id: number = 0;
|
||||
public name: string = "";
|
||||
public email: string = "";
|
||||
public emailVerified: boolean = false;
|
||||
public websiteURL: string = "";
|
||||
public logoURL: string = "";
|
||||
public phone: string = "";
|
||||
public postalCode: string = "";
|
||||
public country: string = ""; // 2 Letter Country Code
|
||||
public stateOrRegion: string = "";
|
||||
public city: string = "";
|
||||
public description: string = "";
|
||||
}
|
||||
|
||||
export class Employee {
|
||||
public id: number = 0;
|
||||
public accountID: number = 0;
|
||||
public companyID: number = 0;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
export class JobListing {
|
||||
public id: number = 0;
|
||||
public companyID: number = 0;
|
||||
public title: string = "";
|
||||
public postalCode: string = "";
|
||||
public country: string = "";
|
||||
public stateOrRegion: string = "";
|
||||
public city: string = "";
|
||||
public salaryMin: number = 0;
|
||||
public salaryMax: number = 0;
|
||||
public jobType: string = "";
|
||||
public remote: boolean = false;
|
||||
public description: string = "";
|
||||
public createdTime: Date = new Date();
|
||||
public modifiedTime: Date = new Date();
|
||||
public isDeleted: boolean = false;
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
export class Product {
|
||||
public id: number = -1;
|
||||
public name: string = "";
|
||||
public description: string = "";
|
||||
public curShowingIMG: number = 0;
|
||||
public images: ProductImage[] = [];
|
||||
public cost: number = 0;
|
||||
public url: string = "";
|
||||
}
|
||||
|
||||
export class ProductImage {
|
||||
imageID: number = 0;
|
||||
productID: number = 0;
|
||||
imageSrc: string = "";
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
export class Resume {
|
||||
public id: number = 0;
|
||||
public accountID: number = 0;
|
||||
public name: string = "";
|
||||
public field: string = "";
|
||||
public email: string = "";
|
||||
public phoneNumber: string = "";
|
||||
public postalCode: string = "";
|
||||
public country: string = "";
|
||||
public stateOrRegion: string = "";
|
||||
public city: string = "";
|
||||
public isActive: boolean = false;
|
||||
public experience: ResumeExperience[] = [];
|
||||
public military: ResumeMilitary = new ResumeMilitary;
|
||||
public education: ResumeEducation[] = [];
|
||||
public skills: ResumeSkill[] = [];
|
||||
public languages: ResumeLanguage[] = [];
|
||||
public certification: ResumeCertification[] = [];
|
||||
public projects: ResumeProject[] = [];
|
||||
}
|
||||
|
||||
export class ResumeExperience {
|
||||
id: number = 0;
|
||||
resumeID: number = 0;
|
||||
jobTitle: string = "";
|
||||
company: string = "";
|
||||
postalCode: string = "";
|
||||
country: string = "";
|
||||
stateOrRegion: string = "";
|
||||
city: string = "";
|
||||
dateStarted: Date = new Date();
|
||||
stillEmployed: boolean = false;
|
||||
dateEnded: Date = new Date();
|
||||
experienceBullets: ResumeExperienceBullet[] = [];
|
||||
}
|
||||
|
||||
export class ResumeExperienceBullet {
|
||||
id: number = 0;
|
||||
resumeID: number = 0;
|
||||
resumeExperienceID: number = 0;
|
||||
jobFunction: string = "";
|
||||
}
|
||||
|
||||
export class ResumeMilitary {
|
||||
id: number = 0;
|
||||
resumeID: number = 0;
|
||||
country: string = "";
|
||||
rank: string = "";
|
||||
dateStarted: Date = new Date();
|
||||
stillServing: boolean = false;
|
||||
dateEnded: Date = new Date();
|
||||
millitaryBullets: ResumeMilitaryBullet[] = [];
|
||||
}
|
||||
|
||||
export class ResumeMilitaryBullet {
|
||||
id: number = 0;
|
||||
resumeID: number = 0;
|
||||
resumeMilitaryID: number = 0;
|
||||
achievement: string = "";
|
||||
description: string = "";
|
||||
}
|
||||
|
||||
export class ResumeEducation {
|
||||
id: number = 0;
|
||||
resumeID: number = 0;
|
||||
degreeType: string = "";
|
||||
degreeField: string = "";
|
||||
school: string = "";
|
||||
postalCode: string = "";
|
||||
country: string = "";
|
||||
stateOrRegion: string = "";
|
||||
city: string = "";
|
||||
dateStarted: Date = new Date();
|
||||
stillStudying: boolean = false;
|
||||
dateEnded: Date = new Date();
|
||||
}
|
||||
|
||||
export class ResumeSkill {
|
||||
id: number = 0; // PK
|
||||
resumeID: number = 0; // FK
|
||||
name: string = "";
|
||||
description: string = "";
|
||||
}
|
||||
|
||||
export class ResumeLanguage {
|
||||
id: number = 0;
|
||||
resumeID: number = 0;
|
||||
language: string = "";
|
||||
proficiency: string = "";
|
||||
}
|
||||
|
||||
export class ResumeCertification {
|
||||
id: number = 0;
|
||||
resumeID: number = 0;
|
||||
name: string = "";
|
||||
verificationURL: string = "";
|
||||
description: string = "";
|
||||
}
|
||||
|
||||
export class ResumeProject {
|
||||
id: number = 0;
|
||||
resumeID: number = 0;
|
||||
name: string = "";
|
||||
url: string = "";
|
||||
description: string = "";
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
export class WebSiteData {
|
||||
public accountID: number = -1;
|
||||
public failedPasswordLock: boolean = false;
|
||||
public passwordAttempts: number = 5;
|
||||
public currentPasswordAttempts: number = 0;
|
||||
public role: string = "Generic";
|
||||
public emailToken: string = "";
|
||||
|
||||
constructor(init?: Partial<WebSiteData>) {
|
||||
Object.assign(this, init);
|
||||
}
|
||||
}
|
||||
@@ -43,15 +43,13 @@ export class LoginComponent {
|
||||
}
|
||||
|
||||
this.errorMsgs.push("Waiting for response from server");
|
||||
this.auth.Login(this.UserName, this.Password, this.StayLoggedIn).subscribe(
|
||||
data => {
|
||||
if (data.error.length === 0){
|
||||
this.auth.Login(this.UserName, this.Password, this.StayLoggedIn).subscribe({
|
||||
next: data => {
|
||||
this.router.navigate([this.returnURL]);
|
||||
}else{
|
||||
this.errorMsgs.pop();
|
||||
this.errorMsgs.push(data.error);
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
error: err => {
|
||||
this.errorMsgs = [ err.error ];
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,10 @@ export class LogoutComponent {
|
||||
}
|
||||
|
||||
ngAfterViewInit(){
|
||||
this.auth.Logout();
|
||||
this.auth.Logout().subscribe({
|
||||
next: data => {
|
||||
this.router.navigate(["/"]);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -68,17 +68,12 @@ export class RegisterComponent {
|
||||
});
|
||||
this.http.post<Account>( "api/account/register", body, { headers } ).subscribe({
|
||||
next: async (data) => {
|
||||
if (data.error.length === 0){
|
||||
this.errorMsgs = ["Account Created"];
|
||||
await this.sleep(3000);
|
||||
this.router.navigate([this.returnURL]);
|
||||
}else{
|
||||
this.errorMsgs = [];
|
||||
this.errorMsgs.push(data.error);
|
||||
}
|
||||
},
|
||||
error: err => {
|
||||
console.log("HTTP Error Signing In: ", err);
|
||||
this.errorMsgs = [ err.error ]
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
.center {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.frame {
|
||||
background-color: #000;
|
||||
padding: 20px;
|
||||
margin: 20px 0;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.center p {
|
||||
color: #FFF;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
<div class="center">
|
||||
<div class="big-frame background-border text-frame">
|
||||
<div class="frame">
|
||||
<p>Welcome to Mistox LLC. A project and hobby of Derek Holloway.</p>
|
||||
<br />
|
||||
<p>I am an indi-developer who has been making small projects since I was 13. I originally learned lua and spent 4 years mastering it. Then I moved onto C# which is my preferred language</p>
|
||||
@@ -15,14 +15,11 @@
|
||||
<p>After you make your account. All the data in the database is easily accessable through the account settings and</p>
|
||||
<p>you can delete your account at any time. Including all your data with it so there is no risk.</p>
|
||||
<p>I wont show ads and never will and I refuse to use trackers on this site.</p>
|
||||
<br />
|
||||
<br />
|
||||
<p>If you have any questions, concerns, or would like to suggest a feature, bug-fix, or request to help. Please feel</p>
|
||||
<p>free to reach out to me at <a href="mailto://derek@mistox.net">derek@mistox.net</a></p>
|
||||
|
||||
<div class="center">
|
||||
<a href='https://ko-fi.com/A0A3TSI2D' target='_blank'>
|
||||
<img height='36' style='border:0px;height:36px;' src='https://storage.ko-fi.com/cdn/kofi6.png?v=6' alt='Buy Me a Coffee at ko-fi.com' />
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -8,6 +8,7 @@ import { CommonModule } from '@angular/common';
|
||||
@Component({
|
||||
selector: 'legal-about',
|
||||
templateUrl: './about.component.html',
|
||||
styleUrls: [ './about.component.css' ],
|
||||
imports: [ FormsModule, CommonModule ]
|
||||
})
|
||||
export class AboutComponent {
|
||||
|
||||
+5
-4
@@ -6,14 +6,15 @@ import { Title } from '@angular/platform-browser';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'project-mist',
|
||||
templateUrl: './mist.component.html',
|
||||
selector: 'legal-contact',
|
||||
templateUrl: './contact.component.html',
|
||||
styleUrls: [ './contact.component.css' ],
|
||||
imports: [ FormsModule, CommonModule ]
|
||||
})
|
||||
export class MistComponent {
|
||||
export class ContactComponent {
|
||||
|
||||
constructor( private http: HttpClient, private router: Router, private route: ActivatedRoute, private title: Title ) {
|
||||
this.title.setTitle("Mist | Mistox");
|
||||
this.title.setTitle("Contact | BoredCareers");
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
.center {
|
||||
background-color: green;
|
||||
}
|
||||
|
||||
.tile-frame {
|
||||
column-count: 4;
|
||||
column-gap: 20px;
|
||||
padding: 20px;
|
||||
width: calc(100% - 40px);
|
||||
}
|
||||
|
||||
.tile{
|
||||
background-color: aqua;
|
||||
height: 40px;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<div class="tile-frame">
|
||||
|
||||
<div class="tile">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tile">
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,20 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { Router, ActivatedRoute } from '@angular/router';
|
||||
import { Title } from '@angular/platform-browser';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'legal-privacy',
|
||||
templateUrl: './privacy.component.html',
|
||||
styleUrls: [ './privacy.component.css' ],
|
||||
imports: [ FormsModule, CommonModule ]
|
||||
})
|
||||
export class PrivacyComponent {
|
||||
|
||||
constructor( private http: HttpClient, private router: Router, private route: ActivatedRoute, private title: Title ) {
|
||||
this.title.setTitle("Privacy | BoredCareers");
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
.title-text {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
form {
|
||||
display: grid;
|
||||
grid-template-areas: "stack";
|
||||
position: relative;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
transition: 0.5s;
|
||||
}
|
||||
|
||||
.center {
|
||||
width: 100%;
|
||||
display: grid;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.sub-frame {
|
||||
position: relative;
|
||||
grid-area: stack;
|
||||
transition: 0.5s;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.content-frame {
|
||||
background-color: #00000088;
|
||||
border-radius: 10px;
|
||||
padding: 40px;
|
||||
break-inside: avoid;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.footer-frame {
|
||||
background-color: #00000044;
|
||||
border-radius: 10px;
|
||||
padding: 10px;
|
||||
break-inside: avoid;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.split {
|
||||
column-count: 2;
|
||||
}
|
||||
|
||||
.half-frame {
|
||||
width: 400px;
|
||||
break-inside: avoid;
|
||||
}
|
||||
|
||||
.content-frame label {
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
.content-frame textarea {
|
||||
width: calc(100% - 40px);
|
||||
margin: 0 20px;
|
||||
height: 200px;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.content-frame input {
|
||||
width: calc(50% - 24px);
|
||||
margin: 0 calc(25% + 10px);
|
||||
margin-bottom: 20px;
|
||||
appearance: textfield;
|
||||
}
|
||||
|
||||
.content-frame input:focus ~ label {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.content-frame select {
|
||||
width: calc(50% - 24px);
|
||||
margin: 0 calc(25% + 10px);
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
<div class="title-text">
|
||||
<h1>Connect To Company</h1>
|
||||
</div>
|
||||
<form (ngSubmit)="PostNewCompany(newListing)">
|
||||
<!-- Company Name -->
|
||||
<div #step class="sub-frame">
|
||||
<div class="center">
|
||||
<div class="content-frame">
|
||||
<label>Company Name</label>
|
||||
<input name="name" [(ngModel)]="newListing.name" type="text" placeholder="Mistox" />
|
||||
<button type="button" (click)="nextStep()">Next</button>
|
||||
</div>
|
||||
<div class="footer-frame">
|
||||
<span>
|
||||
This should be your actual company name. It will be public on all the job postings you make.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Company URL -->
|
||||
<div #step class="sub-frame">
|
||||
<div class="center">
|
||||
<div class="content-frame">
|
||||
<label>Company Website URL</label>
|
||||
<input name="url" [(ngModel)]="newListing.websiteURL" type="text" placeholder="https://mistox.com/" />
|
||||
<button type="button" (click)="prevStep()">Back</button>
|
||||
<button type="button" (click)="nextStep()">Next</button>
|
||||
</div>
|
||||
<div class="footer-frame">
|
||||
<span>This should be a link to your companies URL</span><br />
|
||||
<span>so that people searching for your company</span><br />
|
||||
<span>can find it with ease</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Company LOGO URL -->
|
||||
<div #step class="sub-frame">
|
||||
<div class="center">
|
||||
<div class="content-frame">
|
||||
<label>Company LOGO URL</label>
|
||||
<input name="logoURL" [(ngModel)]="newListing.logoURL" type="text" placeholder="https://mistox.com/img/logo.png" />
|
||||
<button type="button" (click)="prevStep()">Back</button>
|
||||
<button type="button" (click)="nextStep()">Next</button>
|
||||
</div>
|
||||
<div class="footer-frame">
|
||||
<span>This should be a link to your companies Logo</span><br />
|
||||
<span>This will show on all your job listings</span><br />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Contact -->
|
||||
<div #step class="sub-frame">
|
||||
<div class="center">
|
||||
<div class="content-frame split">
|
||||
<div class="half-frame">
|
||||
<label>Company Email</label>
|
||||
<input name="email" [(ngModel)]="newListing.email" type="text" />
|
||||
</div>
|
||||
<div class="half-frame">
|
||||
<label>Company Phone Number</label>
|
||||
<input name="email" [(ngModel)]="newListing.phone" type="text" />
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" (click)="prevStep()">Back</button>
|
||||
<button type="button" (click)="nextStep()">Next</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Location -->
|
||||
<div #step class="sub-frame">
|
||||
<div class="center">
|
||||
<h2>Job Location</h2>
|
||||
<div class="content-frame split">
|
||||
<div class="half-frame">
|
||||
<label>City</label>
|
||||
<input name="city" [(ngModel)]="newListing.city" type="text" />
|
||||
</div>
|
||||
<div class="half-frame">
|
||||
<label>2 Letter Country</label>
|
||||
<input name="country" maxlength="2" minlength="2" [(ngModel)]="newListing.country" type="text" />
|
||||
</div>
|
||||
<div class="half-frame">
|
||||
<label>2 Letter State/Region</label>
|
||||
<input name="stateOrRegion" maxlength="2" minlength="2" [(ngModel)]="newListing.stateOrRegion" type="text" />
|
||||
</div>
|
||||
<div class="half-frame">
|
||||
<label>Postal Code</label>
|
||||
<input name="postalCode" [(ngModel)]="newListing.postalCode" type="text" />
|
||||
</div>
|
||||
<button type="button" (click)="prevStep()">Back</button>
|
||||
<button type="button" (click)="nextStep()">Next</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Description -->
|
||||
<div #step class="sub-frame">
|
||||
<div class="center">
|
||||
<div class="content-frame">
|
||||
<label>Description</label>
|
||||
<textarea name="description" [(ngModel)]="newListing.description" type="text"></textarea>
|
||||
<button type="button" (click)="prevStep()">Back</button>
|
||||
<button type="button" (click)="nextStep()">Next</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Submit -->
|
||||
<div #step class="sub-frame">
|
||||
<div class="center">
|
||||
<div class="content-frame">
|
||||
<a [href]="newListing.websiteURL">{{ newListing.name }}</a>
|
||||
<div class="split">
|
||||
<a href="mailto:{{ newListing.email }}">{{ newListing.email }}</a>
|
||||
<a href="tel:{{ newListing.phone }}">{{ newListing.phone }}</a>
|
||||
</div>
|
||||
<div><img [src]="newListing.logoURL" /></div>
|
||||
<div class="split">
|
||||
<div class="half-frame">
|
||||
<span>city: {{ newListing.city }}</span>
|
||||
</div>
|
||||
<div class="half-frame">
|
||||
<span>country: {{ newListing.country }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="split">
|
||||
<div class="half-frame">
|
||||
<span>state: {{ newListing.stateOrRegion }}</span>
|
||||
</div>
|
||||
<div class="half-frame">
|
||||
<span>postal code: {{ newListing.postalCode }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<span>{{ newListing.description }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-frame">
|
||||
<button type="button" (click)="prevStep()">Back</button>
|
||||
<button type="submit">CREATE COMPANY</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@@ -0,0 +1,77 @@
|
||||
import { Component, ElementRef, QueryList, ViewChildren } 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 } from 'app/models/Company';
|
||||
|
||||
@Component({
|
||||
selector: 'main-company-connect',
|
||||
templateUrl: './companyconnect.component.html',
|
||||
styleUrls: [ './companyconnect.component.css' ],
|
||||
imports: [ FormsModule, CommonModule, RouterModule ]
|
||||
})
|
||||
export class CompanyConnectComponent {
|
||||
|
||||
@ViewChildren('step') formSteps!: QueryList<ElementRef<HTMLDivElement>>;
|
||||
currentStep: number = 0;
|
||||
|
||||
public newListing: Company = new Company();
|
||||
public ErrorMsg: string = "";
|
||||
|
||||
constructor( private http: HttpClient, private router: Router, private route: ActivatedRoute, private title: Title, public auth: Authentication ) {
|
||||
this.title.setTitle("Company - Connect | BoredCareers");
|
||||
};
|
||||
|
||||
ngAfterViewInit(){
|
||||
this.formSteps.forEach((step: ElementRef<HTMLDivElement>, i: number) => {
|
||||
if (i === this.currentStep) {
|
||||
step.nativeElement.style.left = '0%';
|
||||
} else if (i < this.currentStep) {
|
||||
step.nativeElement.style.left = '-100%';
|
||||
} else {
|
||||
step.nativeElement.style.left = '100%';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
nextStep(){
|
||||
this.currentStep += 1;
|
||||
this.formSteps.forEach((step: ElementRef<HTMLDivElement>, i: number) => {
|
||||
if (i === this.currentStep) {
|
||||
step.nativeElement.style.left = '0%';
|
||||
} else if (i < this.currentStep) {
|
||||
step.nativeElement.style.left = '-100%';
|
||||
} else {
|
||||
step.nativeElement.style.left = '100%';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
prevStep(){
|
||||
this.currentStep -= 1;
|
||||
this.formSteps.forEach((step: ElementRef<HTMLDivElement>, i: number) => {
|
||||
if (i === this.currentStep) {
|
||||
step.nativeElement.style.left = '0%';
|
||||
} else if (i < this.currentStep) {
|
||||
step.nativeElement.style.left = '-100%';
|
||||
} else {
|
||||
step.nativeElement.style.left = '100%';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
PostNewCompany(company: Company){
|
||||
this.http.post("api/company?newCompany=true", company).subscribe({
|
||||
next: data => {
|
||||
this.router.navigate([""]);
|
||||
},
|
||||
error: err => {
|
||||
alert("Failed to create the job listing. Err: " + err.error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -6,7 +6,7 @@ import { Title } from '@angular/platform-browser';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'home',
|
||||
selector: 'main-home',
|
||||
templateUrl: './home.component.html',
|
||||
styleUrls: [ './home.component.css' ],
|
||||
imports: [ FormsModule, CommonModule ]
|
||||
@@ -0,0 +1,12 @@
|
||||
.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;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<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>
|
||||
@@ -0,0 +1,53 @@
|
||||
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 { JobListing } from 'app/models/JobListing';
|
||||
import { Authentication } from 'app/services/Authentication';
|
||||
|
||||
@Component({
|
||||
selector: 'main-jobs-edit',
|
||||
templateUrl: './jobedit.component.html',
|
||||
styleUrls: [ './jobedit.component.css' ],
|
||||
imports: [ FormsModule, CommonModule, RouterModule ]
|
||||
})
|
||||
export class JobEditComponent {
|
||||
|
||||
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<JobListing[]>("api/joblisting?PageQuantity=" + 10 + "&Page=" + 1).subscribe({
|
||||
next: data => {
|
||||
this.JobListingPage = data;
|
||||
},
|
||||
error: err => {
|
||||
this.ErrorMsg = err.error;
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
RemoveJobListing( JobListingID: number ){
|
||||
this.http.delete("api/joblisting?JobListingID=" + JobListingID).subscribe({
|
||||
next: data => {
|
||||
window.location.reload();
|
||||
},
|
||||
error: err => {
|
||||
alert("Failed to delete the job listing. Try again");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
.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;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<!-- My Jobs -->
|
||||
<div 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>{{ cur.description }}</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>
|
||||
<button [routerLink]="['/jobs/new']">NEW</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Avaliable Jobs -->
|
||||
<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>
|
||||
@@ -0,0 +1,53 @@
|
||||
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 { JobListing } from 'app/models/JobListing';
|
||||
import { Authentication } from 'app/services/Authentication';
|
||||
|
||||
@Component({
|
||||
selector: 'main-jobs',
|
||||
templateUrl: './jobs.component.html',
|
||||
styleUrls: [ './jobs.component.css' ],
|
||||
imports: [ FormsModule, CommonModule, RouterModule ]
|
||||
})
|
||||
export class JobsComponent {
|
||||
|
||||
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 | BoredCareers");
|
||||
|
||||
if (this.Page == 1){
|
||||
|
||||
}
|
||||
|
||||
http.get<JobListing[]>("api/joblisting?PageQuantity=" + 10 + "&Page=" + 1).subscribe({
|
||||
next: data => {
|
||||
this.JobListingPage = data;
|
||||
},
|
||||
error: err => {
|
||||
this.ErrorMsg = err.error;
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
RemoveJobListing( JobListingID: number ){
|
||||
this.http.delete("api/joblisting?JobListingID=" + JobListingID).subscribe({
|
||||
next: data => {
|
||||
window.location.reload();
|
||||
},
|
||||
error: err => {
|
||||
alert("Failed to delete the job listing. Try again");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
.title-text {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
form {
|
||||
display: grid;
|
||||
grid-template-areas: "stack";
|
||||
position: relative;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
transition: 0.5s;
|
||||
}
|
||||
|
||||
.center {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.sub-frame {
|
||||
position: relative;
|
||||
grid-area: stack;
|
||||
transition: 0.5s;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.content-frame {
|
||||
background-color: #00000088;
|
||||
border-radius: 10px;
|
||||
padding: 40px;
|
||||
break-inside: avoid;
|
||||
}
|
||||
|
||||
.split {
|
||||
column-count: 2;
|
||||
}
|
||||
|
||||
.half-frame {
|
||||
width: 400px;
|
||||
break-inside: avoid;
|
||||
}
|
||||
|
||||
.content-frame label {
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
.content-frame textarea {
|
||||
width: calc(100% - 40px);
|
||||
margin: 0 20px;
|
||||
height: 200px;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.content-frame input {
|
||||
width: calc(50% - 24px);
|
||||
margin: 0 calc(25% + 10px);
|
||||
margin-bottom: 20px;
|
||||
appearance: textfield;
|
||||
}
|
||||
|
||||
.content-frame input:focus ~ label {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.content-frame select {
|
||||
width: calc(50% - 24px);
|
||||
margin: 0 calc(25% + 10px);
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
<div class="title-text">
|
||||
<h1>POST A NEW JOB</h1>
|
||||
</div>
|
||||
<form (ngSubmit)="PostJobListing(newListing)">
|
||||
<!-- Title -->
|
||||
<div #step class="sub-frame">
|
||||
<div class="center">
|
||||
<div class="content-frame">
|
||||
<label>Job Title</label>
|
||||
<input name="title" [(ngModel)]="newListing.title" type="text" />
|
||||
<button type="button" (click)="nextStep()">Next</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Job Type -->
|
||||
<div #step class="sub-frame">
|
||||
<div class="center">
|
||||
<div class="content-frame split">
|
||||
<div class="half-frame">
|
||||
<label>Job Type</label>
|
||||
<select name="jobType" [(ngModel)]="newListing.jobType">
|
||||
<option value="">-- Select Job Type --</option>
|
||||
<option value="Full-time">Full-time</option>
|
||||
<option value="Part-time">Part-time</option>
|
||||
<option value="Contract">Contract</option>
|
||||
<option value="Temporary">Temporary</option>
|
||||
<option value="Internship">Internship</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="half-frame">
|
||||
<label>Remote Position</label>
|
||||
<input name="remote" [(ngModel)]="newListing.remote" type="checkbox" />
|
||||
</div>
|
||||
<button type="button" (click)="prevStep()">Back</button>
|
||||
<button type="button" (click)="nextStep()">Next</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Location -->
|
||||
<div #step class="sub-frame">
|
||||
<div class="center">
|
||||
<h2>Job Location</h2>
|
||||
<div class="content-frame split">
|
||||
<div class="half-frame">
|
||||
<label>City</label>
|
||||
<input name="city" [(ngModel)]="newListing.city" type="text" />
|
||||
</div>
|
||||
<div class="half-frame">
|
||||
<label>2 Letter Country</label>
|
||||
<input name="country" maxlength="2" minlength="2" [(ngModel)]="newListing.country" type="text" />
|
||||
</div>
|
||||
<div class="half-frame">
|
||||
<label>2 Letter State/Region</label>
|
||||
<input name="stateOrRegion" maxlength="2" minlength="2" [(ngModel)]="newListing.stateOrRegion" type="text" />
|
||||
</div>
|
||||
<div class="half-frame">
|
||||
<label>Postal Code</label>
|
||||
<input name="postalCode" [(ngModel)]="newListing.postalCode" type="text" />
|
||||
</div>
|
||||
<button type="button" (click)="prevStep()">Back</button>
|
||||
<button type="button" (click)="nextStep()">Next</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Salary Range -->
|
||||
<div #step class="sub-frame">
|
||||
<h2>Salary Range</h2>
|
||||
<div class="center">
|
||||
<div class="content-frame split">
|
||||
<div class="half-frame">
|
||||
<label>Minimum Salary</label>
|
||||
<input name="salaryMin" [(ngModel)]="newListing.salaryMin" type="number" />
|
||||
</div>
|
||||
<div class="half-frame">
|
||||
<label>Maximum Salary</label>
|
||||
<input name="salaryMax" [(ngModel)]="newListing.salaryMax" type="number" />
|
||||
</div>
|
||||
<button type="button" (click)="prevStep()">Back</button>
|
||||
<button type="button" (click)="nextStep()">Next</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Description -->
|
||||
<div #step class="sub-frame">
|
||||
<div class="center">
|
||||
<div class="content-frame">
|
||||
<label>Description</label>
|
||||
<textarea name="description" [(ngModel)]="newListing.description" type="text"></textarea>
|
||||
<button type="button" (click)="prevStep()">Back</button>
|
||||
<button type="button" (click)="nextStep()">Next</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Submit -->
|
||||
<div #step class="sub-frame">
|
||||
<div class="center">
|
||||
<div class="content-frame">
|
||||
<button type="button" (click)="prevStep()">Back</button>
|
||||
<button type="submit">CREATE JOB LISTING</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@@ -0,0 +1,77 @@
|
||||
import { Component, ElementRef, QueryList, ViewChildren } 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 { JobListing } from 'app/models/JobListing';
|
||||
import { Authentication } from 'app/services/Authentication';
|
||||
|
||||
@Component({
|
||||
selector: 'main-jobs-new',
|
||||
templateUrl: './jobnew.component.html',
|
||||
styleUrls: [ './jobnew.component.css' ],
|
||||
imports: [ FormsModule, CommonModule, RouterModule ]
|
||||
})
|
||||
export class JobNewComponent {
|
||||
|
||||
@ViewChildren('step') formSteps!: QueryList<ElementRef<HTMLDivElement>>;
|
||||
currentStep: number = 0;
|
||||
|
||||
public newListing: JobListing = new JobListing();
|
||||
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");
|
||||
};
|
||||
|
||||
ngAfterViewInit(){
|
||||
this.formSteps.forEach((step: ElementRef<HTMLDivElement>, i: number) => {
|
||||
if (i === this.currentStep) {
|
||||
step.nativeElement.style.left = '0%';
|
||||
} else if (i < this.currentStep) {
|
||||
step.nativeElement.style.left = '-100%';
|
||||
} else {
|
||||
step.nativeElement.style.left = '100%';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
nextStep(){
|
||||
this.currentStep += 1;
|
||||
this.formSteps.forEach((step: ElementRef<HTMLDivElement>, i: number) => {
|
||||
if (i === this.currentStep) {
|
||||
step.nativeElement.style.left = '0%';
|
||||
} else if (i < this.currentStep) {
|
||||
step.nativeElement.style.left = '-100%';
|
||||
} else {
|
||||
step.nativeElement.style.left = '100%';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
prevStep(){
|
||||
this.currentStep -= 1;
|
||||
this.formSteps.forEach((step: ElementRef<HTMLDivElement>, i: number) => {
|
||||
if (i === this.currentStep) {
|
||||
step.nativeElement.style.left = '0%';
|
||||
} else if (i < this.currentStep) {
|
||||
step.nativeElement.style.left = '-100%';
|
||||
} else {
|
||||
step.nativeElement.style.left = '100%';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
PostJobListing(jobListing: JobListing){
|
||||
this.http.post("api/joblisting", jobListing).subscribe({
|
||||
next: data => {
|
||||
|
||||
},
|
||||
error: err => {
|
||||
alert("Failed to create the job listing. Try again");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<div class="tile-frame" *ngFor="let cur of ResumePage">
|
||||
<div class="tile">
|
||||
<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>
|
||||
@@ -0,0 +1,24 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { Router, ActivatedRoute } from '@angular/router';
|
||||
import { Title } from '@angular/platform-browser';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Resume } from 'app/models/Resume';
|
||||
|
||||
@Component({
|
||||
selector: 'main-resumes',
|
||||
templateUrl: './resumes.component.html',
|
||||
styleUrls: [ './resumes.component.css' ],
|
||||
imports: [ FormsModule, CommonModule ]
|
||||
})
|
||||
export class ResumesComponent {
|
||||
|
||||
public ResumePage: Resume[] = [];
|
||||
|
||||
constructor( private http: HttpClient, private router: Router, private route: ActivatedRoute, private title: Title ) {
|
||||
this.title.setTitle("Resumes | BoredCareers");
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
<div class="center">
|
||||
<div class="big-frame background-border text-frame">
|
||||
<p><strong>What is the game</strong></p>
|
||||
<p style="padding-left: 30px;">Project-Mist is a survival game. Kind of like a battle royal in a sense but, think of it backwards. And no I know what your thinking. Its not the first person to die wins. No instead its a never ending survival game where you can free roam and build structures. The catch is, the person who has the highest stats [i.e A combination of kills, survival time] has a marker placed on their forhead.</p>
|
||||
<p><strong>How will the game play</strong></p>
|
||||
<p style="padding-left: 30px;">When you join the game you will be able to customize your character. There you can set a default loadout for your player. This will be the spawn weapon and gear. After that you will drop into the map with other players to fend for your life. The kill-leader will be marked loosely on the mini-map. You can choose to go after the kill leader or you can choose to loot first. The choice is yours. But be aware that if you survive long enough you will become the new kill leader.</p>
|
||||
<p><strong>Current Idea Board *SUBJECT TO CHANGE*</strong></p>
|
||||
<p>Survival Game<br />look at item to pick up 'e' for third person and click for third [No nearby]<br />normal weapons with bullet drop bullet travel time<br />snipers but rare [Maybe special]</p>
|
||||
<p>Abilities selectable at spawn<br /> a max 20 credit slider where you can spend them on traits<br /> Stamina -> run for longer distances<br /> Strength -> carry more weight<br /> Vitality -> Have more base health<br /> Stealth -> Approximate location on map is bigger</p>
|
||||
<p>More weight slows player some<br />Backpacks -> Add slots but not weight</p>
|
||||
<p>Oddball style game<br /> Map that shows the relitive area of the top player</p>
|
||||
<p>spawn with classes<br /> 2 mags<br /> no attachments<br /> unlock guns with experience</p>
|
||||
<p>no health regen<br />final hit headshots = 20 credits<br />final hit bodyshots = 10 credits</p>
|
||||
<p>classes require credits to spawn with better stuff<br />inventory and credits are transferrable between servers and sessions<br />combat loggging - if leave in combat start from scratch<br />one dynamicly roaming entity of the night ( Impossible to kill, when near heart starts pumping and vinegrette )<br /> goes after people possible to get away<br />Dyanmic day and night cycle<br />Dynamic weather ( rain, fog, thunder, lightning )<br />floods that cause roaring rivers to fill that cannot be swam<br />Fires that char trees(no leaves), regrows in 3ish days<br />Master leaderboard in the main menu of top players per rank<br />Ranked lobby ( Disabled until player base )<br />small towns around a main centralized area( ie city or temple )<br />large servers<br />random spawned skin boxes that require credits to open<br />purchasable skins<br />bullet penatration on certain materials<br />bullet reflection on certain materials<br />No kill leader until you get at least 2 kills minimum</p>
|
||||
<p>Tournament mode<br /> all players spawn at the same time<br /> hold oddball for 30mins total</p>
|
||||
<p>server quits introducing people into game after 5 hrs. (last man standing mode)<br /> last person in server wins<br /> on death quit to new server<br /> everyone becomes oddball<br /> less players alive equal less oddball area</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,50 +0,0 @@
|
||||
<div class="center">
|
||||
<div class="column-content">
|
||||
<form class="big-frame background-border" style="width: 520px;" #accountForm="ngForm" (ngSubmit)="onSubmit()">
|
||||
<h3>Edit Item</h3>
|
||||
|
||||
<div class="frame-item">
|
||||
<input type="text" [(ngModel)]="newItem.name" name="ItemName" placeholder=" " />
|
||||
<label>Item Name</label>
|
||||
</div>
|
||||
|
||||
<div class="frame-item">
|
||||
<input type="number" [(ngModel)]="newItem.cost" name="ItemCost" placeholder=" " />
|
||||
<label>Cost</label>
|
||||
</div>
|
||||
|
||||
<div class="frame-item">
|
||||
<input type="text" [(ngModel)]="newItem.url" name="itemURL" placeholder=" " />
|
||||
<label>URL</label>
|
||||
</div>
|
||||
|
||||
<div class="frame-item">
|
||||
<textarea [(ngModel)]="newItem.description" name="ItemDesc" cols="40" placeholder=" " ></textarea>
|
||||
<label>Description</label>
|
||||
</div>
|
||||
|
||||
<div class="frame-item">
|
||||
<div id="FileUploadPlaceholder" ></div>
|
||||
<input #FileUpload type="file" (change)="onFileSelected($event)" accept="image/*" multiple />
|
||||
</div>
|
||||
|
||||
<div class="flex-row">
|
||||
<div class="frame-button">
|
||||
<input class="submit" type="submit" value="Update Item" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul *ngIf="errorMsgs.length > 0" >
|
||||
<li *ngFor="let msg of errorMsgs" >{{ msg }}</li>
|
||||
</ul>
|
||||
</form>
|
||||
|
||||
<!-- Finish file preview for uploads -->
|
||||
<div class="img-frame">
|
||||
<div *ngFor="let cur of imagePreviews" class="image-holder">
|
||||
<input class="delete-button" type="button" value="X" (click)="RemovePhoto(cur)" />
|
||||
<img [src]="cur" alt="Image Preview" style="max-width: 200px;"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,128 +0,0 @@
|
||||
import { Component, ElementRef, ViewChild } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { Router, ActivatedRoute } from '@angular/router';
|
||||
import { Title } from '@angular/platform-browser';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Authentication } from '../../../../services/Authentication';
|
||||
import { Product } from 'app/models/Product';
|
||||
|
||||
@Component({
|
||||
selector: 'item-edit',
|
||||
templateUrl: './edit.component.html',
|
||||
imports: [ FormsModule, CommonModule ]
|
||||
})
|
||||
export class EditItemComponent {
|
||||
@ViewChild('FileUpload') InputDOM!: ElementRef<HTMLInputElement>;
|
||||
|
||||
readonly maxFileMB = 16;
|
||||
|
||||
newItem: Product = new Product();
|
||||
errorMsgs: string[] = [];
|
||||
|
||||
constructor( private http: HttpClient, private router: Router, private route: ActivatedRoute, private title: Title, public auth: Authentication ) {
|
||||
this.title.setTitle("Edit | ADMIN");
|
||||
this.route.queryParams.subscribe(params => {
|
||||
this.newItem.id = params['ProductID'] || '';
|
||||
});
|
||||
|
||||
// If user is not logged in -> route home
|
||||
if (!auth.isLoggedIn){
|
||||
router.navigate(["/"]);
|
||||
}
|
||||
|
||||
// If user is not Admin -> route home
|
||||
if (auth.loggedInUser.siteData.role != "Admin"){
|
||||
router.navigate(["/"]);
|
||||
}
|
||||
|
||||
// Load product
|
||||
const formData = new FormData();
|
||||
formData.append("productID", this.newItem.id.toString());
|
||||
this.http.post<Product>( "api/product/get", formData ).subscribe({
|
||||
next: async (data) => {
|
||||
this.newItem = data;
|
||||
this.newItem.images.forEach(img => {
|
||||
http.get("api/productimage/get?ProductID=" + img.productID + "&ImageID=" + img.imageID, { responseType: 'blob' }).subscribe(blob => {
|
||||
img.imageSrc = URL.createObjectURL(blob);
|
||||
this.imagePreviews.push(img.imageSrc);
|
||||
this.selectedFiles.push(new File([blob], "EmptyName", {type: "image/jpeg"}));
|
||||
});
|
||||
});
|
||||
},
|
||||
error: err => {
|
||||
console.log("Err loading product: ", err);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
sleep(ms: number) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
selectedFiles: File[] = [];
|
||||
imagePreviews: string[] = [];
|
||||
onFileSelected(event: Event){
|
||||
const fileInput = event.target as HTMLInputElement;
|
||||
|
||||
if (!fileInput.files?.length){
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i=0; i<fileInput.files.length; i++){
|
||||
let file = fileInput.files[i];
|
||||
if (file.size > this.maxFileMB * 1024 * 1024){
|
||||
this.errorMsgs.push("File exceeds max file size of 16MB");
|
||||
continue;
|
||||
}
|
||||
// No issues add file to the list
|
||||
this.selectedFiles.push( file );
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload= () => {
|
||||
this.imagePreviews.push(reader.result as string);
|
||||
}
|
||||
reader.readAsDataURL(file);
|
||||
|
||||
this.InputDOM.nativeElement.value = '';
|
||||
}
|
||||
}
|
||||
|
||||
RemovePhoto(imagePreview: string){
|
||||
let i = this.imagePreviews.indexOf(imagePreview);
|
||||
this.imagePreviews.splice(i, 1);
|
||||
this.selectedFiles.splice(i, 1);
|
||||
}
|
||||
|
||||
onSubmit(){
|
||||
const formData = new FormData();
|
||||
// Append non-file fields
|
||||
formData.append("Name", this.newItem.name);
|
||||
formData.append("Description", this.newItem.description);
|
||||
formData.append("Cost", this.newItem.cost.toString());
|
||||
formData.append("Url", this.newItem.url);
|
||||
|
||||
// Add image fileds
|
||||
if (this.selectedFiles.length > 0){
|
||||
for(let i=0; i<this.selectedFiles.length; i++){
|
||||
formData.append("images", this.selectedFiles[i], this.selectedFiles[i].name);
|
||||
};
|
||||
}
|
||||
|
||||
// Proccess data
|
||||
this.http.post<boolean>( "api/product/create", formData ).subscribe({
|
||||
next: async (data) => {
|
||||
if (data == true){
|
||||
this.errorMsgs = ["Product Created Successfully"];
|
||||
await this.sleep(3000);
|
||||
this.router.navigate(["/catalog"]);
|
||||
}else{
|
||||
this.errorMsgs = ["Error has ocurred"];
|
||||
}
|
||||
},
|
||||
error: err => {
|
||||
console.log("New Product Err: ", err);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
<div class="center">
|
||||
<div class="column-content">
|
||||
<form class="big-frame background-border" style="width: 520px;" #accountForm="ngForm" (ngSubmit)="onSubmit()">
|
||||
<h3>Create New Item</h3>
|
||||
|
||||
<div class="frame-item">
|
||||
<input type="text" [(ngModel)]="newItem.name" name="ItemName" placeholder=" " />
|
||||
<label>Item Name</label>
|
||||
</div>
|
||||
|
||||
<div class="frame-item">
|
||||
<input type="number" [(ngModel)]="newItem.cost" name="ItemCost" placeholder=" " />
|
||||
<label>Cost</label>
|
||||
</div>
|
||||
|
||||
<div class="frame-item">
|
||||
<input type="text" [(ngModel)]="newItem.url" name="itemURL" placeholder=" " />
|
||||
<label>URL</label>
|
||||
</div>
|
||||
|
||||
<div class="frame-item">
|
||||
<textarea [(ngModel)]="newItem.description" name="ItemDesc" cols="40" placeholder=" " ></textarea>
|
||||
<label>Description</label>
|
||||
</div>
|
||||
|
||||
<div class="frame-item">
|
||||
<!-- Need to fix for image file upload -->
|
||||
<div id="FileUploadPlaceholder" ></div>
|
||||
<input type="file" (change)="onFileSelected($event)" accept="image/*" multiple />
|
||||
</div>
|
||||
|
||||
<div class="flex-row">
|
||||
<div class="frame-button">
|
||||
<input class="submit" type="submit" value="Create Item" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul *ngIf="errorMsgs.length > 0" >
|
||||
<li *ngFor="let msg of errorMsgs" >{{ msg }}</li>
|
||||
</ul>
|
||||
</form>
|
||||
|
||||
<!-- Finish file preview for uploads -->
|
||||
<div class="img-frame">
|
||||
<div *ngFor="let cur of imagePreviews" class="image-holder">
|
||||
<img [src]="cur" alt="Image Preview" style="max-width: 200px;"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,101 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { Router, ActivatedRoute } from '@angular/router';
|
||||
import { Title } from '@angular/platform-browser';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Authentication } from '../../../../services/Authentication';
|
||||
import { Product } from 'app/models/Product';
|
||||
|
||||
@Component({
|
||||
selector: 'item-new',
|
||||
templateUrl: './new.component.html',
|
||||
imports: [ FormsModule, CommonModule ]
|
||||
})
|
||||
export class NewItemComponent {
|
||||
|
||||
readonly maxFileMB = 16;
|
||||
|
||||
newItem: Product = new Product();
|
||||
errorMsgs: string[] = [];
|
||||
|
||||
constructor( private http: HttpClient, private router: Router, private route: ActivatedRoute, private title: Title, public auth: Authentication ) {
|
||||
this.title.setTitle("New | ADMIN");
|
||||
|
||||
// If user is not logged in -> route home
|
||||
if (!auth.isLoggedIn){
|
||||
router.navigate(["/"]);
|
||||
}
|
||||
|
||||
// If user is not Admin -> route home
|
||||
if (auth.loggedInUser.siteData.role != "Admin"){
|
||||
router.navigate(["/"]);
|
||||
}
|
||||
};
|
||||
|
||||
sleep(ms: number) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
selectedFiles: File[] = [];
|
||||
imagePreviews: string[] = [];
|
||||
onFileSelected(event: Event){
|
||||
const fileInput = event.target as HTMLInputElement;
|
||||
this.imagePreviews = [];
|
||||
this.selectedFiles = [];
|
||||
|
||||
if (!fileInput.files?.length){
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i=0; i<fileInput.files.length; i++){
|
||||
let file = fileInput.files[i];
|
||||
if (file.size > this.maxFileMB * 1024 * 1024){
|
||||
this.errorMsgs.push("File exceeds max file size of 16MB");
|
||||
continue;
|
||||
}
|
||||
// No issues add file to the list
|
||||
this.selectedFiles.push( file );
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload= () => {
|
||||
this.imagePreviews.push(reader.result as string);
|
||||
}
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
}
|
||||
|
||||
onSubmit(){
|
||||
|
||||
const formData = new FormData();
|
||||
|
||||
// Append non-file fields
|
||||
formData.append("Name", this.newItem.name);
|
||||
formData.append("Description", this.newItem.description);
|
||||
formData.append("Cost", this.newItem.cost.toString());
|
||||
formData.append("Url", this.newItem.url);
|
||||
|
||||
// Add image fileds
|
||||
if (this.selectedFiles.length > 0){
|
||||
for(let i=0; i<this.selectedFiles.length; i++){
|
||||
formData.append("images", this.selectedFiles[i], this.selectedFiles[i].name);
|
||||
};
|
||||
}
|
||||
|
||||
// Proccess data
|
||||
this.http.post<boolean>( "api/product/create", formData ).subscribe({
|
||||
next: async (data) => {
|
||||
if (data == true){
|
||||
this.errorMsgs = ["Product Created Successfully"];
|
||||
await this.sleep(3000);
|
||||
this.router.navigate(["store/catalog"]);
|
||||
}else{
|
||||
this.errorMsgs = ["Error has ocurred"];
|
||||
}
|
||||
},
|
||||
error: err => {
|
||||
console.log("New Product Err: ", err);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
.gameCard {
|
||||
position: relative;
|
||||
background-color: var(--Mistox-Black);
|
||||
float: left;
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
border-radius: 10px;
|
||||
break-inside: avoid;
|
||||
margin-bottom: 2rem;
|
||||
border: solid 2px var(--Mistox-Background);
|
||||
transition-duration: 1s;
|
||||
}
|
||||
|
||||
.gameCard :hover{
|
||||
border-color: var(--Mistox-Light);
|
||||
}
|
||||
|
||||
.gameCard-Name {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
font-size: 25px;
|
||||
padding: 5px 0 0 5px;
|
||||
background-color: rgba(0,0,0,.1);
|
||||
}
|
||||
|
||||
.gameCard-Grid {
|
||||
column-count: 4;
|
||||
column-gap: 2rem;
|
||||
padding-top: 20px;
|
||||
width: calc(100% - 40px);
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
@media (max-width: 1400px) {
|
||||
.gameCard-Grid {
|
||||
column-count: 3;
|
||||
padding-top: 20px;
|
||||
width: calc(100% - 40px);
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1100px) {
|
||||
.gameCard-Grid {
|
||||
column-count: 2;
|
||||
padding-top: 20px;
|
||||
width: calc(100% - 40px);
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.gameCard-Grid {
|
||||
column-count: 1;
|
||||
padding-top: 20px;
|
||||
width: calc(100% - 40px);
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.gameCard-Img {
|
||||
width: 100%;
|
||||
border-radius: 10px 10px 0 0;
|
||||
}
|
||||
|
||||
.gameCard-Next,
|
||||
.gameCard-Prev {
|
||||
background-color: transparent;
|
||||
color: var(--Mistox-White);
|
||||
padding: 16px;
|
||||
margin-top: -22px;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
border: none;
|
||||
transition: background-color 0.6s ease;
|
||||
}
|
||||
|
||||
.gameCard-Next:hover,
|
||||
.gameCard-Prev:hover {
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.gameCard-Prev {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
}
|
||||
|
||||
.gameCard-Next {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.gameCard-Desc {
|
||||
font-size: 13px;
|
||||
margin: 5px;
|
||||
color: var(--Mistox-Light);
|
||||
}
|
||||
|
||||
.gameCard-Price {
|
||||
width: calc(50% - 10px);
|
||||
float: left;
|
||||
margin: 5px;
|
||||
text-align: center;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.gameCard-Button {
|
||||
width: 40%;
|
||||
margin: 5px 5%;
|
||||
height: 38.4px;
|
||||
color: var(--Mistox-Black);
|
||||
background-color: var(--Mistox-Light);
|
||||
font-size: 16px;
|
||||
text-decoration: none;
|
||||
text-transform: uppercase;
|
||||
overflow: hidden;
|
||||
transition: 0.5s;
|
||||
letter-spacing: 2px;
|
||||
border: 1px solid var(--Mistox-Light);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.gameCard-Button :hover{
|
||||
background-color: var(--Mistox-Light);
|
||||
color: var(--Mistox-White);
|
||||
box-shadow: 4px 3px 6px var(--Mistox-Dark);
|
||||
}
|
||||
|
||||
.cartopen {
|
||||
position: absolute;
|
||||
background: var(--Mistox-Offset);
|
||||
right: 10px;
|
||||
top: 55px;
|
||||
width: 400px;
|
||||
border-radius: 5px;
|
||||
backdrop-filter: blur(3px);
|
||||
border: 1px solid var(--Mistox-Light);
|
||||
}
|
||||
|
||||
.cartclosed {
|
||||
display: none;
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
<div class="gameCard-Grid">
|
||||
<div class="gameCard" *ngFor="let product of Products">
|
||||
<div style="position: relative;">
|
||||
<div *ngIf="product.images.length > 1">
|
||||
<button class="gameCard-Prev" (click)="nextImg(product)">❮</button>
|
||||
<button class="gameCard-Next" (click)="prevImg(product)">❯</button>
|
||||
</div>
|
||||
<div *ngIf="product.images.length > 0" >
|
||||
<img class="gameCard-Img" [src]="product.images[product.curShowingIMG].imageSrc">
|
||||
</div>
|
||||
</div>
|
||||
<h1 class ="gameCard-Name">{{ product.name }}</h1>
|
||||
<div *ngFor="let line of product.description.split('\n')" >
|
||||
<h2 class="gameCard-Desc">{{ line }}</h2>
|
||||
</div>
|
||||
<h2 class="gameCard-Price">${{ (product.cost/100).toFixed(2) }}</h2>
|
||||
<button class="gameCard-Button" >Add To Cart</button>
|
||||
<div *ngIf="auth.loggedInUser.siteData.role == 'Admin'">
|
||||
<button style="width: calc(50% - 10px); margin: 5px;" [routerLink]="['/store/admin/edit']" [queryParams]="{ ProductID: product.id }" >
|
||||
Edit
|
||||
</button>
|
||||
<button style="width: calc(50% - 10px); margin: 5px;" (click)="DeleteItem(product.id)" >
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="auth.loggedInUser.siteData.role == 'Admin'">
|
||||
<button style="width: calc(100% - 10px); margin: 5px;" [routerLink]="['/store/admin/new']" >
|
||||
New
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,71 +0,0 @@
|
||||
import { Component, NgZone } from '@angular/core';
|
||||
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
|
||||
import { FormsModule, NgModel } from '@angular/forms';
|
||||
import { Router, ActivatedRoute, RouterModule } from '@angular/router';
|
||||
import { Title } from '@angular/platform-browser';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Authentication } from '../../../services/Authentication';
|
||||
import { Product } from 'app/models/Product';
|
||||
|
||||
@Component({
|
||||
selector: 'store-catalog',
|
||||
templateUrl: './catalog.component.html',
|
||||
styleUrl: './catalog.component.css',
|
||||
imports: [ FormsModule, CommonModule, RouterModule ]
|
||||
})
|
||||
export class CatalogComponent {
|
||||
|
||||
public Products: Product[] = [];
|
||||
|
||||
constructor( private http: HttpClient, private router: Router, private route: ActivatedRoute, private title: Title, public auth: Authentication ) {
|
||||
this.title.setTitle("Store | Mistox");
|
||||
|
||||
// load each product
|
||||
http.post<Product[]>("api/product/getall", null).subscribe(
|
||||
response => {
|
||||
this.Products = response;
|
||||
|
||||
// Load each image
|
||||
this.Products.forEach(item => {
|
||||
item.curShowingIMG = 0;
|
||||
item.images.forEach(img => {
|
||||
http.get("api/productimage/get?ProductID=" + img.productID + "&ImageID=" + img.imageID, { responseType: 'blob' }).subscribe(blob => {
|
||||
img.imageSrc = URL.createObjectURL(blob);
|
||||
console.log(img.imageSrc);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
)
|
||||
};
|
||||
|
||||
nextImg( prod: Product ){
|
||||
prod.curShowingIMG += 1;
|
||||
if (prod.curShowingIMG == prod.images.length){
|
||||
prod.curShowingIMG = 0;
|
||||
}
|
||||
}
|
||||
|
||||
prevImg( prod: Product ){
|
||||
prod.curShowingIMG -= 1;
|
||||
if (prod.curShowingIMG == -1){
|
||||
prod.curShowingIMG = prod.images.length -1;
|
||||
}
|
||||
}
|
||||
|
||||
DeleteItem( ProductID: number ) {
|
||||
const body = new HttpParams()
|
||||
.set("productID", ProductID);
|
||||
const headers = new HttpHeaders({
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
});
|
||||
this.http.post<boolean>( "api/product/delete", body, { headers } ).subscribe({
|
||||
next: data => {
|
||||
if (data){
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
#payment-form {
|
||||
max-width: 500px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
#card-element {
|
||||
padding: 12px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
#submit {
|
||||
background-color: #5469d4;
|
||||
color: white;
|
||||
padding: 12px 20px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
<form id="payment-form">
|
||||
<div class="form-group">
|
||||
<label for="card-element">Card Details</label>
|
||||
<div id="card-element"></div>
|
||||
<div id="card-errors" role="alert"></div>
|
||||
</div>
|
||||
<button id="submit">Pay</button>
|
||||
</form>
|
||||
@@ -1,62 +0,0 @@
|
||||
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 '../../../services/Authentication';
|
||||
import { loadStripe, Stripe, StripeElements } from '@stripe/stripe-js';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'store-payment',
|
||||
templateUrl: './payment.component.html',
|
||||
styleUrl: './payment.component.css',
|
||||
imports: [ FormsModule, CommonModule, RouterModule ]
|
||||
})
|
||||
export class PaymentComponent {
|
||||
|
||||
stripe: Stripe | null = null;
|
||||
elements: StripeElements | null = null;
|
||||
|
||||
async ngOnInit(){
|
||||
|
||||
let ApiKey = await firstValueFrom(this.http.get<string>("/api/payment/publickey"));
|
||||
|
||||
this.stripe = await loadStripe(ApiKey);
|
||||
if (this.stripe){
|
||||
this.elements = this.stripe?.elements();
|
||||
}
|
||||
}
|
||||
|
||||
ngAfterViewInit(){
|
||||
if (this.elements){
|
||||
const cardStyle = {
|
||||
base: {
|
||||
color: '#32325d',
|
||||
fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
|
||||
fontSize: '16px',
|
||||
'::placeholder': {
|
||||
color: '#aab7c4',
|
||||
}
|
||||
},
|
||||
invalid: {
|
||||
color: '#fa755a',
|
||||
}
|
||||
}
|
||||
const card = this.elements.create('card', { style: cardStyle });
|
||||
card.mount('#card-element');
|
||||
}
|
||||
}
|
||||
|
||||
constructor( private http: HttpClient, private router: Router, private route: ActivatedRoute, private title: Title, public auth: Authentication ) {
|
||||
this.title.setTitle("Payment | Mistox");
|
||||
|
||||
http.post<void[]>("api/product/getall", null).subscribe(
|
||||
response => {
|
||||
|
||||
}
|
||||
)
|
||||
};
|
||||
|
||||
}
|
||||
@@ -24,22 +24,20 @@ export class Authentication{
|
||||
let sub = this.http.post<Account>( "api/account/login", body, { headers } );
|
||||
sub.subscribe({
|
||||
next: data => {
|
||||
if (data.error.length === 0){
|
||||
this._user.next(data);
|
||||
this.setUserToStorage(data, StayLoggedIn == true ? SessionType.Forever : SessionType.Session);
|
||||
}
|
||||
},
|
||||
error: err => {
|
||||
console.log("HTTP Error Signing In: ", err);
|
||||
console.log("HTTP Error Signing In: ", err.error);
|
||||
}
|
||||
});
|
||||
return sub;
|
||||
}
|
||||
|
||||
Logout(){
|
||||
this.http.post<Account>( "api/account/logout", {}, { responseType: 'json' } ).subscribe( );
|
||||
this._user.next( new Account );
|
||||
this.delUserFromStorage();
|
||||
return this.http.post<Account>( "api/account/logout", {}, { responseType: 'json' } );
|
||||
}
|
||||
|
||||
get isLoggedIn(): boolean {
|
||||
|
||||
@@ -5,7 +5,6 @@ using System.Security.Claims;
|
||||
using BoredCareers.Services;
|
||||
using BoredCareers.Services.DatabaseService;
|
||||
using BoredCareers.Entities;
|
||||
using Microsoft.AspNetCore.Http.HttpResults;
|
||||
using System.Web.Http;
|
||||
|
||||
namespace BoredCareers.Controllers {
|
||||
@@ -48,11 +47,11 @@ namespace BoredCareers.Controllers {
|
||||
IsPersistent = StayLoggedIn, // Is set from the StayLoggedIn
|
||||
}
|
||||
);
|
||||
return test;
|
||||
return Ok(test);
|
||||
} else {
|
||||
test.CurrentPasswordAttempts += 1;
|
||||
await _databaseService.SetAccount(test);
|
||||
return Ok(new Account() { ID = -1, UserName = "Wrong Password" });
|
||||
return NotFound("Wrong Password");
|
||||
}
|
||||
} else {
|
||||
await SendVerify(test.UserName);
|
||||
@@ -62,7 +61,7 @@ namespace BoredCareers.Controllers {
|
||||
return NotFound("Account Not Found");
|
||||
} catch (Exception ex) {
|
||||
Console.WriteLine("Login Error: " + ex.Message);
|
||||
return NotFound();
|
||||
return NotFound("An internal server error has occured");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +92,7 @@ namespace BoredCareers.Controllers {
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Console.WriteLine("Register Error: " + ex.Message);
|
||||
return NotFound();
|
||||
return NotFound("An internal server error has occured");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -111,10 +110,10 @@ namespace BoredCareers.Controllers {
|
||||
return Ok();
|
||||
}
|
||||
}
|
||||
return NotFound();
|
||||
return NotFound("Not logged in");
|
||||
} catch (Exception ex) {
|
||||
Console.WriteLine("ChangePassword Error: " + ex.Message);
|
||||
return NotFound();
|
||||
return NotFound("An internal server error has occured");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,10 +128,10 @@ namespace BoredCareers.Controllers {
|
||||
await _databaseService.SetAccount(user);
|
||||
return Ok();
|
||||
}
|
||||
return NotFound();
|
||||
return NotFound("Not logged in");
|
||||
} catch (Exception ex) {
|
||||
Console.WriteLine("ToggleAccountLock Error: " + ex.Message);
|
||||
return NotFound();
|
||||
return NotFound("An internal server error has occured");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,10 +142,10 @@ namespace BoredCareers.Controllers {
|
||||
if (isLoggedIn()) {
|
||||
return Ok(await getLoggedInUser());
|
||||
}
|
||||
return NotFound();
|
||||
return NotFound("Not logged in");
|
||||
} catch (Exception ex) {
|
||||
Console.WriteLine("Get Error: " + ex);
|
||||
return NotFound();
|
||||
return NotFound("An internal server error has occured");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,7 +168,7 @@ namespace BoredCareers.Controllers {
|
||||
if (_emailContext._SentEmails.ContainsKey(key)) {
|
||||
DateTime PreviousSentTime = _emailContext._SentEmails.GetValueOrDefault(key);
|
||||
if (PreviousSentTime.AddMinutes(5) > DateTime.Now) {
|
||||
return "Cannot sent another verify email until 5 minutes has elapsed ";
|
||||
return NotFound("Cannot sent another verify email until 5 minutes has elapsed");
|
||||
}
|
||||
else {
|
||||
_emailContext._SentEmails.Remove(key);
|
||||
@@ -187,11 +186,11 @@ namespace BoredCareers.Controllers {
|
||||
|
||||
string result = _emailContext.Send(test.Email, EmailService.VerifyEmailSubject, EmailContents);
|
||||
_emailContext._SentEmails.Add(key, DateTime.Now);
|
||||
return result;
|
||||
return Ok(result);
|
||||
}
|
||||
return "Account not found";
|
||||
return NotFound("Account not found");
|
||||
} catch (Exception) {
|
||||
return "The connection couldn't be established to the email server";
|
||||
return NotFound("An internal server error has occured");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,12 +204,12 @@ namespace BoredCareers.Controllers {
|
||||
test.EmailToken = "";
|
||||
test.EmailVerified = true;
|
||||
await _databaseService.SetAccount(test);
|
||||
return true;
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return NotFound("Account not found or token is invalid");;
|
||||
} catch {
|
||||
return false;
|
||||
return NotFound("An internal server error has occured");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,7 +222,7 @@ namespace BoredCareers.Controllers {
|
||||
if (_emailContext._SentEmails.ContainsKey(key)) {
|
||||
DateTime PreviousSentTime = _emailContext._SentEmails.GetValueOrDefault(key);
|
||||
if (PreviousSentTime.AddMinutes(5) > DateTime.Now) {
|
||||
return "Cannot sent another reset requests until 5 minutes has elapsed";
|
||||
return NotFound("Cannot sent another reset requests until 5 minutes has elapsed");
|
||||
}
|
||||
else {
|
||||
_emailContext._SentEmails.Remove(key);
|
||||
@@ -241,12 +240,12 @@ namespace BoredCareers.Controllers {
|
||||
|
||||
string result = _emailContext.Send(test.Email, EmailService.VerifyEmailSubject, EmailContents);
|
||||
_emailContext._SentEmails.Add(key, DateTime.Now);
|
||||
return result;
|
||||
return Ok(result);
|
||||
}
|
||||
return "Account Not Found";
|
||||
return NotFound("Account Not Found");
|
||||
} catch (Exception e) {
|
||||
Console.WriteLine("EmailService Error: " + e.ToString());
|
||||
return "The connection couldn't be established to the email server";
|
||||
return NotFound("An internal server error has occured");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -262,12 +261,12 @@ namespace BoredCareers.Controllers {
|
||||
test.EmailToken = "";
|
||||
test.PasswordHash = BCrypt.Net.BCrypt.HashPassword(NewPassword);
|
||||
await _databaseService.SetAccount(test);
|
||||
return true;
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return NotFound("Account not found or reset token is bad");
|
||||
} catch {
|
||||
return false;
|
||||
return NotFound("An internal server error has occured");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,10 +281,10 @@ namespace BoredCareers.Controllers {
|
||||
return Ok();
|
||||
}
|
||||
}
|
||||
return NotFound();
|
||||
return NotFound("User is not logged in");
|
||||
} catch (Exception ex) {
|
||||
Console.WriteLine("Delete Error: " + ex.Message);
|
||||
return NotFound();
|
||||
return NotFound("An internal server error has occured");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,19 +17,30 @@ namespace BoredCareers.Controllers {
|
||||
if (company != null) {
|
||||
return Ok(company);
|
||||
}
|
||||
return NotFound("Company doesn't exist");
|
||||
}
|
||||
return NotFound();
|
||||
return NotFound("Not logged in");
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> SetCompany([FromBody] Company company) {
|
||||
public async Task<IActionResult> SetCompany([FromBody] Company company, [FromQuery] bool newCompany = false) {
|
||||
if (isLoggedIn()) {
|
||||
if (newCompany) {
|
||||
Company? test = await _databaseService.GetCompany(company.ID);
|
||||
if (test == null) {
|
||||
await _databaseService.SetCompany(company);
|
||||
return Ok();
|
||||
}
|
||||
return NotFound("The company already exists");
|
||||
} else {
|
||||
if (await isLoggedInUserEmployeeOf(company.ID)) {
|
||||
await _databaseService.SetCompany(company);
|
||||
return Ok();
|
||||
}
|
||||
return NotFound("You are not an employee of company");
|
||||
}
|
||||
return NotFound();
|
||||
}
|
||||
return NotFound("Not logged in");
|
||||
}
|
||||
|
||||
[HttpDelete]
|
||||
@@ -39,8 +50,9 @@ namespace BoredCareers.Controllers {
|
||||
await _databaseService.DeleteCompany(CompanyID);
|
||||
return Ok();
|
||||
}
|
||||
return NotFound("You are not an employee of company");
|
||||
}
|
||||
return NotFound();
|
||||
return NotFound("Not logged in");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace BoredCareers.Controllers {
|
||||
if (jobListing != null) {
|
||||
return Ok(jobListing);
|
||||
}
|
||||
return NotFound();
|
||||
return NotFound("Job listing not found");
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
@@ -30,9 +30,11 @@ namespace BoredCareers.Controllers {
|
||||
if (isLoggedIn()) {
|
||||
if (await isLoggedInUserEmployeeOf(JobListing.CompanyID)) {
|
||||
await _databaseService.SetJobListing(JobListing);
|
||||
return Ok();
|
||||
}
|
||||
return NotFound("You are not an employee of company");
|
||||
}
|
||||
return NotFound();
|
||||
return NotFound("Not logged in");
|
||||
}
|
||||
|
||||
[HttpDelete]
|
||||
@@ -42,10 +44,13 @@ namespace BoredCareers.Controllers {
|
||||
if (jobListing != null) {
|
||||
if (await isLoggedInUserEmployeeOf(JobListingID)) {
|
||||
await _databaseService.DeleteJobListing(JobListingID);
|
||||
return Ok();
|
||||
}
|
||||
return NotFound("You are not an employee of company");
|
||||
}
|
||||
return NotFound("Job listing doesn't exist already");
|
||||
}
|
||||
return NotFound();
|
||||
return NotFound("Not logged in");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,14 +17,15 @@ namespace BoredCareers.Controllers {
|
||||
if (resume != null) {
|
||||
return Ok(resume);
|
||||
}
|
||||
return NotFound("Unable to find resume");
|
||||
} else {
|
||||
if (isLoggedIn()) {
|
||||
int accountID = getLoggedInUserID();
|
||||
Resume[] resumes = await _databaseService.GetResumes(accountID);
|
||||
return Ok(resumes);
|
||||
}
|
||||
return NotFound("Not logged in");
|
||||
}
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
@@ -35,8 +36,9 @@ namespace BoredCareers.Controllers {
|
||||
await _databaseService.SetResume(resume);
|
||||
return Ok();
|
||||
}
|
||||
return NotFound("Resume doesn't exist or you are not the owner");
|
||||
}
|
||||
return NotFound();
|
||||
return NotFound("Not logged in");
|
||||
}
|
||||
|
||||
[HttpDelete]
|
||||
@@ -48,8 +50,9 @@ namespace BoredCareers.Controllers {
|
||||
await _databaseService.DeleteResume(ResumeID);
|
||||
return Ok();
|
||||
}
|
||||
return NotFound("Resume doesn't exist or you are not the owner");
|
||||
}
|
||||
return NotFound();
|
||||
return NotFound("Not logged in");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ namespace BoredCareers.Services.DatabaseService {
|
||||
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);
|
||||
(@ID,@UserName,@Email,@EmailVerified,@PasswordHash,@FailedPasswordLock,@PasswordAttempts,@CurrentPasswordAttempts,@Role,@EmailToken,@DataServer)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
UserName = @UserName,
|
||||
Email = @Email,
|
||||
@@ -120,7 +120,7 @@ namespace BoredCareers.Services.DatabaseService {
|
||||
PasswordAttempts = @PasswordAttempts,
|
||||
CurrentPasswordAttempts = @CurrentPasswordAttempts,
|
||||
Role = @Role,
|
||||
EmailToken = @EmailToken;
|
||||
EmailToken = @EmailToken,
|
||||
DataServer = @DataServer;
|
||||
";
|
||||
|
||||
|
||||
@@ -60,10 +60,10 @@ namespace BoredCareers.Services.DatabaseService {
|
||||
connection.Open();
|
||||
|
||||
string command = @"
|
||||
INSERT INTO Account
|
||||
INSERT INTO Company
|
||||
(ID,Name,Email,EmailVerified,WebsiteURL,LogoURL,Phone,PostalCode,Country,StateOrRegion,City,Description)
|
||||
VALUES
|
||||
(@ID,@Name,@Email,@EmailVerified,@WebsiteURL,@LogoURL,@Phone,@PostalCode,@Country,@StateOrRegion,@City,@Description);
|
||||
(@ID,@Name,@Email,@EmailVerified,@WebsiteURL,@LogoURL,@Phone,@PostalCode,@Country,@StateOrRegion,@City,@Description)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
Name = @Name,
|
||||
Email = @Email,
|
||||
@@ -73,7 +73,7 @@ namespace BoredCareers.Services.DatabaseService {
|
||||
Phone = @Phone,
|
||||
PostalCode = @PostalCode,
|
||||
Country = @Country,
|
||||
StateOrRegion = @StateOrRegion;
|
||||
StateOrRegion = @StateOrRegion,
|
||||
City = @City,
|
||||
Description = @Description;
|
||||
";
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace BoredCareers.Services.DatabaseService {
|
||||
INSERT INTO Employee
|
||||
(ID,AccountID,CompanyID)
|
||||
VALUES
|
||||
(@ID,@AccountID,@CompanyID);
|
||||
(@ID,@AccountID,@CompanyID)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
AccountID = @AccountID,
|
||||
CompanyID = @CompanyID;
|
||||
|
||||
@@ -127,7 +127,7 @@ namespace BoredCareers.Services.DatabaseService {
|
||||
INSERT INTO JobListing
|
||||
(ID,CompanyID,Title,PostalCode,Country,StateOrRegion,City,SalaryMin,SalaryMax,JobType,Remote,Description,CreatedTime,ModifiedTime,IsDeleted)
|
||||
VALUES
|
||||
(@ID,@CompanyID,@Title,@PostalCode,@Country,@StateOrRegion,@City,@SalaryMin,@SalaryMax,@JobType,@Remote,@Description,@CreatedTime,@ModifiedTime,@IsDeleted);
|
||||
(@ID,@CompanyID,@Title,@PostalCode,@Country,@StateOrRegion,@City,@SalaryMin,@SalaryMax,@JobType,@Remote,@Description,@CreatedTime,@ModifiedTime,@IsDeleted)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
CompanyID = @CompanyID,
|
||||
Title = @Title,
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace BoredCareers.Services.DatabaseService {
|
||||
INSERT INTO Resume
|
||||
(ID,AccountID,Name,Field,Email,PhoneNumber,PostalCode,Country,StateOrRegion,City,IsActive)
|
||||
VALUES
|
||||
(@ID,@AccountID,@Name,@Field,@Email,@PhoneNumber,@PostalCode,@Country,@StateOrRegion,@City,@IsActive);
|
||||
(@ID,@AccountID,@Name,@Field,@Email,@PhoneNumber,@PostalCode,@Country,@StateOrRegion,@City,@IsActive)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
AccountID = @AccountID,
|
||||
Name = @Name,
|
||||
@@ -45,7 +45,7 @@ namespace BoredCareers.Services.DatabaseService {
|
||||
INSERT INTO Resume
|
||||
(ID,ResumeID,ResumeExperienceID,JobFunction)
|
||||
VALUES
|
||||
(@ID,@ResumeID,@ResumeExperienceID,@JobFunction);
|
||||
(@ID,@ResumeID,@ResumeExperienceID,@JobFunction)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
ResumeID = @ResumeID,
|
||||
ResumeExperienceID = @ResumeExperienceID,
|
||||
@@ -68,7 +68,7 @@ namespace BoredCareers.Services.DatabaseService {
|
||||
INSERT INTO Resume
|
||||
(ID,ResumeID,JobTitle,Company,PostalCode,Country,StateOrRegion,City,DateStarted,StillEmployed,DateEnded)
|
||||
VALUES
|
||||
(@ID,@ResumeID,@JobTitle,@Company,@PostalCode,@Country,@StateOrRegion,@City,@DateStarted,@StillEmployed,@DateEnded);
|
||||
(@ID,@ResumeID,@JobTitle,@Company,@PostalCode,@Country,@StateOrRegion,@City,@DateStarted,@StillEmployed,@DateEnded)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
ResumeID = @ResumeID,
|
||||
JobTitle = @JobTitle,
|
||||
@@ -102,7 +102,7 @@ namespace BoredCareers.Services.DatabaseService {
|
||||
INSERT INTO Resume
|
||||
(ID,ResumeID,ResumeMilitaryID,Achievement)
|
||||
VALUES
|
||||
(@ID,@ResumeID,@ResumeMilitaryID,@Achievement);
|
||||
(@ID,@ResumeID,@ResumeMilitaryID,@Achievement)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
ResumeID = @ResumeID,
|
||||
ResumeMilitaryID = @ResumeMilitaryID,
|
||||
@@ -126,7 +126,7 @@ namespace BoredCareers.Services.DatabaseService {
|
||||
INSERT INTO Resume
|
||||
(ID,ResumeID,Country,Rank,DateStarted,StillServing,DateEnded)
|
||||
VALUES
|
||||
(@ID,@ResumeID,@Country,@Rank,@DateStarted,@StillServing,@DateEnded);
|
||||
(@ID,@ResumeID,@Country,@Rank,@DateStarted,@StillServing,@DateEnded)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
ResumeID = @ResumeID,
|
||||
Country = @Country,
|
||||
@@ -154,7 +154,7 @@ namespace BoredCareers.Services.DatabaseService {
|
||||
INSERT INTO Resume
|
||||
(ID,ResumeID,DegreeType,DegreeField,School,PostalCode,Country,StateOrRegion,City,DateStarted,StillStudying,DateEnded)
|
||||
VALUES
|
||||
(@ID,@ResumeID,@DegreeType,@DegreeField,@School,@PostalCode,@Country,@StateOrRegion,@City,@DateStarted,@StillStudying,@DateEnded);
|
||||
(@ID,@ResumeID,@DegreeType,@DegreeField,@School,@PostalCode,@Country,@StateOrRegion,@City,@DateStarted,@StillStudying,@DateEnded)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
ResumeID = @ResumeID,
|
||||
DegreeType = @DegreeType,
|
||||
@@ -193,7 +193,7 @@ namespace BoredCareers.Services.DatabaseService {
|
||||
INSERT INTO Resume
|
||||
(ID,ResumeID,Name,Description)
|
||||
VALUES
|
||||
(@ID,@ResumeID,@Name,@Description);
|
||||
(@ID,@ResumeID,@Name,@Description)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
ResumeID = @ResumeID,
|
||||
Name = @Name,
|
||||
@@ -216,7 +216,7 @@ namespace BoredCareers.Services.DatabaseService {
|
||||
INSERT INTO Resume
|
||||
(ID,ResumeID,Language,Proficiency)
|
||||
VALUES
|
||||
(@ID,@ResumeID,@Language,@Proficiency);
|
||||
(@ID,@ResumeID,@Language,@Proficiency)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
ResumeID = @ResumeID,
|
||||
Language = @Language,
|
||||
@@ -239,7 +239,7 @@ namespace BoredCareers.Services.DatabaseService {
|
||||
INSERT INTO Resume
|
||||
(ID,ResumeID,Name,VerificationURL,Description)
|
||||
VALUES
|
||||
(@ID,@ResumeID,@Name,@VerificationURL,@Description);
|
||||
(@ID,@ResumeID,@Name,@VerificationURL,@Description)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
ResumeID = @ResumeID,
|
||||
Name = @DegreeNameType,
|
||||
@@ -264,7 +264,7 @@ namespace BoredCareers.Services.DatabaseService {
|
||||
INSERT INTO Resume
|
||||
(ID,ResumeID,Name,URL,Description)
|
||||
VALUES
|
||||
(@ID,@ResumeID,@Name,@URL,@Description);
|
||||
(@ID,@ResumeID,@Name,@URL,@Description)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
ResumeID = @ResumeID,
|
||||
Name = @Name,
|
||||
|
||||
Reference in New Issue
Block a user