update
This commit is contained in:
237
gnx-react/lib/api/careerService.ts
Normal file
237
gnx-react/lib/api/careerService.ts
Normal file
@@ -0,0 +1,237 @@
|
||||
import { API_BASE_URL } from '../config/api';
|
||||
|
||||
export interface JobPosition {
|
||||
id: number;
|
||||
title: string;
|
||||
slug: string;
|
||||
department: string;
|
||||
employment_type: string;
|
||||
location_type: string;
|
||||
location: string;
|
||||
open_positions: number;
|
||||
experience_required?: string;
|
||||
salary_min?: number;
|
||||
salary_max?: number;
|
||||
salary_currency: string;
|
||||
salary_period: string;
|
||||
salary_additional?: string;
|
||||
short_description?: string;
|
||||
about_role?: string;
|
||||
requirements?: string[];
|
||||
responsibilities?: string[];
|
||||
qualifications?: string[];
|
||||
bonus_points?: string[];
|
||||
benefits?: string[];
|
||||
start_date: string;
|
||||
posted_date: string;
|
||||
updated_date: string;
|
||||
deadline?: string;
|
||||
status: string;
|
||||
featured?: boolean;
|
||||
}
|
||||
|
||||
export interface JobApplication {
|
||||
job: number;
|
||||
first_name: string;
|
||||
last_name: string;
|
||||
email: string;
|
||||
phone?: string;
|
||||
current_position?: string;
|
||||
current_company?: string;
|
||||
years_of_experience?: string;
|
||||
cover_letter?: string;
|
||||
resume: File;
|
||||
portfolio_url?: string;
|
||||
linkedin_url?: string;
|
||||
github_url?: string;
|
||||
website_url?: string;
|
||||
available_from?: string;
|
||||
notice_period?: string;
|
||||
expected_salary?: number;
|
||||
salary_currency?: string;
|
||||
consent: boolean;
|
||||
}
|
||||
|
||||
class CareerService {
|
||||
private baseUrl = `${API_BASE_URL}/api/career`;
|
||||
|
||||
/**
|
||||
* Get all active job positions
|
||||
*/
|
||||
async getAllJobs(): Promise<JobPosition[]> {
|
||||
try {
|
||||
const response = await fetch(`${this.baseUrl}/jobs/`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch jobs: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
// Handle paginated response - extract results array
|
||||
return data.results || data;
|
||||
} catch (error) {
|
||||
console.error('Error fetching jobs:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a single job position by slug
|
||||
*/
|
||||
async getJobBySlug(slug: string): Promise<JobPosition> {
|
||||
try {
|
||||
const response = await fetch(`${this.baseUrl}/jobs/${slug}/`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch job: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.error('Error fetching job:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get featured job positions
|
||||
*/
|
||||
async getFeaturedJobs(): Promise<JobPosition[]> {
|
||||
try {
|
||||
const response = await fetch(`${this.baseUrl}/jobs/featured/`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch featured jobs: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
// Handle paginated response - extract results array
|
||||
return data.results || data;
|
||||
} catch (error) {
|
||||
console.error('Error fetching featured jobs:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit a job application
|
||||
*/
|
||||
async submitApplication(applicationData: JobApplication): Promise<any> {
|
||||
try {
|
||||
const formData = new FormData();
|
||||
|
||||
// Append all fields to FormData
|
||||
formData.append('job', applicationData.job.toString());
|
||||
formData.append('first_name', applicationData.first_name);
|
||||
formData.append('last_name', applicationData.last_name);
|
||||
formData.append('email', applicationData.email);
|
||||
formData.append('consent', applicationData.consent.toString());
|
||||
|
||||
// Append resume file
|
||||
if (applicationData.resume) {
|
||||
formData.append('resume', applicationData.resume);
|
||||
}
|
||||
|
||||
// Append optional fields
|
||||
if (applicationData.phone) formData.append('phone', applicationData.phone);
|
||||
if (applicationData.current_position) formData.append('current_position', applicationData.current_position);
|
||||
if (applicationData.current_company) formData.append('current_company', applicationData.current_company);
|
||||
if (applicationData.years_of_experience) formData.append('years_of_experience', applicationData.years_of_experience);
|
||||
if (applicationData.cover_letter) formData.append('cover_letter', applicationData.cover_letter);
|
||||
if (applicationData.portfolio_url) formData.append('portfolio_url', applicationData.portfolio_url);
|
||||
if (applicationData.linkedin_url) formData.append('linkedin_url', applicationData.linkedin_url);
|
||||
if (applicationData.github_url) formData.append('github_url', applicationData.github_url);
|
||||
if (applicationData.website_url) formData.append('website_url', applicationData.website_url);
|
||||
if (applicationData.available_from) formData.append('available_from', applicationData.available_from);
|
||||
if (applicationData.notice_period) formData.append('notice_period', applicationData.notice_period);
|
||||
if (applicationData.expected_salary) formData.append('expected_salary', applicationData.expected_salary.toString());
|
||||
if (applicationData.salary_currency) formData.append('salary_currency', applicationData.salary_currency);
|
||||
|
||||
const response = await fetch(`${this.baseUrl}/applications/`, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
// Don't set Content-Type header - browser will set it with boundary for multipart/form-data
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json();
|
||||
throw new Error(errorData.error || `Failed to submit application: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.error('Error submitting application:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter jobs by department
|
||||
*/
|
||||
async getJobsByDepartment(department: string): Promise<JobPosition[]> {
|
||||
try {
|
||||
const response = await fetch(`${this.baseUrl}/jobs/?department=${department}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch jobs: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
// Handle paginated response - extract results array
|
||||
return data.results || data;
|
||||
} catch (error) {
|
||||
console.error('Error fetching jobs by department:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter jobs by employment type
|
||||
*/
|
||||
async getJobsByEmploymentType(employmentType: string): Promise<JobPosition[]> {
|
||||
try {
|
||||
const response = await fetch(`${this.baseUrl}/jobs/?employment_type=${employmentType}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch jobs: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
// Handle paginated response - extract results array
|
||||
return data.results || data;
|
||||
} catch (error) {
|
||||
console.error('Error fetching jobs by employment type:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const careerService = new CareerService();
|
||||
|
||||
Reference in New Issue
Block a user