Commit 05172c6e authored by Fares's avatar Fares

fix(sa): fix mirror connection error with better error handling

- CSRF token now uses \App\Core\CSRF::token() to ensure it's always
  generated, not raw $_SESSION which could be empty
- apiPost and loadState now check response.ok before parsing JSON,
  preventing silent failures when server returns 419/500/HTML
- Error messages now include status code or exception details
- Added guard for empty SLOTS array (missing operating hours)
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent 26eb4204
......@@ -309,7 +309,7 @@ $gridCols = (int) ($facility['pool_grid_cols'] ?? 0);
<script>
(function(){
const FACILITY_ID = <?= (int) $facility['id'] ?>;
const CSRF = '<?= e($_SESSION['_csrf_token'] ?? '') ?>';
const CSRF = '<?= e(\App\Core\CSRF::token()) ?>';
const SLOTS = <?= json_encode($slots, JSON_UNESCAPED_UNICODE) ?>;
const GROUPS = <?= json_encode($groups, JSON_UNESCAPED_UNICODE) ?>;
let GRID_ROWS = <?= $gridRows ?>;
......@@ -1017,12 +1017,17 @@ $gridCols = (int) ($facility['pool_grid_cols'] ?? 0);
// --- API ---
function loadState(){
if(GRID_ROWS < 1 || GRID_COLS < 1){ renderGrid(); hideLoading(); return; }
if(!SLOTS || SLOTS.length === 0){ toast('لم يتم تهيئة الفترات الزمنية للمنشأة', 'error'); hideLoading(); return; }
showLoading();
let slot = firstActiveSlot();
if(!slot || !slot.start){ hideLoading(); return; }
fetch('/api/sa/pool-grid/' + FACILITY_ID + '/state?date=' + encodeURIComponent(currentDate()) + '&start_time=' + encodeURIComponent(slot.start) + '&end_time=' + encodeURIComponent(slot.end), {
headers: {'X-Requested-With': 'XMLHttpRequest'}
})
.then(function(r){ return r.json(); })
.then(function(r){
if(!r.ok) throw new Error('HTTP ' + r.status);
return r.json();
})
.then(function(data){
if(data.error){ toast(data.error, 'error'); hideLoading(); renderGrid(); return; }
GRID_ROWS = data.rows || GRID_ROWS;
......@@ -1031,7 +1036,7 @@ $gridCols = (int) ($facility['pool_grid_cols'] ?? 0);
renderGrid();
hideLoading();
})
.catch(function(){ toast('خطأ في تحميل البيانات', 'error'); hideLoading(); });
.catch(function(e){ toast('خطأ في تحميل البيانات: ' + (e.message || ''), 'error'); hideLoading(); });
}
function apiPost(url, body){
......@@ -1043,7 +1048,10 @@ $gridCols = (int) ($facility['pool_grid_cols'] ?? 0);
'X-Requested-With': 'XMLHttpRequest'
},
body: JSON.stringify(body)
}).then(function(r){ return r.json(); }).catch(function(){ return {error:'خطأ في الاتصال'}; });
}).then(function(r){
if(!r.ok) return {error: 'خطأ من الخادم (' + r.status + ')'};
return r.json();
}).catch(function(e){ return {error:'خطأ في الاتصال: ' + (e.message || '')}; });
}
function showLoading(){ loading.classList.remove('hidden'); }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment