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:
@@ -61,3 +61,41 @@ struct Workout: Codable, Identifiable, Equatable {
|
|||||||
allSupersetExecercise = try container.decodeIfPresent([SupersetExercise].self, forKey: .allSupersetExecercise)
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,17 +7,17 @@
|
|||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
|
enum SortType: String, CaseIterable {
|
||||||
|
case name = "Name"
|
||||||
|
case date = "Date"
|
||||||
|
}
|
||||||
|
|
||||||
struct AllWorkoutsListView: View {
|
struct AllWorkoutsListView: View {
|
||||||
enum SortType: String, CaseIterable {
|
|
||||||
case name = "Name"
|
|
||||||
case date = "Date"
|
|
||||||
}
|
|
||||||
|
|
||||||
@State var searchString: String = ""
|
@State var searchString: String = ""
|
||||||
@Binding var uniqueWorkoutUsers: [RegisteredUser]?
|
@Binding var uniqueWorkoutUsers: [RegisteredUser]?
|
||||||
@State private var filteredRegisterdUser: RegisteredUser?
|
@State private var filteredRegisterdUser: RegisteredUser?
|
||||||
|
|
||||||
let workouts: [Workout]
|
@State var workouts: [Workout]
|
||||||
let selectedWorkout: ((Workout) -> Void)
|
let selectedWorkout: ((Workout) -> Void)
|
||||||
@State var filteredWorkouts = [Workout]()
|
@State var filteredWorkouts = [Workout]()
|
||||||
var refresh: (() -> Void)
|
var refresh: (() -> Void)
|
||||||
@@ -29,6 +29,13 @@ struct AllWorkoutsListView: View {
|
|||||||
Text((filteredRegisterdUser.firstName ?? "NA") + "'s Workouts")
|
Text((filteredRegisterdUser.firstName ?? "NA") + "'s Workouts")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FilterAllView(searchString: $searchString,
|
||||||
|
uniqueWorkoutUsers: $uniqueWorkoutUsers,
|
||||||
|
filteredRegisterdUser: $filteredRegisterdUser,
|
||||||
|
filteredWorkouts: $filteredWorkouts,
|
||||||
|
workouts: $workouts,
|
||||||
|
currentSort: $currentSort)
|
||||||
|
|
||||||
ScrollView {
|
ScrollView {
|
||||||
LazyVStack(spacing: 20) {
|
LazyVStack(spacing: 20) {
|
||||||
ForEach(filteredWorkouts, id:\.id) { workout in
|
ForEach(filteredWorkouts, id:\.id) { workout in
|
||||||
@@ -44,111 +51,14 @@ struct AllWorkoutsListView: View {
|
|||||||
.refreshable {
|
.refreshable {
|
||||||
refresh()
|
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
|
.onChange(of: searchString) { newValue in
|
||||||
filteredWorkouts = filterWorkouts()
|
filteredWorkouts = workouts.filterWorkouts(searchString: searchString, filteredRegisterdUser: filteredRegisterdUser)
|
||||||
}
|
}
|
||||||
.onAppear{
|
.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 {
|
struct AllWorkoutsListView_Previews: PreviewProvider {
|
||||||
|
|||||||
@@ -14,6 +14,11 @@ struct LoginView: View {
|
|||||||
let completion: (() -> Void)
|
let completion: (() -> Void)
|
||||||
@State var doingNetworkShit: Bool = false
|
@State var doingNetworkShit: Bool = false
|
||||||
|
|
||||||
|
@State var errorTitle = ""
|
||||||
|
@State var errorMessage = ""
|
||||||
|
@State var hasError: Bool = false
|
||||||
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack {
|
VStack {
|
||||||
TextField("Email", text: $email)
|
TextField("Email", text: $email)
|
||||||
@@ -65,6 +70,11 @@ struct LoginView: View {
|
|||||||
.edgesIgnoringSafeArea(.all)
|
.edgesIgnoringSafeArea(.all)
|
||||||
.scaledToFill()
|
.scaledToFill()
|
||||||
)
|
)
|
||||||
|
.alert(errorTitle, isPresented: $hasError, actions: {
|
||||||
|
|
||||||
|
}, message: {
|
||||||
|
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func login() {
|
func login() {
|
||||||
@@ -78,6 +88,10 @@ struct LoginView: View {
|
|||||||
if success {
|
if success {
|
||||||
completion()
|
completion()
|
||||||
dismiss()
|
dismiss()
|
||||||
|
} else {
|
||||||
|
errorTitle = "error logging in"
|
||||||
|
errorMessage = "invalid credentials"
|
||||||
|
hasError = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
90
iphone/Werkout_ios/subview/FilterAllView.swift
Normal file
90
iphone/Werkout_ios/subview/FilterAllView.swift
Normal 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))
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user