// Rental-car details subsection used inside the day editor for rental entries, // plus a compact one-line renderer for the entry list. Pickup/dropoff use // plain-text location names only (they do not feed the route), so there is no // geocode/lat-lng UI here. Kept separate so dayEditor.js stays small. import { el } from '../dom.js'; import { formatDate } from '../format.js'; // createRentalDetails({ initial, entryDate, onChange }) -> // { node, read(), load(rental) } // read() -> { rental: {...} | null, pickupDate } or { error }. export function createRentalDetails({ initial = null, entryDate, onChange = () => {} } = {}) { const brandI = textInput('Brand (e.g. Toyota)', 60); const modelI = textInput('Model (e.g. Yaris Cross)', 60); const carTypeI = textInput('Type (e.g. SUV)', 40); const bookingI = textInput('Booking ref', 60); const includedI = el('input', { class: 'input', type: 'number', min: '0', step: '1', placeholder: 'e.g. 1500' }); const pDate = el('input', { class: 'input', type: 'date' }); const pTime = el('input', { class: 'input', type: 'time' }); const pLoc = textInput('Location (free text)', 120); const dDate = el('input', { class: 'input', type: 'date' }); const dTime = el('input', { class: 'input', type: 'time' }); const dLoc = textInput('Location (free text)', 120); for (const inp of [brandI, modelI, carTypeI, bookingI, includedI, pDate, pTime, pLoc, dDate, dTime, dLoc]) { inp.addEventListener('input', onChange); } const node = el( 'div', { class: 'rental-details' }, el('div', { class: 'form-row' }, field('Brand', brandI), field('Model', modelI)), el('div', { class: 'form-row' }, field('Car type', carTypeI), field('Booking ref', bookingI), field('Included km', includedI)), el('div', { class: 'rental-blocks' }, rentalBlock('Pickup', pDate, pTime, pLoc), rentalBlock('Dropoff', dDate, dTime, dLoc)), ); function read() { const brand = brandI.value.trim(); const model = modelI.value.trim(); const car_type = carTypeI.value.trim(); const booking_ref = bookingI.value.trim(); const includedRaw = includedI.value.trim(); const pickupDate = pDate.value || entryDate; const dropoffDate = dDate.value || pickupDate; const anyContent = brand || model || car_type || booking_ref || includedRaw || pTime.value || pLoc.value.trim() || dTime.value || dLoc.value.trim(); if (!anyContent) return { rental: null, pickupDate }; let included_km = null; if (includedRaw !== '') { const n = Number(includedRaw); if (!Number.isFinite(n) || n < 0) return { error: 'Included km must be a number ≥ 0.' }; included_km = n; } const rental = {}; if (brand) rental.brand = brand; if (model) rental.model = model; if (car_type) rental.car_type = car_type; if (booking_ref) rental.booking_ref = booking_ref; if (included_km != null) rental.included_km = included_km; rental.pickup = { date: pickupDate }; if (pTime.value) rental.pickup.time = pTime.value; if (pLoc.value.trim()) rental.pickup.location_name = pLoc.value.trim(); rental.dropoff = { date: dropoffDate }; if (dTime.value) rental.dropoff.time = dTime.value; if (dLoc.value.trim()) rental.dropoff.location_name = dLoc.value.trim(); return { rental, pickupDate }; } function load(rental) { const r = rental || {}; brandI.value = r.brand || ''; modelI.value = r.model || ''; carTypeI.value = r.car_type || ''; bookingI.value = r.booking_ref || ''; includedI.value = r.included_km != null ? String(r.included_km) : ''; const p = r.pickup || {}; pDate.value = p.date || entryDate || ''; pTime.value = p.time || ''; pLoc.value = p.location_name || ''; const d = r.dropoff || {}; dDate.value = d.date || p.date || entryDate || ''; dTime.value = d.time || ''; dLoc.value = d.location_name || ''; onChange(); } // Initial values (defaults: both dates to the entry's day). load(initial || { pickup: { date: entryDate }, dropoff: { date: entryDate } }); return { node, read, load }; } // "🚙 Toyota Yaris Cross · pickup 09:00 CNX Airport → dropoff 7 Aug 18:00 · 1,500 km included · RC-889231" export function renderRentalLine(rental) { const car = [rental.brand, rental.model].filter(Boolean).join(' ') || 'Rental car'; const p = rental.pickup || {}; const d = rental.dropoff || {}; const pickup = ['pickup', p.time, p.location_name].filter(Boolean).join(' '); const dropoff = ['dropoff', d.date ? formatDate(d.date) : null, d.time, d.location_name].filter(Boolean).join(' '); const bits = [`🚙 ${car}`, `${pickup} → ${dropoff}`]; if (rental.included_km != null) bits.push(`${Number(rental.included_km).toLocaleString()} km included`); if (rental.booking_ref) bits.push(rental.booking_ref); return el('div', { class: 'entry-rental muted' }, bits.join(' · ')); } function textInput(placeholder, maxlength) { return el('input', { class: 'input', type: 'text', maxlength: String(maxlength), placeholder }); } function field(label, input) { return el('label', { class: 'field field-grow' }, el('span', { class: 'field-label' }, label), input); } function rentalBlock(title, dateInput, timeInput, locInput) { return el( 'div', { class: 'rental-block' }, el('h4', { class: 'rental-block-title' }, title), el('div', { class: 'form-row' }, field('Date', dateInput), field('Time', timeInput)), field('Location', locInput), ); }