feat: add toggle switch for disabling error feedback and persist user settings
This commit is contained in:
48
src/app.js
48
src/app.js
@@ -9,7 +9,10 @@ const state = {
|
|||||||
currentLessonIndex: 0,
|
currentLessonIndex: 0,
|
||||||
modules: [],
|
modules: [],
|
||||||
userProgress: {}, // Format: { moduleId: { completed: [0, 2, 3], current: 4 } }
|
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
|
// DOM elements
|
||||||
@@ -36,7 +39,8 @@ const elements = {
|
|||||||
lessonContainer: document.querySelector(".lesson-container"),
|
lessonContainer: document.querySelector(".lesson-container"),
|
||||||
editorContent: document.querySelector(".editor-content"),
|
editorContent: document.querySelector(".editor-content"),
|
||||||
codeEditor: document.querySelector(".code-editor"),
|
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
|
// Initialize the lesson engine
|
||||||
@@ -55,6 +59,32 @@ function saveUserProgress() {
|
|||||||
localStorage.setItem("codeCrispies.Progress", JSON.stringify(state.userProgress));
|
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
|
// Initialize the module list
|
||||||
async function initializeModules() {
|
async function initializeModules() {
|
||||||
try {
|
try {
|
||||||
@@ -102,9 +132,9 @@ function updateModuleSelectorButtonProgress() {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
height: 3px;
|
height: 2px;
|
||||||
width: ${percentComplete}%;
|
width: ${percentComplete}%;
|
||||||
background-color: var(--success-color);
|
background-color: var(--primary-color);
|
||||||
border-radius: 0 3px 3px 0;
|
border-radius: 0 3px 3px 0;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -545,7 +575,9 @@ function handleTabKey(e) {
|
|||||||
// Initialize the application
|
// Initialize the application
|
||||||
function init() {
|
function init() {
|
||||||
loadUserProgress();
|
loadUserProgress();
|
||||||
initializeModules();
|
loadUserSettings();
|
||||||
|
initializeModules().catch(console.error);
|
||||||
|
initFeedbackToggle();
|
||||||
|
|
||||||
// Event listeners
|
// Event listeners
|
||||||
elements.prevBtn.addEventListener("click", prevLesson);
|
elements.prevBtn.addEventListener("click", prevLesson);
|
||||||
@@ -562,6 +594,12 @@ function init() {
|
|||||||
elements.codeInput.focus();
|
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
|
// Add tab key handler for the code input
|
||||||
elements.codeInput.addEventListener("keydown", handleTabKey);
|
elements.codeInput.addEventListener("keydown", handleTabKey);
|
||||||
|
|
||||||
|
|||||||
@@ -94,6 +94,15 @@ export function showFeedback(isSuccess, message) {
|
|||||||
// Clear any existing feedback
|
// Clear any existing feedback
|
||||||
clearFeedback();
|
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
|
// Create feedback element
|
||||||
feedbackElement = document.createElement("div");
|
feedbackElement = document.createElement("div");
|
||||||
feedbackElement.classList.add(isSuccess ? "feedback-success" : "feedback-error");
|
feedbackElement.classList.add(isSuccess ? "feedback-success" : "feedback-error");
|
||||||
|
|||||||
@@ -16,6 +16,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<nav class="main-nav">
|
<nav class="main-nav">
|
||||||
<ul>
|
<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="module-selector-btn" class="btn">Progress</button></li>
|
||||||
<li><button id="reset-btn" class="btn">Reset Progress</button></li>
|
<li><button id="reset-btn" class="btn">Reset Progress</button></li>
|
||||||
<li><button id="help-btn" class="btn">Help</button></li>
|
<li><button id="help-btn" class="btn">Help</button></li>
|
||||||
|
|||||||
67
src/main.css
67
src/main.css
@@ -641,3 +641,70 @@ code {
|
|||||||
background-color: var(--success-color-dark);
|
background-color: var(--success-color-dark);
|
||||||
border-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);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user