Files
Nextcloud-Cookbook-iOS/Nextcloud Cookbook iOS Client/Views/Recipes/ImportURLSheet.swift
Hendrik Hogertz 1536174586 Redesign recipe creation and edit view with Form-based layout and URL import
Replace the single "+" button with a 2-option menu (Create New Recipe / Import
from URL) across RecipeTabView, RecipeListView, and AllRecipesListView. Add
ImportURLSheet for server-side recipe import with loading and error states.

Completely redesign edit mode to use a native Form layout with inline editing
for all sections (metadata, duration, ingredients, instructions, tools,
nutrition) instead of the previous sheet-based EditableListView approach. Move
delete action from edit toolbar to view mode context menu. Add recipe image
display to the edit form.

Refactor RecipeListView and AllRecipesListView to use closure-based callbacks
instead of Binding<Bool> for the create/import actions. Add preloadedRecipeDetail
support to RecipeView.ViewModel for imported recipes.

Add DE/ES/FR translations for all new UI strings.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-15 03:29:20 +01:00

82 lines
2.5 KiB
Swift

//
// ImportURLSheet.swift
// Nextcloud Cookbook iOS Client
//
import SwiftUI
struct ImportURLSheet: View {
@EnvironmentObject var appState: AppState
@Environment(\.dismiss) private var dismiss
var onImport: (RecipeDetail) -> Void
@State private var url: String = ""
@State private var isLoading: Bool = false
@State private var presentAlert: Bool = false
@State private var alertMessage: String = ""
var body: some View {
NavigationStack {
Form {
Section {
TextField("Recipe URL", text: $url)
.keyboardType(.URL)
.textContentType(.URL)
.autocorrectionDisabled()
.textInputAutocapitalization(.never)
} footer: {
Text("Paste the URL of a recipe you would like to import.")
}
Section {
Button {
Task {
await importRecipe()
}
} label: {
HStack {
Spacer()
if isLoading {
ProgressView()
} else {
Text("Import")
}
Spacer()
}
}
.disabled(url.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty || isLoading)
}
}
.navigationTitle("Import Recipe")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button("Cancel") {
dismiss()
}
}
}
.alert("Import Failed", isPresented: $presentAlert) {
Button("OK", role: .cancel) { }
} message: {
Text(alertMessage)
}
}
}
private func importRecipe() async {
isLoading = true
let (recipeDetail, error) = await appState.importRecipe(url: url)
isLoading = false
if let recipeDetail {
dismiss()
onImport(recipeDetail)
} else {
alertMessage = error?.localizedDescription ?? String(localized: "The recipe could not be imported. Please check the URL and try again.")
presentAlert = true
}
}
}