106 lines
4.7 KiB
JavaScript
106 lines
4.7 KiB
JavaScript
import { useState } from 'react';
|
|
import apiClient from '../api/client';
|
|
|
|
export default function TestSmsModal({ businessId, template, onClose }) {
|
|
const [toNumber, setToNumber] = useState('');
|
|
const [sending, setSending] = useState(false);
|
|
const [result, setResult] = useState(null);
|
|
const [error, setError] = useState('');
|
|
|
|
async function handleSend(e) {
|
|
e.preventDefault();
|
|
if (!toNumber.trim()) return;
|
|
setSending(true);
|
|
setError('');
|
|
setResult(null);
|
|
try {
|
|
const res = await apiClient.post(
|
|
`/api/businesses/${businessId}/templates/${template.eventSlug}/test`,
|
|
{ toNumber: toNumber.trim() }
|
|
);
|
|
setResult(res.data);
|
|
} catch (err) {
|
|
setError(err.response?.data?.error || err.response?.data?.details || 'Failed to send test SMS');
|
|
} finally {
|
|
setSending(false);
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div className="fixed inset-0 z-50 flex items-center justify-center bg-gray-900/50 backdrop-blur-sm">
|
|
<div className="bg-white border border-gray-200 rounded-xl p-8 w-full max-w-md shadow-xl">
|
|
<div className="w-12 h-12 rounded-full bg-green-50 flex items-center justify-center mx-auto mb-4">
|
|
<span className="text-xl">📱</span>
|
|
</div>
|
|
<h3 className="text-lg font-bold text-gray-900 text-center mb-1">Test SMS</h3>
|
|
<p className="text-sm text-gray-500 text-center mb-6">
|
|
Enter a phone number to send a real test SMS for <span className="font-semibold text-gray-800 capitalize">{template.eventLabel || template.eventSlug.replace(/_/g, ' ')}</span>
|
|
</p>
|
|
|
|
{!result ? (
|
|
<form onSubmit={handleSend} className="space-y-4">
|
|
{error && (
|
|
<div className="px-4 py-2.5 rounded-md bg-red-50 border border-red-200 text-red-700 text-sm font-medium">
|
|
{error}
|
|
</div>
|
|
)}
|
|
|
|
<div>
|
|
<label className="block text-sm font-semibold text-gray-700 mb-1.5">Phone Number</label>
|
|
<input
|
|
type="tel"
|
|
value={toNumber}
|
|
onChange={e => setToNumber(e.target.value)}
|
|
placeholder="e.g. 919876543210 (with country code)"
|
|
className="w-full px-4 py-2.5 rounded-lg bg-gray-50 border border-gray-300 font-mono text-gray-900 placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-indigo-600 text-sm"
|
|
autoFocus
|
|
required
|
|
/>
|
|
<p className="text-xs text-gray-400 mt-1.5 font-medium">Include country code without +. Not stored.</p>
|
|
</div>
|
|
|
|
<div className="flex gap-3 pt-2">
|
|
<button
|
|
type="button"
|
|
onClick={onClose}
|
|
disabled={sending}
|
|
className="flex-1 py-2.5 rounded-lg border border-gray-300 text-gray-700 hover:bg-gray-50 text-sm font-medium transition disabled:opacity-50"
|
|
>
|
|
Cancel
|
|
</button>
|
|
<button
|
|
type="submit"
|
|
disabled={sending || !toNumber.trim()}
|
|
className="flex-1 py-2.5 rounded-lg bg-green-600 hover:bg-green-700 text-white text-sm font-semibold transition shadow-sm disabled:opacity-50 flex items-center justify-center gap-2"
|
|
>
|
|
{sending ? <><span className="w-4 h-4 border-2 border-white/30 border-t-white rounded-full animate-spin" /> Sending…</> : 'Send Test SMS'}
|
|
</button>
|
|
</div>
|
|
</form>
|
|
) : (
|
|
<div className="space-y-4">
|
|
<div className={`px-4 py-3 rounded-lg border text-sm font-medium ${result.success ? 'bg-green-50 border-green-200 text-green-800' : 'bg-red-50 border-red-200 text-red-800'}`}>
|
|
{result.success ? '✓ SMS sent successfully!' : '✗ SMS send failed'}
|
|
{result.statusCode && <span className="ml-2 opacity-60">HTTP {result.statusCode}</span>}
|
|
</div>
|
|
{result.response && (
|
|
<div>
|
|
<label className="block text-xs font-bold text-gray-500 uppercase tracking-wider mb-2">Provider Response</label>
|
|
<pre className="p-3 bg-gray-50 border border-gray-200 rounded-lg text-xs font-mono text-gray-700 overflow-x-auto whitespace-pre-wrap break-all">
|
|
{typeof result.response === 'string' ? result.response : JSON.stringify(result.response, null, 2)}
|
|
</pre>
|
|
</div>
|
|
)}
|
|
<button
|
|
onClick={onClose}
|
|
className="w-full py-2.5 rounded-lg bg-gray-900 hover:bg-gray-800 text-white text-sm font-semibold transition"
|
|
>
|
|
Close
|
|
</button>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|