Files
GNX-WEB/gnx-react/lib/api/careerService.ts
Iliyan Angelov 5ad9cbe3a6 update
2025-10-13 01:49:06 +03:00

230 lines
6.7 KiB
TypeScript

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) {
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) {
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) {
throw error;
}
}
/**
* Submit a job application
*/
async submitApplication(applicationData: JobApplication): Promise<any> {
try {
const formData = new FormData();
// Required fields
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());
formData.append('resume', applicationData.resume);
// Optional fields (only append if they exist)
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 !== undefined) 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,
});
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
const errorMessage = errorData.error || errorData.message || errorData.detail || `HTTP ${response.status}: ${response.statusText}`;
throw new Error(errorMessage);
}
const data = await response.json();
return data;
} catch (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) {
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) {
throw error;
}
}
}
export const careerService = new CareerService();