211 lines
9.7 KiB
PHP
211 lines
9.7 KiB
PHP
<?php
|
|
// index.php - Inventory Management Dashboard
|
|
require_once 'db/config.php';
|
|
|
|
// Handle Form Submission (Add Product)
|
|
$message = '';
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'add_product') {
|
|
try {
|
|
$pdo = db();
|
|
// Ensure table exists
|
|
$pdo->exec("CREATE TABLE IF NOT EXISTS inventory (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
sku VARCHAR(50) NOT NULL UNIQUE,
|
|
name VARCHAR(255) NOT NULL,
|
|
size VARCHAR(10) NOT NULL,
|
|
price DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
|
stock INT NOT NULL DEFAULT 0,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)");
|
|
|
|
$stmt = $pdo->prepare("INSERT INTO inventory (sku, name, size, price, stock) VALUES (?, ?, ?, ?, ?)");
|
|
$stmt->execute([
|
|
$_POST['sku'],
|
|
$_POST['name'],
|
|
$_POST['size'],
|
|
$_POST['price'],
|
|
$_POST['stock']
|
|
]);
|
|
$message = '<div class="alert alert-success alert-dismissible fade show" role="alert">Product added successfully! <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>';
|
|
} catch (PDOException $e) {
|
|
$err = htmlspecialchars($e->getMessage());
|
|
$message = '<div class="alert alert-danger alert-dismissible fade show" role="alert">Error: ' . $err . ' <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>';
|
|
}
|
|
}
|
|
|
|
// Fetch Inventory
|
|
$inventory = [];
|
|
try {
|
|
$pdo = db();
|
|
// Create table if it doesn't exist (first run safety)
|
|
$pdo->exec("CREATE TABLE IF NOT EXISTS inventory (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
sku VARCHAR(50) NOT NULL UNIQUE,
|
|
name VARCHAR(255) NOT NULL,
|
|
size VARCHAR(10) NOT NULL,
|
|
price DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
|
stock INT NOT NULL DEFAULT 0,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)");
|
|
|
|
$stmt = $pdo->query("SELECT * FROM inventory ORDER BY created_at DESC");
|
|
$inventory = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
} catch (PDOException $e) {
|
|
// Silent fail on read if DB not ready, or show empty
|
|
}
|
|
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Inventory | <?php echo htmlspecialchars($_SERVER['PROJECT_DESCRIPTION'] ?? 'Flatlogic App'); ?></title>
|
|
|
|
<!-- Bootstrap 5 & Inter Font -->
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&display=swap" rel="stylesheet">
|
|
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
|
|
|
|
<!-- Meta Tags -->
|
|
<meta property="og:title" content="<?php echo htmlspecialchars($_SERVER['PROJECT_NAME'] ?? 'Inventory App'); ?>">
|
|
<meta property="og:image" content="<?php echo htmlspecialchars($_SERVER['PROJECT_IMAGE_URL'] ?? ''); ?>">
|
|
</head>
|
|
<body class="bg-light">
|
|
|
|
<nav class="navbar navbar-expand-lg navbar-dark bg-dark sticky-top">
|
|
<div class="container">
|
|
<a class="navbar-brand fw-bold" href="#">Inventory Manager</a>
|
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
|
|
<span class="navbar-toggler-icon"></span>
|
|
</button>
|
|
<div class="collapse navbar-collapse" id="navbarNav">
|
|
<ul class="navbar-nav ms-auto">
|
|
<li class="nav-item"><a class="nav-link active" href="#">Dashboard</a></li>
|
|
<li class="nav-item"><a class="nav-link" href="#">POS (Coming Soon)</a></li>
|
|
<li class="nav-item"><a class="nav-link" href="#">Reports</a></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
<div class="container py-5">
|
|
<?php echo $message; ?>
|
|
|
|
<div class="row mb-4 align-items-center">
|
|
<div class="col">
|
|
<h1 class="h3 mb-0 text-dark fw-bold">Current Stock</h1>
|
|
<p class="text-muted small">Manage your clothing inventory.</p>
|
|
</div>
|
|
<div class="col-auto">
|
|
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addProductModal">
|
|
+ Add Product
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card border-0 shadow-sm">
|
|
<div class="card-body p-0">
|
|
<div class="table-responsive">
|
|
<table class="table table-hover table-nowrap mb-0 align-middle">
|
|
<thead class="bg-light text-secondary">
|
|
<tr>
|
|
<th class="ps-4" style="width: 15%;">SKU</th>
|
|
<th style="width: 30%;">Product Name</th>
|
|
<th style="width: 10%;">Size</th>
|
|
<th style="width: 15%;">Price</th>
|
|
<th style="width: 15%;">Stock</th>
|
|
<th class="text-end pe-4">Status</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php if (empty($inventory)): ?>
|
|
<tr>
|
|
<td colspan="6" class="text-center py-5 text-muted">
|
|
No products found. Add your first item!
|
|
</td>
|
|
</tr>
|
|
<?php else: ?>
|
|
<?php foreach ($inventory as $item): ?>
|
|
<tr>
|
|
<td class="ps-4 fw-mono text-dark"><?php echo htmlspecialchars($item['sku']); ?></td>
|
|
<td class="fw-medium text-dark"><?php echo htmlspecialchars($item['name']); ?></td>
|
|
<td><span class="badge bg-light text-dark border"><?php echo htmlspecialchars($item['size']); ?></span></td>
|
|
<td>$<?php echo number_format($item['price'], 2); ?></td>
|
|
<td><?php echo (int)$item['stock']; ?></td>
|
|
<td class="text-end pe-4">
|
|
<?php if ($item['stock'] > 10): ?>
|
|
<span class="status-dot bg-success"></span> In Stock
|
|
<?php elseif ($item['stock'] > 0): ?>
|
|
<span class="status-dot bg-warning"></span> Low Stock
|
|
<?php else: ?>
|
|
<span class="status-dot bg-danger"></span> Out of Stock
|
|
<?php endif; ?>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Add Product Modal -->
|
|
<div class="modal fade" id="addProductModal" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content border-0 shadow">
|
|
<div class="modal-header border-bottom-0 pb-0">
|
|
<h5 class="modal-title fw-bold">New Product</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body pt-3">
|
|
<form method="POST" action="index.php">
|
|
<input type="hidden" name="action" value="add_product">
|
|
|
|
<div class="mb-3">
|
|
<label class="form-label small text-uppercase text-muted fw-bold">SKU</label>
|
|
<input type="text" name="sku" class="form-control" placeholder="E.g. TS-BLK-M" required>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label class="form-label small text-uppercase text-muted fw-bold">Name</label>
|
|
<input type="text" name="name" class="form-control" placeholder="E.g. Classic Black T-Shirt" required>
|
|
</div>
|
|
|
|
<div class="row g-2 mb-3">
|
|
<div class="col-6">
|
|
<label class="form-label small text-uppercase text-muted fw-bold">Size</label>
|
|
<select name="size" class="form-select" required>
|
|
<option value="XS">XS</option>
|
|
<option value="S">S</option>
|
|
<option value="M" selected>M</option>
|
|
<option value="L">L</option>
|
|
<option value="XL">XL</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-6">
|
|
<label class="form-label small text-uppercase text-muted fw-bold">Price ($)</label>
|
|
<input type="number" step="0.01" name="price" class="form-control" placeholder="0.00" required>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-4">
|
|
<label class="form-label small text-uppercase text-muted fw-bold">Initial Stock</label>
|
|
<input type="number" name="stock" class="form-control" placeholder="0" required>
|
|
</div>
|
|
|
|
<div class="d-grid">
|
|
<button type="submit" class="btn btn-primary py-2">Add to Inventory</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
|
<script src="assets/js/main.js?v=<?php echo time(); ?>"></script>
|
|
</body>
|
|
</html>
|