GET mobiles API (HTML + JS only)

GET: https://api-spring.bigzero.online/api/v1/mobiles


Idle.
Raw JSON

  
[cozy_calc_php]
'); w.document.close(); w.print(); } function showErrorInSummary(message, statusNote = '', errorCode = null) { const summaryContent = $id('summaryContent'); let helpText = ''; if (errorCode === 401) { helpText = `
🔑 خطأ في المصادقة (401 Unauthorized)

هذا الخطأ يعني أن API يتطلب مصادقة.

  • احصل على API Key من مزود الخدمة
  • أضف API Key في ملف api-proxy.php
  • تواصل مع فريق API للحصول على صلاحيات
`; } else if (errorCode === 403) { helpText = `
🚫 خطأ في الصلاحيات (403 Forbidden)

السيرفر يرفض الطلب. الأسباب المحتملة: IP غير مسموح، Rate Limit، أو API Key غير صحيح.

`; } summaryContent.innerHTML = `

⚠️ حدث خطأ في الحساب

${message}

${statusNote ? `

${statusNote}

` : ''}
${helpText}
`; goToStep(8); } /* ================= Submit ================= */ async function submitForm() { if (!validateRoomsRequired()) return; if (!validateBathsRequired()) return; showLoading('جاري حساب التكلفة...'); try { const totalArea = parseFloat($id('totalArea')?.value || '0'); if (!totalArea) { hideLoading(); return alert('⚠️ يرجى إدخال المساحة الكلية'); } const MAGNTIC_TRACK = state.magneticTrack || 'NONE'; const widowCounter = parseInt($id('windowCounter')?.value || '0') || 0; // (اسم الحقل حسب الـ API) const balconyCounter = parseInt($id('balconyCounter')?.value || '0') || 0; const rooms = []; document.querySelectorAll('#roomsContainer .item-card').forEach((card, i) => { const l = parseFloat(card.querySelector('.room-length')?.value) || 0; const w = parseFloat(card.querySelector('.room-width')?.value) || 0; rooms.push({ name: `غرفة ${i + 1}`, width: w, length: l, area: +(w * l).toFixed(2), perimeter: +((2 * (w + l))).toFixed(2), ceilingType: card.dataset.ceiling || 'NONE', ceilingFinish: 'NONE', floorWallMaterial: card.dataset.floor || 'NONE', wallType: card.dataset.wall || 'NONE', exhaustType: 'WINDOW_EXHAUST' }); }); const pathRooms = []; document.querySelectorAll('#bathsContainer .item-card').forEach((card, i) => { const l = parseFloat(card.querySelector('.bath-length')?.value) || 0; const w = parseFloat(card.querySelector('.bath-width')?.value) || 0; pathRooms.push({ name: `حمام ${i + 1}`, width: w, length: l, area: +(w * l).toFixed(2), perimeter: +((2 * (w + l))).toFixed(2), baseType: card.dataset.base || 'NONE', ceilingType: card.dataset.ceiling || 'NONE', ceilingFinish: 'NONE', floorWallMaterial: card.dataset.floor || 'NONE', wallType: card.dataset.wall || 'NONE', basinMixerType: card.dataset.basinMixer || 'NONE', showerMixerType: card.dataset.showerMixer || 'NONE', shattafMixerType: card.dataset.shattafMixer || 'NONE', showerArea: card.dataset.shower || 'NONE', sinkType: card.dataset.sink || 'NONE', exhaustType: card.dataset.exhaust || 'NONE' }); }); const kitL = parseFloat($id('kitLength')?.value) || 0; const kitW = parseFloat($id('kitWidth')?.value) || 0; const kitchens = [ { name: 'مطبخ', width: kitW, length: kitL, area: +(kitW * kitL).toFixed(2), perimeter: +((2 * (kitW + kitL))).toFixed(2), adaptation: false, ceilingType: state.kitchen.ceiling || 'NONE', ceilingFinish: 'NONE', floorWallMaterial: state.kitchen.floor || 'NONE', wallType: state.kitchen.wall || 'NONE', sinkType: 'PORCELAIN', exhaustType: 'WINDOW_EXHAUST' } ]; const data = { totalArea: +totalArea, rooflArea: parseInt($id('roofArea')?.value || '0') || 0, // (الحروف حسب الـ API) gardenlArea: parseInt($id('gardenArea')?.value || '0') || 0, roomsNumber: document.querySelectorAll('#roomsContainer .item-card').length, location: state.location || 'NONE', unitCollection: state.unitCollection || 'NONE', finishingStatus: isUnitNew() ? 'NONE' : state.finishingStatus || 'NONE', spot: state.spot || 'NONE', MAGNTIC_TRACK, interDoor: state.interDoor || 'NONE', interDoorCounter: parseInt($id('interDoorCounter')?.value || '0') || 0, outDoor: state.outDoor || 'NONE', windowType: state.windowType || 'NONE', widowCounter, balconyCounter, shutterTypes: Array.isArray(state.shutterTypes) ? state.shutterTypes : [], rooms, pathRooms, kitchens }; console.log('📤 Cozy API Request • POST /calculate'); console.log('📦 Request Data:', data); const response = await wpProxyPost('calculate', data); console.log('📥 Cozy API Response • POST /calculate'); console.log('Status:', response.status, response.statusText); if (!response.ok) { const errorText = await response.text(); console.error('❌ API Error Response:', errorText); let msg = 'خطأ في API: '; let errorCode = response.status; try { const j = JSON.parse(errorText); msg += j.message || j.error || errorText; } catch (_) { msg += errorText || response.status; } const error = new Error(msg); error.statusCode = errorCode; throw error; } const result = await response.json(); displayResults(result); goToStep(8); } catch (err) { console.error('❌ Error in submitForm:', err); showErrorInSummary( err.message || 'حدث خطأ غير متوقع', err.stack ? 'تفاصيل إضافية في Console (F12)' : '', err.statusCode || null ); } finally { hideLoading(); } } /* ================= Test Fill ================= */ async function fillTestData() { showLoading('جاري ملء البيانات التجريبية...'); try { $id('totalArea').value = 120; $id('roomsCount').value = 2; $id('bathsCount').value = 1; hideLoading(); alert('تم ملء الأساسيات. أكمل اختيارات الغرف والحمّامات.'); } catch (e) { hideLoading(); alert('حدث خطأ أثناء الملء التجريبي'); } } /* ================= Init ================= */ async function init() { showLoading('جاري تحميل البيانات...'); try { // Unit types cards const unitTypes = [ { title: 'شقة', value: 'APARTMENT', icon: '🏢', desc: 'بدون سطح أو حديقة' }, { title: 'فيلا', value: 'VILLA', icon: '🏡', desc: 'مع سطح وحديقة' }, { title: 'دوبليكس', value: 'DUPLEX', icon: '🏘️', desc: 'طابقين متصلين' }, { title: 'بنتهاوس', value: 'PENTHOUSE', icon: '🌆', desc: 'الدور الأخير' } ]; const unitContainer = $id('unitTypeCards'); if (unitContainer) { unitTypes.forEach((type) => { const card = document.createElement('div'); card.className = 'selection-card'; card.innerHTML = `
${type.icon}
${type.title}
${type.desc}
`; card.addEventListener('click', () => { unitContainer.querySelectorAll('.selection-card').forEach((c) => c.classList.remove('selected')); card.classList.add('selected'); state.unitType = type.value; const extra = $id('extraAreasWrap'); if (extra) extra.style.display = type.value === 'APARTMENT' ? 'none' : 'grid'; }); unitContainer.appendChild(card); }); } // Stepper click (optional) document.querySelectorAll('.progress-step').forEach((s) => { s.addEventListener('click', () => goToStep(+s.dataset.step)); }); // Enums & bindings const locations = await loadEnumV1('Location'); renderSimpleCards('locationCards', locations, null, (v) => { state.location = v; }); const unitCollections = await loadEnumV1('UnitCollection'); renderSimpleCards( 'unitCollectionCards', unitCollections, null, (v) => { state.unitCollection = v; applyFinishingVisibility(); }, (v) => (v === 'NEW_BRAND' ? '✨' : '🔧') ); const finishingStatuses = await loadEnumV1('FinishingStatus'); renderSimpleCards('finishingStatusCards', finishingStatuses, null, (v) => { state.finishingStatus = v; }); const spots = await loadEnumV1('SPOT'); renderSimpleCards('spotCards', spots, null, (v) => { state.spot = v; }); const magneticTracks = await loadEnumV1('MAGNTIC_TRACK'); renderSimpleCards( 'magneticTrackCards', magneticTracks, 'NONE', (v) => { state.magneticTrack = v; }, (v) => (v === 'NONE' ? '❌' : '💡') ); const doors = await loadEnumV1('DoorType'); renderSimpleCards( 'interDoorCards', (doors || []).filter((d) => d === 'CUSTOM_MADE' || d === 'READY_MADE'), null, (v) => { state.interDoor = v; } ); renderSimpleCards( 'outDoorCards', (doors || []).filter((d) => d === 'ARMORED' || d === 'NONE'), 'ARMORED', (v) => { state.outDoor = v; } ); renderPrimarySecondaryCards( 'windowPrimaryCards', 'windowSecondaryWrapper', 'windowSecondaryCards', 'WindowType', (value) => { state.windowType = value; } ); const shutters = await loadEnumV1('ShutterType'); renderMultiSelectCards('shutterTypeCards', shutters, state.shutterTypes, (arr) => { state.shutterTypes = arr; }); renderPrimarySecondaryCards( 'recFloorPrimary', 'recFloorSecondaryWrapper', 'recFloorSecondary', 'FloorMaterial', (value) => { state.reception.floor = value; } ); renderPrimarySecondaryCards( 'recWallPrimary', 'recWallSecondaryWrapper', 'recWallSecondary', 'WallType', (value) => { state.reception.wall = value; } ); const ceilingTypes = await loadEnumV1('CeilingType'); renderSimpleCards('recCeilingCards', ceilingTypes, null, (v) => { state.reception.ceiling = v; }); renderUnifiedSurfaceSelector('kitSurfacePrimary', 'kitSurfaceSecondaryWrapper', 'kitSurfaceSecondary', (v) => { state.kitchen.surface = v; state.kitchen.floor = v; state.kitchen.wall = autoWallForFloor(v); }); renderSimpleCards('kitCeilingCards', ceilingTypes, null, (v) => { state.kitchen.ceiling = v; }); // init dims calcReceptionDims(); calcKitchenDims(); } catch (e) { console.error(e); alert('حدث خطأ أثناء تحميل البيانات'); } finally { hideLoading(); } } document.addEventListener('DOMContentLoaded', init); /* ================= Expose to window (for inline onclick) ================= */ Object.assign(window, { // nav goToStep, validateAndGoNext, // actions submitForm, fillTestData, // rooms addRoom, removeRoom, calcRoomDims, // baths addBath, removeBath, calcBathDims, // dims for reception/kitchen calcReceptionDims, calcKitchenDims, // validation (used in submit) validateRoomsRequired, validateBathsRequired, // finishing toggle applyFinishingVisibility, // print printTable, // debug getState: () => state, getEnumCache: () => enumCache, // refs API_BASE_REF }); })();