Skip to content

Commit 9d4f240

Browse files
author
Faxbot Agent
committed
fix(ui): add phone validation to ScriptsTests.tsx phone number inputs
- Add same phone validation logic as Send Fax tab to ScriptsTests.tsx - Update both 'Test to number' and 'To number (optional)' fields - Auto-format US numbers: 3033769234 → (303) 376-9234 - Normalize to E.164 before sending: (303) 376-9234 → +13033769234 - Add helper text and type='tel' for mobile keyboards - Prevents E.164 validation errors in all test scenarios
1 parent 3afff9b commit 9d4f240

File tree

2 files changed

+75
-7
lines changed

2 files changed

+75
-7
lines changed

.worktrees/gh-pages

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit 545b3327c71157116f9fb4bf75e795b7044fbbb3

api/admin_ui/src/components/ScriptsTests.tsx

Lines changed: 74 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,43 @@ const ConsoleBox: React.FC<{ lines: string[]; loading?: boolean; title?: string
145145

146146
const ScriptsTests: React.FC<Props> = ({ client, docsBase, readOnly = false, canSend = false }) => {
147147
const { hasTrait, outboundTraits } = useTraits();
148+
149+
// Phone number utilities - same as Send Fax tab
150+
const digitsOnly = (input: string): string => {
151+
// Strip ALL non-digit characters including hidden/zero-width chars from paste
152+
return input.replace(/\D/g, '');
153+
};
154+
155+
const formatUSPhone = (raw: string): string => {
156+
const digits = digitsOnly(raw).slice(0, 10); // Max 10 digits for US
157+
if (digits.length === 0) return '';
158+
if (digits.length <= 3) return `(${digits})`;
159+
if (digits.length <= 6) {
160+
return `(${digits.slice(0, 3)}) ${digits.slice(3)}`;
161+
}
162+
return `(${digits.slice(0, 3)}) ${digits.slice(3, 6)}-${digits.slice(6, 10)}`;
163+
};
164+
165+
const normalizeToE164 = (input: string): string => {
166+
// Handle already-formatted E.164 numbers
167+
if (input.startsWith('+')) {
168+
return '+' + digitsOnly(input);
169+
}
170+
// US numbers: convert 10 digits to +1XXXXXXXXXX
171+
const digits = digitsOnly(input);
172+
if (digits.length === 10) {
173+
return `+1${digits}`;
174+
}
175+
// 11 digits starting with 1: already has country code
176+
if (digits.length === 11 && digits.startsWith('1')) {
177+
return `+${digits}`;
178+
}
179+
// International: just prepend +
180+
if (digits.length >= 10) {
181+
return `+${digits}`;
182+
}
183+
return input; // Return as-is if can't normalize
184+
};
148185
const [error, setError] = useState<string>('');
149186
const [busyAuth, setBusyAuth] = useState<boolean>(false);
150187
const [busyInbound, setBusyInbound] = useState<boolean>(false);
@@ -211,7 +248,9 @@ const ScriptsTests: React.FC<Props> = ({ client, docsBase, readOnly = false, can
211248
pushAuth('[i] Sending test TXT');
212249
const blob = new Blob([`hello from Faxbot Admin Console — ${new Date().toISOString()}`], { type: 'text/plain' });
213250
const file = new File([blob], 'gui-smoke.txt', { type: 'text/plain' });
214-
const send = await client.sendFax(toNumber, file);
251+
// Normalize to E.164 format before sending
252+
const normalizedNumber = normalizeToE164(toNumber);
253+
const send = await client.sendFax(normalizedNumber, file);
215254
pushAuth(`[✓] Queued: ${send.id} status=${send.status}`);
216255
pushAuth('[i] Fetching status…');
217256
try {
@@ -302,7 +341,9 @@ const ScriptsTests: React.FC<Props> = ({ client, docsBase, readOnly = false, can
302341
const ab = new ArrayBuffer(bytes.byteLength); new Uint8Array(ab).set(bytes);
303342
const blob = new Blob([ab], { type: 'application/pdf' });
304343
const file = new File([blob], 'faxbot_test_image.pdf', { type: 'application/pdf' });
305-
const result = await client.sendFax(toNumber, file);
344+
// Normalize to E.164 format before sending
345+
const normalizedNumber = normalizeToE164(toNumber);
346+
const result = await client.sendFax(normalizedNumber, file);
306347
pushAuth(`[✓] Image Test queued: ${result.id} status=${result.status}`);
307348
} catch (e:any) {
308349
setError(e?.message || 'Test image fax failed to start');
@@ -316,7 +357,9 @@ const ScriptsTests: React.FC<Props> = ({ client, docsBase, readOnly = false, can
316357
const ab = new ArrayBuffer(bytes.byteLength); new Uint8Array(ab).set(bytes);
317358
const blob = new Blob([ab], { type: 'application/pdf' });
318359
const file = new File([blob], 'faxbot_test.pdf', { type: 'application/pdf' });
319-
const result = await client.sendFax(toNumber, file);
360+
// Normalize to E.164 format before sending
361+
const normalizedNumber = normalizeToE164(toNumber);
362+
const result = await client.sendFax(normalizedNumber, file);
320363
pushAuth(`[✓] PDF Test queued: ${result.id} status=${result.status}`);
321364
} catch (e:any) {
322365
setError(e?.message || 'Test PDF fax failed to start');
@@ -418,8 +461,20 @@ const ScriptsTests: React.FC<Props> = ({ client, docsBase, readOnly = false, can
418461
<ResponsiveTextField
419462
label="Test to number"
420463
value={toNumber}
421-
onChange={setToNumber}
422-
placeholder="+15551234567"
464+
onChange={(value) => {
465+
// Auto-format US numbers as user types, like Send Fax tab
466+
const digits = digitsOnly(value);
467+
if (digits.length <= 10 && !value.startsWith('+')) {
468+
// Format US numbers
469+
setToNumber(formatUSPhone(value));
470+
} else {
471+
// Keep international numbers as-is
472+
setToNumber(value);
473+
}
474+
}}
475+
placeholder="(555) 123-4567 or +15551234567"
476+
helperText="US numbers auto-format. Paste any format - we'll handle it!"
477+
type="tel"
423478
icon={<CodeIcon />}
424479
/>
425480
<Stack direction="row" spacing={1}>
@@ -479,8 +534,20 @@ const ScriptsTests: React.FC<Props> = ({ client, docsBase, readOnly = false, can
479534
<ResponsiveTextField
480535
label="To number (optional)"
481536
value={toNumber}
482-
onChange={setToNumber}
483-
placeholder="+15551234567"
537+
onChange={(value) => {
538+
// Auto-format US numbers as user types, like Send Fax tab
539+
const digits = digitsOnly(value);
540+
if (digits.length <= 10 && !value.startsWith('+')) {
541+
// Format US numbers
542+
setToNumber(formatUSPhone(value));
543+
} else {
544+
// Keep international numbers as-is
545+
setToNumber(value);
546+
}
547+
}}
548+
placeholder="(555) 123-4567 or +15551234567"
549+
helperText="US numbers auto-format. Paste any format - we'll handle it!"
550+
type="tel"
484551
/>
485552
<Stack direction="row" spacing={1}>
486553
<Button

0 commit comments

Comments
 (0)