// // CalendarViewController.swift // VDSSample // // Created by Kanamarlapudi, Vasavi on 19/04/24. // import Foundation import UIKit import VDS import Combine import VDSCoreTokens class CalendarViewController: BaseViewController { let label = Label() var containerBorderSwitch = Toggle() var hideCurrentDateIndicatorSwitch = Toggle() var transparentBgSwitch = Toggle() var indicatorOneSwitch = Toggle() var indicatorTwoSwitch = Toggle() var indicatorThreeSwitch = Toggle() var clearActiveDatesSwitch = Toggle() var clearInactiveDatesSwitch = Toggle() var activeDatesField = TextField() var inactiveDatesField = TextField() var legendOneField = TextField() var legendTwoField = TextField() var legendThreeField = TextField() private var minDatePicker: UIDatePicker = UIDatePicker() private var maxDatePicker: UIDatePicker = UIDatePicker() private var indicatorOnePicker: UIDatePicker = UIDatePicker() private var indicatorTwoPicker: UIDatePicker = UIDatePicker() private var indicatorThreePicker: UIDatePicker = UIDatePicker() private var activeDatePicker: UIDatePicker = UIDatePicker().with { $0.datePickerMode = .date } private var inactiveDatePicker: UIDatePicker = UIDatePicker().with { $0.datePickerMode = .date } var indicators: [CalendarBase.CalendarIndicatorModel] = [] let indicatorOnePickerTag = 1 let indicatorTwoPickerTag = 2 let indicatorThreePickerTag = 3 let minDatePickerTag = 4 let maxDatePickerTag = 5 let activeDatePickerTag = 6 let inactiveDatePickerTag = 7 override func viewDidLoad() { super.viewDidLoad() addContentTopView(view: component) component.minDate = Date().startOfMonth component.maxDate = Date().endOfMonth component.onChange = { [weak self] control in self?.label.text = DateFormatter.localizedString(from: control.selectedDate, dateStyle: .short, timeStyle: .none) } minDatePicker.date = component.minDate maxDatePicker.date = component.maxDate setupPicker() setupModel() } override func setupForm() { super.setupForm() configurePicker(indicatorOnePicker) indicatorOnePicker.tag = indicatorOnePickerTag configurePicker(indicatorTwoPicker) indicatorTwoPicker.tag = indicatorTwoPickerTag configurePicker(indicatorThreePicker) indicatorThreePicker.tag = indicatorThreePickerTag configurePicker(minDatePicker) minDatePicker.tag = minDatePickerTag configurePicker(maxDatePicker) maxDatePicker.tag = maxDatePickerTag configurePicker(activeDatePicker) activeDatePicker.tag = activeDatePickerTag configurePicker(inactiveDatePicker) inactiveDatePicker.tag = inactiveDatePickerTag indicators = [ .init(label: "Due Date", date: indicatorOnePicker.date), .init(label: "Auto Pay", date: indicatorTwoPicker.date), .init(label: "Scheduled", date: indicatorThreePicker.date) ] //add form rows addFormRow(label: "onChange", view: label) addFormRow(label: "Surface", view: surfacePickerSelectorView) addFormRow(label: "Hide Container Border", view: containerBorderSwitch, pinTrailing: false) addFormRow(label: "Hide Current Date Indicator", view: hideCurrentDateIndicatorSwitch, pinTrailing: false) addFormRow(label: "Min Date", view: minDatePicker) addFormRow(label: "Max Date", view: maxDatePicker) addFormRow(label: "Transparent Background", view: transparentBgSwitch, pinTrailing: false) addFormRow(label: "Active Dates", view: activeDatesField) addFormRow(label: "Select ActiveDate", view: activeDatePicker) addFormRow(label: "Clear Active Dates", view: clearActiveDatesSwitch, pinTrailing: false) addFormRow(label: "Inactive Dates", view: inactiveDatesField) addFormRow(label: "Select InActiveDate", view: inactiveDatePicker) addFormRow(label: "Clear Inactive Dates", view: clearInactiveDatesSwitch, pinTrailing: false) addFormRow(label: "Indicator One", view: indicatorOneSwitch, pinTrailing: false) addFormRow(label: "Indicator Two", view: indicatorTwoSwitch, pinTrailing: false) addFormRow(label: "Indicator Three", view: indicatorThreeSwitch, pinTrailing: false) addFormRow(label: "Legend One", view: legendOneField) addFormRow(label: "Legend Two", view: legendTwoField) addFormRow(label: "Legend Three", view: legendThreeField) addFormRow(label: "Indicator One Date", view: indicatorOnePicker) addFormRow(label: "Indicator Two Date", view: indicatorTwoPicker) addFormRow(label: "Indicator Three Date", view: indicatorThreePicker) activeDatesField.isUserInteractionEnabled = false inactiveDatesField.isUserInteractionEnabled = false activeDatesField.isEnabled = false inactiveDatesField.isEnabled = false containerBorderSwitch.onChange = { [weak self] sender in guard let self else { return } component.hideContainerBorder = sender.isOn } hideCurrentDateIndicatorSwitch.onChange = { [weak self] sender in guard let self else { return } component.hideCurrentDateIndicator = sender.isOn } transparentBgSwitch.onChange = { [weak self] sender in guard let self else { return } component.transparentBackground = sender.isOn } clearActiveDatesSwitch.onChange = { [weak self] sender in guard let self else { return } if sender.isOn { activeDatesField.text = "" component.activeDates = [] } } clearInactiveDatesSwitch.onChange = { [weak self] sender in guard let self else { return } if sender.isOn { inactiveDatesField.text = "" component.inactiveDates = [] } } legendOneField .textPublisher .sink { [weak self] text in self?.updateIndicatorData(label: text, date: self?.indicatorOnePicker.date, index: 0) }.store(in: &subscribers) legendTwoField .textPublisher .sink { [weak self] text in self?.updateIndicatorData(label: text, date: self?.indicatorTwoPicker.date, index: 1) }.store(in: &subscribers) legendThreeField .textPublisher .sink { [weak self] text in self?.updateIndicatorData(label: text, date: self?.indicatorThreePicker.date, index: 2) }.store(in: &subscribers) indicatorOneSwitch.onChange = { [weak self] sender in guard let self else { return } if !sender.isOn { component.indicators.removeAll() } else { self.setIndicatorsData() } } indicatorTwoSwitch.onChange = { [weak self] sender in guard let self else { return } if !sender.isOn { if component.indicators.count > 2 { component.indicators.removeLast() component.indicators.removeLast() } else if component.indicators.count == 2 { component.indicators.removeLast() } } else { self.setIndicatorsData() } } indicatorThreeSwitch.onChange = { [weak self] sender in guard let self else { return } if !sender.isOn { if component.indicators.count > 2 { component.indicators.removeLast() } } else { self.setIndicatorsData() } } } func setupPicker(){ surfacePickerSelectorView.onPickerDidSelect = { [weak self] item in self?.component.surface = item self?.contentTopView.backgroundColor = item.color } } func setupModel() { let calendar = Calendar.current let indicatorDate = calendar.startOfDay(for: calendar.date(byAdding: .day, value: 1, to: Date())!) component.indicators = indicators legendOneField.text = "Due Date" legendTwoField.text = "Auto Pay" legendThreeField.text = "Scheduled" indicatorOneSwitch.isOn = true indicatorTwoSwitch.isOn = true indicatorThreeSwitch.isOn = true hideCurrentDateIndicatorSwitch.isOn = false indicatorOnePicker.date = indicatorDate indicatorTwoPicker.date = indicatorDate indicatorThreePicker.date = indicatorDate updateIndicatorData(label: legendOneField.text ?? "", date: indicatorOnePicker.date, index: 0) updateIndicatorData(label: legendTwoField.text ?? "", date: indicatorTwoPicker.date, index: 1) updateIndicatorData(label: legendThreeField.text ?? "", date: indicatorThreePicker.date, index: 2) } func updateIndicatorData(label: String = "", date: Date?, index:Int) { indicators[index].label = label indicators[index].date = date ?? Date() setIndicatorsData() } func setIndicatorsData() { if indicatorOneSwitch.isOn && indicatorTwoSwitch.isOn && indicatorThreeSwitch.isOn { component.indicators = [ .init(label: self.legendOneField.text ?? "", date: indicatorOnePicker.date), .init(label: self.legendTwoField.text ?? "", date: indicatorTwoPicker.date), .init(label: self.legendThreeField.text ?? "", date: indicatorThreePicker.date) ] } else if indicatorOneSwitch.isOn && indicatorTwoSwitch.isOn && !indicatorThreeSwitch.isOn { component.indicators = [ .init(label: self.legendOneField.text ?? "", date: indicatorOnePicker.date), .init(label: self.legendTwoField.text ?? "", date: indicatorTwoPicker.date), ] } else if indicatorOneSwitch.isOn && !indicatorTwoSwitch.isOn { component.indicators = [ .init(label: self.legendOneField.text ?? "", date: indicatorOnePicker.date), ] } } func configurePicker(_ sender:UIDatePicker) { // Set some of UIDatePicker properties sender.timeZone = NSTimeZone.local sender.backgroundColor = UIColor.white // Add an event to call onDidChangeDate function when value is changed. sender.addTarget(self, action: #selector(self.datePickerValueChanged(_:)), for: .valueChanged) } @objc func datePickerValueChanged(_ sender: UIDatePicker){ switch sender.tag { case indicatorOnePickerTag: updateIndicatorData(label: legendOneField.text ?? "", date: sender.date, index: 0) case indicatorTwoPickerTag: updateIndicatorData(label: legendTwoField.text ?? "", date: sender.date, index: 1) case indicatorThreePickerTag: updateIndicatorData(label: legendThreeField.text ?? "", date: sender.date, index: 2) case minDatePickerTag: component.minDate = sender.date case maxDatePickerTag: component.maxDate = sender.date case activeDatePickerTag: component.activeDates.append(sender.date) var text = activeDatesField.text if let textEmpty = text?.isEmpty, textEmpty == true { text?.append("") } else { text?.append(", ") } text?.append("\(self.getSelectedDate(with: sender.date))") clearActiveDatesSwitch.isOn = false activeDatesField.text = text case inactiveDatePickerTag: component.inactiveDates.append(sender.date) var text = inactiveDatesField.text if let textEmpty = text?.isEmpty, textEmpty == true { text?.append("") } else { text?.append(", ") } text?.append("\(self.getSelectedDate(with: sender.date))") clearInactiveDatesSwitch.isOn = false inactiveDatesField.text = text default: break } } func getSelectedDate(with date:Date) -> String { let dateFormatter: DateFormatter = DateFormatter() dateFormatter.dateFormat = "MM/dd/yyyy" let day: String = dateFormatter.string(from: date) return day } }