fix: use LocationSearchSheet for Start/End Location fields
Replaces inline text fields with buttons that open LocationSearchSheet, matching the must-stop location picker UI for consistency. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -39,6 +39,8 @@ struct TripCreationView: View {
|
|||||||
case mustStop
|
case mustStop
|
||||||
case preferred
|
case preferred
|
||||||
case homeLocation
|
case homeLocation
|
||||||
|
case startLocation
|
||||||
|
case endLocation
|
||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
@@ -122,9 +124,12 @@ struct TripCreationView: View {
|
|||||||
viewModel.addMustStopLocation(location)
|
viewModel.addMustStopLocation(location)
|
||||||
case .preferred:
|
case .preferred:
|
||||||
viewModel.addPreferredCity(location.name)
|
viewModel.addPreferredCity(location.name)
|
||||||
case .homeLocation:
|
case .homeLocation, .startLocation:
|
||||||
viewModel.startLocationText = location.name
|
viewModel.startLocationText = location.name
|
||||||
viewModel.startLocation = location
|
viewModel.startLocation = location
|
||||||
|
case .endLocation:
|
||||||
|
viewModel.endLocationText = location.name
|
||||||
|
viewModel.endLocation = location
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -240,71 +245,68 @@ struct TripCreationView: View {
|
|||||||
|
|
||||||
private var locationSection: some View {
|
private var locationSection: some View {
|
||||||
ThemedSection(title: "Locations") {
|
ThemedSection(title: "Locations") {
|
||||||
// Start Location with suggestions
|
// Start Location - opens search sheet
|
||||||
VStack(alignment: .leading, spacing: 0) {
|
locationButton(
|
||||||
ThemedTextField(
|
label: "Start Location",
|
||||||
label: "Start Location",
|
icon: "location.circle.fill",
|
||||||
placeholder: "Where are you starting from?",
|
location: viewModel.startLocation,
|
||||||
text: $viewModel.startLocationText,
|
placeholder: "Where are you starting from?"
|
||||||
icon: "location.circle.fill"
|
) {
|
||||||
)
|
cityInputType = .startLocation
|
||||||
.onChange(of: viewModel.startLocationText) { _, newValue in
|
showCityInput = true
|
||||||
searchLocation(query: newValue, isStart: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Suggestions for start location
|
|
||||||
if !startLocationSuggestions.isEmpty {
|
|
||||||
locationSuggestionsList(
|
|
||||||
suggestions: startLocationSuggestions,
|
|
||||||
isLoading: isSearchingStart
|
|
||||||
) { result in
|
|
||||||
viewModel.startLocationText = result.name
|
|
||||||
viewModel.startLocation = result.toLocationInput()
|
|
||||||
startLocationSuggestions = []
|
|
||||||
}
|
|
||||||
} else if isSearchingStart {
|
|
||||||
HStack {
|
|
||||||
ThemedSpinnerCompact(size: 14)
|
|
||||||
Text("Searching...")
|
|
||||||
.font(.subheadline)
|
|
||||||
.foregroundStyle(Theme.textMuted(colorScheme))
|
|
||||||
}
|
|
||||||
.padding(.top, Theme.Spacing.xs)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// End Location with suggestions
|
// End Location - opens search sheet
|
||||||
VStack(alignment: .leading, spacing: 0) {
|
locationButton(
|
||||||
ThemedTextField(
|
label: "End Location",
|
||||||
label: "End Location",
|
icon: "mappin.circle.fill",
|
||||||
placeholder: "Where do you want to end up?",
|
location: viewModel.endLocation,
|
||||||
text: $viewModel.endLocationText,
|
placeholder: "Where do you want to end up?"
|
||||||
icon: "mappin.circle.fill"
|
) {
|
||||||
)
|
cityInputType = .endLocation
|
||||||
.onChange(of: viewModel.endLocationText) { _, newValue in
|
showCityInput = true
|
||||||
searchLocation(query: newValue, isStart: false)
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Suggestions for end location
|
private func locationButton(
|
||||||
if !endLocationSuggestions.isEmpty {
|
label: String,
|
||||||
locationSuggestionsList(
|
icon: String,
|
||||||
suggestions: endLocationSuggestions,
|
location: LocationInput?,
|
||||||
isLoading: isSearchingEnd
|
placeholder: String,
|
||||||
) { result in
|
action: @escaping () -> Void
|
||||||
viewModel.endLocationText = result.name
|
) -> some View {
|
||||||
viewModel.endLocation = result.toLocationInput()
|
VStack(alignment: .leading, spacing: Theme.Spacing.xs) {
|
||||||
endLocationSuggestions = []
|
Text(label)
|
||||||
}
|
.font(.subheadline)
|
||||||
} else if isSearchingEnd {
|
.fontWeight(.medium)
|
||||||
HStack {
|
.foregroundStyle(Theme.warmOrange)
|
||||||
ThemedSpinnerCompact(size: 14)
|
|
||||||
Text("Searching...")
|
Button(action: action) {
|
||||||
.font(.subheadline)
|
HStack(spacing: Theme.Spacing.md) {
|
||||||
|
Image(systemName: icon)
|
||||||
|
.foregroundStyle(Theme.warmOrange)
|
||||||
|
.frame(width: 24)
|
||||||
|
|
||||||
|
if let location = location {
|
||||||
|
Text(location.name)
|
||||||
|
.foregroundStyle(Theme.textPrimary(colorScheme))
|
||||||
|
} else {
|
||||||
|
Text(placeholder)
|
||||||
.foregroundStyle(Theme.textMuted(colorScheme))
|
.foregroundStyle(Theme.textMuted(colorScheme))
|
||||||
}
|
}
|
||||||
.padding(.top, Theme.Spacing.xs)
|
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
Image(systemName: "chevron.right")
|
||||||
|
.font(.caption)
|
||||||
|
.foregroundStyle(Theme.textMuted(colorScheme))
|
||||||
}
|
}
|
||||||
|
.padding(Theme.Spacing.md)
|
||||||
|
.background(Theme.cardBackgroundElevated(colorScheme))
|
||||||
|
.clipShape(RoundedRectangle(cornerRadius: Theme.CornerRadius.medium))
|
||||||
}
|
}
|
||||||
|
.buttonStyle(.plain)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user