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); ...@@ -309,7 +309,7 @@ $gridCols = (int) ($facility['pool_grid_cols'] ?? 0);
<script> <script>
(function(){ (function(){
const FACILITY_ID = <?= (int) $facility['id'] ?>; 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 SLOTS = <?= json_encode($slots, JSON_UNESCAPED_UNICODE) ?>;
const GROUPS = <?= json_encode($groups, JSON_UNESCAPED_UNICODE) ?>; const GROUPS = <?= json_encode($groups, JSON_UNESCAPED_UNICODE) ?>;
let GRID_ROWS = <?= $gridRows ?>; let GRID_ROWS = <?= $gridRows ?>;
...@@ -1017,12 +1017,17 @@ $gridCols = (int) ($facility['pool_grid_cols'] ?? 0); ...@@ -1017,12 +1017,17 @@ $gridCols = (int) ($facility['pool_grid_cols'] ?? 0);
// --- API --- // --- API ---
function loadState(){ function loadState(){
if(GRID_ROWS < 1 || GRID_COLS < 1){ renderGrid(); hideLoading(); return; } if(GRID_ROWS < 1 || GRID_COLS < 1){ renderGrid(); hideLoading(); return; }
if(!SLOTS || SLOTS.length === 0){ toast('لم يتم تهيئة الفترات الزمنية للمنشأة', 'error'); hideLoading(); return; }
showLoading(); showLoading();
let slot = firstActiveSlot(); 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), { 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'} 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){ .then(function(data){
if(data.error){ toast(data.error, 'error'); hideLoading(); renderGrid(); return; } if(data.error){ toast(data.error, 'error'); hideLoading(); renderGrid(); return; }
GRID_ROWS = data.rows || GRID_ROWS; GRID_ROWS = data.rows || GRID_ROWS;
...@@ -1031,7 +1036,7 @@ $gridCols = (int) ($facility['pool_grid_cols'] ?? 0); ...@@ -1031,7 +1036,7 @@ $gridCols = (int) ($facility['pool_grid_cols'] ?? 0);
renderGrid(); renderGrid();
hideLoading(); hideLoading();
}) })
.catch(function(){ toast('خطأ في تحميل البيانات', 'error'); hideLoading(); }); .catch(function(e){ toast('خطأ في تحميل البيانات: ' + (e.message || ''), 'error'); hideLoading(); });
} }
function apiPost(url, body){ function apiPost(url, body){
...@@ -1043,7 +1048,10 @@ $gridCols = (int) ($facility['pool_grid_cols'] ?? 0); ...@@ -1043,7 +1048,10 @@ $gridCols = (int) ($facility['pool_grid_cols'] ?? 0);
'X-Requested-With': 'XMLHttpRequest' 'X-Requested-With': 'XMLHttpRequest'
}, },
body: JSON.stringify(body) 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'); } 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