Deploy: 2026-05-22 03:37:23
This commit is contained in:
@@ -774,13 +774,26 @@
|
||||
<button class="nav-item" :class="{ 'active': activeDashboardTab === 'chatbot' }" @click="activeDashboardTab = 'chatbot'; fetchChatbotSettings()" id="nav-chatbot-btn">
|
||||
<span>🤖</span> <span x-text="lang === 'ar' ? 'روبوت الذكاء الاصطناعي' : 'AI Chatbot Settings'"></span>
|
||||
</button>
|
||||
<button class="nav-item" :class="{ 'active': activeDashboardTab === 'integrations' }" @click="activeDashboardTab = 'integrations'; fetchEndpoints()" id="nav-integrations-btn">
|
||||
<span>🔌</span> <span>ربط تطبيق نبيه بمشروعك (API Integrations)</span>
|
||||
<button class="nav-item" :class="{ 'active': activeDashboardTab === 'integrations' }" @click="activeDashboardTab = 'integrations'; fetchEndpoints(); fetchSallaStatus()" id="nav-integrations-btn">
|
||||
<span>🔌</span> <span x-text="lang === 'ar' ? 'الربط البرمجي والمنصات (Integrations)' : 'API & Platform Integrations'"></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Right Dashboard Panels -->
|
||||
<div style="flex: 1;">
|
||||
<!-- Global Dashboard Banner -->
|
||||
<template x-if="dashboardSuccess">
|
||||
<div class="banner banner-success" style="margin-bottom: 1.5rem;" id="dashboard-success-banner">
|
||||
<span x-text="dashboardSuccess"></span>
|
||||
<button @click="dashboardSuccess = ''" style="background: none; border: none; color: inherit; font-size: 1.2rem; cursor: pointer; margin-left: auto; margin-right: 0;" id="dashboard-success-close-btn">×</button>
|
||||
</div>
|
||||
</template>
|
||||
<template x-if="dashboardError">
|
||||
<div class="banner banner-danger" style="margin-bottom: 1.5rem;" id="dashboard-error-banner">
|
||||
<span x-text="dashboardError"></span>
|
||||
<button @click="dashboardError = ''" style="background: none; border: none; color: inherit; font-size: 1.2rem; cursor: pointer; margin-left: auto; margin-right: 0;" id="dashboard-error-close-btn">×</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Panel: WhatsApp Connection -->
|
||||
<div class="panel" x-show="activeDashboardTab === 'whatsapp'" id="panel-whatsapp">
|
||||
@@ -1113,6 +1126,50 @@
|
||||
<p class="text-muted" style="margin-bottom: 1.5rem; font-size: 0.9rem;" x-text="lang === 'ar' ? 'قم بتهيئة واجهات برمجة التطبيقات الخارجية (Web APIs) للربط البرمجي بمشروعك. يمكن للروبوت جلب الملفات التعريفية للمستخدمين أو التحقق من تفاصيل الدفع ديناميكيًا.' : 'Configure external web APIs for multi-tenant integrations. The chatbot can fetch user profiles or verify payment details dynamically.'">
|
||||
</p>
|
||||
|
||||
<!-- Salla Integration Section -->
|
||||
<div style="background: rgba(0, 178, 137, 0.05); border: 1px solid rgba(0, 178, 137, 0.15); border-radius: 12px; padding: 1.5rem; margin-bottom: 2rem; box-shadow: 0 4px 20px rgba(0, 178, 137, 0.05);">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 1rem;" :style="lang === 'ar' ? 'flex-direction: row-reverse' : ''">
|
||||
<div style="display: flex; align-items: center; gap: 1rem;" :style="lang === 'ar' ? 'flex-direction: row-reverse; text-align: right;' : ''">
|
||||
<div style="background: #00b289; width: 48px; height: 48px; border-radius: 10px; display: flex; align-items: center; justify-content: center; box-shadow: 0 0 15px rgba(0, 178, 137, 0.4);">
|
||||
<span style="font-size: 1.5rem;">🛍️</span>
|
||||
</div>
|
||||
<div>
|
||||
<h3 style="font-size: 1.2rem; margin: 0; display: flex; align-items: center; gap: 0.5rem;" :style="lang === 'ar' ? 'flex-direction: row-reverse' : ''">
|
||||
<span x-text="lang === 'ar' ? 'ربط متجر سلة (Salla)' : 'Salla Store Integration'"></span>
|
||||
<template x-if="sallaStatus && sallaStatus.connected">
|
||||
<span class="status-badge badge-connected" style="margin: 0; padding: 0.15rem 0.5rem; font-size: 0.7rem;" x-text="lang === 'ar' ? 'متصل' : 'Connected'"></span>
|
||||
</template>
|
||||
<template x-if="!sallaStatus || !sallaStatus.connected">
|
||||
<span class="status-badge badge-disconnected" style="margin: 0; padding: 0.15rem 0.5rem; font-size: 0.7rem;" x-text="lang === 'ar' ? 'غير متصل' : 'Disconnected'"></span>
|
||||
</template>
|
||||
</h3>
|
||||
<p class="text-muted" style="margin: 0.25rem 0 0 0; font-size: 0.85rem;" x-text="lang === 'ar' ? 'قم بربط متجر سلة الخاص بك لتفعيل الاستعلام التلقائي عن الطلبات وتتبع الشحنات وإرسال تنبيهات التحديثات للعملاء عبر الواتساب.' : 'Connect your Salla store to enable automatic order tracking and send customer updates via WhatsApp using Gemini AI.'"></p>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: flex; gap: 0.75rem; align-items: center;">
|
||||
<template x-if="sallaLoading">
|
||||
<span class="spinner"></span>
|
||||
</template>
|
||||
<template x-if="!sallaLoading && (!sallaStatus || !sallaStatus.connected)">
|
||||
<button @click="connectSalla()" class="btn" style="background: linear-gradient(135deg, #00b289 0%, #009673 100%); color: #fff; width: auto; font-size: 0.9rem; padding: 0.6rem 1.2rem; box-shadow: 0 4px 12px rgba(0, 178, 137, 0.3);" id="connect-salla-btn">
|
||||
<span x-text="lang === 'ar' ? 'ربط المتجر الآن' : 'Connect Store'"></span>
|
||||
</button>
|
||||
</template>
|
||||
<template x-if="!sallaLoading && sallaStatus && sallaStatus.connected">
|
||||
<div style="display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;" :style="lang === 'ar' ? 'flex-direction: row-reverse' : ''">
|
||||
<div style="text-align: right;" :style="lang === 'ar' ? 'text-align: right;' : 'text-align: left;'">
|
||||
<span style="font-size: 0.8rem; color: var(--text-secondary);" x-text="lang === 'ar' ? 'المتجر المرتبط:' : 'Connected Store:'"></span>
|
||||
<strong style="display: block; font-size: 0.95rem; color: #fff;" x-text="sallaStatus.store_name"></strong>
|
||||
</div>
|
||||
<button @click="disconnectSalla()" class="btn btn-danger" style="width: auto; font-size: 0.9rem; padding: 0.6rem 1.2rem;" id="disconnect-salla-btn">
|
||||
<span x-text="lang === 'ar' ? 'إلغاء الربط' : 'Disconnect'"></span>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="data-table-container">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
@@ -1390,6 +1447,12 @@
|
||||
},
|
||||
endpoints: [],
|
||||
|
||||
// Salla Integration States
|
||||
sallaStatus: null,
|
||||
sallaLoading: false,
|
||||
dashboardSuccess: '',
|
||||
dashboardError: '',
|
||||
|
||||
// Forms
|
||||
contactName: '',
|
||||
contactPhone: '',
|
||||
@@ -1522,12 +1585,25 @@
|
||||
this.templates = [];
|
||||
this.campaigns = [];
|
||||
this.endpoints = [];
|
||||
this.sallaStatus = null;
|
||||
this.dashboardSuccess = '';
|
||||
this.dashboardError = '';
|
||||
},
|
||||
|
||||
initializeDashboard() {
|
||||
this.fetchWhatsappStatus();
|
||||
this.fetchSallaStatus();
|
||||
// Set up persistent background status check
|
||||
this.startPolling();
|
||||
|
||||
// Detect Salla success connect
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
if (urlParams.get('salla_connect') === 'success') {
|
||||
this.dashboardSuccess = this.lang === 'ar'
|
||||
? 'تم ربط متجر سلة بنجاح!'
|
||||
: 'Salla store connected successfully!';
|
||||
window.history.replaceState({}, document.title, window.location.pathname);
|
||||
}
|
||||
},
|
||||
|
||||
async fetchWhatsappStatus() {
|
||||
@@ -1716,6 +1792,65 @@
|
||||
}
|
||||
},
|
||||
|
||||
// Salla Integration Methods
|
||||
async fetchSallaStatus() {
|
||||
if (!this.token) return;
|
||||
this.sallaLoading = true;
|
||||
try {
|
||||
const response = await fetch('/api/integrations/salla/status', {
|
||||
headers: { 'Authorization': `Bearer ${this.token}` }
|
||||
});
|
||||
const data = await response.json();
|
||||
if (response.ok && data.status === 'success') {
|
||||
this.sallaStatus = data;
|
||||
} else {
|
||||
this.sallaStatus = { connected: false };
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error fetching Salla status:', err);
|
||||
this.sallaStatus = { connected: false };
|
||||
} finally {
|
||||
this.sallaLoading = false;
|
||||
}
|
||||
},
|
||||
|
||||
connectSalla() {
|
||||
if (!this.token) return;
|
||||
window.location.href = `/api/integrations/salla/auth?token=${encodeURIComponent(this.token)}`;
|
||||
},
|
||||
|
||||
async disconnectSalla() {
|
||||
const confirmMsg = this.lang === 'ar'
|
||||
? 'هل أنت متأكد من رغبتك في إلغاء ربط متجر سلة؟'
|
||||
: 'Are you sure you want to disconnect your Salla store?';
|
||||
if (!confirm(confirmMsg)) return;
|
||||
|
||||
this.sallaLoading = true;
|
||||
try {
|
||||
const response = await fetch('/api/integrations/salla/disconnect', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${this.token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
const data = await response.json();
|
||||
if (response.ok && data.status === 'success') {
|
||||
this.dashboardSuccess = this.lang === 'ar'
|
||||
? 'تم إلغاء ربط متجر سلة بنجاح.'
|
||||
: 'Salla store disconnected successfully.';
|
||||
await this.fetchSallaStatus();
|
||||
} else {
|
||||
this.dashboardError = data.message || 'Failed to disconnect Salla integration.';
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error disconnecting Salla:', err);
|
||||
this.dashboardError = 'Failed to disconnect Salla integration.';
|
||||
} finally {
|
||||
this.sallaLoading = false;
|
||||
}
|
||||
},
|
||||
|
||||
// CRM List Fetchers
|
||||
async fetchContacts() {
|
||||
this.selectedContactIds = [];
|
||||
|
||||
@@ -73,6 +73,14 @@ $router->get('/api/endpoints', [\App\Controllers\EndpointController::class,
|
||||
$router->post('/api/endpoints', [\App\Controllers\EndpointController::class, 'store'], [\App\Middlewares\AuthMiddleware::class]);
|
||||
$router->delete('/api/endpoints', [\App\Controllers\EndpointController::class, 'delete'], [\App\Middlewares\AuthMiddleware::class]);
|
||||
|
||||
// Salla Platform Integration Routes (Phase 6+)
|
||||
$router->get('/api/integrations/salla/auth', [\App\Controllers\SallaController::class, 'auth']);
|
||||
$router->get('/api/integrations/salla/callback', [\App\Controllers\SallaController::class, 'callback']);
|
||||
$router->get('/api/integrations/salla/status', [\App\Controllers\SallaController::class, 'status'], [\App\Middlewares\AuthMiddleware::class]);
|
||||
$router->post('/api/integrations/salla/disconnect',[\App\Controllers\SallaController::class, 'disconnect'], [\App\Middlewares\AuthMiddleware::class]);
|
||||
$router->post('/api/webhooks/salla', [\App\Controllers\SallaController::class, 'webhook']);
|
||||
|
||||
|
||||
// Mock External API for Entaleq Driver Info (Used to fetch real-time driver data)
|
||||
$router->post('/api/external/driver-info', function ($request, $response) {
|
||||
$body = $request->getBody();
|
||||
|
||||
Reference in New Issue
Block a user