Dashboard-Automatizase/components/QRCodeModal.tsx
Luis Erlacher 0152a2fda0 feat: add n8n API testing script for Google OAuth2 schema and existing credentials
- Implemented a bash script to test n8n API and retrieve credential schemas.
- Added types for API responses, Google Calendar, and WhatsApp instances.
- Configured Vitest for testing with React and added setup for testing-library.
2025-10-10 14:29:02 -03:00

143 lines
4.4 KiB
TypeScript

"use client";
import { useEffect } from "react";
interface QRCodeModalProps {
isOpen: boolean;
onClose: () => void;
qrCode: string | null;
instanceName: string;
loading: boolean;
error: string | null;
}
export default function QRCodeModal({
isOpen,
onClose,
qrCode,
instanceName,
loading,
error,
}: QRCodeModalProps) {
// Close on Escape key
useEffect(() => {
const handleEscape = (e: KeyboardEvent) => {
if (e.key === "Escape") onClose();
};
if (isOpen) {
document.addEventListener("keydown", handleEscape);
return () => document.removeEventListener("keydown", handleEscape);
}
}, [isOpen, onClose]);
if (!isOpen) return null;
return (
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/70">
<div className="bg-gray-800 border border-gray-700 rounded-lg max-w-md w-full p-6">
{/* Header */}
<div className="flex justify-between items-center mb-4">
<h3 className="text-xl font-semibold text-white">
Conectar WhatsApp - {instanceName}
</h3>
<button
type="button"
onClick={onClose}
className="text-gray-400 hover:text-white transition-colors"
aria-label="Fechar modal"
>
<svg
className="w-6 h-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
aria-hidden="true"
>
<title>Fechar</title>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M6 18L18 6M6 6l12 12"
/>
</svg>
</button>
</div>
{/* Content */}
<div className="space-y-4">
{loading && (
<div className="flex flex-col items-center justify-center py-8">
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-primary-500"></div>
<p className="mt-4 text-gray-400">Gerando QR Code...</p>
</div>
)}
{error && (
<div className="p-4 bg-red-900/20 border border-red-800 rounded text-center">
<p className="text-red-400">{error}</p>
<button
type="button"
onClick={onClose}
className="mt-4 px-4 py-2 bg-red-600 hover:bg-red-700 text-white rounded-md transition-colors"
>
Fechar
</button>
</div>
)}
{qrCode && !loading && !error && (
<>
{/* Instructions */}
<div className="bg-primary-900/20 border border-primary-800 rounded p-4">
<p className="text-primary-300 text-sm">
<strong>Instruções:</strong>
</p>
<ol className="mt-2 text-sm text-gray-300 list-decimal list-inside space-y-1">
<li>Abra o WhatsApp no seu celular</li>
<li>
Toque em <strong>Mais opções</strong> ou{" "}
<strong>Configurações</strong>
</li>
<li>
Toque em <strong>Aparelhos conectados</strong>
</li>
<li>
Toque em <strong>Conectar um aparelho</strong>
</li>
<li>
Aponte seu celular para esta tela para escanear o QR code
</li>
</ol>
</div>
{/* QR Code */}
<div className="flex justify-center p-4 bg-white rounded">
{/* biome-ignore lint/performance/noImgElement: QR code is dynamic base64 */}
<img
src={
qrCode.startsWith("data:")
? qrCode
: `data:image/png;base64,${qrCode}`
}
alt="QR Code"
className="w-64 h-64"
/>
</div>
{/* Close Button */}
<button
type="button"
onClick={onClose}
className="w-full px-4 py-2 bg-gray-700 hover:bg-gray-600 text-white rounded-md transition-colors"
>
Fechar
</button>
</>
)}
</div>
</div>
</div>
);
}