feat: add API services for templates, stats, integrations, and calendar
This commit is contained in:
@@ -62,26 +62,26 @@ api.interceptors.response.use(
|
|||||||
|
|
||||||
export const calendarApi = {
|
export const calendarApi = {
|
||||||
async getWorkouts() {
|
async getWorkouts() {
|
||||||
const { data } = await api.get('/protected/workouts')
|
const { data } = await api.get('/api/protected/workouts')
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async getWorkoutsByMonth(year, month) {
|
async getWorkoutsByMonth(year, month) {
|
||||||
const { data } = await api.get('/protected/workouts/month', {
|
const { data } = await api.get('/api/protected/workouts/month', {
|
||||||
params: { year, month }
|
params: { year, month }
|
||||||
})
|
})
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async getWorkoutsByWeek(year, week) {
|
async getWorkoutsByWeek(year, week) {
|
||||||
const { data } = await api.get('/protected/workouts/week', {
|
const { data } = await api.get('/api/protected/workouts/week', {
|
||||||
params: { year, week }
|
params: { year, week }
|
||||||
})
|
})
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async getWorkoutsByRange(startDate, endDate) {
|
async getWorkoutsByRange(startDate, endDate) {
|
||||||
const { data } = await api.get('/protected/workouts/range', {
|
const { data } = await api.get('/api/protected/workouts/range', {
|
||||||
params: {
|
params: {
|
||||||
start: startDate,
|
start: startDate,
|
||||||
end: endDate
|
end: endDate
|
||||||
@@ -91,29 +91,29 @@ export const calendarApi = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async createWorkout(workout) {
|
async createWorkout(workout) {
|
||||||
const { data } = await api.post('/protected/workouts', workout)
|
const { data } = await api.post('/api/protected/workouts', workout)
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async updateWorkout(workoutId, workout) {
|
async updateWorkout(workoutId, workout) {
|
||||||
const { data } = await api.put(`/protected/workouts?id=${workoutId}`, workout)
|
const { data } = await api.put(`/api/protected/workouts?id=${workoutId}`, workout)
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async rescheduleWorkout(workoutId, newDate) {
|
async rescheduleWorkout(workoutId, newDate) {
|
||||||
const { data } = await api.put(`/protected/workouts/reschedule?id=${workoutId}`, {
|
const { data } = await api.put(`/api/protected/workouts/reschedule?id=${workoutId}`, {
|
||||||
scheduled_date: newDate
|
scheduled_date: newDate
|
||||||
})
|
})
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async deleteWorkout(workoutId) {
|
async deleteWorkout(workoutId) {
|
||||||
const { data } = await api.delete(`/protected/workouts?id=${workoutId}`)
|
const { data } = await api.delete(`/api/protected/workouts?id=${workoutId}`)
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async scheduleFromTemplate(templateId, templateName, templateType, duration, scheduledDate, workoutData = null) {
|
async scheduleFromTemplate(templateId, templateName, templateType, duration, scheduledDate, workoutData = null) {
|
||||||
const { data } = await api.post('/protected/workouts/schedule-template', {
|
const { data } = await api.post('/api/protected/workouts/schedule-template', {
|
||||||
template_id: templateId,
|
template_id: templateId,
|
||||||
template_name: templateName,
|
template_name: templateName,
|
||||||
template_type: templateType,
|
template_type: templateType,
|
||||||
@@ -130,7 +130,7 @@ export const calendarApi = {
|
|||||||
if (scheduledDate) {
|
if (scheduledDate) {
|
||||||
formData.append('scheduled_date', scheduledDate)
|
formData.append('scheduled_date', scheduledDate)
|
||||||
}
|
}
|
||||||
const { data } = await api.post('/protected/workouts/upload', formData, {
|
const { data } = await api.post('/api/protected/workouts/upload', formData, {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'multipart/form-data'
|
'Content-Type': 'multipart/form-data'
|
||||||
}
|
}
|
||||||
@@ -139,7 +139,7 @@ export const calendarApi = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async exportICS(startDate, endDate) {
|
async exportICS(startDate, endDate) {
|
||||||
const response = await api.get('/protected/workouts/export/ics', {
|
const response = await api.get('/api/protected/workouts/export/ics', {
|
||||||
params: { start: startDate, end: endDate },
|
params: { start: startDate, end: endDate },
|
||||||
responseType: 'blob'
|
responseType: 'blob'
|
||||||
})
|
})
|
||||||
@@ -147,50 +147,77 @@ export const calendarApi = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async getWorkoutTypes() {
|
async getWorkoutTypes() {
|
||||||
const { data } = await api.get('/protected/workout-types')
|
const { data } = await api.get('/api/protected/workout-types')
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async completeWorkout(workoutId, completionData) {
|
async completeWorkout(workoutId, completionData) {
|
||||||
const { data } = await api.post(`/protected/workouts/complete?id=${workoutId}`, completionData)
|
const { data } = await api.post(`/api/protected/workouts/complete?id=${workoutId}`, completionData)
|
||||||
return data
|
return data
|
||||||
|
},
|
||||||
|
|
||||||
|
async importActivity(file, opts = {}) {
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.append('file', file)
|
||||||
|
if (opts.title) formData.append('title', opts.title)
|
||||||
|
if (opts.workout_id) formData.append('workout_id', String(opts.workout_id))
|
||||||
|
if (opts.equipment_id) formData.append('equipment_id', String(opts.equipment_id))
|
||||||
|
if (opts.notes) formData.append('notes', opts.notes)
|
||||||
|
const { data } = await api.post('/api/protected/workouts/import', formData, {
|
||||||
|
headers: { 'Content-Type': 'multipart/form-data' }
|
||||||
|
})
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
|
||||||
|
async exportFIT(workoutId) {
|
||||||
|
const response = await api.get(`/api/protected/workouts/export/fit?id=${workoutId}`, {
|
||||||
|
responseType: 'blob'
|
||||||
|
})
|
||||||
|
return response.data
|
||||||
|
},
|
||||||
|
|
||||||
|
async exportZWO(workoutId) {
|
||||||
|
const response = await api.get(`/api/protected/workouts/export/zwo?id=${workoutId}`, {
|
||||||
|
responseType: 'blob'
|
||||||
|
})
|
||||||
|
return response.data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const recurringApi = {
|
export const recurringApi = {
|
||||||
async create(schedule) {
|
async create(schedule) {
|
||||||
const { data } = await api.post('/protected/workouts/recurring', schedule)
|
const { data } = await api.post('/api/protected/workouts/recurring', schedule)
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async list() {
|
async list() {
|
||||||
const { data } = await api.get('/protected/workouts/recurring')
|
const { data } = await api.get('/api/protected/workouts/recurring')
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async delete(scheduleId, deleteFuture = true) {
|
async delete(scheduleId, deleteFuture = true) {
|
||||||
const { data } = await api.delete(`/protected/workouts/recurring?id=${scheduleId}&delete_future=${deleteFuture}`)
|
const { data } = await api.delete(`/api/protected/workouts/recurring?id=${scheduleId}&delete_future=${deleteFuture}`)
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const sessionApi = {
|
export const sessionApi = {
|
||||||
async getSessions() {
|
async getSessions() {
|
||||||
const { data } = await api.get('/protected/sessions', {
|
const { data } = await api.get('/api/protected/sessions', {
|
||||||
headers: { 'X-Refresh-Token': localStorage.getItem('refresh_token') }
|
headers: { 'X-Refresh-Token': localStorage.getItem('refresh_token') }
|
||||||
})
|
})
|
||||||
return data.sessions || []
|
return data.sessions || []
|
||||||
},
|
},
|
||||||
|
|
||||||
async revokeSession(sessionId) {
|
async revokeSession(sessionId) {
|
||||||
const { data } = await api.delete(`/protected/sessions/${sessionId}`, {
|
const { data } = await api.delete(`/api/protected/sessions/${sessionId}`, {
|
||||||
headers: { 'X-Refresh-Token': localStorage.getItem('refresh_token') }
|
headers: { 'X-Refresh-Token': localStorage.getItem('refresh_token') }
|
||||||
})
|
})
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async revokeAllOtherSessions() {
|
async revokeAllOtherSessions() {
|
||||||
const { data } = await api.delete('/protected/sessions/all', {
|
const { data } = await api.delete('/api/protected/sessions/all', {
|
||||||
headers: { 'X-Refresh-Token': localStorage.getItem('refresh_token') }
|
headers: { 'X-Refresh-Token': localStorage.getItem('refresh_token') }
|
||||||
})
|
})
|
||||||
return data
|
return data
|
||||||
@@ -199,32 +226,32 @@ export const sessionApi = {
|
|||||||
|
|
||||||
export const onboardingApi = {
|
export const onboardingApi = {
|
||||||
async getStatus() {
|
async getStatus() {
|
||||||
const { data } = await api.get('/protected/onboarding/status')
|
const { data } = await api.get('/api/protected/onboarding/status')
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async saveProfile(profileData) {
|
async saveProfile(profileData) {
|
||||||
const { data } = await api.post('/protected/onboarding/profile', profileData)
|
const { data } = await api.post('/api/protected/onboarding/profile', profileData)
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async saveMetrics(metricsData) {
|
async saveMetrics(metricsData) {
|
||||||
const { data } = await api.post('/protected/onboarding/metrics', metricsData)
|
const { data } = await api.post('/api/protected/onboarding/metrics', metricsData)
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async submitFTPTest(testData) {
|
async submitFTPTest(testData) {
|
||||||
const { data } = await api.post('/protected/onboarding/ftp-test', testData)
|
const { data } = await api.post('/api/protected/onboarding/ftp-test', testData)
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async getFTPHistory() {
|
async getFTPHistory() {
|
||||||
const { data } = await api.get('/protected/onboarding/ftp-history')
|
const { data } = await api.get('/api/protected/onboarding/ftp-history')
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async calculateHRZones(maxHR, restingHR) {
|
async calculateHRZones(maxHR, restingHR) {
|
||||||
const { data } = await api.post('/protected/onboarding/hr-zones', {
|
const { data } = await api.post('/api/protected/onboarding/hr-zones', {
|
||||||
max_hr: maxHR,
|
max_hr: maxHR,
|
||||||
resting_hr: restingHR
|
resting_hr: restingHR
|
||||||
})
|
})
|
||||||
@@ -232,7 +259,7 @@ export const onboardingApi = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async estimateFTP(fitnessLevel, weight) {
|
async estimateFTP(fitnessLevel, weight) {
|
||||||
const { data } = await api.post('/protected/onboarding/estimate-ftp', {
|
const { data } = await api.post('/api/protected/onboarding/estimate-ftp', {
|
||||||
fitness_level: fitnessLevel,
|
fitness_level: fitnessLevel,
|
||||||
weight: weight
|
weight: weight
|
||||||
})
|
})
|
||||||
@@ -240,148 +267,158 @@ export const onboardingApi = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async estimateMaxHR(age) {
|
async estimateMaxHR(age) {
|
||||||
const { data } = await api.post('/protected/onboarding/estimate-max-hr', { age })
|
const { data } = await api.post('/api/protected/onboarding/estimate-max-hr', { age })
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async completeEquipmentStep() {
|
async completeEquipmentStep() {
|
||||||
const { data } = await api.post('/protected/onboarding/equipment')
|
const { data } = await api.post('/api/protected/onboarding/equipment')
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async savePreferences(preferences) {
|
async savePreferences(preferences) {
|
||||||
const { data } = await api.post('/protected/onboarding/preferences', preferences)
|
const { data } = await api.post('/api/protected/onboarding/preferences', preferences)
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async complete() {
|
async complete() {
|
||||||
const { data } = await api.post('/protected/onboarding/complete')
|
const { data } = await api.post('/api/protected/onboarding/complete')
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async skip() {
|
async skip() {
|
||||||
const { data } = await api.post('/protected/onboarding/skip')
|
const { data } = await api.post('/api/protected/onboarding/skip')
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const equipmentApi = {
|
export const equipmentApi = {
|
||||||
async create(equipment) {
|
async create(equipment) {
|
||||||
const { data } = await api.post('/protected/equipment', equipment)
|
const { data } = await api.post('/api/protected/equipment', equipment)
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async list() {
|
async list() {
|
||||||
const { data } = await api.get('/protected/equipment')
|
const { data } = await api.get('/api/protected/equipment')
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async update(equipmentId, equipment) {
|
async update(equipmentId, equipment) {
|
||||||
const { data } = await api.put(`/protected/equipment?id=${equipmentId}`, equipment)
|
const { data } = await api.put(`/api/protected/equipment?id=${equipmentId}`, equipment)
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async delete(equipmentId) {
|
async delete(equipmentId) {
|
||||||
const { data } = await api.delete(`/protected/equipment?id=${equipmentId}`)
|
const { data } = await api.delete(`/api/protected/equipment?id=${equipmentId}`)
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async getTrainingZones() {
|
async getTrainingZones() {
|
||||||
const { data } = await api.get('/protected/zones')
|
const { data } = await api.get('/api/protected/zones')
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
|
||||||
|
async recordService(equipmentId) {
|
||||||
|
const { data } = await api.post(`/api/protected/equipment/service?id=${equipmentId}`)
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
|
||||||
|
async getServiceStatus(equipmentId) {
|
||||||
|
const { data } = await api.get(`/api/protected/equipment/service-status?id=${equipmentId}`)
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const teamsApi = {
|
export const teamsApi = {
|
||||||
async create(team) {
|
async create(team) {
|
||||||
const { data } = await api.post('/protected/teams', team)
|
const { data } = await api.post('/api/protected/teams', team)
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async list() {
|
async list() {
|
||||||
const { data } = await api.get('/protected/teams')
|
const { data } = await api.get('/api/protected/teams')
|
||||||
return data.teams || []
|
return data.teams || []
|
||||||
},
|
},
|
||||||
|
|
||||||
async get(teamId) {
|
async get(teamId) {
|
||||||
const { data } = await api.get(`/protected/teams/${teamId}`)
|
const { data } = await api.get(`/api/protected/teams/${teamId}`)
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async update(teamId, team) {
|
async update(teamId, team) {
|
||||||
const { data } = await api.put(`/protected/teams/${teamId}`, team)
|
const { data } = await api.put(`/api/protected/teams/${teamId}`, team)
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async delete(teamId) {
|
async delete(teamId) {
|
||||||
const { data } = await api.delete(`/protected/teams/${teamId}`)
|
const { data } = await api.delete(`/api/protected/teams/${teamId}`)
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async getMembers(teamId) {
|
async getMembers(teamId) {
|
||||||
const { data } = await api.get(`/protected/teams/${teamId}/members`)
|
const { data } = await api.get(`/api/protected/teams/${teamId}/members`)
|
||||||
return data.members || []
|
return data.members || []
|
||||||
},
|
},
|
||||||
|
|
||||||
async updateMemberRole(teamId, userId, role) {
|
async updateMemberRole(teamId, userId, role) {
|
||||||
const { data } = await api.put(`/protected/teams/${teamId}/members/${userId}/role`, { role })
|
const { data } = await api.put(`/api/protected/teams/${teamId}/members/${userId}/role`, { role })
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async removeMember(teamId, userId) {
|
async removeMember(teamId, userId) {
|
||||||
const { data } = await api.delete(`/protected/teams/${teamId}/members/${userId}`)
|
const { data } = await api.delete(`/api/protected/teams/${teamId}/members/${userId}`)
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async leave(teamId) {
|
async leave(teamId) {
|
||||||
const { data } = await api.delete(`/protected/teams/${teamId}/leave`)
|
const { data } = await api.delete(`/api/protected/teams/${teamId}/leave`)
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async sendInvite(teamId, email, role) {
|
async sendInvite(teamId, email, role) {
|
||||||
const { data } = await api.post(`/protected/teams/${teamId}/invite`, { email, role })
|
const { data } = await api.post(`/api/protected/teams/${teamId}/invite`, { email, role })
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async getTeamInvites(teamId) {
|
async getTeamInvites(teamId) {
|
||||||
const { data } = await api.get(`/protected/teams/${teamId}/invites`)
|
const { data } = await api.get(`/api/protected/teams/${teamId}/invites`)
|
||||||
return data.invites || []
|
return data.invites || []
|
||||||
},
|
},
|
||||||
|
|
||||||
async cancelInvite(teamId, inviteId) {
|
async cancelInvite(teamId, inviteId) {
|
||||||
const { data } = await api.delete(`/protected/teams/${teamId}/invites/${inviteId}`)
|
const { data } = await api.delete(`/api/protected/teams/${teamId}/invites/${inviteId}`)
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async getMyInvites() {
|
async getMyInvites() {
|
||||||
const { data } = await api.get('/protected/invites')
|
const { data } = await api.get('/api/protected/invites')
|
||||||
return data.invites || []
|
return data.invites || []
|
||||||
},
|
},
|
||||||
|
|
||||||
async acceptInvite(token) {
|
async acceptInvite(token) {
|
||||||
const { data } = await api.post('/protected/invites/accept', { token })
|
const { data } = await api.post('/api/protected/invites/accept', { token })
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async declineInvite(token) {
|
async declineInvite(token) {
|
||||||
const { data } = await api.post('/protected/invites/decline', { token })
|
const { data } = await api.post('/api/protected/invites/decline', { token })
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const coachingApi = {
|
export const coachingApi = {
|
||||||
async getAthletes() {
|
async getAthletes() {
|
||||||
const { data } = await api.get('/protected/coaching/athletes')
|
const { data } = await api.get('/api/protected/coaching/athletes')
|
||||||
return data.athletes || []
|
return data.athletes || []
|
||||||
},
|
},
|
||||||
|
|
||||||
async getCoaches() {
|
async getCoaches() {
|
||||||
const { data } = await api.get('/protected/coaching/coaches')
|
const { data } = await api.get('/api/protected/coaching/coaches')
|
||||||
return data.coaches || []
|
return data.coaches || []
|
||||||
},
|
},
|
||||||
|
|
||||||
async requestCoaching(coachId, note = null) {
|
async requestCoaching(coachId, note = null) {
|
||||||
const { data } = await api.post('/protected/coaching/request', {
|
const { data } = await api.post('/api/protected/coaching/request', {
|
||||||
coach_id: coachId,
|
coach_id: coachId,
|
||||||
note: note
|
note: note
|
||||||
})
|
})
|
||||||
@@ -389,41 +426,41 @@ export const coachingApi = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async acceptRequest(relationId) {
|
async acceptRequest(relationId) {
|
||||||
const { data } = await api.post('/protected/coaching/accept', {
|
const { data } = await api.post('/api/protected/coaching/accept', {
|
||||||
relation_id: relationId
|
relation_id: relationId
|
||||||
})
|
})
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async endRelationship(athleteId) {
|
async endRelationship(athleteId) {
|
||||||
const { data } = await api.delete(`/protected/coaching/${athleteId}`)
|
const { data } = await api.delete(`/api/protected/coaching/${athleteId}`)
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const oauthApi = {
|
export const oauthApi = {
|
||||||
async getAccounts() {
|
async getAccounts() {
|
||||||
const { data } = await api.get('/protected/oauth/accounts')
|
const { data } = await api.get('/api/protected/oauth/accounts')
|
||||||
return data.accounts || []
|
return data.accounts || []
|
||||||
},
|
},
|
||||||
|
|
||||||
async linkStrava(code) {
|
async linkStrava(code) {
|
||||||
const { data } = await api.post('/protected/oauth/link/strava', { code })
|
const { data } = await api.post('/api/protected/oauth/link/strava', { code })
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async linkGoogle() {
|
async linkGoogle() {
|
||||||
const { data } = await api.post('/protected/oauth/link/google')
|
const { data } = await api.post('/api/protected/oauth/link/google')
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async unlink(provider) {
|
async unlink(provider) {
|
||||||
const { data } = await api.delete(`/protected/oauth/unlink/${provider}`)
|
const { data } = await api.delete(`/api/protected/oauth/unlink/${provider}`)
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async syncStrava() {
|
async syncStrava() {
|
||||||
const { data } = await api.post('/protected/oauth/strava/sync')
|
const { data } = await api.post('/api/protected/oauth/strava/sync')
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -431,4 +468,87 @@ export const oauthApi = {
|
|||||||
getStravaAuthUrl: () => `${API_BASE_URL}/api/oauth/strava`
|
getStravaAuthUrl: () => `${API_BASE_URL}/api/oauth/strava`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const statsApi = {
|
||||||
|
async getSummary() {
|
||||||
|
const { data } = await api.get('/api/protected/stats/summary')
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
|
||||||
|
async getWeeklyStats(weeks = 12) {
|
||||||
|
const { data } = await api.get('/api/protected/stats/weekly', { params: { weeks } })
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
|
||||||
|
async getMonthlyStats(months = 12) {
|
||||||
|
const { data } = await api.get('/api/protected/stats/monthly', { params: { months } })
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
|
||||||
|
async getPersonalBests() {
|
||||||
|
const { data } = await api.get('/api/protected/stats/personal-bests')
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const templatesApi = {
|
||||||
|
async list(category = '') {
|
||||||
|
const params = {}
|
||||||
|
if (category) params.category = category
|
||||||
|
const { data } = await api.get('/api/protected/workout-templates', { params })
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
|
||||||
|
async getDetail(id) {
|
||||||
|
const { data } = await api.get(`/api/protected/workout-templates/detail?id=${id}`)
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
|
||||||
|
async createFromTemplate(payload) {
|
||||||
|
const { data } = await api.post('/api/protected/workouts/from-template', payload)
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const integrationsApi = {
|
||||||
|
async garminAuth() {
|
||||||
|
const { data } = await api.get('/api/protected/garmin/auth')
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
|
||||||
|
async garminStatus() {
|
||||||
|
const { data } = await api.get('/api/protected/garmin/status')
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
|
||||||
|
async garminDisconnect() {
|
||||||
|
const { data } = await api.delete('/api/protected/garmin/disconnect')
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
|
||||||
|
async pushToGarmin(workoutId) {
|
||||||
|
const { data } = await api.post(`/api/protected/workouts/push/garmin?id=${workoutId}`)
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
|
||||||
|
async wahooAuth() {
|
||||||
|
const { data } = await api.get('/api/protected/wahoo/auth')
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
|
||||||
|
async wahooStatus() {
|
||||||
|
const { data } = await api.get('/api/protected/wahoo/status')
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
|
||||||
|
async wahooDisconnect() {
|
||||||
|
const { data } = await api.delete('/api/protected/wahoo/disconnect')
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
|
||||||
|
async pushToWahoo(workoutId) {
|
||||||
|
const { data } = await api.post(`/api/protected/workouts/push/wahoo?id=${workoutId}`)
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default api
|
export default api
|
||||||
|
|||||||
@@ -3,19 +3,19 @@ import api from './api'
|
|||||||
export const workoutLibraryApi = {
|
export const workoutLibraryApi = {
|
||||||
// Get workout types, categories, and difficulties
|
// Get workout types, categories, and difficulties
|
||||||
async getTypes() {
|
async getTypes() {
|
||||||
const { data } = await api.get('/protected/library/types')
|
const { data } = await api.get('/api/protected/library/types')
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
// Get system-provided workouts
|
// Get system-provided workouts
|
||||||
async getSystemWorkouts() {
|
async getSystemWorkouts() {
|
||||||
const { data } = await api.get('/protected/library/system')
|
const { data } = await api.get('/api/protected/library/system')
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
// Browse public workouts (paginated)
|
// Browse public workouts (paginated)
|
||||||
async browseWorkouts(page = 1, pageSize = 20) {
|
async browseWorkouts(page = 1, pageSize = 20) {
|
||||||
const { data } = await api.get('/protected/library/browse', {
|
const { data } = await api.get('/api/protected/library/browse', {
|
||||||
params: { page, page_size: pageSize }
|
params: { page, page_size: pageSize }
|
||||||
})
|
})
|
||||||
return data
|
return data
|
||||||
@@ -23,7 +23,7 @@ export const workoutLibraryApi = {
|
|||||||
|
|
||||||
// Search/filter workouts
|
// Search/filter workouts
|
||||||
async searchWorkouts(params = {}) {
|
async searchWorkouts(params = {}) {
|
||||||
const { data } = await api.get('/protected/library/search', {
|
const { data } = await api.get('/api/protected/library/search', {
|
||||||
params: {
|
params: {
|
||||||
q: params.search || undefined,
|
q: params.search || undefined,
|
||||||
type: params.type || undefined,
|
type: params.type || undefined,
|
||||||
@@ -38,73 +38,73 @@ export const workoutLibraryApi = {
|
|||||||
|
|
||||||
// Get workouts by type
|
// Get workouts by type
|
||||||
async getWorkoutsByType(type) {
|
async getWorkoutsByType(type) {
|
||||||
const { data } = await api.get(`/protected/library/type/${type}`)
|
const { data } = await api.get(`/api/protected/library/type/${type}`)
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
// Get workouts by category
|
// Get workouts by category
|
||||||
async getWorkoutsByCategory(category) {
|
async getWorkoutsByCategory(category) {
|
||||||
const { data } = await api.get(`/protected/library/category/${category}`)
|
const { data } = await api.get(`/api/protected/library/category/${category}`)
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
// Get single workout details
|
// Get single workout details
|
||||||
async getWorkout(workoutId) {
|
async getWorkout(workoutId) {
|
||||||
const { data } = await api.get(`/protected/library/${workoutId}`)
|
const { data } = await api.get(`/api/protected/library/${workoutId}`)
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
// Get current user's custom workouts
|
// Get current user's custom workouts
|
||||||
async getUserWorkouts() {
|
async getUserWorkouts() {
|
||||||
const { data } = await api.get('/protected/library/mine')
|
const { data } = await api.get('/api/protected/library/mine')
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
// Get user's favorited workouts
|
// Get user's favorited workouts
|
||||||
async getFavorites() {
|
async getFavorites() {
|
||||||
const { data } = await api.get('/protected/library/favorites')
|
const { data } = await api.get('/api/protected/library/favorites')
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
// Create custom workout
|
// Create custom workout
|
||||||
async createWorkout(workout) {
|
async createWorkout(workout) {
|
||||||
const { data } = await api.post('/protected/library', workout)
|
const { data } = await api.post('/api/protected/library', workout)
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
// Update user's workout
|
// Update user's workout
|
||||||
async updateWorkout(workoutId, workout) {
|
async updateWorkout(workoutId, workout) {
|
||||||
const { data } = await api.put(`/protected/library/${workoutId}`, workout)
|
const { data } = await api.put(`/api/protected/library/${workoutId}`, workout)
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
// Delete user's workout
|
// Delete user's workout
|
||||||
async deleteWorkout(workoutId) {
|
async deleteWorkout(workoutId) {
|
||||||
const { data } = await api.delete(`/protected/library/${workoutId}`)
|
const { data } = await api.delete(`/api/protected/library/${workoutId}`)
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
// Mark workout as used
|
// Mark workout as used
|
||||||
async recordUsage(workoutId) {
|
async recordUsage(workoutId) {
|
||||||
const { data } = await api.post(`/protected/library/${workoutId}/use`)
|
const { data } = await api.post(`/api/protected/library/${workoutId}/use`)
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
// Add to favorites
|
// Add to favorites
|
||||||
async addFavorite(workoutId) {
|
async addFavorite(workoutId) {
|
||||||
const { data } = await api.post(`/protected/library/${workoutId}/favorite`)
|
const { data } = await api.post(`/api/protected/library/${workoutId}/favorite`)
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
// Remove from favorites
|
// Remove from favorites
|
||||||
async removeFavorite(workoutId) {
|
async removeFavorite(workoutId) {
|
||||||
const { data } = await api.delete(`/protected/library/${workoutId}/favorite`)
|
const { data } = await api.delete(`/api/protected/library/${workoutId}/favorite`)
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
// Rate workout (1-5 stars + optional comment)
|
// Rate workout (1-5 stars + optional comment)
|
||||||
async rateWorkout(workoutId, rating, comment = null) {
|
async rateWorkout(workoutId, rating, comment = null) {
|
||||||
const { data } = await api.post(`/protected/library/${workoutId}/rate`, {
|
const { data } = await api.post(`/api/protected/library/${workoutId}/rate`, {
|
||||||
rating,
|
rating,
|
||||||
comment: comment || undefined
|
comment: comment || undefined
|
||||||
})
|
})
|
||||||
@@ -113,7 +113,7 @@ export const workoutLibraryApi = {
|
|||||||
|
|
||||||
// Schedule a library workout to a specific date
|
// Schedule a library workout to a specific date
|
||||||
async scheduleToCalendar(workout, scheduledDate) {
|
async scheduleToCalendar(workout, scheduledDate) {
|
||||||
const { data } = await api.post('/protected/workouts/schedule-template', {
|
const { data } = await api.post('/api/protected/workouts/schedule-template', {
|
||||||
template_id: workout.id,
|
template_id: workout.id,
|
||||||
template_name: workout.name,
|
template_name: workout.name,
|
||||||
template_type: workout.type,
|
template_type: workout.type,
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ export const useAuthStore = defineStore('auth', () => {
|
|||||||
error.value = null
|
error.value = null
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { data } = await api.get('/protected/profile')
|
const { data } = await api.get('/api/protected/profile')
|
||||||
return data
|
return data
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
error.value = err.response?.data?.error || 'Failed to fetch profile'
|
error.value = err.response?.data?.error || 'Failed to fetch profile'
|
||||||
@@ -140,7 +140,7 @@ export const useAuthStore = defineStore('auth', () => {
|
|||||||
error.value = null
|
error.value = null
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { data } = await api.put('/protected/profile', profileData)
|
const { data } = await api.put('/api/protected/profile', profileData)
|
||||||
return data
|
return data
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
error.value = err.response?.data?.error || 'Failed to update profile'
|
error.value = err.response?.data?.error || 'Failed to update profile'
|
||||||
|
|||||||
Reference in New Issue
Block a user