sapidjy/aerotracker-pro
0
1// Sample data2let planes = [3 {4 id: '1',5 model: 'Boeing 737',6 registration: 'F-GZCP',7 capacity: 180,8 manufactureYear: 2015,9 createdAt: new Date('2020-01-15')10 },11 {12 id: '2',13 model: 'Airbus A320',14 registration: 'F-HUIP',15 capacity: 160,16 manufactureYear: 2018,17 createdAt: new Date('2020-03-22')18 },19 {20 id: '3',21 model: 'Boeing 787 Dreamliner',22 registration: 'F-ABCD',23 capacity: 290,24 manufactureYear: 2019,25 createdAt: new Date('2021-05-10')26 },27 {28 id: '4',29 model: 'Airbus A380',30 registration: 'F-XYZK',31 capacity: 555,32 manufactureYear: 2012,33 createdAt: new Date('2021-07-30')34 },35];36 37// Initialize the application38function initApp() {39 renderPlanesList();40 renderPlanesCards();41 setupEventListeners();42}43 44// Render planes in table view45function renderPlanesList(filteredPlanes = null) {46 const planesToRender = filteredPlanes || planes;47 const tableBody = document.getElementById('planes-table-body');48 49 tableBody.innerHTML = planesToRender.map(plane => `50 <tr class="hover:bg-gray-50">51 <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">${plane.model}</td>52 <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${plane.registration}</td>53 <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${plane.capacity}</td>54 <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${plane.manufactureYear || 'N/A'}</td>55 <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 flex gap-2">56 <button class="text-blue-600 hover:text-blue-800 edit-btn" data-id="${plane.id}">57 <i data-feather="edit"></i>58 </button>59 <button class="text-red-600 hover:text-red-800 delete-btn" data-id="${plane.id}">60 <i data-feather="trash-2"></i>61 </button>62 </td>63 </tr>64 `).join('');65 66 feather.replace();67}68 69// Render planes in card view70function renderPlanesCards(filteredPlanes = null) {71 const planesToRender = filteredPlanes || planes;72 const cardContainer = document.getElementById('card-view');73 74 cardContainer.innerHTML = planesToRender.map(plane => `75 <div class="plane-card bg-white rounded-lg shadow overflow-hidden border border-gray-100">76 <div class="p-6">77 <div class="flex justify-between items-start">78 <h3 class="text-lg font-semibold text-gray-900">${plane.model}</h3>79 <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">80 ${plane.registration}81 </span>82 </div>83 <div class="mt-4 grid grid-cols-2 gap-4">84 <div>85 <p class="text-sm text-gray-500">Capacité</p>86 <p class="text-sm font-medium text-gray-900">${plane.capacity} passagers</p>87 </div>88 <div>89 <p class="text-sm text-gray-500">Année</p>90 <p class="text-sm font-medium text-gray-900">${plane.manufactureYear || 'N/A'}</p>91 </div>92 </div>93 <div class="mt-6 flex justify-end gap-2">94 <button class="text-blue-600 hover:text-blue-800 edit-btn p-1 rounded hover:bg-blue-50" data-id="${plane.id}">95 <i data-feather="edit" class="w-4 h-4"></i>96 </button>97 <button class="text-red-600 hover:text-red-800 delete-btn p-1 rounded hover:bg-red-50" data-id="${plane.id}">98 <i data-feather="trash-2" class="w-4 h-4"></i>99 </button>100 </div>101 </div>102 </div>103 `).join('');104 105 feather.replace();106}107 108// Filter planes based on search criteria109function filterPlanes() {110 const searchTerm = document.getElementById('search-input').value.toLowerCase();111 const minCapacity = parseInt(document.getElementById('min-capacity').value) || 0;112 const minYear = parseInt(document.getElementById('min-year').value) || 0;113 114 const filtered = planes.filter(plane => {115 const matchesSearch = plane.model.toLowerCase().includes(searchTerm) || 116 plane.registration.toLowerCase().includes(searchTerm);117 const matchesCapacity = plane.capacity >= minCapacity;118 const matchesYear = !plane.manufactureYear || plane.manufactureYear >= minYear;119 120 return matchesSearch && matchesCapacity && matchesYear;121 });122 123 renderPlanesList(filtered);124 renderPlanesCards(filtered);125}126 127// Setup all event listeners128function setupEventListeners() {129 // View toggle130 document.getElementById('list-view-btn').addEventListener('click', () => {131 document.getElementById('list-view').classList.remove('hidden');132 document.getElementById('card-view').classList.add('hidden');133 });134 135 document.getElementById('card-view-btn').addEventListener('click', () => {136 document.getElementById('list-view').classList.add('hidden');137 document.getElementById('card-view').classList.remove('hidden');138 });139 140 // Modal controls141 document.getElementById('add-plane-btn').addEventListener('click', () => {142 document.getElementById('add-plane-modal').classList.remove('hidden');143 });144 145 document.getElementById('close-modal-btn').addEventListener('click', () => {146 document.getElementById('add-plane-modal').classList.add('hidden');147 });148 149 document.getElementById('cancel-btn').addEventListener('click', () => {150 document.getElementById('add-plane-modal').classList.add('hidden');151 });152 153 // Filter controls154 document.getElementById('filter-btn').addEventListener('click', filterPlanes);155 document.getElementById('reset-btn').addEventListener('click', () => {156 document.getElementById('search-input').value = '';157 document.getElementById('min-capacity').value = '';158 document.getElementById('min-year').value = '';159 renderPlanesList();160 renderPlanesCards();161 });162 163 // Form submission164 document.getElementById('plane-form').addEventListener('submit', (e) => {165 e.preventDefault();166 addNewPlane();167 });168 169 // Event delegation for edit/delete buttons170 document.addEventListener('click', (e) => {171 if (e.target.closest('.edit-btn')) {172 const planeId = e.target.closest('.edit-btn').dataset.id;173 editPlane(planeId);174 }175 176 if (e.target.closest('.delete-btn')) {177 const planeId = e.target.closest('.delete-btn').dataset.id;178 deletePlane(planeId);179 }180 });181}182 183// Add a new plane184function addNewPlane() {185 const model = document.getElementById('model').value;186 const registration = document.getElementById('registration').value;187 const capacity = parseInt(document.getElementById('capacity').value);188 const manufactureYear = document.getElementById('manufacture-year').value 189 ? parseInt(document.getElementById('manufacture-year').value) 190 : null;191 192 const newPlane = {193 id: generateId(),194 model,195 registration,196 capacity,197 manufactureYear,198 createdAt: new Date()199 };200 201 planes.push(newPlane);202 renderPlanesList();203 renderPlanesCards();204 document.getElementById('add-plane-modal').classList.add('hidden');205 document.getElementById('plane-form').reset();206}207 208// Edit a plane (simplified for demo)209function editPlane(planeId) {210 const plane = planes.find(p => p.id === planeId);211 if (!plane) return;212 213 // In a real app, we would populate the form with existing data and handle update214 alert(`Edition de l'avion ${plane.model} (${plane.registration}) - Cette fonctionnalité sera implémentée dans la version finale.`);215}216 217// Delete a plane218function deletePlane(planeId) {219 if (confirm('Êtes-vous sûr de vouloir supprimer cet avion ?')) {220 planes = planes.filter(p => p.id !== planeId);221 renderPlanesList();222 renderPlanesCards();223 }224}225 226// Helper function to generate unique ID227function generateId() {228 return Math.random().toString(36).substr(2, 9);229}