product-list.php 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. <?php
  2. require_once __DIR__ . '/../../config/database.php';
  3. require_once __DIR__ . '/../../lib/auth.php';
  4. require_once __DIR__ . '/../../lib/csrf.php';
  5. if (session_status() === PHP_SESSION_NONE) {
  6. session_start();
  7. }
  8. requireLogin();
  9. $pageTitle = 'Product List';
  10. $siteName = 'Crop Monitor';
  11. $pdo = getDBConnection();
  12. $userId = getCurrentUserId();
  13. $stmt = $pdo->prepare(
  14. 'SELECT * FROM fertiliser_specifications WHERE modx_user_id = ? ORDER BY name ASC'
  15. );
  16. $stmt->execute([$userId]);
  17. $products = $stmt->fetchAll();
  18. $h = fn($v) => htmlspecialchars((string) $v, ENT_QUOTES, 'UTF-8');
  19. include __DIR__ . '/../../layouts/header.php';
  20. include __DIR__ . '/../../layouts/navbar.php';
  21. ?>
  22. <div id="layoutSidenav">
  23. <div id="layoutSidenav_nav">
  24. <?php include __DIR__ . '/../../layouts/sidebar.php'; ?>
  25. </div>
  26. <div id="layoutSidenav_content">
  27. <main>
  28. <div class="container-fluid px-4">
  29. <h1 class="mt-4"><?= $h($pageTitle) ?></h1>
  30. <ol class="breadcrumb mb-4">
  31. <li class="breadcrumb-item"><a href="/dashboard/dashboard.php">Dashboard</a></li>
  32. <li class="breadcrumb-item active">Product List</li>
  33. </ol>
  34. <div class="card mb-4">
  35. <div class="card-header d-flex justify-content-between align-items-center">
  36. <span><i class="fas fa-flask me-1"></i>Company Product Analysis</span>
  37. <button type="button" class="btn btn-success btn-sm"
  38. data-bs-toggle="modal" data-bs-target="#addProductModal">
  39. <i class="fas fa-plus me-1"></i>Add Product
  40. </button>
  41. </div>
  42. <div class="card-body p-0">
  43. <p class="text-muted px-3 pt-3 mb-0">Products used in Soil Analysis recommendation programs.</p>
  44. <div class="table-responsive">
  45. <table class="table table-bordered table-hover mb-0">
  46. <thead class="table-dark">
  47. <tr>
  48. <th>ID</th><th>Product</th><th>Chemical</th>
  49. <th>N</th><th>P</th><th>K</th><th>Na</th><th>Ca</th><th>Mg</th>
  50. <th>B</th><th>Zn</th><th>Cu</th><th>Mn</th><th>Fe</th><th>Co</th><th>Mo</th>
  51. </tr>
  52. </thead>
  53. <tbody>
  54. <?php if (empty($products)): ?>
  55. <tr><td colspan="16" class="text-center text-muted">No products found.</td></tr>
  56. <?php else: ?>
  57. <?php foreach ($products as $prod):
  58. $id = (int) $prod['id']; ?>
  59. <tr>
  60. <td><?= $id ?></td>
  61. <td><strong><?= $h($prod['name']) ?></strong></td>
  62. <td><?= $h($prod['chemical']) ?></td>
  63. <?php foreach (['n','p','k','Na','Ca','Mg','B','Zn','Cu','Mn','Fe','Co','Mo'] as $col): ?>
  64. <td contenteditable="true"
  65. onblur="updateDatabase(this,'<?= $h($col) ?>','<?= $id ?>')"
  66. onclick="showEdit(this)"><?= $h($prod[$col]) ?></td>
  67. <?php endforeach; ?>
  68. </tr>
  69. <?php endforeach; ?>
  70. <?php endif; ?>
  71. </tbody>
  72. </table>
  73. </div>
  74. </div>
  75. </div>
  76. </div><!-- /container-fluid -->
  77. </main>
  78. <!-- Add Product modal -->
  79. <div class="modal fade" id="addProductModal" tabindex="-1"
  80. aria-labelledby="addProductModalLabel" aria-hidden="true">
  81. <div class="modal-dialog modal-lg">
  82. <div class="modal-content">
  83. <div class="modal-header">
  84. <h5 class="modal-title" id="addProductModalLabel">Add New Product</h5>
  85. <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
  86. </div>
  87. <form method="post" action="/controllers/newProductSubmit.php" id="newProductForm">
  88. <div class="modal-body">
  89. <input type="hidden" name="csrf_token"
  90. value="<?= $h(generateCsrfToken()) ?>">
  91. <div class="row mb-3">
  92. <div class="col">
  93. <label class="form-label">Product Name</label>
  94. <input type="text" class="form-control" name="name" required>
  95. </div>
  96. <div class="col">
  97. <label class="form-label">Chemical Symbol</label>
  98. <input type="text" class="form-control" name="chemical">
  99. </div>
  100. </div>
  101. <div class="row row-cols-2 row-cols-md-4 g-2">
  102. <?php foreach ([
  103. 'N' => 'Nitrogen', 'P' => 'Phosphorus', 'K' => 'Potassium',
  104. 'Na' => 'Sodium', 'Ca' => 'Calcium', 'Mg' => 'Magnesium',
  105. 'B' => 'Boron', 'Zn' => 'Zinc', 'Cu' => 'Copper',
  106. 'Mn' => 'Manganese', 'Fe' => 'Iron', 'Co' => 'Cobalt',
  107. 'Mo' => 'Molybdenum',
  108. ] as $col => $label): ?>
  109. <div class="col">
  110. <label class="form-label form-label-sm"><?= $h($label) ?> — <?= $h($col) ?></label>
  111. <input type="number" step="0.01" class="form-control form-control-sm"
  112. name="<?= $h($col) ?>" value="0">
  113. </div>
  114. <?php endforeach; ?>
  115. </div>
  116. </div>
  117. <div class="modal-footer">
  118. <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
  119. <button type="submit" class="btn btn-success">Save Product</button>
  120. </div>
  121. </form>
  122. </div>
  123. </div>
  124. </div>
  125. <?php include __DIR__ . '/../../layouts/footer.php'; ?>
  126. <script>
  127. function showEdit(el) {
  128. el.style.background = '#97e499';
  129. }
  130. function updateDatabase(el, column, id) {
  131. el.style.background = '#FDFDFD';
  132. fetch('/dashboard/client-settings/updateproduct.php', {
  133. method: 'POST',
  134. headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  135. body: 'column=' + encodeURIComponent(column)
  136. + '&editval=' + encodeURIComponent(el.innerText.trim())
  137. + '&id=' + encodeURIComponent(id)
  138. + '&csrf_token=' + encodeURIComponent(
  139. document.querySelector('input[name="csrf_token"]').value
  140. )
  141. }).then(() => { el.style.background = 'white'; });
  142. }
  143. </script>