Skip to content
This repository was archived by the owner on Oct 12, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "Vector.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "[email protected]",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "[email protected]",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "Group 995.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Group [email protected]",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Group [email protected]",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 23 additions & 0 deletions HackIllinois/Assets.xcassets/profile-orb.imageset/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "Group 995.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Group [email protected]",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Group [email protected]",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "SAVE.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "[email protected]",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "[email protected]",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion HackIllinois/UI/HIAppearance.swift
Original file line number Diff line number Diff line change
Expand Up @@ -383,14 +383,15 @@ struct HIAppearance: Equatable {
static let loginSelection = UIFont(name: "MontserratRoman-SemiBold", size: UIDevice.current.userInterfaceIdiom == .pad ? 26: 16)

// Profile-related fonts
static let profileName = UIFont(name: "MontserratRoman-Bold", size: UIDevice.current.userInterfaceIdiom == .pad ? 40 : 20)
static let profileName = UIFont(name: "MontserratRoman-SemiBold", size: UIDevice.current.userInterfaceIdiom == .pad ? 40 : 22)
static let profileSubtitle = UIFont(name: "MontserratRoman-Bold", size: UIDevice.current.userInterfaceIdiom == .pad ? 24 : 12)
static let profileDietaryRestrictions = UIFont(name: "MontserratRoman-SemiBold", size: UIDevice.current.userInterfaceIdiom == .pad ? 32 : 16)
static let profileDietaryRestrictionsLabel = UIFont(name: "MontserratRoman-Bold", size: UIDevice.current.userInterfaceIdiom == .pad ? 24 : 12)
static let profileTier = UIFont(name: "MontserratRoman-Bold", size: UIDevice.current.userInterfaceIdiom == .pad ? 36 : 18)
static let profileNumberFigure = UIFont(name: "MontserratRoman-SemiBold", size: 24)
static let profileUsername = UIFont(name: "MontserratRoman-Bold", size: 16)
static let profileInterests = UIFont(name: "MontserratRoman-SemiBold", size: 14)
static let profileRank = UIFont(name: "MontserratRoman-Bold", size: 16)

// QR code fonts
static let QRCheckInFont = UIFont(name: "MontserratRoman-SemiBold", size: 14)
Expand Down
245 changes: 165 additions & 80 deletions HackIllinois/ViewControllers/HIProfileCardView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,89 +62,173 @@ struct HIProfileCardView: View {
// Factors used to change frame to alter based on device
let padFactor = UIScreen.main.bounds.height/1366
let phoneFactor = UIScreen.main.bounds.height/844


// Screen size
let screenWidth = UIScreen.main.bounds.width
let screenHeight = UIScreen.main.bounds.height


var body: some View {
ScrollView {
ZStack {
ZStack(alignment: .top) {
ZStack(alignment: .bottom) {
Image("ProfileCardBackground")
.resizable()
.frame(width: UIDevice.current.userInterfaceIdiom == .pad ? 566.93*padFactor : 338*phoneFactor, height: UIDevice.current.userInterfaceIdiom == .pad ? 777.2*padFactor : 463.36*phoneFactor)
ZStack {
Image("ProfileBanner")
.resizable()
.frame(width: UIDevice.current.userInterfaceIdiom == .pad ? 395.7*padFactor : 235.91*phoneFactor, height: UIDevice.current.userInterfaceIdiom == .pad ? 137.71*padFactor : 82.1*phoneFactor)
VStack(spacing: 0) {
Text("Your Ranking")
.foregroundColor(.white)

.font(Font(HIAppearance.Font.profileSubtitle ?? .systemFont(ofSize: 20)))
HStack(alignment: .bottom, spacing: UIDevice.current.userInterfaceIdiom == .pad ? 5*padFactor : 5*phoneFactor) {
Image("RankSymbol")
Text("\(rank != 0 ? "\(rank)" : "...")")
.foregroundColor(.white)
.font(Font(HIAppearance.Font.profileSubtitle ?? .systemFont(ofSize: 20)))
.onAppear {
// Call getRank and update the rank when it's available
getRank { rank in
self.rank = rank
}
}
}
}.padding(.bottom, isIpad ? 40*padFactor : 25*phoneFactor)
}.alignmentGuide(.bottom) {dimensions in dimensions[.bottom] / 1.2 }
}
Image(uiImage: avatarUrl.load())
.resizable()
.frame(width: isIpad ? 249.92*padFactor : 149*phoneFactor, height: isIpad ? 286.4*padFactor : 170.75*phoneFactor)
.alignmentGuide(.top) {dimensions in dimensions[VerticalAlignment.center] / 0.9 }
// Y coordinate position calculation placeholders so the compiler doesn't get mad at long arithmetic within views
let height_adjustment_factor = (40 / 841) * screenHeight

let name_spacing = (screenHeight * (210 / 841)) / 2 + (15 / 841) * screenHeight // Scaled 15px spacing

// Base Y coordinate
let base_y = (521 / 841) * screenHeight

// Half heights for stacking calculations
let half_pillar_height = (screenHeight * (262 / 841)) / 2
let half_flame_height = (screenHeight * (450 / 841)) / 2
let half_orb_height = (screenHeight * (140.49 / 841)) / 2
let half_qr_height = (screenHeight * (210 / 841)) / 2

let full_flame_height = (screenHeight * (450 / 841))
let full_orb_height = ( 140.49 / 841) * screenHeight

// Additional offsets
let flame_offset = (13 / 841) * screenHeight
let qr_offset = (210 / 841) * screenHeight

// Calculated positions
let flame_y = base_y - half_pillar_height - half_flame_height + flame_offset + height_adjustment_factor
let pillar_y = base_y // Centered at the bottom
let orb_y = base_y - half_pillar_height - full_flame_height - half_orb_height + flame_offset + full_orb_height + height_adjustment_factor
let qr_y = base_y - half_pillar_height - half_flame_height - half_qr_height + qr_offset
let name_y = qr_y - name_spacing
let avatar_y = orb_y



ZStack(alignment: .bottom) {
Image("flame-vector")
.resizable()
.scaledToFit()
.frame(
width: screenWidth * (371.01 / 393), // Scaled width
height: screenHeight * (450 / 841) // Scaled height
)
.position(
x: screenWidth / 2,
y: flame_y
) // Position at the top of the pillar

// Pillar Image - Anchored at the bottom
Image("pillar-vector")
.resizable()
.scaledToFit()
.frame(
width: screenWidth * (361 / 393), // Scaled width
height: screenHeight * (262 / 841) // Scaled height
)
.position(
x: screenWidth / 2,
y: pillar_y
)

// Profile Orb - Stacked on top of the flame
Image("profile-orb")
.resizable()
.scaledToFit()
.frame(
width: screenWidth * (174.99 / 393), // Scaled width
height: screenHeight * (140.49 / 841) // Scaled height
)
.position(
x: screenWidth / 2,
y: orb_y
) // Positioned on top of the flame

// Avatar Image - Positioned in the center of the profile orb
Image(uiImage: avatarUrl.load())
.resizable()
.scaledToFit()
.frame(width: screenWidth * (88.82 / 393), height: screenHeight * (86.91 / 841))
.clipShape(Circle())
// .overlay(
// Circle()
// .stroke(Color.red, lineWidth: 3) // Add a red outline to test the positioning of the avatar
// )
.position(x: screenWidth / 2, y: avatar_y)


// Name Label - Positioned Above the QR Code
Text(displayName)
.font(Font(HIAppearance.Font.profileName ?? .systemFont(ofSize: 22))) // Adjust font size as needed
.foregroundColor(Color.black) // White text color
.multilineTextAlignment(.center)
.position(
x: screenWidth / 2,
y: name_y
)

// QR Code - Positioned inside the Flame
if let qrCodeData = getQRCodeDate(text: qrInfo), let qrCodeImage = UIImage(data: qrCodeData) {
Image(uiImage: qrCodeImage)
.resizable()
.scaledToFit()
.frame(
width: screenWidth * (208 / 393), // Scaled width
height: screenHeight * (210 / 841) // Scaled height
)
.position(
x: screenWidth / 2,
y: qr_y
) // Centered inside the flame
}


// VStack for User Information inside the pillar
VStack(spacing: screenHeight * (10 / 841)) {
// HStack for Role and Wave labels
HStack(spacing: screenWidth * (10 / 393)) {
Text(role)
.font(Font(HIAppearance.Font.profileTier ?? .systemFont(ofSize: 18)))
.foregroundColor(.white)
.frame(width: screenWidth * (120 / 393), height: screenHeight * (38 / 841))
.background(Color(red: 217/255, green: 217/255, blue: 217/255).opacity(0.5))
.cornerRadius(12)

Text("Wave \(foodWave)")
.font(Font(HIAppearance.Font.profileTier ?? .systemFont(ofSize: 18)))
.foregroundColor(.white)
.frame(width: screenWidth * (120 / 393), height: screenHeight * (38 / 841))
.background(Color(red: 217/255, green: 217/255, blue: 217/255).opacity(0.5))
.cornerRadius(12)
}
VStack(spacing: 0) {
Spacer().frame(height: UIDevice.current.userInterfaceIdiom == .pad ? 90*padFactor : (90*phoneFactor))
Text(formatName())
.font(Font(HIAppearance.Font.profileName ?? .systemFont(ofSize: 24)))
.foregroundColor(Color((\HIAppearance.countdownTextColor).value))
.padding(isIpad ? 32*padFactor : 16*phoneFactor)
HStack(spacing: isIpad ? 16*padFactor : 8*phoneFactor) {
Rectangle()
.frame(width: isIpad ? 148*padFactor : 74*phoneFactor, height: isIpad ? 48*padFactor : 24*phoneFactor)
.cornerRadius(isIpad ? 40*padFactor : 20*phoneFactor)
.foregroundColor(Color(red: 226/255, green: 142/255, blue: 174/255))
.overlay(
Text(role)
.font(Font(HIAppearance.Font.profileSubtitle ?? .systemFont(ofSize: 12)))
.foregroundColor(Color(red: 1, green: 248/255, blue: 245/255))
)

Rectangle()
.frame(width: isIpad ? 136*padFactor : 68*phoneFactor, height: isIpad ? 48*padFactor : 24*phoneFactor)
.cornerRadius(isIpad ? 40*padFactor : 20*phoneFactor)
.foregroundColor(
(Color(red: 226/255, green: 142/255, blue: 174/255)))
.overlay(
Text("Wave \(foodWave)")
.font(Font(HIAppearance.Font.profileSubtitle ?? .systemFont(ofSize: 12)))
.foregroundColor((Color(red: 1, green: 248/255, blue: 245/255)))
)
}.padding(.bottom)
Image(uiImage: UIImage(data: getQRCodeDate(text: qrInfo)!)!)
.resizable()
.frame(width: isIpad ? 371*padFactor : 221*phoneFactor, height: isIpad ? 371*padFactor : 221*phoneFactor)
.padding(.bottom, 20*phoneFactor)

// HStack for Rank Label (Text + Rank Value)
HStack(spacing: screenWidth * (20 / 393)) {
Text("Rank")
.font(Font(HIAppearance.Font.profileTier ?? .systemFont(ofSize: 18)))
.foregroundColor(.white)

Text("\(rank != 0 ? "\(rank)" : "...")")
.font(Font(HIAppearance.Font.profileRank ?? .systemFont(ofSize: 16)))
.foregroundColor(Color(red: 97/255, green: 37/255, blue: 71/255)) // Updated color
.frame(width: screenWidth * (84.5 / 393), height: screenHeight * (27.26 / 841))
.background(
Image("profile-rank-label-background") // Use imported image
.resizable()
.scaledToFit()
.frame(width: screenWidth * (84.5 / 393), height: screenHeight * (27.26 / 841)) // Match dimensions
)
.onAppear {
// Call getRank and update the rank when it's available
getRank { rank in
self.rank = rank
}
}
}
.padding(.top, isIpad ? 50*padFactor : 0)

}
.padding(.top, 24)
}
.preferredColorScheme(.dark)
.onAppear {
startFetchingQR = true
QRFetchLoop()
}
.onDisappear {
startFetchingQR = false
.position(
x: screenWidth / 2,
y: (591 / 841) * screenHeight - (screenHeight * (262 / 841)) / 2 + (55 / 841) * screenHeight // Position based on Figma
)
}
.edgesIgnoringSafeArea(.bottom) // Extend to the bottom edge
.offset(y: 30 * (UIScreen.main.bounds.height/926))
}

func formatName() -> String {
Expand All @@ -171,8 +255,9 @@ struct HIProfileCardView: View {
// Change color of QR code
guard let colorFilter = CIFilter(name: "CIFalseColor") else { return nil }
colorFilter.setValue(filter.outputImage, forKey: "inputImage")
colorFilter.setValue(CIColor(red: 1, green: 248/255, blue: 245/255), forKey: "inputColor1") // Background off-white
colorFilter.setValue(CIColor(red: 102/255, green: 43/255, blue: 19/255), forKey: "inputColor0") // Barcode brown
colorFilter.setValue(CIColor(red: 0, green: 0, blue: 0, alpha: 0), forKey: "inputColor1") // Background transparent
colorFilter.setValue(CIColor(red: 0.337254902, green: 0.1411764706, blue: 0.06666666667), forKey: "inputColor0") // Barcode brown


guard let ciimage = colorFilter.outputImage else { return nil }
let transform = CGAffineTransform(scaleX: 10, y: 10)
Expand Down
Loading