Add custom interval days support for task frequency

- Add customIntervalDays field to Kotlin models (TaskResponse, TaskCreateRequest, TaskUpdateRequest)
- Update Android AddTaskDialog to show interval field only for "Custom" frequency
- Update Android EditTaskScreen for custom frequency support
- Update iOS TaskFormView for custom frequency support
- Fix preview data in TaskCard and TasksSection to include new field
- Add customIntervalDays to OnboardingFirstTaskView

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Trey t
2025-12-13 19:05:59 -06:00
parent 3140c75815
commit 33ee445aea
20 changed files with 524 additions and 238 deletions

View File

@@ -71,7 +71,7 @@ struct TaskFormView: View {
formatter.dateFormat = "yyyy-MM-dd"
_dueDate = State(initialValue: formatter.date(from: task.effectiveDueDate ?? "") ?? Date())
_intervalDays = State(initialValue: "") // No longer in API
_intervalDays = State(initialValue: task.customIntervalDays != nil ? String(task.customIntervalDays!.int32Value) : "")
_estimatedCost = State(initialValue: task.estimatedCost != nil ? String(task.estimatedCost!.doubleValue) : "")
} else {
_title = State(initialValue: "")
@@ -220,8 +220,15 @@ struct TaskFormView: View {
Text(frequency.displayName).tag(frequency as TaskFrequency?)
}
}
.onChange(of: selectedFrequency) { newFrequency in
// Clear interval days if not Custom frequency
if newFrequency?.name.lowercased() != "custom" {
intervalDays = ""
}
}
if selectedFrequency?.name != "once" {
// Show custom interval field only for "Custom" frequency
if selectedFrequency?.name.lowercased() == "custom" {
TextField(L10n.Tasks.customInterval, text: $intervalDays)
.keyboardType(.numberPad)
.focused($focusedField, equals: .intervalDays)
@@ -231,9 +238,15 @@ struct TaskFormView: View {
} header: {
Text(L10n.Tasks.scheduling)
} footer: {
Text(L10n.Tasks.required)
.font(.caption)
.foregroundColor(Color.appError)
if selectedFrequency?.name.lowercased() == "custom" {
Text("Enter the number of days between each occurrence")
.font(.caption)
.foregroundColor(Color.appTextSecondary)
} else {
Text(L10n.Tasks.required)
.font(.caption)
.foregroundColor(Color.appError)
}
}
.listRowBackground(Color.appBackgroundSecondary)
@@ -460,6 +473,11 @@ struct TaskFormView: View {
if isEditMode, let task = existingTask {
// UPDATE existing task
// Include customIntervalDays only for "Custom" frequency
let customInterval: KotlinInt? = frequency.name.lowercased() == "custom" && !intervalDays.isEmpty
? KotlinInt(int: Int32(intervalDays) ?? 0)
: nil
let request = TaskCreateRequest(
residenceId: task.residenceId,
title: title,
@@ -468,6 +486,7 @@ struct TaskFormView: View {
priorityId: KotlinInt(int: Int32(priority.id)),
inProgress: inProgress,
frequencyId: KotlinInt(int: Int32(frequency.id)),
customIntervalDays: customInterval,
assignedToId: nil,
dueDate: dueDateString,
estimatedCost: estimatedCost.isEmpty ? nil : KotlinDouble(double: Double(estimatedCost) ?? 0.0),
@@ -491,6 +510,11 @@ struct TaskFormView: View {
return
}
// Include customIntervalDays only for "Custom" frequency
let customIntervalCreate: KotlinInt? = frequency.name.lowercased() == "custom" && !intervalDays.isEmpty
? KotlinInt(int: Int32(intervalDays) ?? 0)
: nil
let request = TaskCreateRequest(
residenceId: actualResidenceId,
title: title,
@@ -499,6 +523,7 @@ struct TaskFormView: View {
priorityId: KotlinInt(int: Int32(priority.id)),
inProgress: inProgress,
frequencyId: KotlinInt(int: Int32(frequency.id)),
customIntervalDays: customIntervalCreate,
assignedToId: nil,
dueDate: dueDateString,
estimatedCost: estimatedCost.isEmpty ? nil : KotlinDouble(double: Double(estimatedCost) ?? 0.0),