QUICK NOTE: I've used block quotes to reflect which parts of the below text are copied from copilot's output.
Now we need to use the map to set up our target location. I think searching would be helpful for this to keep it in app. So let's go!
import React from 'react'
type SearchResult = {
name: string
geometry: {
location: {
lat: () => number
lng: () => number
}
}
}
type SearchResultsProps = {
results: SearchResult[]
onSelect: (location: { lat: number; lng: number }) => void
}
const SearchResults: React.FC<SearchResultsProps> = ({ results, onSelect }) => {
return (
<div>
<h2>Search Results</h2>
<ul>
{results.map((result, index) => (
<li
key={index}
onClick={() =>
onSelect({
lat: result.geometry.location.lat(),
lng: result.geometry.location.lng(),
})
}
>
{result.name}
</li>
))}
</ul>
</div>
)
}
Looks like we have a jsxa11y error
{
results.map((result, index) => (
<li
key={index}
role="button"
tabIndex={0}
onClick={() =>
onSelect({
lat: result.geometry.location.lat(),
lng: result.geometry.location.lng(),
})
}
onKeyPress={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
onSelect({
lat: result.geometry.location.lat(),
lng: result.geometry.location.lng(),
})
}
}}
style={{ cursor: 'pointer' }}
>
{result.name}
</li>
))
}
<li>
elements are still non-interactive so we need to go inline to fix!
{
results.map((result, index) => (
<button
key={index}
onClick={() =>
onSelect({
lat: result.geometry.location.lat(),
lng: result.geometry.location.lng(),
})
}
style={{
cursor: 'pointer',
display: 'block',
width: '100%',
textAlign: 'left',
background: 'none',
border: 'none',
padding: '0',
margin: '0',
}}
>
{result.name}
</button>
))
}
commit f373de3266724cd3799c43e3325d19789f6a8964
When looking at the above commit you'll notice that copilot inferred what I wanted to do when a result is clicked on: it centers the map on the target location. I was expecting that to be a separate request!
There were still some issues with types which resolved with inline copilot, but I had to be careful copilot didn't force custom types instead of using existing ones.
No, I don't need you to iterate over all results to filter out ones that don't have a specific key value. (Though that could cause errors down the line, I'm sure we'll have types yell at us when it matters.)
commit 9d9fa7c624628f1e228ba4a08eeef03c0c448b0f
Hmm, we center the map, but can we set a pin down?
The result does not work. I think it's supposed to have been placing the pin this whole time with the <Marker>
, but that's never worked.
I'll manually dive into google's advanced marker docs.
And there we go. Check it out on this commit:
commit 87de3312cdbd3efea06c9a82a3ed523ef25bb4cd Next we'll have to sort out what we're saving and if we have steps or single puzzles to solve.
Think this naive schema will work?
interface IScavengerHunt {
steps:{
location: google.maps.places.PlaceResult
clues: {type: 'img'|'string', value: string}[]
solution: string
}[]
}
Should we refactor some of the initial loading logic into a custom hook?