tractatus/public/js/utils/api.js
TheFlow ac2db33732 fix(submissions): restructure Economist package and fix article display
- Create Economist SubmissionTracking package correctly:
  * mainArticle = full blog post content
  * coverLetter = 216-word SIR— letter
  * Links to blog post via blogPostId
- Archive 'Letter to The Economist' from blog posts (it's the cover letter)
- Fix date display on article cards (use published_at)
- Target publication already displaying via blue badge

Database changes:
- Make blogPostId optional in SubmissionTracking model
- Economist package ID: 68fa85ae49d4900e7f2ecd83
- Le Monde package ID: 68fa2abd2e6acd5691932150

Next: Enhanced modal with tabs, validation, export

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-24 08:47:42 +13:00

110 lines
2.1 KiB
JavaScript

/**
* API Client for Tractatus Platform
* Handles all HTTP requests to the backend API
*/
const API_BASE = '/api';
/**
* Generic API request handler
*/
async function apiRequest(endpoint, options = {}) {
const url = `${API_BASE}${endpoint}`;
const config = {
headers: {
'Content-Type': 'application/json',
...options.headers
},
...options
};
try {
const response = await fetch(url, config);
const data = await response.json();
if (!response.ok) {
throw new Error(data.message || data.error || 'Request failed');
}
return data;
} catch (error) {
console.error('API Request failed:', error);
throw error;
}
}
/**
* Documents API
*/
const Documents = {
/**
* List all documents with optional filtering
*/
async list(params = {}) {
const query = new URLSearchParams(params).toString();
return apiRequest(`/documents${query ? '?' + query : ''}`);
},
/**
* Get document by ID or slug
*/
async get(identifier) {
return apiRequest(`/documents/${identifier}`);
},
/**
* Search documents
*/
async search(query, params = {}) {
const searchParams = new URLSearchParams({ q: query, ...params }).toString();
return apiRequest(`/documents/search?${searchParams}`);
}
};
/**
* Authentication API
*/
const Auth = {
/**
* Login
*/
async login(email, password) {
return apiRequest('/auth/login', {
method: 'POST',
body: JSON.stringify({ email, password })
});
},
/**
* Get current user
*/
async getCurrentUser() {
const token = localStorage.getItem('auth_token');
return apiRequest('/auth/me', {
headers: {
'Authorization': `Bearer ${token}`
}
});
},
/**
* Logout
*/
async logout() {
const token = localStorage.getItem('auth_token');
const result = await apiRequest('/auth/logout', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`
}
});
localStorage.removeItem('auth_token');
return result;
}
};
// Export as global API object
window.API = {
Documents,
Auth
};