diff --git a/ToDo.yaml b/ToDo.yaml index 3f213f4..75ac676 100755 --- a/ToDo.yaml +++ b/ToDo.yaml @@ -17,16 +17,14 @@ Server: JobCleanupService: Need to update notification email + CompanyEmailVerify: + Need to update notification email + Client: - jobs/new: + jobs/editor: Job Listing Skills exists but isn't implimented in the UI Tab doesnt do anything Want to add completed job listing preview at end of carosel - Edit employees not implimented yet - - Jobs/editor: - Jobs/editor w/ Querystring JobID=# is not implimented yet - Edit employees not implimented yet Resume: Resume builder minimal user input [ Dont allow AI input ] @@ -38,9 +36,17 @@ Client: Allow users to look up jobs and apply [ Boost visibility | Completely manual ] Mark ghost listings to allow users to be informed and put companies on blast - CompanyConnect: - need to lookup company before making a new one - + company/editor: + Need to lookup company before making a new one + Tab key does nothing + Format phone number for database + Check DataType's for email and phone. + Setup QueryParam's for Edit and New + Edit employees not implimented yet + + Company: + No employees for table yet + database: Add Applied Jobs Table \ No newline at end of file diff --git a/database/mistox.sql b/database/mistox.sql index 72c979b..bcf7be0 100755 --- a/database/mistox.sql +++ b/database/mistox.sql @@ -129,6 +129,7 @@ CREATE TABLE IF NOT EXISTS `Company` ( `Name` varchar(100) DEFAULT NULL, `Email` varchar(255) DEFAULT NULL, `EmailVerified` boolean DEFAULT 0, + `EmailToken` char(36) DEFAULT NULL, `WebsiteURL` varchar(255) DEFAULT NULL, `Logo` mediumblob DEFAULT NULL, `JobsClosedSuccessful` int DEFAULT 0, diff --git a/src/Client/src/app/app.html b/src/Client/src/app/app.html index 369369b..c02f3a9 100644 --- a/src/Client/src/app/app.html +++ b/src/Client/src/app/app.html @@ -1,8 +1,8 @@
- JOB BOARD - RESUMES - COMPANIES + JOB BOARD + RESUMES + COMPANIES
- + +

{{ Comp.name }}

+ +
+
+

{{ Comp.city }}, {{ Comp.stateOrRegion }} {{ Comp.postalCode }}

+
+
+

{{ line }}

+
+
+ +
+
+ + You must verify your company email before you can post job listings. +
+
+
+
+

Active Job Listings

+
+
+

{{ listing.title }}

+
+ + + +
+
+
+

Employees

+ +
-

{{ Comp.emailVerified }}

- -

{{ Comp.phone }}

-

{{ Comp.postalCode }}

-

{{ Comp.country }}

-

{{ Comp.stateOrRegion }}

-

{{ Comp.city }}

-

{{ Comp.description }}

-
\ No newline at end of file diff --git a/src/Client/src/app/pages/main/company/company.component.ts b/src/Client/src/app/pages/main/company/company.component.ts index dc8ee16..015c90d 100644 --- a/src/Client/src/app/pages/main/company/company.component.ts +++ b/src/Client/src/app/pages/main/company/company.component.ts @@ -6,6 +6,7 @@ import { Title } from '@angular/platform-browser'; import { CommonModule } from '@angular/common'; import { Authentication } from 'app/services/Authentication'; import { Company, Employee } from 'app/models/Company'; +import { JobListing } from 'app/models/JobListing'; @Component({ selector: 'main-company', @@ -17,13 +18,22 @@ export class CompanyComponent { public ErrorMsg: string = ""; public Employers: Employee[] = []; + public Comp: Company | null = null; + public Desc: string[] = []; + + public List: JobListing[] = []; constructor( private http: HttpClient, private router: Router, private route: ActivatedRoute, private title: Title, public auth: Authentication ) { this.title.setTitle("Companies | BoredCareers"); http.get("api/employee/").subscribe({ next: data => { this.Employers = data; + if (data[0] != null){ + if (data[0].company.id !== null){ + this.changeSelectedCompany(data[0].company.id); + } + } }, error: err => { this.ErrorMsg = err.error; @@ -36,6 +46,27 @@ export class CompanyComponent { this.http.get("api/company?CompanyID=" + companyID).subscribe({ next: data => { this.Comp = data; + this.Desc = data.description.split("\n"); + }, + error: err => { + this.ErrorMsg = err.error; + } + }); + + this.http.get("api/joblisting/company?CompanyID=" + companyID).subscribe({ + next: data => { + this.List = 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 => { this.ErrorMsg = err.error; diff --git a/src/Client/src/app/pages/main/company/connect/companyconnect.component.css b/src/Client/src/app/pages/main/company/editor/editor.component.css similarity index 100% rename from src/Client/src/app/pages/main/company/connect/companyconnect.component.css rename to src/Client/src/app/pages/main/company/editor/editor.component.css diff --git a/src/Client/src/app/pages/main/company/connect/companyconnect.component.html b/src/Client/src/app/pages/main/company/editor/editor.component.html similarity index 100% rename from src/Client/src/app/pages/main/company/connect/companyconnect.component.html rename to src/Client/src/app/pages/main/company/editor/editor.component.html diff --git a/src/Client/src/app/pages/main/company/connect/companyconnect.component.ts b/src/Client/src/app/pages/main/company/editor/editor.component.ts similarity index 92% rename from src/Client/src/app/pages/main/company/connect/companyconnect.component.ts rename to src/Client/src/app/pages/main/company/editor/editor.component.ts index 11be3da..3c21b7c 100644 --- a/src/Client/src/app/pages/main/company/connect/companyconnect.component.ts +++ b/src/Client/src/app/pages/main/company/editor/editor.component.ts @@ -8,12 +8,12 @@ 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' ], + selector: 'main-company-editor', + templateUrl: './editor.component.html', + styleUrls: [ './editor.component.css' ], imports: [ FormsModule, CommonModule, RouterModule ] }) -export class CompanyConnectComponent { +export class CompanyEditorComponent { @ViewChildren('step') formSteps!: QueryList>; currentStep: number = 0; @@ -23,7 +23,10 @@ export class CompanyConnectComponent { MaxFileMB: number = 3; constructor( private http: HttpClient, private router: Router, private route: ActivatedRoute, private title: Title, public auth: Authentication ) { - this.title.setTitle("Company - Connect | BoredCareers"); + this.title.setTitle("Company - Editor | BoredCareers"); + + // Query param CompanyID -> Edit + // Query param null -> New }; ngAfterViewInit(){ @@ -35,7 +38,7 @@ export class CompanyConnectComponent { @HostListener('window:keydown', ['$event']) handleGlobalKeyDown(event: KeyboardEvent){ - if (event.key === 'Tab'){ + if ( event.key === 'Tab' ){ event.preventDefault(); } } diff --git a/src/Client/src/app/pages/main/company/jobs/jobs.component.css b/src/Client/src/app/pages/main/company/jobs/jobs.component.css deleted file mode 100644 index 6044df9..0000000 --- a/src/Client/src/app/pages/main/company/jobs/jobs.component.css +++ /dev/null @@ -1,87 +0,0 @@ -button { - width: 150px; - border-radius: 5px; - margin: 10px; - text-align: center; - padding: 15px 0; - transition: .5s; - background-color: #0000; - border: 1px solid var(--Mistox-White); - color: var(--Mistox-White); - text-decoration: none; -} - - button:hover { - background-color: #00000044; - color: var(--Mistox-Light); - } - -.full-width { - display: block; - width: 100%; - column-count: 2; -} - -.tile-frame { - display: grid; - grid-template-columns: repeat(4, 1fr); - column-gap: 20px; - padding: 20px; - width: calc(100% - 40px); -} - -.tile{ - background-color: var(--Mistox-Dark); - color: var(--Mistox-White); - break-inside: avoid; - padding: 20px; - border-radius: 20px; - margin-bottom: 20px; -} - -.jobs-frame { - width: 100%; - background-color: #8888; - border-top: 2px solid black; -} - -.post-job-frame { - display: flex; - justify-content: center; - padding: 10px 0; -} - -.tile-title { - text-align: center; - border-bottom: 1px solid; -} - -.tile-title h1 { - font-size: 40px; - margin: 5px 0; -} - -.tile-title h2 { - font-size: 14px; -} - -.tile-split { - columns: 2; - text-align: center; - padding: 10px 0; -} - -.tile-split h1 { - margin: 0; -} - -.tile-button { - display: flex; - width: 100%; - justify-content: center; -} - -.post-job-frame button { - border-color: var(--Mistox-Black); - color: var(--Mistox-Black); -} \ No newline at end of file diff --git a/src/Client/src/app/pages/main/company/jobs/jobs.component.html b/src/Client/src/app/pages/main/company/jobs/jobs.component.html deleted file mode 100644 index db11b14..0000000 --- a/src/Client/src/app/pages/main/company/jobs/jobs.component.html +++ /dev/null @@ -1,23 +0,0 @@ -
- -
- -
-
-
-

{{ cur.title }}

-

{{ cur.jobType }}

-

Is Remote: {{ cur.remote }}

-

{{ cur.salaryMin }}

-

{{ cur.salaryMax }}

-

{{ cur.city }}

-

{{ cur.stateOrRegion }}

-

{{ cur.country }}

-

{{ cur.postalCode }}

-

Posted: {{ cur.createdTime }}

-

Modified: {{ cur.modifiedTime }}

-
- - -
-
\ No newline at end of file diff --git a/src/Client/src/app/pages/main/company/jobs/jobs.component.ts b/src/Client/src/app/pages/main/company/jobs/jobs.component.ts deleted file mode 100644 index d81f192..0000000 --- a/src/Client/src/app/pages/main/company/jobs/jobs.component.ts +++ /dev/null @@ -1,52 +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 { JobListing } from 'app/models/JobListing'; -import { Authentication } from 'app/services/Authentication'; - -@Component({ - selector: 'main-company-jobs', - templateUrl: './jobs.component.html', - styleUrls: [ './jobs.component.css' ], - imports: [ FormsModule, CommonModule, RouterModule ] -}) -export class CompanyJobsComponent { - - public MyJobListings: JobListing[] = []; - public ErrorMsg: string = ""; - - constructor( private http: HttpClient, private router: Router, private route: ActivatedRoute, private title: Title, public auth: Authentication ) { - this.title.setTitle("Company - Jobs | BoredCareers"); - - this.route.queryParams.subscribe(params => { - const companyID = params['CompanyID']; - if (companyID){ - http.get("api/joblisting/company?CompanyID=" + companyID).subscribe({ - next: data => { - this.MyJobListings = data; - }, - error: err => { - this.ErrorMsg = err.error; - } - }); - }else{ - router.navigate(["/company"]); - } - }); - }; - - RemoveJobListing( JobListingID: number ){ - this.http.delete("api/joblisting?JobListingID=" + JobListingID).subscribe({ - next: data => { - window.location.reload(); - }, - error: err => { - this.ErrorMsg = err.error; - } - }); - } - -} \ No newline at end of file diff --git a/src/Client/src/app/pages/main/jobs/editor/jobeditor.component.html b/src/Client/src/app/pages/main/jobs/editor/jobeditor.component.html index c519c73..e60b47f 100644 --- a/src/Client/src/app/pages/main/jobs/editor/jobeditor.component.html +++ b/src/Client/src/app/pages/main/jobs/editor/jobeditor.component.html @@ -1,33 +1,14 @@

POST A NEW JOB

-
- - -
-
-
- - - -
- -
-
+
- +
@@ -40,7 +21,7 @@
- @@ -50,7 +31,7 @@
- +
@@ -59,28 +40,28 @@
-
+

Job Location

- +
- +
- +
- +
@@ -96,11 +77,11 @@
- +
- +
@@ -113,7 +94,7 @@
- +
diff --git a/src/Client/src/app/pages/main/jobs/editor/jobeditor.component.ts b/src/Client/src/app/pages/main/jobs/editor/jobeditor.component.ts index 63b61bc..b5522dc 100644 --- a/src/Client/src/app/pages/main/jobs/editor/jobeditor.component.ts +++ b/src/Client/src/app/pages/main/jobs/editor/jobeditor.component.ts @@ -15,31 +15,46 @@ import { Company, Employee } from 'app/models/Company'; imports: [ FormsModule, CommonModule, RouterModule ] }) export class JobEditorComponent { + public ErrorMsg: string = ""; @ViewChildren('step') formSteps!: QueryList>; currentStep: number = 0; - public employeeOfList: Employee[] = []; - public selectedCompany: Company = new Company; + public Listing: JobListing = new JobListing(); - public newListing: JobListing = new JobListing(); - public ErrorMsg: string = ""; + public mode: string = ""; + public modeID: number = 0; constructor( private http: HttpClient, private router: Router, private route: ActivatedRoute, private title: Title, public auth: Authentication ) { this.title.setTitle("Jobs - Editor | BoredCareers"); - this.http.get("api/employee").subscribe({ - next: empOf => { - if (empOf.length === 0){ - router.navigate(["company/connect"]); - } - this.employeeOfList = empOf; - }, - error: err => { - this.ErrorMsg = err.error; + this.route.queryParams.subscribe(params => { + const CompanyID = params['CompanyID'] ? +params['CompanyID'] : null; + const JobID = params['JobID'] ? +params['JobID'] : null; + if (CompanyID !== null && JobID !== null){ + this.router.navigate([""]); + }else if (CompanyID !== null ){ + this.mode = "new"; + this.modeID = CompanyID; + }else if(JobID !== null){ + this.mode = "edit"; + this.modeID = JobID; + }else if (CompanyID === null && JobID === null){ + this.router.navigate([""]); + } + + if (this.mode === "edit") { + this.http.get("api/joblisting/" + JobID).subscribe({ + next: data => { + this.Listing = data; + }, + error: err => { + this.ErrorMsg = err.error; + } + }); } }); - }; + } ngAfterViewInit(){ this.formSteps.changes.subscribe(() => { @@ -70,8 +85,8 @@ export class JobEditorComponent { this.updateUI(); } - PostJobListing(jobListing: JobListing){ - jobListing.companyID = this.selectedCompany.id!; + PostNewJob(jobListing: JobListing){ + jobListing.companyID = this.modeID; this.http.post("api/joblisting", jobListing).subscribe({ next: data => { this.router.navigate([""]); @@ -82,4 +97,23 @@ export class JobEditorComponent { }); } + PostEditJob(jobListing: JobListing){ + this.http.post("api/joblisting", jobListing).subscribe({ + next: data => { + this.router.navigate([""]); + }, + error: err => { + this.ErrorMsg = err.error; + } + }); + } + + SubmitForm(job: JobListing){ + if (this.mode === "new"){ + this.PostNewJob(job); + }else if (this.mode === "edit"){ + this.PostEditJob(job); + } + } + } \ No newline at end of file diff --git a/src/Client/src/app/pages/main/jobs/jobs.component.html b/src/Client/src/app/pages/main/jobs/jobs.component.html index f6bdacc..a92934d 100644 --- a/src/Client/src/app/pages/main/jobs/jobs.component.html +++ b/src/Client/src/app/pages/main/jobs/jobs.component.html @@ -3,7 +3,7 @@

{{ cur.title }}

-

${{ cur.salaryMax }} - ${{ cur.salaryMin }}

+

${{ cur.salaryMin }} - ${{ cur.salaryMax }}

{{ cur.jobType }}

diff --git a/src/Client/src/app/pages/main/jobs/viewer/jobviewer.component.css b/src/Client/src/app/pages/main/jobs/viewer/jobviewer.component.css index c357862..e9653e1 100644 --- a/src/Client/src/app/pages/main/jobs/viewer/jobviewer.component.css +++ b/src/Client/src/app/pages/main/jobs/viewer/jobviewer.component.css @@ -1,11 +1,91 @@ -.job-frame { - +.company-details { + background-color: #5c3030; } -.job-warning { +.company-details::after { + content: ""; + display: block; + height: 50px; + clear: both; +} +.content-frame { + background-color: #3c3c3c; + width: calc(100% - 40px); + height: calc(100vh - 400px); + border-radius: 20px; + margin: 10px; + overflow: scroll; + padding: 10px; + color: var(--Mistox-White); +} + +.center-item { + display: flex; + width: 100%; + justify-content: center; +} + +.content-edit { + position: absolute; + right: 20px; +} + +.center-item img { + width: 300px; +} + +.content-name { + width: 300px; + text-align: center; + font-size: 30px; +} + +.content-name h1 { + margin: 0; +} + +.content-link { + display: flex; + width: 300px; + justify-content: center; +} + +.content-link a { + text-decoration: none; + color: var(--Mistox-White); + margin-top: auto; +} + +.content-desc { + border: solid 1px red; + border-radius: 5px; + padding: 20px; + margin: 0 100px; +} + +.content-desc h1 { + margin: 0; + font-size: 20px; +} + +.content-button { + display: flex; + justify-content: center; +} + +.content-button span { + align-content: center; } .job-details { - + background-color: #3c3c3c; +} + +.job-timestamp { + width: 100%; +} + +.job-timestamp h1 { + margin: 0; } \ No newline at end of file diff --git a/src/Client/src/app/pages/main/jobs/viewer/jobviewer.component.html b/src/Client/src/app/pages/main/jobs/viewer/jobviewer.component.html index 23243a9..3da246a 100644 --- a/src/Client/src/app/pages/main/jobs/viewer/jobviewer.component.html +++ b/src/Client/src/app/pages/main/jobs/viewer/jobviewer.component.html @@ -1,21 +1,27 @@
-

{{ jobsCompany.name }}

- -

{{ jobsCompany.email }}

-

{{ jobsCompany.websiteURL }}

- -

{{ jobsCompany.logo }}

-

{{ jobsCompany.phone }}

- -

{{ jobsCompany.city }}

-

{{ jobsCompany.stateOrRegion }}

-

{{ jobsCompany.country }}

-

{{ jobsCompany.postalCode }}

- -

{{ jobsCompany.description }}

-
+
+ + + +
+
+ +

{{ jobsCompany.name }}

+ +
+
+

{{ jobsCompany.city }}, {{ jobsCompany.stateOrRegion }} {{ jobsCompany.postalCode }}

+
+
+

{{ line }}

+
+
+
+

Opened: {{ selectedJob.createdTime }}

+

Modified: {{ selectedJob.modifiedTime }}

+

THIS JOB POSTING IS CLOSED

@@ -35,8 +41,5 @@

{{ selectedJob.postalCode }}

{{ selectedJob.description }}

- -

{{ selectedJob.createdTime }}

-

{{ selectedJob.modifiedTime }}

\ No newline at end of file diff --git a/src/Server/Controllers/CompanyController.cs b/src/Server/Controllers/CompanyController.cs index c546bf8..d27bb70 100644 --- a/src/Server/Controllers/CompanyController.cs +++ b/src/Server/Controllers/CompanyController.cs @@ -2,19 +2,25 @@ using Microsoft.AspNetCore.Mvc; using BoredCareers.Services.DatabaseService; using BoredCareers.Entities; using System.Web.Http; +using BoredCareers.Services; namespace BoredCareers.Controllers { [ApiController] [Route("api/company")] public class CompanyController : MistoxControllerBase { - public CompanyController(DatabaseService db) : base(db) {} + EmailService _emailContext; + + public CompanyController(DatabaseService db, EmailService emailContext) : base(db) { + _emailContext = emailContext; + } [HttpGet] public async Task GetCompany(int CompanyID) { if (isLoggedIn()) { Company? company = await _databaseService.GetCompany(CompanyID); if (company != null) { + company.EmailToken = ""; return Ok(company); } return NotFound("Company doesn't exist"); @@ -59,6 +65,57 @@ namespace BoredCareers.Controllers { return NotFound("Not logged in"); } - } + [HttpGet("sendverifyemail")] + public async Task> SendVerify([FromQuery] int CompanyID) { + try { + string key = "v" + CompanyID; + // Stop from sending multiple emails quickly + if (_emailContext._SentEmails.ContainsKey(key)) { + DateTime PreviousSentTime = _emailContext._SentEmails.GetValueOrDefault(key); + if (PreviousSentTime.AddMinutes(5) > DateTime.Now) { + return NotFound("Cannot sent another verify email until 5 minutes has elapsed"); + } else { + _emailContext._SentEmails.Remove(key); + } + } + Company? test = await _databaseService.GetCompany(CompanyID); + if (test != null) { + test.EmailToken = Guid.NewGuid().ToString(); + await _databaseService.SetCompany(test); + string EmailContents = EmailService.CompanyVerifyEmailSubject; + EmailContents = Substitue(EmailContents, "@CompanyName", test.Name); + EmailContents = Substitue(EmailContents, "@ID", CompanyID.ToString()); + EmailContents = Substitue(EmailContents, "@VerifyPassword", test.EmailToken); + + string result = _emailContext.Send(test.Email, EmailService.CompanyVerifyEmailSubject, EmailContents); + _emailContext._SentEmails.Add(key, DateTime.Now); + return Redirect("/"); + } + return NotFound("Account not found"); + } catch (Exception) { + return NotFound("An internal server error has occured"); + } + } + + [HttpGet("verifyemail")] + public async Task> VerifyEmail([FromQuery] int CompanyID, [FromQuery] string EmailToken) { + try { + Company? test = await _databaseService.GetCompany(CompanyID); + if (test != null) { + if (test.EmailToken == EmailToken) { + test.EmailToken = ""; + test.EmailVerified = true; + await _databaseService.SetCompany(test); + return Redirect("/"); + } + return BadRequest("The token isn't valid"); + } + return BadRequest("Account not found"); ; + } catch { + return BadRequest("An internal server error has occured"); + } + } + + } } diff --git a/src/Server/Entities/Company.cs b/src/Server/Entities/Company.cs index c6fbcb8..f30d2e1 100644 --- a/src/Server/Entities/Company.cs +++ b/src/Server/Entities/Company.cs @@ -5,6 +5,7 @@ namespace BoredCareers.Entities { public string Name { get; set; } = ""; public string Email { get; set; } = ""; public bool EmailVerified { get; set; } = false; + public string EmailToken { get; set; } = ""; public string WebsiteURL { get; set; } = ""; public string Logo { get; set; } = ""; public int JobsClosedSuccessful { get; set; } diff --git a/src/Server/Services/BackgroundServices/JobCleanupService.cs b/src/Server/Services/BackgroundServices/JobCleanupService.cs index fbd30fb..d943280 100644 --- a/src/Server/Services/BackgroundServices/JobCleanupService.cs +++ b/src/Server/Services/BackgroundServices/JobCleanupService.cs @@ -11,6 +11,17 @@ namespace BoredCareers.Services.TimerService { _em = em; } + public string Substitue(string message, string subString, string Replacement) { + for (int i = 0; i < (message.Length - subString.Length); i++) { + if (message.Substring(i, subString.Length) == subString) { + string before = message.Substring(0, i); + string after = message.Substring(i + subString.Length); + return before + Replacement + after; + } + } + return message; + } + protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { try { @@ -37,7 +48,10 @@ namespace BoredCareers.Services.TimerService { string[] emails = await _db.GetApplicationResponseEmailFromJobListing(listing.JobListingID); foreach (string email in emails) { // Send Notify Email - _em.Send(email, EmailService.JobAutoClosedSubject, EmailService.JobAutoClosedEmail); + string emailbody = EmailService.JobAutoClosedBody; + //Substitue(emailbody, "@job", listing.JobListingID); + + _em.Send(email, EmailService.JobAutoClosedSubject, emailbody); } } diff --git a/src/Server/Services/DatabaseService/Company.cs b/src/Server/Services/DatabaseService/Company.cs index 5aaad81..5e6d334 100644 --- a/src/Server/Services/DatabaseService/Company.cs +++ b/src/Server/Services/DatabaseService/Company.cs @@ -26,6 +26,7 @@ namespace BoredCareers.Services.DatabaseService { string _name = reader.GetString("Name"); string _email = reader.GetString("Email"); bool _emailVerified = reader.GetBoolean("EmailVerified"); + string _emailtoken = reader.GetString("EmailToken"); string _websiteurl = reader.GetString("WebsiteURL"); string _logo = Encoding.UTF8.GetString((byte[])reader["Logo"]); int _jobsclosedsuccessful = reader.GetInt32("JobsClosedSuccessful"); @@ -42,6 +43,7 @@ namespace BoredCareers.Services.DatabaseService { Name = _name, Email = _email, EmailVerified = _emailVerified, + EmailToken = _emailtoken, WebsiteURL = _websiteurl, Logo = _logo, JobsAutoClosed = _jobsautoclosed, @@ -64,13 +66,14 @@ namespace BoredCareers.Services.DatabaseService { await connection.OpenAsync(); string command = @" INSERT INTO Company - (ID,Name,Email,EmailVerified,WebsiteURL,Logo,JobsClosedSuccessful,JobsAutoClosed,Phone,PostalCode,Country,StateOrRegion,City,Description) + (ID,Name,Email,EmailVerified,EmailToken,WebsiteURL,Logo,JobsClosedSuccessful,JobsAutoClosed,Phone,PostalCode,Country,StateOrRegion,City,Description) VALUES - (@ID,@Name,@Email,@EmailVerified,@WebsiteURL,@Logo,@JobsClosedSuccessful,@JobsAutoClosed,@Phone,@PostalCode,@Country,@StateOrRegion,@City,@Description) + (@ID,@Name,@Email,@EmailVerified,@EmailToken,@WebsiteURL,@Logo,@JobsClosedSuccessful,@JobsAutoClosed,@Phone,@PostalCode,@Country,@StateOrRegion,@City,@Description) ON DUPLICATE KEY UPDATE Name = @Name, Email = @Email, EmailVerified = @EmailVerified, + EmailToken = @EmailToken, WebsiteURL = @WebsiteURL, Logo = @Logo, JobsClosedSuccessful = @JobsClosedSuccessful, @@ -90,6 +93,7 @@ namespace BoredCareers.Services.DatabaseService { cmd.Parameters.AddWithValue("@Name", company.Name); cmd.Parameters.AddWithValue("@Email", company.Email); cmd.Parameters.AddWithValue("@EmailVerified", company.EmailVerified); + cmd.Parameters.AddWithValue("@EmailToken", company.EmailToken); cmd.Parameters.AddWithValue("@WebsiteURL", company.WebsiteURL); cmd.Parameters.AddWithValue("@Logo", Encoding.UTF8.GetBytes(company.Logo)); cmd.Parameters.AddWithValue("@JobsClosedSuccessful", company.JobsClosedSuccessful); diff --git a/src/Server/Services/DatabaseService/JobListing.cs b/src/Server/Services/DatabaseService/JobListing.cs index 18fa04a..f23b28a 100644 --- a/src/Server/Services/DatabaseService/JobListing.cs +++ b/src/Server/Services/DatabaseService/JobListing.cs @@ -73,7 +73,8 @@ namespace BoredCareers.Services.DatabaseService { string command = @" SELECT * FROM JobListing - WHERE CompanyID = @CompanyID; + WHERE IsDeleted = FALSE + AND CompanyID = @CompanyID; "; MySqlCommand cmd = new MySqlCommand(command, connection); diff --git a/src/Server/Services/EmailService/CompanyVerifyEmail.cs b/src/Server/Services/EmailService/CompanyVerifyEmail.cs new file mode 100755 index 0000000..ccaecca --- /dev/null +++ b/src/Server/Services/EmailService/CompanyVerifyEmail.cs @@ -0,0 +1,52 @@ +namespace BoredCareers.Services { + public partial class EmailService { + +// @UserName +// @VerifyPassword +// https://mistox.com/api/account/verifyemail?UserName=@UserName&Guid=@VerifyPassword + + public static string CompanyVerifyEmailSubject = "Verify Your Email Address"; + public static string CompanyVerifyEmailBody = @" + + + + + + Verify Your Email + + + + + + +
+ + + + + + + + + + +
+

Verify Email Request

+
+

Hi @CompanyName,

+

Thank you for making an account with us:

+

In order to start using your account we need to verify your email address by clicking the link below:

+

+ Verify Email +

+

If you didn't create an account please ignore this email.

+

Best regards

+
+

If you have any questions, feel free to contact support.

+
+
+ +"; + + } +} \ No newline at end of file diff --git a/src/Server/Services/EmailService/JobAutoCloseEmail.cs b/src/Server/Services/EmailService/JobAutoCloseEmail.cs index a1055f3..00aeb87 100755 --- a/src/Server/Services/EmailService/JobAutoCloseEmail.cs +++ b/src/Server/Services/EmailService/JobAutoCloseEmail.cs @@ -6,7 +6,7 @@ namespace BoredCareers.Services { // https://mistox.com/api/account/verifyemail?UserName=@UserName&Guid=@VerifyPassword public static string JobAutoClosedSubject = "Verify Your Email Address"; - public static string JobAutoClosedEmail = @" + public static string JobAutoClosedBody = @"