import React, { useState } from 'react'; import { RecurrenceType } from '../../../entities/Task'; import { useTranslation } from 'react-i18next'; import RecurrenceSelectDropdown from '../../Shared/RecurrenceSelectDropdown'; import NumberSelectDropdown from '../../Shared/NumberSelectDropdown'; import ToggleSwitch from '../../Shared/ToggleSwitch'; import DatePicker from '../../Shared/DatePicker'; import WeekdaySelector from './WeekdaySelector'; interface TaskRecurrenceSectionProps { recurrenceType: RecurrenceType; recurrenceInterval: number; recurrenceEndDate?: string; recurrenceWeekday?: number; recurrenceWeekdays?: number[]; recurrenceMonthDay?: number; recurrenceWeekOfMonth?: number; completionBased: boolean; onChange: (field: string, value: any) => void; disabled?: boolean; isChildTask?: boolean; parentTaskLoading?: boolean; onEditParent?: () => void; onParentRecurrenceChange?: (field: string, value: any) => void; } const TaskRecurrenceSection: React.FC = ({ recurrenceType, recurrenceInterval, recurrenceEndDate, recurrenceWeekday, recurrenceWeekdays, recurrenceMonthDay, recurrenceWeekOfMonth, completionBased, onChange, disabled = false, isChildTask = false, parentTaskLoading = false, onEditParent, // eslint-disable-line @typescript-eslint/no-unused-vars onParentRecurrenceChange, }) => { // Helper function to convert ISO date string to YYYY-MM-DD format for DatePicker const formatDateForPicker = (dateString?: string) => { if (!dateString) return ''; try { const date = new Date(dateString); if (isNaN(date.getTime())) return ''; return date.toISOString().split('T')[0]; // Returns YYYY-MM-DD } catch { return dateString; // Return as-is if it's already in the correct format } }; const { t } = useTranslation(); const [editingParentRecurrence, setEditingParentRecurrence] = useState(false); const weekdays = [ { value: 0, label: t('weekdays.sunday', 'Sunday') }, { value: 1, label: t('weekdays.monday', 'Monday') }, { value: 2, label: t('weekdays.tuesday', 'Tuesday') }, { value: 3, label: t('weekdays.wednesday', 'Wednesday') }, { value: 4, label: t('weekdays.thursday', 'Thursday') }, { value: 5, label: t('weekdays.friday', 'Friday') }, { value: 6, label: t('weekdays.saturday', 'Saturday') }, ]; const weekOfMonthOptions = [ { value: 1, label: t('recurrence.firstWeek', 'First') }, { value: 2, label: t('recurrence.secondWeek', 'Second') }, { value: 3, label: t('recurrence.thirdWeek', 'Third') }, { value: 4, label: t('recurrence.fourthWeek', 'Fourth') }, { value: 5, label: t('recurrence.lastWeek', 'Last') }, ]; const recurrenceTypeOptions = [ { value: 'none', label: t('recurrence.none', 'No repeat') }, { value: 'daily', label: t('recurrence.daily', 'Daily') }, { value: 'weekly', label: t('recurrence.weekly', 'Weekly') }, { value: 'monthly', label: t('recurrence.monthly', 'Monthly') }, { value: 'monthly_weekday', label: t('recurrence.monthlyWeekday', 'Monthly on weekday'), }, { value: 'monthly_last_day', label: t('recurrence.monthlyLastDay', 'Monthly on last day'), }, ]; const renderRecurrenceTypeSelect = ( customOnChange?: (field: string, value: any) => void, isDisabled?: boolean ) => (
(customOnChange || onChange)( 'recurrence_type', value as RecurrenceType ) } options={recurrenceTypeOptions} disabled={isDisabled} />
); const renderIntervalInput = ( customOnChange?: (field: string, value: any) => void, isDisabled?: boolean ) => { // Determine max value based on recurrence type const getMaxValue = () => { if (recurrenceType === 'daily') return 30; if (recurrenceType === 'weekly') return 52; // Max 52 weeks (1 year) if ( recurrenceType === 'monthly' || recurrenceType === 'monthly_weekday' || recurrenceType === 'monthly_last_day' ) return 24; // Max 24 months (2 years) return 99; }; return (
(customOnChange || onChange)( 'recurrence_interval', value ) } min={1} max={getMaxValue()} disabled={isDisabled} />
{recurrenceType === 'daily' && t('recurrence.days', 'days')} {recurrenceType === 'weekly' && t('recurrence.weeks', 'weeks')} {(recurrenceType === 'monthly' || recurrenceType === 'monthly_weekday' || recurrenceType === 'monthly_last_day') && t('recurrence.months', 'months')}
); }; const renderWeekdaySelect = ( customOnChange?: (field: string, value: any) => void, isDisabled?: boolean ) => { return (
(customOnChange || onChange)( 'recurrence_weekdays', days ) } disabled={isDisabled} />
); }; const renderMonthDayInput = ( customOnChange?: (field: string, value: any) => void, isDisabled?: boolean ) => (
(customOnChange || onChange)('recurrence_month_day', value) } min={1} max={31} placeholder={t( 'recurrence.monthDayPlaceholder', 'Select day of month' )} disabled={isDisabled} />
); const renderMonthlyWeekdayInputs = () => (
onChange( 'recurrence_week_of_month', parseInt(value as string) ) } options={weekOfMonthOptions} />
onChange( 'recurrence_weekday', parseInt(value as string) ) } options={weekdays} />
); const renderEndDateInput = ( customOnChange?: (field: string, value: any) => void, isDisabled?: boolean ) => (
(customOnChange || onChange)( 'recurrence_end_date', value || null ) } placeholder={t( 'forms.task.endDatePlaceholder', 'Select end date' )} disabled={isDisabled} />
); const renderCompletionBasedToggle = () => (
onChange('completion_based', checked)} label={t( 'forms.task.labels.completionBased', 'Repeat after completion' )} description={t( 'forms.task.completionBasedHelp', 'If checked, the next task will be created based on completion date instead of due date' )} />
); // Show message for child tasks if (isChildTask && parentTaskLoading) { return (

{t('forms.task.recurrenceSettings', 'Recurrence Settings')}

Loading parent task recurrence settings...
); } if (isChildTask) { return (

{t('forms.task.recurrenceSettings', 'Recurrence Settings')}

Recurring Task Instance

This task was generated from a recurring task. The recurrence settings shown below are inherited from the original task and cannot be edited here.

{onParentRecurrenceChange && ( )}
{editingParentRecurrence && (
⚠️ You are editing the parent task's recurrence settings. Changes will affect all future instances of this recurring task.
)} {recurrenceType === 'none' ? ( renderRecurrenceTypeSelect( editingParentRecurrence ? onParentRecurrenceChange : undefined, !editingParentRecurrence ) ) : ( <> {renderRecurrenceTypeSelect( editingParentRecurrence ? onParentRecurrenceChange : undefined, !editingParentRecurrence )} {renderIntervalInput( editingParentRecurrence ? onParentRecurrenceChange : undefined, !editingParentRecurrence )} {(recurrenceType === 'weekly' || recurrenceType === 'monthly_weekday') && renderWeekdaySelect( editingParentRecurrence ? onParentRecurrenceChange : undefined, !editingParentRecurrence )} {recurrenceType === 'monthly' && renderMonthDayInput( editingParentRecurrence ? onParentRecurrenceChange : undefined, !editingParentRecurrence )} {recurrenceType === 'monthly_weekday' && renderMonthlyWeekdayInputs()} {renderEndDateInput( editingParentRecurrence ? onParentRecurrenceChange : undefined, !editingParentRecurrence )} {renderCompletionBasedToggle()} )}
); } if (recurrenceType === 'none') { return
{renderRecurrenceTypeSelect()}
; } return (

{t('forms.task.recurrenceSettings', 'Recurrence Settings')}

{/* Main recurrence settings in one row */}
onChange('recurrence_type', value as RecurrenceType) } options={recurrenceTypeOptions} disabled={disabled} />
{(recurrenceType === 'daily' || recurrenceType === 'weekly' || recurrenceType === 'monthly' || recurrenceType === 'monthly_weekday' || recurrenceType === 'monthly_last_day') && (
{recurrenceType === 'monthly' ? ( onChange('recurrence_interval', value) } min={1} max={24} disabled={disabled} /> ) : (
onChange( 'recurrence_interval', value ) } min={1} max={ recurrenceType === 'daily' ? 30 : recurrenceType === 'weekly' ? 52 : recurrenceType === 'monthly_weekday' || recurrenceType === 'monthly_last_day' ? 24 : 99 } disabled={disabled} />
{recurrenceType === 'daily' && t('recurrence.days', 'days')} {recurrenceType === 'weekly' && t('recurrence.weeks', 'weeks')} {(recurrenceType === 'monthly_weekday' || recurrenceType === 'monthly_last_day') && t('recurrence.months', 'months')}
)}
)} {recurrenceType === 'monthly' && (
onChange('recurrence_month_day', value) } min={1} max={31} placeholder={t( 'recurrence.monthDayPlaceholder', 'Select day of month' )} disabled={disabled} />
)}
onChange('recurrence_end_date', value || null) } placeholder={t( 'forms.task.endDatePlaceholder', 'Select end date' )} disabled={disabled} />
{/* Additional settings for specific recurrence types */} {recurrenceType === 'weekly' && renderWeekdaySelect()} {recurrenceType === 'monthly_weekday' && renderMonthlyWeekdayInputs()} {renderCompletionBasedToggle()}
); }; export default TaskRecurrenceSection;