Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrated backend and fixed UI #4

Open
wants to merge 14 commits into
base: main
Choose a base branch
from

Conversation

AdelynnWu
Copy link
Contributor

Overview

Integrated backend into the app using Apollo-client and fixed filter and icon-rendering issues.

Changes

Change 1

Set up GraphQL schema and generated queries.

Change 2

Implemented functions in NetworkManager

Change 3

Fixed filtering functions in HomeView and PastGameView

Change 4

Updated icon image names

Change 5

Modified Game struct, added new Team struct, and implemented decoding initializers for all structs in model Game

Comment on lines +16 to +19
// private(set) lazy var apollo: ApolloClient = {
// let url = URL(string: "https://yourgraphqlendpoint.com/graphql")!
// return ApolloClient(url: url)
//}()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove commented out code if not necessary.

Comment on lines +43 to +45
// for datum in gamesData {
// print("Game of \(datum.sport) and \(datum.gender)")
// }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove commented out code if not necessary.

(gender == nil || game.gender == gender) &&
(sport == nil || game.sport == sport)
}
// print("game is empty: " + String(filteredGames.isEmpty))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove commented out code if not necessary.

Comment on lines +10 to +28
func ordinalSuffix(for number: Int) -> String {
let lastDigit = number % 10
let lastTwoDigits = number % 100

if lastTwoDigits >= 11 && lastTwoDigits <= 13 {
return "th"
}

switch lastDigit {
case 1: return "st"
case 2: return "nd"
case 3: return "rd"
default: return "th"
}
}

func ordinalNumberString(for number: Int) -> String {
return "\(number)\(ordinalSuffix(for: number))"
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you put these functions inside of a class called OrdinalSuffix?

Comment on lines +12 to +22
// @Published var allGames: [Game] = []
// @Published var upcomingGames: [Game] = []
// @Published var pastGames: [Game] = []

init() {
// fetchAllGames { [weak self] game in
// DispatchQueue.main.async {
// self?.allGames = games
// }
// }
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove if unused.

Comment on lines +28 to +31
let now = Date()
let twoHours: TimeInterval = 2 * 60 * 60
let calendar = Calendar.current
let startOfToday = calendar.startOfDay(for: now)
Copy link

@caitlynjin caitlynjin Dec 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would combine these onto the startOfToday line, except for twoHours. If it makes more sense, you could also use Date.now for the current date.

Comment on lines +53 to +55
let now = Date()
let calendar = Calendar.current
let startOfToday = calendar.startOfDay(for: now)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above comment.

// }
}

private func getUpcomingGames(allGames: [Game]) -> [Game] {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might be able to make this code more concise by using the filter and sort function on the allGames array. I believe you can filter the games today, then sort by their dates (assuming that's what your array looks like).

return upcomingGames
}

private func getPastGames(allGames: [Game]) -> [Game] {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same idea with this function - use the filter function!

// completion([])
// }
// }
//}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For all of the above commented lines, delete if they're unused, or leave a TODO: with some comments about it.

.frame(width: 32, height: 32)
.foregroundStyle(selected ? Constants.Colors.selected : Constants.Colors.iconGray)
// .foregroundStyle(selected ? Constants.Colors.selected : Constants.Colors.iconGray)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove if unused.

.frame(maxWidth: .infinity, alignment: .leading)
}
.padding(.leading, 24)
.padding(.trailing, 24)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.padding(.trailing, 24)
.padding(.trailing, 24)

.font(Constants.Fonts.subheader)
Text("Cornell vs. " + game.opponent.rawValue)
.font(Constants.Fonts.header)
.font(Constants.Fonts.medium14)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.font(Constants.Fonts.medium14)
.font(Constants.Fonts.medium14)


HStack() {
Image("Location-g")
.resizable()
.frame(width: 23, height: 26)
.frame(width: 13, height: 19)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.frame(width: 13, height: 19)
.frame(width: 13, height: 19)


HStack() {
Image("Location-g")
.resizable()
.frame(width: 23, height: 26)
.frame(width: 13, height: 19)
Text("Ithaca (Schoellkopf)")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Text("Ithaca (Schoellkopf)")
Text("Ithaca (Schoellkopf)")

Text("Ithaca (Schoellkopf)")
Image("Alarm")
.resizable()
.frame(width: 24, height: 24)
.frame(width: 19.78, height: 18.34)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.frame(width: 19.78, height: 18.34)
.frame(width: 19.78, height: 18.34)

Comment on lines +133 to +140
Text("2")
.font(Constants.Fonts.countdownNum)
Text("days")
.font(Constants.Fonts.gameText)
Text("0")
.font(Constants.Fonts.countdownNum)
Text("hours")
.font(Constants.Fonts.gameText)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Place empty lines in between views.

Comment on lines +149 to +153
Image("Calendar")
.resizable()
.frame(width: 24, height: 24)
Text("Add to Calendar")
.font(Constants.Fonts.buttonLabel)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Place empty lines in between views.

Comment on lines +145 to +147
Button(action: {
// TODO: action
}) {
Copy link

@caitlynjin caitlynjin Dec 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use the standard Button format:

Button {
// Action
} label: {
// UI
}

@@ -18,11 +18,19 @@ struct GameTile: View {
// Opponent Logo, Opponent Name | Sport Icon, Sex Icon
HStack(spacing: 8) {
HStack(spacing: 8) {
Image(game.opponent.rawValue)
// Image(game.opponent)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove comment.

Comment on lines +12 to +19
@State private var selectedSex : Sex = .Both
@State private var selectedSport : Sport = .All
var paddingMain : CGFloat = 20
@State private var selectedCardIndex: Int = 0
@State private var games: [Game] = []
@State private var allGames: [Game] = []
@State private var upcomingGames: [Game] = []
@State private var errorMessage: String?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you make these alphabetical order?

HomeView()
}

// MARK: Functions
Copy link

@caitlynjin caitlynjin Dec 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of this code would make more sense in a ViewModel, could you move this to the HomeViewModel?
Also, similar idea with the filtering/sorting in my other comment.

Button {
selectedSport = sport
} label: {
FilterTile(sport: sport, selected: sport == selectedSport)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
FilterTile(sport: sport, selected: sport == selectedSport)
FilterTile(sport: sport, selected: sport == selectedSport)

Comment on lines +247 to +249
ForEach(
games
) { game in

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Place these on the same line.

.frame(maxWidth: .infinity)
.background(Constants.Colors.white)
.shadow(radius: 6)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

import SwiftUI

struct PastGameCard: View {
var game: Game

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
var game: Game
var game: Game

Comment on lines +40 to +41
.resizable()
.frame(width: 64, height: 64)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add an indent.

Comment on lines +86 to +100
AsyncImage(url: URL(string: game.opponent.image)) {image in
image.resizable()
} placeholder: {
Constants.Colors.gray_icons
}
.frame(width: 25, height: 27)
Text(game.opponent.name)
.font(Constants.Fonts.gameTitle)
Spacer()
Image(game.sport.rawValue + "-g")
.resizable()
.frame(width: 30, height: 30)
Image(game.sex.description + "-g")
.resizable()
.frame(width: 25, height: 25)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty lines in between views.

Comment on lines +104 to +113
Image("Location-g")
.resizable()
.frame(width: 10, height: 15)
Text("\(game.city), \(game.state)")
.font(Constants.Fonts.gameText)
.foregroundStyle(.gray)
Spacer()
Text(Date.dateToString(date: game.date))
.font(Constants.Fonts.gameDate)
.foregroundStyle(.gray)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty lines in between views.

@@ -12,20 +12,95 @@ struct PastGameTile: View {


var body: some View {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is quite a big code section, could you separate these into separate variables?

Comment on lines +99 to +100
// arrow

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there something that's supposed to be here?

@State private var errorMessage: String?
@State private var pastGames: [Game] = []
@EnvironmentObject var viewModel: GamesViewModel

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

Comment on lines +12 to +20
@State private var selectedSex : Sex = .Both
@State private var selectedSport : Sport = .All
var paddingMain : CGFloat = 20
@State private var selectedCardIndex: Int = 0
@State private var games: [Game] = []
@State private var allGames: [Game] = []
@State private var errorMessage: String?
@State private var pastGames: [Game] = []
@EnvironmentObject var viewModel: GamesViewModel

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alphabetical order please :)

}
}

#Preview {
PastGameView()
}

// MARK: Functions

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These functions would go in the view model as well. Then you would call it by calling viewModel.fetchPastGames().

Button {
selectedSport = sport
} label: {
FilterTile(sport: sport, selected: sport == selectedSport)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
FilterTile(sport: sport, selected: sport == selectedSport)
FilterTile(sport: sport, selected: sport == selectedSport)

}
}.padding(.top, paddingMain)
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general in this view, I see lots of duplicate code that is used elsewhere - could you create files that hold those views so that you can reuse them? e.g. a Carousel file that contains a Carousel view.

}
}

struct ScoringUpdateCell : View {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create another file for this struct.

HStack {
if update.isCornell {
Image("Cornell")
.resizable().frame(width: 32, height: 32)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.resizable().frame(width: 32, height: 32)
.resizable().frame(width: 32, height: 32)

Comment on lines +91 to +94
.padding(.leading, 24)
.padding(.trailing, 24)
.padding(.top, 12)
.padding(.bottom, 12)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use .horizontal and .vertical to make these more concise.

Comment on lines +13 to +16
@Binding var selectionIndex: Int

let itemIndex: Int
private let tabItems = ["schedule", "scoreboard"]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation is off here.

Comment on lines +23 to +29
Image(itemIndex == selectionIndex ? "\(tabItems[itemIndex])-selected" : tabItems[itemIndex])
.resizable()
.frame(width: 28, height: 28)
.tint(Constants.Colors.gray_icons)
Text(itemIndex == 0 ? "Schedule" : "Scores")
.font(Constants.Fonts.buttonLabel)
.foregroundStyle(itemIndex == selectionIndex ? Constants.Colors.primary_red : Constants.Colors.unselectedText)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty line in between views.

Comment on lines +54 to +55
AsyncImage(url: URL(string: game.opponent.image)) {
image in

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Place on the same line.

.resizable()
.frame(width: 24, height: 30)
Text(game.opponent.rawValue)
AsyncImage(url: URL(string: game.opponent.image)) {image in

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
AsyncImage(url: URL(string: game.opponent.image)) {image in
AsyncImage(url: URL(string: game.opponent.image)) { image in

Copy link

@caitlynjin caitlynjin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome PR Adelynn!! There's a few styling comments I'd like you to address, as well as making some functions that filter/sort games, etc more concise. Please let me know if you have any specific questions :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants