725 lines
37 KiB
HTML
725 lines
37 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="es">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>AidsMonitoring — Maritime Traffic System</title>
|
||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@v9.2.4/ol.css">
|
||
<link rel="stylesheet" href="css/main.css">
|
||
</head>
|
||
<body>
|
||
|
||
<!-- ── PANTALLA DE LOGIN INICIAL ──────────────────────────────────────── -->
|
||
<div id="login-screen">
|
||
<div class="ls-box">
|
||
<div class="ls-logo">AIDS<span>MONITORING</span></div>
|
||
<div class="ls-subtitle">MARITIME TRAFFIC SYSTEM</div>
|
||
<div class="ls-version">v1.0</div>
|
||
<div class="ls-fields">
|
||
<div class="form-field">
|
||
<label class="form-label">Username</label>
|
||
<input class="form-input" id="ls-user" type="text" placeholder="username" autocomplete="username">
|
||
</div>
|
||
<div class="form-field" style="margin-top:10px">
|
||
<label class="form-label">Password</label>
|
||
<input class="form-input" id="ls-pass" type="password" placeholder="••••••••" autocomplete="current-password">
|
||
</div>
|
||
<div id="ls-error" class="modal-error hidden" style="margin-top:10px"></div>
|
||
<button class="btn-modal-primary" id="ls-submit" style="width:100%;margin-top:16px;padding:10px">LOGIN</button>
|
||
</div>
|
||
<div class="ls-footer">AidsMonitoring © 2026</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ── APP PRINCIPAL (oculta hasta login) ────────────────────────────── -->
|
||
<div id="app" class="hidden">
|
||
|
||
<header>
|
||
<div class="header-brand">
|
||
<svg class="app-icon" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||
<circle cx="18" cy="18" r="15.5" stroke="#06b6d4" stroke-width="1.5" opacity="0.45"/>
|
||
<circle cx="18" cy="18" r="10" stroke="#06b6d4" stroke-width="1" opacity="0.35"/>
|
||
<circle cx="18" cy="18" r="3" fill="#06b6d4"/>
|
||
<line x1="18" y1="2.5" x2="18" y2="9" stroke="#06b6d4" stroke-width="2" stroke-linecap="round"/>
|
||
<path d="M18 18 L18 8 L29 7 Z" fill="#06b6d4" opacity="0.22"/>
|
||
<line x1="18" y1="18" x2="29" y2="7" stroke="#06b6d4" stroke-width="1.5" stroke-linecap="round"/>
|
||
<line x1="2" y1="18" x2="34" y2="18" stroke="#06b6d4" stroke-width="0.5" opacity="0.2"/>
|
||
<line x1="18" y1="2" x2="18" y2="34" stroke="#06b6d4" stroke-width="0.5" opacity="0.2"/>
|
||
</svg>
|
||
<div>
|
||
<div class="logo">AIDS<span>MONITORING</span></div>
|
||
<div class="company-tagline" id="company-tagline">MARITIME TRAFFIC SYSTEM</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- MENÚ PRINCIPAL -->
|
||
<nav id="main-nav">
|
||
<div class="nav-item" id="nav-settings">
|
||
<span data-i18n="nav.settings">SETTINGS</span>
|
||
<div class="nav-dropdown" id="dd-settings">
|
||
<div class="dd-item" data-action="settings-datasource" data-i18n="dd.datasource">Data Source / AIS</div>
|
||
<div class="dd-item" data-action="settings-station" data-i18n="dd.station">Station & Antenna</div>
|
||
<div class="dd-item" data-action="settings-alerts" data-i18n="dd.alerts">Alert Parameters</div>
|
||
<div class="dd-item" data-action="settings-equipment">Connected Equipment</div>
|
||
<div class="dd-item dd-sep" data-action="lamps-catalog">Lamp Catalog</div>
|
||
<div class="dd-item" data-action="contacts-catalog">Contacts (port auth / owners)</div>
|
||
</div>
|
||
</div>
|
||
<div class="nav-item" id="nav-charts">
|
||
<span data-i18n="nav.charts">CHARTS</span>
|
||
<div class="nav-dropdown" id="dd-charts">
|
||
<div class="dd-item" data-action="charts-catalog" data-i18n="dd.installed">Installed Charts</div>
|
||
<div class="dd-item" data-action="charts-install" data-i18n="dd.install">Install Chart Cell (.000)</div>
|
||
<div class="dd-item dd-sep" data-action="charts-noaa" data-i18n="dd.noaa">Download NOAA Free Charts</div>
|
||
</div>
|
||
</div>
|
||
<div class="nav-item" id="nav-reports">
|
||
<span data-i18n="nav.reports">REPORTS</span>
|
||
<div class="nav-dropdown" id="dd-reports">
|
||
<div class="dd-item" data-action="recordings-list" data-i18n="dd.recordings">Vessel Recordings (VDR)</div>
|
||
<div class="dd-item" data-action="ais-history" data-i18n="dd.history">AIS Track History</div>
|
||
<div class="dd-item dd-sep" data-action="export-data" data-i18n="dd.export">Export Data (CSV)</div>
|
||
</div>
|
||
</div>
|
||
<div class="nav-item" id="nav-users">
|
||
<span data-i18n="nav.users">USERS</span>
|
||
<div class="nav-dropdown" id="dd-users">
|
||
<div class="dd-item" data-action="users-list" data-i18n="dd.manage">Manage Users</div>
|
||
<div class="dd-item" data-action="users-create" data-i18n="dd.create">Create User</div>
|
||
</div>
|
||
</div>
|
||
</nav>
|
||
|
||
<div class="header-right">
|
||
<div class="stat-block">
|
||
<span class="stat-label">UTC</span>
|
||
<span id="clock" class="stat-value mono">--:--:--</span>
|
||
</div>
|
||
<div class="stat-block">
|
||
<span class="stat-label" data-i18n="stat.vessels">VESSELS</span>
|
||
<span id="vessel-count" class="stat-value mono">0</span>
|
||
</div>
|
||
<div class="stat-block">
|
||
<span class="stat-label" data-i18n="stat.aids">AIDS</span>
|
||
<span id="aid-count" class="stat-value mono">0</span>
|
||
</div>
|
||
<div class="stat-block">
|
||
<span class="stat-label" data-i18n="stat.link">LINK</span>
|
||
<span id="ws-status" class="link-indicator offline">OFFLINE</span>
|
||
</div>
|
||
<div id="session-badge" class="session-badge"></div>
|
||
</div>
|
||
</header>
|
||
|
||
<div class="main-layout">
|
||
|
||
<!-- SECTOR 1: CARTOGRAFIA -->
|
||
<div id="map-sector">
|
||
<div id="map-toolbar">
|
||
<span class="toolbar-label" data-i18n="tb.port">PORT</span>
|
||
<div class="port-search-wrap">
|
||
<input id="port-search" class="port-search-input" type="text"
|
||
data-i18n-placeholder="tb.port.ph" placeholder="Search worldwide port..." autocomplete="off">
|
||
<div id="port-suggestions" class="port-suggestions hidden"></div>
|
||
</div>
|
||
<div class="toolbar-sep"></div>
|
||
<span class="toolbar-label" data-i18n="tb.display">DISPLAY</span>
|
||
<button class="tb-btn active" data-filter="all" data-i18n="tb.all">ALL</button>
|
||
<button class="tb-btn" data-filter="vessels" data-i18n="tb.vessels">VESSELS</button>
|
||
<button class="tb-btn" data-filter="aids" data-i18n="tb.aids">AIDS</button>
|
||
<button class="tb-btn" data-filter="alerts" data-i18n="tb.alerts">ALERTS</button>
|
||
<div class="toolbar-sep"></div>
|
||
<span class="toolbar-label" data-i18n="tb.layer">LAYER</span>
|
||
<button class="tb-btn active" id="toggle-world" data-i18n="tb.world" title="OSM world raster basemap">WORLD</button>
|
||
<button class="tb-btn active" id="toggle-seamap" data-i18n="tb.seamark" title="OpenSeaMap overlay">SEAMARK</button>
|
||
<button class="tb-btn active" id="toggle-enc" data-i18n="tb.aids" title="S-57 aids to navigation (buoys, beacons, lights)">AIDS</button>
|
||
<button class="tb-btn active" id="toggle-land" data-i18n="tb.land" title="S-57 terrain: land areas, coastline, structures">LAND</button>
|
||
<button class="tb-btn active" id="toggle-depths" data-i18n="tb.bathy" title="S-57 bathymetry: depth areas, contours, soundings">BATHY</button>
|
||
<button class="tb-btn active" id="toggle-hazards" data-i18n="tb.hazards" title="S-57 hazards: wrecks, obstructions, rocks">HAZARDS</button>
|
||
<button class="tb-btn active" id="toggle-zones" data-i18n="tb.zones" title="S-57 zones: restricted, anchorage, traffic lanes, fairways">ZONES</button>
|
||
<div class="toolbar-sep"></div>
|
||
<button class="tb-btn" id="toggle-night" data-i18n="tb.night">NIGHT</button>
|
||
<div class="toolbar-sep"></div>
|
||
<button class="tb-btn active" id="toggle-lang">EN/ES</button>
|
||
<div class="toolbar-sep"></div>
|
||
<button class="tb-btn" id="btn-sdr" title="Launch AIS-catcher (RTL-SDR receiver)">SDR</button>
|
||
</div>
|
||
<div id="map"></div>
|
||
<div id="map-coords" class="mono">LAT -- LON --</div>
|
||
</div>
|
||
|
||
<!-- SECTOR 2: COLUMNA DERECHA -->
|
||
<div id="right-column">
|
||
<div id="info-sector">
|
||
<div class="sector-header" data-i18n="sector.info">OBJECT INFO</div>
|
||
<div id="info-content">
|
||
<div class="no-selection">
|
||
<div class="no-sel-line"></div>
|
||
<span data-i18n="no.sel">SELECT OBJECT ON CHART</span>
|
||
<div class="no-sel-line"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div id="panel-divider"></div>
|
||
<div id="events-sector">
|
||
<div class="sector-header">
|
||
<span data-i18n="sector.events">EVENTS & ALERTS</span>
|
||
<span id="alert-badge" class="alert-badge hidden">0</span>
|
||
</div>
|
||
<div id="events-list"></div>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
<!-- ── BARRA DE ESTADO INFERIOR ──────────────────────────────────────── -->
|
||
<div id="status-bar">
|
||
<div class="sb-group"><span class="sb-dot grey" id="sb-dot-ais"></span><span class="sb-label" id="sb-ais">AIS: SIMULATOR</span></div>
|
||
<div class="sb-group"><span class="sb-dot grey" id="sb-dot-gps"></span><span class="sb-label" id="sb-gps">GPS: --</span></div>
|
||
<div class="sb-group"><span class="sb-dot grey" id="sb-dot-nmea"></span><span class="sb-label" id="sb-nmea">NMEA: --</span></div>
|
||
<div class="sb-group"><span class="sb-dot grey" id="sb-dot-ws"></span><span class="sb-label" id="sb-ws">WS: OFFLINE</span></div>
|
||
<div class="sb-sep"></div>
|
||
<div class="sb-user" id="sb-user"></div>
|
||
</div>
|
||
|
||
</div><!-- /app -->
|
||
|
||
<div id="tooltip" class="tooltip hidden"></div>
|
||
|
||
<!-- Panel flotante de cartas disponibles en área actual -->
|
||
<div id="chart-nearby-panel" class="chart-nearby-panel hidden">
|
||
<div class="cnp-header">
|
||
<span class="cnp-title">CHARTS IN VIEW</span>
|
||
<button class="cnp-close" onclick="window._cnpClose && _cnpClose()">×</button>
|
||
</div>
|
||
<div id="cnp-body"></div>
|
||
</div>
|
||
|
||
<!-- ── MODAL OVERLAY ──────────────────────────────────────────────────── -->
|
||
<div id="modal-overlay" class="modal-overlay hidden">
|
||
|
||
<!-- LOGIN (edición) -->
|
||
<div id="modal-login" class="modal hidden">
|
||
<div class="modal-header">
|
||
<span class="modal-title">AUTHENTICATION REQUIRED</span>
|
||
<button class="modal-close" id="btn-close-login">×</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="modal-subtitle">Admin or Superadmin credentials required.</div>
|
||
<div class="form-field" style="margin-top:16px">
|
||
<label class="form-label">Username</label>
|
||
<input class="form-input" id="login-user" type="text" placeholder="username">
|
||
</div>
|
||
<div class="form-field" style="margin-top:10px">
|
||
<label class="form-label">Password</label>
|
||
<input class="form-input" id="login-pass" type="password" placeholder="••••••••">
|
||
</div>
|
||
<div id="login-error" class="modal-error hidden"></div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button class="btn-modal-primary" id="btn-login-submit">LOGIN</button>
|
||
<button class="btn-modal-secondary" id="btn-login-cancel">CANCEL</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- EDICIÓN AYUDA -->
|
||
<div id="modal-edit" class="modal hidden">
|
||
<div class="modal-header">
|
||
<div>
|
||
<span class="modal-title">EDIT AID DATA</span>
|
||
<span id="edit-aid-name" class="modal-subtitle-inline"></span>
|
||
</div>
|
||
<button class="modal-close" id="btn-close-edit">×</button>
|
||
</div>
|
||
<div class="modal-body" id="modal-edit-body"></div>
|
||
<div class="modal-footer">
|
||
<button class="btn-modal-primary" id="btn-edit-submit">SAVE CHANGES</button>
|
||
<button class="btn-modal-secondary" id="btn-edit-cancel">CANCEL</button>
|
||
<span id="edit-save-status" class="save-status"></span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- GESTIÓN DE USUARIOS -->
|
||
<div id="modal-users" class="modal modal-wide hidden">
|
||
<div class="modal-header">
|
||
<span class="modal-title">USER MANAGEMENT</span>
|
||
<button class="modal-close" id="btn-close-users">×</button>
|
||
</div>
|
||
<div class="modal-body" id="modal-users-body"></div>
|
||
<div class="modal-footer">
|
||
<button class="btn-modal-primary" id="btn-user-new">NEW USER</button>
|
||
<button class="btn-modal-secondary" id="btn-close-users2">CLOSE</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- CARTAS NÁUTICAS -->
|
||
<div id="modal-charts" class="modal hidden" style="max-width:680px">
|
||
<div class="modal-header">
|
||
<span class="modal-title">NAUTICAL CHARTS — S-57 ENC</span>
|
||
<button class="modal-close" id="btn-close-charts">×</button>
|
||
</div>
|
||
<div class="modal-body" id="modal-charts-body">
|
||
|
||
<!-- TABS -->
|
||
<div class="stab-bar" style="margin-bottom:14px">
|
||
<button class="stab active" data-ctab="tab-catalog">NOAA CATALOG</button>
|
||
<button class="stab" data-ctab="tab-installed">INSTALLED</button>
|
||
<button class="stab" data-ctab="tab-upload">UPLOAD FILE</button>
|
||
<button class="stab" data-ctab="tab-buy">BUY CHARTS</button>
|
||
</div>
|
||
|
||
<!-- TAB: NOAA CATALOG -->
|
||
<div id="tab-catalog" class="ctab-panel">
|
||
<div style="font-size:0.7rem;color:var(--text-muted);margin-bottom:10px">
|
||
Click DOWNLOAD to fetch directly from NOAA servers and install. No manual download needed.
|
||
</div>
|
||
<table class="chart-table" id="noaa-catalog-table">
|
||
<thead><tr><th>Cell</th><th>Description</th><th>Status</th><th></th></tr></thead>
|
||
<tbody id="noaa-catalog-body"></tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<!-- TAB: INSTALLED -->
|
||
<div id="tab-installed" class="ctab-panel hidden">
|
||
<div style="display:flex;justify-content:flex-end;margin-bottom:8px">
|
||
<button class="chart-row-btn" id="btn-rebuild-all"
|
||
onclick="rebuildAllCells()"
|
||
title="Re-parse all installed charts and reload map layers">
|
||
↺ REBUILD ALL
|
||
</button>
|
||
</div>
|
||
<table class="chart-table" id="installed-table">
|
||
<thead><tr><th>Cell</th><th>Features</th><th>IALA</th><th style="min-width:140px"></th></tr></thead>
|
||
<tbody id="installed-body"></tbody>
|
||
</table>
|
||
<div id="installed-empty" style="display:none;color:var(--text-muted);font-size:0.75rem;padding:16px 0">
|
||
No charts installed yet.
|
||
</div>
|
||
</div>
|
||
|
||
<!-- TAB: UPLOAD -->
|
||
<div id="tab-upload" class="ctab-panel hidden">
|
||
<div class="form-field">
|
||
<label class="form-label">Chart cell (.000) or ZIP archive *</label>
|
||
<input class="form-input" id="chart-file" type="file" accept=".000,.zip" style="padding:4px">
|
||
</div>
|
||
<div id="chart-upload-status" style="margin-top:10px;font-size:0.75rem"></div>
|
||
<button class="btn-modal-primary" id="btn-chart-upload" style="margin-top:12px">INSTALL</button>
|
||
</div>
|
||
|
||
<!-- TAB: BUY -->
|
||
<div id="tab-buy" class="ctab-panel hidden">
|
||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:10px">
|
||
<div class="chart-source-card" onclick="window.open('https://www.admiralty.co.uk/digital-services/digital-charts/admiralty-vector-chart-service','_blank')">
|
||
<div class="chart-card-title">UKHO / AVCS</div>
|
||
<div class="chart-card-sub">Licensed · Worldwide</div>
|
||
<div class="chart-card-desc">UK Hydrographic Office. Global coverage, encrypted S-63. Requires permit file.</div>
|
||
<div class="chart-card-btn">BUY / INFO</div>
|
||
</div>
|
||
<div class="chart-source-card" onclick="window.open('https://www.primar.org','_blank')">
|
||
<div class="chart-card-title">PRIMAR</div>
|
||
<div class="chart-card-sub">Licensed · Worldwide</div>
|
||
<div class="chart-card-desc">Norwegian Hydrographic Service distribution. Buy by cell or subscription.</div>
|
||
<div class="chart-card-btn">BUY / INFO</div>
|
||
</div>
|
||
<div class="chart-source-card" onclick="window.open('https://www.dimar.mil.co','_blank')">
|
||
<div class="chart-card-title">DIMAR</div>
|
||
<div class="chart-card-sub">Colombia · Oficial</div>
|
||
<div class="chart-card-desc">Dirección General Marítima — cartas de Colombia. Contactar para licencias ENC.</div>
|
||
<div class="chart-card-btn">INFO / CONTACTO</div>
|
||
</div>
|
||
<div class="chart-source-card" onclick="window.open('https://www.ic-enc.org','_blank')">
|
||
<div class="chart-card-title">IC-ENC</div>
|
||
<div class="chart-card-sub">Licensed · International</div>
|
||
<div class="chart-card-desc">International Centre for ENC. Worldwide coverage, S-63 encrypted.</div>
|
||
<div class="chart-card-btn">BUY / INFO</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="chart-install-status" style="margin-top:10px;font-size:0.75rem"></div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button class="btn-modal-secondary" id="btn-rebuild-cache" onclick="rebuildAllCells()" title="Re-parse all installed charts and reload map">↺ REBUILD ALL SYMBOLS</button>
|
||
<button class="btn-modal-secondary" id="btn-close-charts2">CLOSE</button>
|
||
<span id="chart-save-status" class="save-status"></span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- CREAR / EDITAR USUARIO -->
|
||
<div id="modal-user-form" class="modal hidden">
|
||
<div class="modal-header">
|
||
<span class="modal-title" id="user-form-title">CREATE USER</span>
|
||
<button class="modal-close" id="btn-close-user-form">×</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="form-field">
|
||
<label class="form-label">Username *</label>
|
||
<input class="form-input" id="uf-username" type="text" placeholder="login name">
|
||
</div>
|
||
<div class="form-field" style="margin-top:10px">
|
||
<label class="form-label">Full name *</label>
|
||
<input class="form-input" id="uf-nombre" type="text" placeholder="Full name">
|
||
</div>
|
||
<div class="form-field" style="margin-top:10px">
|
||
<label class="form-label">Email</label>
|
||
<input class="form-input" id="uf-email" type="email" placeholder="email@company.com">
|
||
</div>
|
||
<div class="form-field" style="margin-top:10px">
|
||
<label class="form-label">Password *</label>
|
||
<input class="form-input" id="uf-password" type="password" placeholder="••••••••">
|
||
</div>
|
||
<div class="form-field" style="margin-top:10px">
|
||
<label class="form-label">Role *</label>
|
||
<select class="form-input-select" id="uf-role">
|
||
<option value="USER">USER — Read only</option>
|
||
<option value="ADMIN">ADMIN — Can edit aids</option>
|
||
<option value="SUPERADMIN">SUPERADMIN — Full access</option>
|
||
</select>
|
||
</div>
|
||
<div id="uf-error" class="modal-error hidden" style="margin-top:10px"></div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button class="btn-modal-primary" id="btn-uf-save">CREATE USER</button>
|
||
<button class="btn-modal-secondary" id="btn-uf-cancel">CANCEL</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- SETTINGS -->
|
||
<div id="modal-settings" class="modal modal-wide hidden">
|
||
<div class="modal-header">
|
||
<span class="modal-title">SYSTEM SETTINGS</span>
|
||
<button class="modal-close" id="btn-close-settings">×</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="settings-tabs">
|
||
<button class="stab active" data-tab="ais">AIS SOURCE</button>
|
||
<button class="stab" data-tab="station">STATION</button>
|
||
<button class="stab" data-tab="alerts">ALERT THRESHOLDS</button>
|
||
<button class="stab" data-tab="equipment">CONNECTED EQUIPMENT</button>
|
||
<button class="stab" data-tab="smtp">EMAIL (SMTP)</button>
|
||
</div>
|
||
<!-- AIS Source -->
|
||
<div class="stab-panel" id="stab-ais">
|
||
<div class="form-field">
|
||
<label class="form-label">AIS Input Source</label>
|
||
<select class="form-input-select" id="set-ais-source">
|
||
<option value="SIMULATOR">Simulator (testing / demo)</option>
|
||
<option value="SDR">RTL-SDR — AIS-catcher (auto-launch)</option>
|
||
<option value="SERIAL">Serial Port — AIS transponder / NMEA mux</option>
|
||
<option value="NETWORK">Network TCP/UDP (aggregator / kplex)</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-field" style="margin-top:12px" id="field-serial-port">
|
||
<label class="form-label">Serial Port (COM / tty)</label>
|
||
<input class="form-input" id="set-serial-port" placeholder="COM3 or /dev/ttyUSB0">
|
||
</div>
|
||
<div class="form-field" style="margin-top:10px" id="field-baud">
|
||
<label class="form-label">Baud Rate</label>
|
||
<select class="form-input-select" id="set-baud">
|
||
<option value="38400">38400 — AIS standard (NMEA 0183)</option>
|
||
<option value="115200">115200 — High-speed USB</option>
|
||
<option value="4800">4800 — Legacy NMEA</option>
|
||
<option value="9600">9600</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-field" style="margin-top:10px hidden" id="field-net-addr">
|
||
<label class="form-label">Network Address : Port</label>
|
||
<input class="form-input" id="set-net-addr" placeholder="192.168.1.100:10110">
|
||
</div>
|
||
</div>
|
||
<!-- Station -->
|
||
<div class="stab-panel hidden" id="stab-station">
|
||
<div class="field-row-modal">
|
||
<div class="form-field">
|
||
<label class="form-label">Station Name</label>
|
||
<input class="form-input" id="set-station-name" placeholder="e.g. Barranquilla — Central Station">
|
||
</div>
|
||
<div class="form-field">
|
||
<label class="form-label">IALA Region (buoy colors)</label>
|
||
<select class="form-input-select" id="set-iala-region" title="IALA-A: red=port. IALA-B Americas: green=port (Red Right Returning)">
|
||
<option value="B">IALA-B — Américas / Japan / Korea (Green=Port)</option>
|
||
<option value="A">IALA-A — Europa / Africa / Asia (Red=Port)</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div class="form-field" style="margin-top:10px">
|
||
<label class="form-label">GPS Serial Port (leave blank for auto-detect)</label>
|
||
<input class="form-input" id="set-gps-port" placeholder="COM8 or /dev/ttyUSB0 — blank = auto-scan">
|
||
</div>
|
||
<div class="field-row-modal" style="margin-top:10px">
|
||
<div class="form-field">
|
||
<label class="form-label">Antenna Latitude</label>
|
||
<input class="form-input" id="set-ant-lat" type="number" step="0.000001" placeholder="10.987800">
|
||
</div>
|
||
<div class="form-field">
|
||
<label class="form-label">Antenna Longitude</label>
|
||
<input class="form-input" id="set-ant-lon" type="number" step="0.000001" placeholder="-74.804000">
|
||
</div>
|
||
</div>
|
||
<div class="form-field" style="margin-top:10px">
|
||
<label class="form-label">Antenna Height (m ASL)</label>
|
||
<input class="form-input" id="set-ant-height" type="number" placeholder="25">
|
||
</div>
|
||
<div class="form-field" style="margin-top:10px">
|
||
<label class="form-label">Notes</label>
|
||
<textarea class="form-textarea" id="set-station-notes" style="height:56px" placeholder="Description or notes about this station"></textarea>
|
||
</div>
|
||
</div>
|
||
<!-- Connected Equipment -->
|
||
<div class="stab-panel hidden" id="stab-equipment">
|
||
<div style="display:flex;align-items:center;gap:12px;margin-bottom:14px">
|
||
<button class="btn-modal-primary" id="btn-scan-ports" style="padding:6px 18px">SCAN PORTS</button>
|
||
<span id="scan-status" style="font-size:0.72rem;color:var(--text-muted)">Click SCAN PORTS to detect connected equipment</span>
|
||
</div>
|
||
<div id="equipment-list"></div>
|
||
</div>
|
||
<!-- Alerts -->
|
||
<div class="stab-panel hidden" id="stab-alerts">
|
||
<div class="modal-section-label">AID DISPLACEMENT</div>
|
||
<div class="field-row-modal">
|
||
<div class="form-field">
|
||
<label class="form-label">Warning threshold (m)</label>
|
||
<input class="form-input" id="set-disp-warn" type="number" value="10">
|
||
</div>
|
||
<div class="form-field">
|
||
<label class="form-label">Alarm threshold (m)</label>
|
||
<input class="form-input" id="set-disp-alarm" type="number" value="15">
|
||
</div>
|
||
</div>
|
||
<div class="modal-section-label" style="margin-top:14px">VESSEL PROXIMITY</div>
|
||
<div class="field-row-modal">
|
||
<div class="form-field">
|
||
<label class="form-label">Warning distance (m)</label>
|
||
<input class="form-input" id="set-prox-warn" type="number" value="300">
|
||
</div>
|
||
<div class="form-field">
|
||
<label class="form-label">Auto-record trigger (m)</label>
|
||
<input class="form-input" id="set-rec-trigger" type="number" value="200">
|
||
</div>
|
||
</div>
|
||
<div class="modal-section-label" style="margin-top:14px">BATTERY (ATON)</div>
|
||
<div class="field-row-modal">
|
||
<div class="form-field">
|
||
<label class="form-label">Low battery warning (V)</label>
|
||
<input class="form-input" id="set-batt-warn" type="number" step="0.1" value="11.5">
|
||
</div>
|
||
<div class="form-field">
|
||
<label class="form-label">Critical battery alarm (V)</label>
|
||
<input class="form-input" id="set-batt-alarm" type="number" step="0.1" value="10.8">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- SMTP / Email -->
|
||
<div class="stab-panel hidden" id="stab-smtp">
|
||
<div style="font-size:0.72rem;color:var(--text-muted);margin-bottom:10px">
|
||
Configure your organisation's email account so REPORT emails are sent from
|
||
the system (no popup, no operator email client).
|
||
For Gmail use <code>smtp.gmail.com</code> port <code>587</code> with an
|
||
<a href="https://myaccount.google.com/apppasswords" target="_blank" style="color:var(--accent)">app password</a>.
|
||
</div>
|
||
<div class="field-row-modal">
|
||
<div class="form-field">
|
||
<label class="form-label">SMTP Host</label>
|
||
<input class="form-input" id="set-smtp-host" placeholder="smtp.gmail.com">
|
||
</div>
|
||
<div class="form-field">
|
||
<label class="form-label">Port</label>
|
||
<input class="form-input" id="set-smtp-port" type="number" value="587">
|
||
</div>
|
||
</div>
|
||
<div class="field-row-modal" style="margin-top:10px">
|
||
<div class="form-field">
|
||
<label class="form-label">SMTP Username</label>
|
||
<input class="form-input" id="set-smtp-user" placeholder="user@yourdomain.com">
|
||
</div>
|
||
<div class="form-field">
|
||
<label class="form-label">SMTP Password (app password)</label>
|
||
<input class="form-input" id="set-smtp-password" type="password" placeholder="••••••••">
|
||
</div>
|
||
</div>
|
||
<div class="field-row-modal" style="margin-top:10px">
|
||
<div class="form-field">
|
||
<label class="form-label">From address (sender)</label>
|
||
<input class="form-input" id="set-smtp-from" placeholder="monitoreo@yourdomain.com">
|
||
</div>
|
||
<div class="form-field">
|
||
<label class="form-label">From name (display)</label>
|
||
<input class="form-input" id="set-smtp-from-name" placeholder="AidsMonitoring">
|
||
</div>
|
||
</div>
|
||
<div class="form-field" style="margin-top:10px">
|
||
<label class="form-label" style="display:flex;align-items:center;gap:6px">
|
||
<input type="checkbox" id="set-smtp-tls" checked> Use STARTTLS (port 587). Disable for SSL on port 465.
|
||
</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button class="btn-modal-primary" id="btn-settings-save">SAVE SETTINGS</button>
|
||
<button class="btn-modal-secondary" id="btn-close-settings2">CLOSE</button>
|
||
<span id="settings-status" class="save-status"></span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- RECORDINGS / VDR -->
|
||
<div id="modal-recordings" class="modal modal-wide hidden">
|
||
<div class="modal-header">
|
||
<span class="modal-title">VESSEL RECORDINGS — VDR</span>
|
||
<button class="modal-close" id="btn-close-recordings">×</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div style="display:flex;gap:10px;margin-bottom:14px;align-items:flex-end">
|
||
<div class="form-field" style="flex:1">
|
||
<label class="form-label">MMSI or Vessel Name</label>
|
||
<input class="form-input" id="rec-filter-mmsi" placeholder="All vessels">
|
||
</div>
|
||
<div class="form-field">
|
||
<label class="form-label">Date From</label>
|
||
<input class="form-input" id="rec-filter-from" type="date">
|
||
</div>
|
||
<div class="form-field">
|
||
<label class="form-label">Date To</label>
|
||
<input class="form-input" id="rec-filter-to" type="date">
|
||
</div>
|
||
<button class="btn-modal-primary" id="btn-rec-search" style="padding:5px 14px;margin-bottom:0">SEARCH</button>
|
||
</div>
|
||
<div id="modal-recordings-body">
|
||
<div style="color:var(--text-muted);font-size:0.75rem;padding:20px 0;text-align:center">
|
||
Select filters above and press SEARCH to load recordings.
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button class="btn-modal-secondary" id="btn-close-recordings2">CLOSE</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- REPORT ALERT -->
|
||
<div id="modal-report" class="modal modal-wide hidden">
|
||
<div class="modal-header">
|
||
<span class="modal-title">REPORT ALERT — Notify port authority & aid owner</span>
|
||
<button class="modal-close" id="btn-close-report">×</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div id="report-alert-summary" style="background:#1a2a3a;border-left:3px solid var(--yellow);padding:8px 12px;margin-bottom:12px;font-size:0.78rem"></div>
|
||
<div class="form-field" style="margin-bottom:10px">
|
||
<label class="form-label">Message (editable)</label>
|
||
<textarea id="report-message" class="form-textarea" style="height:90px;width:100%"></textarea>
|
||
</div>
|
||
<div id="report-recipients">
|
||
<div style="color:var(--text-muted);font-size:0.78rem">Loading recipients…</div>
|
||
</div>
|
||
<div id="report-status" class="save-status" style="margin-top:10px"></div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button class="btn-modal-secondary" id="btn-close-report2">CLOSE</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- CONTACTS CATALOG -->
|
||
<div id="modal-contacts" class="modal modal-wide hidden">
|
||
<div class="modal-header">
|
||
<span class="modal-title">CONTACTS — Port authorities & aid owners</span>
|
||
<button class="modal-close" id="btn-close-contacts">×</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div style="font-size:0.72rem;color:var(--text-muted);margin-bottom:10px">
|
||
Each row is a <strong>contact person</strong> (or office) that gets notified.<br>
|
||
The <strong>Organization</strong> column holds the port name (for PORT_AUTHORITY) or
|
||
the company name (for OWNER) — it must match exactly the
|
||
<code>puerto_responsable</code> / <code>empresa_responsable</code> field of the aid
|
||
so REPORT can route alerts to the right people.
|
||
</div>
|
||
<table class="chart-table" id="contacts-table">
|
||
<thead><tr>
|
||
<th>Role</th>
|
||
<th>Contact Person / Office</th>
|
||
<th>Organization (port or company)</th>
|
||
<th>Email</th><th>Phone</th><th>WhatsApp</th><th>Pref.</th><th></th>
|
||
</tr></thead>
|
||
<tbody id="contacts-body"></tbody>
|
||
<tfoot>
|
||
<tr id="contacts-newrow">
|
||
<td>
|
||
<select class="form-input-select" id="ct-new-role">
|
||
<option value="PORT_AUTHORITY">PORT AUTH</option>
|
||
<option value="OWNER">OWNER</option>
|
||
</select>
|
||
</td>
|
||
<td><input class="form-input" id="ct-new-name" placeholder="e.g. Capt. J. Pérez / Maritime Office"></td>
|
||
<td><input class="form-input" id="ct-new-match" placeholder="Port or company name"></td>
|
||
<td><input class="form-input" id="ct-new-email" placeholder="email@..."></td>
|
||
<td><input class="form-input" id="ct-new-phone" placeholder="+57..."></td>
|
||
<td><input class="form-input" id="ct-new-whatsapp" placeholder="+57..."></td>
|
||
<td>
|
||
<select class="form-input-select" id="ct-new-pref">
|
||
<option value="EMAIL">EMAIL</option>
|
||
<option value="WHATSAPP">WHATSAPP</option>
|
||
<option value="SMS">SMS</option>
|
||
</select>
|
||
</td>
|
||
<td><button class="chart-row-btn" id="btn-contact-add">ADD</button></td>
|
||
</tr>
|
||
</tfoot>
|
||
</table>
|
||
<div id="contacts-status" class="save-status" style="margin-top:8px"></div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button class="btn-modal-secondary" id="btn-close-contacts2">CLOSE</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- LAMP CATALOG -->
|
||
<div id="modal-lamps" class="modal modal-wide hidden">
|
||
<div class="modal-header">
|
||
<span class="modal-title">LAMP CATALOG — Battery thresholds derived from V min/max</span>
|
||
<button class="modal-close" id="btn-close-lamps">×</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div style="font-size:0.72rem;color:var(--text-muted);margin-bottom:10px">
|
||
Each row defines a lamp model. <strong>V min</strong> = nominal discharged battery voltage (e.g. 12.2 V).
|
||
<strong>V max</strong> = nominal fully-charged voltage (e.g. 12.8 V). Aids assigned to this lamp get
|
||
their battery WARN / ALARM thresholds computed automatically:<br>
|
||
<code style="color:var(--accent)">warn = vmin + (vmax − vmin) × 0.20</code> ·
|
||
<code style="color:var(--accent)">alarm = vmin + (vmax − vmin) × 0.10</code>
|
||
</div>
|
||
<table class="chart-table" id="lamps-table">
|
||
<thead><tr>
|
||
<th>Manufacturer</th><th>Model</th><th># Lamps</th>
|
||
<th title="Nominal voltage when fully discharged">V min nom.</th>
|
||
<th title="Nominal voltage when fully charged">V max nom.</th>
|
||
<th>WARN</th><th>ALARM</th>
|
||
<th>Notes</th><th></th>
|
||
</tr></thead>
|
||
<tbody id="lamps-body"></tbody>
|
||
<tfoot>
|
||
<tr id="lamps-newrow">
|
||
<td><input class="form-input" id="lp-new-mfr" placeholder="e.g. Tideland"></td>
|
||
<td><input class="form-input" id="lp-new-model" placeholder="e.g. MaxLumen 200"></td>
|
||
<td><input class="form-input" id="lp-new-count" type="number" value="1" style="width:60px"></td>
|
||
<td><input class="form-input" id="lp-new-vmin" type="number" step="0.1" placeholder="12.2" style="width:70px"></td>
|
||
<td><input class="form-input" id="lp-new-vmax" type="number" step="0.1" placeholder="12.8" style="width:70px"></td>
|
||
<td colspan="2" style="font-size:0.7rem;color:var(--text-muted)" id="lp-new-preview">—</td>
|
||
<td><input class="form-input" id="lp-new-notes" placeholder="optional"></td>
|
||
<td><button class="chart-row-btn" id="btn-lamp-add">ADD</button></td>
|
||
</tr>
|
||
</tfoot>
|
||
</table>
|
||
<div id="lamps-status" class="save-status" style="margin-top:8px"></div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button class="btn-modal-secondary" id="btn-close-lamps2">CLOSE</button>
|
||
</div>
|
||
</div>
|
||
|
||
</div><!-- /modal-overlay -->
|
||
|
||
<script src="https://cdn.jsdelivr.net/npm/ol@v9.2.4/dist/ol.js"></script>
|
||
<script src="js/ports.js"></script>
|
||
<script src="js/auth.js"></script>
|
||
<script src="js/map.js"></script>
|
||
<script src="js/websocket.js"></script>
|
||
<script src="js/menu.js"></script>
|
||
</body>
|
||
</html>
|