content calendar fixed

This commit is contained in:
IGNY8 VPS (Salman)
2026-01-16 21:34:20 +00:00
parent 0f5e02e451
commit cf755b23dc
3 changed files with 47 additions and 44 deletions

View File

@@ -192,52 +192,45 @@ export default function ContentCalendar() {
// IMPORTANT: Since content is ordered by -created_at, we need to fetch items by specific site_status // IMPORTANT: Since content is ordered by -created_at, we need to fetch items by specific site_status
// Otherwise old scheduled/failed items will be on later pages and won't load // Otherwise old scheduled/failed items will be on later pages and won't load
// NOTE: fetchAPI doesn't support params object - must use URL query strings
const siteId = activeSite.id;
console.log('[ContentCalendar] ========== SITE FILTERING DEBUG =========='); console.log('[ContentCalendar] ========== SITE FILTERING DEBUG ==========');
console.log('[ContentCalendar] Active site ID:', activeSite.id); console.log('[ContentCalendar] Active site ID:', siteId);
console.log('[ContentCalendar] Active site name:', activeSite.name); console.log('[ContentCalendar] Active site name:', activeSite.name);
console.log('[ContentCalendar] Fetching content with multiple targeted queries...'); console.log('[ContentCalendar] Fetching content with multiple targeted queries...');
// Fetch scheduled items (all of them, regardless of page) // Fetch scheduled items (all of them, regardless of page)
const scheduledResponse = await fetchAPI('/v1/writer/content/', { const scheduledResponse = await fetchAPI(
params: { `/v1/writer/content/?site_id=${siteId}&page_size=1000&site_status=scheduled`
site_id: activeSite.id, );
page_size: 1000,
site_status: 'scheduled', // Filter specifically for scheduled
}
});
// Fetch failed items (all of them) // Fetch failed items (all of them)
const failedResponse = await fetchAPI('/v1/writer/content/', { const failedResponse = await fetchAPI(
params: { `/v1/writer/content/?site_id=${siteId}&page_size=1000&site_status=failed`
site_id: activeSite.id, );
page_size: 1000,
site_status: 'failed', // Filter specifically for failed
}
});
// Fetch approved items (for sidebar drag-drop) // Fetch review items (for review count display)
const approvedResponse = await fetchAPI('/v1/writer/content/', { const reviewResponse = await fetchAPI(
params: { `/v1/writer/content/?site_id=${siteId}&page_size=100&status=review`
site_id: activeSite.id, );
page_size: 100,
status: 'approved', // Approved workflow status
}
});
// Fetch published items (with external_id) for display // Fetch approved items (for sidebar drag-drop) - not yet published to site
const publishedResponse = await fetchAPI('/v1/writer/content/', { const approvedResponse = await fetchAPI(
params: { `/v1/writer/content/?site_id=${siteId}&page_size=100&status=approved&site_status=not_published`
site_id: activeSite.id, );
page_size: 100,
ordering: '-updated_at', // Most recently published first // Fetch published items (site_status=published) for display
} const publishedResponse = await fetchAPI(
}); `/v1/writer/content/?site_id=${siteId}&page_size=100&site_status=published&ordering=-updated_at`
);
// Combine all results, removing duplicates by ID // Combine all results, removing duplicates by ID
const allItems = [ const allItems = [
...(scheduledResponse.results || []), ...(scheduledResponse.results || []),
...(failedResponse.results || []), ...(failedResponse.results || []),
...(reviewResponse.results || []),
...(approvedResponse.results || []), ...(approvedResponse.results || []),
...(publishedResponse.results || []), ...(publishedResponse.results || []),
]; ];
@@ -251,6 +244,7 @@ export default function ContentCalendar() {
console.log('[ContentCalendar] ========== DATA LOAD DEBUG =========='); console.log('[ContentCalendar] ========== DATA LOAD DEBUG ==========');
console.log('[ContentCalendar] Scheduled query returned:', scheduledResponse.results?.length, 'items'); console.log('[ContentCalendar] Scheduled query returned:', scheduledResponse.results?.length, 'items');
console.log('[ContentCalendar] Failed query returned:', failedResponse.results?.length, 'items'); console.log('[ContentCalendar] Failed query returned:', failedResponse.results?.length, 'items');
console.log('[ContentCalendar] Review query returned:', reviewResponse.results?.length, 'items');
console.log('[ContentCalendar] Approved query returned:', approvedResponse.results?.length, 'items'); console.log('[ContentCalendar] Approved query returned:', approvedResponse.results?.length, 'items');
console.log('[ContentCalendar] Published query returned:', publishedResponse.results?.length, 'items'); console.log('[ContentCalendar] Published query returned:', publishedResponse.results?.length, 'items');
console.log('[ContentCalendar] Total unique items after deduplication:', uniqueItems.length); console.log('[ContentCalendar] Total unique items after deduplication:', uniqueItems.length);

View File

@@ -290,8 +290,10 @@ export default function Approved() {
}) })
}); });
if (response.success && response.data?.results?.[0]?.success) { // Note: fetchAPI unwraps the response, so response IS the data object
const result = response.data.results[0]; // Response format: { success: true, results: [{ success: true, url: '...', external_id: '...' }] }
if (response.success && response.results?.[0]?.success) {
const result = response.results[0];
// Phase 3: Processing (50-75%) // Phase 3: Processing (50-75%)
setSinglePublishState(prev => prev ? { ...prev, progress: 50, statusMessage: 'Processing response...' } : null); setSinglePublishState(prev => prev ? { ...prev, progress: 50, statusMessage: 'Processing response...' } : null);
@@ -313,7 +315,7 @@ export default function Approved() {
loadContent(); loadContent();
} else { } else {
throw new Error(response.error || 'Failed to publish'); throw new Error(response.error || response.results?.[0]?.error || 'Failed to publish');
} }
} catch (error: any) { } catch (error: any) {
console.error('Publish error:', error); console.error('Publish error:', error);
@@ -412,6 +414,8 @@ export default function Approved() {
try { try {
const contentIds = selectedIds.map(id => parseInt(id)); const contentIds = selectedIds.map(id => parseInt(id));
// Note: fetchAPI unwraps success_response, so response IS the data object
// Response format: { scheduled_count: N, schedule_preview: [...], site_settings: {...} }
const response = await fetchAPI('/v1/writer/content/bulk_schedule_preview/', { const response = await fetchAPI('/v1/writer/content/bulk_schedule_preview/', {
method: 'POST', method: 'POST',
body: JSON.stringify({ body: JSON.stringify({
@@ -420,11 +424,13 @@ export default function Approved() {
}) })
}); });
if (response.success) { // fetchAPI throws on error, so if we get here, response is successful
setBulkSchedulePreview(response.data); // Response is the unwrapped data object
if (response && response.schedule_preview) {
setBulkSchedulePreview(response);
setShowBulkSchedulePreviewModal(true); setShowBulkSchedulePreviewModal(true);
} else { } else {
throw new Error(response.error || 'Failed to generate preview'); throw new Error('Invalid response from server');
} }
} catch (error: any) { } catch (error: any) {
toast.error(`Failed to generate schedule preview: ${error.message}`); toast.error(`Failed to generate schedule preview: ${error.message}`);
@@ -437,6 +443,7 @@ export default function Approved() {
try { try {
const contentIds = selectedIds.map(id => parseInt(id)); const contentIds = selectedIds.map(id => parseInt(id));
// Note: fetchAPI unwraps success_response, so response IS the data object
const response = await fetchAPI('/v1/writer/content/bulk_schedule/', { const response = await fetchAPI('/v1/writer/content/bulk_schedule/', {
method: 'POST', method: 'POST',
body: JSON.stringify({ body: JSON.stringify({
@@ -446,14 +453,15 @@ export default function Approved() {
}) })
}); });
if (response.success) { // fetchAPI throws on error, so if we get here, response is successful
toast.success(`Scheduled ${response.data.scheduled_count} item(s)`); if (response && response.scheduled_count !== undefined) {
toast.success(`Scheduled ${response.scheduled_count} item(s)`);
setShowBulkSchedulePreviewModal(false); setShowBulkSchedulePreviewModal(false);
setBulkSchedulePreview(null); setBulkSchedulePreview(null);
setSelectedIds([]); setSelectedIds([]);
loadContent(); loadContent();
} else { } else {
throw new Error(response.error || 'Failed to schedule'); throw new Error('Invalid response from server');
} }
} catch (error: any) { } catch (error: any) {
toast.error(`Failed to schedule: ${error.message}`); toast.error(`Failed to schedule: ${error.message}`);
@@ -568,9 +576,10 @@ export default function Approved() {
}) })
}); });
// Handle response // Handle response - fetchAPI unwraps the data object
if (response.success && response.data?.results?.[0]?.success) { // Response format: { success: true, results: [{ success: true, url: '...', external_id: '...' }] }
const result = response.data.results[0]; if (response.success && response.results?.[0]?.success) {
const result = response.results[0];
// Animate to completion // Animate to completion
setBulkPublishQueue(prev => prev.map((item, idx) => setBulkPublishQueue(prev => prev.map((item, idx) =>
@@ -589,7 +598,7 @@ export default function Approved() {
} : item } : item
)); ));
} else { } else {
throw new Error(response.error || 'Unknown error'); throw new Error(response.error || response.results?.[0]?.error || 'Unknown error');
} }
} catch (error: any) { } catch (error: any) {
console.error(`Error publishing content ${queue[i].contentId}:`, error); console.error(`Error publishing content ${queue[i].contentId}:`, error);