diff --git a/assets/css/dashboard.css b/assets/css/dashboard.css index d222915..fe28c3b 100644 --- a/assets/css/dashboard.css +++ b/assets/css/dashboard.css @@ -2691,3 +2691,119 @@ body.modal-open { width: 100%; height: 100%; } + +/* ======================================== + MARKDOWN FORMATTING STYLES + ======================================== */ + +/* Code blocks */ +.code-block { + background: var(--bg-primary); + border: 2px solid var(--terminal-green); + border-left: 4px solid var(--terminal-amber); + padding: 1rem; + margin: 1rem 0; + overflow-x: auto; + font-family: var(--font-mono); + color: var(--terminal-green); + text-shadow: var(--glow-green); +} + +.code-block code { + background: transparent; + border: none; + padding: 0; +} + +/* Inline code */ +code.inline-code { + background: var(--bg-secondary); + border: 1px solid var(--terminal-green); + padding: 0.2rem 0.4rem; + font-family: var(--font-mono); + color: var(--terminal-amber); + text-shadow: var(--glow-amber); + border-radius: 0; +} + +/* Markdown headings in content */ +[data-markdown] h1, +[data-markdown] h2, +[data-markdown] h3 { + color: var(--terminal-amber); + text-shadow: var(--glow-amber); + font-family: var(--font-mono); + margin: 1.5rem 0 0.5rem 0; + border-bottom: 2px solid var(--terminal-green); + padding-bottom: 0.5rem; +} + +[data-markdown] h1 { font-size: 1.8rem; } +[data-markdown] h2 { font-size: 1.5rem; } +[data-markdown] h3 { font-size: 1.2rem; } + +/* Markdown lists */ +[data-markdown] ul, +[data-markdown] ol { + margin: 1rem 0; + padding-left: 2rem; +} + +[data-markdown] li { + color: var(--terminal-green); + margin: 0.5rem 0; +} + +[data-markdown] li::marker { + color: var(--terminal-amber); +} + +/* Markdown blockquotes */ +[data-markdown] blockquote { + border-left: 4px solid var(--terminal-amber); + background: var(--bg-secondary); + padding: 1rem; + margin: 1rem 0; + color: var(--terminal-green); + font-style: italic; +} + +/* Markdown links */ +[data-markdown] a { + color: var(--terminal-cyan); + text-decoration: none; + border-bottom: 1px dotted var(--terminal-cyan); + transition: all 0.3s ease; +} + +[data-markdown] a:hover { + color: var(--terminal-amber); + border-bottom-color: var(--terminal-amber); + text-shadow: var(--glow-amber); +} + +/* Horizontal rules */ +[data-markdown] hr { + border: none; + border-top: 2px solid var(--terminal-green); + margin: 2rem 0; +} + +/* Markdown paragraphs */ +[data-markdown] p { + margin: 1rem 0; + line-height: 1.6; +} + +/* Strong/bold text */ +[data-markdown] strong { + color: var(--terminal-amber); + font-weight: bold; + text-shadow: var(--glow-amber); +} + +/* Italic/emphasized text */ +[data-markdown] em { + color: var(--terminal-cyan); + font-style: italic; +} diff --git a/assets/js/markdown.js b/assets/js/markdown.js new file mode 100644 index 0000000..9930167 --- /dev/null +++ b/assets/js/markdown.js @@ -0,0 +1,77 @@ +/** + * Simple Markdown Parser for Tinker Tickets + * Supports basic markdown formatting without external dependencies + */ + +function parseMarkdown(markdown) { + if (!markdown) return ''; + + let html = markdown; + + // Escape HTML first to prevent XSS + html = html.replace(/&/g, '&') + .replace(//g, '>'); + + // Code blocks (```code```) + html = html.replace(/```([\s\S]*?)```/g, '
$1');
+
+ // Inline code (`code`)
+ html = html.replace(/`([^`]+)`/g, '$1');
+
+ // Bold (**text** or __text__)
+ html = html.replace(/\*\*(.+?)\*\*/g, '$1');
+ html = html.replace(/__(.+?)__/g, '$1');
+
+ // Italic (*text* or _text_)
+ html = html.replace(/\*(.+?)\*/g, '$1');
+ html = html.replace(/_(.+?)_/g, '$1');
+
+ // Links [text](url)
+ html = html.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '$1');
+
+ // Headers (# H1, ## H2, etc.)
+ html = html.replace(/^### (.+)$/gm, '$1'); + + // Horizontal rules (--- or ***) + html = html.replace(/^(?:---|___|\*\*\*)$/gm, '
'); + + // Wrap in paragraph if not already wrapped + if (!html.startsWith('<')) { + html = '
' + html + '
'; + } + + return html; +} + +// Apply markdown rendering to all elements with data-markdown attribute +function renderMarkdownElements() { + document.querySelectorAll('[data-markdown]').forEach(element => { + const markdownText = element.getAttribute('data-markdown') || element.textContent; + element.innerHTML = parseMarkdown(markdownText); + }); +} + +// Apply markdown to description and comments on page load +document.addEventListener('DOMContentLoaded', renderMarkdownElements); + +// Expose for manual use +window.parseMarkdown = parseMarkdown; +window.renderMarkdownElements = renderMarkdownElements; diff --git a/models/BulkOperationsModel.php b/models/BulkOperationsModel.php index 34df0f2..6c5c8d8 100644 --- a/models/BulkOperationsModel.php +++ b/models/BulkOperationsModel.php @@ -150,14 +150,6 @@ class BulkOperationsModel { } } break; - - case 'bulk_delete': - $success = $ticketModel->deleteTicket($ticketId); - if ($success) { - $auditLogModel->log($operation['performed_by'], 'delete', 'ticket', $ticketId, - ['bulk_operation_id' => $operationId]); - } - break; } if ($success) { diff --git a/views/DashboardView.php b/views/DashboardView.php index 56377c9..2d2823b 100644 --- a/views/DashboardView.php +++ b/views/DashboardView.php @@ -262,7 +262,6 @@ -