Files
resumeformatter/frontend/services/resumeService.ts
Laxmi Khilnani cda50356b4
Some checks failed
Profile Linker Docker Build / Build and push Docker image (push) Failing after 3s
feat: Complete Smart Resume Formatter with R2 and Gemini AI integration
- Integrated Cloudflare R2 for template storage and converted file management
- Added Google Gemini AI for resume parsing and HTML generation
- Created backend API endpoints for templates, conversion, and history
- Refactored frontend to use real API instead of mock data
- Fixed Docker networking issues (IPv6/IPv4) for R2 connectivity
- Added resumeService.ts for frontend API integration
- Updated Vite configuration for proper asset serving in Docker
- Successfully tested with 13 templates from R2 bucket
2025-10-14 21:43:41 +05:30

151 lines
4.1 KiB
TypeScript

/**
* Resume API Service
* Handles all API calls to the backend for resume processing
*/
const APP_NAME = import.meta.env.VITE_APP_NAME || 'resumeformatter';
const API_BASE_URL = `/${APP_NAME}/api/resumes`;
export interface ConvertedFile {
id: string;
name: string;
url: string;
size: number;
lastModified: string;
timestamp: Date;
}
export interface ConvertResponse {
success: boolean;
html_url: string;
html_content: string;
message: string;
}
/**
* Fetch list of available templates from R2
*/
export const fetchTemplates = async (): Promise<string[]> => {
console.log('Fetching templates from API...');
try {
const response = await fetch(`${API_BASE_URL}/templates`);
if (!response.ok) {
throw new Error(`API error: ${response.status}`);
}
const data = await response.json();
console.log('Templates loaded:', data);
return data;
} catch (error) {
console.error('Error fetching templates:', error);
throw error;
}
};
/**
* Fetch HTML content of a specific template
*/
export const fetchTemplateContent = async (templateName: string): Promise<string> => {
console.log(`Fetching template content for: ${templateName}`);
try {
const response = await fetch(`${API_BASE_URL}/templates/${encodeURIComponent(templateName)}`);
if (!response.ok) {
throw new Error(`API error: ${response.status}`);
}
const data = await response.json();
console.log('Template content loaded');
return data.content;
} catch (error) {
console.error('Error fetching template content:', error);
throw error;
}
};
/**
* Convert a resume file using the specified template
*/
export const convertResume = async (
file: File,
templateName: string,
onProgress?: (message: string) => void
): Promise<ConvertResponse> => {
console.log(`Converting resume: ${file.name} with template: ${templateName}`);
try {
// Create form data
const formData = new FormData();
formData.append('file', file);
formData.append('template_name', templateName);
onProgress?.('Uploading file to server...');
// Send request
const response = await fetch(`${API_BASE_URL}/convert`, {
method: 'POST',
body: formData,
});
if (!response.ok) {
const errorData = await response.json().catch(() => ({ detail: 'Unknown error' }));
throw new Error(errorData.detail || `API error: ${response.status}`);
}
onProgress?.('Processing complete!');
const data = await response.json();
console.log('Conversion complete:', data);
return data;
} catch (error) {
console.error('Error converting resume:', error);
throw error;
}
};
/**
* Fetch list of converted resumes from R2
*/
export const fetchConversionHistory = async (limit: number = 50): Promise<ConvertedFile[]> => {
console.log('Fetching conversion history from API...');
try {
const response = await fetch(`${API_BASE_URL}/history?limit=${limit}`);
if (!response.ok) {
throw new Error(`API error: ${response.status}`);
}
const data = await response.json();
// Transform data to match ConvertedFile interface
const files: ConvertedFile[] = data.map((file: any) => ({
id: file.id,
name: file.name,
url: file.url,
size: file.size,
lastModified: file.lastModified,
timestamp: new Date(file.lastModified),
}));
console.log('Conversion history loaded:', files.length, 'files');
return files;
} catch (error) {
console.error('Error fetching conversion history:', error);
throw error;
}
};
/**
* Get download URL for a specific file
*/
export const getDownloadUrl = async (fileKey: string): Promise<string> => {
console.log(`Getting download URL for: ${fileKey}`);
try {
const response = await fetch(`${API_BASE_URL}/download/${encodeURIComponent(fileKey)}`);
if (!response.ok) {
throw new Error(`API error: ${response.status}`);
}
const data = await response.json();
console.log('Download URL retrieved');
return data.url;
} catch (error) {
console.error('Error getting download URL:', error);
throw error;
}
};