freightdesk/webapp/src/views/pages/loads/form.ejs
FreightDesk 4a06fe370f
Some checks failed
FreightDesk CI/CD / Lint & Test (push) Has been cancelled
FreightDesk CI/CD / Build Docker Image (push) Has been cancelled
FreightDesk CI/CD / Deploy to Coolify (push) Has been cancelled
[OWL] Fix EJS include paths + layouts/main.ejs syntax
- Fixed 30 EJS views: changed ../partials/ to ../../partials/ for views in subdirectories
  (pages/loads/, pages/shippers/, pages/portal/, pages/marketplace/, pages/payments/, etc.)
- Fixed layouts/main.ejs: corrected malformed EJS tags on lines 11 and 66
  (<% ... { <% → <% ... { %>)
2026-06-08 04:30:59 +00:00

234 lines
9.8 KiB
Text

<%- include('../../partials/header', { activeMenu: 'loads' }) %>
<div class="page-header">
<div>
<h1 class="page-title"><%= isEdit ? 'Edit Load' : '+ New Load' %></h1>
<p class="page-subtitle"><%= isEdit ? 'Update load details' : 'Add a new freight load' %></p>
</div>
<a href="/loads" class="btn btn-outline">&larr; Back to Loads</a>
</div>
<% if (typeof error !== 'undefined' && error) { %>
<div class="alert alert-error"><%= error %></div>
<% } %>
<div class="grid-2">
<!-- Form -->
<div class="card">
<div class="card-header"><h3 class="card-title">Load Details</h3></div>
<div class="card-body">
<form method="POST" action="<%= isEdit ? '/loads/' + encodeURIComponent(load.id) : '/loads' %>" id="loadForm">
<input type="hidden" name="_csrf" value="<%= _csrf %>">
<div class="form-row">
<div class="form-group">
<label class="form-label">Date</label>
<input type="date" name="date" class="form-input" value="<%= load.date || '' %>">
</div>
<div class="form-group">
<label class="form-label">Status</label>
<select name="status" class="form-input">
<% for (const s of LOAD_STATUSES) { %>
<option value="<%= s %>" <%= load.status === s ? 'selected' : '' %>><%= s %></option>
<% } %>
</select>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label class="form-label">Shipper</label>
<select name="shipper_id" class="form-input">
<option value="">— Select —</option>
<% for (const s of shippers) { %>
<option value="<%= s.id %>" <%= load.shipper_id === s.id ? 'selected' : '' %>><%= s.name %></option>
<% } %>
</select>
</div>
<div class="form-group">
<label class="form-label">Vehicle</label>
<select name="vehicle_id" class="form-input">
<option value="">— Select —</option>
<% for (const v of vehicles) { %>
<option value="<%= v.id %>" <%= load.vehicle_id === v.id ? 'selected' : '' %>><%= v.number %></option>
<% } %>
</select>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label class="form-label">From City</label>
<input type="text" name="from_city" class="form-input" list="cities" value="<%= load.from_city || '' %>" placeholder="Origin">
</div>
<div class="form-group">
<label class="form-label">Via</label>
<input type="text" name="via" class="form-input" value="<%= load.via || '' %>" placeholder="Via (optional)">
</div>
<div class="form-group">
<label class="form-label">To City</label>
<input type="text" name="to_city" class="form-input" list="cities" value="<%= load.to_city || '' %>" placeholder="Destination">
</div>
</div>
<datalist id="cities">
<% for (const c of CITIES) { %><option value="<%= c %>"><% } %>
</datalist>
<div class="form-row">
<div class="form-group">
<label class="form-label">Load Type</label>
<select name="load_type" class="form-input">
<option value="">— Select —</option>
<% for (const t of LOAD_TYPES) { %>
<option value="<%= t %>" <%= load.load_type === t ? 'selected' : '' %>><%= t %></option>
<% } %>
</select>
</div>
<div class="form-group">
<label class="form-label">Item</label>
<input type="text" name="item" class="form-input" value="<%= load.item || '' %>" placeholder="Goods description">
</div>
</div>
<h4 class="section-title">Financials</h4>
<div class="form-row">
<div class="form-group">
<label class="form-label">Freight Charged (&#8377;)</label>
<input type="number" name="freight_charged" class="form-input" value="<%= load.freight_charged || '' %>" placeholder="0" id="freight_charged">
</div>
<div class="form-group">
<label class="form-label">Advance Received (&#8377;)</label>
<input type="number" name="advance_received" class="form-input" value="<%= load.advance_received || '' %>" placeholder="0" id="advance_received">
</div>
</div>
<div class="form-row">
<div class="form-group">
<label class="form-label">Paid to Driver (&#8377;)</label>
<input type="number" name="paid_to_driver" class="form-input" value="<%= load.paid_to_driver || '' %>" placeholder="0" id="paid_to_driver">
</div>
<div class="form-group">
<label class="form-label">Driver Freight (&#8377;)</label>
<input type="number" name="driver_freight" class="form-input" value="<%= load.driver_freight || '' %>" placeholder="0" id="driver_freight">
</div>
</div>
<div class="form-row">
<div class="form-group">
<label class="form-label">Commission (&#8377;)</label>
<input type="number" name="commission" class="form-input" value="<%= load.commission || '' %>" placeholder="Auto-calculated" id="commission">
</div>
<div class="form-group">
<label class="form-label">Pending from Shipper (&#8377;)</label>
<input type="number" name="pending_from_shipper" class="form-input" value="<%= load.pending_from_shipper || '' %>" placeholder="Auto-calculated" id="pending_from_shipper">
</div>
</div>
<div class="form-group">
<label class="form-label">Notes</label>
<textarea name="notes" class="form-input" rows="3" placeholder="Additional notes..."><%= load.notes || '' %></textarea>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary"><%= isEdit ? 'Update Load' : 'Save Load' %></button>
<a href="/loads" class="btn btn-outline">Cancel</a>
</div>
</form>
</div>
</div>
<!-- WhatsApp Parser -->
<div class="card">
<div class="card-header"><h3 class="card-title">&#128241; WhatsApp Parser</h3></div>
<div class="card-body">
<p class="text-muted">Paste a WhatsApp message to auto-fill the form.</p>
<div class="form-group">
<textarea id="whatsappInput" class="form-input" rows="4" placeholder='e.g. "Agarwal Bangalore TN39DV8142 loaded 19000 freight driver advance 15900"'></textarea>
</div>
<button type="button" class="btn btn-secondary" onclick="parseWhatsApp()">Parse Message</button>
<div id="parseResult" class="mt-3" style="display:none;">
<div class="parse-result">
<h4>Parsed Fields <span id="parseConfidence" class="badge"></span></h4>
<div id="parseFields"></div>
<button type="button" class="btn btn-primary mt-2" onclick="applyParsed()">Apply to Form</button>
</div>
</div>
</div>
</div>
</div>
<% if (isEdit) { %>
<div class="mt-4">
<form method="POST" action="/loads/<%= encodeURIComponent(load.id) %>/delete" onsubmit="return confirm('Delete this load?')">
<input type="hidden" name="_csrf" value="<%= _csrf %>">
<button type="submit" class="btn btn-danger">Delete Load</button>
</form>
</div>
<% } %>
<script>
let parsedData = null;
async function parseWhatsApp() {
const msg = document.getElementById('whatsappInput').value;
if (!msg.trim()) return;
const res = await fetch('/api/parse-whatsapp', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message: msg })
});
parsedData = await res.json();
const resultDiv = document.getElementById('parseResult');
const fieldsDiv = document.getElementById('parseFields');
const confidenceSpan = document.getElementById('parseConfidence');
resultDiv.style.display = 'block';
confidenceSpan.textContent = parsedData.confidence + ' confidence';
confidenceSpan.className = 'badge badge-' + (parsedData.confidence === 'high' ? 'success' : parsedData.confidence === 'medium' ? 'warning' : 'gray');
const fieldLabels = {
shipper: 'Shipper', vehicle: 'Vehicle', from_city: 'From', to_city: 'To',
via: 'Via', status: 'Status', freight_charged: 'Freight', advance_received: 'Advance',
paid_to_driver: 'Paid to Driver', commission: 'Commission', driver_freight: 'Driver Freight',
pending_from_shipper: 'Pending (Shipper)', pending_to_driver: 'Pending (Driver)'
};
let html = '<div class="parse-fields">';
for (const [key, value] of Object.entries(parsedData)) {
if (key === 'confidence' || key === 'parsed_fields' || key === 'notes' || value === null || value === undefined) continue;
html += '<div class="parse-field"><span class="parse-key">' + (fieldLabels[key] || key) + ':</span> <span class="parse-val">' + value + '</span></div>';
}
html += '</div>';
fieldsDiv.innerHTML = html;
}
function applyParsed() {
if (!parsedData) return;
const map = {
shipper_id: parsedData.shipper,
vehicle_id: parsedData.vehicle,
from_city: parsedData.from_city,
to_city: parsedData.to_city,
via: parsedData.via,
status: parsedData.status,
freight_charged: parsedData.freight_charged,
advance_received: parsedData.advance_received,
paid_to_driver: parsedData.paid_to_driver,
commission: parsedData.commission,
driver_freight: parsedData.driver_freight,
pending_from_shipper: parsedData.pending_from_shipper,
pending_to_driver: parsedData.pending_to_driver,
};
for (const [field, value] of Object.entries(map)) {
if (value === null || value === undefined) continue;
const el = document.querySelector('[name="' + field + '"]');
if (el) el.value = value;
}
}
</script>
<%- include('../../partials/footer', { extraJs: [] }) %>