Files
Unimarket/admin/edit_product.php
T
2025-06-24 07:54:24 +08:00

564 lines
22 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
require_once '../includes/auth_functions.php';
redirectIfNotLoggedIn();
redirectIfNotAdmin();
require_once '../config/database.php';
$success_message = '';
$error_message = '';
// Get product ID from URL
$product_id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
// Fetch product details
$stmt = $pdo->prepare("SELECT * FROM products WHERE product_id = ? AND owner_id = ?");
$stmt->execute([$product_id, $_SESSION['user_id']]);
$product = $stmt->fetch();
if (!$product) {
header('Location: dashboard.php');
exit;
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = trim($_POST['name']);
$description = trim($_POST['description']);
$price = trim($_POST['price']);
$category = trim($_POST['category']);
$subcategory = trim($_POST['subcategory']);
$stock_quantity = (int)$_POST['stock_quantity'];
// Get size data if category is clothes
$size_data = null;
if ($category === 'clothes' && isset($_POST['sizes']) && isset($_POST['size_quantities'])) {
$sizes = $_POST['sizes'];
$quantities = $_POST['size_quantities'];
$size_data = [];
for ($i = 0; $i < count($sizes); $i++) {
if (!empty($sizes[$i]) && isset($quantities[$i]) && $quantities[$i] > 0) {
$size_data[$sizes[$i]] = (int)$quantities[$i];
}
}
// Update stock quantity based on sizes
$stock_quantity = array_sum($size_data);
}
// Validate inputs
if (empty($name) || empty($description) || empty($price) || empty($stock_quantity)) {
$error_message = 'Please fill in all required fields.';
} elseif (!is_numeric($price) || $price <= 0) {
$error_message = 'Please enter a valid price.';
} elseif ($stock_quantity < 0) {
$error_message = 'Stock quantity cannot be negative.';
} elseif ($category === 'clothes' && empty($size_data)) {
$error_message = 'Please add at least one size with quantity.';
} else {
try {
// Handle image upload
$image_path = $product['image_path']; // Keep existing image by default
if (isset($_FILES['image']) && $_FILES['image']['error'] === UPLOAD_ERR_OK) {
$upload_dir = '../uploads/products/';
if (!file_exists($upload_dir)) {
mkdir($upload_dir, 0777, true);
}
$file_extension = strtolower(pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION));
$allowed_extensions = ['jpg', 'jpeg', 'png', 'gif'];
if (!in_array($file_extension, $allowed_extensions)) {
throw new Exception('Invalid file type. Only JPG, JPEG, PNG, and GIF files are allowed.');
}
$image_path = uniqid() . '.' . $file_extension;
$upload_path = $upload_dir . $image_path;
if (!move_uploaded_file($_FILES['image']['tmp_name'], $upload_path)) {
throw new Exception('Failed to upload image.');
}
// Delete old image if exists
if ($product['image_path'] && file_exists($upload_dir . $product['image_path'])) {
unlink($upload_dir . $product['image_path']);
}
}
if (empty($error_message)) {
$pdo->beginTransaction();
$stmt = $pdo->prepare("
UPDATE products
SET name = ?, description = ?, price = ?, category = ?, Sub_Cat = ?,
stock_quantity = ?, image_path = ?, size_data = ?
WHERE product_id = ? AND owner_id = ?
");
$stmt->execute([
$name,
$description,
$price,
$category,
$subcategory,
$stock_quantity,
$image_path,
$size_data ? json_encode($size_data) : null,
$product_id,
$_SESSION['user_id']
]);
$pdo->commit();
$success_message = 'Product updated successfully!';
// Refresh product data
$stmt = $pdo->prepare("SELECT * FROM products WHERE product_id = ? AND owner_id = ?");
$stmt->execute([$product_id, $_SESSION['user_id']]);
$product = $stmt->fetch();
}
} catch (Exception $e) {
$pdo->rollBack();
$error_message = $e->getMessage();
}
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Edit Product - UniMarket</title>
<link rel="stylesheet" href="/assets/css/style.css">
<link rel="stylesheet" href="/assets/css/responsive.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
<style>
.edit-product {
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.form-group {
margin-bottom: 20px;
}
.form-group label {
display: block;
margin-bottom: 5px;
font-weight: 500;
}
.form-group input[type="text"],
.form-group input[type="number"],
.form-group textarea,
.form-group select {
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 16px;
}
.form-group textarea {
height: 150px;
resize: vertical;
}
.btn-submit {
background-color: #4CAF50;
color: white;
padding: 12px 24px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
.btn-submit:hover {
background-color: #45a049;
}
.alert {
padding: 15px;
margin-bottom: 20px;
border-radius: 4px;
}
.alert-success {
background-color: #dff0d8;
color: #3c763d;
border: 1px solid #d6e9c6;
}
.alert-error {
background-color: #f2dede;
color: #a94442;
border: 1px solid #ebccd1;
}
.back-button {
display: inline-flex;
align-items: center;
gap: 8px;
color: #6c757d;
text-decoration: none;
margin-bottom: 20px;
font-weight: 500;
transition: color 0.3s ease;
}
.back-button:hover {
color: #495057;
}
.back-button i {
font-size: 1.1rem;
}
.image-preview {
max-width: 200px;
margin-top: 10px;
}
.size-row {
display: flex;
gap: 10px;
margin-bottom: 10px;
align-items: center;
}
.size-select, .size-quantity {
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
}
.size-select {
width: 100px;
}
.size-quantity {
width: 100px;
}
.btn-remove-size {
background: #ff4444;
color: white;
border: none;
border-radius: 4px;
width: 30px;
height: 30px;
cursor: pointer;
font-size: 18px;
display: flex;
align-items: center;
justify-content: center;
}
.btn-add-size {
background: var(--primary-color);
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
margin-top: 10px;
}
.btn-add-size:hover {
background: var(--primary-dark);
}
</style>
</head>
<body>
<?php include '../includes/header.php'; ?>
<div class="container edit-product">
<a href="dashboard.php" class="back-button">
<i class="fas fa-arrow-left"></i> Back to Dashboard
</a>
<h1>Edit Product</h1>
<?php if ($success_message): ?>
<div class="alert alert-success">
<?php echo $success_message; ?>
</div>
<?php endif; ?>
<?php if ($error_message): ?>
<div class="alert alert-error">
<?php echo $error_message; ?>
</div>
<?php endif; ?>
<form method="POST" enctype="multipart/form-data">
<div class="form-group">
<label for="name">Product Name*</label>
<input type="text" id="name" name="name" value="<?php echo htmlspecialchars($product['name']); ?>" required>
</div>
<div class="form-group">
<label for="description">Description*</label>
<textarea id="description" name="description" required><?php echo htmlspecialchars($product['description']); ?></textarea>
</div>
<div class="form-group">
<label for="price">Price*</label>
<input type="number" id="price" name="price" step="0.01" min="0" value="<?php echo htmlspecialchars($product['price']); ?>" required>
</div>
<div class="form-group">
<label for="category">Category*</label>
<select id="category" name="category" onchange="updateSubcategories()" required>
<option value="">Select a category</option>
<option value="clothes" <?php echo $product['category'] === 'clothes' ? 'selected' : ''; ?>>Clothes</option>
<option value="school_supplies" <?php echo $product['category'] === 'school_supplies' ? 'selected' : ''; ?>>School Supplies</option>
<option value="others" <?php echo $product['category'] === 'others' ? 'selected' : ''; ?>>Others</option>
</select>
</div>
<div class="form-group" id="subcategoryGroup" style="display: none;">
<label for="subcategory">Subcategory*</label>
<select id="subcategory" name="subcategory" onchange="handleSubcategoryChange()" required>
<option value="">Select a subcategory</option>
</select>
<input type="text" id="customSubcategory" name="custom_subcategory" style="display: none;" placeholder="Enter subcategory">
</div>
<div class="form-group" id="sizeGroup" style="display: <?php echo $product['category'] === 'clothes' ? 'block' : 'none'; ?>;">
<label>Sizes and Quantities*</label>
<div id="sizeContainer">
<?php
$size_data = json_decode($product['size_data'], true);
if ($size_data) {
foreach ($size_data as $size => $quantity) {
echo '<div class="size-row">';
echo '<select class="size-select" name="sizes[]">';
echo '<option value="XS" ' . ($size === 'XS' ? 'selected' : '') . '>XS</option>';
echo '<option value="S" ' . ($size === 'S' ? 'selected' : '') . '>S</option>';
echo '<option value="M" ' . ($size === 'M' ? 'selected' : '') . '>M</option>';
echo '<option value="L" ' . ($size === 'L' ? 'selected' : '') . '>L</option>';
echo '<option value="XL" ' . ($size === 'XL' ? 'selected' : '') . '>XL</option>';
echo '</select>';
echo '<input type="number" class="size-quantity" name="size_quantities[]" min="0" value="' . $quantity . '" required>';
echo '<button type="button" class="btn-remove-size" onclick="removeSize(this)">×</button>';
echo '</div>';
}
}
?>
</div>
<button type="button" class="btn-add-size" onclick="addSize()">Add Size</button>
</div>
<div class="form-group" id="stockGroup" style="display: <?php echo $product['category'] === 'clothes' ? 'none' : 'block'; ?>;">
<label for="stock_quantity">Stock Quantity*</label>
<input type="number" id="stock_quantity" name="stock_quantity" min="0" value="<?php echo htmlspecialchars($product['stock_quantity']); ?>" required>
</div>
<div class="form-group">
<label for="image">Product Image</label>
<?php if ($product['image_path']): ?>
<img src="/uploads/products/<?php echo htmlspecialchars($product['image_path']); ?>" class="image-preview" style="display: block;">
<?php endif; ?>
<input type="file" id="image" name="image" accept="image/*" onchange="previewImage(this)">
<img id="imagePreview" class="image-preview">
</div>
<button type="submit" class="btn-submit">Update Product</button>
</form>
</div>
<script>
const subcategories = {
clothes: [
'T-Shirts',
'Pants',
'PE Uniform',
'University Uniform'
],
school_supplies: [
'Notebooks',
'Pens',
'Pencils',
'Highlighters',
'Markers',
'Art Supplies',
'Paper',
'Folders',
'Binders',
'Staplers'
],
others: [
'University Lace',
'Hygiene Products',
'Seals',
'Calculator',
'ID Holders'
]
};
function updateSubcategories() {
const categorySelect = document.getElementById('category');
const subcategorySelect = document.getElementById('subcategory');
const subcategoryGroup = document.getElementById('subcategoryGroup');
const customSubcategory = document.getElementById('customSubcategory');
const sizeGroup = document.getElementById('sizeGroup');
const stockQuantityInput = document.getElementById('stock_quantity');
const selectedCategory = categorySelect.value;
// Clear current options
subcategorySelect.innerHTML = '<option value="">Select a subcategory</option>';
if (selectedCategory && subcategories[selectedCategory]) {
// Show subcategory group
subcategoryGroup.style.display = 'block';
subcategorySelect.style.display = 'block';
customSubcategory.style.display = 'none';
// Show/hide size group based on category
if (selectedCategory === 'clothes') {
sizeGroup.style.display = 'block';
stockQuantityInput.style.display = 'none';
stockQuantityInput.value = calculateTotalSizeQuantity();
} else {
sizeGroup.style.display = 'none';
stockQuantityInput.style.display = 'block';
}
// Add new options
subcategories[selectedCategory].forEach(subcategory => {
const option = document.createElement('option');
option.value = subcategory.toLowerCase().replace(/\s+/g, '_');
option.textContent = subcategory;
subcategorySelect.appendChild(option);
});
// Add custom option
const customOption = document.createElement('option');
customOption.value = 'custom';
customOption.textContent = 'Other (Type your own)';
subcategorySelect.appendChild(customOption);
} else {
// Hide subcategory group if no category selected
subcategoryGroup.style.display = 'none';
sizeGroup.style.display = 'none';
stockQuantityInput.style.display = 'block';
}
}
function handleSubcategoryChange() {
const subcategorySelect = document.getElementById('subcategory');
const customSubcategory = document.getElementById('customSubcategory');
if (subcategorySelect.value === 'custom') {
subcategorySelect.style.display = 'none';
customSubcategory.style.display = 'block';
customSubcategory.focus();
customSubcategory.required = true;
subcategorySelect.name = 'subcategory_placeholder';
customSubcategory.name = 'subcategory';
} else {
subcategorySelect.style.display = 'block';
customSubcategory.style.display = 'none';
customSubcategory.required = false;
subcategorySelect.name = 'subcategory';
customSubcategory.name = 'custom_subcategory';
}
}
function calculateTotalSizeQuantity() {
const quantities = document.getElementsByName('size_quantities[]');
let total = 0;
for (let input of quantities) {
total += parseInt(input.value) || 0;
}
return total;
}
function updateTotalQuantity() {
const stockQuantityInput = document.getElementById('stock_quantity');
stockQuantityInput.value = calculateTotalSizeQuantity();
}
function addSize() {
const container = document.getElementById('sizeContainer');
const row = document.createElement('div');
row.className = 'size-row';
const sizeSelect = document.createElement('select');
sizeSelect.className = 'size-select';
sizeSelect.name = 'sizes[]';
['XS', 'S', 'M', 'L', 'XL'].forEach(size => {
const option = document.createElement('option');
option.value = size;
option.textContent = size;
sizeSelect.appendChild(option);
});
const quantityInput = document.createElement('input');
quantityInput.type = 'number';
quantityInput.className = 'size-quantity';
quantityInput.name = 'size_quantities[]';
quantityInput.min = '0';
quantityInput.required = true;
const removeButton = document.createElement('button');
removeButton.type = 'button';
removeButton.className = 'btn-remove-size';
removeButton.textContent = '×';
removeButton.onclick = function() { removeSize(this); };
row.appendChild(sizeSelect);
row.appendChild(quantityInput);
row.appendChild(removeButton);
container.appendChild(row);
}
function removeSize(button) {
button.parentElement.remove();
}
function previewImage(input) {
const preview = document.getElementById('imagePreview');
if (input.files && input.files[0]) {
const reader = new FileReader();
reader.onload = function(e) {
preview.src = e.target.result;
preview.style.display = 'block';
}
reader.readAsDataURL(input.files[0]);
} else {
preview.style.display = 'none';
}
}
// Initialize form state
document.addEventListener('DOMContentLoaded', function() {
updateSubcategories();
const subcategorySelect = document.getElementById('subcategory');
const currentSubcategory = '<?php echo htmlspecialchars($product['Sub_Cat']); ?>';
// Check if current subcategory is in the list
let found = false;
for (let option of subcategorySelect.options) {
if (option.value === currentSubcategory) {
option.selected = true;
found = true;
break;
}
}
// If not found, it's a custom subcategory
if (!found) {
subcategorySelect.value = 'custom';
handleSubcategoryChange();
document.getElementById('customSubcategory').value = currentSubcategory;
}
});
</script>
</body>
</html>