diff --git a/frontend/src/templates/ContentViewTemplate.tsx b/frontend/src/templates/ContentViewTemplate.tsx index 4defd704..8e54e8a5 100644 --- a/frontend/src/templates/ContentViewTemplate.tsx +++ b/frontend/src/templates/ContentViewTemplate.tsx @@ -21,6 +21,7 @@ import { ArrowLeftIcon, CalendarIcon, TagIcon, FileTextIcon, CheckCircleIcon, XC import { useNavigate } from 'react-router-dom'; import Button from '../components/ui/button/Button'; import { useToast } from '../components/ui/toast/ToastContainer'; +import { formatDateTime, formatDateTimeLocal, getDatePartsInAccountTimezone, toUtcISOStringFromLocal } from '../utils/date'; interface ContentViewTemplateProps { content: Content | null; @@ -632,16 +633,17 @@ export default function ContentViewTemplate({ content, loading, onBack }: Conten // Initialize schedule datetime when content loads useEffect(() => { if (content?.scheduled_publish_at) { - // Convert ISO string to datetime-local format (YYYY-MM-DDTHH:mm) - const date = new Date(content.scheduled_publish_at); - const localDateTime = date.toISOString().slice(0, 16); + const localDateTime = formatDateTimeLocal(content.scheduled_publish_at); setScheduleDateTime(localDateTime); } else if (content?.site_status === 'failed') { - // Default to tomorrow at 9 AM for failed items without a schedule - const tomorrow = new Date(); - tomorrow.setDate(tomorrow.getDate() + 1); - tomorrow.setHours(9, 0, 0, 0); - setScheduleDateTime(tomorrow.toISOString().slice(0, 16)); + // Default to tomorrow at 9 AM (account timezone) for failed items without a schedule + const todayParts = getDatePartsInAccountTimezone(new Date()); + const baseDate = new Date(Date.UTC(todayParts.year, todayParts.month - 1, todayParts.day)); + baseDate.setUTCDate(baseDate.getUTCDate() + 1); + const year = baseDate.getUTCFullYear(); + const month = String(baseDate.getUTCMonth() + 1).padStart(2, '0'); + const day = String(baseDate.getUTCDate()).padStart(2, '0'); + setScheduleDateTime(`${year}-${month}-${day}T09:00`); } }, [content?.scheduled_publish_at, content?.site_status]); @@ -651,7 +653,11 @@ export default function ContentViewTemplate({ content, loading, onBack }: Conten setIsUpdatingSchedule(true); try { - const isoDateTime = new Date(scheduleDateTime).toISOString(); + const isoDateTime = toUtcISOStringFromLocal(scheduleDateTime); + if (!isoDateTime) { + toast.error('Invalid schedule date/time.'); + return; + } // Use reschedule endpoint for failed items, schedule endpoint for scheduled items const endpoint = content.site_status === 'failed' @@ -875,20 +881,6 @@ export default function ContentViewTemplate({ content, loading, onBack }: Conten ); } - const formatDate = (dateString: string) => { - try { - return new Date(dateString).toLocaleDateString('en-US', { - year: 'numeric', - month: 'long', - day: 'numeric', - hour: '2-digit', - minute: '2-digit', - }); - } catch { - return dateString; - } - }; - const getStatusColor = (status: string) => { const statusLower = status.toLowerCase(); if (statusLower === 'generated' || statusLower === 'published' || statusLower === 'complete') { @@ -974,7 +966,7 @@ export default function ContentViewTemplate({ content, loading, onBack }: Conten

Generated

- {formatDate(content.generated_at)} + {formatDateTime(content.generated_at)}

@@ -984,7 +976,7 @@ export default function ContentViewTemplate({ content, loading, onBack }: Conten

Last Updated

- {formatDate(content.updated_at)} + {formatDateTime(content.updated_at)}

@@ -1225,14 +1217,16 @@ export default function ContentViewTemplate({ content, loading, onBack }: Conten setIsEditingSchedule(false); // Reset to original value or tomorrow if failed if (content.scheduled_publish_at) { - const date = new Date(content.scheduled_publish_at); - setScheduleDateTime(date.toISOString().slice(0, 16)); + setScheduleDateTime(formatDateTimeLocal(content.scheduled_publish_at)); } else if (content.site_status === 'failed') { // Default to tomorrow for failed items - const tomorrow = new Date(); - tomorrow.setDate(tomorrow.getDate() + 1); - tomorrow.setHours(9, 0, 0, 0); - setScheduleDateTime(tomorrow.toISOString().slice(0, 16)); + const todayParts = getDatePartsInAccountTimezone(new Date()); + const baseDate = new Date(Date.UTC(todayParts.year, todayParts.month - 1, todayParts.day)); + baseDate.setUTCDate(baseDate.getUTCDate() + 1); + const year = baseDate.getUTCFullYear(); + const month = String(baseDate.getUTCMonth() + 1).padStart(2, '0'); + const day = String(baseDate.getUTCDate()).padStart(2, '0'); + setScheduleDateTime(`${year}-${month}-${day}T09:00`); } }} > @@ -1243,10 +1237,10 @@ export default function ContentViewTemplate({ content, loading, onBack }: Conten <> {content.site_status === 'failed' && ( - content.scheduled_publish_at ? `Was scheduled: ${formatDate(content.scheduled_publish_at)}` : 'Not scheduled' + content.scheduled_publish_at ? `Was scheduled: ${formatDateTime(content.scheduled_publish_at)}` : 'Not scheduled' )} {content.site_status === 'scheduled' && ( - content.scheduled_publish_at ? formatDate(content.scheduled_publish_at) : '' + content.scheduled_publish_at ? formatDateTime(content.scheduled_publish_at) : '' )}