Files
scoreodonto.com/frontend/views/newwhats/components/ForwardModal.tsx
T
VPS 4 Builder 8ea8faa4c2 wip: inbox/agenda diversos (trabalho anterior à sessão)
Consolida WIP acumulado que não faz parte das features de hoje: melhorias do
inbox (WhatsChatDrawer, InputBar, MessageBubble, ProtocolPanel, StickerPanel,
LinkPreview, hooks, socketService, chatStore, nwClient), componentes novos
(ConversationSearch, ForwardModal, LabelManagerModal, roleMeta), AgendaPresence,
ComunicacaoInternaModal, Sidebar, GestaoEquipeView, SessionsView, appTime e o
asset chat-bg.png.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 06:08:07 +02:00

104 lines
4.9 KiB
TypeScript

import React, { useState, useMemo } from 'react';
import { createPortal } from 'react-dom';
import { X, Search, Send, Check } from 'lucide-react';
interface ForwardModalProps {
isOpen: boolean;
onClose: () => void;
chats: any[];
onForward: (toChatIds: string[]) => Promise<void> | void;
}
// Modal para escolher um ou mais chats de destino e encaminhar a mensagem selecionada.
const ForwardModal: React.FC<ForwardModalProps> = ({ isOpen, onClose, chats, onForward }) => {
const [query, setQuery] = useState('');
const [selected, setSelected] = useState<Set<string>>(new Set());
const [sending, setSending] = useState(false);
const label = (c: any) => c.displayName || c.subject || c.name || c.phone || c.remote_jid || String(c.id);
const filtered = useMemo(() => {
const q = query.trim().toLowerCase();
if (!q) return chats;
return chats.filter((c) => label(c).toLowerCase().includes(q));
}, [chats, query]);
if (!isOpen || typeof document === 'undefined') return null;
const toggle = (id: string) => {
setSelected((prev) => {
const n = new Set(prev);
n.has(id) ? n.delete(id) : n.add(id);
return n;
});
};
const handleForward = async () => {
if (selected.size === 0 || sending) return;
setSending(true);
try { await onForward(Array.from(selected)); }
finally { setSending(false); setSelected(new Set()); setQuery(''); }
};
return createPortal(
<div className="fixed inset-0 z-[9999] flex items-center justify-center bg-black/50 backdrop-blur-sm p-4" onClick={onClose}>
<div className="w-full max-w-md bg-white rounded-2xl shadow-2xl overflow-hidden flex flex-col max-h-[80vh]" onClick={(e) => e.stopPropagation()}>
<div className="flex items-center justify-between px-4 py-3 border-b border-gray-100">
<h3 className="text-[15px] font-bold text-[#111b21]">Encaminhar para</h3>
<button onClick={onClose} className="p-1 text-gray-400 hover:text-gray-700 rounded-full transition-colors"><X className="w-5 h-5" /></button>
</div>
<div className="px-4 py-2.5 border-b border-gray-100">
<div className="flex items-center gap-2 bg-[#f0f2f5] rounded-lg px-3 py-2">
<Search className="w-4 h-4 text-[#667781] shrink-0" />
<input
autoFocus
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Pesquisar conversa"
className="w-full bg-transparent text-[14px] text-[#111b21] placeholder:text-[#667781] focus:outline-none"
/>
</div>
</div>
<div className="flex-1 overflow-y-auto">
{filtered.length === 0 && (
<div className="px-4 py-6 text-center text-[13px] text-[#667781]">Nenhuma conversa encontrada.</div>
)}
{filtered.map((c) => {
const id = String(c.id);
const isSel = selected.has(id);
return (
<button
key={id}
onClick={() => toggle(id)}
className="w-full flex items-center gap-3 px-4 py-2.5 hover:bg-[#f5f6f6] transition-colors text-left"
>
<div className={`w-5 h-5 rounded-full border-2 flex items-center justify-center shrink-0 transition-colors ${isSel ? 'bg-[#00a884] border-[#00a884]' : 'border-gray-300'}`}>
{isSel && <Check className="w-3 h-3 text-white" />}
</div>
<span className="text-[14px] text-[#111b21] truncate">{label(c)}</span>
</button>
);
})}
</div>
<div className="px-4 py-3 border-t border-gray-100 flex items-center justify-between">
<span className="text-[12px] text-[#667781]">{selected.size} selecionada(s)</span>
<button
onClick={handleForward}
disabled={selected.size === 0 || sending}
className="flex items-center gap-2 bg-[#00a884] text-white text-[14px] font-bold px-4 py-2 rounded-lg disabled:opacity-40 hover:bg-[#008f6f] transition-colors"
>
<Send className="w-4 h-4" />
{sending ? 'Encaminhando…' : 'Encaminhar'}
</button>
</div>
</div>
</div>,
document.body,
);
};
export default ForwardModal;