casa-ai / api.js
andevs's picture
Update api.js
4c91ac4 verified
Raw
History Blame Contribute Delete
3.6 kB
const BASE = import.meta.env?.VITE_API_URL ?? '';
const req = async (path, opts = {}) => {
const token = localStorage.getItem('casa_token');
const headers = { ...(opts.headers || {}) };
if (token) headers['Authorization'] = `Bearer ${token}`;
if (opts.json) {
headers['Content-Type'] = 'application/json';
opts.body = JSON.stringify(opts.json);
delete opts.json;
}
const r = await fetch(`${BASE}${path}`, { ...opts, headers });
if (!r.ok) {
const e = await r.json().catch(() => ({ detail: r.statusText }));
throw new Error(e.detail || 'Request failed');
}
return r.json();
};
const fd = (obj) => {
const f = new FormData();
Object.entries(obj).forEach(([k,v]) => v != null && f.append(k, typeof v === 'object' ? JSON.stringify(v) : String(v)));
return f;
};
export const api = {
// Health
health: () => req('/health'),
// Auth
register: (b) => req('/api/auth/register', { method:'POST', json:b }),
login: (b) => req('/api/auth/login', { method:'POST', json:b }),
me: () => req('/api/auth/me'),
logout: () => req('/api/auth/logout', { method:'POST' }),
// Designs
saveDesign: (d) => req('/api/auth/save-design', { method:'POST', json:{ design:d } }),
savedDesigns: () => req('/api/auth/saved-designs'),
getDesign: (id) => req(`/api/designs/${id}`),
getPublicDesigns: (params) => req('/api/designs', { method:'GET', json:params }),
likeDesign: (id) => req(`/api/designs/${id}/like`, { method:'POST' }),
addComment: (id, comment) => req(`/api/designs/${id}/comments`, { method:'POST', json:comment }),
getComments: (id) => req(`/api/designs/${id}/comments`),
// Room Analysis
analyzeRoom: (f) => {
const form = new FormData();
form.append('file', f);
return req('/api/rooms/analyze', { method:'POST', body:form });
},
// Design Generation
generateDesign: (p) => req('/api/designs/generate', { method:'POST', body:fd(p) }),
explanation: (p) => req('/api/design-explanation', { method:'POST', body:fd(p) }),
wallFinish: (p) => req('/api/wall-finish', { method:'POST', body:fd(p) }),
// Style Tools
styleQuiz: (answers) => req('/api/quiz/submit', { method:'POST', json:{ answers } }),
getQuizQuestions: () => req('/api/quiz/questions'),
moodBoard: (p) => req('/api/mood-board', { method:'POST', body:fd(p) }),
budgetBreakdown: (p) => req('/api/budget-breakdown', { method:'POST', body:fd(p) }),
// Catalog with affiliate links
getCatalog: (params) => {
const query = new URLSearchParams(params).toString();
return req(`/api/catalog${query ? '?' + query : ''}`);
},
getCategories: () => req('/api/catalog/categories'),
getBrands: () => req('/api/catalog/brands'),
getCatalogItem: (id) => req(`/api/catalog/${id}`),
// Export
exportDesign: (designId, format) => req('/api/export/pdf', { method:'POST', json:{ design_id:designId, format } }),
getExportStatus: (exportId) => req(`/api/export/status/${exportId}`),
// Stats
getDesignStats: () => req('/api/stats/designs'),
// 3D
generate3DModel: (designData) => req('/api/designs/3d', { method:'POST', json:designData }),
// Style Transfer
styleTransfer: (image, style) => {
const form = new FormData();
form.append('image', image);
form.append('style', style);
return req('/api/style-transfer', { method:'POST', body:form });
},
// Reviews
getItemReviews: (itemId) => req(`/api/catalog/${itemId}/reviews`),
submitReview: (itemId, rating, comment) =>
req(`/api/catalog/${itemId}/reviews`, { method:'POST', json:{ rating, comment } }),
};