Files
fendi-react-app/src/api/CategoriesApi.js

117 lines
3.6 KiB
JavaScript

// src/api/CategoriesApi.js
export default class CategoriesApi {
constructor(token) {
// IMPORTANTE: singular "Tag", no "Tags"
this.baseUrl = 'https://inventory-bff.dream-views.com/api/v1/Tag';
this.token = token;
}
headers(json = true) {
return {
accept: 'application/json',
...(json ? { 'Content-Type': 'application/json' } : {}),
...(this.token ? { Authorization: `Bearer ${this.token}` } : {}),
};
}
// Utilidad: validar ObjectId (24-hex) — el DAL lo exige para ChangeStatus
static isHex24(v) {
return typeof v === 'string' && /^[0-9a-fA-F]{24}$/.test(v);
}
// (Opcional) Utilidad: validar campos mínimos en create/update para evitar 400
static ensureFields(obj, fields) {
const missing = fields.filter((k) => obj[k] === undefined || obj[k] === null || obj[k] === '');
if (missing.length) {
throw new Error(`Missing required field(s): ${missing.join(', ')}`);
}
}
// GET /Tag/GetAll
async getAll() {
const res = await fetch(`${this.baseUrl}/GetAll`, {
method: 'GET',
headers: this.headers(false),
});
if (!res.ok) {
throw new Error(`GetAll error ${res.status}: ${await res.text()}`);
}
return res.json();
}
// POST /Tag/Create
// payload esperado (min): tenantId, tagName, typeId(_id TagType), slug, displayOrder, icon, parentTagId([])
async create(payload) {
// Validaciones básicas para evitar 400 comunes
CategoriesApi.ensureFields(payload, ['tenantId', 'tagName', 'typeId', 'icon']);
if (!Array.isArray(payload.parentTagId)) {
payload.parentTagId = [];
}
const res = await fetch(`${this.baseUrl}/Create`, {
method: 'POST',
headers: this.headers(),
body: JSON.stringify(payload),
});
if (!res.ok) {
throw new Error(`Create error ${res.status}: ${await res.text()}`);
}
return res.json();
}
// PUT /Tag/Update
// payload esperado (min): id(GUID) ó _id(24-hex) según backend, + tenantId, tagName, typeId, icon, etc.
async update(payload) {
CategoriesApi.ensureFields(payload, ['tenantId', 'tagName', 'typeId', 'icon']);
const res = await fetch(`${this.baseUrl}/Update`, {
method: 'PUT',
headers: this.headers(),
body: JSON.stringify(payload),
});
if (!res.ok) {
throw new Error(`Update error ${res.status}: ${await res.text()}`);
}
return res.json();
}
// PATCH /Tag/ChangeStatus
// Debe mandarse { id: <_id 24-hex>, status: 'Active'|'Inactive' }
async changeStatus({ id, status }) {
if (!CategoriesApi.isHex24(id)) {
// Evitar el 500 "String should contain only hexadecimal digits."
throw new Error('ChangeStatus requires a Mongo _id (24-hex) for "id".');
}
if (!status) {
throw new Error('ChangeStatus requires "status" field.');
}
const res = await fetch(`${this.baseUrl}/ChangeStatus`, {
method: 'PATCH',
headers: this.headers(),
body: JSON.stringify({ id, status }),
});
if (!res.ok) {
throw new Error(`ChangeStatus error ${res.status}: ${await res.text()}`);
}
// Algunos endpoints devuelven vacío; devolvemos parsed o true
try {
return await res.json();
} catch {
return true;
}
}
// DELETE /Tag/Delete (si lo usan; muchos usan soft-delete con ChangeStatus/Update)
async delete(payload) {
const res = await fetch(`${this.baseUrl}/Delete`, {
method: 'DELETE',
headers: this.headers(),
body: JSON.stringify(payload),
});
if (!res.ok) {
throw new Error(`Delete error ${res.status}: ${await res.text()}`);
}
return res.json();
}
}