🚀 مُصادَق: تحديث برمجي جديد 2026-05-03 13:19

This commit is contained in:
Hamza-Ayed
2026-05-03 13:19:45 +03:00
parent cf68007ef1
commit 2de6a0adfd
32 changed files with 1133 additions and 102 deletions

View File

@@ -1,73 +1,55 @@
/**
* مُصادَق — API Client with JWT Auth & Refresh Flow
*/
window.API = {
baseUrl: '/Application/public/api.php',
accessToken: localStorage.getItem('access_token'),
async get(path) {
return this._request('GET', path);
},
async post(path, body) {
return this._request('POST', path, body);
},
async upload(path, formData) {
return this._request('POST', path, formData, true);
},
async _request(method, path, body = null, isFormData = false) {
const API = {
baseUrl: '/api/v1',
async request(endpoint, options = {}) {
const url = `${this.baseUrl}${endpoint}`;
const token = localStorage.getItem('access_token');
const headers = {
'Accept': 'application/json',
...(options.body instanceof FormData ? {} : { 'Content-Type': 'application/json' }),
...(token ? { 'Authorization': `Bearer ${token}` } : {}),
...options.headers
};
if (this.accessToken) {
headers['Authorization'] = `Bearer ${this.accessToken}`;
}
if (!isFormData && body) {
headers['Content-Type'] = 'application/json';
body = JSON.stringify(body);
}
try {
const response = await fetch(`${this.baseUrl}${path}`, {
method,
headers,
body
});
if (response.status === 401) {
const refreshed = await this.refreshToken();
if (refreshed) {
return this._request(method, path, body, isFormData);
} else {
window.location.href = '/login';
}
const response = await fetch(url, { ...options, headers });
if (response.status === 401 && !options._retry) {
// Attempt token refresh
const refreshed = await this.refresh();
if (refreshed) {
return this.request(endpoint, { ...options, _retry: true });
}
const data = await response.json();
if (!response.ok) throw data;
return data;
} catch (error) {
console.error('API Error:', error);
throw error;
}
const data = await response.json();
if (!response.ok) {
throw new Error(data.message || 'حدث خطأ ما');
}
return data;
},
async refreshToken() {
async login(email, password) {
const data = await this.request('/auth/login', {
method: 'POST',
body: JSON.stringify({ email, password })
});
localStorage.setItem('access_token', data.data.access_token);
return data;
},
async refresh() {
try {
const response = await fetch(`${this.baseUrl}/auth/refresh`, { method: 'POST' });
if (response.ok) {
const result = await response.json();
this.accessToken = result.data.access_token;
localStorage.setItem('access_token', this.accessToken);
const data = await fetch(`${this.baseUrl}/auth/refresh`, { method: 'POST' });
if (data.ok) {
const result = await data.json();
localStorage.setItem('access_token', result.data.access_token);
return true;
}
} catch (e) {
return false;
console.error('Refresh failed', e);
}
localStorage.removeItem('access_token');
return false;
}
};