270 lines
6.9 KiB
JavaScript
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
|
|
}
|
|
})
|