jerry 2 mēneši atpakaļ
vecāks
revīzija
6ec206e3c5
1 mainītis faili ar 67 papildinājumiem un 3 dzēšanām
  1. 67 3
      src/components/admin/tasks/TaskTable.tsx

+ 67 - 3
src/components/admin/tasks/TaskTable.tsx

@@ -6,6 +6,7 @@ import {
   User, History, Edit, MessageCircle, MessageSquare, X
   User, History, Edit, MessageCircle, MessageSquare, X
 } from 'lucide-react';
 } from 'lucide-react';
 import LocalTime from '@/components/common/LocalTime';
 import LocalTime from '@/components/common/LocalTime';
+import api from '@/lib/api';
 
 
 export interface VasTask {
 export interface VasTask {
   id: number;
   id: number;
@@ -40,6 +41,9 @@ export default function TaskTable({ tasks, loading, onRetry, onManualConfirm, on
   const [messageChannel, setMessageChannel] = useState<'sms' | 'whatsapp'>('sms');
   const [messageChannel, setMessageChannel] = useState<'sms' | 'whatsapp'>('sms');
   const [messageTask, setMessageTask] = useState<VasTask | null>(null);
   const [messageTask, setMessageTask] = useState<VasTask | null>(null);
   const [messageText, setMessageText] = useState('');
   const [messageText, setMessageText] = useState('');
+  const [messageSending, setMessageSending] = useState(false);
+  const [messageResult, setMessageResult] = useState<'idle' | 'success' | 'error'>('idle');
+  const [messageResultText, setMessageResultText] = useState('');
 
 
   const toggleRow = (id: number) => {
   const toggleRow = (id: number) => {
     const newSet = new Set(expandedRows);
     const newSet = new Set(expandedRows);
@@ -55,6 +59,9 @@ export default function TaskTable({ tasks, loading, onRetry, onManualConfirm, on
     setMessageTask(task);
     setMessageTask(task);
     setMessageChannel(channel);
     setMessageChannel(channel);
     setMessageText(template);
     setMessageText(template);
+    setMessageSending(false);
+    setMessageResult('idle');
+    setMessageResultText('');
     setIsMessageOpen(true);
     setIsMessageOpen(true);
   };
   };
 
 
@@ -63,6 +70,46 @@ export default function TaskTable({ tasks, loading, onRetry, onManualConfirm, on
     setMessageTask(null);
     setMessageTask(null);
   };
   };
 
 
+  const handleSendMessage = async () => {
+    if (!messageTask) return;
+    const target = getRecipientPhoneRaw(messageTask);
+    if (!target) {
+      setMessageResult('error');
+      setMessageResultText('Missing recipient phone number.');
+      return;
+    }
+    setMessageSending(true);
+    setMessageResult('idle');
+    setMessageResultText('');
+
+    try {
+      if (messageChannel === 'whatsapp') {
+        const res = await api.post('/api/whatsapp/send_no_token', {
+          chat_id: target,
+          message: messageText,
+        });
+        const ok = res.data?.code === 0;
+        setMessageResult(ok ? 'success' : 'error');
+        setMessageResultText(ok ? 'WhatsApp sent successfully.' : (res.data?.message || 'Failed to send WhatsApp.'));
+      } else {
+        const res = await api.post('/api/sms/send', {
+          send_to: target,
+          sender: getSmsSender(messageTask),
+          content: messageText,
+        });
+        const ok = res.data?.code === 0;
+        setMessageResult(ok ? 'success' : 'error');
+        setMessageResultText(ok ? 'SMS sent successfully.' : (res.data?.message || 'Failed to send SMS.'));
+      }
+    } catch (error) {
+      const fallback = messageChannel === 'whatsapp' ? 'Failed to send WhatsApp.' : 'Failed to send SMS.';
+      setMessageResult('error');
+      setMessageResultText(fallback);
+    } finally {
+      setMessageSending(false);
+    }
+  };
+
   const getRecipientName = (task: VasTask) => {
   const getRecipientName = (task: VasTask) => {
     if (!task.user_inputs) return '-';
     if (!task.user_inputs) return '-';
     const { first_name, last_name, social_media_account } = task.user_inputs;
     const { first_name, last_name, social_media_account } = task.user_inputs;
@@ -80,6 +127,13 @@ export default function TaskTable({ tasks, loading, onRetry, onManualConfirm, on
     return combined || '-';
     return combined || '-';
   };
   };
 
 
+  const getRecipientPhoneRaw = (task: VasTask) => {
+    if (!task.user_inputs) return '';
+    const code = String(task.user_inputs.phone_country_code || '').replace(/\D/g, '');
+    const rawPhone = String(task.user_inputs.phone || '').replace(/\D/g, '').replace(/^0+/, '');
+    return `${code}${rawPhone}`;
+  };
+
   const getSmsSender = (task: VasTask) => {
   const getSmsSender = (task: VasTask) => {
     return 'Visafly';
     return 'Visafly';
   };
   };
@@ -318,16 +372,26 @@ export default function TaskTable({ tasks, loading, onRetry, onManualConfirm, on
                 className="w-full border border-slate-200 rounded-lg p-3 text-sm text-slate-700 focus:ring-2 focus:ring-blue-500 outline-none"
                 className="w-full border border-slate-200 rounded-lg p-3 text-sm text-slate-700 focus:ring-2 focus:ring-blue-500 outline-none"
               />
               />
               <p className="text-xs text-slate-400">Keep it concise (about 20 words).</p>
               <p className="text-xs text-slate-400">Keep it concise (about 20 words).</p>
+              {messageResult !== 'idle' && (
+                <div className={`text-xs rounded-lg px-3 py-2 border ${
+                  messageResult === 'success'
+                    ? 'border-green-200 bg-green-50 text-green-700'
+                    : 'border-red-200 bg-red-50 text-red-700'
+                }`}>
+                  {messageResultText}
+                </div>
+              )}
             </div>
             </div>
             <div className="px-6 py-4 border-t bg-slate-50 flex justify-end gap-3">
             <div className="px-6 py-4 border-t bg-slate-50 flex justify-end gap-3">
               <button onClick={closeMessageModal} className="px-4 py-2 border border-slate-200 rounded-lg text-slate-600 text-sm hover:bg-slate-100">
               <button onClick={closeMessageModal} className="px-4 py-2 border border-slate-200 rounded-lg text-slate-600 text-sm hover:bg-slate-100">
                 Cancel
                 Cancel
               </button>
               </button>
               <button
               <button
-                onClick={closeMessageModal}
-                className="px-5 py-2 bg-slate-900 text-white rounded-lg text-sm font-semibold hover:bg-slate-800"
+                onClick={handleSendMessage}
+                disabled={messageSending}
+                className="px-5 py-2 bg-slate-900 text-white rounded-lg text-sm font-semibold hover:bg-slate-800 disabled:opacity-60"
               >
               >
-                Send
+                {messageSending ? 'Sending...' : 'Send'}
               </button>
               </button>
             </div>
             </div>
           </div>
           </div>