Skip to content

Commit

Permalink
SMA-107: the main page should use user s location (#91)
Browse files Browse the repository at this point in the history
Co-authored-by: MatejFrnka <[email protected]>
  • Loading branch information
ivamach and MatejFrnka authored May 6, 2024
1 parent adcd6b5 commit 0f46900
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 3 deletions.
93 changes: 93 additions & 0 deletions frontend/sportsmatch-app/src/hooks/UseLocation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { useEffect, useState } from 'react'

// source https://gist.github.com/KristofferEriksson/ee5af0a52e1fea0acc028e9b10aa0969

interface LocationOptions {
enableHighAccuracy?: boolean
timeout?: number
maximumAge?: number
}

interface LocationState {
coords: {
latitude: number | null
longitude: number | null
accuracy: number | null
altitude: number | null
altitudeAccuracy: number | null
heading: number | null
speed: number | null
}
locatedAt: number | null
error: string | null
}

const useLocation = (options: LocationOptions = {}) => {
const [location, setLocation] = useState<LocationState>({
coords: {
latitude: null,
longitude: null,
accuracy: null,
altitude: null,
altitudeAccuracy: null,
heading: null,
speed: null,
},
locatedAt: null,
error: null,
})

useEffect(() => {
// Ensuring this runs only in a client-side environment
if (typeof window === 'undefined' || !('geolocation' in navigator)) {
setLocation((prevState) => ({
...prevState,
error:
'Geolocation is not supported by your browser or not available in the current' +
' environment',
}))
return
}

const handleSuccess = (position: GeolocationPosition) => {
setLocation({
coords: {
latitude: position.coords.latitude,
longitude: position.coords.longitude,
accuracy: position.coords.accuracy,
altitude: position.coords.altitude,
altitudeAccuracy: position.coords.altitudeAccuracy,
heading: position.coords.heading,
speed: position.coords.speed,
},
locatedAt: position.timestamp,
error: null,
})
}

const handleError = (error: GeolocationPositionError) => {
setLocation((prevState) => ({
...prevState,
error: error.message,
}))
}

const geoOptions = {
enableHighAccuracy: options.enableHighAccuracy || false,
timeout: options.timeout || Infinity,
maximumAge: options.maximumAge || 0,
}

const watcher = navigator.geolocation.watchPosition(
handleSuccess,
handleError,
geoOptions,
)

return () => navigator.geolocation.clearWatch(watcher)
}, [options.enableHighAccuracy, options.timeout, options.maximumAge])

return location
}

export default useLocation
15 changes: 12 additions & 3 deletions frontend/sportsmatch-app/src/pages/Index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { ApiError, EventDTO, EventsControllerService } from '../generated/api'
import useModal from '../hooks/UseModal'
import Modal from '../components/Modal'
import JoinEventComponent from '../components/JoinEventComponent'
import useLocation from '../hooks/UseLocation'

export default function MainPage() {
const [searchQuery, setSearchQuery] = useState<string>('')
Expand All @@ -21,6 +22,8 @@ export default function MainPage() {
const [page, setPage] = useState<number>(0)
const size = 3

const userCoords = useLocation().coords

// handle sports name selected from sportButtoncomponent
const handleSportSelectionChange = (selectedButtonSports: string[]) => {
setSelectedSports(selectedButtonSports)
Expand All @@ -45,8 +48,8 @@ export default function MainPage() {
try {
const response = await EventsControllerService.getNearbyEvents(
selectedSports,
0,
0,
userCoords.longitude || undefined,
userCoords.latitude || undefined,
searchQuery,
page,
size,
Expand All @@ -71,7 +74,13 @@ export default function MainPage() {
}
// call the method
fetchData()
}, [selectedSports, page, searchQuery])
}, [
selectedSports,
page,
searchQuery,
userCoords.latitude,
userCoords.longitude,
])

// handle join event pop up after cliking on the event
const handleEventSelection = (e: EventDTO) => {
Expand Down

0 comments on commit 0f46900

Please sign in to comment.