224 lines
5.1 KiB
JavaScript
224 lines
5.1 KiB
JavaScript
|
|
/**
|
||
|
|
* Shinkan Jinkendo API Client
|
||
|
|
*
|
||
|
|
* Zentrale API-Kommunikation mit automatischer Token-Injektion
|
||
|
|
*/
|
||
|
|
|
||
|
|
const API_URL = import.meta.env.VITE_API_URL || ''
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generic API request with automatic token injection
|
||
|
|
*/
|
||
|
|
async function request(endpoint, options = {}) {
|
||
|
|
const token = localStorage.getItem('authToken')
|
||
|
|
|
||
|
|
const headers = {
|
||
|
|
'Content-Type': 'application/json',
|
||
|
|
...options.headers
|
||
|
|
}
|
||
|
|
|
||
|
|
if (token) {
|
||
|
|
headers['X-Auth-Token'] = token
|
||
|
|
}
|
||
|
|
|
||
|
|
const response = await fetch(`${API_URL}${endpoint}`, {
|
||
|
|
...options,
|
||
|
|
headers
|
||
|
|
})
|
||
|
|
|
||
|
|
if (!response.ok) {
|
||
|
|
const error = await response.json().catch(() => ({ detail: 'Unknown error' }))
|
||
|
|
throw new Error(error.detail || `HTTP ${response.status}`)
|
||
|
|
}
|
||
|
|
|
||
|
|
return response.json()
|
||
|
|
}
|
||
|
|
|
||
|
|
// ============================================================================
|
||
|
|
// Auth
|
||
|
|
// ============================================================================
|
||
|
|
|
||
|
|
export async function login(email, password) {
|
||
|
|
return request('/api/auth/login', {
|
||
|
|
method: 'POST',
|
||
|
|
body: JSON.stringify({ email, password })
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function register(email, password, name) {
|
||
|
|
return request('/api/auth/register', {
|
||
|
|
method: 'POST',
|
||
|
|
body: JSON.stringify({ email, password, name })
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function logout() {
|
||
|
|
return request('/api/auth/logout', { method: 'POST' })
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function getCurrentProfile() {
|
||
|
|
return request('/api/profiles/me')
|
||
|
|
}
|
||
|
|
|
||
|
|
// ============================================================================
|
||
|
|
// Clubs & Groups
|
||
|
|
// ============================================================================
|
||
|
|
|
||
|
|
export async function listClubs() {
|
||
|
|
return request('/api/clubs')
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function createClub(data) {
|
||
|
|
return request('/api/clubs', {
|
||
|
|
method: 'POST',
|
||
|
|
body: JSON.stringify(data)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function listTrainingGroups(clubId) {
|
||
|
|
const query = clubId ? `?club_id=${clubId}` : ''
|
||
|
|
return request(`/api/groups${query}`)
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function createTrainingGroup(data) {
|
||
|
|
return request('/api/groups', {
|
||
|
|
method: 'POST',
|
||
|
|
body: JSON.stringify(data)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// ============================================================================
|
||
|
|
// Skills & Methods
|
||
|
|
// ============================================================================
|
||
|
|
|
||
|
|
export async function listSkills() {
|
||
|
|
return request('/api/skills')
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function createSkill(data) {
|
||
|
|
return request('/api/skills', {
|
||
|
|
method: 'POST',
|
||
|
|
body: JSON.stringify(data)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function listMethods() {
|
||
|
|
return request('/api/methods')
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function createMethod(data) {
|
||
|
|
return request('/api/methods', {
|
||
|
|
method: 'POST',
|
||
|
|
body: JSON.stringify(data)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// ============================================================================
|
||
|
|
// Exercises
|
||
|
|
// ============================================================================
|
||
|
|
|
||
|
|
export async function listExercises(filters = {}) {
|
||
|
|
const query = new URLSearchParams(filters).toString()
|
||
|
|
return request(`/api/exercises${query ? '?' + query : ''}`)
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function getExercise(id) {
|
||
|
|
return request(`/api/exercises/${id}`)
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function createExercise(data) {
|
||
|
|
return request('/api/exercises', {
|
||
|
|
method: 'POST',
|
||
|
|
body: JSON.stringify(data)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function updateExercise(id, data) {
|
||
|
|
return request(`/api/exercises/${id}`, {
|
||
|
|
method: 'PUT',
|
||
|
|
body: JSON.stringify(data)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function deleteExercise(id) {
|
||
|
|
return request(`/api/exercises/${id}`, { method: 'DELETE' })
|
||
|
|
}
|
||
|
|
|
||
|
|
// ============================================================================
|
||
|
|
// Training Planning
|
||
|
|
// ============================================================================
|
||
|
|
|
||
|
|
export async function listTrainingUnits(groupId, startDate, endDate) {
|
||
|
|
const query = new URLSearchParams({ group_id: groupId, start_date: startDate, end_date: endDate }).toString()
|
||
|
|
return request(`/api/training-units?${query}`)
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function getTrainingUnit(id) {
|
||
|
|
return request(`/api/training-units/${id}`)
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function createTrainingUnit(data) {
|
||
|
|
return request('/api/training-units', {
|
||
|
|
method: 'POST',
|
||
|
|
body: JSON.stringify(data)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function updateTrainingUnit(id, data) {
|
||
|
|
return request(`/api/training-units/${id}`, {
|
||
|
|
method: 'PUT',
|
||
|
|
body: JSON.stringify(data)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// ============================================================================
|
||
|
|
// Version & Health
|
||
|
|
// ============================================================================
|
||
|
|
|
||
|
|
export async function getVersion() {
|
||
|
|
return request('/api/version')
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function healthCheck() {
|
||
|
|
return request('/health')
|
||
|
|
}
|
||
|
|
|
||
|
|
export const api = {
|
||
|
|
// Auth
|
||
|
|
login,
|
||
|
|
register,
|
||
|
|
logout,
|
||
|
|
getCurrentProfile,
|
||
|
|
|
||
|
|
// Clubs & Groups
|
||
|
|
listClubs,
|
||
|
|
createClub,
|
||
|
|
listTrainingGroups,
|
||
|
|
createTrainingGroup,
|
||
|
|
|
||
|
|
// Skills & Methods
|
||
|
|
listSkills,
|
||
|
|
createSkill,
|
||
|
|
listMethods,
|
||
|
|
createMethod,
|
||
|
|
|
||
|
|
// Exercises
|
||
|
|
listExercises,
|
||
|
|
getExercise,
|
||
|
|
createExercise,
|
||
|
|
updateExercise,
|
||
|
|
deleteExercise,
|
||
|
|
|
||
|
|
// Training Planning
|
||
|
|
listTrainingUnits,
|
||
|
|
getTrainingUnit,
|
||
|
|
createTrainingUnit,
|
||
|
|
updateTrainingUnit,
|
||
|
|
|
||
|
|
// System
|
||
|
|
getVersion,
|
||
|
|
healthCheck
|
||
|
|
}
|
||
|
|
|
||
|
|
export default api
|