| | import apiClient from './apiClient'; |
| |
|
| | class PostService { |
| | |
| | |
| | |
| | |
| | |
| | |
| | async getAll(params = {}) { |
| | try { |
| | const response = await apiClient.get('/posts', { params }); |
| | |
| | if (import.meta.env.VITE_NODE_ENV === 'development') { |
| | console.log('π [Post] Retrieved posts:', response.data); |
| | } |
| | |
| | return response; |
| | } catch (error) { |
| | if (import.meta.env.VITE_NODE_ENV === 'development') { |
| | console.error('π [Post] Get posts error:', error.response?.data || error.message); |
| | } |
| | throw error; |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | async generate() { |
| | try { |
| | |
| | const startResponse = await apiClient.post('/posts/generate', {}); |
| | |
| | if (import.meta.env.VITE_NODE_ENV === 'development') { |
| | console.log('π [Post] AI post generation started:', startResponse.data); |
| | } |
| | |
| | const jobId = startResponse.data.job_id; |
| | |
| | |
| | const generatedResult = await this.pollForJobResult(jobId); |
| | |
| | |
| | const finalContent = generatedResult.content !== undefined && generatedResult.content !== null ? generatedResult.content : "Generated content will appear here..."; |
| | const finalImage = generatedResult.image || null; |
| | |
| | return { data: { success: true, content: finalContent, image: finalImage } }; |
| | } catch (error) { |
| | if (import.meta.env.VITE_NODE_ENV === 'development') { |
| | console.error('π [Post] Generate post error:', error.response?.data || error.message); |
| | } |
| | throw error; |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | async pollForJobResult(jobId) { |
| | const pollInterval = 6000; |
| | const maxAttempts = 60; |
| | |
| | for (let attempt = 1; attempt <= maxAttempts; attempt++) { |
| | try { |
| | const response = await apiClient.get(`/posts/jobs/${jobId}`); |
| | const jobData = response.data; |
| | |
| | if (import.meta.env.VITE_NODE_ENV === 'development') { |
| | console.log(`π [Post] Job status check ${attempt}/${maxAttempts}:`, jobData); |
| | } |
| | |
| | switch (jobData.status) { |
| | case 'completed': |
| | |
| | if (import.meta.env.VITE_NODE_ENV === 'development') { |
| | console.log('π [Post] Raw job data:', jobData); |
| | } |
| | |
| | |
| | let content = ''; |
| | let imageData = null; |
| | |
| | |
| | if (jobData.content !== undefined) { |
| | content = jobData.content; |
| | } |
| | |
| | |
| | if (jobData.image_url !== undefined && jobData.image_url !== null) { |
| | imageData = jobData.image_url; |
| | } else if (jobData.has_image_data) { |
| | |
| | |
| | if (jobData.image_data) { |
| | |
| | if (typeof jobData.image_data === 'string' && jobData.image_data.startsWith('data:image')) { |
| | imageData = jobData.image_data; |
| | } else { |
| | imageData = 'HAS_IMAGE_DATA_BUT_NOT_URL'; |
| | } |
| | } else { |
| | imageData = 'HAS_IMAGE_DATA_BUT_NOT_URL'; |
| | } |
| | } |
| | |
| | |
| | if (Array.isArray(content)) { |
| | content = content[0] || ''; |
| | } |
| | |
| | |
| | return { |
| | content: content !== undefined ? content : '', |
| | image: imageData |
| | }; |
| | case 'failed': |
| | throw new Error(jobData.error || 'Job failed'); |
| | case 'processing': |
| | case 'pending': |
| | |
| | await new Promise(resolve => setTimeout(resolve, pollInterval)); |
| | break; |
| | default: |
| | throw new Error(`Unknown job status: ${jobData.status}`); |
| | } |
| | } catch (error) { |
| | if (error.response?.status === 404) { |
| | throw new Error('Job not found'); |
| | } |
| | throw error; |
| | } |
| | } |
| | |
| | |
| | throw new Error('Job polling timed out after 6 minutes. Please check back later.'); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | async create(postData) { |
| | try { |
| | if (import.meta.env.VITE_NODE_ENV === 'development') { |
| | console.log('π [Post] Creating post with data:', postData); |
| | } |
| | |
| | const response = await apiClient.post('/posts', { |
| | social_account_id: postData.social_account_id, |
| | text_content: postData.text_content, |
| | image_content_url: postData.image_content_url, |
| | scheduled_at: postData.scheduled_at |
| | }); |
| | |
| | if (import.meta.env.VITE_NODE_ENV === 'development') { |
| | console.log('π [Post] Post created:', response.data); |
| | } |
| | |
| | return response; |
| | } catch (error) { |
| | if (import.meta.env.VITE_NODE_ENV === 'development') { |
| | console.error('π [Post] Create post error:', error.response?.data || error.message); |
| | console.error('π [Post] Error details:', { |
| | status: error.response?.status, |
| | statusText: error.response?.statusText, |
| | headers: error.response?.headers, |
| | data: error.response?.data |
| | }); |
| | } |
| | throw error; |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | async publishDirect(publishData) { |
| | try { |
| | if (import.meta.env.VITE_NODE_ENV === 'development') { |
| | console.log('π [Post] Publishing post directly to social media with data:', publishData); |
| | } |
| | |
| | const response = await apiClient.post('/posts/publish-direct', publishData); |
| | |
| | if (import.meta.env.VITE_NODE_ENV === 'development') { |
| | console.log('π [Post] Post published directly:', response.data); |
| | } |
| | |
| | return response; |
| | } catch (error) { |
| | if (import.meta.env.VITE_NODE_ENV === 'development') { |
| | console.error('π [Post] Publish post directly error:', error.response?.data || error.message); |
| | console.error('π [Post] Error details:', { |
| | status: error.response?.status, |
| | statusText: error.response?.statusText, |
| | headers: error.response?.headers, |
| | data: error.response?.data |
| | }); |
| | } |
| | throw error; |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | async delete(postId) { |
| | try { |
| | const response = await apiClient.delete(`/posts/${postId}`); |
| | |
| | if (import.meta.env.VITE_NODE_ENV === 'development') { |
| | console.log('π [Post] Post deleted:', response.data); |
| | } |
| | |
| | return response; |
| | } catch (error) { |
| | if (import.meta.env.VITE_NODE_ENV === 'development') { |
| | console.error('π [Post] Delete post error:', error.response?.data || error.message); |
| | } |
| | throw error; |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | async analyzeKeywordTrend(keyword) { |
| | try { |
| | const response = await apiClient.post('/posts/keyword-analysis', { |
| | keyword: keyword, |
| | date_range: 'monthly' |
| | }); |
| |
|
| | if (import.meta.env.VITE_NODE_ENV === 'development') { |
| | console.log('π [Post] Keyword analysis result:', response.data); |
| | } |
| |
|
| | return response; |
| | } catch (error) { |
| | if (import.meta.env.VITE_NODE_ENV === 'development') { |
| | console.error('π [Post] Keyword analysis error:', error.response?.data || error.message); |
| | } |
| | throw error; |
| | } |
| | } |
| | } |
| |
|
| | export default new PostService(); |