filter view

all workout filter view is its own view
all workout filter view is the top of all workout view
This commit is contained in:
Trey t
2024-11-25 09:48:44 -08:00
parent 63b7a2daa5
commit 4b6352b8fd
4 changed files with 157 additions and 105 deletions

View File

@@ -61,3 +61,41 @@ struct Workout: Codable, Identifiable, Equatable {
allSupersetExecercise = try container.decodeIfPresent([SupersetExercise].self, forKey: .allSupersetExecercise)
}
}
extension Array where Element == Workout {
func filterWorkouts(searchString: String, filteredRegisterdUser: RegisteredUser?) -> [Workout] {
var matchingWorkouts = [Workout]()
if (!searchString.isEmpty && searchString.count > 0) {
matchingWorkouts = self.filter({
if $0.name.lowercased().contains(searchString.lowercased()) {
return true
}
if let equipment = $0.equipment?.joined(separator: "").lowercased(),
equipment.contains(searchString.lowercased()) {
return true
}
if let muscles = $0.muscles?.joined(separator: "").lowercased(),
muscles.contains(searchString.lowercased()) {
return true
}
return false
})
}
if matchingWorkouts.isEmpty {
matchingWorkouts.append(contentsOf: self)
}
if let filteredRegisterdUser = filteredRegisterdUser {
matchingWorkouts = matchingWorkouts.filter({
$0.registeredUser == filteredRegisterdUser
})
}
return matchingWorkouts
}
}

View File

@@ -7,17 +7,17 @@
import SwiftUI
enum SortType: String, CaseIterable {
case name = "Name"
case date = "Date"
}
struct AllWorkoutsListView: View {
enum SortType: String, CaseIterable {
case name = "Name"
case date = "Date"
}
@State var searchString: String = ""
@Binding var uniqueWorkoutUsers: [RegisteredUser]?
@State private var filteredRegisterdUser: RegisteredUser?
let workouts: [Workout]
@State var workouts: [Workout]
let selectedWorkout: ((Workout) -> Void)
@State var filteredWorkouts = [Workout]()
var refresh: (() -> Void)
@@ -29,6 +29,13 @@ struct AllWorkoutsListView: View {
Text((filteredRegisterdUser.firstName ?? "NA") + "'s Workouts")
}
FilterAllView(searchString: $searchString,
uniqueWorkoutUsers: $uniqueWorkoutUsers,
filteredRegisterdUser: $filteredRegisterdUser,
filteredWorkouts: $filteredWorkouts,
workouts: $workouts,
currentSort: $currentSort)
ScrollView {
LazyVStack(spacing: 20) {
ForEach(filteredWorkouts, id:\.id) { workout in
@@ -44,111 +51,14 @@ struct AllWorkoutsListView: View {
.refreshable {
refresh()
}
HStack {
TextField("Filter" ,text: $searchString)
.padding()
.textFieldStyle(OvalTextFieldStyle())
if let uniqueWorkoutUsers = uniqueWorkoutUsers {
Menu(content: {
ForEach(uniqueWorkoutUsers, id: \.self) { index in
Button(action: {
filteredRegisterdUser = index
filteredWorkouts = filterWorkouts()
}, label: {
Text((index.firstName ?? "") + " -" + (index.lastName ?? ""))
})
}
Button(action: {
filteredRegisterdUser = nil
filteredWorkouts = filterWorkouts()
}, label: {
Text("All")
})
}, label: {
Image(systemName: filteredRegisterdUser == nil ? "person.2" : "person.2.fill")
.padding(.trailing)
})
}
Menu(content: {
ForEach(SortType.allCases, id: \.self) { index in
Button(action: {
sortWorkouts(sortType: index)
}, label: {
Text(index.rawValue)
})
}
}, label: {
Image(systemName: "list.number")
.padding(.trailing)
})
}
}
.onChange(of: searchString) { newValue in
filteredWorkouts = filterWorkouts()
filteredWorkouts = workouts.filterWorkouts(searchString: searchString, filteredRegisterdUser: filteredRegisterdUser)
}
.onAppear{
filteredWorkouts = filterWorkouts()
filteredWorkouts = workouts.filterWorkouts(searchString: searchString, filteredRegisterdUser: filteredRegisterdUser)
}
}
func sortWorkouts(sortType: SortType) {
if currentSort == sortType {
filteredWorkouts = filteredWorkouts.reversed()
return
}
switch sortType {
case .name:
filteredWorkouts = filteredWorkouts.sorted(by: {
$0.name < $1.name
})
case .date:
filteredWorkouts = filteredWorkouts.sorted(by: {
$0.createdAt ?? Date() < $1.createdAt ?? Date()
})
}
currentSort = sortType
}
func filterWorkouts() -> [Workout] {
var matchingWorkouts = [Workout]()
if (!searchString.isEmpty && searchString.count > 0) {
matchingWorkouts = workouts.filter({
if $0.name.lowercased().contains(searchString.lowercased()) {
return true
}
if let equipment = $0.equipment?.joined(separator: "").lowercased(),
equipment.contains(searchString.lowercased()) {
return true
}
if let muscles = $0.muscles?.joined(separator: "").lowercased(),
muscles.contains(searchString.lowercased()) {
return true
}
return false
})
}
if matchingWorkouts.isEmpty {
matchingWorkouts.append(contentsOf: workouts)
}
if let filteredRegisterdUser = filteredRegisterdUser {
matchingWorkouts = matchingWorkouts.filter({
$0.registeredUser == filteredRegisterdUser
})
}
return matchingWorkouts
}
}
struct AllWorkoutsListView_Previews: PreviewProvider {

View File

@@ -14,6 +14,11 @@ struct LoginView: View {
let completion: (() -> Void)
@State var doingNetworkShit: Bool = false
@State var errorTitle = ""
@State var errorMessage = ""
@State var hasError: Bool = false
var body: some View {
VStack {
TextField("Email", text: $email)
@@ -65,6 +70,11 @@ struct LoginView: View {
.edgesIgnoringSafeArea(.all)
.scaledToFill()
)
.alert(errorTitle, isPresented: $hasError, actions: {
}, message: {
})
}
func login() {
@@ -78,6 +88,10 @@ struct LoginView: View {
if success {
completion()
dismiss()
} else {
errorTitle = "error logging in"
errorMessage = "invalid credentials"
hasError = true
}
})
}

View File

@@ -0,0 +1,90 @@
//
// FilterAllView.swift
// Werkout_ios
//
// Created by Trey Tartt on 11/25/24.
//
import SwiftUI
struct FilterAllView: View {
@Binding var searchString: String
@Binding var uniqueWorkoutUsers: [RegisteredUser]?
@Binding var filteredRegisterdUser: RegisteredUser?
@Binding var filteredWorkouts: [Workout]
@Binding var workouts: [Workout]
@Binding var currentSort: SortType?
var body: some View {
HStack {
TextField("Filter" ,text: $searchString)
.padding(.horizontal)
.textFieldStyle(.roundedBorder)
if let uniqueWorkoutUsers = uniqueWorkoutUsers {
Menu(content: {
ForEach(uniqueWorkoutUsers, id: \.self) { index in
Button(action: {
filteredRegisterdUser = index
filteredWorkouts = workouts.filterWorkouts(searchString: searchString,
filteredRegisterdUser: filteredRegisterdUser)
}, label: {
Text((index.firstName ?? "") + " -" + (index.lastName ?? ""))
})
}
Button(action: {
filteredRegisterdUser = nil
filteredWorkouts = workouts.filterWorkouts(searchString: searchString,filteredRegisterdUser: filteredRegisterdUser)
}, label: {
Text("All")
})
}, label: {
Image(systemName: filteredRegisterdUser == nil ? "person.2" : "person.2.fill")
.padding(.trailing)
})
}
Menu(content: {
ForEach(SortType.allCases, id: \.self) { index in
Button(action: {
sortWorkouts(sortType: index)
}, label: {
Text(index.rawValue)
})
}
}, label: {
Image(systemName: "list.number")
.padding(.trailing)
})
}
}
func sortWorkouts(sortType: SortType) {
if currentSort == sortType {
filteredWorkouts = filteredWorkouts.reversed()
return
}
switch sortType {
case .name:
filteredWorkouts = filteredWorkouts.sorted(by: {
$0.name < $1.name
})
case .date:
filteredWorkouts = filteredWorkouts.sorted(by: {
$0.createdAt ?? Date() < $1.createdAt ?? Date()
})
}
currentSort = sortType
}
}
#Preview {
FilterAllView(searchString: .constant(""),
uniqueWorkoutUsers: .constant(nil),
filteredRegisterdUser: .constant(nil),
filteredWorkouts: .constant(PreviewData.allWorkouts()),
workouts: .constant(PreviewData.allWorkouts()),
currentSort: .constant(nil))
}