Deploy: 2026-07-15 05:08:07

This commit is contained in:
Hamza-Ayed
2026-07-15 05:08:07 +03:00
parent 3de7764cdd
commit 66b2c0eaa9
5 changed files with 834 additions and 0 deletions
+115
View File
@@ -901,6 +901,7 @@
<!-- Sub-tabs for Channels -->
<div style="display: flex; gap: 1rem; border-bottom: 1px solid var(--card-border); margin-bottom: 1.5rem;" :style="lang === 'ar' ? 'flex-direction: row-reverse' : ''">
<button class="tab-btn" :class="{ 'active': channelTab === 'whatsapp' }" @click="channelTab = 'whatsapp'" x-text="lang === 'ar' ? 'واتساب' : 'WhatsApp'"></button>
<button class="tab-btn" :class="{ 'active': channelTab === 'whatsapp_cloud' }" @click="channelTab = 'whatsapp_cloud'; fetchCloudSession()" x-text="lang === 'ar' ? 'واتساب بزنس API (رسمي)' : 'WhatsApp Business API'"></button>
<button class="tab-btn" :class="{ 'active': channelTab === 'messenger' }" @click="channelTab = 'messenger'; fetchMetaSessions()" x-text="lang === 'ar' ? 'فيسبوك ماسنجر' : 'Facebook Messenger'"></button>
<button class="tab-btn" :class="{ 'active': channelTab === 'instagram' }" @click="channelTab = 'instagram'; fetchMetaSessions()" x-text="lang === 'ar' ? 'إنستغرام' : 'Instagram'"></button>
</div>
@@ -978,6 +979,52 @@
</template>
</div>
<!-- WhatsApp Cloud API Tab Content -->
<div x-show="channelTab === 'whatsapp_cloud'">
<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 (الربط الرسمي بـ Meta)' : 'WhatsApp Business API Integration'"></h2>
</div>
<p class="text-muted" style="margin-bottom: 1.5rem; font-size: 0.9rem;" x-text="lang === 'ar' ? 'اربط حساب شركتك الرسمي مع Meta مباشرة. هذا الخيار مثالي لإرسال حملات دعائية ضخمة وقوالب معتمدة بدون خطر حظر الرقم.' : 'Connect your official WhatsApp Business account with Meta. Best for massive broadcast campaigns using approved templates without ban risks.'"></p>
<div class="card" style="margin-bottom: 2rem;">
<template x-if="!cloudSession">
<div style="display: flex; flex-direction: column; gap: 1.5rem;" :style="lang === 'ar' ? 'align-items: flex-end;' : 'align-items: flex-start;'">
<div style="width: 100%; max-width: 500px;">
<label class="form-label" x-text="lang === 'ar' ? 'رقم الهاتف (Phone Number ID)' : 'Phone Number ID'"></label>
<input type="text" x-model="newCloudSession.phone_number_id" class="form-input" placeholder="e.g. 123456789012345">
</div>
<div style="width: 100%; max-width: 500px;">
<label class="form-label" x-text="lang === 'ar' ? 'رقم حساب الأعمال (WABA ID)' : 'WhatsApp Business Account ID'"></label>
<input type="text" x-model="newCloudSession.waba_id" class="form-input" placeholder="e.g. 987654321098765">
</div>
<div style="width: 100%; max-width: 500px;">
<label class="form-label" x-text="lang === 'ar' ? 'رمز الوصول الدائم (Access Token)' : 'Permanent Access Token'"></label>
<input type="password" x-model="newCloudSession.access_token" class="form-input" placeholder="EA...XXXX">
</div>
<button @click="connectCloudSession()" class="btn btn-primary" :disabled="actionLoading" style="align-self: flex-start;">
<span x-text="lang === 'ar' ? 'ربط حساب Meta' : 'Connect Meta Account'"></span>
</button>
</div>
</template>
<template x-if="cloudSession">
<div style="display: flex; flex-direction: column; gap: 1rem;" :style="lang === 'ar' ? 'align-items: flex-end;' : 'align-items: flex-start;'">
<div style="display: flex; align-items: center; gap: 1rem;">
<div style="font-size: 2rem; color: var(--success);">✓</div>
<div>
<h3 style="margin: 0; color: var(--success);" x-text="lang === 'ar' ? 'الحساب مربوط بنجاح' : 'Account Connected Successfully'"></h3>
<p class="text-muted" style="margin: 0.5rem 0 0 0;" x-text="lang === 'ar' ? 'رقم الهاتف ID: ' + cloudSession.phone_number_id : 'Phone ID: ' + cloudSession.phone_number_id"></p>
</div>
</div>
<div style="display: flex; gap: 1rem; margin-top: 1rem;">
<button @click="disconnectCloudSession()" class="btn btn-danger" :disabled="actionLoading">
<span x-text="lang === 'ar' ? 'قطع الاتصال وإزالة الحساب' : 'Disconnect Account'"></span>
</button>
</div>
</div>
</template>
</div>
</div>
<div class="grid-two" style="align-items: start;">
<!-- QR Display Card (Active selected session) -->
<div class="card" style="margin: 0;" x-show="whatsappSession && (whatsappSession.status === 'connecting' || whatsappSession.status === 'waiting_qr' || whatsappSession.status === 'connected')">
@@ -1946,6 +1993,12 @@
whatsappMaxSessions: 1,
newSessionName: '',
metaSessions: [],
cloudSession: null,
newCloudSession: {
phone_number_id: '',
waba_id: '',
access_token: ''
},
newMetaSession: {
channel_type: 'messenger',
page_id: '',
@@ -2375,6 +2428,68 @@
this.actionLoading = false;
}
},
async fetchCloudSession() {
if (!this.token) return;
try {
const response = await fetch('/api/cloud/status', {
headers: { 'Authorization': `Bearer ${this.token}` }
});
const data = await response.json();
if (response.ok && data.status === 'success') {
this.cloudSession = data.data;
}
} catch (err) {
console.error('Failed to fetch cloud session', err);
}
},
async connectCloudSession() {
if (!this.newCloudSession.phone_number_id || !this.newCloudSession.waba_id || !this.newCloudSession.access_token) {
alert(this.lang === 'ar' ? 'الرجاء تعبئة جميع الحقول' : 'Please fill all fields');
return;
}
this.actionLoading = true;
try {
const response = await fetch('/api/cloud/connect', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.token}`
},
body: JSON.stringify(this.newCloudSession)
});
const data = await response.json();
if (response.ok && data.status === 'success') {
this.cloudSession = data.data;
this.newCloudSession = { phone_number_id: '', waba_id: '', access_token: '' };
} else {
alert(data.message || data.error || 'Connection failed');
}
} catch (err) {
alert('Network error connecting Cloud API');
} finally {
this.actionLoading = false;
}
},
async disconnectCloudSession() {
if (!confirm(this.lang === 'ar' ? 'هل أنت متأكد من قطع الاتصال بحساب Meta؟' : 'Are you sure you want to disconnect Meta Account?')) {
return;
}
this.actionLoading = true;
try {
const response = await fetch('/api/cloud/disconnect', {
method: 'POST',
headers: { 'Authorization': `Bearer ${this.token}` }
});
const data = await response.json();
if (response.ok && data.status === 'success') {
this.cloudSession = null;
}
} catch (err) {
console.error('Failed to disconnect cloud session', err);
} finally {
this.actionLoading = false;
}
},
async deleteMetaSession(id) {
if (!confirm(this.lang === 'ar' ? 'هل أنت متأكد من حذف هذه القناة؟' : 'Are you sure you want to disconnect this channel?')) {
return;