index.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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 = 'Account Settings';
  10. $siteName = 'Crop Monitor';
  11. $pdo = getDBConnection();
  12. $userId = getCurrentUserId();
  13. $user = getCurrentUser();
  14. $errors = [];
  15. $success = false;
  16. // Handle profile update POST
  17. if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['form-save'])) {
  18. if (!verifyCsrfToken($_POST['csrf_token'] ?? '')) {
  19. $errors[] = 'Invalid CSRF token.';
  20. } else {
  21. $fields = ['fullname', 'company', 'phone', 'mobilephone', 'email', 'address', 'city', 'state', 'zip', 'country', 'industry', 'role'];
  22. $set = [];
  23. $values = [];
  24. foreach ($fields as $f) {
  25. $set[] = "`$f` = ?";
  26. $values[] = trim($_POST[$f] ?? '');
  27. }
  28. $values[] = $userId;
  29. try {
  30. $pdo->prepare('UPDATE users SET ' . implode(', ', $set) . ' WHERE id = ?')->execute($values);
  31. $success = true;
  32. // Refresh session name
  33. $_SESSION['user_name'] = trim($_POST['fullname'] ?? '');
  34. } catch (\PDOException $e) {
  35. $errors[] = 'Failed to update profile.';
  36. }
  37. }
  38. }
  39. // Load current profile data from users table
  40. $profile = [];
  41. $stmt = $pdo->prepare('SELECT * FROM users WHERE id = ? LIMIT 1');
  42. $stmt->execute([$userId]);
  43. $profile = $stmt->fetch() ?: [];
  44. $h = fn($v) => htmlspecialchars((string) $v, ENT_QUOTES, 'UTF-8');
  45. include __DIR__ . '/../../layouts/header.php';
  46. include __DIR__ . '/../../layouts/navbar.php';
  47. ?>
  48. <div id="layoutSidenav">
  49. <div id="layoutSidenav_nav">
  50. <?php include __DIR__ . '/../../layouts/sidebar.php'; ?>
  51. </div>
  52. <div id="layoutSidenav_content">
  53. <main>
  54. <div class="container-fluid px-4">
  55. <h1 class="mt-4"><?= $h($pageTitle) ?></h1>
  56. <ol class="breadcrumb mb-4">
  57. <li class="breadcrumb-item"><a href="/dashboard/dashboard.php">Dashboard</a></li>
  58. <li class="breadcrumb-item active">Account Settings</li>
  59. </ol>
  60. <?php if ($success): ?>
  61. <div class="alert alert-success">Profile updated successfully.</div>
  62. <?php endif; ?>
  63. <?php foreach ($errors as $err): ?>
  64. <div class="alert alert-danger"><?= $h($err) ?></div>
  65. <?php endforeach; ?>
  66. <div class="row">
  67. <div class="col-sm-3">
  68. <div class="text-center">
  69. <img src="/client-assets/images/avatar-placeholder.png"
  70. class="img-circle img-fluid img-thumbnail mb-2" alt="avatar"
  71. style="max-width:150px">
  72. </div>
  73. <div class="alert alert-success mt-2" role="alert">
  74. Your Account level is: <b>FREE</b>
  75. <a href="#" class="alert-link">Upgrade Account</a>
  76. </div>
  77. </div>
  78. <div class="col-sm-9">
  79. <ul class="nav nav-tabs" id="settingsTabs">
  80. <li class="nav-item">
  81. <a class="nav-link active" data-bs-toggle="tab" href="#contact-details">Your Details</a>
  82. </li>
  83. <li class="nav-item">
  84. <a class="nav-link" data-bs-toggle="tab" href="#change-password">Change Password</a>
  85. </li>
  86. </ul>
  87. <div class="tab-content mt-3">
  88. <!-- Contact Details Tab -->
  89. <div class="tab-pane fade show active" id="contact-details">
  90. <form class="form" action="" method="post" id="registrationForm">
  91. <input type="hidden" name="csrf_token" value="<?= $h(generateCsrfToken()) ?>">
  92. <input type="hidden" name="form-save" value="1">
  93. <div class="row mb-3">
  94. <div class="col-md-6">
  95. <label class="form-label">Name</label>
  96. <input type="text" class="form-control" name="fullname"
  97. value="<?= $h($profile['fullname'] ?? '') ?>">
  98. </div>
  99. <div class="col-md-6">
  100. <label class="form-label">Company</label>
  101. <input type="text" class="form-control" name="company"
  102. value="<?= $h($profile['company'] ?? '') ?>">
  103. </div>
  104. </div>
  105. <div class="row mb-3">
  106. <div class="col-md-6">
  107. <label class="form-label">Phone</label>
  108. <input type="text" class="form-control" name="phone"
  109. value="<?= $h($profile['phone'] ?? '') ?>">
  110. </div>
  111. <div class="col-md-6">
  112. <label class="form-label">Mobile</label>
  113. <input type="text" class="form-control" name="mobilephone"
  114. value="<?= $h($profile['mobilephone'] ?? '') ?>">
  115. </div>
  116. </div>
  117. <div class="mb-3">
  118. <label class="form-label">Email</label>
  119. <input type="email" class="form-control" name="email"
  120. value="<?= $h($profile['email'] ?? $user['email'] ?? '') ?>">
  121. </div>
  122. <div class="mb-3">
  123. <label class="form-label">Address</label>
  124. <input type="text" class="form-control" name="address"
  125. value="<?= $h($profile['address'] ?? '') ?>">
  126. </div>
  127. <div class="row mb-3">
  128. <div class="col-md-3">
  129. <label class="form-label">City</label>
  130. <input type="text" class="form-control" name="city"
  131. value="<?= $h($profile['city'] ?? '') ?>">
  132. </div>
  133. <div class="col-md-3">
  134. <label class="form-label">State</label>
  135. <input type="text" class="form-control" name="state"
  136. value="<?= $h($profile['state'] ?? '') ?>">
  137. </div>
  138. <div class="col-md-3">
  139. <label class="form-label">Postcode</label>
  140. <input type="text" class="form-control" name="zip"
  141. value="<?= $h($profile['zip'] ?? '') ?>">
  142. </div>
  143. <div class="col-md-3">
  144. <label class="form-label">Country</label>
  145. <input type="text" class="form-control" name="country"
  146. value="<?= $h($profile['country'] ?? '') ?>">
  147. </div>
  148. </div>
  149. <hr>
  150. <h5>Industry Details</h5>
  151. <div class="row mb-3">
  152. <div class="col-md-6">
  153. <label class="form-label">Industry</label>
  154. <select class="form-select" name="industry">
  155. <?php foreach (['Broadacre','Viticulture','Horticulture','Permaculture','Dairy'] as $opt): ?>
  156. <option value="<?= $h($opt) ?>" <?= ($profile['industry'] ?? '') === $opt ? 'selected' : '' ?>>
  157. <?= $h($opt) ?>
  158. </option>
  159. <?php endforeach; ?>
  160. </select>
  161. </div>
  162. <div class="col-md-6">
  163. <label class="form-label">Role</label>
  164. <select class="form-select" name="role">
  165. <?php foreach (['Manager','Viticulturist','Horticulturist','Permaculturist','Irrigation Manager'] as $opt): ?>
  166. <option value="<?= $h($opt) ?>" <?= ($profile['role'] ?? '') === $opt ? 'selected' : '' ?>>
  167. <?= $h($opt) ?>
  168. </option>
  169. <?php endforeach; ?>
  170. </select>
  171. </div>
  172. </div>
  173. <button class="btn btn-success" type="submit">Save</button>
  174. <button class="btn btn-warning ms-2" type="reset">Reset</button>
  175. </form>
  176. </div>
  177. <!-- Change Password Tab -->
  178. <div class="tab-pane fade" id="change-password">
  179. <p class="text-muted">
  180. To change your password, please use the
  181. <a href="/login/change-password.php">Change Password</a> page.
  182. </p>
  183. </div>
  184. </div>
  185. </div>
  186. </div>
  187. </div>
  188. </main>
  189. <?php include __DIR__ . '/../../layouts/footer.php'; ?>
  190. </div>
  191. </div>