Start work on filtering logic

This commit is contained in:
2025-09-02 22:31:05 -07:00
parent 72fb4f2536
commit 73c1e1ce98
10 changed files with 230 additions and 83 deletions
+11
View File
@@ -0,0 +1,11 @@
export class JobFilter {
public JobsPerPage: number = 20;
public CurrentPage: number = 1;
public CountryCode: string | null = null;
public PostalCode: string | null = null;
public Distance: number | null = null;
public JobType: string | null = null;
public Remote: boolean | null = null;
public SalaryMin: number | null = null;
public SalaryMax: number | null = null;
}
@@ -1,3 +1,35 @@
<!-- Filter Bar -->
<div>
<div>
<h1>Country</h1>
<input name="CountryCode" [(ngModel)]="currentFilter.CountryCode" (ngModelChange)="reloadFilters()" type="text" />
</div>
<div>
<h1>Postal Code</h1>
<input name="PostalCode" [(ngModel)]="currentFilter.PostalCode" (ngModelChange)="reloadFilters()" type="text" />
</div>
<div>
<h1>Distance</h1>
<input name="Distance" [(ngModel)]="currentFilter.Distance" (ngModelChange)="reloadFilters()" type="number" />
</div>
<div>
<h1>Job Type</h1>
<input name="CountryCode" [(ngModel)]="currentFilter.JobType" (ngModelChange)="reloadFilters()" type="text" />
</div>
<div>
<h1>Remote</h1>
<input name="Remote" [(ngModel)]="currentFilter.Remote" (ngModelChange)="reloadFilters()" type="checkbox" />
</div>
<div>
<h1>Minimum Salary</h1>
<input name="SalaryMin" [(ngModel)]="currentFilter.SalaryMin" (ngModelChange)="reloadFilters()" type="number" />
</div>
<div>
<h1>Maximum Salary</h1>
<input name="SalaryMax" [(ngModel)]="currentFilter.SalaryMax" (ngModelChange)="reloadFilters()" type="number" />
</div>
</div>
<!-- Avaliable Jobs -->
<div class="tile-frame">
@for (cur of JobListingPage; track cur.id){
@@ -21,4 +53,8 @@
</div>
</div>
}
<div>
<h1>Jobs Per Page</h1>
<input name="JobsPerPage" [(ngModel)]="currentFilter.JobsPerPage" (ngModelChange)="reloadFilters()" type="number" />
</div>
</div>
@@ -6,6 +6,7 @@ import { Title } from '@angular/platform-browser';
import { CommonModule } from '@angular/common';
import { JobListing } from 'app/models/JobListing';
import { Authentication } from 'app/services/Authentication';
import { JobFilter } from 'app/models/JobFilter';
@Component({
selector: 'main-jobs',
@@ -15,7 +16,7 @@ import { Authentication } from 'app/services/Authentication';
})
export class JobsComponent {
public MyJobListings: JobListing[] = [];
public currentFilter: JobFilter;
public JobListingPage: JobListing[] = [];
public ErrorMsg: string = "";
@@ -23,10 +24,46 @@ export class JobsComponent {
constructor( private http: HttpClient, private router: Router, private route: ActivatedRoute, private title: Title, public auth: Authentication ) {
this.title.setTitle("Jobs | BoredCareers");
this.currentFilter = new JobFilter();
};
ngOnInit(){
this.http.get<JobListing[]>("api/joblisting?PageQuantity=" + 10 + "&Page=" + 1).subscribe({
this.http.get<JobListing[]>("api/joblisting?PageQuantity=" + this.currentFilter.JobsPerPage + "&Page=" + this.currentFilter.CurrentPage).subscribe({
next: data => {
this.JobListingPage = data;
},
error: err => {
this.ErrorMsg = err.error;
}
});
}
reloadFilters(){
var queryBuilder = "api/joblisting?PageQuantity=" + this.currentFilter.JobsPerPage + "&Page=" + this.currentFilter.CurrentPage;
if (this.currentFilter.PostalCode != null){
queryBuilder += "&PC=" + this.currentFilter.PostalCode;
}
if (this.currentFilter.CountryCode != null){
queryBuilder += "&CC=" + this.currentFilter.CountryCode;
}
if (this.currentFilter.Distance != null){
queryBuilder += "&D=" + this.currentFilter.Distance;
}
if (this.currentFilter.JobType != null){
queryBuilder += "&JT=" + this.currentFilter.JobType;
}
if (this.currentFilter.Remote != null){
queryBuilder += "&R=" + this.currentFilter.Remote;
}
if (this.currentFilter.SalaryMin != null){
queryBuilder += "&SMI=" + this.currentFilter.SalaryMin;
}
if (this.currentFilter.SalaryMax != null){
queryBuilder += "&SMA=" + this.currentFilter.SalaryMax;
}
this.http.get<JobListing[]>(queryBuilder).subscribe({
next: data => {
this.JobListingPage = data;
},
+25 -10
View File
@@ -74,16 +74,31 @@ export class Validation {
///////// HELPER FUNCTIONS /////////
isPrivateIPv6(ip: string): boolean {
try {
const normalized = ip.replace(/^\[|\]$/g, '').toLowerCase();
if (normalized === '::1') return true;
if (normalized.startsWith('fc') || normalized.startsWith('fd')) return true;
const first4 = normalized.slice(0, 4);
if (first4 >= 'fe80' && first4 <= 'febf') return true;
return false;
} catch {
return true;
try {
const normalized = ip.replace(/^\[|\]$/g, '').toLowerCase();
if (normalized === '::1') return true;
if (normalized.startsWith('fc') || normalized.startsWith('fd')) return true;
const first4 = normalized.slice(0, 4);
if (first4 >= 'fe80' && first4 <= 'febf') return true;
return false;
} catch {
return true;
}
}
///////// GETTERS /////////
get ValidCountries(): string[] {
return ['AD', 'AE', 'AI', 'AL', 'AR', 'AS', 'AT', 'AU', 'AX', 'AZ', 'BD', 'BE', 'BG',
'BM', 'BR', 'BY', 'CA', 'CC', 'CH', 'CL', 'CN', 'CO', 'CR', 'CX', 'CY', 'CZ',
'DE', 'DK', 'DO', 'DZ', 'EC', 'EE', 'ES', 'FI', 'FK', 'FM', 'FO', 'FR', 'GB',
'GF', 'GG', 'GI', 'GL', 'GP', 'GS', 'GT', 'GU', 'HK', 'HM', 'HN', 'HR', 'HT',
'HU', 'ID', 'IE', 'IM', 'IN', 'IO', 'IS', 'IT', 'JE', 'JP', 'KE', 'KR', 'LI',
'LK', 'LT', 'LU', 'LV', 'MA', 'MC', 'MD', 'MH', 'MK', 'MO', 'MP', 'MQ', 'MT',
'MW', 'MX', 'MY', 'NC', 'NF', 'NL', 'NO', 'NR', 'NU', 'NZ', 'PA', 'PE', 'PF',
'PH', 'PK', 'PL', 'PM', 'PN', 'PR', 'PT', 'PW', 'RE', 'RO', 'RS', 'RU', 'SE',
'SG', 'SI', 'SJ', 'SK', 'SM', 'TC', 'TH', 'TR', 'UA', 'US', 'UY', 'VA', 'VI',
'WF', 'WS', 'YT', 'ZA'];
}
}
}