feat(itinerary): add row views for itinerary items
Add specialized row components for the new unified itinerary system: - DayHeaderRow: Day number, date display, and add item button - GameItemRow: Prominent card with sport color bar for games - TravelItemRow: Gold-styled travel segments with drag handle - CustomItemRow: Minimal custom items with icon, title, and optional time All views follow existing Theme patterns and use SportColorBar for consistency. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
//
|
||||
// CustomItemRow.swift
|
||||
// SportsTime
|
||||
//
|
||||
// Row view for displaying custom user-added items in the itinerary.
|
||||
// Minimal styling with drag handle for reordering.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct CustomItemRow: View {
|
||||
let item: ItineraryItem
|
||||
let onTap: () -> Void
|
||||
|
||||
@Environment(\.colorScheme) private var colorScheme
|
||||
|
||||
private var customInfo: CustomInfo? {
|
||||
item.customInfo
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
Button(action: onTap) {
|
||||
HStack(spacing: Theme.Spacing.md) {
|
||||
// Drag handle
|
||||
Image(systemName: "line.3.horizontal")
|
||||
.font(.title3)
|
||||
.foregroundStyle(Theme.textMuted(colorScheme))
|
||||
|
||||
// Icon
|
||||
if let info = customInfo {
|
||||
Text(info.icon)
|
||||
.font(.title3)
|
||||
}
|
||||
|
||||
// Title
|
||||
if let info = customInfo {
|
||||
Text(info.title)
|
||||
.font(.body)
|
||||
.foregroundStyle(Theme.textPrimary(colorScheme))
|
||||
}
|
||||
|
||||
Spacer()
|
||||
|
||||
// Time (if set)
|
||||
if let time = customInfo?.time {
|
||||
Text(time.formatted(.dateTime.hour().minute()))
|
||||
.font(.caption)
|
||||
.foregroundStyle(Theme.textSecondary(colorScheme))
|
||||
}
|
||||
}
|
||||
.padding(.vertical, Theme.Spacing.sm)
|
||||
.padding(.horizontal, Theme.Spacing.md)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
let customInfo = CustomInfo(
|
||||
title: "Dinner at Pizzeria",
|
||||
icon: "\u{1F355}",
|
||||
time: Date()
|
||||
)
|
||||
let item = ItineraryItem(
|
||||
tripId: UUID(),
|
||||
day: 1,
|
||||
sortOrder: 2.0,
|
||||
kind: .custom(customInfo)
|
||||
)
|
||||
|
||||
VStack(spacing: 16) {
|
||||
CustomItemRow(item: item, onTap: {})
|
||||
|
||||
// Without time
|
||||
let noTimeInfo = CustomInfo(title: "Visit Museum", icon: "\u{1F3DB}", time: nil)
|
||||
let noTimeItem = ItineraryItem(tripId: UUID(), day: 1, sortOrder: 3.0, kind: .custom(noTimeInfo))
|
||||
CustomItemRow(item: noTimeItem, onTap: {})
|
||||
}
|
||||
.padding()
|
||||
.background(Color.gray.opacity(0.1))
|
||||
}
|
||||
Reference in New Issue
Block a user