furry/static/js/mobile-api-client.js

455 lines
14 KiB
JavaScript

/**
* Kasico Mobile API Client für React Native
* Vollständige API-Integration für Mobile App
*/
class KasicoMobileApiClient {
constructor(baseUrl = '/mobile/api/') {
this.baseUrl = baseUrl;
this.deviceToken = null;
this.sessionId = null;
this.isAuthenticated = false;
this.authToken = null;
this.init();
}
init() {
// Load stored data
this.loadStoredData();
// Initialize session
this.initializeSession();
}
loadStoredData() {
// Load from localStorage (in web) or AsyncStorage (in React Native)
if (typeof localStorage !== 'undefined') {
this.deviceToken = localStorage.getItem('kasico_device_token');
this.authToken = localStorage.getItem('kasico_auth_token');
this.sessionId = localStorage.getItem('kasico_session_id');
}
}
saveStoredData() {
if (typeof localStorage !== 'undefined') {
if (this.deviceToken) localStorage.setItem('kasico_device_token', this.deviceToken);
if (this.authToken) localStorage.setItem('kasico_auth_token', this.authToken);
if (this.sessionId) localStorage.setItem('kasico_session_id', this.sessionId);
}
}
async initializeSession() {
if (!this.sessionId) {
this.sessionId = this.generateSessionId();
}
await this.startSession();
}
generateSessionId() {
return 'session_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
}
// Authentication
async authenticate(username, password) {
try {
const response = await fetch('/api/auth/login/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ username, password })
});
const data = await response.json();
if (response.ok) {
this.authToken = data.token;
this.isAuthenticated = true;
this.saveStoredData();
return data;
} else {
throw new Error(data.error || 'Authentication failed');
}
} catch (error) {
console.error('Authentication error:', error);
throw error;
}
}
async logout() {
try {
await fetch('/api/auth/logout/', {
method: 'POST',
headers: this.getAuthHeaders()
});
this.authToken = null;
this.isAuthenticated = false;
this.saveStoredData();
await this.endSession();
} catch (error) {
console.error('Logout error:', error);
}
}
// Device Management
async registerDevice(deviceInfo) {
try {
const response = await fetch(this.baseUrl + 'device/register/', {
method: 'POST',
headers: this.getAuthHeaders(),
body: JSON.stringify({
device_token: deviceInfo.deviceToken,
device_type: deviceInfo.deviceType || 'web',
device_name: deviceInfo.deviceName || '',
device_model: deviceInfo.deviceModel || '',
os_version: deviceInfo.osVersion || '',
app_version: deviceInfo.appVersion || ''
})
});
const data = await response.json();
if (response.ok) {
this.deviceToken = deviceInfo.deviceToken;
this.saveStoredData();
return data;
} else {
throw new Error(data.error || 'Device registration failed');
}
} catch (error) {
console.error('Device registration error:', error);
throw error;
}
}
async unregisterDevice() {
if (!this.deviceToken) return;
try {
await fetch(`${this.baseUrl}device/unregister/${this.deviceToken}/`, {
method: 'DELETE',
headers: this.getAuthHeaders()
});
this.deviceToken = null;
this.saveStoredData();
} catch (error) {
console.error('Device unregistration error:', error);
}
}
// Session Management
async startSession() {
if (!this.deviceToken) return;
try {
const response = await fetch(this.baseUrl + 'session/start/', {
method: 'POST',
headers: this.getAuthHeaders(),
body: JSON.stringify({
session_id: this.sessionId,
device_token: this.deviceToken,
app_version: '1.0.0',
device_info: this.getDeviceInfo()
})
});
const data = await response.json();
return data;
} catch (error) {
console.error('Session start error:', error);
}
}
async endSession() {
if (!this.sessionId) return;
try {
await fetch(`${this.baseUrl}session/end/${this.sessionId}/`, {
method: 'POST',
headers: this.getAuthHeaders()
});
} catch (error) {
console.error('Session end error:', error);
}
}
// Analytics
async trackEvent(eventType, eventData = {}, screenName = '') {
if (!this.deviceToken) return;
try {
await fetch(this.baseUrl + 'analytics/track/', {
method: 'POST',
headers: this.getAuthHeaders(),
body: JSON.stringify({
event_type: eventType,
event_data: eventData,
session_id: this.sessionId,
screen_name: screenName,
device_token: this.deviceToken
})
});
} catch (error) {
console.error('Analytics tracking error:', error);
}
}
// Error Reporting
async reportError(errorLevel, errorType, errorMessage, stackTrace = '') {
if (!this.deviceToken) return;
try {
await fetch(this.baseUrl + 'error/report/', {
method: 'POST',
headers: this.getAuthHeaders(),
body: JSON.stringify({
error_level: errorLevel,
error_type: errorType,
error_message: errorMessage,
stack_trace: stackTrace,
app_version: '1.0.0',
os_version: this.getOSVersion(),
device_info: this.getDeviceInfo(),
session_id: this.sessionId
})
});
} catch (error) {
console.error('Error reporting failed:', error);
}
}
// Mobile-optimierte Produkt-API
async getMobileProducts(page = 1, perPage = 20) {
try {
const response = await fetch(`${this.baseUrl}products/?page=${page}&per_page=${perPage}`, {
headers: this.getAuthHeaders()
});
const data = await response.json();
if (response.ok) {
// Track analytics
this.trackEvent('products_viewed', { page, per_page: perPage });
return data;
} else {
throw new Error(data.error || 'Failed to fetch products');
}
} catch (error) {
console.error('Get products error:', error);
throw error;
}
}
// Mobile-optimierte Auction-API
async getMobileAuctions(page = 1, perPage = 10) {
try {
const response = await fetch(`${this.baseUrl}auctions/?page=${page}&per_page=${perPage}`, {
headers: this.getAuthHeaders()
});
const data = await response.json();
if (response.ok) {
// Track analytics
this.trackEvent('auctions_viewed', { page, per_page: perPage });
return data;
} else {
throw new Error(data.error || 'Failed to fetch auctions');
}
} catch (error) {
console.error('Get auctions error:', error);
throw error;
}
}
// Offline Sync
async syncOfflineData(syncType, syncData) {
if (!this.deviceToken) return;
try {
const response = await fetch(this.baseUrl + 'sync/', {
method: 'POST',
headers: this.getAuthHeaders(),
body: JSON.stringify({
sync_type: syncType,
data: syncData,
device_token: this.deviceToken
})
});
const data = await response.json();
if (response.ok) {
this.trackEvent('offline_sync', { sync_type: syncType });
return data;
} else {
throw new Error(data.error || 'Sync failed');
}
} catch (error) {
console.error('Offline sync error:', error);
throw error;
}
}
// Cache Management
async getCache(cacheType, cacheKey = 'default') {
try {
const response = await fetch(`${this.baseUrl}cache/${cacheType}/?key=${cacheKey}`, {
headers: this.getAuthHeaders()
});
const data = await response.json();
if (response.ok) {
return data;
} else {
return null;
}
} catch (error) {
console.error('Get cache error:', error);
return null;
}
}
async updateCache(cacheType, cacheKey, cacheData, expiresIn = 3600) {
try {
const response = await fetch(`${this.baseUrl}cache/${cacheType}/update/`, {
method: 'POST',
headers: this.getAuthHeaders(),
body: JSON.stringify({
key: cacheKey,
data: cacheData,
expires_in: expiresIn
})
});
const data = await response.json();
if (response.ok) {
return data;
} else {
throw new Error(data.error || 'Cache update failed');
}
} catch (error) {
console.error('Update cache error:', error);
throw error;
}
}
// Push Notifications
async sendPushNotification(userId, notificationType, title, message, data = {}) {
try {
const response = await fetch(this.baseUrl + 'notifications/send/', {
method: 'POST',
headers: this.getAuthHeaders(),
body: JSON.stringify({
user_id: userId,
notification_type: notificationType,
title: title,
message: message,
data: data
})
});
const responseData = await response.json();
if (response.ok) {
return responseData;
} else {
throw new Error(responseData.error || 'Failed to send notification');
}
} catch (error) {
console.error('Send notification error:', error);
throw error;
}
}
// Utility Methods
getAuthHeaders() {
const headers = {
'Content-Type': 'application/json',
};
if (this.authToken) {
headers['Authorization'] = `Token ${this.authToken}`;
}
return headers;
}
getDeviceInfo() {
return {
userAgent: navigator.userAgent,
platform: navigator.platform,
language: navigator.language,
screenWidth: screen.width,
screenHeight: screen.height,
windowWidth: window.innerWidth,
windowHeight: window.innerHeight
};
}
getOSVersion() {
const userAgent = navigator.userAgent;
if (userAgent.includes('Windows')) return 'Windows';
if (userAgent.includes('Mac')) return 'macOS';
if (userAgent.includes('Linux')) return 'Linux';
if (userAgent.includes('Android')) return 'Android';
if (userAgent.includes('iOS')) return 'iOS';
return 'Unknown';
}
// Event Tracking Helpers
trackScreenView(screenName) {
this.trackEvent('screen_view', {}, screenName);
}
trackProductView(productId, productName) {
this.trackEvent('product_view', { product_id: productId, product_name: productName });
}
trackAuctionView(auctionId, auctionTitle) {
this.trackEvent('auction_view', { auction_id: auctionId, auction_title: auctionTitle });
}
trackPurchase(orderId, total) {
this.trackEvent('purchase', { order_id: orderId, total: total });
}
trackAddToCart(productId, quantity) {
this.trackEvent('add_to_cart', { product_id: productId, quantity: quantity });
}
trackSearch(query, resultsCount) {
this.trackEvent('search', { query: query, results_count: resultsCount });
}
// Error Handling
handleError(error, context = '') {
console.error(`Error in ${context}:`, error);
this.reportError(
'error',
'api_error',
error.message,
error.stack
);
throw error;
}
}
// Mobile API Client initialisieren
document.addEventListener('DOMContentLoaded', function() {
window.kasicoMobileApi = new KasicoMobileApiClient();
});
// Export für React Native
if (typeof module !== 'undefined' && module.exports) {
module.exports = KasicoMobileApiClient;
}