standardize mobile api transport for gyms and core services
This commit is contained in:
1 parent
c36cad9c54
commit
80110acbf7
8 files changed
+322
-386
No files matched your search
@@ -1,4 +1,6 @@
|
||||
import { API_BASE_URL, API_ENDPOINTS } from "../config/api";
|
||||
import { isAxiosError } from "axios";
|
||||
import { apiClient, withAuth } from "../api/client";
|
||||
import { API_ENDPOINTS } from "../config/api";
|
||||
import log from "../utils/logger";
|
||||
|
||||
export interface FitnessGoal {
|
||||
@@ -41,38 +43,21 @@ export interface CreateGoalData {
|
||||
}
|
||||
|
||||
export class FitnessGoalsService {
|
||||
private async getAuthHeaders(token: string | null): Promise<any> {
|
||||
const headers: any = {
|
||||
"Content-Type": "application/json",
|
||||
};
|
||||
|
||||
if (token) {
|
||||
headers["Authorization"] = `Bearer ${token}`;
|
||||
}
|
||||
|
||||
return headers;
|
||||
}
|
||||
|
||||
async getGoals(
|
||||
userId: string,
|
||||
token: string | null,
|
||||
status?: string,
|
||||
): Promise<FitnessGoal[]> {
|
||||
try {
|
||||
const headers = await this.getAuthHeaders(token);
|
||||
let url = `${API_BASE_URL}${API_ENDPOINTS.FITNESS_GOALS.LIST}?userId=${userId}`;
|
||||
const response = await apiClient.get(API_ENDPOINTS.FITNESS_GOALS.LIST, {
|
||||
params: {
|
||||
userId,
|
||||
...(status && status !== "all" ? { status } : {}),
|
||||
},
|
||||
...withAuth(token),
|
||||
});
|
||||
|
||||
if (status && status !== "all") {
|
||||
url += `&status=${status}`;
|
||||
}
|
||||
|
||||
const response = await fetch(url, { headers });
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch goals: ${response.status}`);
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
const result = response.data;
|
||||
|
||||
// Handle standardized API response format
|
||||
// API returns: { success: true, data: [...], meta: {...} }
|
||||
@@ -83,6 +68,9 @@ export class FitnessGoalsService {
|
||||
// Fallback for legacy format (direct array)
|
||||
return Array.isArray(result) ? result : [];
|
||||
} catch (error) {
|
||||
if (isAxiosError(error) && error.response) {
|
||||
throw new Error(`Failed to fetch goals: ${error.response.status}`);
|
||||
}
|
||||
log.error("Failed to fetch fitness goals", error);
|
||||
throw error;
|
||||
}
|
||||
@@ -93,22 +81,13 @@ export class FitnessGoalsService {
|
||||
token: string | null,
|
||||
): Promise<FitnessGoal> {
|
||||
try {
|
||||
const headers = await this.getAuthHeaders(token);
|
||||
const response = await fetch(
|
||||
`${API_BASE_URL}${API_ENDPOINTS.FITNESS_GOALS.CREATE}`,
|
||||
{
|
||||
method: "POST",
|
||||
headers,
|
||||
body: JSON.stringify(goalData),
|
||||
},
|
||||
const response = await apiClient.post(
|
||||
API_ENDPOINTS.FITNESS_GOALS.CREATE,
|
||||
goalData,
|
||||
withAuth(token),
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json();
|
||||
throw new Error(error.error || "Failed to create goal");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
const result = response.data;
|
||||
|
||||
// Handle standardized API response format
|
||||
if (result.success && result.data) {
|
||||
@@ -118,6 +97,14 @@ export class FitnessGoalsService {
|
||||
// Fallback for legacy format
|
||||
return result;
|
||||
} catch (error) {
|
||||
if (isAxiosError(error)) {
|
||||
const message =
|
||||
(error.response?.data as { error?: string } | undefined)?.error ||
|
||||
(error.response
|
||||
? `Failed to create goal: ${error.response.status}`
|
||||
: "Failed to create goal");
|
||||
throw new Error(message);
|
||||
}
|
||||
log.error("Failed to create fitness goal", error);
|
||||
throw error;
|
||||
}
|
||||
@@ -129,21 +116,13 @@ export class FitnessGoalsService {
|
||||
token: string | null,
|
||||
): Promise<FitnessGoal> {
|
||||
try {
|
||||
const headers = await this.getAuthHeaders(token);
|
||||
const response = await fetch(
|
||||
`${API_BASE_URL}${API_ENDPOINTS.FITNESS_GOALS.UPDATE(id)}`,
|
||||
{
|
||||
method: "PUT",
|
||||
headers,
|
||||
body: JSON.stringify(updates),
|
||||
},
|
||||
const response = await apiClient.put(
|
||||
API_ENDPOINTS.FITNESS_GOALS.UPDATE(id),
|
||||
updates,
|
||||
withAuth(token),
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to update goal");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
const result = response.data;
|
||||
|
||||
// Handle standardized API response format
|
||||
if (result.success && result.data) {
|
||||
@@ -153,6 +132,9 @@ export class FitnessGoalsService {
|
||||
// Fallback for legacy format
|
||||
return result;
|
||||
} catch (error) {
|
||||
if (isAxiosError(error) && error.response) {
|
||||
throw new Error(`Failed to update goal: ${error.response.status}`);
|
||||
}
|
||||
log.error("Failed to update fitness goal", error);
|
||||
throw error;
|
||||
}
|
||||
@@ -168,20 +150,13 @@ export class FitnessGoalsService {
|
||||
|
||||
async completeGoal(id: string, token: string | null): Promise<FitnessGoal> {
|
||||
try {
|
||||
const headers = await this.getAuthHeaders(token);
|
||||
const response = await fetch(
|
||||
`${API_BASE_URL}${API_ENDPOINTS.FITNESS_GOALS.COMPLETE(id)}`,
|
||||
{
|
||||
method: "POST",
|
||||
headers,
|
||||
},
|
||||
const response = await apiClient.post(
|
||||
API_ENDPOINTS.FITNESS_GOALS.COMPLETE(id),
|
||||
{},
|
||||
withAuth(token),
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to complete goal");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
const result = response.data;
|
||||
|
||||
// Note: Complete endpoint returns direct object (legacy format)
|
||||
// Handle standardized API response format (if migrated)
|
||||
@@ -192,6 +167,9 @@ export class FitnessGoalsService {
|
||||
// Fallback for legacy format (current implementation)
|
||||
return result;
|
||||
} catch (error) {
|
||||
if (isAxiosError(error) && error.response) {
|
||||
throw new Error(`Failed to complete goal: ${error.response.status}`);
|
||||
}
|
||||
log.error("Failed to complete fitness goal", error);
|
||||
throw error;
|
||||
}
|
||||
@@ -199,22 +177,17 @@ export class FitnessGoalsService {
|
||||
|
||||
async deleteGoal(id: string, token: string | null): Promise<void> {
|
||||
try {
|
||||
const headers = await this.getAuthHeaders(token);
|
||||
const response = await fetch(
|
||||
`${API_BASE_URL}${API_ENDPOINTS.FITNESS_GOALS.DELETE(id)}`,
|
||||
{
|
||||
method: "DELETE",
|
||||
headers,
|
||||
},
|
||||
await apiClient.delete(
|
||||
API_ENDPOINTS.FITNESS_GOALS.DELETE(id),
|
||||
withAuth(token),
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to delete goal");
|
||||
}
|
||||
|
||||
// DELETE endpoint returns: { success: true, data: { deleted: true }, meta: {...} }
|
||||
// No need to parse the result for void return type
|
||||
} catch (error) {
|
||||
if (isAxiosError(error) && error.response) {
|
||||
throw new Error(`Failed to delete goal: ${error.response.status}`);
|
||||
}
|
||||
log.error("Failed to delete fitness goal", error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user