| Server IP : 10.200.247.200 / Your IP : 216.73.217.19 Web Server : Apache System : Linux synergy-usa-sites 6.8.0-138-generic #138-Ubuntu SMP PREEMPT_DYNAMIC Fri Jul 31 22:41:49 UTC 2026 x86_64 User : jeremy ( 1001) PHP Version : 8.4.25 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/surf_sites/usworkathomesolutions.com/ |
Upload File : |
<?php
$pageTitle = 'Voice Sample | US Work At Home Solutions';
$appId = htmlspecialchars($_GET['app_id'] ?? '', ENT_QUOTES);
require_once __DIR__ . '/data/mysql.php';
$rawAppId = $db->clean($_GET['app_id'] ?? '');
$applicantRow = $db->get_results(
"SELECT first_name, last_name, email_address FROM surfcrm.potential_employees WHERE id = '$rawAppId' LIMIT 1"
);
$applicantFirstName = !empty($applicantRow) ? htmlspecialchars($applicantRow[0]->first_name, ENT_QUOTES) : '(Your Name)';
$applicantLastName = !empty($applicantRow) ? htmlspecialchars($applicantRow[0]->last_name, ENT_QUOTES) : '';
$applicantFullName = trim($applicantFirstName . ' ' . $applicantLastName);
$applicantEmail = !empty($applicantRow) ? htmlspecialchars($applicantRow[0]->email_address, ENT_QUOTES) : '';
?>
<?php require __DIR__ . '/includes/header.php'; ?>
<style>
.recording-hero {
background: linear-gradient(180deg, #ffffff 0%, #f6faff 100%);
border-top: 1px solid rgba(20,58,99,.06);
}
.recording-step {
background: #fff;
border: 1px solid rgba(20,58,99,.08);
border-radius: 18px;
box-shadow: var(--shadow);
padding: 22px;
max-width: 820px;
margin: 0 auto;
}
.step-label {
display: inline-block;
padding: 7px 12px;
border-radius: 999px;
background: var(--blue-soft);
color: var(--navy);
font-size: 13px;
font-weight: 800;
margin-bottom: 10px;
}
.recording-step h3 {
margin: 0 0 8px;
color: var(--navy);
font-size: 24px;
font-weight: 800;
}
.script-box {
background: #eef7ff;
border: 1px solid #cfe0f2;
border-radius: 16px;
padding: 16px;
color: #36536d;
font-size: 16px;
line-height: 1.6;
}
.record-controls {
display: grid;
gap: 10px;
margin-top: 12px;
}
.record-btn {
font-size: 18px;
min-height: 58px;
border-radius: 14px;
font-weight: 800;
}
.timer {
text-align: center;
font-weight: 800;
color: var(--navy);
font-size: 22px;
}
.meter {
height: 10px;
border-radius: 999px;
background: #e6eef8;
overflow: hidden;
}
.meter-bar {
height: 100%;
width: 0%;
background: linear-gradient(90deg, #2f80ed, #1f9d6a);
transition: width 0.08s linear;
}
.mic-status {
text-align: center;
font-size: 13px;
color: var(--muted);
font-weight: 700;
}
.callout-strong {
color: #b42318;
font-weight: 800;
}
.big-number {
font-size: 38px;
font-weight: 800;
color: #c62828;
line-height: 1.1;
margin: 8px 0 4px;
}
.collapse-toggle {
margin-top: 16px;
color: var(--navy);
font-weight: 800;
font-size: 14px;
background: none;
border: none;
padding: 0;
cursor: pointer;
}
.details-collapse { margin-top: 18px; }
.upload-dropzone {
border: 2px dashed #c9d6e6;
border-radius: 18px;
background: #f8fbff;
padding: 22px;
text-align: center;
color: var(--muted);
}
.upload-icon {
width: 56px;
height: 56px;
border-radius: 999px;
background: var(--blue-soft);
color: var(--navy);
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 24px;
font-weight: 800;
margin-bottom: 10px;
}
.or-divider {
display: flex;
align-items: center;
gap: 10px;
color: var(--muted);
font-size: 13px;
font-weight: 800;
text-transform: uppercase;
letter-spacing: .4px;
margin: 18px 0;
}
.or-divider:before,
.or-divider:after {
content: '';
height: 1px;
background: var(--line);
flex: 1;
}
.playback-area {
margin-top: 14px;
padding: 16px;
background: #f8fbff;
border: 1px solid var(--line);
border-radius: 16px;
}
.playback-area audio {
width: 100%;
border-radius: 12px;
}
.recording-indicator {
display: inline-flex;
align-items: center;
gap: 8px;
color: #c62828;
font-weight: 800;
font-size: 15px;
}
.recording-indicator .dot {
width: 12px;
height: 12px;
border-radius: 50%;
background: #c62828;
animation: pulse-dot 1s infinite;
}
@keyframes pulse-dot {
0%, 100% { opacity: 1; }
50% { opacity: 0.3; }
}
</style>
<section class="section recording-hero">
<div class="container-modern">
<div class="stepper">
<span class="stepper-item done">1. Application</span>
<span class="stepper-item active">2. Voice Sample</span>
<span class="stepper-item">3. Confirmation</span>
</div>
<!-- ── Email Verification Gate ──────────────────────────────────── -->
<div id="verifySection" style="max-width:820px; margin:0 auto;">
<div class="application-header">
<h2>Verify your email to continue</h2>
<p>We just sent a one-time verification code to your email address.</p>
</div>
<div id="verifyError" class="error-box" style="display:none; max-width:820px; margin:0 auto 18px;"></div>
<div id="verifyNotice" class="helper-box" style="display:none; max-width:820px; margin:0 auto 18px; background:#e8f5ee; border-color:#b8dfc7; color:#1f5c3a;"></div>
<div class="recording-step" style="text-align:center;">
<div class="step-label">Email Verification Required</div>
<h3 style="margin-bottom:4px;">Check your inbox</h3>
<p class="muted-block" style="margin-top:0; font-size:16px; max-width:560px; margin-left:auto; margin-right:auto;">
We sent a verification code to the email address you provided. Please enter it below to continue your application.
</p>
<div class="helper-box" style="text-align:left; margin-top:18px;">
<div style="display:flex; justify-content:space-between; align-items:center; gap:12px; flex-wrap:wrap;">
<div style="min-width:0; flex:1;">
<div style="font-size:13px; color:var(--muted); font-weight:700; text-transform:uppercase; letter-spacing:.4px;">Code sent to</div>
<div id="sentToEmail" style="font-weight:800; color:var(--navy); font-size:16px; word-break:break-all;"><?= $applicantEmail ?: '(no email on file)' ?></div>
</div>
<button type="button" class="btn-secondary-modern" style="padding:8px 14px; font-size:14px; white-space:nowrap;" id="btnEditEmail" onclick="toggleEmailEdit()">Change / Resend</button>
</div>
<div id="emailEditPanel" style="display:none; margin-top:14px; padding-top:14px; border-top:1px solid var(--line);">
<div class="field">
<label for="newEmail" style="text-align:left;">Email address</label>
<input type="email" id="newEmail" name="new_email" value="<?= $applicantEmail ?>" placeholder="you@example.com">
<div class="field-note">Update your address if needed, then resend. We’ll send a fresh code.</div>
</div>
<div style="display:grid; grid-template-columns:1fr 1fr; gap:10px; margin-top:10px;">
<button type="button" class="btn-secondary-modern" onclick="toggleEmailEdit()">Cancel</button>
<button type="button" class="btn-primary-modern" id="btnResend" onclick="resendCode()">Resend Code</button>
</div>
</div>
</div>
<div class="helper-box" style="text-align:left; margin-top:12px;">
<strong style="color:var(--navy);">Don’t see the email?</strong>
<ul style="margin:8px 0 0; padding-left:20px; color:var(--muted); font-size:15px;">
<li>Check your <strong>spam</strong> or <strong>junk</strong> folder.</li>
<li>The email is from <strong>NoReply@usworkathomesolutions.com</strong>.</li>
<li>It may take a minute or two to arrive.</li>
<li>Make sure the email address above is correct — tap <strong>Change / Resend</strong> to fix it.</li>
</ul>
</div>
<div style="max-width:400px; margin:24px auto 0;">
<div class="field">
<label for="verifyCode" style="text-align:left;">Verification Code</label>
<input type="text" id="verifyCode" name="verify_code" placeholder="Enter your 8-character code" maxlength="8" style="text-align:center; font-size:22px; font-weight:800; letter-spacing:4px; text-transform:uppercase;">
</div>
<div class="btn-row" style="margin-top:14px;">
<button type="button" class="btn-primary-modern" id="btnVerify" style="width:100%;" onclick="verifyCode()">Verify Email</button>
</div>
</div>
</div>
</div>
<!-- ── Voice Sample Section (hidden until verified) ──────────────── -->
<div id="voiceSection" style="display:none;">
<div class="application-header">
<h2>Step 2: Submit your required voice sample</h2>
<p>Almost done. This usually takes 1–2 minutes and is required to complete the application.</p>
</div>
<div id="voiceError" class="error-box" style="display:none; max-width:820px; margin:0 auto 18px;"></div>
<div class="recording-step">
<div class="step-label">Required final step</div>
<h3>Record your voice sample</h3>
<p class="muted-block" style="margin-top:0; font-size:16px;">Tap <strong>Start Recording</strong>, read the short script below, then tap <strong>Stop</strong>. You can listen to your recording and re-record if needed before submitting.</p>
<div class="subsection-title">Quick example of what we're looking for</div>
<div class="helper-box">
<div style="font-weight:800; color:var(--navy); margin-bottom:8px;">Sample call (short)</div>
<audio controls style="width:100%; border-radius:12px;">
<source src="/archive/applications/samples/2 - Program Overview - Good - 01 - Jason.mp3" type="audio/mpeg">
</audio>
<div class="field-note" style="margin-top:8px;">This is a short example so you can hear tone, pace, and clarity. You do not need to sound perfect.</div>
</div>
<div class="subsection-title" id="scriptSection">Read this short script while recording</div>
<div class="script-box">
<strong>Hi, this is <?= $applicantFullName ?>, are you familiar with grants</strong> and how they work? Okay, then you know that <strong>grants are monies awarded to you that you don't have to pay back.</strong> Usually John the hardest part of applying for a grant is <strong>finding the applications.</strong> We have a team of grant researchers who <strong>track down the free-money grants for you.</strong> They update our site with the newest applications as they become available. <strong>Once you're in our system,</strong> John, we give you a user name and password so you can log in to see those applications and start applying for grants immediately. <strong>The first thing I'll do to get you started is send you an email.</strong>
</div>
<!-- Mic meter -->
<div style="margin-top:16px;">
<div class="meter">
<div class="meter-bar" id="meterBar"></div>
</div>
<div class="mic-status" id="micStatus">Mic inactive</div>
</div>
<!-- Recording controls -->
<div class="record-controls">
<div class="timer" id="timer">00:00</div>
<div id="stateIdle">
<div class="helper-box" style="text-align:left; margin-bottom:12px;">
<strong style="color:var(--navy);">Before you tap Start:</strong>
<ul style="margin:8px 0 0; padding-left:20px; color:var(--muted); font-size:15px;">
<li>When prompted, select <strong>Allow</strong> to let this page use your microphone.</li>
<li>On iPhone/iPad, tap <strong>Allow</strong> in Safari’s popup. On Android/Chrome, tap <strong>Allow</strong> at the top of the screen.</li>
<li>If you don’t see a prompt, check the address bar for a blocked-mic icon and switch it to <strong>Allow</strong>, then tap Start again.</li>
<li>Using headphones? Make sure they have a built-in mic, or unplug them to use your device’s mic.</li>
</ul>
</div>
<button type="button" class="btn-primary-modern record-btn" style="width:100%;" id="btnStart">
Start Recording
</button>
</div>
<div id="stateRecording" style="display:none;">
<div style="text-align:center; margin-bottom:10px;">
<span class="recording-indicator"><span class="dot"></span> Recording...</span>
</div>
<button type="button" class="btn-secondary-modern record-btn" style="width:100%; border-color:#c62828; color:#c62828;" id="btnStop">
Stop Recording
</button>
</div>
<div id="stateReview" style="display:none;">
<div class="playback-area">
<div style="font-weight:800; color:var(--navy); margin-bottom:8px;">Your recording:</div>
<audio id="playbackAudio" controls style="width:100%; border-radius:12px;"></audio>
</div>
<div style="display:grid; grid-template-columns:1fr 1fr; gap:10px; margin-top:12px;">
<button type="button" class="btn-secondary-modern record-btn" id="btnReRecord">
Re-record
</button>
<button type="button" class="btn-primary-modern record-btn" id="btnSubmit">
Submit Voice Sample
</button>
</div>
</div>
<div id="stateSubmitting" style="display:none;">
<button type="button" class="btn-primary-modern record-btn" style="width:100%; opacity:.7;" disabled>
Submitting...
</button>
</div>
</div>
<div class="helper-box" style="margin-top:18px;">
<div class="callout-strong">Your application is not complete until you submit your voice sample.</div>
You do not need to sound perfect — we just want to hear your speaking voice and clarity.
</div>
<button id="altToggleBtn" type="button" class="collapse-toggle" onclick="toggleAltOptions()">Having trouble? Use another option</button>
<div id="altOptions" class="details-collapse" style="display:none;">
<div class="divider-modern"></div>
<div class="subsection-title">Option 2: Call in your voicemail</div>
<div class="helper-box">
<div class="big-number">+1 (888) 887-5758</div>
<div class="field-note">Call, say your name and callback number first, then read the script.</div>
</div>
<div class="quick-fields">
<div class="field full-width">
<label for="call_from_phone">What phone number did you call from?</label>
<input type="tel" id="call_from_phone" name="call_from_phone" placeholder="Enter the number you used to call">
</div>
</div>
<div class="btn-row">
<button type="button" class="btn-primary-modern" id="btnSubmitPhone" onclick="submitPhoneOption()">Submit Phone Option</button>
</div>
<div class="or-divider">or</div>
<div class="subsection-title">Option 3: Upload recording</div>
<div class="upload-dropzone" id="uploadDropzone">
<div class="upload-icon">↑</div>
<div style="font-weight:800; color:var(--navy); font-size:18px; margin-bottom:6px;">Upload your recording</div>
<input type="file" id="fileInput" accept="audio/*" style="display:none;">
<button type="button" class="btn-secondary-modern" onclick="document.getElementById('fileInput').click()">Choose Audio File</button>
<div id="fileName" class="field-note" style="margin-top:8px;"></div>
</div>
<div style="margin-top:12px;">
<div class="btn-row">
<button type="button" class="btn-primary-modern" id="btnUploadSubmit" style="display:none;" onclick="submitUploadOption()">Submit Uploaded File</button>
</div>
</div>
</div>
</div>
</div><!-- /voiceSection -->
</div>
</section>
<script>
(function() {
var appId = <?= json_encode($appId) ?>;
// ── Email Verification ──────────────────────────────────────────
var verifySection = document.getElementById('verifySection');
var voiceSection = document.getElementById('voiceSection');
var verifyError = document.getElementById('verifyError');
var verifyNotice = document.getElementById('verifyNotice');
var verifyInput = document.getElementById('verifyCode');
var sentToEmail = document.getElementById('sentToEmail');
var emailEditPanel = document.getElementById('emailEditPanel');
var newEmailInput = document.getElementById('newEmail');
window.toggleEmailEdit = function() {
var open = emailEditPanel.style.display === 'block';
emailEditPanel.style.display = open ? 'none' : 'block';
if (!open) {
newEmailInput.focus();
newEmailInput.select();
}
};
function showNotice(msg) {
verifyNotice.textContent = msg;
verifyNotice.style.display = 'block';
verifyError.style.display = 'none';
}
window.resendCode = function() {
var email = (newEmailInput.value || '').trim();
if (!email || email.indexOf('@') === -1) {
verifyError.textContent = 'Please enter a valid email address.';
verifyError.style.display = 'block';
return;
}
verifyError.style.display = 'none';
verifyNotice.style.display = 'none';
var btn = document.getElementById('btnResend');
btn.disabled = true;
btn.textContent = 'Sending...';
var formData = new FormData();
formData.append('application_id', appId);
formData.append('email', email);
fetch(BASE_URL + '/api/resend-code.php', {
method: 'POST',
body: formData
})
.then(function(res) { return res.json(); })
.then(function(data) {
btn.disabled = false;
btn.textContent = 'Resend Code';
if (data.success) {
sentToEmail.textContent = data.email || email;
emailEditPanel.style.display = 'none';
showNotice('A new verification code has been sent to ' + (data.email || email) + '. Please check your inbox.');
verifyInput.value = '';
verifyInput.focus();
} else {
verifyError.textContent = data.message || 'Could not resend the code. Please try again.';
verifyError.style.display = 'block';
}
})
.catch(function() {
btn.disabled = false;
btn.textContent = 'Resend Code';
verifyError.textContent = 'Network error. Please check your connection and try again.';
verifyError.style.display = 'block';
});
};
// Allow pressing Enter in the code input to verify
verifyInput.addEventListener('keydown', function(e) {
if (e.key === 'Enter') {
e.preventDefault();
verifyCode();
}
});
window.verifyCode = function() {
var code = verifyInput.value.trim();
if (!code) {
verifyError.textContent = 'Please enter the verification code from your email.';
verifyError.style.display = 'block';
return;
}
verifyError.style.display = 'none';
var btn = document.getElementById('btnVerify');
btn.disabled = true;
btn.textContent = 'Verifying...';
var formData = new FormData();
formData.append('application_id', appId);
formData.append('code', code);
fetch(BASE_URL + '/api/verify-code.php', {
method: 'POST',
body: formData
})
.then(function(res) { return res.json(); })
.then(function(data) {
if (data.success) {
verifySection.style.display = 'none';
voiceSection.style.display = 'block';
} else {
verifyError.textContent = data.message || 'Invalid code. Please try again.';
verifyError.style.display = 'block';
btn.disabled = false;
btn.textContent = 'Verify Email';
}
})
.catch(function() {
verifyError.textContent = 'Network error. Please check your connection and try again.';
verifyError.style.display = 'block';
btn.disabled = false;
btn.textContent = 'Verify Email';
});
};
// State management
var mediaRecorder = null;
var audioChunks = [];
var recordedBlob = null;
var audioStream = null;
var audioCtx = null;
var analyser = null;
var timerInterval = null;
var startTime = 0;
// Detect supported MIME type (Safari doesn't support webm)
var mimeType = '';
var fileExt = 'webm';
if (typeof MediaRecorder !== 'undefined') {
if (MediaRecorder.isTypeSupported('audio/webm')) {
mimeType = 'audio/webm';
fileExt = 'webm';
} else if (MediaRecorder.isTypeSupported('audio/mp4')) {
mimeType = 'audio/mp4';
fileExt = 'mp4';
}
// else let browser pick default
}
var stateIdle = document.getElementById('stateIdle');
var stateRecording = document.getElementById('stateRecording');
var stateReview = document.getElementById('stateReview');
var stateSubmitting = document.getElementById('stateSubmitting');
var btnStart = document.getElementById('btnStart');
var btnStop = document.getElementById('btnStop');
var btnReRecord = document.getElementById('btnReRecord');
var btnSubmit = document.getElementById('btnSubmit');
var playbackAudio = document.getElementById('playbackAudio');
var meterBar = document.getElementById('meterBar');
var micStatus = document.getElementById('micStatus');
var timerEl = document.getElementById('timer');
var errorBox = document.getElementById('voiceError');
function showState(state) {
stateIdle.style.display = state === 'idle' ? 'block' : 'none';
stateRecording.style.display = state === 'recording' ? 'block' : 'none';
stateReview.style.display = state === 'review' ? 'block' : 'none';
stateSubmitting.style.display = state === 'submitting' ? 'block' : 'none';
}
function showError(msg) {
errorBox.textContent = msg;
errorBox.style.display = 'block';
window.scrollTo({ top: 0, behavior: 'smooth' });
}
function hideError() {
errorBox.style.display = 'none';
}
function formatTime(seconds) {
var m = Math.floor(seconds / 60);
var s = seconds % 60;
return (m < 10 ? '0' : '') + m + ':' + (s < 10 ? '0' : '') + s;
}
function startTimer() {
startTime = Date.now();
timerEl.textContent = '00:00';
timerInterval = setInterval(function() {
var elapsed = Math.floor((Date.now() - startTime) / 1000);
timerEl.textContent = formatTime(elapsed);
}, 1000);
}
function stopTimer() {
if (timerInterval) clearInterval(timerInterval);
}
// Mic level meter using Web Audio API
function startMeter(stream) {
if (!audioCtx) {
audioCtx = new (window.AudioContext || window.webkitAudioContext)();
}
// iOS Safari suspends AudioContext until resumed from a user gesture
if (audioCtx.state === 'suspended') {
audioCtx.resume();
}
var source = audioCtx.createMediaStreamSource(stream);
analyser = audioCtx.createAnalyser();
analyser.fftSize = 256;
source.connect(analyser);
var dataArray = new Uint8Array(analyser.frequencyBinCount);
function draw() {
if (!analyser) return;
analyser.getByteFrequencyData(dataArray);
var sum = 0;
for (var i = 0; i < dataArray.length; i++) {
sum += dataArray[i];
}
var avg = sum / dataArray.length;
var level = Math.min(100, Math.round((avg / 128) * 100));
meterBar.style.width = level + '%';
requestAnimationFrame(draw);
}
draw();
micStatus.textContent = 'Listening...';
}
function stopMeter() {
analyser = null;
meterBar.style.width = '0%';
micStatus.textContent = 'Mic inactive';
}
// Acquire mic stream once up front so recording starts instantly
function acquireMic() {
return navigator.mediaDevices.getUserMedia({ audio: true })
.then(function(stream) {
audioStream = stream;
startMeter(stream);
micStatus.textContent = 'Mic ready';
})
.catch(function() {
showError('Microphone access is required. Please allow microphone permissions and try again.');
});
}
// Don't auto-acquire mic — iOS Safari requires a user gesture for getUserMedia
// Start recording
btnStart.addEventListener('click', function() {
document.getElementById('scriptSection').scrollIntoView({ behavior: 'smooth', block: 'start' });
hideError();
audioChunks = [];
recordedBlob = null;
if (!audioStream) {
// Mic not yet acquired (e.g. user denied then retries)
acquireMic().then(function() { if (audioStream) beginRecording(); });
return;
}
beginRecording();
});
function beginRecording() {
var recorderOptions = {};
if (mimeType) recorderOptions.mimeType = mimeType;
mediaRecorder = new MediaRecorder(audioStream, recorderOptions);
mediaRecorder.ondataavailable = function(e) {
if (e.data.size > 0) {
audioChunks.push(e.data);
}
};
mediaRecorder.onstop = function() {
var blobType = mediaRecorder.mimeType || mimeType || 'audio/webm';
recordedBlob = new Blob(audioChunks, { type: blobType });
var url = URL.createObjectURL(recordedBlob);
playbackAudio.src = url;
stopMeter();
stopTimer();
showState('review');
};
// Use timeslice to capture data every 250ms for reliable recording
// Note: Safari may ignore timeslice — data arrives in onstop instead, which is fine
mediaRecorder.start(250);
startTimer();
showState('recording');
}
// Stop recording
btnStop.addEventListener('click', function() {
if (mediaRecorder && mediaRecorder.state === 'recording') {
mediaRecorder.stop();
}
});
// Re-record
btnReRecord.addEventListener('click', function() {
recordedBlob = null;
playbackAudio.src = '';
timerEl.textContent = '00:00';
// Re-acquire mic if stream ended
if (!audioStream || !audioStream.active) {
acquireMic();
} else {
startMeter(audioStream);
}
showState('idle');
});
// Submit voice sample
btnSubmit.addEventListener('click', function() {
if (!recordedBlob) return;
hideError();
showState('submitting');
var formData = new FormData();
formData.append('application_id', appId);
formData.append('voice_sample', recordedBlob, 'voice-sample.' + fileExt);
formData.append('method', 'browser_recording');
fetch(BASE_URL + '/api/submit-voice.php', {
method: 'POST',
body: formData
})
.then(function(res) { return res.json(); })
.then(function(data) {
if (data.success) {
window.location.href = BASE_URL + '/confirmation.php?app_id=' + encodeURIComponent(appId);
} else {
showError(data.message || 'Failed to submit voice sample. Please try again.');
showState('review');
}
})
.catch(function() {
showError('Network error. Please check your connection and try again.');
showState('review');
});
});
// File upload
var fileInput = document.getElementById('fileInput');
var fileName = document.getElementById('fileName');
var btnUploadSubmit = document.getElementById('btnUploadSubmit');
fileInput.addEventListener('change', function() {
if (fileInput.files.length > 0) {
fileName.textContent = 'Selected: ' + fileInput.files[0].name;
btnUploadSubmit.style.display = 'inline-flex';
}
});
// Submit phone option
window.submitPhoneOption = function() {
var phoneEl = document.getElementById('call_from_phone');
if (!phoneEl.value.trim()) {
showError('Please enter the phone number you called from.');
return;
}
hideError();
var btn = document.getElementById('btnSubmitPhone');
btn.disabled = true;
btn.textContent = 'Submitting...';
var formData = new FormData();
formData.append('application_id', appId);
formData.append('method', 'phone_call');
formData.append('call_from_phone', phoneEl.value.trim());
fetch(BASE_URL + '/api/submit-voice.php', {
method: 'POST',
body: formData
})
.then(function(res) { return res.json(); })
.then(function(data) {
if (data.success) {
window.location.href = BASE_URL + '/confirmation.php?app_id=' + encodeURIComponent(appId);
} else {
showError(data.message || 'Something went wrong.');
btn.disabled = false;
btn.textContent = 'Submit Phone Option';
}
})
.catch(function() {
showError('Network error.');
btn.disabled = false;
btn.textContent = 'Submit Phone Option';
});
};
// Submit upload option
window.submitUploadOption = function() {
if (!fileInput.files.length) {
showError('Please choose an audio file first.');
return;
}
hideError();
btnUploadSubmit.disabled = true;
btnUploadSubmit.textContent = 'Submitting...';
var formData = new FormData();
formData.append('application_id', appId);
formData.append('method', 'file_upload');
formData.append('voice_sample', fileInput.files[0]);
fetch(BASE_URL + '/api/submit-voice.php', {
method: 'POST',
body: formData
})
.then(function(res) { return res.json(); })
.then(function(data) {
if (data.success) {
window.location.href = BASE_URL + '/confirmation.php?app_id=' + encodeURIComponent(appId);
} else {
showError(data.message || 'Something went wrong.');
btnUploadSubmit.disabled = false;
btnUploadSubmit.textContent = 'Submit Uploaded File';
}
})
.catch(function() {
showError('Network error.');
btnUploadSubmit.disabled = false;
btnUploadSubmit.textContent = 'Submit Uploaded File';
});
};
// Alt options toggle
window.toggleAltOptions = function() {
var el = document.getElementById('altOptions');
var btn = document.getElementById('altToggleBtn');
if (!el || !btn) return;
var open = el.style.display === 'block';
el.style.display = open ? 'none' : 'block';
btn.textContent = open ? 'Having trouble? Use another option' : 'Hide other options';
};
})();
</script>
<?php require __DIR__ . '/includes/footer.php'; ?>