144 lines
7.8 KiB
JavaScript
144 lines
7.8 KiB
JavaScript
import { currentUser } from '../components/auth.js';
|
||
|
||
// Import editors
|
||
import { loadVditor, initVditorEditor } from '../editors/vditorLoader.js';
|
||
|
||
// Import course-builder modules
|
||
import { courseStructure, currentCourseId, isEditMode, isDraftMode, setVditorInstance, getVditorInstance } from '../course-builder/State.js';
|
||
import { saveDraft, previewCourse, publishCourse, updateDraftsCount, showDraftsModal, loadDraftIntoEditor } from '../course-builder/DraftManager.js';
|
||
import { initCourseStructure, loadCourseForEditing, renderCourseStructure } from '../course-builder/StructureManager.js';
|
||
import { showMessage, updateBuilderTitle } from '../course-builder/CourseUI.js';
|
||
|
||
export { courseStructure, currentCourseId, isEditMode, isDraftMode };
|
||
|
||
export async function render() {
|
||
if (!currentUser) {
|
||
return `
|
||
<div class="auth-required">
|
||
<h2>Требуется авторизация</h2>
|
||
<p>Для доступа к конструктору курса необходимо войти в систему.</p>
|
||
<a href="/login" data-link>Войти</a>
|
||
</div>`;
|
||
}
|
||
|
||
return `
|
||
<div class="course-builder-page">
|
||
<div class="course-builder-container">
|
||
<h2>Конструктор курса</h2>
|
||
<p class="subtitle">Создайте новый курс с помощью редактора Markdown с поддержкой LaTeX</p>
|
||
<div class="course-form">
|
||
<div class="form-group">
|
||
<label for="course-title">Название курса</label>
|
||
<input type="text" id="course-title" placeholder="Введите название курса" required>
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="course-description">Краткое описание</label>
|
||
<textarea id="course-description" placeholder="Краткое описание курса" rows="3"></textarea>
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="course-level">Уровень сложности</label>
|
||
<select id="course-level">
|
||
<option value="beginner">Начальный</option>
|
||
<option value="intermediate">Средний</option>
|
||
<option value="advanced">Продвинутый</option>
|
||
</select>
|
||
</div>
|
||
<div class="course-structure-section">
|
||
<h3>Структура курса</h3>
|
||
<p class="section-description">Создайте модули и уроки для вашего курса</p>
|
||
<div class="structure-actions">
|
||
<button type="button" id="add-module-btn" class="btn btn-outline"><span class="btn-icon">+</span> Добавить модуль</button>
|
||
</div>
|
||
<div id="course-structure" class="course-structure">
|
||
<div class="empty-structure"><p>Пока нет модулей. Добавьте первый модуль, чтобы начать.</p></div>
|
||
</div>
|
||
</div>
|
||
<div class="editor-section">
|
||
<h3>Содержание курса (Vditor редактор)</h3>
|
||
<div id="vditor-container"></div>
|
||
<div class="editor-help">
|
||
<h4>Возможности редактора:</h4>
|
||
<ul>
|
||
<li>Редактирование Markdown в реальном времени</li>
|
||
<li>Поддержка LaTeX формул через KaTeX</li>
|
||
<li>Встроенный предпросмотр</li>
|
||
<li>Подсветка синтаксиса кода</li>
|
||
<li>Экспорт в HTML и PDF</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<div class="form-actions">
|
||
<button type="button" id="manage-drafts" class="btn btn-outline">📝 Мои черновики <span id="drafts-count" class="badge">0</span></button>
|
||
<button type="button" id="save-draft" class="btn btn-secondary">Сохранить черновик</button>
|
||
<button type="button" id="preview-course" class="btn btn-outline">Предпросмотр</button>
|
||
<button type="button" id="publish-course" class="btn btn-primary">Опубликовать курс</button>
|
||
</div>
|
||
<div id="builder-message" class="message"></div>
|
||
</div>
|
||
</div>
|
||
</div>`;
|
||
}
|
||
|
||
export function afterRender() {
|
||
if (!currentUser) return;
|
||
|
||
initVditor();
|
||
initCourseStructure();
|
||
|
||
document.getElementById('save-draft').addEventListener('click', saveDraft);
|
||
document.getElementById('preview-course').addEventListener('click', previewCourse);
|
||
document.getElementById('publish-course').addEventListener('click', publishCourse);
|
||
document.getElementById('manage-drafts').addEventListener('click', showDraftsModal);
|
||
|
||
updateDraftsCount();
|
||
|
||
setTimeout(() => {
|
||
const vditor = getVditorInstance();
|
||
if (vditor) {
|
||
let debounceTimeout;
|
||
vditor.vditor.element.addEventListener('keyup', () => {
|
||
clearTimeout(debounceTimeout);
|
||
debounceTimeout = setTimeout(() => { if (currentCourseId) saveDraft(); }, 2000);
|
||
});
|
||
}
|
||
}, 2000);
|
||
}
|
||
|
||
function initVditor() {
|
||
const initialContent = getInitialContent();
|
||
if (typeof Vditor === 'undefined') loadVditor().then(() => { const inst = initVditorEditor('vditor-container', initialContent); if (inst) setVditorInstance(inst); });
|
||
else { const inst = initVditorEditor('vditor-container', initialContent); if (inst) setVditorInstance(inst); }
|
||
}
|
||
|
||
function getInitialContent() {
|
||
const draft = localStorage.getItem('course_draft');
|
||
let initialContent = '# Заголовок курса\n\n## Введение\nНапишите введение к вашему курсу здесь...\n\n## Основная часть\n- Пункт 1\n- Пункт 2\n\n## Формулы LaTeX\nВведите формулы в формате LaTeX:\n$$E = mc^2$$\n$$\\int_{a}^{b} f(x) dx$$\n\n## Заключение\nПодведите итоги курса...';
|
||
if (draft) {
|
||
try {
|
||
const data = JSON.parse(draft);
|
||
if (data.content) initialContent = data.content;
|
||
} catch (e) { console.error('Error loading draft for editor:', e); }
|
||
}
|
||
return initialContent;
|
||
}
|
||
|
||
window.addEventListener('load', () => {
|
||
const draft = localStorage.getItem('course_draft');
|
||
if (draft) {
|
||
try {
|
||
const data = JSON.parse(draft);
|
||
const titleEl = document.getElementById('course-title');
|
||
const descEl = document.getElementById('course-description');
|
||
const levelEl = document.getElementById('course-level');
|
||
const messageEl = document.getElementById('builder-message');
|
||
if (titleEl) titleEl.value = data.title || '';
|
||
if (descEl) descEl.value = data.description || '';
|
||
if (levelEl) levelEl.value = data.level || 'beginner';
|
||
if (messageEl && data.savedAt) {
|
||
messageEl.textContent = `📝 Загружен черновик от ${new Date(data.savedAt).toLocaleString()}`;
|
||
messageEl.className = 'message info';
|
||
}
|
||
} catch (e) { console.error('Error loading draft:', e); }
|
||
}
|
||
});
|