2026-04-28 15:59:47 +02:00
<!DOCTYPE html> < html lang = "en" class = "dark" data-astro-cid-sckkx6r4 > < head > < meta charset = "UTF-8" > < meta name = "viewport" content = "width=device-width" > < link rel = "icon" type = "image/svg+xml" href = "/favicon.svg" > < meta name = "generator" content = "Astro v6.1.7" > < title > PR Dojo - Code Review Practice< / title > < link rel = "stylesheet" href = "/_astro/Layout.slfrh7tA.css" >
< style > t r [ d a t a - a s t r o - c i d - 2 e x 4 4 d s a ] { l i n e - h e i g h t : 1 . 6 } t r [ d a t a - a s t r o - c i d - 2 e x 4 4 d s a ] : h o v e r { b a c k g r o u n d - c o l o r : # 1 6 1 b 2 2 } t d [ d a t a - a s t r o - c i d - 2 e x 4 4 d s a ] : f i r s t - c h i l d { b o r d e r - r i g h t : 1 p x s o l i d # 3 0 3 6 3 d } t r [ d a t a - a s t r o - c i d - 2 e x 4 4 d s a ] . b u g g e d t d [ d a t a - a s t r o - c i d - 2 e x 4 4 d s a ] : f i r s t - c h i l d { b o r d e r - l e f t : 3 p x s o l i d # f 8 5 1 4 9 } t r [ d a t a - a s t r o - c i d - 2 e x 4 4 d s a ] . b u g g e d . l i n e - n u m b e r [ d a t a - a s t r o - c i d - 2 e x 4 4 d s a ] { c o l o r : # f 8 5 1 4 9 } t r [ d a t a - a s t r o - c i d - 2 e x 4 4 d s a ] . b u g g e d { b a c k g r o u n d - c o l o r : # f 8 5 1 4 9 1 8 } . d i f f - v i e w e r - c o n t a i n e r [ d a t a - a s t r o - c i d - 2 e x 4 4 d s a ] : n o t ( . r e v e a l e d ) t r [ d a t a - a s t r o - c i d - 2 e x 4 4 d s a ] . b u g g e d . l i n e - n u m b e r [ d a t a - a s t r o - c i d - 2 e x 4 4 d s a ] . h a s - h i n t - c o l o r { c o l o r : # f 8 5 1 4 9 ! i m p o r t a n t } . d i f f - v i e w e r - c o n t a i n e r [ d a t a - a s t r o - c i d - 2 e x 4 4 d s a ] : n o t ( . r e v e a l e d ) t r [ d a t a - a s t r o - c i d - 2 e x 4 4 d s a ] : n o t ( . b u g g e d ) s p a n [ d a t a - a s t r o - c i d - 2 e x 4 4 d s a ] . l i n e - n u m b e r . h a s - h i n t - c o l o r { c o l o r : # 8 b 9 4 9 e ! i m p o r t a n t ; f o n t - w e i g h t : 4 0 0 ! i m p o r t a n t } . d i f f - v i e w e r - c o n t a i n e r [ d a t a - a s t r o - c i d - 2 e x 4 4 d s a ] . r e v e a l e d t r [ d a t a - a s t r o - c i d - 2 e x 4 4 d s a ] . b u g g e d . h i n t [ d a t a - a s t r o - c i d - 2 e x 4 4 d s a ] { d i s p l a y : i n l i n e } . d i f f - v i e w e r - c o n t a i n e r [ d a t a - a s t r o - c i d - 2 e x 4 4 d s a ] : n o t ( . r e v e a l e d ) t d [ d a t a - a s t r o - c i d - 2 e x 4 4 d s a ] > s p a n [ d a t a - a s t r o - c i d - 2 e x 4 4 d s a ] . h a s - h i n t - b g { b a c k g r o u n d - c o l o r : t r a n s p a r e n t ! i m p o r t a n t } # f i x - e d i t o r - c o n t a i n e r [ d a t a - a s t r o - c i d - 7 f g t u n e g ] t e x t a r e a [ d a t a - a s t r o - c i d - 7 f g t u n e g ] { r e s i z e : v e r t i c a l ; m i n - h e i g h t : 4 8 p x }
< / style > < / head > < body data-astro-cid-sckkx6r4 > < div class = "min-h-screen" data-astro-cid-7fgtuneg > <!-- Header --> < header class = "bg-[#161b22] border-b border-[#30363d]" data-astro-cid-7fgtuneg > < div class = "max-w-6xl mx-auto px-4 py-3 flex items-center gap-4" data-astro-cid-7fgtuneg > < a href = "/" class = "text-[#58a6ff] text-sm font-medium no-underline focus:outline-none focus:ring-0" data-astro-cid-7fgtuneg > ← Back to Challenges< / a > < span class = "text-[#8b949e] text-sm" data-astro-cid-7fgtuneg > / Challenge #4< / span > < / div > < / header > < main class = "max-w-6xl mx-auto px-4 py-6" data-astro-cid-7fgtuneg > <!-- Challenge Header --> < div class = "bg-[#161b22] border border-[#30363d] rounded-md p-6 mb-6" data-astro-cid-7fgtuneg > < div class = "flex justify-between items-start mb-4" data-astro-cid-7fgtuneg > < div data-astro-cid-7fgtuneg > < h1 class = "text-2xl font-semibold text-[#c9d1d9] mb-2 no-underline" data-astro-cid-7fgtuneg > SQL Injection Vulnerability< / h1 > < div class = "mb-4" data-astro-cid-7fgtuneg > < span class = "text-[#79c0ff] text-xl no-underline" data-astro-cid-7fgtuneg > ★★★★★< / span > < / div > < div class = "flex flex-wrap items-center gap-4 text-sm" data-astro-cid-7fgtuneg > < span class = "text-[#8b949e]" data-astro-cid-7fgtuneg > 📁 < span class = "text-[#a5d6ff]" data-astro-cid-7fgtuneg > django/django< / span > < / span > < span class = "text-[#8b949e]" data-astro-cid-7fgtuneg > 🔢 < code class = "bg-[#21262d] px-2 py-0.5 rounded text-xs" data-astro-cid-7fgtuneg > jkl3456< / code > < / span > < span class = "px-2 py-0.5 bg-[#0a3064] rounded text-xs text-[#79c0ff]" data-astro-cid-7fgtuneg > Security< / span > < / div > < / div > < div class = "text-right" data-astro-cid-7fgtuneg > < div class = "text-[#79c0ff] text-lg mb-1 no-underline" data-astro-cid-7fgtuneg > ★★★★★< / div > < div class = "text-xs text-[#8b949e]" data-astro-cid-7fgtuneg > Difficulty< / div > < / div > < / div > < div class = "bg-[#0a3064] rounded p-3 flex items-center gap-2" data-astro-cid-7fgtuneg > < svg class = "w-5 h-5 text-[#58a6ff]" fill = "currentColor" viewBox = "0 0 20 20" data-astro-cid-7fgtuneg > < path d = "M10 18a8 8 0 100-16 8 8 0 000 16zm1-11a1 1 0 10-2 0v2H7a1 1 0 100 2h2v2a1 1 0 102 0v-2h2a1 1 0 100-2h-2V7z" data-astro-cid-7fgtuneg > < / path > < / svg > < span class = "text-[#79c0ff] font-semibold" data-astro-cid-7fgtuneg > +200 XP reward< / span > < / div > < / div > <!-- Code Viewer --> < div id = "dv-e35geif" class = "diff-viewer-container" data-dv-id = "dv-e35geif" data-astro-cid-2ex44dsa > < div class = "bg-[#0d1117] border border-[#30363d] rounded-md overflow-hidden" data-astro-cid-2ex44dsa > < div class = "bg-[#161b22] px-4 py-3 border-b border-[#30363d]" data-astro-cid-2ex44dsa > < span class = "text-sm text-[#8b949e]" data-astro-cid-2ex44dsa > file.js< / span > < / div > < div class = "overflow-x-auto" data-astro-cid-2ex44dsa > < table class = "w-full font-mono text-sm" data-astro-cid-2ex44dsa > < tbody data-astro-cid-2ex44dsa > < tr data-line = "1" class = "group hover:bg-[#161b22] cursor-pointer transition-colors" title = "Mark line 1 as buggy" data-astro-cid-2ex44dsa > < td class = "w-16 text-right pr-4 select-none" data-astro-cid-2ex44dsa > < span class = "text-[#8b949e] line-number " data-astro-cid-2ex44dsa > 1 < / span > < / td > < td class = "px-4 py-0.5 whitespace-pre" data-astro-cid-2ex44dsa > < span class = "text-[#e6edf3] " data-astro-cid-2ex44dsa > function findUserByUsername(username) { < / span > < / td > < / tr > < tr data-line = "2" class = "group hover:bg-[#161b22] cursor-pointer transition-colors" title = "Mark line 2 as buggy" data-astro-cid-2ex44dsa > < td class = "w-16 text-right pr-4 select-none" data-astro-cid-2ex44dsa > < span class = "text-[#8b949e] line-number has-hint-color" data-astro-cid-2ex44dsa > 2 < / span > < / td > < td class = "px-4 py-0.5 whitespace-pre" data-astro-cid-2ex44dsa > < span class = "text-[#e6edf3] has-hint-bg bg-[#ff7b7233] px-2 -mx-2" data-astro-cid-2ex44dsa > const query = `SELECT * FROM users WHERE username = ' ${username}' `; < / span > < span class = "ml-2 hint text-[#79c0ff] text-xs hidden" data-astro-cid-2ex44dsa >
• Direct string interpolation allows SQL injection < / span > < / td > < / tr > < tr data-line = "3" class = "group hover:bg-[#161b22] cursor-pointer transition-colors" title = "Mark line 3 as buggy" data-astro-cid-2ex44dsa > < td class = "w-16 text-right pr-4 select-none" data-astro-cid-2ex44dsa > < span class = "text-[#8b949e] line-number " data-astro-cid-2ex44dsa > 3 < / span > < / td > < td class = "px-4 py-0.5 whitespace-pre" data-astro-cid-2ex44dsa > < span class = "text-[#e6edf3] " data-astro-cid-2ex44dsa > return database.query(query); < / span > < / td > < / tr > < tr data-line = "4" class = "group hover:bg-[#161b22] cursor-pointer transition-colors" title = "Mark line 4 as buggy" data-astro-cid-2ex44dsa > < td class = "w-16 text-right pr-4 select-none" data-astro-cid-2ex44dsa > < span class = "text-[#8b949e] line-number " data-astro-cid-2ex44dsa > 4 < / span > < / td > < td class = "px-4 py-0.5 whitespace-pre" data-astro-cid-2ex44dsa > < span class = "text-[#e6edf3] " data-astro-cid-2ex44dsa > } < / span > < / td > < / tr > < tr data-line = "5" class = "group hover:bg-[#161b22] cursor-pointer transition-colors" title = "Mark line 5 as buggy" data-astro-cid-2ex44dsa > < td class = "w-16 text-right pr-4 select-none" data-astro-cid-2ex44dsa > < span class = "text-[#8b949e] line-number " data-astro-cid-2ex44dsa > 5 < / span > < / td > < td class = "px-4 py-0.5 whitespace-pre" data-astro-cid-2ex44dsa > < span class = "text-[#e6edf3] " data-astro-cid-2ex44dsa > < / span > < / td > < / tr > < tr data-line = "6" class = "group hover:bg-[#161b22] cursor-pointer transition-colors" title = "Mark line 6 as buggy" data-astro-cid-2ex44dsa > < td class = "w-16 text-right pr-4 select-none" data-astro-cid-2ex44dsa > < span class = "text-[#8b949e] line-number " data-astro-cid-2ex44dsa > 6 < / span > < / td > < td class = "px-4 py-0.5 whitespace-pre" data-astro-cid-2ex44dsa > < span class = "text-[#e6edf3] " data-astro-cid-2ex44dsa > function deleteUser(userId) { < / span > < / td > < / tr > < tr data-line = "7" class = "group hover:bg-[#161b22] cursor-pointer transition-colors" title = "Mark line 7 as buggy" data-astro-cid-2ex44dsa > < td class = "w-16 text-right pr-4 select-none" data-astro-cid-2ex44dsa > < span class = "text-[#8b949e] line-number has-hint-color" data-astro-cid-2ex44dsa > 7 < / span > < / td > < td class = "px-4 py-0.5 whitespace-pre" data-astro-cid-2ex44dsa > < span class = "text-[#e6edf3] has-hint-bg bg-[#ff7b7233] px-2 -mx-2" data-astro-cid-2ex44dsa > const query = `DELETE FROM users WHERE id = ${userId}`; < / span > < span class = "ml-2 hint text-[#79c0ff] text-xs hidden" data-astro-cid-2ex44dsa >
• Second SQL injection vulnerability in delete operation < / span > < / td > < / tr > < tr data-line = "8" class = "group hover:bg-[#161b22] cursor-pointer transition-colors" title = "Mark line 8 as buggy" data-astro-cid-2ex44dsa > < td class = "w-16 text-right pr-4 select-none" data-astro-cid-2ex44dsa > < span class = "text-[#8b949e] line-number " data-astro-cid-2ex44dsa > 8 < / span > < / td > < td class = "px-4 py-0.5 whitespace-pre" data-astro-cid-2ex44dsa > < span class = "text-[#e6edf3] " data-astro-cid-2ex44dsa > return database.query(query); < / span > < / td > < / tr > < tr data-line = "9" class = "group hover:bg-[#161b22] cursor-pointer transition-colors" title = "Mark line 9 as buggy" data-astro-cid-2ex44dsa > < td class = "w-16 text-right pr-4 select-none" data-astro-cid-2ex44dsa > < span class = "text-[#8b949e] line-number " data-astro-cid-2ex44dsa > 9 < / span > < / td > < td class = "px-4 py-0.5 whitespace-pre" data-astro-cid-2ex44dsa > < span class = "text-[#e6edf3] " data-astro-cid-2ex44dsa > } < / span > < / td > < / tr > < / tbody > < / table > < / div > < / div > < / div > < script client:load >
2026-04-17 13:09:06 +02:00
(() => {
const el = document.querySelector('[data-dv-id]');
if (!el) return;
const buggedLines = new Set();
function updateBuggedState() {
const rows = el.querySelectorAll('tr[data-line]');
rows.forEach(row => {
const lineNum = parseInt(row.getAttribute('data-line') || '0', 10);
row.classList.toggle('bugged', buggedLines.has(lineNum));
});
}
el.addEventListener('click', function(e) {
const target = e.target;
if (!(target instanceof HTMLElement)) return;
const row = target.closest('tr[data-line]');
if (!row) return;
const lineNum = parseInt(row.getAttribute('data-line') || '0', 10);
if (buggedLines.has(lineNum)) {
buggedLines.delete(lineNum);
} else {
buggedLines.add(lineNum);
}
updateBuggedState();
el.dispatchEvent(new CustomEvent('bugged-line-toggle', {
bubbles: true,
detail: { line: lineNum, bugged: buggedLines.has(lineNum), allBugged: [...buggedLines] }
}));
});
})();
< / script > <!-- Fix Submission --> < div id = "fix-panel" class = "mt-6 bg-[#161b22] border border-[#30363d] rounded-md overflow-hidden" data-astro-cid-7fgtuneg > < div class = "bg-[#161b22] px-4 py-3 border-b border-[#30363d] flex items-center justify-between" data-astro-cid-7fgtuneg > < h2 class = "text-lg font-semibold text-[#c9d1d9]" data-astro-cid-7fgtuneg > Submit Your Fix< / h2 > < div id = "bugged-count" class = "text-sm text-[#8b949e]" data-astro-cid-7fgtuneg >
Lines marked: < span id = "bugged-count-num" class = "text-[#f85149] font-semibold" data-astro-cid-7fgtuneg > 0< / span > < / div > < / div > <!-- Marked lines summary --> < div id = "marked-lines-summary" class = "px-4 py-3 border-b border-[#30363d] hidden" data-astro-cid-7fgtuneg > < p class = "text-sm text-[#8b949e] mb-2" data-astro-cid-7fgtuneg > Marked lines:< / p > < div id = "marked-lines-tags" class = "flex flex-wrap gap-2" data-astro-cid-7fgtuneg > < / div > < / div > <!-- Inline fix editor --> < div class = "p-4" data-astro-cid-7fgtuneg > < div class = "mb-4" data-astro-cid-7fgtuneg > < label class = "block text-sm font-medium text-[#c9d1d9] mb-2" data-astro-cid-7fgtuneg >
Line-by-line fix:
< / label > < p class = "text-xs text-[#8b949e] mb-3" data-astro-cid-7fgtuneg > Click a marked line number below to edit its fix.< / p > < div id = "fix-editor-container" class = "space-y-2" data-astro-cid-7fgtuneg > < p id = "fix-editor-placeholder" class = "text-sm text-[#484f58] italic" data-astro-cid-7fgtuneg > Click on lines in the diff above to mark them, then add your fixes here.< / p > < / div > < / div > <!-- Unified diff textarea --> < div class = "mb-4" data-astro-cid-7fgtuneg > < label class = "block text-sm font-medium text-[#c9d1d9] mb-2" data-astro-cid-7fgtuneg >
Or provide as unified diff:
< / label > < textarea id = "diff-textarea" placeholder = "- old line
+ new line" rows="6" class="w-full bg-[#0d1117] border border-[#30363d] text-[#c9d1d9] rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-[#58a6ff] focus:border-transparent text-sm font-mono" data-astro-cid-7fgtuneg>< / textarea > < / div > < div class = "flex gap-3" data-astro-cid-7fgtuneg > < button id = "submit-fix-btn" class = "flex-1 bg-[#1f6feb] hover:bg-[#388bfd] disabled:bg-[#21262d] disabled:text-[#484f58] disabled:cursor-not-allowed text-white font-semibold py-2.5 px-4 rounded-md transition-colors focus:outline-none focus:ring-0" data-astro-cid-7fgtuneg >
Submit Fix
< / button > < button id = "clear-all-btn" class = "bg-[#21262d] hover:bg-[#30363d] text-[#8b949e] font-semibold py-2.5 px-4 rounded-md transition-colors focus:outline-none focus:ring-0" data-astro-cid-7fgtuneg >
Clear All
2026-04-28 15:59:47 +02:00
< / button > < / div > < div id = "submission-message" class = "mt-3 text-sm hidden" data-astro-cid-7fgtuneg > < / div > < / div > < / div > < / main > < / div > < footer class = "border-t border-[#30363d] mt-16" > < div class = "max-w-6xl mx-auto px-4 py-12" > < div class = "grid grid-cols-2 md:grid-cols-4 gap-8" > < div > < h3 class = "text-[#c9d1d9] font-semibold mb-4" > PR Dojo< / h3 > < ul class = "space-y-2" > < li > < a href = "/" class = "text-[#8b949e] text-sm hover:text-[#c9d1d9]" > Challenges< / a > < / li > < li > < a href = "/profile" class = "text-[#8b949e] text-sm hover:text-[#c9d1d9]" > Profile< / a > < / li > < / ul > < / div > < div > < h3 class = "text-[#c9d1d9] font-semibold mb-4" > Learn< / h3 > < ul class = "space-y-2" > < li > < a href = "/about" class = "text-[#8b949e] text-sm hover:text-[#c9d1d9]" > About< / a > < / li > < li > < a href = "/faq" class = "text-[#8b949e] text-sm hover:text-[#c9d1d9]" > FAQ< / a > < / li > < / ul > < / div > < div > < h3 class = "text-[#c9d1d9] font-semibold mb-4" > Legal< / h3 > < ul class = "space-y-2" > < li > < a href = "/imprint" class = "text-[#8b949e] text-sm hover:text-[#c9d1d9]" > Imprint< / a > < / li > < li > < a href = "/privacy" class = "text-[#8b949e] text-sm hover:text-[#c9d1d9]" > Privacy Policy< / a > < / li > < li > < a href = "/terms" class = "text-[#8b949e] text-sm hover:text-[#c9d1d9]" > Terms of Service< / a > < / li > < / ul > < / div > < div > < h3 class = "text-[#c9d1d9] font-semibold mb-4" > Connect< / h3 > < ul class = "space-y-2" > < li > < a href = "https://github.com" target = "_blank" rel = "noopener noreferrer" class = "text-[#8b949e] text-sm hover:text-[#c9d1d9]" > GitHub< / a > < / li > < li > < a href = "https://twitter.com" target = "_blank" rel = "noopener noreferrer" class = "text-[#8b949e] text-sm hover:text-[#c9d1d9]" > Twitter< / a > < / li > < / ul > < / div > < / div > < div class = "border-t border-[#30363d] mt-8 pt-8 text-center" > < p class = "text-[#8b949e] text-sm" > © 2026 PR Dojo. All rights reserved.< / p > < / div > < / div > < / footer > < / body > < / html > < script client:load >
2026-04-17 13:09:06 +02:00
(() => {
const buggedLines = new Set();
const fixEditorContainer = document.getElementById('fix-editor-container');
const markedLinesTags = document.getElementById('marked-lines-tags');
const markedLinesSummary = document.getElementById('marked-lines-summary');
const buggedCountNum = document.getElementById('bugged-count-num');
const submitBtn = document.getElementById('submit-fix-btn');
const clearBtn = document.getElementById('clear-all-btn');
const diffTextarea = document.getElementById('diff-textarea');
const submissionMessage = document.getElementById('submission-message');
const fixEditorPlaceholder = document.getElementById('fix-editor-placeholder');
function updateUI() {
const arr = [...buggedLines].sort((a, b) => a - b);
buggedCountNum.textContent = arr.length.toString();
if (markedLinesTags) {
markedLinesTags.innerHTML = '';
arr.forEach(lineNum => {
const tag = document.createElement('span');
tag.className = 'inline-flex items-center gap-1 bg-[#f8514920] text-[#f85149] text-xs px-2 py-0.5 rounded cursor-pointer hover:bg-[#f8514930] transition-colors';
tag.textContent = `Line ${lineNum}`;
tag.addEventListener('click', () => {
showLineFixEditor(lineNum);
});
markedLinesTags.appendChild(tag);
});
}
if (markedLinesSummary) {
markedLinesSummary.classList.toggle('hidden', arr.length === 0);
}
if (fixEditorPlaceholder) {
fixEditorPlaceholder.classList.toggle('hidden', arr.length > 0);
}
if (submitBtn) {
submitBtn.disabled = arr.length === 0 & & !diffTextarea?.value.trim();
}
}
function showLineFixEditor(lineNum) {
if (!fixEditorContainer) return;
const existing = document.getElementById(`fix-editor-${lineNum}`);
if (existing) {
existing.scrollIntoView({ behavior: 'smooth', block: 'center' });
existing.querySelector('textarea')?.focus();
return;
}
const editorDiv = document.createElement('div');
editorDiv.id = `fix-editor-${lineNum}`;
editorDiv.className = 'bg-[#0d1117] border border-[#30363d] rounded-md p-3';
const header = document.createElement('div');
header.className = 'flex items-center justify-between mb-2';
const label = document.createElement('span');
label.className = 'text-sm font-medium text-[#f85149]';
label.textContent = `Line ${lineNum} — Your fix:`;
const removeBtn = document.createElement('button');
removeBtn.className = 'text-xs text-[#484f58] hover:text-[#f85149] transition-colors';
removeBtn.textContent = '✕';
removeBtn.addEventListener('click', () => {
buggedLines.delete(lineNum);
editorDiv.remove();
updateUI();
});
header.appendChild(label);
header.appendChild(removeBtn);
const textarea = document.createElement('textarea');
textarea.rows = 3;
textarea.className = 'w-full bg-[#0d1117] border border-[#30363d] text-[#c9d1d9] rounded px-2 py-1.5 focus:outline-none focus:ring-2 focus:ring-[#58a6ff] focus:border-transparent text-sm font-mono';
textarea.placeholder = 'Enter the corrected line...';
textarea.addEventListener('input', updateUI);
editorDiv.appendChild(header);
editorDiv.appendChild(textarea);
fixEditorContainer.appendChild(editorDiv);
}
// Listen for bugged-line-toggle events from DiffViewer
document.addEventListener('bugged-line-toggle', (e) => {
const detail = e.detail;
if (detail.bugged) {
buggedLines.add(detail.line);
showLineFixEditor(detail.line);
} else {
buggedLines.delete(detail.line);
const editor = document.getElementById(`fix-editor-${detail.line}`);
if (editor) editor.remove();
}
updateUI();
});
// Diff textarea input
if (diffTextarea) {
diffTextarea.addEventListener('input', updateUI);
}
// Submit
if (submitBtn) {
submitBtn.addEventListener('click', () => {
const lineFixes = {};
buggedLines.forEach(lineNum => {
const editor = document.getElementById(`fix-editor-${lineNum}`);
if (editor) {
const ta = editor.querySelector('textarea');
if (ta?.value.trim()) {
lineFixes[lineNum] = ta.value.trim();
}
}
});
const unifiedDiff = diffTextarea?.value.trim() || '';
if (Object.keys(lineFixes).length === 0 & & !unifiedDiff) {
if (submissionMessage) {
submissionMessage.textContent = 'Please mark some lines or provide a diff.';
submissionMessage.className = 'mt-3 text-sm text-[#f85149]';
submissionMessage.classList.remove('hidden');
}
return;
}
2026-04-28 15:59:47 +02:00
// Reveal bugged lines and hints in the diff viewer
const dvContainer = document.querySelector('.diff-viewer-container');
if (dvContainer) {
dvContainer.classList.add('revealed');
}
2026-04-17 13:09:06 +02:00
// Show success message
if (submissionMessage) {
submissionMessage.textContent = 'Fix submitted! (Backend integration coming soon)';
2026-04-28 15:59:47 +02:00
submissionMessage.className = 'mt-3 text-sm text-[#3ac840]';
2026-04-17 13:09:06 +02:00
submissionMessage.classList.remove('hidden');
}
});
}
// Clear all
if (clearBtn) {
clearBtn.addEventListener('click', () => {
buggedLines.clear();
const editors = fixEditorContainer?.querySelectorAll('[id^="fix-editor-"]');
editors?.forEach(e => e.remove());
if (diffTextarea) diffTextarea.value = '';
if (submissionMessage) submissionMessage.classList.add('hidden');
updateUI();
2026-04-28 15:59:47 +02:00
// Reset bugged state and revealed state in DiffViewer
const dvContainer = document.querySelector('.diff-viewer-container');
if (dvContainer) {
dvContainer.classList.remove('revealed');
}
2026-04-17 13:09:06 +02:00
document.querySelectorAll('tr.bugged').forEach(row => {
row.classList.remove('bugged');
});
});
}
updateUI();
})();
< / script >