// // ContentView.swift // Shared // // Created by Trey Tartt on 1/5/22. // import SwiftUI import CoreData import Charts struct ContentView: View { @Environment(\.managedObjectContext) private var viewContext @State private var showingSheet = false @State private var showTodayInput = true @ObservedObject var viewModel = ContentModeViewModel() init(){ UITabBar.appearance().backgroundColor = UIColor.systemBackground } var body: some View { TabView { mainView .tabItem { Label("Main", systemImage: "list.dash") } FilterView() .tabItem { Label("Filter", systemImage: "calendar.circle") } GraphView() .tabItem { Label("Stats", systemImage: "chart.line.uptrend.xyaxis") } } } private var settingsButtonView: some View { HStack { Spacer() Button(action: { showingSheet.toggle() }, label: { Image(systemName: "gear") .foregroundColor(Color(UIColor.darkGray)) .font(.system(size: 20)) }).sheet(isPresented: $showingSheet) { SettingsView(editedDataClosure: { withAnimation{ viewModel.updateData() } }) }.padding(.trailing) } } private func weekdayName(fromDate date: Date) -> String { let weekday = Calendar.current.component(.weekday, from: date) let calendar = Calendar.current let dayIndex = ((weekday - 1) + (calendar.firstWeekday - 1)) % 7 return calendar.weekdaySymbols[dayIndex] } private func monthName(fromMonthInt: Int) -> String { let monthName = DateFormatter().monthSymbols[fromMonthInt-1] return monthName } private func dayFormat(fromDate date: Date) -> String { let components = Calendar.current.dateComponents([.day], from: date) let day = components.day! let formatter = NumberFormatter() formatter.numberStyle = .ordinal return formatter.string(from: NSNumber(integerLiteral: day)) ?? "" } private var listView: some View { VStack { List { // for reach year ForEach(viewModel.grouped.sorted(by: { $0.key > $1.key }), id: \.key) { year, months in // for reach month ForEach(months.sorted(by: { $0.key > $1.key }), id: \.key) { month, entries in Section(header: HStack{ Text(monthName(fromMonthInt: month)) .font(.title2) .foregroundColor(Color(UIColor.label)) Text(String(year)) .font(.title2) .foregroundColor(Color(UIColor.label)) }) { // for reach all entries ForEach(entries.sorted(by: { $0.forDate! > $1.forDate! }), id: \.self) { entry in entryListView(entry: entry) }.onDelete(perform: { offsets in withAnimation { viewModel.delete(offsets: offsets, inMonth: month, inYear: year) } }) } } } } .background(Color.clear.ignoresSafeArea()) .onAppear { // Set the default to clear UITableView.appearance().backgroundColor = .clear } } } private func entryListView(entry: MoodEntry) -> some View { HStack { entry.mood.icon .resizable() .aspectRatio(contentMode: .fit) .frame(width: 40, height: 40, alignment: .center) .foregroundColor(entry.mood.color) VStack { HStack { Text(weekdayName(fromDate:entry.forDate!)) .font(.title3) .foregroundColor(Color(UIColor.label)) Text(" - ") .padding([.leading, .trailing], -10) Text(dayFormat(fromDate:entry.forDate!)) .font(.title3) .foregroundColor(Color(UIColor.label)) Spacer() } .multilineTextAlignment(.leading) Text("\(entry.moodString)") .font(.body) .foregroundColor(Color(UIColor.systemGray)) .frame(maxWidth: .infinity, alignment: .leading) } } } private var mainView: some View { ZStack { BGView() VStack{ settingsButtonView if viewModel.shouldShowTodayInput() { AddMoodHeaderView(addItemClosure: { (mood, date) in withAnimation { viewModel.add(mood: mood, forDate: date) } }) .frame(minHeight: 85, maxHeight: 180) .frame(minWidth: 0, maxWidth: .infinity) } else { HeaderStatsView(fakeData: false, backDays: 30) .frame(minHeight: 85, maxHeight: 180) // should match backDays above Text("Past \(30) days") .font(.body) .foregroundColor(Color(UIColor.systemGray)) .frame(maxWidth: .infinity, alignment: .center) } listView .padding(.bottom) } .padding(.top, 50) } } } private let itemFormatter: DateFormatter = { let formatter = DateFormatter() formatter.dateStyle = .short formatter.timeStyle = .medium return formatter }() struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView().environment(\.managedObjectContext, PersistenceController.shared.container.viewContext) .onAppear(perform: { PersistenceController.shared.populateMemory() }) ContentView() .preferredColorScheme(.dark) .environment(\.managedObjectContext, PersistenceController.shared.container.viewContext) } }