File size: 6,011 Bytes
6aecd8c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
// frontend/src/App.jsx
import { useState, useEffect, useRef } from 'react';
import { io } from 'socket.io-client';
import './App.css';
function App() {
const [phoneNumber, setPhoneNumber] = useState('');
const [status, setStatus] = useState('');
const [pairingCode, setPairingCode] = useState('');
const [isConnecting, setIsConnecting] = useState(false);
const [logs, setLogs] = useState([]);
const socketRef = useRef(null);
useEffect(() => {
// Initialize socket connection
const socketUrl = window.location.origin;
socketRef.current = io(socketUrl, {
autoConnect: true,
reconnection: true,
reconnectionDelay: 1000,
reconnectionAttempts: 5
});
const socket = socketRef.current;
socket.on('connect', () => {
addLog('β
Connected to server', 'success');
});
socket.on('disconnect', () => {
addLog('β Disconnected from server', 'error');
setIsConnecting(false);
});
socket.on('status', (data) => {
setStatus(data.message);
addLog(`βΉοΈ ${data.message}`, 'info');
});
socket.on('pairing-code', (data) => {
setPairingCode(data.code);
setStatus('Pairing code generated successfully!');
addLog(`π Pairing Code: ${data.code}`, 'success');
});
socket.on('success', (data) => {
setStatus(data.message);
addLog(`β
${data.message}`, 'success');
setIsConnecting(false);
// Reset after 3 seconds
setTimeout(() => {
resetForm();
}, 3000);
});
socket.on('error', (data) => {
setStatus(`Error: ${data.message}`);
addLog(`β ${data.message}`, 'error');
setIsConnecting(false);
setPairingCode('');
});
return () => {
socket.disconnect();
};
}, []);
const addLog = (message, type = 'info') => {
const timestamp = new Date().toLocaleTimeString();
setLogs(prev => [...prev, { message, type, timestamp }]);
};
const resetForm = () => {
setPhoneNumber('');
setPairingCode('');
setStatus('');
setIsConnecting(false);
};
const handleSubmit = (e) => {
e.preventDefault();
if (!phoneNumber.trim()) {
setStatus('Phone number cannot be empty!');
addLog('β Phone number cannot be empty', 'error');
return;
}
const cleanNumber = phoneNumber.replace(/[^\d]/g, '');
if (cleanNumber.length < 10 || cleanNumber.length > 15) {
setStatus('Invalid phone number! Must be 10-15 digits');
addLog('β Invalid phone number format', 'error');
return;
}
if (cleanNumber.startsWith('0')) {
setStatus('Phone number must include country code (e.g., 1, 44, 62, 91)');
addLog('β Country code required', 'error');
return;
}
setIsConnecting(true);
setPairingCode('');
setStatus('Starting pairing process...');
setLogs([]);
addLog('π Initiating connection...', 'info');
socketRef.current.emit('start-pairing', { phoneNumber: cleanNumber });
};
const handlePhoneChange = (e) => {
const value = e.target.value.replace(/[^\d+]/g, '');
setPhoneNumber(value);
};
const copyCode = () => {
navigator.clipboard.writeText(pairingCode);
addLog('π Pairing code copied!', 'success');
};
return (
<div className="container">
<div className="card">
<div className="header">
<h1>π€ WA Pairing Service</h1>
<p>Get your WhatsApp bot session easily</p>
</div>
<form onSubmit={handleSubmit} className="form">
<div className="input-group">
<label htmlFor="phone">WhatsApp Bot Number</label>
<input
type="text"
id="phone"
value={phoneNumber}
onChange={handlePhoneChange}
placeholder="12025551234 (with country code)"
disabled={isConnecting}
maxLength={16}
className="input"
/>
<small>Include country code (e.g., 1 for US, 44 for UK, 62 for ID, 91 for IN)</small>
</div>
<button
type="submit"
disabled={isConnecting}
className={`button ${isConnecting ? 'loading' : ''}`}
>
{isConnecting ? 'β³ Processing...' : 'π Start Pairing'}
</button>
</form>
{pairingCode && (
<div className="pairing-code">
<h3>Pairing Code</h3>
<div className="code-display">
<span className="code">{pairingCode}</span>
<button onClick={copyCode} className="copy-btn" title="Copy">
π
</button>
</div>
<div className="instructions">
<p>Next steps:</p>
<ol>
<li>Open WhatsApp on your phone</li>
<li>Go to <strong>Linked Devices</strong></li>
<li>Enter the pairing code above</li>
<li>Wait for creds.json to be sent</li>
</ol>
</div>
</div>
)}
{status && (
<div className={`status ${status.includes('Error') || status.includes('Gagal') ? 'error' : 'success'}`}>
{status}
</div>
)}
{logs.length > 0 && (
<div className="logs">
<h3>π Activity Log</h3>
<div className="log-container">
{logs.map((log, index) => (
<div key={index} className={`log-entry ${log.type}`}>
<span className="log-time">{log.timestamp}</span>
<span className="log-message">{log.message}</span>
</div>
))}
</div>
</div>
)}
<div className="footer">
<p>π Privacy guaranteed - Sessions auto-deleted after completion</p>
<p>β‘ Powered by Baileys 6.7.20</p>
</div>
</div>
</div>
);
}
export default App; |