← back to AbramsOS

views/neighborhood.ejs

78 lines

<%- include('partials/header', { title: 'Neighborhood Watch' }) %>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />

<section class="page-head">
  <div>
    <h1>🛡 Neighborhood Watch</h1>
    <p class="subtle">Safety around a location — your Ring cameras, Nextdoor, Citizen, crime maps &amp; registries within a chosen radius.</p>
  </div>
</section>

<section class="glass" style="padding:1rem 1.25rem;margin-bottom:1rem">
  <form id="nbForm" style="display:flex;gap:.6rem;flex-wrap:wrap;align-items:end">
    <% if (props.length) { %>
      <label>Saved property
        <select id="assetPick">
          <% props.forEach(p => { %><option value="<%= p.id %>" <%= assetId===p.id?'selected':'' %>><%= p.name %></option><% }) %>
          <option value="">— custom —</option>
        </select>
      </label>
    <% } %>
    <label class="grow" style="min-width:240px">Address
      <input id="addr" name="address" value="<%= address || '' %>" placeholder="123 Main St, City, ST" style="width:100%">
    </label>
    <label>Radius: <span id="radLbl"><%= radiusMi %></span> mi
      <input id="radius" type="range" min="0.5" max="25" step="0.5" value="<%= radiusMi %>">
    </label>
    <button type="submit" class="btn primary">Update</button>
  </form>
  <% if (address && !loc) { %><p class="subtle" style="margin:.5rem 0 0">Couldn't pinpoint that address on the map — the links below still work by address.</p><% } %>
</section>

<% if (!address) { %>
  <section class="empty glass"><p>Enter an address above, or add a property in <a href="/assets">Assets</a> to watch your home's neighborhood.</p></section>
<% } %>

<% if (loc) { %>
  <div id="map" style="height:340px;border-radius:12px;margin-bottom:1rem"></div>
<% } %>

<section id="linkArea">
  <% linkGroups.forEach(g => { %>
    <section class="page-head" style="margin:.5rem 0 .25rem"><div><h2 style="font-size:1.1rem;margin:0"><%= g.title %></h2></div></section>
    <section class="purchase-grid" style="grid-template-columns: repeat(auto-fill, minmax(280px, 1fr))">
      <% g.items.forEach(it => { %>
        <a class="purchase glass" href="<%= it.url %>" target="_blank" rel="noopener noreferrer" style="text-decoration:none;display:block">
          <header><h3 style="margin:0"><%= it.name %> ↗</h3></header>
          <% if (it.note) { %><p class="subtle" style="margin:.35rem 0 0"><%= it.note %></p><% } %>
        </a>
      <% }) %>
    </section>
  <% }) %>
</section>

<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script>
  const LOC = <%- JSON.stringify(loc || null) %>;
  const RADIUS = <%= radiusMi %>;
  if (LOC && window.L) {
    const map = L.map('map').setView([LOC.lat, LOC.lon], 14);
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 19, attribution: '© OpenStreetMap' }).addTo(map);
    L.marker([LOC.lat, LOC.lon]).addTo(map);
    L.circle([LOC.lat, LOC.lon], { radius: RADIUS * 1609.34, color: '#539bf5', fillColor: '#539bf5', fillOpacity: 0.12 }).addTo(map);
    setTimeout(() => map.invalidateSize(), 200);
  }
  // radius label + submit-as-querystring (server geocodes + rebuilds links)
  const rad = document.getElementById('radius'), radLbl = document.getElementById('radLbl');
  rad?.addEventListener('input', () => radLbl.textContent = rad.value);
  const pick = document.getElementById('assetPick');
  pick?.addEventListener('change', () => { if (pick.value) { location.href = '/neighborhood?asset=' + pick.value + '&radius=' + rad.value; } });
  document.getElementById('nbForm')?.addEventListener('submit', (e) => {
    e.preventDefault();
    const a = document.getElementById('addr').value.trim();
    location.href = '/neighborhood?address=' + encodeURIComponent(a) + '&radius=' + rad.value;
  });
</script>

<%- include('partials/footer', {}) %>