Added Repository

This commit is contained in:
2026-01-30 14:02:35 +03:30
parent 8917e625a5
commit dbc8f70b4a
53 changed files with 7758 additions and 2 deletions

88
static/js/add_product.js Normal file
View 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
View 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
View 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
View 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;
});
});

View 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
View File

@@ -0,0 +1,3 @@
document.getElementById('sort').addEventListener('change', function () {
this.closest('form').submit();
});

159
static/js/register.js Normal file
View 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;
});
});