enhance UI, notif prevent copy paste jadi satu dengan succeas card tempatnya dan image resize

master
a2nr 2026-01-16 21:25:28 +07:00
parent 7c1bfdc35a
commit 2c07b8518e
3 changed files with 148 additions and 33 deletions

View File

@ -24,7 +24,8 @@ body {
.lesson-content h1, .lesson-content h2, .lesson-content h3 {
color: #2c3e50;
margin-top: 20px;
margin-top: 30px;
margin-bottom: 20px;
}
.lesson-content h1 {
@ -33,8 +34,22 @@ body {
}
.lesson-content p {
line-height: 1.6;
margin-bottom: 15px;
line-height: 1.8;
margin-bottom: 20px;
}
/* Add spacing after other block elements */
.lesson-content ul, .lesson-content ol {
margin-top: 15px;
margin-bottom: 20px;
}
.lesson-content blockquote {
margin-top: 20px;
margin-bottom: 20px;
padding: 15px 20px;
border-left: 4px solid #3498db;
background-color: #f8f9fa;
}
.lesson-content code {
@ -160,10 +175,46 @@ body {
padding: 10px;
}
.lesson-content img {
.lesson-content img, .home-content img {
max-width: 100%;
height: auto;
margin: 10px 0;
margin: 15px 0;
display: block;
cursor: pointer;
transition: transform 0.3s ease;
object-fit: contain; /* Ensures the entire image is visible within its bounds */
}
.lesson-content img.zoomable-img {
max-width: 100%;
height: auto;
margin: 15px 0;
display: block;
cursor: zoom-in;
transition: transform 0.3s ease;
object-fit: contain; /* Ensures the entire image is visible within its bounds */
}
.lesson-content img.zoomable-img.enlarged {
cursor: zoom-out;
max-width: 95vw;
max-height: 90vh;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 1050; /* High z-index to appear above other elements */
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
}
.lesson-content img.zoomable-img {
max-width: 100%;
height: auto;
margin: 15px 0;
display: block;
cursor: zoom-in;
transition: transform 0.3s ease;
object-fit: contain; /* Ensures the entire image is visible within its bounds */
}
.lesson-content figure {

View File

@ -354,6 +354,38 @@
studentTokenInput.disabled = false;
});
}
// Image zoom functionality for home page
document.addEventListener('DOMContentLoaded', function() {
// Select all images inside home content
const homeImages = document.querySelectorAll('.home-content img');
homeImages.forEach(img => {
// Add zoomable-img class to make them zoomable
if (!img.classList.contains('zoomable-img')) {
img.classList.add('zoomable-img');
}
img.addEventListener('click', function() {
// Toggle enlarged class to zoom in/out
this.classList.toggle('enlarged');
// Prevent default behavior to avoid any conflicts
if (event) {
event.preventDefault();
event.stopPropagation();
}
});
});
// Add event listener to close enlarged images when clicking outside
document.addEventListener('click', function(event) {
const enlargedImg = document.querySelector('.home-content img.enlarged');
if (enlargedImg && !event.target.classList.contains('zoomable-img')) {
enlargedImg.classList.remove('enlarged');
}
});
});
});
</script>
</body>

View File

@ -110,6 +110,12 @@
<strong>Tugas anda berhasil!</strong> Output sesuai dengan yang diharapkan.
</div>
<!-- Warning message card for copy-paste detection -->
<div id="warning-message" class="alert alert-danger d-none mt-3" role="alert">
<i class="fas fa-exclamation-triangle me-2"></i>
<span id="warning-message-text">Peringatan: Copy-paste tidak diperbolehkan. Silakan ketik kode Anda secara manual.</span>
</div>
<div id="output" class="mt-3 p-3 border rounded bg-light d-none" style="max-height: 200px; overflow-y: auto;">
<div class="d-flex justify-content-between align-items-center mb-2">
<h5 class="mb-0"><i class="fas fa-terminal"></i> Output</h5>
@ -379,40 +385,39 @@
showCopyPasteNotification('Cut detected. Cut is not allowed in the code editor. Please type your code manually.');
};
// Allow context menu (right-click) but prevent paste actions
// We'll handle paste operations separately in the paste event
// Prevent context menu (right-click) on the code editor to avoid paste options
codeEditor.addEventListener('contextmenu', function(e) {
e.preventDefault();
e.stopPropagation();
return false;
});
// Device detection function
// Device detection function - updated to consider screen size as well
function isMobileDevice() {
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
// Check both user agent and screen size to determine if it's a mobile device
const isUserAgentMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
// Also check screen dimensions - if screen width is small, likely mobile device
const isScreenSmall = window.innerWidth <= 768 || window.screen.width <= 768;
// Return true if either condition is met
return isUserAgentMobile || isScreenSmall;
}
// Function to show a temporary notification about copy-paste detection
// Function to show a temporary warning card about copy-paste detection
function showCopyPasteNotification(message) {
// Create or update notification element
let notificationEl = document.getElementById('copy-paste-notification');
if (!notificationEl) {
notificationEl = document.createElement('div');
notificationEl.id = 'copy-paste-notification';
notificationEl.style.position = 'fixed';
notificationEl.style.top = '20px';
notificationEl.style.right = '20px';
notificationEl.style.padding = '10px 15px';
notificationEl.style.backgroundColor = '#dc3545';
notificationEl.style.color = 'white';
notificationEl.style.borderRadius = '4px';
notificationEl.style.zIndex = '10000';
notificationEl.style.boxShadow = '0 2px 10px rgba(0,0,0,0.2)';
document.body.appendChild(notificationEl);
const warningElement = document.getElementById('warning-message');
const warningTextElement = document.getElementById('warning-message-text');
if (warningElement && warningTextElement) {
warningTextElement.textContent = message;
warningElement.classList.remove('d-none');
// Hide warning after 5 seconds
setTimeout(() => {
warningElement.classList.add('d-none');
}, 5000);
}
notificationEl.textContent = message;
notificationEl.style.display = 'block';
// Hide notification after 3 seconds
setTimeout(() => {
notificationEl.style.display = 'none';
}, 3000);
}
// Enhanced mobile clipboard detection algorithm
@ -991,6 +996,33 @@
}
});
}
// Image zoom functionality
document.addEventListener('DOMContentLoaded', function() {
// Select all images inside lesson content
const lessonImages = document.querySelectorAll('.lesson-content img');
lessonImages.forEach(img => {
// Add zoomable-img class to make them zoomable
img.classList.add('zoomable-img');
img.addEventListener('click', function() {
// Toggle enlarged class to zoom in/out
this.classList.toggle('enlarged');
// Prevent default behavior to avoid any conflicts
event.preventDefault();
});
});
// Add event listener to close enlarged images when clicking outside
document.addEventListener('click', function(event) {
const enlargedImg = document.querySelector('.lesson-content img.enlarged');
if (enlargedImg && !event.target.classList.contains('zoomable-img')) {
enlargedImg.classList.remove('enlarged');
}
});
});
});
</script>
</body>