feat: add toggle switch for disabling error feedback and persist user settings

This commit is contained in:
Michael Czechowski
2025-05-20 00:37:36 +02:00
parent 7cdbf0807f
commit 0f368b7373
4 changed files with 126 additions and 5 deletions

View File

@@ -9,7 +9,10 @@ const state = {
currentLessonIndex: 0,
modules: [],
userProgress: {}, // Format: { moduleId: { completed: [0, 2, 3], current: 4 } }
userCodeBeforeValidation: "" // Track user code state before validation
userCodeBeforeValidation: "", // Track user code state before validation
userSettings: {
disableFeedbackErrors: false
}
};
// DOM elements
@@ -36,7 +39,8 @@ const elements = {
lessonContainer: document.querySelector(".lesson-container"),
editorContent: document.querySelector(".editor-content"),
codeEditor: document.querySelector(".code-editor"),
validationIndicators: document.querySelector(".validation-indicators-container")
validationIndicators: document.querySelector(".validation-indicators-container"),
disableFeedbackToggle: document.getElementById("disable-feedback-toggle")
};
// Initialize the lesson engine
@@ -55,6 +59,32 @@ function saveUserProgress() {
localStorage.setItem("codeCrispies.Progress", JSON.stringify(state.userProgress));
}
function loadUserSettings() {
const savedSettings = localStorage.getItem("codeCrispies.settings");
if (savedSettings) {
try {
const settings = JSON.parse(savedSettings);
state.userSettings = { ...state.userSettings, ...settings };
// Apply saved settings to UI
elements.disableFeedbackToggle.checked = !state.userSettings.disableFeedbackErrors;
} catch (e) {
console.error("Error loading user settings:", e);
}
}
}
function saveUserSettings() {
localStorage.setItem("codeCrispies.settings", JSON.stringify(state.userSettings));
}
function initFeedbackToggle() {
elements.disableFeedbackToggle.addEventListener("change", (e) => {
state.userSettings.disableFeedbackErrors = !e.target.checked;
saveUserSettings();
});
}
// Initialize the module list
async function initializeModules() {
try {
@@ -102,9 +132,9 @@ function updateModuleSelectorButtonProgress() {
position: absolute;
bottom: 0;
left: 0;
height: 3px;
height: 2px;
width: ${percentComplete}%;
background-color: var(--success-color);
background-color: var(--primary-color);
border-radius: 0 3px 3px 0;
`;
@@ -545,7 +575,9 @@ function handleTabKey(e) {
// Initialize the application
function init() {
loadUserProgress();
initializeModules();
loadUserSettings();
initializeModules().catch(console.error);
initFeedbackToggle();
// Event listeners
elements.prevBtn.addEventListener("click", prevLesson);
@@ -562,6 +594,12 @@ function init() {
elements.codeInput.focus();
});
// Load user settings
elements.disableFeedbackToggle.addEventListener("change", (e) => {
state.userSettings.disableFeedbackErrors = !e.target.checked;
saveUserSettings();
});
// Add tab key handler for the code input
elements.codeInput.addEventListener("keydown", handleTabKey);

View File

@@ -94,6 +94,15 @@ export function showFeedback(isSuccess, message) {
// Clear any existing feedback
clearFeedback();
// Check if error feedback is disabled in user settings
if (!isSuccess) {
const disableFeedbackErrors = !document.getElementById("disable-feedback-toggle").checked;
if (disableFeedbackErrors) {
// Skip showing error feedback if disabled
return;
}
}
// Create feedback element
feedbackElement = document.createElement("div");
feedbackElement.classList.add(isSuccess ? "feedback-success" : "feedback-error");

View File

@@ -16,6 +16,13 @@
</div>
<nav class="main-nav">
<ul>
<li class="toggle-container">
<label class="toggle-switch" title="Toggle error feedback">
<input type="checkbox" id="disable-feedback-toggle" checked />
<span class="toggle-slider"></span>
<span class="toggle-label">Show Hints</span>
</label>
</li>
<li><button id="module-selector-btn" class="btn">Progress</button></li>
<li><button id="reset-btn" class="btn">Reset Progress</button></li>
<li><button id="help-btn" class="btn">Help</button></li>

View File

@@ -641,3 +641,70 @@ code {
background-color: var(--success-color-dark);
border-color: var(--success-color-dark);
}
/**
* CSS to style the toggle switch in the header
* Add this to your main.css file
*/
/* Toggle Switch Styles */
.toggle-container {
display: flex;
align-items: center;
margin-left: 10px;
}
.toggle-switch {
position: relative;
display: inline-block;
height: 24px;
display: flex;
align-items: center;
cursor: pointer;
}
.toggle-switch input {
opacity: 0;
width: 0;
height: 0;
}
.toggle-slider {
position: relative;
display: inline-block;
width: 40px;
height: 20px;
background-color: #ccc;
border-radius: 34px;
transition: 0.4s;
margin-right: 8px;
}
.toggle-slider:before {
position: absolute;
content: "";
height: 16px;
width: 16px;
left: 2px;
bottom: 2px;
background-color: white;
border-radius: 50%;
transition: 0.4s;
}
input:checked + .toggle-slider {
background-color: var(--primary-color);
}
input:focus + .toggle-slider {
box-shadow: 0 0 1px var(--primary-color);
}
input:checked + .toggle-slider:before {
transform: translateX(20px);
}
.toggle-label {
font-size: 14px;
color: var(--text-color);
}