36 lines
3.6 KiB
JSON
36 lines
3.6 KiB
JSON
{
|
|
"skill_name": "mapbox-store-locator-patterns",
|
|
"evals": [
|
|
{
|
|
"id": 1,
|
|
"prompt": "Review this store locator implementation and identify the issues:\n\n```javascript\n// Store locator for 300 coffee shop locations\nmapboxgl.accessToken = TOKEN;\nconst map = new mapboxgl.Map({ container: 'map', style: 'mapbox://styles/mapbox/streets-v12' });\n\n// Display markers\nfunction loadMarkers(storeData) {\n storeData.features.forEach(store => {\n new mapboxgl.Marker()\n .setLngLat(store.geometry.coordinates)\n .addTo(map);\n });\n}\n\n// Filter: fetch filtered results from server on each keystroke\nasync function filterStores(searchTerm) {\n const results = await fetch(`/api/stores?q=${encodeURIComponent(searchTerm)}`).then(r => r.json());\n\n // Remove old layer and re-add with filtered data\n if (map.getLayer('stores-layer')) map.removeLayer('stores-layer');\n if (map.getSource('stores')) map.removeSource('stores');\n map.addSource('stores', { type: 'geojson', data: results });\n map.addLayer({ id: 'stores-layer', type: 'symbol', source: 'stores', layout: { 'icon-image': 'marker-15' } });\n\n document.getElementById('listings').innerHTML = '';\n buildLocationList(results);\n}\n\n// Highlight selected listing\nfunction highlightListing(id) {\n document.querySelectorAll('.listing').forEach(l => l.classList.remove('active'));\n const listing = document.getElementById(`listing-${id}`);\n listing.classList.add('active');\n}\n\ndocument.getElementById('search-input').addEventListener('input', e => filterStores(e.target.value));\n\nmap.on('load', () => loadMarkers(allStores));\n```",
|
|
"expectations": [
|
|
"Identifies 300 HTML markers exceeds the < 100 threshold — recommends switching to a symbol layer",
|
|
"Identifies the filter function fetches from the server on every keystroke — recommends loading all store data once and filtering in memory",
|
|
"Identifies remove/re-add layer pattern is expensive — recommends map.getSource('stores').setData(filtered) instead",
|
|
"Identifies highlightListing is missing scrollIntoView — the selected listing should scroll into view in the sidebar"
|
|
]
|
|
},
|
|
{
|
|
"id": 2,
|
|
"prompt": "I'm building a coffee shop finder. I have 150 locations in a GeoJSON file. I started with `new mapboxgl.Marker()` for each one but the page feels sluggish. My colleague says I should add clustering. What's the right marker strategy for 150 locations?",
|
|
"expectations": [
|
|
"Recommends symbol layer (not clustering) for 150 locations",
|
|
"States HTML markers are appropriate only for fewer than 100 locations",
|
|
"States clustering is appropriate for more than 1000 locations — 150 does not require it",
|
|
"Explains symbol layers render on the GPU via WebGL instead of creating 150 DOM elements"
|
|
]
|
|
},
|
|
{
|
|
"id": 3,
|
|
"prompt": "I want to add a location-aware feature to my store locator: when the user clicks 'Find Stores Near Me', I want to (a) show their location on the map as a blue dot and (b) sort the sidebar listing by distance from their location. What APIs and approach should I use?",
|
|
"expectations": [
|
|
"Recommends adding mapboxgl.GeolocateControl to the map for the blue dot / on-map location indicator",
|
|
"Recommends using navigator.geolocation.getCurrentPosition() separately to get coordinates for distance calculation",
|
|
"Recommends using Turf.js (turf.distance) for distance calculation rather than a custom Haversine formula",
|
|
"Shows sorting the stores array by the calculated distance before rebuilding the sidebar list"
|
|
]
|
|
}
|
|
]
|
|
}
|