116 lines
3.3 KiB
JavaScript
116 lines
3.3 KiB
JavaScript
// src/stores/parks.js
|
|
import { defineStore } from 'pinia'
|
|
import ApiService from '../services/api'
|
|
|
|
export const useParksStore = defineStore('parks', {
|
|
state: () => ({
|
|
parks: [],
|
|
loading: false,
|
|
error: null,
|
|
neighborhoods: [],
|
|
filters: {
|
|
limit: 5,
|
|
minScore: 50,
|
|
neighborhood: null
|
|
}
|
|
}),
|
|
|
|
getters: {
|
|
parksByScore: (state) => {
|
|
return state.parks.sort((a, b) => b.currentScore - a.currentScore)
|
|
},
|
|
|
|
topParks: (state) => {
|
|
return state.parks.filter(park => park.currentScore >= 80)
|
|
}
|
|
},
|
|
|
|
actions: {
|
|
async fetchParks(personality) {
|
|
this.loading = true
|
|
this.error = null
|
|
|
|
try {
|
|
// Import mock data dynamically
|
|
const { mockParks } = await import('../data/mockParks')
|
|
|
|
// Simulate API delay
|
|
await new Promise(resolve => setTimeout(resolve, 800))
|
|
|
|
// Process parks with scoring for the selected personality
|
|
const scoredParks = mockParks
|
|
.map(park => ({
|
|
...park,
|
|
currentScore: park.scores[personality],
|
|
whyGood: park.why_good[personality] || "Great spot for this activity!"
|
|
}))
|
|
.sort((a, b) => b.currentScore - a.currentScore)
|
|
|
|
this.parks = scoredParks
|
|
} catch (error) {
|
|
this.error = error.message
|
|
console.error('Error fetching parks:', error)
|
|
} finally {
|
|
this.loading = false
|
|
}
|
|
},
|
|
|
|
async fetchGreenSpaceRecommendations(personalityType, customFilters = {}) {
|
|
this.loading = true
|
|
this.error = null
|
|
|
|
try {
|
|
const options = { ...this.filters, ...customFilters }
|
|
const result = await ApiService.getGreenSpaceRecommendations(personalityType, options)
|
|
|
|
// Normalize the data structure to match what components expect
|
|
if (result.recommendations && Array.isArray(result.recommendations)) {
|
|
this.parks = result.recommendations.map(rec => ({
|
|
...rec.green_space,
|
|
lat: rec.green_space.coordinates?.lat,
|
|
lng: rec.green_space.coordinates?.lng,
|
|
currentScore: rec.score,
|
|
whyGood: rec.explanation,
|
|
bestFeatures: rec.best_features || [],
|
|
visitRecommendation: rec.visit_recommendation,
|
|
area: rec.green_space.area_sqm,
|
|
amenities: {
|
|
wildlife_spotting: rec.green_space.environmental?.wildlife_diversity_score || 'Unknown'
|
|
}
|
|
}))
|
|
} else if (Array.isArray(result)) {
|
|
this.parks = result
|
|
} else {
|
|
this.parks = []
|
|
}
|
|
|
|
this.filters = result.filters || options
|
|
} catch (error) {
|
|
this.error = error.message
|
|
this.parks = []
|
|
console.error('Error fetching green space recommendations:', error)
|
|
} finally {
|
|
this.loading = false
|
|
}
|
|
},
|
|
|
|
async fetchNeighborhoods() {
|
|
try {
|
|
const neighborhoods = await ApiService.getNeighborhoods()
|
|
this.neighborhoods = Array.isArray(neighborhoods) ? neighborhoods : []
|
|
} catch (error) {
|
|
console.error('Error fetching neighborhoods:', error)
|
|
this.neighborhoods = []
|
|
}
|
|
},
|
|
|
|
updateFilters(newFilters) {
|
|
this.filters = { ...this.filters, ...newFilters }
|
|
},
|
|
|
|
clearParks() {
|
|
this.parks = []
|
|
this.error = null
|
|
}
|
|
}
|
|
}) |