Files
rideaware-ui/src/stores/workoutLibrary.js

270 lines
6.9 KiB
JavaScript

import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import workoutLibraryApi from '@/services/workoutLibraryApi'
export const useWorkoutLibraryStore = defineStore('workoutLibrary', () => {
const workouts = ref([])
const userWorkouts = ref([])
const favorites = ref([])
const currentWorkout = ref(null)
const currentIntervals = ref([])
const loading = ref(false)
const error = ref(null)
const filters = ref({
category: '',
duration_min: null,
duration_max: null,
intensity_min: null,
intensity_max: null,
search: ''
})
const pagination = ref({
page: 1,
limit: 20,
total: 0
})
const favoriteIds = computed(() => new Set(favorites.value.map(f => f.id)))
const isFavorited = (workoutId) => favoriteIds.value.has(workoutId)
async function fetchWorkouts() {
loading.value = true
error.value = null
try {
const params = {
page: pagination.value.page,
limit: pagination.value.limit,
...Object.fromEntries(
Object.entries(filters.value).filter(([_, v]) => v !== '' && v !== null)
)
}
const data = await workoutLibraryApi.getWorkouts(params)
workouts.value = data.workouts || []
pagination.value.total = data.total || 0
} catch (err) {
error.value = err.response?.data?.error || 'Failed to fetch workouts'
} finally {
loading.value = false
}
}
async function fetchWorkout(workoutId) {
loading.value = true
error.value = null
try {
const data = await workoutLibraryApi.getWorkout(workoutId)
currentWorkout.value = data.workout || data
return currentWorkout.value
} catch (err) {
error.value = err.response?.data?.error || 'Failed to fetch workout'
throw err
} finally {
loading.value = false
}
}
async function fetchWorkoutIntervals(workoutId) {
try {
const data = await workoutLibraryApi.getWorkoutIntervals(workoutId)
currentIntervals.value = data.intervals || []
return currentIntervals.value
} catch (err) {
error.value = err.response?.data?.error || 'Failed to fetch intervals'
throw err
}
}
async function fetchUserWorkouts() {
loading.value = true
error.value = null
try {
const data = await workoutLibraryApi.getUserWorkouts()
userWorkouts.value = data.workouts || []
} catch (err) {
error.value = err.response?.data?.error || 'Failed to fetch your workouts'
} finally {
loading.value = false
}
}
async function createWorkout(workout) {
loading.value = true
error.value = null
try {
const data = await workoutLibraryApi.createWorkout(workout)
userWorkouts.value.unshift(data.workout || data)
return data.workout || data
} catch (err) {
error.value = err.response?.data?.error || 'Failed to create workout'
throw err
} finally {
loading.value = false
}
}
async function updateWorkout(workoutId, workout) {
loading.value = true
error.value = null
try {
const data = await workoutLibraryApi.updateWorkout(workoutId, workout)
const index = userWorkouts.value.findIndex(w => w.id === workoutId)
if (index !== -1) {
userWorkouts.value[index] = data.workout || data
}
return data.workout || data
} catch (err) {
error.value = err.response?.data?.error || 'Failed to update workout'
throw err
} finally {
loading.value = false
}
}
async function deleteWorkout(workoutId) {
loading.value = true
error.value = null
try {
await workoutLibraryApi.deleteWorkout(workoutId)
userWorkouts.value = userWorkouts.value.filter(w => w.id !== workoutId)
} catch (err) {
error.value = err.response?.data?.error || 'Failed to delete workout'
throw err
} finally {
loading.value = false
}
}
async function publishWorkout(workoutId) {
loading.value = true
error.value = null
try {
const data = await workoutLibraryApi.publishWorkout(workoutId)
const index = userWorkouts.value.findIndex(w => w.id === workoutId)
if (index !== -1) {
userWorkouts.value[index].is_public = true
}
return data
} catch (err) {
error.value = err.response?.data?.error || 'Failed to publish workout'
throw err
} finally {
loading.value = false
}
}
async function fetchFavorites() {
loading.value = true
error.value = null
try {
const data = await workoutLibraryApi.getFavorites()
favorites.value = data.favorites || data.workouts || []
} catch (err) {
error.value = err.response?.data?.error || 'Failed to fetch favorites'
} finally {
loading.value = false
}
}
async function toggleFavorite(workoutId) {
try {
if (isFavorited(workoutId)) {
await workoutLibraryApi.removeFavorite(workoutId)
favorites.value = favorites.value.filter(f => f.id !== workoutId)
} else {
await workoutLibraryApi.addFavorite(workoutId)
const workout = workouts.value.find(w => w.id === workoutId) || currentWorkout.value
if (workout) {
favorites.value.push(workout)
}
}
} catch (err) {
error.value = err.response?.data?.error || 'Failed to update favorite'
throw err
}
}
async function recordUsage(workoutId) {
try {
await workoutLibraryApi.recordUsage(workoutId)
} catch (err) {
console.error('Failed to record usage:', err)
}
}
async function rateWorkout(workoutId, rating) {
try {
const data = await workoutLibraryApi.rateWorkout(workoutId, rating)
if (currentWorkout.value && currentWorkout.value.id === workoutId) {
currentWorkout.value.average_rating = data.average_rating
currentWorkout.value.rating_count = data.rating_count
currentWorkout.value.user_rating = rating
}
return data
} catch (err) {
error.value = err.response?.data?.error || 'Failed to rate workout'
throw err
}
}
function setFilters(newFilters) {
filters.value = { ...filters.value, ...newFilters }
pagination.value.page = 1
}
function clearFilters() {
filters.value = {
category: '',
duration_min: null,
duration_max: null,
intensity_min: null,
intensity_max: null,
search: ''
}
pagination.value.page = 1
}
function setPage(page) {
pagination.value.page = page
}
return {
workouts,
userWorkouts,
favorites,
currentWorkout,
currentIntervals,
loading,
error,
filters,
pagination,
favoriteIds,
isFavorited,
fetchWorkouts,
fetchWorkout,
fetchWorkoutIntervals,
fetchUserWorkouts,
createWorkout,
updateWorkout,
deleteWorkout,
publishWorkout,
fetchFavorites,
toggleFavorite,
recordUsage,
rateWorkout,
setFilters,
clearFilters,
setPage
}
})