feat(auth): implement OTP login flow with toast notifications

feat(content): enhance detail view with dynamic content and comments
feat(order): add polling for payment status in the payment view
feat(user): update dashboard to display wallet and recent orders
feat(user): improve orders view with dynamic order fetching and status mapping
feat(api): create API modules for auth, content, order, user, and common functionalities
refactor(request): implement a centralized request utility for API calls
This commit is contained in:
2025-12-30 21:15:13 +08:00
parent 179b6aa0e2
commit cf29a2bf1a
14 changed files with 400 additions and 310 deletions

View File

@@ -0,0 +1,50 @@
// Simple Fetch Wrapper
const BASE_URL = '/v1';
export async function request(endpoint, options = {}) {
const token = localStorage.getItem('token');
const headers = {
'Content-Type': 'application/json',
...options.headers,
};
if (token) {
headers['Authorization'] = `Bearer ${token}`;
}
if (options.body && !(options.body instanceof FormData)) {
options.body = JSON.stringify(options.body);
}
if (options.body instanceof FormData) {
delete headers['Content-Type']; // Let browser set boundary
}
try {
const res = await fetch(`${BASE_URL}${endpoint}`, {
...options,
headers
});
const contentType = res.headers.get("content-type");
let data;
if (contentType && contentType.indexOf("application/json") !== -1) {
data = await res.json();
} else {
data = await res.text();
}
if (!res.ok) {
// Handle errorx response { code, message, error_id }
const errorMsg = data.message || `Request failed with status ${res.status}`;
throw new Error(errorMsg);
}
return data;
} catch (err) {
console.error('API Request Error:', err);
throw err;
}
}