diff --git a/Sources/PennForms/FormComponents/DateRangeField.swift b/Sources/PennForms/FormComponents/DateRangeField.swift index d4e2c42..2bec248 100644 --- a/Sources/PennForms/FormComponents/DateRangeField.swift +++ b/Sources/PennForms/FormComponents/DateRangeField.swift @@ -49,9 +49,9 @@ public struct DateRangeField: FormComponent { .bold() } HStack { - let begin = range.lowerBound < lowerDate ? lowerDate : range.lowerBound - let end = range.upperBound > upperDate ? upperDate : range.upperBound - DateRangeSubfield(date: $lowerDate, range: self.range.lowerBound...end, placeholder: lowerPlaceholder, wasSet: $wasSet1) + let begin = max(self.lowerDate, self.range.lowerBound) + let end = min(self.upperDate, self.range.upperBound) + DateRangeSubfield(date: $lowerDate, range: min(self.range.lowerBound, end)...max(self.range.lowerBound, end), placeholder: lowerPlaceholder, wasSet: $wasSet1) DateRangeSubfield(date: $upperDate, range: begin...self.range.upperBound, placeholder: upperPlaceholder, wasSet: $wasSet2) } @@ -69,7 +69,7 @@ public struct DateRangeField: FormComponent { self.lowerDate = self.range.lowerBound == .distantPast ? .now : self.range.lowerBound } .onChange(of: wasSet2) { _ in - self.upperDate = Calendar.current.date(byAdding: .day, value: upperOffset, to: .now) ?? (self.range.upperBound == .distantFuture ? .now : self.range.upperBound) + self.upperDate = min(Calendar.current.date(byAdding: .day, value: upperOffset, to: self.range.lowerBound == .distantPast ? .now : self.range.lowerBound) ?? .now, self.range.upperBound) } } } diff --git a/Sources/PennForms/FormComponents/ImagePicker.swift b/Sources/PennForms/FormComponents/ImagePicker.swift index 1c64bf2..4ea48a7 100644 --- a/Sources/PennForms/FormComponents/ImagePicker.swift +++ b/Sources/PennForms/FormComponents/ImagePicker.swift @@ -31,48 +31,30 @@ public struct ImagePicker: FormComponent { public var body: some View { VStack(alignment: .leading, spacing: 10) { if existingImages.count > 0 { - AsyncImage( - url: URL(string: existingImages[0]), - content: { image in - ZStack { - RoundedRectangle(cornerRadius: 8) - .strokeBorder(style: StrokeStyle(lineWidth: 0.5)) - .frame(width: 350, height: 200) - - image - .resizable() - .aspectRatio(contentMode: .fill) - .frame(width: 350, height: 200) - .clipShape(RoundedRectangle(cornerRadius: 8)) - - } - }, - placeholder: { - ProgressView() - } - ) - } else if selectedImages.count > 0 { - ZStack { - RoundedRectangle(cornerRadius: 8) - .strokeBorder(style: StrokeStyle(lineWidth: 0.5)) - .frame(width: 350, height: 200) - - Image(uiImage: selectedImages[0]) - .resizable() - .aspectRatio(contentMode: .fill) - .frame(width: 350, height: 200) - .clipShape(RoundedRectangle(cornerRadius: 8)) - - - } - } else { + PhotosPicker(selection: $selection, maxSelectionCount: maxSelectionCount - existingImages.count, matching: .any(of: [.images, .not(.videos)])) { - VStack(spacing: 8) { - Image(systemName: "photo.badge.plus") - Text("Add Photos") - } + AsyncImage( + url: URL(string: existingImages[0]), + content: { image in + ZStack { + RoundedRectangle(cornerRadius: 8) + .strokeBorder(style: StrokeStyle(lineWidth: 0.5)) + .frame(width: 350, height: 200) + + image + .resizable() + .aspectRatio(contentMode: .fill) + .frame(width: 350, height: 200) + .clipShape(RoundedRectangle(cornerRadius: 8)) + + } + }, + placeholder: { + ProgressView() + } + ) .frame(width: 350, height: 200) .background(RoundedRectangle(cornerRadius: 8) .strokeBorder(style: StrokeStyle(lineWidth: 1, dash: [7]))) @@ -88,20 +70,87 @@ public struct ImagePicker: FormComponent { } } } + + + + + } else if selectedImages.count > 0 { + PhotosPicker(selection: $selection, + maxSelectionCount: maxSelectionCount - existingImages.count, + matching: .any(of: [.images, .not(.videos)])) { + ZStack { + RoundedRectangle(cornerRadius: 8) + .strokeBorder(style: StrokeStyle(lineWidth: 0.5)) + .frame(width: 350, height: 200) + + Image(uiImage: selectedImages[0]) + .resizable() + .aspectRatio(contentMode: .fill) + .frame(width: 350, height: 200) + .clipShape(RoundedRectangle(cornerRadius: 8)) + + + } + .frame(width: 350, height: 200) + .background(RoundedRectangle(cornerRadius: 8) + .strokeBorder(style: StrokeStyle(lineWidth: 1, dash: [7]))) + .foregroundColor(!showValidationErrors || validator.isValid(selectedImages.count + existingImages.count) ? Color.secondary : Color.red) + } + .onChange(of: selection) { newSelection in + Task { + selectedImages.removeAll() + for item in newSelection { + if let data = try? await item.loadTransferable(type: Data.self), let image = UIImage(data: data) { + selectedImages.append(image) + } + } + } + } + + + + + + } else { + PhotosPicker(selection: $selection, + maxSelectionCount: maxSelectionCount - existingImages.count, + matching: .any(of: [.images, .not(.videos)])) { + VStack(spacing: 8) { + Image(systemName: "photo.badge.plus") + Text("Add Photos") + } + .frame(width: 350, height: 200) + .background(RoundedRectangle(cornerRadius: 8) + .strokeBorder(style: StrokeStyle(lineWidth: 1, dash: [7]))) + .foregroundColor(!showValidationErrors || validator.isValid(selectedImages.count + existingImages.count) ? Color.secondary : Color.red) + } + .onChange(of: selection) { newSelection in + Task { + selectedImages.removeAll() + for item in newSelection { + if let data = try? await item.loadTransferable(type: Data.self), let image = UIImage(data: data) { + selectedImages.append(image) + } + } + } + } } - ScrollView(.horizontal) { HStack(spacing: 8) { - ForEach(Array(existingImages.enumerated()), id: \.offset) { index, image in + ForEach(Array(existingImages.enumerated()), id: \.offset) { index, url in if index != 0 { - ForEach(existingImages, id: \.self) { url in +// ForEach(existingImages, id: \.self) { url in AsyncImage( url: URL(string: url), content: { image in + image.resizable() - .aspectRatio(contentMode: .fit) - .badge(imageStr: "xmark", badgeColor: Color(uiColor: .systemGray3), textColor: Color(uiColor: .systemGray), action: { + .aspectRatio(contentMode: .fill) + .frame(width: 350, height: 200) + .clipShape(RoundedRectangle(cornerRadius: 8)) + .badge(imageStr: "xmark", badgeColor: Color(uiColor: .systemGray3), textColor: + Color(uiColor: .systemGray), action: { withAnimation { existingImages.removeAll(where: { $0 == url }) } @@ -112,48 +161,26 @@ public struct ImagePicker: FormComponent { ProgressView() } ) - } +// } } } - if (existingImages.count == 0 && selectedImages.count-1 > 0) || selectedImages.count > 0 { + if (existingImages.count == 0 && selectedImages.count-1 > 0) || selectedImages.count > 0 { ForEach(Array(selectedImages.enumerated()), id: \.offset) { index, image in if index != 0 { - ZStack { - RoundedRectangle(cornerRadius: 8) - .strokeBorder(style: StrokeStyle(lineWidth: 0.5)) - .frame(width: 120, height: 120) - - Image(uiImage: image) - .resizable() - .aspectRatio(contentMode: .fill) - .frame(width: 120, height: 120) - .clipShape(RoundedRectangle(cornerRadius: 8)) - } + Image(uiImage: image) + .resizable() + .aspectRatio(contentMode: .fill) + .frame(width: 120, height: 120) + .clipShape(RoundedRectangle(cornerRadius: 8)) } } - } if selectedImages.count + existingImages.count < maxSelectionCount { ForEach(0..<(maxSelectionCount - selectedImages.count - existingImages.count), id: \.self) { _ in - PhotosPicker(selection: $selection, - maxSelectionCount: maxSelectionCount - existingImages.count, - matching: .any(of: [.images, .not(.videos)])) { - - Image(systemName: "photo.badge.plus") + RoundedRectangle(cornerRadius: 8) .frame(width: 120, height: 120) - .background(RoundedRectangle(cornerRadius: 8) - .strokeBorder(style: StrokeStyle(lineWidth: 1))) - .foregroundColor(Color.secondary) - } - .onChange(of: selection) { newSelection in - Task { - for item in newSelection { - if let data = try? await item.loadTransferable(type: Data.self), let image = UIImage(data: data) { - selectedImages.append(image) - } - } - } - } + .foregroundColor(Color.gray.opacity(0.5)) // Fill color for the rounded rectangle + } } }