bmc_hub/static/js/sms.js
Christian 0831715d3a feat: add SMS service and frontend integration
- Implement SmsService class for sending SMS via CPSMS API.
- Add SMS sending functionality in the frontend with validation and user feedback.
- Create database migrations for SMS message storage and telephony features.
- Introduce telephony settings and user-specific configurations for click-to-call functionality.
- Enhance user experience with toast notifications for incoming calls and actions.
2026-02-14 02:26:29 +01:00

151 lines
5.0 KiB
JavaScript

let smsModalInstance = null;
function normalizeSmsNumber(number) {
const raw = String(number || '').trim();
if (!raw) return '';
let cleaned = raw.replace(/[^\d+]/g, '');
if (cleaned.startsWith('+')) cleaned = cleaned.slice(1);
if (cleaned.startsWith('00')) cleaned = cleaned.slice(2);
if (/^\d{8}$/.test(cleaned)) cleaned = `45${cleaned}`;
return cleaned;
}
async function sendSms(number, message, sender = null, contactId = null) {
const to = normalizeSmsNumber(number);
if (!to) {
alert('Ugyldigt mobilnummer');
return { ok: false };
}
const response = await fetch('/api/v1/sms/send', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify({ to, message, sender: sender || null, contact_id: contactId || null })
});
if (!response.ok) {
const text = await response.text();
alert('SMS fejlede: ' + text);
return { ok: false };
}
const data = await response.json();
alert('SMS sendt ✅');
return { ok: true, data };
}
function updateSmsCounter() {
const textarea = document.getElementById('smsMessageInput');
const counter = document.getElementById('smsCharCounter');
if (!textarea || !counter) return;
const len = String(textarea.value || '').length;
counter.textContent = `${len}/1530`;
counter.classList.toggle('text-danger', len > 1530);
}
function ensureSmsModal() {
const modalEl = document.getElementById('smsModal');
if (!modalEl || !window.bootstrap) return null;
if (!smsModalInstance) {
smsModalInstance = new bootstrap.Modal(modalEl);
}
return smsModalInstance;
}
async function submitSmsFromModal() {
const recipientInput = document.getElementById('smsRecipientInput');
const senderInput = document.getElementById('smsSenderInput');
const messageInput = document.getElementById('smsMessageInput');
const sendBtn = document.getElementById('smsSendBtn');
if (!recipientInput || !messageInput || !sendBtn) return;
const recipient = String(recipientInput.value || '').trim();
const message = String(messageInput.value || '').trim();
const sender = String(senderInput?.value || '').trim();
const contactIdRaw = String(recipientInput.dataset.contactId || '').trim();
const contactId = contactIdRaw ? Number(contactIdRaw) : null;
if (!recipient) {
alert('Modtager mangler');
return;
}
if (!message) {
alert('Besked må ikke være tom');
return;
}
if (message.length > 1530) {
alert('Besked er for lang (max 1530 tegn)');
return;
}
const original = sendBtn.innerHTML;
sendBtn.disabled = true;
sendBtn.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span>Sender...';
try {
const result = await sendSms(recipient, message, sender || null, contactId);
if (result.ok) {
const modal = ensureSmsModal();
if (modal) modal.hide();
messageInput.value = '';
updateSmsCounter();
}
} finally {
sendBtn.disabled = false;
sendBtn.innerHTML = original;
}
}
async function openSmsPrompt(number, label = '', contactId = null) {
const recipient = String(number || '').trim();
if (!recipient || recipient === '-') {
alert('Intet gyldigt mobilnummer');
return;
}
const modal = ensureSmsModal();
const recipientInput = document.getElementById('smsRecipientInput');
const title = document.getElementById('smsModalTitle');
const messageInput = document.getElementById('smsMessageInput');
if (modal && recipientInput && title && messageInput) {
recipientInput.value = recipient;
recipientInput.dataset.contactId = contactId ? String(contactId) : '';
title.textContent = label ? `Send SMS til ${label}` : 'Send SMS';
if (!messageInput.value) {
messageInput.value = '';
}
updateSmsCounter();
modal.show();
setTimeout(() => messageInput.focus(), 200);
return;
}
const fallbackPrefix = label ? `SMS til ${label} (${recipient})` : `SMS til ${recipient}`;
const fallbackMessage = window.prompt(`${fallbackPrefix}\n\nSkriv besked:`);
if (fallbackMessage === null) return;
if (!String(fallbackMessage).trim()) {
alert('Besked må ikke være tom');
return;
}
try {
await sendSms(recipient, String(fallbackMessage), null, contactId);
} catch (error) {
console.error('SMS send failed:', error);
alert('Kunne ikke sende SMS');
}
}
document.addEventListener('DOMContentLoaded', () => {
const messageInput = document.getElementById('smsMessageInput');
const sendBtn = document.getElementById('smsSendBtn');
if (messageInput) {
messageInput.addEventListener('input', updateSmsCounter);
updateSmsCounter();
}
if (sendBtn) {
sendBtn.addEventListener('click', submitSmsFromModal);
}
});