SessionListViewController.swift 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. //
  2. // SessionListViewController.swift
  3. // LMS
  4. //
  5. // Created by Suraj Kumar Mandal on 24/08/22.
  6. //
  7. import UIKit
  8. import Toast_Swift
  9. import SideMenu
  10. class SessionListViewController: UIViewController {
  11. @IBOutlet var navigationBar: UINavigationBar!
  12. @IBOutlet var contentScrollView: UIScrollView!
  13. @IBOutlet var customView: UIView!
  14. // @IBOutlet var interventionLabel: UILabel!
  15. // @IBOutlet var interventionTF: UITextField!
  16. // @IBOutlet var interventionLevelLabel: UILabel!
  17. // @IBOutlet var interventionLevelTF: UITextField!
  18. // @IBOutlet var batchLabel: UILabel!
  19. // @IBOutlet var batchTF: UITextField!
  20. @IBOutlet var monthYearLabel: UILabel!
  21. @IBOutlet var monthYearTF: UITextField!
  22. @IBOutlet var sessionListTableView: UITableView!
  23. @IBOutlet var filterButton: UIButton!
  24. @IBOutlet var sessionTableHeightConstraint: NSLayoutConstraint!
  25. var viewModel = SessionListViewModel()
  26. var sessionListModel = [SessionListModel]()
  27. var interventionModel = [SessionInterventionModel]()
  28. var interventionLevelModel = [InterventionLevel]()
  29. var batchListModel = [BatchListModel]()
  30. fileprivate let picker = ToolbarPickerView()
  31. var activeTextField = 0
  32. let userData = DBManager.sharedInstance.database.objects(UserDetailsModel.self)
  33. var interventionId = Int()
  34. var batchId = Int()
  35. var interventionLevelId = Int()
  36. var monthYear = String()
  37. override func viewDidLoad() {
  38. super.viewDidLoad()
  39. // Do any additional setup after loading the view.
  40. setupUI()
  41. viewModel.delegate = self
  42. sessionListTableView.delegate = self
  43. sessionListTableView.dataSource = self
  44. sessionListTableView.addObserver(self, forKeyPath: "contentSize", options: .new, context: nil)
  45. //getInterventionList()
  46. // Set UITableViewAutomaticDimension for automatic cell height calculation.
  47. sessionListTableView.rowHeight = UITableView.automaticDimension
  48. sessionListTableView.estimatedRowHeight = 240 // Estimated average cell height, adjust as needed.
  49. }
  50. override func viewWillAppear(_ animated: Bool) {
  51. getSessionList(month: getCurrentMonth())
  52. createPickerView()
  53. }
  54. override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
  55. if(keyPath == "contentSize") {
  56. if let newvalue = change?[.newKey] {
  57. DispatchQueue.main.async {
  58. let newsize = newvalue as! CGSize
  59. self.sessionTableHeightConstraint.constant = newsize.height
  60. }
  61. }
  62. }
  63. }
  64. func setupUI() {
  65. navigationBar.topItem?.title = "Session List"
  66. // Hide unused fields
  67. // interventionLabel.isHidden = true
  68. // interventionTF.isHidden = true
  69. // interventionLevelLabel.isHidden = true
  70. // interventionLevelTF.isHidden = true
  71. // batchLabel.isHidden = true
  72. // batchTF.isHidden = true
  73. customView.isHidden = false
  74. customView.layer.cornerRadius = 10
  75. // interventionTF.isUserInteractionEnabled = true
  76. // interventionLevelTF.isUserInteractionEnabled = false
  77. // batchTF.isUserInteractionEnabled = false
  78. filterButton.layer.cornerRadius = filterButton.frame.size.height / 2
  79. let dateFormatter = DateFormatter()
  80. dateFormatter.dateFormat = "MM-yyyy"
  81. let currentDate = Date()
  82. let formattedDate = dateFormatter.string(from: currentDate)
  83. // Set the formatted date as the text of the UITextField
  84. monthYearTF.text = formattedDate
  85. }
  86. func createPickerView() {
  87. monthYearTF.delegate = self
  88. self.monthYearTF.datePicker(target: self,
  89. doneAction: #selector(doneAction),
  90. cancelAction: #selector(cancelAction),
  91. datePickerMode: .date)
  92. // //1
  93. // self.interventionTF.delegate = self
  94. // self.interventionTF.inputView = self.picker
  95. // self.interventionTF.inputAccessoryView = self.picker.toolbar
  96. // //2
  97. // self.interventionLevelTF.delegate = self
  98. // self.interventionLevelTF.inputView = self.picker
  99. // self.interventionLevelTF.inputAccessoryView = self.picker.toolbar
  100. // //3
  101. // self.batchTF.delegate = self
  102. // self.batchTF.inputView = self.picker
  103. // self.batchTF.inputAccessoryView = self.picker.toolbar
  104. //
  105. // self.picker.delegate = self
  106. // self.picker.dataSource = self
  107. // self.picker.toolbarDelegate = self
  108. }
  109. @objc func cancelAction() {
  110. self.monthYearTF.resignFirstResponder()
  111. }
  112. @objc func doneAction() {
  113. if let datePickerView = self.monthYearTF.inputView as? UIDatePicker {
  114. let dateFormatter = DateFormatter()
  115. dateFormatter.dateFormat = "MM-yyyy"
  116. let dateString = dateFormatter.string(from: datePickerView.date)
  117. self.monthYearTF.text = dateString
  118. print(datePickerView.date)
  119. print(dateString)
  120. self.getSessionList(month: self.monthYearTF.text ?? "")
  121. self.monthYearTF.resignFirstResponder()
  122. }
  123. }
  124. func getSessionList(month:String) {
  125. if Reachability.isConnectedToNetwork() {
  126. viewModel.getSessionList(userId: userData[0].id, interventionId: "", batchId: "", schoolId: "", interventionLevelId: "", month: month)
  127. } else {
  128. Alert.showInternetFailureAlert(on: self)
  129. }
  130. }
  131. func getInterventionList() {
  132. if Reachability.isConnectedToNetwork() {
  133. viewModel.getSessionIntervention()
  134. } else {
  135. Alert.showInternetFailureAlert(on: self)
  136. }
  137. }
  138. func formattedDateFromString(dateString: String, withFormat format: String) -> String? {
  139. let inputFormatter = DateFormatter()
  140. inputFormatter.dateFormat = "yyyy-MM-dd"
  141. if let date = inputFormatter.date(from: dateString) {
  142. let outputFormatter = DateFormatter()
  143. outputFormatter.dateFormat = format
  144. return outputFormatter.string(from: date)
  145. }
  146. return nil
  147. }
  148. func formattedTimeFromString(dateString: String, withFormat format: String) -> String? {
  149. let inputFormatter = DateFormatter()
  150. inputFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
  151. if let date = inputFormatter.date(from: dateString) {
  152. let outputFormatter = DateFormatter()
  153. outputFormatter.dateFormat = format
  154. outputFormatter.timeStyle = .short
  155. return outputFormatter.string(from: date)
  156. }
  157. return nil
  158. }
  159. func getCurrentMonth() -> String {
  160. let date = Date()
  161. let format = DateFormatter()
  162. format.dateFormat = "MM-yyyy"
  163. let formattedMonth = format.string(from: date)
  164. return formattedMonth
  165. }
  166. private func executeRepeatedly() {
  167. // put your code here
  168. self.sessionListTableView.reloadData()
  169. DispatchQueue.main.asyncAfter(deadline: .now() + 60.0) { [weak self] in
  170. self?.executeRepeatedly()
  171. }
  172. }
  173. /*
  174. // MARK: - Navigation
  175. // In a storyboard-based application, you will often want to do a little preparation before navigation
  176. override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
  177. // Get the new view controller using segue.destination.
  178. // Pass the selected object to the new view controller.
  179. }
  180. */
  181. @IBAction func sideMenuAction(_ sender: UIBarButtonItem) {
  182. let menu = storyboard!.instantiateViewController(withIdentifier: "SideMenuNavigationController") as! SideMenuNavigationController
  183. present(menu, animated: true, completion: nil)
  184. }
  185. @IBAction func filterAction(_ sender: Any) {
  186. if customView.isHidden == true {
  187. customView.isHidden = false
  188. //contentScrollView.scrollToTop()
  189. contentScrollView.scrollViewToTop(customView)
  190. } else {
  191. customView.isHidden = true
  192. }
  193. }
  194. }
  195. extension SessionListViewController: SessionListProtocol {
  196. func startLoader() {
  197. ActivityIndicator.start()
  198. }
  199. func stopLoader() {
  200. ActivityIndicator.stop()
  201. }
  202. func showError(error: String) {
  203. self.view.makeToast(error)
  204. }
  205. func sessionListModel(model: [SessionListModel]) {
  206. let dateSortedData = model.sorted(by: {$0.date! > $1.date!})
  207. let timeSortedData = dateSortedData.sorted(by: {$0.startTime! > $1.startTime!})
  208. self.sessionListModel = timeSortedData
  209. self.executeRepeatedly()
  210. }
  211. func interventionModel(model: [SessionInterventionModel]) {
  212. self.interventionModel = model
  213. //interventionLevelTF.isUserInteractionEnabled = true
  214. }
  215. func interventionLevelModel(model: [InterventionLevel]) {
  216. self.interventionLevelModel = model
  217. //batchTF.isUserInteractionEnabled = true
  218. }
  219. func batchListModel(model: [BatchListModel]) {
  220. self.batchListModel = model
  221. }
  222. }
  223. //extension SessionListViewController: UIPickerViewDelegate, UIPickerViewDataSource {
  224. // // MARK: UIPickerView Delegation
  225. //
  226. // func numberOfComponents(in pickerView: UIPickerView) -> Int {
  227. // return 1
  228. // }
  229. //
  230. // func pickerView( _ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
  231. // switch activeTextField
  232. // {
  233. // case 1:
  234. // return interventionModel.count
  235. // case 2:
  236. // return interventionLevelModel.count
  237. // case 3:
  238. // return batchListModel.count
  239. // default:
  240. // return 0
  241. //
  242. // }
  243. // }
  244. //
  245. // func pickerView( _ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
  246. // switch activeTextField{
  247. // case 1:
  248. // return interventionModel[row].interventionName
  249. // case 2:
  250. // return interventionLevelModel[row].interventionLevels
  251. // case 3:
  252. // return batchListModel[row].batchName
  253. // default:
  254. // return ""
  255. // }
  256. // }
  257. //
  258. // func pickerView( _ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
  259. // switch activeTextField{
  260. // case 1:
  261. // //interventionTF.text = interventionModel[row].interventionName
  262. // break
  263. // case 2:
  264. // //interventionLevelTF.text = interventionLevelModel[row].interventionLevels
  265. // break
  266. // case 3:
  267. // //batchTF.text = batchListModel[row].batchName
  268. // break
  269. // default:
  270. // break
  271. // }
  272. // }
  273. //}
  274. //extension SessionListViewController: UITextFieldDelegate {
  275. // func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
  276. // switch textField {
  277. // case interventionTF:
  278. // return false
  279. // case interventionLevelTF:
  280. // return false
  281. // case batchTF:
  282. // return false
  283. // default:
  284. // return true
  285. // }
  286. // }
  287. //
  288. // // when user select a textfield, this method will be called
  289. // func textFieldDidBeginEditing(_ textField: UITextField) {
  290. // switch textField {
  291. // case interventionTF:
  292. // activeTextField = 1
  293. // picker.reloadAllComponents()
  294. // case interventionLevelTF:
  295. // activeTextField = 2
  296. // picker.reloadAllComponents()
  297. // case batchTF:
  298. // activeTextField = 3
  299. // picker.reloadAllComponents()
  300. // default:
  301. // activeTextField = 0
  302. // }
  303. // }
  304. //}
  305. //extension SessionListViewController: ToolbarPickerViewDelegate {
  306. // func didTapDone() {
  307. // switch activeTextField {
  308. // case 1:
  309. // let row = self.picker.selectedRow(inComponent: 0)
  310. // self.picker.selectRow(row, inComponent: 0, animated: false)
  311. // self.interventionTF.text = interventionModel[row].interventionName
  312. // self.interventionId = interventionModel[row].id ?? 0
  313. // if Reachability.isConnectedToNetwork() {
  314. // viewModel.getSessionList(userId: userData[0].id, interventionId: self.interventionId, batchId: "", schoolId: "", interventionLevelId: "", month: getCurrentMonth())
  315. // }
  316. // self.interventionTF.resignFirstResponder()
  317. // if Reachability.isConnectedToNetwork() {
  318. // self.viewModel.getInterventionLevel(id: interventionModel[row].id ?? 0)
  319. // }
  320. // case 2:
  321. // let row = self.picker.selectedRow(inComponent: 0)
  322. // self.picker.selectRow(row, inComponent: 0, animated: false)
  323. // self.interventionLevelTF.text = interventionLevelModel[row].interventionLevels
  324. // self.interventionLevelId = interventionLevelModel[row].id ?? 0
  325. // if Reachability.isConnectedToNetwork() {
  326. // viewModel.getSessionList(userId: userData[0].id, interventionId: self.interventionId, batchId: "", schoolId: "", interventionLevelId: self.interventionLevelId, month: getCurrentMonth())
  327. // }
  328. // self.interventionLevelTF.resignFirstResponder()
  329. // if Reachability.isConnectedToNetwork() {
  330. // self.viewModel.getBatchList()
  331. // }
  332. // case 3:
  333. // let row = self.picker.selectedRow(inComponent: 0)
  334. // self.picker.selectRow(row, inComponent: 0, animated: false)
  335. // self.batchTF.text = batchListModel[row].batchName ?? ""
  336. // self.batchId = batchListModel[row].id ?? 0
  337. // if Reachability.isConnectedToNetwork() {
  338. // viewModel.getSessionList(userId: userData[0].id, interventionId: self.interventionId, batchId: self.batchId, schoolId: "", interventionLevelId: self.interventionLevelId, month: getCurrentMonth())
  339. // }
  340. // self.batchTF.resignFirstResponder()
  341. // default:
  342. // return
  343. // }
  344. // }
  345. // func didTapCancel() {
  346. // switch activeTextField {
  347. // case 1:
  348. // self.interventionTF.text = nil
  349. // self.interventionTF.resignFirstResponder()
  350. // case 2:
  351. // self.interventionLevelTF.text = nil
  352. // self.interventionLevelTF.resignFirstResponder()
  353. // case 3:
  354. // self.batchTF.text = nil
  355. // self.batchTF.resignFirstResponder()
  356. // default:
  357. // return
  358. // }
  359. // }
  360. //}
  361. extension SessionListViewController: UITableViewDelegate, UITableViewDataSource, UICollectionViewDelegateFlowLayout {
  362. func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  363. return sessionListModel.count
  364. }
  365. func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  366. guard let cell = tableView.dequeueReusableCell(withIdentifier: "SessionListTableViewCell", for: indexPath) as? SessionListTableViewCell else {
  367. return UITableViewCell()
  368. }
  369. cell.listCustomView.layer.cornerRadius = 10
  370. cell.listCustomView.layer.borderWidth = 1
  371. cell.listCustomView.layer.borderColor = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1)
  372. cell.serialNumberLabel.text = "\(indexPath.row + 1)"
  373. cell.meetingNameLabel.text = sessionListModel[indexPath.row].scheduleTitle
  374. cell.batchLabel.text = sessionListModel[indexPath.row].batchName
  375. cell.teacherLabel.text = "Teacher: \(sessionListModel[indexPath.row].teacherFirstName ?? "") \(sessionListModel[indexPath.row].teacherLastName ?? "")"
  376. cell.interventionNameLabel.text = "Intervention Name: \(sessionListModel[indexPath.row].interventionName ?? "")"
  377. cell.dateLabel.text = " " + (formattedDateFromString(dateString: sessionListModel[indexPath.row].date!, withFormat: "dd MMM") ?? "") + " "
  378. cell.timeLabel.text = (formattedTimeFromString(dateString: sessionListModel[indexPath.row].startTime!, withFormat: "HH:mm") ?? "") + " to " + (formattedTimeFromString(dateString: sessionListModel[indexPath.row].endTime!, withFormat: "HH:mm") ?? "")
  379. cell.joinClassButton.layer.cornerRadius = 5
  380. if sessionListModel[indexPath.row].offline == true {
  381. cell.activeStatusLabel.text = "Online"
  382. cell.activeIndicatorImageView.tintColor = #colorLiteral(red: 0.3843137255, green: 0.6470588235, blue: 0.262745098, alpha: 1)
  383. cell.joinClassButton.isHidden = false
  384. } else {
  385. cell.activeStatusLabel.text = "Offline"
  386. cell.activeIndicatorImageView.tintColor = #colorLiteral(red: 0.9098039216, green: 0.2980392157, blue: 0.2470588235, alpha: 1)
  387. cell.joinClassButton.isHidden = true
  388. }
  389. let date = Date()
  390. let format = DateFormatter()
  391. format.dateFormat = "yyyy-MM-dd HH:mm:ss"
  392. let time = format.string(from: date)
  393. let currentTime = format.date(from: time)
  394. let startTime = format.date(from: sessionListModel[indexPath.row].startTime!)?.addingTimeInterval(TimeInterval(10.0 * 60.0))
  395. let endTime = format.date(from: sessionListModel[indexPath.row].endTime!)?.addingTimeInterval(TimeInterval(20.0 * 60.0))
  396. if currentTime! > startTime! && currentTime! < endTime! {
  397. cell.joinClassButton.backgroundColor = #colorLiteral(red: 0.00400000019, green: 0.200000003, blue: 0.3919999897, alpha: 1)
  398. cell.joinClassButton.tag = indexPath.row
  399. cell.joinClassButton.addTarget(self, action: #selector(joinClass), for: .touchUpInside)
  400. } else {
  401. cell.joinClassButton.backgroundColor = UIColor.lightGray
  402. cell.joinClassButton.isUserInteractionEnabled = false
  403. }
  404. return cell
  405. }
  406. @objc func joinClass(sender: UIButton){
  407. print(sender.tag)
  408. guard let url = URL(string: sessionListModel[sender.tag].link ?? "") else { return }
  409. print(sessionListModel[sender.tag].link ?? "")
  410. UIApplication.shared.open(url)
  411. }
  412. func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
  413. return UITableView.automaticDimension
  414. }
  415. }
  416. extension SessionListViewController: UITextFieldDelegate {
  417. // MARK: - UITextFieldDelegate methods
  418. func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
  419. switch textField {
  420. case monthYearTF:
  421. return false
  422. default:
  423. return true
  424. }
  425. }
  426. }