117 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			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();
 | |
|   }
 | |
| }
 |