Dashboard Fach hinzufügen funktioniert in swe-b1-a-dev
This commit is contained in:
committed by
Matthias Grief
parent
b2cff02086
commit
6f73884baf
116
swe-b1-a-dev/webseite/dashboard/js/main.js
Normal file
116
swe-b1-a-dev/webseite/dashboard/js/main.js
Normal file
@@ -0,0 +1,116 @@
|
||||
// Modal management
|
||||
export function openSubjectModal() {
|
||||
fetch('components/modals/subject-modal.php')
|
||||
.then(response => response.text())
|
||||
.then(html => {
|
||||
document.getElementById('modalContainer').innerHTML = html;
|
||||
document.querySelector('.modal-overlay').classList.remove('hidden');
|
||||
document.querySelector('.modal').classList.add('active');
|
||||
});
|
||||
}
|
||||
|
||||
export function openTopicModal() {
|
||||
console.log('Opening topic modal...'); // Debug log
|
||||
fetch('components/modals/topic-modal.php')
|
||||
.then(response => response.text())
|
||||
.then(html => {
|
||||
document.getElementById('modalContainer').innerHTML = html;
|
||||
document.querySelector('.modal-overlay').classList.remove('hidden');
|
||||
document.querySelector('.modal').classList.add('active');
|
||||
// Initialize topic manager after modal is loaded
|
||||
const event = new CustomEvent('openTopicModal');
|
||||
document.dispatchEvent(event);
|
||||
})
|
||||
.catch(error => console.error('Error loading topic modal:', error));
|
||||
}
|
||||
|
||||
export function openTopicEditorModal() {
|
||||
fetch('components/modals/topic-editor-modal.php')
|
||||
.then(response => response.text())
|
||||
.then(html => {
|
||||
document.getElementById('modalContainer').innerHTML = html;
|
||||
document.querySelector('.modal-overlay').classList.remove('hidden');
|
||||
document.querySelector('.modal').classList.add('active');
|
||||
// Initialize topic editor
|
||||
const event = new CustomEvent('openTopicEditorModal');
|
||||
document.dispatchEvent(event);
|
||||
});
|
||||
}
|
||||
|
||||
export function closeModal() {
|
||||
document.querySelector('.modal-overlay').classList.add('hidden');
|
||||
document.querySelector('.modal').classList.remove('active');
|
||||
}
|
||||
|
||||
// Event listeners
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
loadRecentActivity();
|
||||
});
|
||||
|
||||
async function loadRecentActivity() {
|
||||
try {
|
||||
const response = await fetch('api/get-recent-activity.php');
|
||||
const activities = await response.json();
|
||||
displayActivities(activities);
|
||||
} catch (error) {
|
||||
console.error('Error loading recent activities:', error);
|
||||
}
|
||||
}
|
||||
|
||||
function displayActivities(activities) {
|
||||
const container = document.getElementById('recentActivity');
|
||||
container.innerHTML = activities.map(activity => `
|
||||
<div class="flex items-center gap-4 p-4 bg-gray-50 rounded-lg">
|
||||
<i class="fas ${activity.icon} text-blue-500"></i>
|
||||
<div>
|
||||
<p class="font-medium">${activity.title}</p>
|
||||
<p class="text-sm text-gray-600">${activity.timestamp}</p>
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
async function handleSubjectSubmit(event) {
|
||||
event.preventDefault();
|
||||
const form = event.target;
|
||||
const formData = new FormData(form);
|
||||
|
||||
// Ensure icon is included
|
||||
/*
|
||||
const selectedIcon = document.getElementById('selectedIcon').value;
|
||||
if (!selectedIcon) {
|
||||
alert('Bitte wählen Sie ein Icon aus');
|
||||
return;
|
||||
}
|
||||
formData.set('icon', selectedIcon);
|
||||
*/
|
||||
|
||||
try {
|
||||
console.log('Form data before submit:', Object.fromEntries(formData));
|
||||
|
||||
const response = await fetch('api/create-subject.php', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
console.log('Server response:', result);
|
||||
|
||||
if (result.success) {
|
||||
closeModal();
|
||||
window.location.reload();
|
||||
} else {
|
||||
alert('Fehler beim Erstellen des Fachs: ' + result.message);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error creating subject:', error);
|
||||
alert('Ein Fehler ist aufgetreten: ' + error.message);
|
||||
}
|
||||
}
|
||||
|
||||
// Make functions available globally
|
||||
window.openSubjectModal = openSubjectModal;
|
||||
window.openTopicModal = openTopicModal;
|
||||
window.closeModal = closeModal;
|
||||
window.handleSubjectSubmit = handleSubjectSubmit;
|
||||
window.openTopicEditorModal = openTopicEditorModal;
|
||||
80
swe-b1-a-dev/webseite/dashboard/js/modules/QuillEditor.js
Normal file
80
swe-b1-a-dev/webseite/dashboard/js/modules/QuillEditor.js
Normal file
@@ -0,0 +1,80 @@
|
||||
export class QuillEditor {
|
||||
constructor(editorId = 'quillEditor', previewId = 'contentPreview') {
|
||||
this.quill = null;
|
||||
this.editorId = editorId;
|
||||
this.previewId = previewId;
|
||||
this.initialize();
|
||||
}
|
||||
|
||||
initialize() {
|
||||
console.log('Initializing Quill editor...'); // Debug log
|
||||
|
||||
const editorContainer = document.getElementById(this.editorId);
|
||||
if (!editorContainer) {
|
||||
console.error(`Editor container #${this.editorId} not found`);
|
||||
return;
|
||||
}
|
||||
|
||||
this.quill = new Quill(`#${this.editorId}`, {
|
||||
theme: 'snow',
|
||||
modules: {
|
||||
toolbar: [
|
||||
[{ 'header': [1, 2, false] }],
|
||||
['bold', 'italic', 'underline'],
|
||||
['blockquote', 'code-block'],
|
||||
[{ 'list': 'ordered'}, { 'list': 'bullet' }],
|
||||
[{ 'script': 'sub'}, { 'script': 'super' }],
|
||||
['link', 'image', 'formula'],
|
||||
['clean']
|
||||
]
|
||||
},
|
||||
placeholder: 'Fügen Sie hier Ihren Inhalt ein...'
|
||||
});
|
||||
|
||||
this.quill.on('text-change', () => this.updatePreview());
|
||||
console.log('Quill editor initialized');
|
||||
}
|
||||
|
||||
updatePreview() {
|
||||
const content = this.quill.root.innerHTML;
|
||||
const preview = document.getElementById(this.previewId);
|
||||
|
||||
if (preview) {
|
||||
preview.innerHTML = content;
|
||||
|
||||
// Re-render math if present
|
||||
if (window.MathJax) {
|
||||
MathJax.typeset([preview]);
|
||||
}
|
||||
|
||||
// Highlight code blocks if any
|
||||
if (window.Prism) {
|
||||
Prism.highlightAllUnder(preview);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getContent() {
|
||||
return this.quill.root.innerHTML;
|
||||
}
|
||||
|
||||
setContent(content) {
|
||||
if (this.quill) {
|
||||
this.quill.root.innerHTML = content;
|
||||
this.updatePreview();
|
||||
}
|
||||
}
|
||||
|
||||
undo() {
|
||||
this.quill?.history.undo();
|
||||
}
|
||||
|
||||
redo() {
|
||||
this.quill?.history.redo();
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.quill?.setContents([]);
|
||||
this.updatePreview();
|
||||
}
|
||||
}
|
||||
61
swe-b1-a-dev/webseite/dashboard/js/modules/TopicEditor.js
Normal file
61
swe-b1-a-dev/webseite/dashboard/js/modules/TopicEditor.js
Normal file
@@ -0,0 +1,61 @@
|
||||
export class TopicEditor {
|
||||
constructor() {
|
||||
this.quill = null;
|
||||
this.initializeEventListeners();
|
||||
}
|
||||
|
||||
initializeEventListeners() {
|
||||
document.addEventListener('openTopicEditorModal', () => {
|
||||
this.loadSubjects();
|
||||
if (!this.quill) {
|
||||
this.initializeQuill();
|
||||
}
|
||||
});
|
||||
|
||||
// Handle subject selection change
|
||||
document.addEventListener('change', (e) => {
|
||||
if (e.target.id === 'editSubjectSelect') {
|
||||
this.loadTopicsForSubject(e.target.value);
|
||||
}
|
||||
if (e.target.id === 'editTopicSelect') {
|
||||
this.loadTopicContent(e.target.value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
initializeQuill() {
|
||||
const toolbarOptions = [
|
||||
['bold', 'italic', 'underline'],
|
||||
['blockquote', 'code-block'],
|
||||
[{ 'list': 'ordered'}, { 'list': 'bullet' }],
|
||||
['link', 'image', 'formula'],
|
||||
['clean']
|
||||
];
|
||||
|
||||
this.quill = new Quill('#topicEditorQuill', {
|
||||
modules: {
|
||||
toolbar: toolbarOptions
|
||||
},
|
||||
theme: 'snow'
|
||||
});
|
||||
}
|
||||
|
||||
async loadSubjects() {
|
||||
const select = document.getElementById('editSubjectSelect');
|
||||
try {
|
||||
const subjects = SubjectData.getAll();
|
||||
select.innerHTML = '<option value="">Fach auswählen...</option>';
|
||||
Object.values(subjects).forEach(subject => {
|
||||
const option = document.createElement('option');
|
||||
option.value = subject.id;
|
||||
option.textContent = subject.displayName;
|
||||
select.appendChild(option);
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error loading subjects:', error);
|
||||
alert('Fehler beim Laden der Fächer');
|
||||
}
|
||||
}
|
||||
|
||||
// ... rest of your provided methods ...
|
||||
}
|
||||
150
swe-b1-a-dev/webseite/dashboard/js/modules/TopicManager.js
Normal file
150
swe-b1-a-dev/webseite/dashboard/js/modules/TopicManager.js
Normal file
@@ -0,0 +1,150 @@
|
||||
export class TopicManager {
|
||||
constructor() {
|
||||
this.quill = null;
|
||||
this.initializeEventListeners();
|
||||
}
|
||||
|
||||
initializeEditor() {
|
||||
if (this.quill) return; // Prevent multiple initializations
|
||||
|
||||
console.log('Initializing Quill editor...'); // Debug log
|
||||
|
||||
const editorContainer = document.getElementById('quillEditor');
|
||||
if (!editorContainer) {
|
||||
console.error('Editor container not found');
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize Quill
|
||||
this.quill = new Quill('#quillEditor', {
|
||||
theme: 'snow',
|
||||
modules: {
|
||||
toolbar: [
|
||||
[{ 'header': [1, 2, false] }],
|
||||
['bold', 'italic', 'underline'],
|
||||
['blockquote', 'code-block'],
|
||||
[{ 'list': 'ordered'}, { 'list': 'bullet' }],
|
||||
['link', 'image', 'formula']
|
||||
]
|
||||
},
|
||||
placeholder: 'Fügen Sie hier Ihren Inhalt ein...'
|
||||
});
|
||||
|
||||
// Set up change handler
|
||||
this.quill.on('text-change', () => this.updatePreview());
|
||||
|
||||
console.log('Quill editor initialized'); // Debug log
|
||||
}
|
||||
|
||||
// ... rest of the methods from your code ...
|
||||
|
||||
undo() {
|
||||
if (this.quill) {
|
||||
this.quill.history.undo();
|
||||
}
|
||||
}
|
||||
|
||||
redo() {
|
||||
if (this.quill) {
|
||||
this.quill.history.redo();
|
||||
}
|
||||
}
|
||||
|
||||
deleteSelected() {
|
||||
if (this.quill) {
|
||||
const range = this.quill.getSelection();
|
||||
if (range) {
|
||||
if (range.length > 0) {
|
||||
// Delete selected text/content
|
||||
this.quill.deleteText(range.index, range.length);
|
||||
} else {
|
||||
// Delete current line if no selection
|
||||
const [line] = this.quill.getLine(range.index);
|
||||
const lineLength = line.length();
|
||||
this.quill.deleteText(range.index - lineLength, lineLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async loadSubjectsIntoSelect() {
|
||||
const select = document.getElementById('topicSubjectSelect');
|
||||
if (!select) return;
|
||||
|
||||
// Clear existing options except the first placeholder
|
||||
while (select.options.length > 1) {
|
||||
select.remove(1);
|
||||
}
|
||||
|
||||
try {
|
||||
const subjects = await this.subjectStorage.getAllSubjects();
|
||||
subjects.forEach(subject => {
|
||||
const option = document.createElement('option');
|
||||
option.value = subject.id;
|
||||
option.textContent = subject.name;
|
||||
select.appendChild(option);
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error loading subjects:', error);
|
||||
}
|
||||
}
|
||||
|
||||
initializeEventListeners() {
|
||||
const form = document.getElementById('topicForm');
|
||||
if (form) {
|
||||
form.addEventListener('submit', (e) => this.handleTopicSubmit(e));
|
||||
}
|
||||
document.addEventListener('openTopicModal', () => {
|
||||
this.loadSubjectsIntoSelect();
|
||||
if (!this.quill) {
|
||||
this.initializeEditor();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updatePreview() {
|
||||
const content = this.quill.root.innerHTML;
|
||||
const preview = document.getElementById('contentPreview');
|
||||
const quillContent = document.getElementById('quillContent');
|
||||
|
||||
if (preview) {
|
||||
// Preserve classes for styling while updating content
|
||||
preview.innerHTML = content;
|
||||
// Update hidden input with content
|
||||
if (quillContent) {
|
||||
quillContent.value = content;
|
||||
}
|
||||
// Re-render math if present
|
||||
if (window.MathJax) {
|
||||
MathJax.typeset([preview]);
|
||||
}
|
||||
// Highlight code blocks if any
|
||||
if (window.Prism) {
|
||||
Prism.highlightAllUnder(preview);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleTopicSubmit(e) {
|
||||
e.preventDefault();
|
||||
const formData = new FormData(e.target);
|
||||
const content = this.quill.root.innerHTML;
|
||||
const subjectId = formData.get('subject');
|
||||
|
||||
if (!subjectId) {
|
||||
throw new Error('Bitte wählen Sie ein Fach aus');
|
||||
}
|
||||
|
||||
// Add your topic saving logic here
|
||||
|
||||
closeModal('topicModal');
|
||||
}
|
||||
|
||||
clearEditor() {
|
||||
if (this.quill) {
|
||||
this.quill.setContents([]);
|
||||
this.updatePreview();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user