Files
orderPRO/public/assets/js/modules/sms-template-picker.js
Jacek Pyziak 522c94a434 feat(124): sms templates CRUD + order picker
- Nowa tabela sms_templates (name + body + is_active) + minimalny CRUD.
- /settings/sms-templates: lista + formularz z paleta zmiennych (pill chips).
- Wydzielono Sms\SmsVariableResolver ze wspolna logika placeholderow;
  Email\VariableResolver staje sie cienka fasada — EmailSendingService bez zmian.
- Dropdown "Wybierz szablon" w zakladce SMS na /orders/{id} z fetch
  GET /orders/{id}/sms/template + OrderProAlerts.confirm przy nadpisaniu.
- Stopka SMSPLANET dalej doklejana wylacznie przez SmsConversationService
  (Phase 122 contract preserved).
- Sidebar Ustawien: nowy link "Szablony SMS".

Migration: 20260512_000112_create_sms_templates.sql (CREATE TABLE).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 21:37:51 +02:00

97 lines
3.0 KiB
JavaScript

(function () {
'use strict';
if (window.__smsTemplatePickerBound) return;
window.__smsTemplatePickerBound = true;
function findTarget(picker) {
var targetId = picker.getAttribute('data-message-target');
if (!targetId) return null;
return document.getElementById(targetId);
}
function applyBody(textarea, body) {
textarea.value = body;
textarea.dispatchEvent(new Event('input', { bubbles: true }));
textarea.focus();
}
function bind(picker) {
if (picker.dataset.smsPickerBound === '1') return;
picker.dataset.smsPickerBound = '1';
picker.addEventListener('change', function () {
var templateId = parseInt(picker.value, 10);
var orderId = parseInt(picker.getAttribute('data-order-id'), 10);
if (!templateId || !orderId) {
return;
}
var textarea = findTarget(picker);
if (!textarea) {
picker.value = '';
return;
}
var doFetch = function () {
picker.disabled = true;
fetch('/orders/' + orderId + '/sms/template?template_id=' + templateId, {
headers: { 'Accept': 'application/json' },
credentials: 'same-origin'
})
.then(function (r) { return r.json(); })
.then(function (data) {
if (data && data.ok && typeof data.body === 'string') {
applyBody(textarea, data.body);
} else if (window.OrderProAlerts && window.OrderProAlerts.alert) {
window.OrderProAlerts.alert({
title: 'Nie udalo sie wczytac szablonu',
message: (data && data.error) ? String(data.error) : 'Sprobuj ponownie.'
});
}
})
.catch(function () {})
.finally(function () {
picker.disabled = false;
picker.value = '';
});
};
var current = (textarea.value || '').trim();
if (current === '') {
doFetch();
return;
}
if (window.OrderProAlerts && typeof window.OrderProAlerts.confirm === 'function') {
var triggered = false;
var run = function () { if (!triggered) { triggered = true; doFetch(); } };
var result = window.OrderProAlerts.confirm({
title: 'Zamiana tresci',
message: 'Tekst w polu wiadomosci zostanie nadpisany trescia szablonu. Kontynuowac?',
confirmLabel: 'Wstaw szablon',
danger: false,
onConfirm: run,
onCancel: function () { picker.value = ''; }
});
if (result && typeof result.then === 'function') {
result.then(function (ok) { if (ok) run(); else picker.value = ''; });
}
} else if (window.confirm('Tekst w polu wiadomosci zostanie nadpisany. Kontynuowac?')) {
doFetch();
} else {
picker.value = '';
}
});
}
function init() {
document.querySelectorAll('[data-sms-template-picker]').forEach(bind);
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();