Added: vehicle creation
This commit is contained in:
		| @@ -1,12 +1,12 @@ | ||||
| <?php | ||||
| class DashboardController extends Controller { | ||||
|     public function index() { | ||||
|         $habit = new Habit(); | ||||
|         $habits = $habit->getHabitsByUser($_SESSION['user']['id']); | ||||
|         $vehicle = new Vehicle(); | ||||
|         $vehicles = $vehicle->getVehiclesByUser($_SESSION['user']['id']); | ||||
|  | ||||
|         $this->view('dashboard/index', [ | ||||
|             'title' => 'Dashboard', | ||||
|             'habits' => $habits, | ||||
|             'vehicles' => $vehicles, | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -1,57 +0,0 @@ | ||||
| <?php | ||||
|  | ||||
| class HabitController extends Controller { | ||||
|     public function index() { | ||||
|         $habit = new Habit(); | ||||
|         $habits = $habit->getHabitsByUser($_SESSION['user']['id']); | ||||
|         $this->view('habits/index', ['title' => 'Habits', 'habits' => $habits]); | ||||
|     } | ||||
|  | ||||
|     public function create() { | ||||
|         if ($_SERVER['REQUEST_METHOD'] === 'POST') { | ||||
|             $name = $_POST['name'] ?? ''; | ||||
|             $frequency = $_POST['frequency'] ?? 'Daily'; | ||||
|             $customFrequency = null; | ||||
|  | ||||
|             if (empty($name)) { | ||||
|                 $this->view('habits/create', ['error' => 'Habit name is required.']); | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             if ($frequency === 'Custom') { | ||||
|                 $daysOfWeek = $_POST['days_of_week'] ?? []; | ||||
|                 $daysOfMonth = $_POST['days_of_month'] ?? '*'; | ||||
|                 $months = $_POST['months'] ?? '*'; | ||||
|  | ||||
|                 // Combine into crontab-like string | ||||
|                 $customFrequency = implode(',', $daysOfWeek) . " $daysOfMonth $months"; | ||||
|             } | ||||
|  | ||||
|             $habit = new Habit(); | ||||
|             $result = $habit->create([ | ||||
|                 'name' => $name, | ||||
|                 'frequency' => $frequency, | ||||
|                 'custom_frequency' => $customFrequency, | ||||
|                 'reward_points' => intval($_POST['difficulty'] ?? 1), | ||||
|                 'user_id' => $_SESSION['user']['id'], | ||||
|             ]); | ||||
|  | ||||
|             if ($result) { | ||||
|                 $this->redirect('/habits'); | ||||
|             } else { | ||||
|                 $this->view('habits/create', ['error' => 'Failed to create habit.']); | ||||
|             } | ||||
|         } else { | ||||
|             $this->view('habits/create', ['title' => 'Create Habit']); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
|     public function edit() { | ||||
|         // Edit habit (to be implemented later) | ||||
|     } | ||||
|  | ||||
|     public function delete() { | ||||
|         // Delete habit (to be implemented later) | ||||
|     } | ||||
| } | ||||
							
								
								
									
										61
									
								
								app/controllers/VehicleController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								app/controllers/VehicleController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,61 @@ | ||||
| <?php | ||||
|  | ||||
| class VehicleController extends Controller { | ||||
|     public function index() { | ||||
|         $vehicle = new Vehicle(); | ||||
|         $vehicles = $vehicle->getVehiclesByUser($_SESSION['user']['id']); | ||||
|         $this->view('vehicles/index', ['title' => 'Vehicles', 'vehicles' => $vehicles]); | ||||
|     } | ||||
|  | ||||
|     public function create() { | ||||
|         if ($_SERVER['REQUEST_METHOD'] === 'POST') { | ||||
|             $name = $_POST['name'] ?? ''; | ||||
|             $registration_plate = $_POST['registration_plate'] ?? ''; | ||||
|             $fuel_type = $_POST['fuel_type'] ?? ''; | ||||
|             $note = $_POST['note'] ?? ''; | ||||
|  | ||||
|             $validator = new Validator(); | ||||
|             $validator->required('name', $name); | ||||
|             $validator->required('registration_plate', $registration_plate); | ||||
|             $validator->required('fuel_type', $fuel_type); | ||||
|  | ||||
|             if($note == "") $note = NULL; | ||||
|  | ||||
|             if (!$validator->passes()) { | ||||
|                 $this->view('vehicle/create', [ | ||||
|                     'error' => 'Please correct the errors below.', | ||||
|                     'validationErrors' => $validator->errors() ?: [], | ||||
|                 ]); | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             $vehicle = new Vehicle(); | ||||
|             $result = $vehicle->create([ | ||||
|                 'name' => $name, | ||||
|                 'registration_plate' => strtoupper($registration_plate), | ||||
|                 'fuel_type' => $fuel_type, | ||||
|                 'note' => $note, | ||||
|                 'user_id' => $_SESSION['user']['id'], | ||||
|             ]); | ||||
|  | ||||
|  | ||||
|             if ($result === true) { | ||||
|                 $this->redirect('/vehicles'); | ||||
|             } else { | ||||
|                 $this->view('vehicles/create', ['title' => 'Create vehicle', 'error' => $result, 'validationErrors' => []] ); | ||||
|             } | ||||
|  | ||||
|         } else { | ||||
|             $this->view('vehicles/create', ['title' => 'Create Vehicle']); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
|     public function edit() { | ||||
|         // Edit vehicle (to be implemented later) | ||||
|     } | ||||
|  | ||||
|     public function delete() { | ||||
|         // Delete vehicle (to be implemented later) | ||||
|     } | ||||
| } | ||||
| @@ -1,46 +0,0 @@ | ||||
| <?php | ||||
|  | ||||
| class Habit { | ||||
|     private $db; | ||||
|  | ||||
|     public function __construct() { | ||||
|         $this->db = Database::getInstance()->getConnection(); | ||||
|     } | ||||
|  | ||||
|     public function create($data) { | ||||
|         $stmt = $this->db->prepare(" | ||||
|             INSERT INTO habits (user_id, title, frequency, custom_frequency, reward_points, created_at) | ||||
|             VALUES (?, ?, ?, ?, ?, NOW()) | ||||
|         "); | ||||
|  | ||||
|         $stmt->bind_param( | ||||
|             "isssi", // Bind types: int, string, string, string, int | ||||
|             $data['user_id'], | ||||
|             $data['name'], | ||||
|             $data['frequency'], | ||||
|             $data['custom_frequency'], // Bind the custom_frequency field | ||||
|             $data['reward_points'] | ||||
|         ); | ||||
|  | ||||
|         if ($stmt->execute()) { | ||||
|             return true; | ||||
|         } else { | ||||
|             error_log("Failed to create habit: " . $stmt->error); | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public function getHabitsByUser($userId) { | ||||
|         $stmt = $this->db->prepare("SELECT id, title, frequency, custom_frequency, reward_points, created_at FROM habits WHERE user_id = ?"); | ||||
|         $stmt->bind_param("i", $userId); | ||||
|         $stmt->execute(); | ||||
|         $result = $stmt->get_result(); | ||||
|  | ||||
|         $habits = []; | ||||
|         while ($row = $result->fetch_assoc()) { | ||||
|             $habits[] = $row; | ||||
|         } | ||||
|          | ||||
|         return $habits; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										49
									
								
								app/models/Vehicle.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								app/models/Vehicle.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | ||||
| <?php | ||||
|  | ||||
| class Vehicle { | ||||
|     private $db; | ||||
|  | ||||
|     public function __construct() { | ||||
|         $this->db = Database::getInstance()->getConnection(); | ||||
|     } | ||||
|  | ||||
|     public function create($data) { | ||||
|         try{ | ||||
|             $stmt = $this->db->prepare(" | ||||
|                 INSERT INTO vehicles (user_id, name, registration_plate, fuel_type, note, created_at) | ||||
|                 VALUES (?, ?, ?, ?, ?, NOW()) | ||||
|             "); | ||||
|  | ||||
|             $stmt->bind_param( | ||||
|                 "issss", | ||||
|                 $data['user_id'], | ||||
|                 $data['name'], | ||||
|                 $data['registration_plate'], | ||||
|                 $data['fuel_type'], | ||||
|                 $data['note'], | ||||
|             ); | ||||
|  | ||||
|             if ($stmt->execute()) { | ||||
|                 return true; | ||||
|             } else { | ||||
|                 return "Error: " . $stmt->error; | ||||
|             } | ||||
|         } catch(mysqli_sql_exception $e) { | ||||
|             return $e->getMessage(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public function getVehiclesByUser($userId) { | ||||
|         $stmt = $this->db->prepare("SELECT id, name, registration_plate, fuel_type, note, created_at FROM vehicles WHERE user_id = ?"); | ||||
|         $stmt->bind_param("i", $userId); | ||||
|         $stmt->execute(); | ||||
|         $result = $stmt->get_result(); | ||||
|  | ||||
|         $vehicles = []; | ||||
|         while ($row = $result->fetch_assoc()) { | ||||
|             $vehicles[] = $row; | ||||
|         } | ||||
|          | ||||
|         return $vehicles; | ||||
|     } | ||||
| } | ||||
| @@ -3,8 +3,8 @@ | ||||
| <section class="dashboard"> | ||||
|     <h1>Welcome, <?= htmlspecialchars($_SESSION['user']['username']) ?>!</h1> | ||||
|     <div> | ||||
|         <a href="/habits/create" class="btn-green">Create new habit!</a> | ||||
|         <a href="/habits" class="btn-primary">List all habits</a> | ||||
|         <a href="/refuel/add" class="btn-green">Add new refuel record!</a> | ||||
|         <a href="/vehicles" class="btn-primary">List all vehicles</a> | ||||
|     </div> | ||||
|     <div class="card-wrapper"> | ||||
|         <section class="card upcoming"> | ||||
|   | ||||
| @@ -1,70 +0,0 @@ | ||||
| <link rel="stylesheet" href="/css/form.css"> | ||||
| <link rel="stylesheet" href="/css/habits_create.css"> | ||||
| <section class="form habit-create"> | ||||
|     <h1 class="header-form"><?= $this->get('title', 'Create Habit') ?></h1> | ||||
|  | ||||
|     <?php if ($this->get('error')): ?> | ||||
|         <div class="error" style="color: red; margin-bottom: 1rem;"> | ||||
|             <?= htmlspecialchars($this->get('error')) ?> | ||||
|         </div> | ||||
|     <?php endif; ?> | ||||
|  | ||||
|     <form method="POST" action="/habits/create"> | ||||
|         <label for="name">Habit Name</label> | ||||
|         <input type="text" name="name" id="name" required value="<?= htmlspecialchars($_POST['name'] ?? '') ?>"> | ||||
|  | ||||
|         <label for="frequency">Frequency</label> | ||||
|         <select name="frequency" id="frequency" onchange="toggleCustomFrequency(this.value)"> | ||||
|             <option value="Daily">Daily</option> | ||||
|             <option value="Weekly">Weekly</option> | ||||
|             <option value="Custom">Custom</option> | ||||
|         </select> | ||||
|  | ||||
|         <div id="custom-frequency" style="display: none;"> | ||||
|             <label id="lbl_dow">Days of the Week</label> | ||||
|             <div class="dow_chb_wrapper"> | ||||
|                 <label for="dow_mon">Monday</label> | ||||
|                 <input type="checkbox" name="days_of_week[]" id="dow_mon" value="1"> | ||||
|             </div> | ||||
|             <div class="dow_chb_wrapper"> | ||||
|                 <label for="dow_tue">Tuesday</label> | ||||
|                 <input type="checkbox" name="days_of_week[]" id="dow_tue" value="2"> | ||||
|             </div> | ||||
|             <div class="dow_chb_wrapper"> | ||||
|                 <label for="dow_wed">Wednesday</label> | ||||
|                 <input type="checkbox" name="days_of_week[]" id="dow_wed" value="3"> | ||||
|             </div> | ||||
|             <div class="dow_chb_wrapper"> | ||||
|                 <label for="dow_thu">Thursday</label> | ||||
|                 <input type="checkbox" name="days_of_week[]" id="dow_thu" value="4"> | ||||
|             </div> | ||||
|             <div class="dow_chb_wrapper"> | ||||
|                 <label for="dow_fri">Friday</label> | ||||
|                 <input type="checkbox" name="days_of_week[]" id="dow_fri" value="5"> | ||||
|             </div> | ||||
|             <div class="dow_chb_wrapper"> | ||||
|                 <label for="dow_sat">Saturday</label> | ||||
|                 <input type="checkbox" name="days_of_week[]" id="dow_sat" value="6"> | ||||
|             </div> | ||||
|             <div class="dow_chb_wrapper"> | ||||
|                 <label for="dow_sun">Sunday</label> | ||||
|                 <input type="checkbox" name="days_of_week[]" id="dow_sun" value="7"> | ||||
|             </div> | ||||
|  | ||||
|             <label for="days_of_month" id="lbl_dom">Days of the Month</label> | ||||
|             <input type="text" name="days_of_month" id="days_of_month" placeholder="1,15 (comma-separated)"> | ||||
|  | ||||
|             <label for="months">Months</label> | ||||
|             <input type="text" name="months" id="months" placeholder="1,7,12 (comma-separated)"> | ||||
|         </div> | ||||
|  | ||||
|         <input type="submit" value="Create Habit"> | ||||
|     </form> | ||||
| </section> | ||||
|  | ||||
| <script> | ||||
| function toggleCustomFrequency(value) { | ||||
|     const customFrequencyDiv = document.getElementById('custom-frequency'); | ||||
|     customFrequencyDiv.style.display = value === 'Custom' ? 'flex' : 'none'; | ||||
| } | ||||
| </script> | ||||
| @@ -1,24 +0,0 @@ | ||||
| <link rel="stylesheet" href="/css/habits_dashboard.css"> | ||||
| <section class="habits"> | ||||
|     <?php if (empty($this->get('habits'))): ?> | ||||
|         <p>No habits yet. <a href="/habits/create">Create your first habit</a>.</p> | ||||
|     <?php else: ?> | ||||
|         <div class="habits-wrapper"> | ||||
|         <?php foreach ($this->get('habits') as $habit): ?> | ||||
|             <div class="habit bordered"> | ||||
|                 <b><?= htmlspecialchars($habit['title']) ?></b> | ||||
|                 <p>Frequency: <?= htmlspecialchars($habit['frequency']) ?></p> | ||||
|                 <?php if (isset($habit['custom_frequency'])): ?> | ||||
|                     <p><?= htmlspecialchars($habit['custom_frequency'] ?? 'N/A') ?></p> | ||||
|                 <?php endif; ?> | ||||
|                     <p><?= htmlspecialchars($habit['reward_points']) ?></p> | ||||
|                     <p><?= htmlspecialchars($habit['created_at']) ?></p> | ||||
|                     <a href="/habits/done">Mark as done</a> | | ||||
|                     <a href="/habits/edit?id=<?= $habit['id'] ?>">Edit</a> | | ||||
|                     <a href="/habits/delete?id=<?= $habit['id'] ?>" onclick="return confirm('Are you sure you want to delete this habit?')">Delete</a> | ||||
|             </div> | ||||
|         <?php endforeach; ?> | ||||
|         </div> | ||||
|         <a href="/habits/create" class="btn-green">Create new habit!</a> | ||||
|     <?php endif; ?> | ||||
| </section> | ||||
							
								
								
									
										35
									
								
								app/views/vehicles/create.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								app/views/vehicles/create.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| <link rel="stylesheet" href="/css/form.css"> | ||||
| <link rel="stylesheet" href="/css/vehicle_create.css"> | ||||
| <section class="form"> | ||||
|     <h1 class="header-form"><?= $this->get('title', 'Create Vehicle') ?></h1> | ||||
|  | ||||
|     <?php if ($this->get('error')): ?> | ||||
|         <div class="error" style="color: red; margin-bottom: 1rem;"> | ||||
|             <?= htmlspecialchars($this->get('error')) ?> | ||||
|         </div> | ||||
|     <?php endif; ?> | ||||
|  | ||||
|     <form method="POST" action="/vehicles/add"> | ||||
|         <label for="name">Vehicle name</label> | ||||
|         <input type="text" name="name" id="name" required value="<?= htmlspecialchars($_POST['name'] ?? '') ?>"> | ||||
|  | ||||
|         <label for="registration_plate">Registration plate</label> | ||||
|         <input type="text" name="registration_plate" id="registration_plate" maxlength="10" onkeypress="return event.charCode != 32" required value="<?= htmlspecialchars($_POST['registration_plate'] ?? '') ?>"> | ||||
|  | ||||
|         <label for="fuel_type">Fuel type</label> | ||||
|         <select name="fuel_type" id="fuel_type"> | ||||
|             <option value="Diesel">Diesel</option> | ||||
|             <option value="Gasoline 95">Gasoline 95</option> | ||||
|             <option value="Gasoline 98">Gasoline 98</option> | ||||
|             <option value="Premium Diesel">Premium Diesel</option> | ||||
|             <option value="Premium Gasoline 95">Premium Gasoline 95</option> | ||||
|             <option value="Premium Gasoline 98">Premium Gasoline 98</option> | ||||
|             <option value="Other">Other</option> | ||||
|         </select> | ||||
|  | ||||
|         <label for="note">Note</label> | ||||
|         <input type="text" name="note" id="note" value="<?= htmlspecialchars($_POST['note'] ?? '') ?>"> | ||||
|  | ||||
|         <input type="submit" value="Create vehicle"> | ||||
|     </form> | ||||
| </section> | ||||
							
								
								
									
										19
									
								
								app/views/vehicles/index.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								app/views/vehicles/index.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| <link rel="stylesheet" href="/css/vehicles.css"> | ||||
| <section class="vehicles"> | ||||
|     <?php if (empty($this->get('vehicles'))): ?> | ||||
|         <p>No vehicles yet. <a href="/vehicles/add">Add your first vehicle</a>.</p> | ||||
|     <?php else: ?> | ||||
|         <div class="vehicle-wrapper"> | ||||
|         <?php foreach ($this->get('vehicles') as $vehicle): ?> | ||||
|             <div class="vehicle bordered"> | ||||
|                 <b><?= htmlspecialchars($vehicle['name']) ?></b> | ||||
|                 <a href="/vehicles/edit?id=<?= $vehicle['id'] ?>">Edit</a> | | ||||
|                 <a href="/vehicles/delete?id=<?= $vehicle['id'] ?>" onclick="return confirm('Are you sure you want to delete this habit?')">Delete</a> | ||||
|             </div> | ||||
|         <?php endforeach; ?> | ||||
|         </div> | ||||
|  | ||||
|         <br> | ||||
|         <a href="/vehicles/create" class="btn-green">Add new vehicle!</a> | ||||
|     <?php endif; ?> | ||||
| </section> | ||||
| @@ -79,6 +79,7 @@ class Database { | ||||
|                 registration_plate VARCHAR(50) NOT NULL UNIQUE, | ||||
|                 fuel_type ENUM('Diesel', 'Gasoline 95', 'Gasoline 98', 'Premium Diesel', 'Premium Gasoline 95', 'Premium Gasoline 98', 'Other') NOT NULL, | ||||
|                 note VARCHAR(150) NULL, | ||||
|                 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | ||||
|                 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE | ||||
|             ) ENGINE=InnoDB; | ||||
|         "; | ||||
| @@ -95,7 +96,7 @@ class Database { | ||||
|                 liters DECIMAL(10, 2) NOT NULL, | ||||
|                 price_per_liter DECIMAL(10, 2) NOT NULL, | ||||
|                 total_price DECIMAL(10, 2) NOT NULL, | ||||
|                 refueling_date DATE NOT NULL, | ||||
|                 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | ||||
|                 FOREIGN KEY (vehicle_id) REFERENCES vehicles(id) ON DELETE CASCADE | ||||
|             ) ENGINE=InnoDB; | ||||
|         "; | ||||
|   | ||||
| @@ -1,21 +0,0 @@ | ||||
| .form form .dow_chb_wrapper input[type="checkbox"] { | ||||
|   width: 1rem; | ||||
| } | ||||
|  | ||||
| .form form .dow_chb_wrapper { | ||||
|   display: flex; | ||||
|   justify-content: space-between; | ||||
| } | ||||
|  | ||||
| #lbl_dow { | ||||
|   margin-bottom: .5rem; | ||||
| } | ||||
|  | ||||
| #lbl_dom { | ||||
|   margin-top: .5rem; | ||||
| } | ||||
|  | ||||
| #custom-frequency { | ||||
|   flex-direction: column; | ||||
|   justify-content: space-between; | ||||
| } | ||||
							
								
								
									
										3
									
								
								public/css/vehicle_create.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								public/css/vehicle_create.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| #registration_plate { | ||||
|   text-transform: uppercase; | ||||
| } | ||||
| @@ -20,7 +20,8 @@ require_once '../core/Database.php'; | ||||
| require_once '../core/middlewares/RequireAuth.php'; | ||||
|  | ||||
| require_once models . 'User.php'; | ||||
| require_once models . 'Habit.php'; | ||||
| require_once models . 'Vehicle.php'; | ||||
| #require_once models . 'Refueling.php'; | ||||
|  | ||||
| // Initialize router | ||||
| $router = new Router(); | ||||
| @@ -41,11 +42,11 @@ $router->group('/auth', [], function ($router) { | ||||
| $router->add('/dashboard', 'DashboardController@index', ['RequireAuth']); | ||||
|  | ||||
| // habits routes | ||||
| $router->group('/habits', ['RequireAuth'], function ($router) { | ||||
|     $router->add('', 'HabitController@index'); | ||||
|     $router->add('/create', 'HabitController@create'); | ||||
|     $router->add('/edit/{id}', 'HabitController@edit'); | ||||
|     $router->add('/delete/{id}', 'HabitController@delete'); | ||||
| $router->group('/vehicles', ['RequireAuth'], function ($router) { | ||||
|     $router->add('', 'VehicleController@index'); | ||||
|     $router->add('/add', 'VehicleController@create'); | ||||
|     $router->add('/edit/{id}', 'VehicleController@edit'); | ||||
|     $router->add('/delete/{id}', 'VehicleController@delete'); | ||||
| }); | ||||
|  | ||||
| $router->dispatch(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user