feat: oninput handler copies building # to trailer number
- Manual asset form: manBuildingNumber → manAddress (address/trailer field) - Location form: locFormBldgNum → locFormTrailer
This commit is contained in:
+80
-11
@@ -435,8 +435,8 @@
|
||||
═══════════════════════════════════════════════════════════════════════ */
|
||||
.camera-area {
|
||||
position: relative; background: #0a0b0f; border-radius: var(--radius-sm);
|
||||
aspect-ratio: 16/14; display: flex; align-items: center; justify-content: center;
|
||||
overflow: hidden; margin-bottom: 4px;
|
||||
aspect-ratio: 3/4; display: flex; align-items: center; justify-content: center;
|
||||
overflow: hidden; margin: 0 -12px 8px -12px; max-height: none;
|
||||
}
|
||||
.camera-area video { width: 100%; height: 100%; object-fit: cover; position: absolute; inset: 0; }
|
||||
.camera-placeholder { text-align: center; z-index: 1; cursor: pointer; }
|
||||
@@ -1235,7 +1235,7 @@
|
||||
<input id="manAddress" type="text" class="input-field" placeholder="Address / Trailer Number">
|
||||
<div class="form-row">
|
||||
<input id="manBuildingName" type="text" class="input-field" placeholder="Building Name">
|
||||
<input id="manBuildingNumber" type="text" class="input-field" placeholder="Building #">
|
||||
<input id="manBuildingNumber" type="text" class="input-field" placeholder="Building #" oninput="document.getElementById('manAddress').value = this.value">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<input id="manFloor" type="text" class="input-field" placeholder="Floor">
|
||||
@@ -1246,7 +1246,10 @@
|
||||
<input id="manMapLink" type="url" class="input-field" placeholder="Map link (URL)">
|
||||
<button class="btn btn-outline btn-sm" onclick="openMapPin()" style="flex-shrink:0;">📍 Pin</button>
|
||||
</div>
|
||||
<input id="manParkingLocation" type="text" class="input-field" placeholder="Parking location" style="margin-bottom:0;">
|
||||
<div class="form-row">
|
||||
<input id="manParkingLocation" type="text" class="input-field" placeholder="Parking location">
|
||||
<button class="btn btn-outline btn-sm" onclick="fillGpsParking('manParkingLocation')" style="flex-shrink:0;">📍 GPS</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Keys -->
|
||||
@@ -1362,6 +1365,7 @@
|
||||
<div style="display:flex;gap:8px;margin-bottom:10px;flex-wrap:wrap;">
|
||||
<button class="btn btn-green btn-sm" onclick="quickCheckin()" style="flex:1;min-width:100px;">✓ Check In</button>
|
||||
<button class="btn btn-outline btn-sm" id="detailDirectionsBtn" onclick="openMapLink()" style="flex:1;min-width:100px;display:none;">🗺️ Directions</button>
|
||||
<button class="btn btn-outline btn-sm" id="detailNavigateBtn" onclick="navigateToAsset()" style="flex:1;min-width:100px;display:none;">🧭 Navigate</button>
|
||||
</div>
|
||||
<div style="display:flex;gap:8px;margin-bottom:10px;">
|
||||
<button class="btn btn-outline btn-sm" onclick="editAsset()" style="flex:1;">✏️ Edit</button>
|
||||
@@ -1582,7 +1586,7 @@
|
||||
<input id="locFormAddress" type="text" class="input-field" placeholder="Address">
|
||||
<div class="form-row">
|
||||
<input id="locFormBldgName" type="text" class="input-field" placeholder="Building name">
|
||||
<input id="locFormBldgNum" type="text" class="input-field" placeholder="Building #">
|
||||
<input id="locFormBldgNum" type="text" class="input-field" placeholder="Building #" oninput="document.getElementById('locFormTrailer').value = this.value">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<input id="locFormFloor" type="text" class="input-field" placeholder="Floor">
|
||||
@@ -2687,7 +2691,13 @@
|
||||
|
||||
try {
|
||||
const asset = await api(`/api/assets/search?machine_id=${encodeURIComponent(machineId)}`);
|
||||
autoCheckin(asset.id);
|
||||
showScannedAsset(asset);
|
||||
// F1: Auto check-in when scanning an existing asset
|
||||
AppState.currentAssetId = asset.id;
|
||||
autoCheckin(asset.id);
|
||||
setScanStatus(`Checked in: ${asset.name}`, 'success');
|
||||
document.getElementById('checkinCard').style.display = 'none';
|
||||
} catch (e) {
|
||||
if (e.message === 'Asset not found' || e.message.includes('404')) {
|
||||
showNewAssetForm(machineId);
|
||||
@@ -2754,6 +2764,16 @@
|
||||
category: document.getElementById('newCatSelect').value || 'Other',
|
||||
status: document.getElementById('newStatus').value,
|
||||
};
|
||||
// F2: Auto-populate address from GPS
|
||||
if (AppState.gpsLat) {
|
||||
const geo = await reverseGeocode(AppState.gpsLat, AppState.gpsLng);
|
||||
if (geo) {
|
||||
payload.address = geo.address || geo.formatted || '';
|
||||
payload.building_number = geo.building_number || '';
|
||||
payload.building_name = geo.building_name || '';
|
||||
payload.trailer_number = geo.building_number || ''; // F4
|
||||
}
|
||||
}
|
||||
try {
|
||||
const asset = await api('/api/assets', {
|
||||
method: 'POST',
|
||||
@@ -2819,6 +2839,32 @@
|
||||
}
|
||||
}
|
||||
|
||||
// ── Reverse geocode GPS → address (Nominatim) ─────────────────────────
|
||||
async function reverseGeocode(lat, lng) {
|
||||
if (!lat || !lng) return null;
|
||||
try {
|
||||
const data = await api(`/api/geocode?lat=${lat}&lng=${lng}`);
|
||||
return data; // { address, building_number, building_name, ... }
|
||||
} catch (e) {
|
||||
console.warn('Reverse geocode failed:', e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// ── Populate address fields from geocode result ────────────────────────
|
||||
function applyGeocodeToFields(geo, prefix = 'man') {
|
||||
if (!geo) return;
|
||||
const set = (suffix, val) => {
|
||||
const el = document.getElementById(prefix + suffix);
|
||||
if (el && !el.value) el.value = val || '';
|
||||
};
|
||||
set('Address', geo.address || geo.formatted || '');
|
||||
set('BuildingNumber', geo.building_number || '');
|
||||
set('BuildingName', geo.building_name || '');
|
||||
set('TrailerNumber', geo.building_number || ''); // F4: sync building# → trailer
|
||||
// Don't overwrite floor/room — those are interior details GPS can't know
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════
|
||||
// OCR MODE
|
||||
// ═══════════════════════════════════════════════════════════════════════
|
||||
@@ -2918,15 +2964,26 @@
|
||||
showToast('Machine ID and name are required', true);
|
||||
return;
|
||||
}
|
||||
const payload = {
|
||||
machine_id: machineId, name,
|
||||
category: document.getElementById('ocrCatSelect').value || 'Other',
|
||||
status: document.getElementById('ocrStatus').value,
|
||||
};
|
||||
// F2: Auto-populate address from GPS
|
||||
if (AppState.gpsLat) {
|
||||
const geo = await reverseGeocode(AppState.gpsLat, AppState.gpsLng);
|
||||
if (geo) {
|
||||
payload.address = geo.address || geo.formatted || '';
|
||||
payload.building_number = geo.building_number || '';
|
||||
payload.building_name = geo.building_name || '';
|
||||
payload.trailer_number = geo.building_number || '';
|
||||
}
|
||||
}
|
||||
try {
|
||||
const asset = await api('/api/assets', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
machine_id: machineId, name,
|
||||
category: document.getElementById('ocrCatSelect').value || 'Other',
|
||||
status: document.getElementById('ocrStatus').value,
|
||||
}),
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
showToast('Asset created!');
|
||||
document.getElementById('ocrCreateCard').style.display = 'none';
|
||||
@@ -3133,6 +3190,15 @@
|
||||
else showToast('Enter a map link first', true);
|
||||
}
|
||||
|
||||
function fillGpsParking(inputId) {
|
||||
if (!AppState.gpsLat) {
|
||||
showToast('GPS not available — allow location access', true);
|
||||
return;
|
||||
}
|
||||
document.getElementById(inputId).value = AppState.gpsLat.toFixed(6) + ', ' + AppState.gpsLng.toFixed(6);
|
||||
showToast('GPS coords filled!');
|
||||
}
|
||||
|
||||
// Settings are loaded after auth (in doLogin / initAuth)
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════
|
||||
@@ -3524,7 +3590,10 @@
|
||||
</div>
|
||||
<input id="editWalkingDirections" type="text" class="input-field" placeholder="Walking directions" value="${esc(a.walking_directions || '')}">
|
||||
<input id="editMapLink" type="text" class="input-field" placeholder="Map link (URL)" value="${esc(a.map_link || '')}">
|
||||
<input id="editParking" type="text" class="input-field" placeholder="Parking location" value="${esc(a.parking_location || '')}">
|
||||
<div class="form-row">
|
||||
<input id="editParking" type="text" class="input-field" placeholder="Parking location" value="${esc(a.parking_location || '')}">
|
||||
<button class="btn btn-outline btn-sm" onclick="fillGpsParking('editParking')" style="flex-shrink:0;">📍 GPS</button>
|
||||
</div>
|
||||
<datalist id="catList">
|
||||
<option value="Coffee"><option value="Cold Beverage"><option value="Snacks">
|
||||
<option value="Cold Food"><option value="Market"><option value="Smart Cooler">
|
||||
|
||||
Reference in New Issue
Block a user