Prac2026_Email/ListmonkIntegration/Pages/Templates/Create.cshtml
2026-07-15 17:17:03 +03:00

235 lines
12 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@page
@model ListmonkIntegration.Pages.Templates.CreateModel
@{
ViewData["Title"] = "Создание шаблона письма";
}
<h1>Создание шаблона письма</h1>
<hr />
@if (TempData["SuccessMessage"] != null)
{
<div class="alert alert-success">
@TempData["SuccessMessage"]
</div>
}
@if (TempData["ErrorMessage"] != null)
{
<div class="alert alert-danger">
@TempData["ErrorMessage"]
</div>
}
<div class="row">
<div class="col-md-8">
<form method="post">
<div class="mb-3">
<label class="form-label">Название шаблона</label>
<input type="text" asp-for="TemplateName" class="form-control" required placeholder="Например: Приветственное письмо" />
</div>
<div class="mb-3">
<label class="form-label">Тема письма</label>
<input type="text" asp-for="Subject" class="form-control" required placeholder="Например: Добро пожаловать, {{ .Subscriber.Name }}!" />
<div class="form-text">Можно использовать переменные: {{ .Subscriber.Name }}, {{ .Subscriber.Email }}, {{ .Subscriber.Attribs.ИмяАтрибута }}</div>
</div>
<div class="mb-3">
<label class="form-label">Выберите список рассылки (для просмотра атрибутов)</label>
<select asp-for="SelectedListId" class="form-select" asp-items="Model.Lists" id="listSelect">
<option value="">-- Выберите список --</option>
</select>
</div>
<div class="mb-3">
<label class="form-label">Текст письма</label>
<textarea asp-for="Body" id="editor" class="form-control" rows="15" placeholder="Введите текст письма здесь..."></textarea>
<div class="form-text">
Используйте редактор для форматирования текста. HTML код генерируется автоматически.
</div>
</div>
<div class="mb-3">
<button type="submit" class="btn btn-primary">Создать шаблон</button>
<a asp-page="/Campaigns/Index" class="btn btn-secondary">Отмена</a>
</div>
</form>
</div>
<div class="col-md-4">
<!-- Кнопки для вставки переменных -->
<div class="card mb-3">
<div class="card-header">
<h5>Быстрая вставка переменных</h5>
</div>
<div class="card-body">
<div class="mb-2">
<label class="form-label small text-muted">Стандартные поля:</label>
<div class="btn-group-vertical w-100">
<button type="button" class="btn btn-sm btn-outline-primary mb-1" onclick="insertVariable('{{ .Subscriber.Name }}')">
Имя (Name)
</button>
<button type="button" class="btn btn-sm btn-outline-primary mb-1" onclick="insertVariable('{{ .Subscriber.Email }}')">
Email
</button>
</div>
</div>
<hr />
<div id="attributesButtons">
<label class="form-label small text-muted">Атрибуты из списка:</label>
<p class="text-muted small">Выберите список для загрузки атрибутов</p>
</div>
</div>
</div>
<!-- Примеры использования -->
<div class="card">
<div class="card-header">
<h5>Пример использования</h5>
</div>
<div class="card-body">
<small class="text-muted">
Переменные подставляются автоматически при отправке письма каждому получателю.
</small>
</div>
</div>
</div>
</div>
@section Scripts {
<script src="https://cdn.tiny.cloud/1/k6rorn68v4xqaesxvaroqlkyhfmncfoq8bxgxv3nd39szqrc/tinymce/8/tinymce.min.js" referrerpolicy="origin" crossorigin="anonymous"></script>
<script>
console.log('Script started');
// Глобальная переменная для хранения ссылки на редактор
window.tinymceEditor = null;
// Инициализация TinyMCE
tinymce.init({
selector: '#editor', // ИСПРАВЛЕНО: конкретный ID вместо всех textarea
api_key: 'k6rorn68v4xqaesxvaroqlkyhfmncfoq8bxgxv3nd39szqrc',
height: 400,
plugins: 'lists link table code bold italic underline',
toolbar: 'bold italic underline | h1 h2 h3 | bullist numlist | link unlink | code',
menubar: false,
statusbar: true,
branding: false,
content_style: 'body { font-family: Arial, sans-serif; font-size: 14px; }',
// ИСПРАВЛЕНО: добавлена setup функция для сохранения редактора
setup: function(editor) {
window.tinymceEditor = editor;
console.log('TinyMCE editor saved to window.tinymceEditor');
editor.on('change', function() {
tinymce.triggerSave();
});
},
init_instance_callback: function(editor) {
console.log('TinyMCE initialized successfully');
}
});
// Глобальная функция для вставки переменной
window.insertVariable = function(variable) {
console.log('insertVariable called with:', variable);
try {
// Проверяем, существует ли редактор
if (window.tinymceEditor && !window.tinymceEditor.destroyed) {
// Вставляем в TinyMCE
window.tinymceEditor.insertContent(variable);
window.tinymceEditor.focus();
console.log('✓ Inserted into TinyMCE editor');
} else if (window.tinymce && window.tinymce.editors.length > 0) {
// Альтернативный способ - берём первый редактор
var editor = window.tinymce.editors[0];
editor.insertContent(variable);
editor.focus();
console.log('✓ Inserted via tinymce.editors');
} else {
// Если TinyMCE не инициализирован, вставляем в textarea
var textarea = document.querySelector('textarea[name="Body"]');
if (textarea) {
var start = textarea.selectionStart || 0;
var end = textarea.selectionEnd || 0;
var text = textarea.value;
textarea.value = text.substring(0, start) + variable + text.substring(end);
textarea.focus();
console.log('✓ Inserted into textarea (TinyMCE not ready)');
} else {
console.error('✗ Textarea not found');
}
}
} catch (error) {
console.error('✗ Error inserting variable:', error);
}
};
console.log('Script loaded, waiting for DOM...');
// Загрузка атрибутов при выборе списка
document.addEventListener('DOMContentLoaded', function() {
console.log('DOM loaded');
const listSelect = document.getElementById('listSelect');
if (listSelect) {
listSelect.addEventListener('change', async function() {
const listId = this.value;
const attributesDiv = document.getElementById('attributesButtons');
console.log('List selected, ID:', listId);
if (listId) {
attributesDiv.innerHTML = '<label class="form-label small text-muted">Атрибуты из списка:</label><div class="text-center"><div class="spinner-border spinner-border-sm" role="status"><span class="visually-hidden">Загрузка...</span></div></div>';
try {
const response = await fetch(`/api/lists/${listId}/attributes`);
console.log('API response status:', response.status);
if (response.ok) {
const attributes = await response.json();
console.log('Attributes loaded:', attributes);
displayAttributeButtons(attributes);
} else {
attributesDiv.innerHTML = '<label class="form-label small text-muted">Атрибуты из списка:</label><p class="text-danger small">Ошибка загрузки атрибутов.</p>';
}
} catch (error) {
console.error('Error loading attributes:', error);
attributesDiv.innerHTML = '<label class="form-label small text-muted">Атрибуты из списка:</label><p class="text-danger small">Ошибка загрузки атрибутов.</p>';
}
} else {
attributesDiv.innerHTML = '<label class="form-label small text-muted">Атрибуты из списка:</label><p class="text-muted small">Выберите список для загрузки атрибутов</p>';
}
});
}
});
// Отображение кнопок для атрибутов
window.displayAttributeButtons = function(attributes) {
console.log('displayAttributeButtons called with:', attributes);
const attributesDiv = document.getElementById('attributesButtons');
if (attributes && attributes.length > 0) {
let html = '<label class="form-label small text-muted">Атрибуты из списка:</label><div class="d-flex flex-wrap gap-1">';
attributes.forEach(attr => {
const variable = `{{ .Subscriber.Attribs.${attr} }}`;
console.log('Creating button for attr:', attr, 'variable:', variable);
// Экранируем специальные символы для onclick
const escapedVar = variable.replace(/'/g, "\\'").replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
html += `<button type="button" class="btn btn-sm btn-outline-secondary m-1" onclick="insertVariable('${escapedVar}')">
${attr}
</button>`;
});
html += '</div>';
attributesDiv.innerHTML = html;
console.log('Buttons created');
} else {
attributesDiv.innerHTML = '<label class="form-label small text-muted">Атрибуты из списка:</label><p class="text-muted small">У выбранного списка нет пользовательских атрибутов.</p>';
}
};
console.log('All scripts initialized');
</script>
}