CoolFace
Apppublic

ZohnBorn/fleet-space

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes
index.html311 linesDownload Raw Back to root
1<!DOCTYPE html>2<html lang="en">3<head>4  <meta charset="UTF-8" />5  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>6  <title>Fleet Management App</title>7  <script src="https://cdn.tailwindcss.com"></script>8</head>9<body class="bg-gray-100 font-sans text-gray-900">10 11<!-- App Container -->12<div id="app" class="flex flex-col h-screen">13 14  <!-- Header -->15  <header class="bg-blue-600 text-white p-4 text-center text-xl font-semibold">16    Fleet Management App17  </header>18 19  <!-- Main Content -->20  <main id="main" class="flex-1 p-4 overflow-auto"></main>21 22  <!-- Navigation -->23  <nav class="bg-blue-600 text-white flex justify-around items-center h-16">24    <button onclick="navigate('home')" class="flex flex-col items-center">25      <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">26        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />27      </svg>28      <span>Home</span>29    </button>30    <button onclick="navigate('cars')" class="flex flex-col items-center">31      <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">32        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z" />33      </svg>34      <span>Cars</span>35    </button>36    <button onclick="navigate('drivers')" class="flex flex-col items-center">37      <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">38        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />39      </svg>40      <span>Drivers</span>41    </button>42    <button onclick="navigate('records')" class="flex flex-col items-center">43      <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">44        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" />45      </svg>46      <span>Records</span>47    </button>48    <button onclick="navigate('reports')" class="flex flex-col items-center">49      <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">50        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" />51      </svg>52      <span>Reports</span>53    </button>54    <button onclick="navigate('settings')" class="flex flex-col items-center">55      <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">56        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" />57        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />58      </svg>59      <span>Settings</span>60    </button>61  </nav>62 63</div>64 65<!-- Scripts -->66<script type="module">67  // Mock data68  const cars = [69    { CarID: "CAR001", Make: "Toyota", Model: "Corolla", Year: 2023, LicensePlate: "ABC123GP", VIN: "VIN1234567890", MonthlyRentalCost: 500, MonthlyKms: 4000, TotalKms: 12000, AssignedDriver: "DRV001", Province: "Gauteng", Division: "Sales", Status: "Active" },70    { CarID: "CAR002", Make: "Ford", Model: "Ranger", Year: 2022, LicensePlate: "XYZ789EC", VIN: "VIN9876543210", MonthlyRentalCost: 700, MonthlyKms: 5500, TotalKms: 18000, AssignedDriver: "DRV002", Province: "Western Cape", Division: "Logistics", Status: "Maintenance" }71  ];72  const drivers = [73    { DriverID: "DRV001", FirstName: "John", LastName: "Smith", FullName: "John Smith", ContactNumber: "+27123456789", Position: "Field Manager", Province: "Gauteng", Division: "Sales", AssignedCar: "CAR001", Status: "Active" },74    { DriverID: "DRV002", FirstName: "Jane", LastName: "Doe", FullName: "Jane Doe", ContactNumber: "+27987654321", Position: "Logistics Lead", Province: "Western Cape", Division: "Logistics", AssignedCar: "CAR002", Status: "Active" }75  ];76  const records = [77    { RecordID: "REC001", CarID: "CAR001", MonthYear: "2025-09-01", MonthlyRentalCost: 500, MonthlyKms: 4000, Description: "September 2025 usage" },78    { RecordID: "REC002", CarID: "CAR002", MonthYear: "2025-09-01", MonthlyRentalCost: 700, MonthlyKms: 5500, Description: "September 2025 usage" }79  ];80 81  let currentMonth = new Date(new Date().getFullYear(), new Date().getMonth(), 1).toISOString().split('T')[0];82  let selectedCar = null;83  let selectedDriver = null;84 85  function navigate(screen) {86    const main = document.getElementById('main');87    main.innerHTML = '';88    switch (screen) {89      case 'home':90        showHome();91        break;92      case 'cars':93        showCars();94        break;95      case 'drivers':96        showDrivers();97        break;98      case 'records':99        showRecords();100        break;101      case 'reports':102        showReports();103        break;104      case 'settings':105        showSettings();106        break;107    }108  }109 110  function showHome() {111    const html = `112      <h2 class="text-2xl text-blue-600 text-center mb-4">Dashboard</h2>113      <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-6">114        <div class="bg-white p-4 border border-blue-600 rounded shadow">115          <h3 class="text-lg">Total Active Cars</h3>116          <p class="text-xl">${cars.filter(c => c.Status === 'Active').length}</p>117        </div>118        <div class="bg-white p-4 border border-blue-600 rounded shadow">119          <h3 class="text-lg">Total Active Drivers</h3>120          <p class="text-xl">${drivers.filter(d => d.Status === 'Active').length}</p>121        </div>122        <div class="bg-white p-4 border border-blue-600 rounded shadow">123          <h3 class="text-lg">Total Monthly Cost</h3>124          <p class="text-xl">$${(records.filter(r => r.MonthYear === currentMonth).reduce((a, b) => a + b.MonthlyRentalCost, 0)).toFixed(2)}</p>125        </div>126        <div class="bg-white p-4 border border-blue-600 rounded shadow">127          <h3 class="text-lg">Total Kms Driven</h3>128          <p class="text-xl">${records.filter(r => r.MonthYear === currentMonth).reduce((a, b) => a + b.MonthlyKms, 0)} km</p>129        </div>130      </div>131      <h3 class="text-lg text-blue-600 mb-2">Recent Records</h3>132      <ul class="bg-white p-4 border border-blue-600 rounded shadow max-h-64 overflow-y-auto">133        ${records.filter(r => r.MonthYear === currentMonth).map(r => `134          <li class="mb-2">${cars.find(c => c.CarID === r.CarID)?.LicensePlate} - ${r.MonthlyKms} km - $${r.MonthlyRentalCost}</li>135        `).join('')}136      </ul>137    `;138    document.getElementById('main').innerHTML = html;139  }140 141  function showCars() {142    document.getElementById('main').innerHTML = `143      <h2 class="text-2xl text-blue-600 text-center mb-4">Cars</h2>144      <input id="searchCar" class="w-full mb-4 p-2 border rounded" placeholder="Search by Make, Model or License Plate"/>145      <ul class="space-y-2">146        ${cars.map(car => `147          <li onclick="editCar('${car.CarID}')" class="bg-white p-3 border rounded shadow cursor-pointer">148            <div><strong>${car.Make} ${car.Model}</strong> - ${car.LicensePlate}</div>149            <div>Status: <span class="font-semibold ${car.Status === 'Active' ? 'text-green-500' : car.Status === 'Maintenance' ? 'text-yellow-500' : 'text-red-500'}">${car.Status}</span></div>150            <div>Driver: ${drivers.find(d => d.DriverID === car.AssignedDriver)?.FullName || 'None'}</div>151          </li>152        `).join('')}153      </ul>154      <button onclick="addCar()" class="mt-4 bg-green-500 text-white px-4 py-2 rounded">Add Car</button>155    `;156  }157 158  function showDrivers() {159    document.getElementById('main').innerHTML = `160      <h2 class="text-2xl text-blue-600 text-center mb-4">Drivers</h2>161      <input id="searchDriver" class="w-full mb-4 p-2 border rounded" placeholder="Search by Name or Contact"/>162      <ul class="space-y-2">163        ${drivers.map(driver => `164          <li onclick="editDriver('${driver.DriverID}')" class="bg-white p-3 border rounded shadow cursor-pointer">165            <div><strong>${driver.FirstName} ${driver.LastName}</strong></div>166            <div>Contact: ${driver.ContactNumber}</div>167            <div>Position: ${driver.Position}</div>168            <div>Status: <span class="font-semibold ${driver.Status === 'Active' ? 'text-green-500' : driver.Status === 'OnLeave' ? 'text-yellow-500' : 'text-red-500'}">${driver.Status}</span></div>169          </li>170        `).join('')}171      </ul>172      <button onclick="addDriver()" class="mt-4 bg-green-500 text-white px-4 py-2 rounded">Add Driver</button>173    `;174  }175 176  function showRecords() {177    document.getElementById('main').innerHTML = `178      <h2 class="text-2xl text-blue-600 text-center mb-4">Monthly Records</h2>179      <ul class="space-y-2">180        ${records.map(record => `181          <li class="bg-white p-3 border rounded shadow">182            <div>Car: ${cars.find(c => c.CarID === record.CarID)?.LicensePlate}</div>183            <div>Month: ${record.MonthYear}</div>184            <div>Kms: ${record.MonthlyKms} km</div>185            <div>Rental: $${record.MonthlyRentalCost}</div>186          </li>187        `).join('')}188      </ul>189      <button onclick="addRecord()" class="mt-4 bg-green-500 text-white px-4 py-2 rounded">Add Record</button>190    `;191  }192 193  function showReports() {194    const totalKms = records.reduce((a, b) => a + b.MonthlyKms, 0);195    const totalCost = records.reduce((a, b) => a + b.MonthlyRentalCost, 0);196    const avgCostPerKm = totalKms > 0 ? (totalCost / totalKms).toFixed(2) : 0;197 198    document.getElementById('main').innerHTML = `199      <h2 class="text-2xl text-blue-600 text-center mb-4">Reports</h2>200      <div class="bg-white p-4 border border-blue-600 rounded shadow mb-4">201        <p>Average Cost per Km: $${avgCostPerKm}/km</p>202        <p>Over-limit Cars: ${records.filter(r => r.MonthlyKms > 6000).length}</p>203      </div>204      <button class="bg-blue-600 text-white px-4 py-2 rounded">Export to Excel</button>205    `;206  }207 208  function showSettings() {209    document.getElementById('main').innerHTML = `210      <h2 class="text-2xl text-blue-600 text-center mb-4">Settings</h2>211      <input type="date" id="monthPicker" value="${currentMonth}" class="w-full mb-4 p-2 border rounded"/>212      <button onclick="refreshData()" class="bg-blue-600 text-white px-4 py-2 rounded mr-2">Refresh Data</button>213      <button onclick="resetMonthlyKms()" class="bg-blue-600 text-white px-4 py-2 rounded">Reset Monthly Kms</button>214    `;215  }216 217  function editCar(id) {218    selectedCar = cars.find(c => c.CarID === id);219    showCarForm();220  }221 222  function editDriver(id) {223    selectedDriver = drivers.find(d => d.DriverID === id);224    showDriverForm();225  }226 227  function addCar() {228    selectedCar = null;229    showCarForm();230  }231 232  function addDriver() {233    selectedDriver = null;234    showDriverForm();235  }236 237  function addRecord() {238    alert('Add Monthly Record Form (not implemented in this prototype)');239  }240 241  function refreshData() {242    alert('Data refreshed (mock)');243  }244 245  function resetMonthlyKms() {246    if (confirm('Are you sure you want to reset monthly kms?')) {247      cars.forEach(car => car.MonthlyKms = 0);248      alert('Monthly kms reset');249    }250  }251 252  function showCarForm() {253    const car = selectedCar || { CarID: '', Make: '', Model: '', LicensePlate: '' };254    document.getElementById('main').innerHTML = `255      <h2 class="text-2xl text-blue-600 text-center mb-4">${selectedCar ? 'Edit' : 'Add'} Car</h2>256      <form id="carForm" class="space-y-2">257        <input type="text" name="Make" value="${car.Make}" placeholder="Make" class="w-full p-2 border rounded" required />258        <input type="text" name="Model" value="${car.Model}" placeholder="Model" class="w-full p-2 border rounded" required />259        <input type="text" name="LicensePlate" value="${car.LicensePlate}" placeholder="License Plate" class="w-full p-2 border rounded" required />260        <button type="submit" class="bg-green-500 text-white px-4 py-2 rounded mr-2">Save</button>261        <button type="button" onclick="navigate('cars')" class="bg-red-500 text-white px-4 py-2 rounded">Cancel</button>262      </form>263    `;264    document.getElementById('carForm').onsubmit = function(e) {265      e.preventDefault();266      const formData = new FormData(e.target);267      const updatedCar = Object.fromEntries(formData);268      if (!selectedCar) {269        updatedCar.CarID = 'CAR' + (cars.length + 1).toString().padStart(3, '0');270        cars.push(updatedCar);271      } else {272        Object.assign(selectedCar, updatedCar);273      }274      navigate('cars');275    };276  }277 278  function showDriverForm() {279    const driver = selectedDriver || { FirstName: '', LastName: '', ContactNumber: '' };280    document.getElementById('main').innerHTML = `281      <h2 class="text-2xl text-blue-600 text-center mb-4">${selectedDriver ? 'Edit' : 'Add'} Driver</h2>282      <form id="driverForm" class="space-y-2">283        <input type="text" name="FirstName" value="${driver.FirstName}" placeholder="First Name" class="w-full p-2 border rounded" required />284        <input type="text" name="LastName" value="${driver.LastName}" placeholder="Last Name" class="w-full p-2 border rounded" required />285        <input type="text" name="ContactNumber" value="${driver.ContactNumber}" placeholder="Contact Number" class="w-full p-2 border rounded" required />286        <button type="submit" class="bg-green-500 text-white px-4 py-2 rounded mr-2">Save</button>287        <button type="button" onclick="navigate('drivers')" class="bg-red-500 text-white px-4 py-2 rounded">Cancel</button>288      </form>289    `;290    document.getElementById('driverForm').onsubmit = function(e) {291      e.preventDefault();292      const formData = new FormData(e.target);293      const updatedDriver = Object.fromEntries(formData);294      if (!selectedDriver) {295        updatedDriver.DriverID = 'DRV' + (drivers.length + 1).toString().padStart(3, '0');296        updatedDriver.FullName = `${updatedDriver.FirstName} ${updatedDriver.LastName}`;297        drivers.push(updatedDriver);298      } else {299        Object.assign(selectedDriver, updatedDriver);300        selectedDriver.FullName = `${updatedDriver.FirstName} ${updatedDriver.LastName}`;301      }302      navigate('drivers');303    };304  }305 306  // Initialize307  navigate('home');308</script>309 310<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-qwensite.hf.space/logo.svg" alt="qwensite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-qwensite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >QwenSite</a> - 🧬 <a href="https://enzostvs-qwensite.hf.space?remix=ZohnBorn/fleet-space" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>311</html>