Skip to content
This repository has been archived by the owner on Apr 27, 2024. It is now read-only.

Commit

Permalink
Added jobs map
Browse files Browse the repository at this point in the history
  • Loading branch information
carlobortolan committed Sep 9, 2023
1 parent ad55ed0 commit db89671
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 71 deletions.
4 changes: 4 additions & 0 deletions mobile.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
22DC3AEE2AACC05800B783E8 /* Parchment in Frameworks */ = {isa = PBXBuildFile; productRef = 22DC3AED2AACC05800B783E8 /* Parchment */; };
22DC3AF02AACC20F00B783E8 /* JobCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22DC3AEF2AACC20F00B783E8 /* JobCard.swift */; };
22DC3AF22AACE4C200B783E8 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22DC3AF12AACE4C200B783E8 /* AppDelegate.swift */; };
22DC3AF42AAD23B400B783E8 /* JobsMapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22DC3AF32AAD23B400B783E8 /* JobsMapView.swift */; };
22E40B052A8C20DB00D3F91E /* APIManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22E40B042A8C20DB00D3F91E /* APIManager.swift */; };
22E40B072A8C21AF00D3F91E /* APITypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22E40B062A8C21AF00D3F91E /* APITypes.swift */; };
22E73EC62A8BFDDF0042CF01 /* mobileApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22E73EC52A8BFDDF0042CF01 /* mobileApp.swift */; };
Expand Down Expand Up @@ -157,6 +158,7 @@
22DC3AEA2AACBF7500B783E8 /* JobCarusel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JobCarusel.swift; sourceTree = "<group>"; };
22DC3AEF2AACC20F00B783E8 /* JobCard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JobCard.swift; sourceTree = "<group>"; };
22DC3AF12AACE4C200B783E8 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
22DC3AF32AAD23B400B783E8 /* JobsMapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JobsMapView.swift; sourceTree = "<group>"; };
22E40B042A8C20DB00D3F91E /* APIManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIManager.swift; sourceTree = "<group>"; };
22E40B062A8C21AF00D3F91E /* APITypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APITypes.swift; sourceTree = "<group>"; };
22E73EC22A8BFDDF0042CF01 /* mobile.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = mobile.app; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -233,6 +235,7 @@
children = (
2216EA7A2A8D730E00C970DD /* README.md */,
2216EA852A8D765500C970DD /* StartView.swift */,
22DC3AF32AAD23B400B783E8 /* JobsMapView.swift */,
);
path = StartPage;
sourceTree = "<group>";
Expand Down Expand Up @@ -591,6 +594,7 @@
226B637C2AA78A85004620EE /* JobPosting.swift in Sources */,
226B63892AA790DB004620EE /* SignInForm.swift in Sources */,
22B804252AA9037A008D7108 /* AccountHandler.swift in Sources */,
22DC3AF42AAD23B400B783E8 /* JobsMapView.swift in Sources */,
226B63842AA78BCC004620EE /* JobForm.swift in Sources */,
22E73EC82A8BFDDF0042CF01 /* ContentView.swift in Sources */,
22430F9C2AAAB3C400747827 /* SettingsView.swift in Sources */,
Expand Down
4 changes: 3 additions & 1 deletion mobile/Models/JobModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ struct FeedResponse: Codable {
let feed: [Job]
}

struct Job: Codable, Hashable {
struct Job: Codable, Hashable, Identifiable {
let jobId: Int
let jobType: String
let jobTypeValue: Int
Expand Down Expand Up @@ -51,6 +51,8 @@ struct Job: Codable, Hashable {
let allowedCvFormat: [String]
let imageUrl: String

var id: Int { jobId }

func hash(into hasher: inout Hasher) {
hasher.combine(jobId)
}
Expand Down
2 changes: 1 addition & 1 deletion mobile/Views/Components/JobCarusel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ struct JobCarousel: View {
let offset = getOffset(for: index, currentPage: currentPage)

JobCardView(job: jobManager.upcomingJobs[index])
.frame(width: UIScreen.main.bounds.width - 40, height: 200)
.frame(width: UIScreen.main.bounds.width - 50, height: 200)
.padding(.horizontal, 20)
.scaleEffect(scale)
.offset(x: offset, y: 0)
Expand Down
1 change: 0 additions & 1 deletion mobile/Views/Components/JobDetail.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ struct JobDetail: View {
center: CLLocationCoordinate2D(latitude: job.latitude, longitude: job.longitude),
span: MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1)
))

}

var body: some View {
Expand Down
72 changes: 72 additions & 0 deletions mobile/Views/StartPage/JobsMapView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
//
// JobsMapsView.swift
// mobile
//
// Created by cb on 10.09.23.
//

import SwiftUI
import MapKit
import CoreLocation

struct JobsMapView: View {

@State private var region: MKCoordinateRegion
let nearbyJobs: [Job]
private let locationManager = CLLocationManager()

init(nearbyJobs: [Job]) {
_region = State(initialValue: MKCoordinateRegion(
center: CLLocationCoordinate2D(latitude: 0.0, longitude: 0.0),
span: MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1)
))

self.nearbyJobs = nearbyJobs
}

var body: some View {
Map(coordinateRegion: .constant(region), showsUserLocation: true, userTrackingMode: .constant(.follow), annotationItems: nearbyJobs) { job in
MapPin(coordinate: CLLocationCoordinate2D(latitude: job.latitude, longitude: job.longitude), tint: .blue)
}
.frame(width: 300, height: 500)
.onAppear {
// Request location authorization
locationManager.requestWhenInUseAuthorization()

// Start updating the user's location
locationManager.startUpdatingLocation()

// Set the initial region based on the user's location
if let userLocation = locationManager.location?.coordinate {
region.center = userLocation
}

let coordinates = nearbyJobs.map { CLLocationCoordinate2D(latitude: $0.latitude, longitude: $0.longitude) }
if let boundingRegion = regionBounding(coordinates: coordinates) {
region = boundingRegion
}
}
}

// Function to calculate the region to fit all pins
private func regionBounding(coordinates: [CLLocationCoordinate2D]) -> MKCoordinateRegion? {
guard !coordinates.isEmpty else { return nil }

let maxLat = coordinates.map { $0.latitude }.max()!
let minLat = coordinates.map { $0.latitude }.min()!
let maxLon = coordinates.map { $0.longitude }.max()!
let minLon = coordinates.map { $0.longitude }.min()!

let center = CLLocationCoordinate2D(
latitude: (maxLat + minLat) / 2,
longitude: (maxLon + minLon) / 2
)

let span = MKCoordinateSpan(
latitudeDelta: (maxLat - minLat) * 1.2,
longitudeDelta: (maxLon - minLon) * 1.2
)

return MKCoordinateRegion(center: center, span: span)
}
}
154 changes: 86 additions & 68 deletions mobile/Views/StartPage/StartView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//

import SwiftUI
import MapKit

struct StartView: View {
@EnvironmentObject var errorHandlingManager: ErrorHandlingManager
Expand All @@ -15,68 +16,96 @@ struct StartView: View {

@State var isLoadingUpcomingJobs = false
@State var isLoadingNearbyJobs = false

@State private var notifications: [String] = ["Notification 1", "Notification 2"]

var body: some View {
NavigationView {
ScrollView {
VStack(spacing: 20) {
VStack {
Text("Upcoming Jobs")
.font(.title)
.fontWeight(.bold)
.foregroundColor(.primary)

if isLoadingUpcomingJobs {
ProgressView()
}

if jobManager.upcomingJobs.isEmpty && !isLoadingUpcomingJobs {
Text("No confirmed jobs yet.")
.foregroundColor(.secondary)
} else {
JobCarousel().padding()
}
Spacer()
}
.padding()

VStack {
Text("Jobs Near You")
.font(.title)
.fontWeight(.bold)
.foregroundColor(.primary)

if isLoadingNearbyJobs {
ProgressView()
}

if jobManager.nearbyJobs.isEmpty && !isLoadingNearbyJobs {
Text("No jobs found.")
.foregroundColor(.secondary)
} else {
ForEach(jobManager.nearbyJobs, id: \.jobId) { job in
JobCard(job: job)
}
}
}
.padding()
}
VStack(spacing: 20) {
RoundedRectangle(cornerRadius: 10)
.frame(height: 325)
.foregroundColor(Color("FeedBgColor"))
.border(Color("FgColor"), width: 3)
.cornerRadius(10)
.overlay(
RoundedRectangle(cornerRadius: 10)
.frame(height: 325)
.foregroundColor(Color("FeedBgColor"))
.border(Color("FgColor"), width: 3)
.padding(.horizontal, 10.0)
.overlay(
VStack {
Text("Upcoming Jobs")
.font(.title)
.fontWeight(.bold)
.foregroundColor(.primary)

if isLoadingUpcomingJobs {
ProgressView()
}

if jobManager.upcomingJobs.isEmpty && !isLoadingUpcomingJobs {
Text("No confirmed jobs yet.")
.foregroundColor(.secondary)
} else {
JobCarousel().padding()
}
Spacer()
}.padding([.top, .leading, .trailing])
)
)

RoundedRectangle(cornerRadius: 10)
.frame(height: 300)
.foregroundColor(Color("FeedBgColor"))
.border(Color("FgColor"), width: 3)
.cornerRadius(10)
.overlay(
RoundedRectangle(cornerRadius: 10)
.frame(height: 300)
.foregroundColor(Color("FeedBgColor"))
.border(Color("FgColor"), width: 3)
.padding(.horizontal, 10.0)
.overlay(
VStack {
Text("Jobs Near You")
.font(.title)
.fontWeight(.bold)
.foregroundColor(.primary)

if jobManager.nearbyJobs.isEmpty && !isLoadingNearbyJobs {
Text("No jobs found.")
.foregroundColor(.secondary)
} else {
NavigationView {
JobsMapView(nearbyJobs: jobManager.nearbyJobs)
}
}
Spacer()
}.padding([.top, .leading, .trailing])
.overlay(
VStack {
if isLoadingNearbyJobs {
Spacer()
ProgressView()
Spacer()
} else {EmptyView()}
})
)
)
}
}
.navigationBarTitle("EMBLOY", displayMode: .inline)
.padding()
.onAppear {
// Load notifications, upcoming jobs, and nearby jobs
// Update 'notifications' and 'nearbyJobs'
isLoadingUpcomingJobs = true
jobManager.loadUpcomingJobs(iteration: 0) {
isLoadingUpcomingJobs = false
}
.navigationBarTitle("EMBLOY", displayMode: .inline)
.padding()
.onAppear {
// Load notifications, upcoming jobs, and nearby jobs
// Update 'notifications' and 'nearbyJobs'
isLoadingUpcomingJobs = true
jobManager.loadUpcomingJobs(iteration: 0) {
isLoadingUpcomingJobs = false
}
isLoadingNearbyJobs = true
jobManager.loadNearbyJobs(iteration: 0, longitude: 0.0, latitude: 0.0) {
isLoadingNearbyJobs = false
}
isLoadingNearbyJobs = true
jobManager.loadNearbyJobs(iteration: 0, longitude: 0.0, latitude: 0.0) {
isLoadingNearbyJobs = false
}
}
}
Expand Down Expand Up @@ -114,14 +143,3 @@ struct JobCard: View {
}
}
}

struct Previews_StartView_Previews: PreviewProvider {
static var previews: some View {
let errorHandlingManager = ErrorHandlingManager()
let authenticationManager = AuthenticationManager(errorHandlingManager: errorHandlingManager)
let jobManager = JobManager(authenticationManager: authenticationManager, errorHandlingManager: errorHandlingManager)
return StartView()
.environmentObject(jobManager)

}
}

0 comments on commit db89671

Please sign in to comment.