|
|
|
|
@@ -627,9 +627,37 @@
|
|
|
|
|
.recording-pulse {
|
|
|
|
|
animation: pulse-red 1.2s infinite;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* RTL Overrides */
|
|
|
|
|
body[dir="rtl"] .nav-item {
|
|
|
|
|
text-align: right;
|
|
|
|
|
flex-direction: row;
|
|
|
|
|
}
|
|
|
|
|
body[dir="rtl"] .data-table {
|
|
|
|
|
text-align: right;
|
|
|
|
|
}
|
|
|
|
|
body[dir="rtl"] .modal-header {
|
|
|
|
|
flex-direction: row-reverse;
|
|
|
|
|
}
|
|
|
|
|
body[dir="rtl"] .form-group {
|
|
|
|
|
text-align: right;
|
|
|
|
|
}
|
|
|
|
|
body[dir="rtl"] .form-label {
|
|
|
|
|
text-align: right;
|
|
|
|
|
display: block;
|
|
|
|
|
}
|
|
|
|
|
body[dir="rtl"] .dashboard-header {
|
|
|
|
|
flex-direction: row-reverse;
|
|
|
|
|
}
|
|
|
|
|
body[dir="rtl"] .user-info {
|
|
|
|
|
flex-direction: row-reverse;
|
|
|
|
|
}
|
|
|
|
|
body[dir="rtl"] .modal-footer {
|
|
|
|
|
flex-direction: row-reverse;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
</head>
|
|
|
|
|
<body x-data="app()" x-init="checkAuth()">
|
|
|
|
|
<body x-data="app()" x-init="checkAuth()" :dir="lang === 'ar' ? 'rtl' : 'ltr'">
|
|
|
|
|
|
|
|
|
|
<div class="app-container">
|
|
|
|
|
<!-- Auth View -->
|
|
|
|
|
@@ -708,17 +736,23 @@
|
|
|
|
|
<!-- Main Dashboard View -->
|
|
|
|
|
<template x-if="isLoggedIn">
|
|
|
|
|
<div>
|
|
|
|
|
<div class="dashboard-header" style="display: flex; align-items: center; justify-content: space-between;">
|
|
|
|
|
<div style="display: flex; align-items: center; gap: 16px;">
|
|
|
|
|
<div class="dashboard-header" style="display: flex; align-items: center; justify-content: space-between;" :style="lang === 'ar' ? 'flex-direction: row-reverse' : ''">
|
|
|
|
|
<div style="display: flex; align-items: center; gap: 16px;" :style="lang === 'ar' ? 'flex-direction: row-reverse' : ''">
|
|
|
|
|
<img src="/logo.svg" alt="Nabeh Logo" style="width: 52px; height: 52px; border-radius: 12px; box-shadow: 0 0 15px rgba(6, 182, 212, 0.35); border: 1px solid rgba(255, 255, 255, 0.08);">
|
|
|
|
|
<div>
|
|
|
|
|
<h1 style="font-size: 1.8rem; margin: 0 0 0.15rem 0;">Nabeh Dashboard</h1>
|
|
|
|
|
<p class="text-muted" style="font-size: 0.9rem; margin: 0;">Connected to system: <span class="font-semibold" x-text="user.name"></span></p>
|
|
|
|
|
<div :style="lang === 'ar' ? 'text-align: right;' : ''">
|
|
|
|
|
<h1 style="font-size: 1.8rem; margin: 0 0 0.15rem 0;" x-text="lang === 'ar' ? 'لوحة تحكم نبيه' : 'Nabeh Dashboard'"></h1>
|
|
|
|
|
<p class="text-muted" style="font-size: 0.9rem; margin: 0;">
|
|
|
|
|
<span x-text="lang === 'ar' ? 'متصل بالنظام باسم:' : 'Connected to system:'"></span>
|
|
|
|
|
<span class="font-semibold" x-text="user.name"></span>
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="user-info">
|
|
|
|
|
<div class="user-info" style="display: flex; align-items: center; gap: 12px;" :style="lang === 'ar' ? 'flex-direction: row-reverse' : ''">
|
|
|
|
|
<button @click="toggleLang()" class="btn btn-secondary" style="width: auto; padding: 0.5rem 1rem; font-size: 0.85rem;" id="lang-toggle-btn">
|
|
|
|
|
<span x-text="lang === 'ar' ? 'English 🇬🇧' : 'العربية 🇸🇦'"></span>
|
|
|
|
|
</button>
|
|
|
|
|
<div class="avatar" x-text="user.name.charAt(0).toUpperCase()"></div>
|
|
|
|
|
<button @click="logout()" class="btn btn-secondary" style="width: auto; padding: 0.5rem 1rem; font-size: 0.85rem;" id="logout-btn">Log Out</button>
|
|
|
|
|
<button @click="logout()" class="btn btn-secondary" style="width: auto; padding: 0.5rem 1rem; font-size: 0.85rem;" id="logout-btn" x-text="lang === 'ar' ? 'تسجيل الخروج' : 'Log Out'"></button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
@@ -726,22 +760,22 @@
|
|
|
|
|
<!-- Left Sidebar Nav -->
|
|
|
|
|
<div class="nav-menu">
|
|
|
|
|
<button class="nav-item" :class="{ 'active': activeDashboardTab === 'whatsapp' }" @click="activeDashboardTab = 'whatsapp'" id="nav-whatsapp-btn">
|
|
|
|
|
<span>📱</span> WhatsApp Connection
|
|
|
|
|
<span>📱</span> <span x-text="lang === 'ar' ? 'اتصال الواتساب' : 'WhatsApp Connection'"></span>
|
|
|
|
|
</button>
|
|
|
|
|
<button class="nav-item" :class="{ 'active': activeDashboardTab === 'contacts' }" @click="activeDashboardTab = 'contacts'; fetchContacts(); fetchGroups()" id="nav-contacts-btn">
|
|
|
|
|
<span>👥</span> Contacts Directory
|
|
|
|
|
<span>👥</span> <span x-text="lang === 'ar' ? 'دليل جهات الاتصال' : 'Contacts Directory'"></span>
|
|
|
|
|
</button>
|
|
|
|
|
<button class="nav-item" :class="{ 'active': activeDashboardTab === 'templates' }" @click="activeDashboardTab = 'templates'; fetchTemplates()" id="nav-templates-btn">
|
|
|
|
|
<span>📝</span> Message Templates
|
|
|
|
|
<span>📝</span> <span x-text="lang === 'ar' ? 'قوالب الرسائل' : 'Message Templates'"></span>
|
|
|
|
|
</button>
|
|
|
|
|
<button class="nav-item" :class="{ 'active': activeDashboardTab === 'campaigns' }" @click="activeDashboardTab = 'campaigns'; fetchCampaigns()" id="nav-campaigns-btn">
|
|
|
|
|
<span>📣</span> Marketing Campaigns
|
|
|
|
|
<span>📣</span> <span x-text="lang === 'ar' ? 'الحملات التسويقية' : 'Marketing Campaigns'"></span>
|
|
|
|
|
</button>
|
|
|
|
|
<button class="nav-item" :class="{ 'active': activeDashboardTab === 'chatbot' }" @click="activeDashboardTab = 'chatbot'; fetchChatbotSettings()" id="nav-chatbot-btn">
|
|
|
|
|
<span>🤖</span> AI Chatbot Settings
|
|
|
|
|
<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> API Integrations
|
|
|
|
|
<span>🔌</span> <span>ربط تطبيق نبيه بمشروعك (API Integrations)</span>
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
@@ -1069,26 +1103,25 @@
|
|
|
|
|
|
|
|
|
|
<!-- Panel: API Integrations -->
|
|
|
|
|
<div class="panel" x-show="activeDashboardTab === 'integrations'" id="panel-integrations">
|
|
|
|
|
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem;">
|
|
|
|
|
<h2 style="font-size: 1.4rem; margin: 0;">API Endpoints Integration</h2>
|
|
|
|
|
<button class="btn btn-primary" style="width: auto;" @click="endpointForm = { id: null, name: '', endpoint_url: '', action_type: 'verify_payment', description: '', headers: '' }; showAddEndpointModal = true" id="add-endpoint-btn">
|
|
|
|
|
+ Add API Integration
|
|
|
|
|
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem;" :style="lang === 'ar' ? 'flex-direction: row-reverse' : ''">
|
|
|
|
|
<h2 style="font-size: 1.4rem; margin: 0;" x-text="lang === 'ar' ? 'ربط تطبيق نبيه بمشروعك (API Integrations)' : 'API Endpoints Integration'"></h2>
|
|
|
|
|
<button class="btn btn-primary" style="width: auto;" @click="endpointForm = { id: null, name: '', endpoint_url: '', action_type: 'verify_payment', description: '', api_key: '' }; showAddEndpointModal = true" id="add-endpoint-btn">
|
|
|
|
|
<span x-text="lang === 'ar' ? '+ إضافة ربط برمجي' : '+ Add API Integration'"></span>
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<p class="text-muted" style="margin-bottom: 1.5rem; font-size: 0.9rem;">
|
|
|
|
|
Configure external web APIs for multi-tenant integrations. The chatbot can fetch user profiles or verify payment details dynamically.
|
|
|
|
|
<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>
|
|
|
|
|
|
|
|
|
|
<div class="data-table-container">
|
|
|
|
|
<table class="data-table">
|
|
|
|
|
<thead>
|
|
|
|
|
<tr>
|
|
|
|
|
<th>Integration Name</th>
|
|
|
|
|
<th>Action Type</th>
|
|
|
|
|
<th>Endpoint URL</th>
|
|
|
|
|
<th>Description</th>
|
|
|
|
|
<th style="width: 150px; text-align: center;">Actions</th>
|
|
|
|
|
<th x-text="lang === 'ar' ? 'اسم الربط' : 'Integration Name'"></th>
|
|
|
|
|
<th x-text="lang === 'ar' ? 'نوع الإجراء' : 'Action Type'"></th>
|
|
|
|
|
<th x-text="lang === 'ar' ? 'رابط نقطة النهاية (Endpoint URL)' : 'Endpoint URL'"></th>
|
|
|
|
|
<th x-text="lang === 'ar' ? 'الوصف' : 'Description'"></th>
|
|
|
|
|
<th style="width: 150px; text-align: center;" x-text="lang === 'ar' ? 'الخيارات' : 'Actions'"></th>
|
|
|
|
|
</tr>
|
|
|
|
|
</thead>
|
|
|
|
|
<tbody>
|
|
|
|
|
@@ -1096,20 +1129,20 @@
|
|
|
|
|
<tr>
|
|
|
|
|
<td class="font-semibold" x-text="endpoint.name"></td>
|
|
|
|
|
<td>
|
|
|
|
|
<span class="status-badge" :class="endpoint.action_type === 'verify_payment' ? 'badge-waiting_qr' : 'badge-connecting'" style="margin: 0; padding: 0.2rem 0.5rem; font-size: 0.75rem;" x-text="endpoint.action_type === 'verify_payment' ? 'Verify Payment' : 'Fetch User Info'"></span>
|
|
|
|
|
<span class="status-badge" :class="endpoint.action_type === 'verify_payment' ? 'badge-waiting_qr' : 'badge-connecting'" style="margin: 0; padding: 0.2rem 0.5rem; font-size: 0.75rem;" x-text="endpoint.action_type === 'verify_payment' ? (lang === 'ar' ? 'تأكيد الدفع' : 'Verify Payment') : (endpoint.action_type === 'fetch_user_info' ? (lang === 'ar' ? 'جلب بيانات العميل' : 'Fetch User Info') : endpoint.action_type)"></span>
|
|
|
|
|
</td>
|
|
|
|
|
<td style="font-family: monospace; font-size: 0.85rem;" x-text="endpoint.endpoint_url"></td>
|
|
|
|
|
<td x-text="endpoint.description || 'No description provided.'"></td>
|
|
|
|
|
<td style="text-align: center; display: flex; gap: 0.5rem; justify-content: center; align-items: center;">
|
|
|
|
|
<button class="btn btn-secondary" style="width: auto; padding: 0.4rem 0.8rem; font-size: 0.8rem;" @click="editEndpoint(endpoint)" :id="'edit-endpoint-btn-' + endpoint.id">Edit</button>
|
|
|
|
|
<button class="btn btn-danger" style="width: auto; padding: 0.4rem 0.8rem; font-size: 0.8rem;" @click="deleteEndpoint(endpoint.id)" :id="'delete-endpoint-btn-' + endpoint.id">Delete</button>
|
|
|
|
|
<td x-text="endpoint.description || (lang === 'ar' ? 'لا يوجد وصف.' : 'No description provided.')"></td>
|
|
|
|
|
<td style="text-align: center; display: flex; gap: 0.5rem; justify-content: center; align-items: center;" :style="lang === 'ar' ? 'flex-direction: row-reverse' : ''">
|
|
|
|
|
<button class="btn btn-secondary" style="width: auto; padding: 0.4rem 0.8rem; font-size: 0.8rem;" @click="editEndpoint(endpoint)" :id="'edit-endpoint-btn-' + endpoint.id" x-text="lang === 'ar' ? 'تعديل' : 'Edit'"></button>
|
|
|
|
|
<button class="btn btn-danger" style="width: auto; padding: 0.4rem 0.8rem; font-size: 0.8rem;" @click="deleteEndpoint(endpoint.id)" :id="'delete-endpoint-btn-' + endpoint.id" x-text="lang === 'ar' ? 'حذف' : 'Delete'"></button>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
</template>
|
|
|
|
|
</tbody>
|
|
|
|
|
</table>
|
|
|
|
|
<template x-if="endpoints.length === 0">
|
|
|
|
|
<div class="empty-state" id="empty-endpoints-state">No API endpoints configured yet. Connect Intaleq or Salla integrations.</div>
|
|
|
|
|
<div class="empty-state" id="empty-endpoints-state" x-text="lang === 'ar' ? 'لم يتم تكوين نقاط نهاية واجهة برمجة تطبيقات (API Endpoints) بعد.' : 'No API endpoints configured yet. Connect Intaleq or Salla integrations.'"></div>
|
|
|
|
|
</template>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
@@ -1157,43 +1190,49 @@
|
|
|
|
|
<!-- Modal: Add/Edit Endpoint Integration -->
|
|
|
|
|
<div class="modal-overlay" x-show="showAddEndpointModal" id="modal-add-endpoint" style="display: none;">
|
|
|
|
|
<div class="modal-card">
|
|
|
|
|
<div class="modal-header">
|
|
|
|
|
<h3 class="modal-title" x-text="endpointForm.id ? 'Edit API Endpoint Integration' : 'Add API Endpoint Integration'"></h3>
|
|
|
|
|
<div class="modal-header" :style="lang === 'ar' ? 'flex-direction: row-reverse' : ''">
|
|
|
|
|
<h3 class="modal-title" x-text="endpointForm.id ? (lang === 'ar' ? 'تعديل ربط تطبيق نبيه بمشروعك' : 'Edit API Endpoint Integration') : (lang === 'ar' ? 'إضافة ربط تطبيق نبيه بمشروعك' : 'Add API Endpoint Integration')"></h3>
|
|
|
|
|
<button class="modal-close" @click="showAddEndpointModal = false">×</button>
|
|
|
|
|
</div>
|
|
|
|
|
<form @submit.prevent="submitAddEndpoint()" id="form-add-endpoint">
|
|
|
|
|
<div class="modal-body">
|
|
|
|
|
<div class="form-group">
|
|
|
|
|
<label class="form-label">Integration Name</label>
|
|
|
|
|
<label class="form-label" x-text="lang === 'ar' ? 'اسم الربط' : 'Integration Name'"></label>
|
|
|
|
|
<input type="text" class="form-input" x-model="endpointForm.name" required placeholder="e.g. Intaleq Driver Lookup" id="add-endpoint-name">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="form-group">
|
|
|
|
|
<label class="form-label">Endpoint URL</label>
|
|
|
|
|
<label class="form-label" x-text="lang === 'ar' ? 'رابط نقطة النهاية (Endpoint URL)' : 'Endpoint URL'"></label>
|
|
|
|
|
<input type="url" class="form-input" x-model="endpointForm.endpoint_url" required placeholder="https://yourdomain.com/api/nabeh/action" id="add-endpoint-url">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="form-group">
|
|
|
|
|
<label class="form-label">Action Type</label>
|
|
|
|
|
<select class="form-input" x-model="endpointForm.action_type" required id="add-endpoint-action-type">
|
|
|
|
|
<option value="verify_payment">Verify Payment (تحليل وتأكيد الدفع)</option>
|
|
|
|
|
<option value="fetch_user_info">Fetch User Info (جلب معلومات السائق أو العميل)</option>
|
|
|
|
|
</select>
|
|
|
|
|
<label class="form-label" x-text="lang === 'ar' ? 'نوع الإجراء (Action Type)' : 'Action Type'"></label>
|
|
|
|
|
<input type="text" class="form-input" x-model="endpointForm.action_type" required placeholder="e.g. verify_payment" id="add-endpoint-action-type">
|
|
|
|
|
|
|
|
|
|
<!-- Shortcuts/Hint Tags -->
|
|
|
|
|
<div style="display: flex; gap: 0.5rem; margin-top: 0.5rem; flex-wrap: wrap;" :style="lang === 'ar' ? 'flex-direction: row-reverse' : ''">
|
|
|
|
|
<button type="button" class="btn btn-secondary" style="width: auto; padding: 0.25rem 0.5rem; font-size: 0.75rem; border-radius: 4px;" @click="endpointForm.action_type = 'verify_payment'">
|
|
|
|
|
verify_payment (تحليل وتأكيد الدفع)
|
|
|
|
|
</button>
|
|
|
|
|
<button type="button" class="btn btn-secondary" style="width: auto; padding: 0.25rem 0.5rem; font-size: 0.75rem; border-radius: 4px;" @click="endpointForm.action_type = 'fetch_user_info'">
|
|
|
|
|
fetch_user_info (جلب معلومات العميل)
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
<span style="font-size: 0.75rem; color: var(--text-secondary); display: block; margin-top: 0.25rem;" x-text="lang === 'ar' ? 'يمكنك كتابة نوع إجراء مخصص هنا لتسهيل ربط النظام أو الضغط على الاختصارات بالأعلى.' : 'You can type a custom action type here or click the shortcuts above.'"></span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="form-group">
|
|
|
|
|
<label class="form-label">Description</label>
|
|
|
|
|
<label class="form-label" x-text="lang === 'ar' ? 'الوصف' : 'Description'"></label>
|
|
|
|
|
<textarea class="form-input" x-model="endpointForm.description" placeholder="A brief explanation of what this endpoint does..." id="add-endpoint-description"></textarea>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="form-group">
|
|
|
|
|
<label class="form-label">Custom HTTP Headers (JSON Object)</label>
|
|
|
|
|
<textarea class="form-input" style="font-family: monospace; font-size: 0.85rem; height: 120px;" x-model="endpointForm.headers" placeholder='{ "Authorization": "Bearer YOUR_SECRET_TOKEN", "X-Custom-Source": "Nabeh App" }' id="add-endpoint-headers"></textarea>
|
|
|
|
|
<span style="font-size: 0.75rem; color: var(--text-secondary); display: block; margin-top: 0.25rem;">
|
|
|
|
|
Optionally define any authorization tokens or custom headers in JSON format.
|
|
|
|
|
</span>
|
|
|
|
|
<label class="form-label" x-text="lang === 'ar' ? 'مفتاح واجهة برمجة التطبيقات (API Key)' : 'API Key'"></label>
|
|
|
|
|
<input type="password" class="form-input" x-model="endpointForm.api_key" placeholder="e.g. key_xxxxxxxxxxxxxxxxx" id="add-endpoint-api-key">
|
|
|
|
|
<span style="font-size: 0.75rem; color: var(--text-secondary); display: block; margin-top: 0.25rem;" x-text="lang === 'ar' ? 'سيتم إرسال هذا المفتاح في ترويسات X-API-Key و Authorization: Bearer عند استدعاء الخادم.' : 'This key will be automatically sent in X-API-Key and Authorization: Bearer headers for outbound server-to-server calls.'"></span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="modal-footer">
|
|
|
|
|
<button type="button" class="btn btn-secondary" style="width: auto;" @click="showAddEndpointModal = false">Cancel</button>
|
|
|
|
|
<div class="modal-footer" :style="lang === 'ar' ? 'flex-direction: row-reverse' : ''">
|
|
|
|
|
<button type="button" class="btn btn-secondary" style="width: auto;" @click="showAddEndpointModal = false" x-text="lang === 'ar' ? 'إلغاء' : 'Cancel'"></button>
|
|
|
|
|
<button type="submit" class="btn btn-primary" style="width: auto;" :disabled="actionLoading">
|
|
|
|
|
<span x-show="!actionLoading" x-text="endpointForm.id ? 'Save Changes' : 'Create Integration'"></span>
|
|
|
|
|
<span x-show="!actionLoading" x-text="endpointForm.id ? (lang === 'ar' ? 'حفظ التعديلات' : 'Save Changes') : (lang === 'ar' ? 'إنشاء الربط' : 'Create Integration')"></span>
|
|
|
|
|
<span x-show="actionLoading" class="spinner"></span>
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
@@ -1305,6 +1344,9 @@
|
|
|
|
|
<script>
|
|
|
|
|
function app() {
|
|
|
|
|
return {
|
|
|
|
|
// Multi-Language State
|
|
|
|
|
lang: localStorage.getItem('nabeh_lang') || 'ar',
|
|
|
|
|
|
|
|
|
|
// Auth States
|
|
|
|
|
isLoggedIn: false,
|
|
|
|
|
authTab: 'login',
|
|
|
|
|
@@ -1344,7 +1386,7 @@
|
|
|
|
|
endpoint_url: '',
|
|
|
|
|
action_type: 'verify_payment',
|
|
|
|
|
description: '',
|
|
|
|
|
headers: ''
|
|
|
|
|
api_key: ''
|
|
|
|
|
},
|
|
|
|
|
endpoints: [],
|
|
|
|
|
|
|
|
|
|
@@ -1383,6 +1425,11 @@
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// Methods
|
|
|
|
|
toggleLang() {
|
|
|
|
|
this.lang = this.lang === 'ar' ? 'en' : 'ar';
|
|
|
|
|
localStorage.setItem('nabeh_lang', this.lang);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
checkAuth() {
|
|
|
|
|
this.token = localStorage.getItem('nabeh_token');
|
|
|
|
|
const storedUser = localStorage.getItem('nabeh_user');
|
|
|
|
|
@@ -1606,16 +1653,6 @@
|
|
|
|
|
async submitAddEndpoint() {
|
|
|
|
|
this.actionLoading = true;
|
|
|
|
|
try {
|
|
|
|
|
if (this.endpointForm.headers && this.endpointForm.headers.trim()) {
|
|
|
|
|
try {
|
|
|
|
|
JSON.parse(this.endpointForm.headers);
|
|
|
|
|
} catch (jsonErr) {
|
|
|
|
|
alert('Invalid JSON in Custom Headers. Please verify format.');
|
|
|
|
|
this.actionLoading = false;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const response = await fetch('/api/endpoints', {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
headers: {
|
|
|
|
|
@@ -1627,7 +1664,7 @@
|
|
|
|
|
const data = await response.json();
|
|
|
|
|
if (response.ok) {
|
|
|
|
|
this.showAddEndpointModal = false;
|
|
|
|
|
this.endpointForm = { id: null, name: '', endpoint_url: '', action_type: 'verify_payment', description: '', headers: '' };
|
|
|
|
|
this.endpointForm = { id: null, name: '', endpoint_url: '', action_type: 'verify_payment', description: '', api_key: '' };
|
|
|
|
|
await this.fetchEndpoints();
|
|
|
|
|
} else {
|
|
|
|
|
alert(data.message || 'Failed to save integration endpoint.');
|
|
|
|
|
@@ -1646,13 +1683,16 @@
|
|
|
|
|
endpoint_url: endpoint.endpoint_url,
|
|
|
|
|
action_type: endpoint.action_type,
|
|
|
|
|
description: endpoint.description || '',
|
|
|
|
|
headers: endpoint.headers || ''
|
|
|
|
|
api_key: endpoint.api_key || ''
|
|
|
|
|
};
|
|
|
|
|
this.showAddEndpointModal = true;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
async deleteEndpoint(id) {
|
|
|
|
|
if (!confirm('Are you sure you want to delete this integration endpoint?')) return;
|
|
|
|
|
const confirmMsg = this.lang === 'ar'
|
|
|
|
|
? 'هل أنت متأكد من رغبتك في حذف ربط نقطة النهاية هذا؟'
|
|
|
|
|
: 'Are you sure you want to delete this integration endpoint?';
|
|
|
|
|
if (!confirm(confirmMsg)) return;
|
|
|
|
|
this.actionLoading = true;
|
|
|
|
|
try {
|
|
|
|
|
const response = await fetch('/api/endpoints', {
|
|
|
|
|
|