Added Repository
This commit is contained in:
88
static/js/add_product.js
Normal file
88
static/js/add_product.js
Normal file
@@ -0,0 +1,88 @@
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const imageInput = document.getElementById('image-input');
|
||||
const imagePreview = document.getElementById('image-preview');
|
||||
const uploadArea = document.getElementById('image-upload-area');
|
||||
|
||||
imageInput.addEventListener('change', function (e) {
|
||||
updatePreview();
|
||||
});
|
||||
|
||||
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
|
||||
uploadArea.addEventListener(eventName, preventDefaults, false);
|
||||
});
|
||||
|
||||
function preventDefaults(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
['dragenter', 'dragover'].forEach(eventName => {
|
||||
uploadArea.addEventListener(eventName, highlight, false);
|
||||
});
|
||||
|
||||
['dragleave', 'drop'].forEach(eventName => {
|
||||
uploadArea.addEventListener(eventName, unhighlight, false);
|
||||
});
|
||||
|
||||
function highlight() {
|
||||
uploadArea.style.borderColor = '#007bff';
|
||||
uploadArea.style.background = '#f8f9fa';
|
||||
}
|
||||
|
||||
function unhighlight() {
|
||||
uploadArea.style.borderColor = '#ccc';
|
||||
uploadArea.style.background = '';
|
||||
}
|
||||
|
||||
uploadArea.addEventListener('drop', handleDrop, false);
|
||||
|
||||
function handleDrop(e) {
|
||||
const dt = e.dataTransfer;
|
||||
const files = dt.files;
|
||||
imageInput.files = files;
|
||||
updatePreview();
|
||||
}
|
||||
|
||||
function updatePreview() {
|
||||
imagePreview.innerHTML = '';
|
||||
const files = imageInput.files;
|
||||
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const file = files[i];
|
||||
if (!file.type.match('image.*')) continue;
|
||||
|
||||
const reader = new FileReader();
|
||||
|
||||
reader.onload = function (e) {
|
||||
const previewItem = document.createElement('div');
|
||||
previewItem.className = 'preview-item';
|
||||
|
||||
const img = document.createElement('img');
|
||||
img.src = e.target.result;
|
||||
|
||||
const removeBtn = document.createElement('button');
|
||||
removeBtn.className = 'remove-image';
|
||||
removeBtn.innerHTML = '×';
|
||||
removeBtn.onclick = function () {
|
||||
previewItem.remove();
|
||||
const dt = new DataTransfer();
|
||||
const inputFiles = imageInput.files;
|
||||
|
||||
for (let j = 0; j < inputFiles.length; j++) {
|
||||
if (j !== i) {
|
||||
dt.items.add(inputFiles[j]);
|
||||
}
|
||||
}
|
||||
|
||||
imageInput.files = dt.files;
|
||||
};
|
||||
|
||||
previewItem.appendChild(img);
|
||||
previewItem.appendChild(removeBtn);
|
||||
imagePreview.appendChild(previewItem);
|
||||
};
|
||||
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
}
|
||||
});
|
||||
118
static/js/edit_product.js
Normal file
118
static/js/edit_product.js
Normal file
@@ -0,0 +1,118 @@
|
||||
let deletedImages = [];
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const imageInput = document.getElementById('image-input');
|
||||
const imagePreview = document.getElementById('image-preview');
|
||||
const uploadArea = document.getElementById('image-upload-area');
|
||||
|
||||
imageInput.addEventListener('change', function (e) {
|
||||
updatePreview();
|
||||
});
|
||||
|
||||
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
|
||||
uploadArea.addEventListener(eventName, preventDefaults, false);
|
||||
});
|
||||
|
||||
function preventDefaults(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
['dragenter', 'dragover'].forEach(eventName => {
|
||||
uploadArea.addEventListener(eventName, highlight, false);
|
||||
});
|
||||
|
||||
['dragleave', 'drop'].forEach(eventName => {
|
||||
uploadArea.addEventListener(eventName, unhighlight, false);
|
||||
});
|
||||
|
||||
function highlight() {
|
||||
uploadArea.style.borderColor = '#007bff';
|
||||
uploadArea.style.background = '#f8f9fa';
|
||||
}
|
||||
|
||||
function unhighlight() {
|
||||
uploadArea.style.borderColor = '#ccc';
|
||||
uploadArea.style.background = '';
|
||||
}
|
||||
|
||||
uploadArea.addEventListener('drop', handleDrop, false);
|
||||
|
||||
function handleDrop(e) {
|
||||
const dt = e.dataTransfer;
|
||||
const files = dt.files;
|
||||
imageInput.files = files;
|
||||
updatePreview();
|
||||
}
|
||||
|
||||
function updatePreview() {
|
||||
imagePreview.innerHTML = '';
|
||||
const files = imageInput.files;
|
||||
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const file = files[i];
|
||||
if (!file.type.match('image.*')) continue;
|
||||
|
||||
const reader = new FileReader();
|
||||
|
||||
reader.onload = function (e) {
|
||||
const previewItem = document.createElement('div');
|
||||
previewItem.className = 'preview-item';
|
||||
|
||||
const img = document.createElement('img');
|
||||
img.src = e.target.result;
|
||||
|
||||
const removeBtn = document.createElement('button');
|
||||
removeBtn.className = 'remove-image';
|
||||
removeBtn.innerHTML = '×';
|
||||
removeBtn.onclick = function () {
|
||||
previewItem.remove();
|
||||
const dt = new DataTransfer();
|
||||
const inputFiles = imageInput.files;
|
||||
|
||||
for (let j = 0; j < inputFiles.length; j++) {
|
||||
if (j !== i) {
|
||||
dt.items.add(inputFiles[j]);
|
||||
}
|
||||
}
|
||||
|
||||
imageInput.files = dt.files;
|
||||
};
|
||||
|
||||
previewItem.appendChild(img);
|
||||
previewItem.appendChild(removeBtn);
|
||||
imagePreview.appendChild(previewItem);
|
||||
};
|
||||
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function deleteImage(imageId) {
|
||||
if (confirm('Delete this image?')) {
|
||||
deletedImages.push(imageId);
|
||||
document.getElementById('deleted-images').value = JSON.stringify(deletedImages);
|
||||
|
||||
const imageItem = document.querySelector('.image-item[data-id="' + imageId + '"]');
|
||||
if (imageItem) {
|
||||
imageItem.style.display = 'none';
|
||||
}
|
||||
|
||||
fetch('/admin/image/delete/' + imageId, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({})
|
||||
}).then(function (response) {
|
||||
return response.json();
|
||||
}).then(function (data) {
|
||||
if (!data.success) {
|
||||
alert('Error deleting image: ' + data.error);
|
||||
}
|
||||
}).catch(function (error) {
|
||||
console.error('Error:', error);
|
||||
});
|
||||
}
|
||||
}
|
||||
24
static/js/home.js
Normal file
24
static/js/home.js
Normal file
@@ -0,0 +1,24 @@
|
||||
document.querySelector('.newsletter-form').addEventListener('submit', function (e) {
|
||||
e.preventDefault();
|
||||
const email = this.querySelector('.newsletter-input').value;
|
||||
|
||||
alert(`Thank you for subscribing with: ${email}\nYou'll hear from us soon!`);
|
||||
this.querySelector('.newsletter-input').value = '';
|
||||
});
|
||||
|
||||
document.querySelectorAll('.product-card-home').forEach(card => {
|
||||
card.addEventListener('mouseenter', function () {
|
||||
const img = this.querySelector('img');
|
||||
if (img) {
|
||||
img.style.transform = 'scale(1.05)';
|
||||
img.style.transition = 'transform 0.3s ease';
|
||||
}
|
||||
});
|
||||
|
||||
card.addEventListener('mouseleave', function () {
|
||||
const img = this.querySelector('img');
|
||||
if (img) {
|
||||
img.style.transform = 'scale(1)';
|
||||
}
|
||||
});
|
||||
});
|
||||
47
static/js/login.js
Normal file
47
static/js/login.js
Normal file
@@ -0,0 +1,47 @@
|
||||
function togglePassword(inputId) {
|
||||
const input = document.getElementById(inputId);
|
||||
const button = event.target;
|
||||
|
||||
if (input.type === 'password') {
|
||||
input.type = 'text';
|
||||
button.textContent = '🙈';
|
||||
} else {
|
||||
input.type = 'password';
|
||||
button.textContent = '👁️';
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const form = document.querySelector('.auth-form');
|
||||
const emailInput = document.getElementById('email');
|
||||
const passwordInput = document.getElementById('password');
|
||||
|
||||
[emailInput, passwordInput].forEach(input => {
|
||||
input.addEventListener('focus', function () {
|
||||
this.parentElement.classList.add('focused');
|
||||
});
|
||||
|
||||
input.addEventListener('blur', function () {
|
||||
this.parentElement.classList.remove('focused');
|
||||
});
|
||||
});
|
||||
|
||||
form.addEventListener('submit', function (e) {
|
||||
const email = emailInput.value.trim();
|
||||
const password = passwordInput.value.trim();
|
||||
|
||||
if (!email || !password) {
|
||||
e.preventDefault();
|
||||
alert('Please fill in all fields');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!email.includes('@')) {
|
||||
e.preventDefault();
|
||||
alert('Please enter a valid email address');
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
});
|
||||
70
static/js/product_detail.js
Normal file
70
static/js/product_detail.js
Normal file
@@ -0,0 +1,70 @@
|
||||
function changeImage(thumbnailElement) {
|
||||
const imageUrl = thumbnailElement.getAttribute('data-image-url');
|
||||
|
||||
document.getElementById('mainImage').src = imageUrl;
|
||||
|
||||
document.querySelectorAll('.thumbnail-container').forEach(thumb => {
|
||||
thumb.classList.remove('active');
|
||||
});
|
||||
thumbnailElement.classList.add('active');
|
||||
}
|
||||
|
||||
function deleteImage(imageId) {
|
||||
if (confirm('Are you sure you want to delete this image?')) {
|
||||
fetch(`/admin/delete-image/${imageId}`, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
const imageElement = document.querySelector(`[data-image-id="${imageId}"]`);
|
||||
if (imageElement) {
|
||||
imageElement.remove();
|
||||
}
|
||||
alert('Image deleted successfully');
|
||||
} else {
|
||||
alert('Failed to delete image');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
alert('Error deleting image');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const thumbnails = document.querySelectorAll('.thumbnail-container');
|
||||
|
||||
thumbnails.forEach((thumb, index) => {
|
||||
thumb.addEventListener('keydown', function (e) {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
e.preventDefault();
|
||||
changeImage(this);
|
||||
}
|
||||
|
||||
if (e.key === 'ArrowRight') {
|
||||
e.preventDefault();
|
||||
const next = thumbnails[index + 1];
|
||||
if (next) {
|
||||
next.focus();
|
||||
changeImage(next);
|
||||
}
|
||||
}
|
||||
|
||||
if (e.key === 'ArrowLeft') {
|
||||
e.preventDefault();
|
||||
const prev = thumbnails[index - 1];
|
||||
if (prev) {
|
||||
prev.focus();
|
||||
changeImage(prev);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
thumb.setAttribute('tabindex', '0');
|
||||
});
|
||||
});
|
||||
3
static/js/products.js
Normal file
3
static/js/products.js
Normal file
@@ -0,0 +1,3 @@
|
||||
document.getElementById('sort').addEventListener('change', function () {
|
||||
this.closest('form').submit();
|
||||
});
|
||||
159
static/js/register.js
Normal file
159
static/js/register.js
Normal file
@@ -0,0 +1,159 @@
|
||||
function togglePassword(inputId) {
|
||||
const input = document.getElementById(inputId);
|
||||
const button = event.target;
|
||||
|
||||
if (input.type === 'password') {
|
||||
input.type = 'text';
|
||||
button.textContent = '🙈';
|
||||
} else {
|
||||
input.type = 'password';
|
||||
button.textContent = '👁️';
|
||||
}
|
||||
}
|
||||
|
||||
function checkPasswordStrength(password) {
|
||||
const strengthBar = document.getElementById('strengthBar');
|
||||
const hints = {
|
||||
lengthHint: document.getElementById('lengthHint'),
|
||||
uppercaseHint: document.getElementById('uppercaseHint'),
|
||||
lowercaseHint: document.getElementById('lowercaseHint'),
|
||||
numberHint: document.getElementById('numberHint'),
|
||||
specialHint: document.getElementById('specialHint')
|
||||
};
|
||||
|
||||
let strength = 0;
|
||||
let messages = [];
|
||||
|
||||
if (password.length >= 8) {
|
||||
strength += 20;
|
||||
hints.lengthHint.style.color = '#28a745';
|
||||
hints.lengthHint.style.textDecoration = 'line-through';
|
||||
} else {
|
||||
hints.lengthHint.style.color = '#666';
|
||||
hints.lengthHint.style.textDecoration = 'none';
|
||||
}
|
||||
|
||||
if (/[A-Z]/.test(password)) {
|
||||
strength += 20;
|
||||
hints.uppercaseHint.style.color = '#28a745';
|
||||
hints.uppercaseHint.style.textDecoration = 'line-through';
|
||||
} else {
|
||||
hints.uppercaseHint.style.color = '#666';
|
||||
hints.uppercaseHint.style.textDecoration = 'none';
|
||||
}
|
||||
|
||||
if (/[a-z]/.test(password)) {
|
||||
strength += 20;
|
||||
hints.lowercaseHint.style.color = '#28a745';
|
||||
hints.lowercaseHint.style.textDecoration = 'line-through';
|
||||
} else {
|
||||
hints.lowercaseHint.style.color = '#666';
|
||||
hints.lowercaseHint.style.textDecoration = 'none';
|
||||
}
|
||||
|
||||
if (/[0-9]/.test(password)) {
|
||||
strength += 20;
|
||||
hints.numberHint.style.color = '#28a745';
|
||||
hints.numberHint.style.textDecoration = 'line-through';
|
||||
} else {
|
||||
hints.numberHint.style.color = '#666';
|
||||
hints.numberHint.style.textDecoration = 'none';
|
||||
}
|
||||
|
||||
if (/[^A-Za-z0-9]/.test(password)) {
|
||||
strength += 20;
|
||||
hints.specialHint.style.color = '#28a745';
|
||||
hints.specialHint.style.textDecoration = 'line-through';
|
||||
} else {
|
||||
hints.specialHint.style.color = '#666';
|
||||
hints.specialHint.style.textDecoration = 'none';
|
||||
}
|
||||
|
||||
strengthBar.className = 'strength-bar';
|
||||
if (strength <= 25) {
|
||||
strengthBar.classList.add('strength-weak');
|
||||
} else if (strength <= 50) {
|
||||
strengthBar.classList.add('strength-medium');
|
||||
} else if (strength <= 75) {
|
||||
strengthBar.classList.add('strength-strong');
|
||||
} else {
|
||||
strengthBar.classList.add('strength-very-strong');
|
||||
}
|
||||
strengthBar.style.width = strength + '%';
|
||||
}
|
||||
|
||||
function checkPasswordMatch() {
|
||||
const password = document.getElementById('password').value;
|
||||
const confirmPassword = document.getElementById('confirm_password').value;
|
||||
const matchElement = document.getElementById('passwordMatch');
|
||||
|
||||
if (!confirmPassword) {
|
||||
matchElement.textContent = '';
|
||||
matchElement.style.color = '';
|
||||
return;
|
||||
}
|
||||
|
||||
if (password === confirmPassword) {
|
||||
matchElement.textContent = '✓ Passwords match';
|
||||
matchElement.style.color = '#28a745';
|
||||
} else {
|
||||
matchElement.textContent = '✗ Passwords do not match';
|
||||
matchElement.style.color = '#dc3545';
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const form = document.querySelector('.auth-form');
|
||||
const emailInput = document.getElementById('email');
|
||||
const passwordInput = document.getElementById('password');
|
||||
const confirmInput = document.getElementById('confirm_password');
|
||||
const termsCheckbox = document.getElementById('terms');
|
||||
|
||||
[emailInput, passwordInput, confirmInput].forEach(input => {
|
||||
input.addEventListener('focus', function () {
|
||||
this.parentElement.classList.add('focused');
|
||||
});
|
||||
|
||||
input.addEventListener('blur', function () {
|
||||
this.parentElement.classList.remove('focused');
|
||||
});
|
||||
});
|
||||
|
||||
form.addEventListener('submit', function (e) {
|
||||
const email = emailInput.value.trim();
|
||||
const password = passwordInput.value.trim();
|
||||
const confirmPassword = confirmInput.value.trim();
|
||||
|
||||
if (!email || !password || !confirmPassword) {
|
||||
e.preventDefault();
|
||||
alert('Please fill in all fields');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!email.includes('@')) {
|
||||
e.preventDefault();
|
||||
alert('Please enter a valid email address');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (password.length < 8) {
|
||||
e.preventDefault();
|
||||
alert('Password must be at least 8 characters long');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (password !== confirmPassword) {
|
||||
e.preventDefault();
|
||||
alert('Passwords do not match');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!termsCheckbox.checked) {
|
||||
e.preventDefault();
|
||||
alert('You must agree to the Terms of Service');
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user