Compare commits
No commits in common. "ai-dev" and "master" have entirely different histories.
250
add_item.php
250
add_item.php
@ -1,250 +0,0 @@
|
||||
<?php
|
||||
require_once 'db/config.php';
|
||||
|
||||
$success_message = '';
|
||||
$error_message = '';
|
||||
|
||||
if ($_SERVER["REQUEST_METHOD"] == "POST") {
|
||||
try {
|
||||
$pdo = db_connect();
|
||||
|
||||
// Basic validation
|
||||
$required_fields = [
|
||||
'acquisition_date', 'item_code', 'company_origin', 'category', 'sub_category',
|
||||
'po_number', 'item_name', 'acquisition_price', 'item_user_name', 'user_division',
|
||||
'user_department', 'location_city', 'location_building', 'location_area',
|
||||
'current_condition', 'condition_at_acquisition', 'asset_status'
|
||||
];
|
||||
|
||||
foreach ($required_fields as $field) {
|
||||
if (empty($_POST[$field])) {
|
||||
throw new Exception("Error: Field '{$field}' is required.");
|
||||
}
|
||||
}
|
||||
|
||||
$sql = "INSERT INTO inventory_items (
|
||||
acquisition_date, item_code, company_origin, category, sub_category, po_number,
|
||||
item_name, acquisition_price, item_user_name, user_division, user_department,
|
||||
location_city, location_building, location_area, current_condition,
|
||||
condition_at_acquisition, item_information, asset_status, transfer_status
|
||||
) VALUES (
|
||||
:acquisition_date, :item_code, :company_origin, :category, :sub_category, :po_number,
|
||||
:item_name, :acquisition_price, :item_user_name, :user_division, :user_department,
|
||||
:location_city, :location_building, :location_area, :current_condition,
|
||||
:condition_at_acquisition, :item_information, :asset_status, :transfer_status
|
||||
)";
|
||||
|
||||
$stmt = $pdo->prepare($sql);
|
||||
|
||||
$stmt->execute([
|
||||
':acquisition_date' => $_POST['acquisition_date'],
|
||||
':item_code' => $_POST['item_code'],
|
||||
':company_origin' => $_POST['company_origin'],
|
||||
':category' => $_POST['category'],
|
||||
':sub_category' => $_POST['sub_category'],
|
||||
':po_number' => $_POST['po_number'],
|
||||
':item_name' => $_POST['item_name'],
|
||||
':acquisition_price' => $_POST['acquisition_price'],
|
||||
':item_user_name' => $_POST['item_user_name'],
|
||||
':user_division' => $_POST['user_division'],
|
||||
':user_department' => $_POST['user_department'],
|
||||
':location_city' => $_POST['location_city'],
|
||||
':location_building' => $_POST['location_building'],
|
||||
':location_area' => $_POST['location_area'],
|
||||
':current_condition' => $_POST['current_condition'],
|
||||
':condition_at_acquisition' => $_POST['condition_at_acquisition'],
|
||||
':item_information' => $_POST['item_information'] ?? '',
|
||||
':asset_status' => $_POST['asset_status'],
|
||||
':transfer_status' => $_POST['transfer_status'] ?? 'N/A',
|
||||
]);
|
||||
|
||||
$success_message = "Inventory item added successfully!";
|
||||
|
||||
} catch (Exception $e) {
|
||||
$error_message = "Error: " . $e->getMessage();
|
||||
// Check for duplicate item_code
|
||||
if ($e instanceof PDOException && $e->errorInfo[1] == 1062) {
|
||||
$error_message = "Error: An item with this Item Code already exists.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Static options for dropdowns
|
||||
$categories = ['Electronics', 'Furniture', 'Software', 'Office Supplies'];
|
||||
$conditions = ['Good', 'Minor Damage', 'Major Damage', 'Broken'];
|
||||
$conditions_acq = ['New', 'Used', 'Refurbished'];
|
||||
$asset_statuses = ['Active', 'In Use', 'In Storage', 'Transferred', 'Disposed'];
|
||||
$transfer_statuses = ['Pending', 'Approved', 'Rejected', 'Completed', 'N/A'];
|
||||
$divisions = ['IT', 'HR', 'Finance', 'Operations'];
|
||||
$departments = ['Help Desk', 'Recruitment', 'Accounting', 'Logistics'];
|
||||
$cities = ['New York', 'London', 'Tokyo', 'Sydney'];
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Add New Inventory Item</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&family=Roboto+Slab:wght@700&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
|
||||
</head>
|
||||
<body>
|
||||
<header class="app-header">
|
||||
<h1>Inventory Management System</h1>
|
||||
<nav>
|
||||
<a href="add_item.php" class="active">Add New Item</a>
|
||||
<a href="inventory_list.php">View Inventory</a>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main class="container">
|
||||
<div class="form-container card">
|
||||
<h2>Add a New Inventory Item</h2>
|
||||
<p>Fill out the form below to add a new asset to the inventory.</p>
|
||||
|
||||
<?php if ($success_message): ?>
|
||||
<div class="toast success"><?php echo htmlspecialchars($success_message); ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if ($error_message): ?>
|
||||
<div class="toast error"><?php echo htmlspecialchars($error_message); ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form action="add_item.php" method="POST" id="add-item-form">
|
||||
<div class="form-grid">
|
||||
<!-- Column 1 -->
|
||||
<div class="form-column">
|
||||
<div class="form-group">
|
||||
<label for="acquisition_date">Acquisition Date</label>
|
||||
<input type="date" id="acquisition_date" name="acquisition_date" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="item_code">Item Code (Unique)</label>
|
||||
<input type="text" id="item_code" name="item_code" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="company_origin">Company Origin (PT)</label>
|
||||
<input type="text" id="company_origin" name="company_origin" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="category">Category</label>
|
||||
<select id="category" name="category" required>
|
||||
<?php foreach ($categories as $cat): ?>
|
||||
<option value="<?php echo htmlspecialchars($cat); ?>"><?php echo htmlspecialchars($cat); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="sub_category">Sub Category</label>
|
||||
<input type="text" id="sub_category" name="sub_category" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="po_number">Purchase Order Number</label>
|
||||
<input type="text" id="po_number" name="po_number" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Column 2 -->
|
||||
<div class="form-column">
|
||||
<div class="form-group">
|
||||
<label for="item_name">Inventory Item Name</label>
|
||||
<input type="text" id="item_name" name="item_name" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="acquisition_price">Acquisition Price</label>
|
||||
<input type="number" step="0.01" id="acquisition_price" name="acquisition_price" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="item_user_name">Item User Name</label>
|
||||
<input type="text" id="item_user_name" name="item_user_name" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="user_division">User Division</label>
|
||||
<select id="user_division" name="user_division" required>
|
||||
<?php foreach ($divisions as $div): ?>
|
||||
<option value="<?php echo htmlspecialchars($div); ?>"><?php echo htmlspecialchars($div); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="user_department">User Department</label>
|
||||
<select id="user_department" name="user_department" required>
|
||||
<?php foreach ($departments as $dep): ?>
|
||||
<option value="<?php echo htmlspecialchars($dep); ?>"><?php echo htmlspecialchars($dep); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="asset_status">Asset Status</label>
|
||||
<select id="asset_status" name="asset_status" required>
|
||||
<?php foreach ($asset_statuses as $status): ?>
|
||||
<option value="<?php echo htmlspecialchars($status); ?>"><?php echo htmlspecialchars($status); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Column 3 -->
|
||||
<div class="form-column">
|
||||
<div class="form-group">
|
||||
<label for="location_city">Location – City</label>
|
||||
<select id="location_city" name="location_city" required>
|
||||
<?php foreach ($cities as $city): ?>
|
||||
<option value="<?php echo htmlspecialchars($city); ?>"><?php echo htmlspecialchars($city); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="location_building">Location – Building</label>
|
||||
<input type="text" id="location_building" name="location_building" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="location_area">Location – Area / Room</label>
|
||||
<input type="text" id="location_area" name="location_area" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="current_condition">Current Condition</label>
|
||||
<select id="current_condition" name="current_condition" required>
|
||||
<?php foreach ($conditions as $cond): ?>
|
||||
<option value="<?php echo htmlspecialchars($cond); ?>"><?php echo htmlspecialchars($cond); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="condition_at_acquisition">Condition at Acquisition</label>
|
||||
<select id="condition_at_acquisition" name="condition_at_acquisition" required>
|
||||
<?php foreach ($conditions_acq as $cond): ?>
|
||||
<option value="<?php echo htmlspecialchars($cond); ?>"><?php echo htmlspecialchars($cond); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="transfer_status">Transfer Status</label>
|
||||
<select id="transfer_status" name="transfer_status" required>
|
||||
<?php foreach ($transfer_statuses as $status): ?>
|
||||
<option value="<?php echo htmlspecialchars($status); ?>"><?php echo htmlspecialchars($status); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group form-full-width">
|
||||
<label for="item_information">Item Information (Notes)</label>
|
||||
<textarea id="item_information" name="item_information" rows="4"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn btn-primary">Add Item</button>
|
||||
<button type="reset" class="btn btn-secondary">Clear Form</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="app-footer">
|
||||
<p>© <?php echo date("Y"); ?> Inventory Management System</p>
|
||||
</footer>
|
||||
<script src="assets/js/main.js?v=<?php echo time(); ?>"></script>
|
||||
</body>
|
||||
</html>
|
||||
@ -1,283 +0,0 @@
|
||||
/* General Body Styles */
|
||||
body {
|
||||
font-family: 'Roboto', sans-serif;
|
||||
background-color: #ECF0F1;
|
||||
color: #333;
|
||||
line-height: 1.6;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* App Header */
|
||||
.app-header {
|
||||
background: linear-gradient(135deg, #2A3F54 0%, #3E5771 100%);
|
||||
color: #FFFFFF;
|
||||
padding: 1rem 2rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.app-header h1 {
|
||||
font-family: 'Roboto Slab', serif;
|
||||
margin: 0;
|
||||
font-size: 1.5rem;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.app-header nav a {
|
||||
color: #FFFFFF;
|
||||
text-decoration: none;
|
||||
margin-left: 1.5rem;
|
||||
font-weight: 500;
|
||||
padding-bottom: 0.25rem;
|
||||
border-bottom: 2px solid transparent;
|
||||
transition: border-color 0.3s ease;
|
||||
}
|
||||
|
||||
.app-header nav a.active,
|
||||
.app-header nav a:hover {
|
||||
border-color: #2ECC71;
|
||||
}
|
||||
|
||||
|
||||
/* Main Container */
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 2rem auto;
|
||||
padding: 0 2rem;
|
||||
}
|
||||
|
||||
/* Card Style */
|
||||
.card {
|
||||
background-color: #FFFFFF;
|
||||
border-radius: 0.5rem;
|
||||
box-shadow: 0 4px 6px rgba(0,0,0,0.05);
|
||||
padding: 2rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
/* Form Styles */
|
||||
.form-container h2 {
|
||||
font-family: 'Roboto Slab', serif;
|
||||
color: #2A3F54;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.form-container p {
|
||||
margin-top: 0;
|
||||
margin-bottom: 2rem;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.form-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
.form-column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.form-group label {
|
||||
font-weight: 700;
|
||||
margin-bottom: 0.5rem;
|
||||
color: #3E5771;
|
||||
}
|
||||
|
||||
.form-group input,
|
||||
.form-group select,
|
||||
.form-group textarea {
|
||||
width: 100%;
|
||||
padding: 0.75rem;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 0.25rem;
|
||||
font-size: 1rem;
|
||||
transition: border-color 0.3s ease, box-shadow 0.3s ease;
|
||||
}
|
||||
|
||||
.form-group input:focus,
|
||||
.form-group select:focus,
|
||||
.form-group textarea:focus {
|
||||
outline: none;
|
||||
border-color: #2A3F54;
|
||||
box-shadow: 0 0 0 2px rgba(42, 63, 84, 0.2);
|
||||
}
|
||||
|
||||
.form-full-width {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
grid-column: 1 / -1;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 1rem;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
/* Buttons */
|
||||
.btn {
|
||||
padding: 0.75rem 1.5rem;
|
||||
border-radius: 0.25rem;
|
||||
text-decoration: none;
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
transition: background-color 0.3s ease, transform 0.2s ease;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: #2ECC71;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background-color: #25a25a;
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background-color: #95a5a6;
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background-color: #7f8c8d;
|
||||
}
|
||||
|
||||
|
||||
/* Toast Notifications */
|
||||
.toast {
|
||||
padding: 1rem;
|
||||
margin-bottom: 1.5rem;
|
||||
border-radius: 0.25rem;
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.toast.success {
|
||||
background-color: #2ECC71;
|
||||
}
|
||||
|
||||
.toast.error {
|
||||
background-color: #E74C3C;
|
||||
}
|
||||
|
||||
|
||||
/* Inventory List Specific */
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 2rem;
|
||||
border-bottom: 1px solid #ddd;
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.search-and-filter-section {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.search-bar input {
|
||||
width: 100%;
|
||||
padding: 0.75rem;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 0.25rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.filter-form {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.filter-controls {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.filter-controls select {
|
||||
padding: 0.75rem;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 0.25rem;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.filter-controls .btn {
|
||||
padding: 0.75rem 1.5rem;
|
||||
}
|
||||
|
||||
.inventory-table-container {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.inventory-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.inventory-table th, .inventory-table td {
|
||||
padding: 1rem;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.inventory-table th {
|
||||
font-family: 'Roboto Slab', serif;
|
||||
}
|
||||
|
||||
.inventory-table th a {
|
||||
text-decoration: none;
|
||||
color: #2A3F54;
|
||||
}
|
||||
|
||||
.inventory-table tbody tr:hover {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
.status {
|
||||
padding: 0.25rem 0.5rem;
|
||||
border-radius: 1rem;
|
||||
color: #fff;
|
||||
font-size: 0.8rem;
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.status-active, .status-in-use {
|
||||
background-color: #2ECC71;
|
||||
}
|
||||
|
||||
.status-in-storage {
|
||||
background-color: #3498DB;
|
||||
}
|
||||
|
||||
.status-transferred {
|
||||
background-color: #F1C40F;
|
||||
}
|
||||
|
||||
.status-disposed {
|
||||
background-color: #E74C3C;
|
||||
}
|
||||
|
||||
/* App Footer */
|
||||
.app-footer {
|
||||
text-align: center;
|
||||
padding: 2rem 0;
|
||||
margin-top: 2rem;
|
||||
color: #777;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
@ -1,36 +0,0 @@
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const addItemForm = document.getElementById('add-item-form');
|
||||
|
||||
if (addItemForm) {
|
||||
addItemForm.addEventListener('submit', function(e) {
|
||||
const requiredInputs = addItemForm.querySelectorAll('[required]');
|
||||
let firstError = null;
|
||||
|
||||
requiredInputs.forEach(input => {
|
||||
if (!input.value.trim()) {
|
||||
input.style.borderColor = '#E74C3C';
|
||||
if (!firstError) {
|
||||
firstError = input;
|
||||
}
|
||||
} else {
|
||||
input.style.borderColor = '#ccc';
|
||||
}
|
||||
});
|
||||
|
||||
if (firstError) {
|
||||
e.preventDefault();
|
||||
alert('Please fill out all required fields.');
|
||||
firstError.focus();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Auto-hide toast messages
|
||||
const toastMessages = document.querySelectorAll('.toast');
|
||||
toastMessages.forEach(toast => {
|
||||
setTimeout(() => {
|
||||
toast.style.display = 'none';
|
||||
}, 5000); // Hide after 5 seconds
|
||||
});
|
||||
|
||||
});
|
||||
@ -1,64 +1,17 @@
|
||||
<?php
|
||||
function db_connect() {
|
||||
$host = '127.0.0.1';
|
||||
$db = 'inventory_management';
|
||||
$user = 'inventory_user';
|
||||
$pass = 'password';
|
||||
$charset = 'utf8mb4';
|
||||
// Generated by setup_mariadb_project.sh — edit as needed.
|
||||
define('DB_HOST', '127.0.0.1');
|
||||
define('DB_NAME', 'app_30908');
|
||||
define('DB_USER', 'app_30908');
|
||||
define('DB_PASS', '98b730aa-be6c-479d-a47d-e5e7abc49229');
|
||||
|
||||
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
|
||||
$options = [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
];
|
||||
try {
|
||||
$pdo = new PDO($dsn, $user, $pass, $options);
|
||||
} catch (PDOException $e) {
|
||||
throw new PDOException($e->getMessage(), (int)$e->getCode());
|
||||
}
|
||||
return $pdo;
|
||||
function db() {
|
||||
static $pdo;
|
||||
if (!$pdo) {
|
||||
$pdo = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8mb4', DB_USER, DB_PASS, [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
]);
|
||||
}
|
||||
return $pdo;
|
||||
}
|
||||
|
||||
function create_schema($pdo) {
|
||||
$queries = [
|
||||
'CREATE TABLE IF NOT EXISTS `inventory_items` (
|
||||
`id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||
`acquisition_date` DATE NOT NULL,
|
||||
`item_code` VARCHAR(255) UNIQUE NOT NULL,
|
||||
`company_origin` VARCHAR(255) NOT NULL,
|
||||
`category` VARCHAR(255) NOT NULL,
|
||||
`sub_category` VARCHAR(255) NOT NULL,
|
||||
`po_number` VARCHAR(255) NOT NULL,
|
||||
`item_name` VARCHAR(255) NOT NULL,
|
||||
`acquisition_price` DECIMAL(10, 2) NOT NULL,
|
||||
`item_user_name` VARCHAR(255) NOT NULL,
|
||||
`user_division` VARCHAR(255) NOT NULL,
|
||||
`user_department` VARCHAR(255) NOT NULL,
|
||||
`location_city` VARCHAR(255) NOT NULL,
|
||||
`location_building` VARCHAR(255) NOT NULL,
|
||||
`location_area` VARCHAR(255) NOT NULL,
|
||||
`current_condition` VARCHAR(255) NOT NULL,
|
||||
`condition_at_acquisition` VARCHAR(255) NOT NULL,
|
||||
`item_information` TEXT,
|
||||
`asset_status` VARCHAR(255) NOT NULL,
|
||||
`transfer_status` VARCHAR(255) NOT NULL,
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);'
|
||||
];
|
||||
|
||||
foreach ($queries as $query) {
|
||||
$pdo->exec($query);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$pdo = db_connect();
|
||||
create_schema($pdo);
|
||||
} catch (PDOException $e) {
|
||||
// In a real app, you'd log this error
|
||||
error_log($e->getMessage());
|
||||
// You could also show a generic error page
|
||||
// die("Database setup failed. Please check the logs.");
|
||||
}
|
||||
?>
|
||||
161
index.php
161
index.php
@ -1,23 +1,150 @@
|
||||
<!DOCTYPE html>
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
@ini_set('display_errors', '1');
|
||||
@error_reporting(E_ALL);
|
||||
@date_default_timezone_set('UTC');
|
||||
|
||||
$phpVersion = PHP_VERSION;
|
||||
$now = date('Y-m-d H:i:s');
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Inventory Management System</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&family=Roboto+Slab:wght@700&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="assets/css/custom.css">
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>New Style</title>
|
||||
<?php
|
||||
// Read project preview data from environment
|
||||
$projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? '';
|
||||
$projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
|
||||
?>
|
||||
<?php if ($projectDescription): ?>
|
||||
<!-- Meta description -->
|
||||
<meta name="description" content='<?= htmlspecialchars($projectDescription) ?>' />
|
||||
<!-- Open Graph meta tags -->
|
||||
<meta property="og:description" content="<?= htmlspecialchars($projectDescription) ?>" />
|
||||
<!-- Twitter meta tags -->
|
||||
<meta property="twitter:description" content="<?= htmlspecialchars($projectDescription) ?>" />
|
||||
<?php endif; ?>
|
||||
<?php if ($projectImageUrl): ?>
|
||||
<!-- Open Graph image -->
|
||||
<meta property="og:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
|
||||
<!-- Twitter image -->
|
||||
<meta property="twitter:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
|
||||
<?php endif; ?>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
--bg-color-start: #6a11cb;
|
||||
--bg-color-end: #2575fc;
|
||||
--text-color: #ffffff;
|
||||
--card-bg-color: rgba(255, 255, 255, 0.01);
|
||||
--card-border-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: 'Inter', sans-serif;
|
||||
background: linear-gradient(45deg, var(--bg-color-start), var(--bg-color-end));
|
||||
color: var(--text-color);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
body::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><path d="M-10 10L110 10M10 -10L10 110" stroke-width="1" stroke="rgba(255,255,255,0.05)"/></svg>');
|
||||
animation: bg-pan 20s linear infinite;
|
||||
z-index: -1;
|
||||
}
|
||||
@keyframes bg-pan {
|
||||
0% { background-position: 0% 0%; }
|
||||
100% { background-position: 100% 100%; }
|
||||
}
|
||||
main {
|
||||
padding: 2rem;
|
||||
}
|
||||
.card {
|
||||
background: var(--card-bg-color);
|
||||
border: 1px solid var(--card-border-color);
|
||||
border-radius: 16px;
|
||||
padding: 2rem;
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.loader {
|
||||
margin: 1.25rem auto 1.25rem;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border: 3px solid rgba(255, 255, 255, 0.25);
|
||||
border-top-color: #fff;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
@keyframes spin {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
.hint {
|
||||
opacity: 0.9;
|
||||
}
|
||||
.sr-only {
|
||||
position: absolute;
|
||||
width: 1px; height: 1px;
|
||||
padding: 0; margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
white-space: nowrap; border: 0;
|
||||
}
|
||||
h1 {
|
||||
font-size: 3rem;
|
||||
font-weight: 700;
|
||||
margin: 0 0 1rem;
|
||||
letter-spacing: -1px;
|
||||
}
|
||||
p {
|
||||
margin: 0.5rem 0;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
code {
|
||||
background: rgba(0,0,0,0.2);
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
||||
}
|
||||
footer {
|
||||
position: absolute;
|
||||
bottom: 1rem;
|
||||
font-size: 0.8rem;
|
||||
opacity: 0.7;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header class="header">
|
||||
<h1>Inventory Management System</h1>
|
||||
</header>
|
||||
<div style="text-align:center; padding: 4rem 0;">
|
||||
<h2>Welcome!</h2>
|
||||
<p>You can start by viewing the inventory or adding a new item.</p>
|
||||
<a href="inventory_list.php" class="btn btn-primary">View Inventory</a>
|
||||
<a href="add_item.php" class="btn" style="background-color: #3498DB;">Add New Item</a>
|
||||
</div>
|
||||
<main>
|
||||
<div class="card">
|
||||
<h1>Analyzing your requirements and generating your website…</h1>
|
||||
<div class="loader" role="status" aria-live="polite" aria-label="Applying initial changes">
|
||||
<span class="sr-only">Loading…</span>
|
||||
</div>
|
||||
<p class="hint"><?= ($_SERVER['HTTP_HOST'] ?? '') === 'appwizzy.com' ? 'AppWizzy' : 'Flatlogic' ?> AI is collecting your requirements and applying the first changes.</p>
|
||||
<p class="hint">This page will update automatically as the plan is implemented.</p>
|
||||
<p>Runtime: PHP <code><?= htmlspecialchars($phpVersion) ?></code> — UTC <code><?= htmlspecialchars($now) ?></code></p>
|
||||
</div>
|
||||
</main>
|
||||
<footer>
|
||||
Page updated: <?= htmlspecialchars($now) ?> (UTC)
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
@ -1,158 +0,0 @@
|
||||
<?php
|
||||
require_once 'db/config.php';
|
||||
|
||||
$pdo = db_connect();
|
||||
|
||||
// Get distinct values for filters
|
||||
$categories = $pdo->query("SELECT DISTINCT category FROM inventory_items ORDER BY category")->fetchAll(PDO::FETCH_COLUMN);
|
||||
$statuses = $pdo->query("SELECT DISTINCT asset_status FROM inventory_items ORDER BY asset_status")->fetchAll(PDO::FETCH_COLUMN);
|
||||
$locations = $pdo->query("SELECT DISTINCT location_city FROM inventory_items ORDER BY location_city")->fetchAll(PDO::FETCH_COLUMN);
|
||||
|
||||
// Base query
|
||||
$sql = "SELECT id, item_name, item_code, category, asset_status, location_city, acquisition_price, acquisition_date FROM inventory_items";
|
||||
$params = [];
|
||||
$where_clauses = [];
|
||||
|
||||
// Search
|
||||
$search = $_GET['search'] ?? '';
|
||||
if ($search) {
|
||||
$search_term = "%{$search}%";
|
||||
$where_clauses[] = "(item_name LIKE :search OR item_code LIKE :search OR po_number LIKE :search OR item_user_name LIKE :search OR user_department LIKE :search OR location_city LIKE :search OR company_origin LIKE :search)";
|
||||
$params[':search'] = $search_term;
|
||||
}
|
||||
|
||||
// Filters
|
||||
$filter_category = $_GET['category'] ?? '';
|
||||
if ($filter_category) {
|
||||
$where_clauses[] = "category = :category";
|
||||
$params[':category'] = $filter_category;
|
||||
}
|
||||
|
||||
$filter_status = $_GET['status'] ?? '';
|
||||
if ($filter_status) {
|
||||
$where_clauses[] = "asset_status = :status";
|
||||
$params[':status'] = $filter_status;
|
||||
}
|
||||
|
||||
$filter_location = $_GET['location'] ?? '';
|
||||
if ($filter_location) {
|
||||
$where_clauses[] = "location_city = :location";
|
||||
$params[':location'] = $filter_location;
|
||||
}
|
||||
|
||||
if (!empty($where_clauses)) {
|
||||
$sql .= " WHERE " . implode(' AND ', $where_clauses);
|
||||
}
|
||||
|
||||
// Sorting
|
||||
$sort_columns = ['item_name', 'item_code', 'category', 'asset_status', 'location_city', 'acquisition_price', 'acquisition_date'];
|
||||
$sort_column = $_GET['sort'] ?? 'acquisition_date';
|
||||
$sort_direction = $_GET['dir'] ?? 'desc';
|
||||
|
||||
if (!in_array($sort_column, $sort_columns)) {
|
||||
$sort_column = 'acquisition_date';
|
||||
}
|
||||
|
||||
$sort_direction = strtolower($sort_direction) === 'asc' ? 'asc' : 'desc';
|
||||
|
||||
$sql .= " ORDER BY `$sort_column` $sort_direction";
|
||||
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
$items = $stmt->fetchAll();
|
||||
|
||||
function get_sort_link($column, $current_sort, $current_dir) {
|
||||
$dir = ($current_sort === $column && $current_dir === 'asc') ? 'desc' : 'asc';
|
||||
$query_params = http_build_query(array_merge($_GET, ['sort' => $column, 'dir' => $dir]));
|
||||
return '?' . $query_params;
|
||||
}
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Inventory List</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&family=Roboto+Slab:wght@700&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="assets/css/custom.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header class="header">
|
||||
<h1>Inventory List</h1>
|
||||
<a href="add_item.php" class="btn btn-primary">Add New Item</a>
|
||||
</header>
|
||||
|
||||
<form method="get" action="inventory_list.php" class="filter-form">
|
||||
<div class="search-and-filter-section">
|
||||
<div class="search-bar">
|
||||
<input type="text" id="search" name="search" placeholder="Search by keyword..." value="<?= htmlspecialchars($search) ?>">
|
||||
</div>
|
||||
<div class="filter-controls">
|
||||
<select name="category">
|
||||
<option value="">All Categories</option>
|
||||
<?php foreach ($categories as $category): ?>
|
||||
<option value="<?= htmlspecialchars($category) ?>" <?= $filter_category === $category ? 'selected' : '' ?>><?= htmlspecialchars($category) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<select name="status">
|
||||
<option value="">All Statuses</option>
|
||||
<?php foreach ($statuses as $status): ?>
|
||||
<option value="<?= htmlspecialchars($status) ?>" <?= $filter_status === $status ? 'selected' : '' ?>><?= htmlspecialchars($status) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<select name="location">
|
||||
<option value="">All Locations</option>
|
||||
<?php foreach ($locations as $location): ?>
|
||||
<option value="<?= htmlspecialchars($location) ?>" <?= $filter_location === $location ? 'selected' : '' ?>><?= htmlspecialchars($location) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<button type="submit" class="btn">Filter</button>
|
||||
<a href="/inventory_list.php" class="btn btn-sm" style="background-color: #95a5a6;">Reset</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="inventory-table-container">
|
||||
<table class="inventory-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><a href="<?= get_sort_link('item_name', $sort_column, $sort_direction) ?>">Item Name</a></th>
|
||||
<th><a href="<?= get_sort_link('item_code', $sort_column, $sort_direction) ?>">Item Code</a></th>
|
||||
<th><a href="<?= get_sort_link('category', $sort_column, $sort_direction) ?>">Category</a></th>
|
||||
<th><a href="<?= get_sort_link('asset_status', $sort_column, $sort_direction) ?>">Status</a></th>
|
||||
<th><a href="<?= get_sort_link('location_city', $sort_column, $sort_direction) ?>">Location</a></th>
|
||||
<th><a href="<?= get_sort_link('acquisition_price', $sort_column, $sort_direction) ?>">Price</a></th>
|
||||
<th><a href="<?= get_sort_link('acquisition_date', $sort_column, $sort_direction) ?>">Acquisition Date</a></th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($items)): ?>
|
||||
<tr>
|
||||
<td colspan="8" style="text-align:center;">No inventory items found matching your criteria.</td>
|
||||
</tr>
|
||||
<?php else: ?>
|
||||
<?php foreach ($items as $item): ?>
|
||||
<tr>
|
||||
<td><?= htmlspecialchars($item['item_name']) ?></td>
|
||||
<td><?= htmlspecialchars($item['item_code']) ?></td>
|
||||
<td><?= htmlspecialchars($item['category']) ?></td>
|
||||
<td><span class="status status-<?= strtolower(str_replace(' ', '-', $item['asset_status'])) ?>"><?= htmlspecialchars($item['asset_status']) ?></span></td>
|
||||
<td><?= htmlspecialchars($item['location_city']) ?></td>
|
||||
<td>$<?= number_format($item['acquisition_price'], 2) ?></td>
|
||||
<td><?= htmlspecialchars($item['acquisition_date']) ?></td>
|
||||
<td>
|
||||
<a href="edit_item.php?id=<?= $item['id'] ?>" class="btn btn-sm">Edit</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<script src="assets/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
x
Reference in New Issue
Block a user