Files
gps-frontend/resources/views/menu_v1/reports/view_trip_detail.blade.php

374 lines
12 KiB
PHP

<!DOCTYPE html>
<html lang="\en">
<head>
<title>Movana Fleet Management | @yield('title', 'App')</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<link rel="icon" type="image/x-icon" href="{{ asset('images/favicon.png') }}">
<link href="{{ asset('fonts/stylesheet.css') }}" rel="stylesheet">
<link href="{{ asset('assets/vendor/bootstrap-5.0.2-dist/css/bootstrap.css') }}" rel="stylesheet">
<link href="{{ asset('assets/vendor/leaflet-1.7.1/leaflet.css') }}" rel="stylesheet">
<link href="{{ asset('assets/vendor/ionicons-v2.0-1/css/ionicons.css') }}" rel="stylesheet">
<link href="{{ asset('assets/vendor/select2-4.1.0-rc.0/dist/css/select2.css') }}" rel="stylesheet">
<link href="{{ asset('assets/vendor/DataTables/datatables.css') }}" rel="stylesheet">
<link href="{{ asset('assets/css/bootstrap-datepicker.min.css') }}" rel="stylesheet">
<link href="{{ asset('assets/css/meus.css') }}" rel="stylesheet">
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.20/jquery.datetimepicker.min.css"
integrity="sha512-f0tzWhCwVFS3WeYaofoLWkTP62ObhewQ1EZn65oSYDZUg1+CyywGKkWzm8BxaJj5HGKI72PnMH9jYyIFz+GH7g=="
crossorigin="anonymous" referrerpolicy="no-referrer" />
<style>
.landscape-photo {
max-height: max(21vh, 210px);
}
.thumb-img-table {
width: max(4vw, 75px);
height: max(4vh, 55px);
object-fit: cover;
}
.thumb-img-small {
width: max(2vw, 45px);
height: max(2vh, 35px);
object-fit: cover;
}
.thumb-img-landscape {
width: max(6vw, 275px);
height: max(5vh, 125px);
object-fit: cover;
}
.thumb-img-landscape-med {
width: max(4vw, 125px);
height: max(2vh, 65px);
object-fit: contain;
}
</style>
@yield('customcss')
</head>
{{--
<body onload="startTime()"> --}}
<body>
<div class="container-fluid">
<div class="content">
<div class="card">
<div class="card-header">
<h4>{{$nopol1}}</h4>
</div>
<div class="card-body">
<div class="row head-text" id="viewPdf">
<div class="col-6">
<p class="text-bold mb-0">Start</p>
<p class="mb-0 time">{{ $start['time'] }}</p>
<p class="mb-0">Vehicle Mileage: {{number_format($start['mileage'], 2)}} km</p>
<p>{{$start['fulladdress']}}</p>
</div>
<div class="col-6">
<p class="text-bold mb-0">Finish</p>
<p class="mb-0 time">{{ $finish['time'] }}</p>
<p class="mb-0">Vehicle Mileage: {{number_format($finish['mileage'], 2)}} km</p>
<p>{{$finish['fulladdress']}}</p>
</div>
<div class="col-4">
<p class="text-bold mb-0">Distance</p>
<p class="mb-0">{{number_format($distance, 2)}} km</p>
</div>
<div class="col-4">
<p class="text-bold mb-0">Duration</p>
<p class="mb-0">{{$duration}}</p>
</div>
<div class="col-4">
<p class="text-bold mb-0">Fuel consumption</p>
<p class="mb-0">{{$fuel_consumed / 10}} L</p>
</div>
<div class="col-12 mt-2">
<div id="leafMap" style="height: 400px;"></div>
</div>
<div class="col-12">
<!-- <li class="list-group-item p-1 px-2">
<p class="text-bold mb-0">Time: 25 Aug 2025 07:31:08</p>
<p class="text-muted mb-0 dtl-text">-8.55387 - 125.542409</p>
<p class="text-muted mb-0 dtl-text">Avenida Luro Mata, Praia dos Coqueiros, Bebunuk, Dom Aleixo, Dili, Timor-Leste;2066973</p>
<p class="mb-0 dtl-text">Current speed: 7km/h</p>
</li> -->
@foreach ($list as $item)
<!-- <li class="list-group-item p-1 px-2">
<p class="text-bold mb-0">Time: {{date('d-m-Y H:i:s', $item->crt_d)}}</p>
<p class="text-muted mb-0 dtl-text">Vehicle Mileage: {{number_format($item->vhc_milleage, 2)}} km</p>
<p class="text-muted mb-0 dtl-text">{{number_format($item->latitude, 6)}} - {{number_format($item->longitude, 6)}}</p>
<p class="text-muted mb-0 dtl-text">{{urldecode($item->fulladdress)}}</p>
<p class="text-muted mb-0 dtl-text">Current speed: {{number_format($item->speed, 2)}} km/h</p>
</li> -->
<li class="list-group-item p-1 px-2">
<div class="row">
<div class="col-4">
<p class="text-bold mb-0 dtl-text">Time: <span
class="time">{{ $item->crt_d }}</span>
</p>
<p class="text-muted mb-0 dtl-text">Vehicle Mileage:
{{number_format($item->vhc_milleage, 2)}} km
</p>
<p class="text-muted mb-0 dtl-text">Current speed: {{$item->speed}} km/h</p>
</div>
<div class="col-8">
<p class="text-muted mb-0 dtl-text">{{number_format($item->latitude, 6)}},
{{number_format($item->longitude, 6)}}
</p>
<p class="text-muted mb-0 dtl-text">{{urldecode($item->fulladdress)}}</p>
</div>
</div>
</li>
@endforeach
</div>
</div>
</div>
</div>
</div>
</div>
<script src="{{ asset('assets/vendor/jquery-3.6.0/jquery-3.6.0.js') }}"></script>
<script src="{{ asset('assets/vendor/bootstrap-5.0.2-dist/js/bootstrap.bundle.min.js') }}"></script>
<script src="{{ asset('assets/js/moment.min.js') }}"></script>
<script src="{{ asset('assets/js/helper.js') }}"></script>
<script src="{{ asset('assets/js/load-image.all.min.js') }}"></script>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
<script src="https://unpkg.com/leaflet-routing-machine@3.2.12/dist/leaflet-routing-machine.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="{{ asset('assets/vendor/printThis.js') }}"></script>
<script>
$(document).ready(function () {
$('.time').each(function () {
const unix = parseInt($(this).text().trim()) + 25200;
$(this).text(moment.unix(unix).format('DD MMM YYYY HH:mm:ss'));
});
let coords
setTimeout(async () => {
map.invalidateSize(); // force Leaflet to recalc
map.fitBounds(polyline.getBounds());
// map.fitBounds(await coords.map(c => L.latLng(c[0], c[1])));
}, 200);
const linesData = (@json($list));
// 1) Initialize map
const map = L.map("leafMap").setView([-8.90507, 125.9945732], 10)
// 2) Add tile layer
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
maxZoom: 20,
crossOrigin: true
}).addTo(map);
// // // 3) Coordinates (Lat, Lng) for polyline
const points = linesData
.filter(p => p.latitude && p.longitude)
.map((point) => [point.latitude, point.longitude])
// 4) Add polyline
const polyline = L.polyline(points, {
color: 'red',
weight: 3,
opacity: 0.7,
smoothFactor: 1
})
// .addTo(map);
function chunkArray(arr, size) {
const result = [];
for (let i = 0; i < arr.length; i += size) {
result.push(arr.slice(i, i + size));
}
return result;
}
function fetchOsrm(points) {
const coords = points;
const hints = ";".repeat(points.length - 1);
const body = {
coordinates: coords,
overview: "false",
alternatives: "false",
steps: "true",
hints: hints
};
let config = {
method: 'post',
maxBodyLength: Infinity,
url: 'https://brilianapps.britimorleste.tl/osrm-backend/post-route/v1/driving/',
headers: {
'Content-Type': 'application/json'
},
data: body
};
return axios.request(config)
.then((response) => {
return response.data;
})
.catch((error) => {
console.error("Error:", error.message);
return null;
});
}
function decodeOSRMGeometry(encoded) {
const coordinates = [];
let index = 0,
lat = 0,
lng = 0;
while (index < encoded.length) {
let result = 1,
shift = 0,
b;
do {
b = encoded.charCodeAt(index++) - 63 - 1;
result += b << shift;
shift += 5;
} while (b >= 0x1f);
lat += (result & 1 ? ~(result >> 1) : result >> 1);
result = 1;
shift = 0;
do {
b = encoded.charCodeAt(index++) - 63 - 1;
result += b << shift;
shift += 5;
} while (b >= 0x1f);
lng += (result & 1 ? ~(result >> 1) : result >> 1);
coordinates.push([lat / 1e5, lng / 1e5]);
}
return coordinates;
}
async function getCoordinates(points) {
const chunkSize = 500;
const chunks = chunkArray(points, chunkSize); // Split the points array into chunks of 500
let allCoords = [];
for (const chunk of chunks) {
const osrm = await fetchOsrm(chunk); // Fetch OSRM data for each chunk
if (!osrm) {
console.log("OSRM failed for chunk");
return;
}
const coords = osrm.routes[0].legs.flatMap(leg =>
leg.steps.flatMap(step =>
decodeOSRMGeometry(step.geometry)
)
);
allCoords = allCoords.concat(coords); // Combine the result
}
// Now add the polyline to the map
L.polyline(allCoords, {
color: "#2980B9",
weight: 3,
opacity: 0.8
}).addTo(map);
// map.fitBounds(allCoords.map(c => L.latLng(c[0], c[1])));
}
// Usage: Pass the array of coordinates to the function
getCoordinates(points);
// start and finish point
const startIcon = L.icon({
iconUrl: "{{ asset('images/start.png') }}",
iconSize: [30, 30],
iconAnchor: [15, 28], // lb, rt, bottom, rb. Positive
})
L.marker(points[0], { icon: startIcon }).addTo(map)
const finishIcon = L.icon({
iconUrl: "{{ asset('images/finish.png') }}",
iconSize: [30, 30],
iconAnchor: [15, 28], // lb, rt, bottom, rb. Positive
})
L.marker(points[points.length - 1], { icon: finishIcon }).addTo(map)
// // 5) Auto-fit map to polyline bounds
// map.fitBounds(polyline.getBounds())
// download pdf
window._downloadReportBound ||= (
$(document).on('click', '#btnDownloadReport', function () {
$('#viewPdf').printThis({
debug: false, // show the iframe for debugging
importCSS: true, // copy linked styles
importStyle: true, // copy inline styles
});
// const viewPdf = document.getElementById("viewPdf");
// // find overlay svg (the one holding polylines)
// const overlaySvg = document.querySelector('.leaflet-overlay-pane svg');
// let originalTransform = '';
// if (overlaySvg) {
// originalTransform = overlaySvg.style.transform;
// overlaySvg.style.transform = 'none';
// }
// html2canvas(viewPdf, {
// scale: 2,
// useCORS: true,
// logging: true
// }).then(canvas => {
// const imgData = canvas.toDataURL('image/png');
// const { jsPDF } = window.jspdf;
// const pdf = new jsPDF('p', 'mm', 'a4');
// const pageWidth = pdf.internal.pageSize.getWidth();
// const pageHeight = pdf.internal.pageSize.getHeight();
// const imgWidth = pageWidth - 20; // margin
// const imgHeight = canvas.height * imgWidth / canvas.width;
// let position = 10;
// // 👉 Handle multipage content
// let heightLeft = imgHeight;
// while (heightLeft > 0) {
// pdf.addImage(imgData, 'PNG', 10, position, imgWidth, imgHeight);
// heightLeft -= pageHeight;
// if (heightLeft > 0) {
// pdf.addPage();
// position = 0;
// }
// }
// pdf.save(`{{$nopol1}} Trip Report {{$start['time']}}.pdf`);
// });
}),
true
);
});
</script>
</body>
</html>