← back to AbramsOS

views/claims.ejs

222 lines

<%- include('partials/header', { title: 'Claims' }) %>

<section class="page-head">
  <h1>Claims</h1>
  <p class="subtle" style="margin:0;color:var(--text-dim);font-size:13px">Drafts only. Nothing leaves AbramsOS without your explicit approval per action.</p>
</section>

<%
  var household = (typeof household !== 'undefined' && household) ? household : [];
  var claimitUrl = 'https://claimit.ca.gov/app/claim-search';
%>
<section class="glass" style="padding:16px 18px;margin-bottom:20px;display:flex;flex-direction:column;gap:12px">
  <header style="display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap">
    <span class="name" style="display:flex;align-items:center;gap:10px">
      <span class="icon">🐻</span>
      <strong>California Unclaimed Property</strong>
    </span>
    <a class="button" href="<%= claimitUrl %>" target="_blank" rel="noopener noreferrer">Search claimit.ca.gov ↗</a>
  </header>
  <p class="desc" style="margin:0;color:var(--text-dim);font-size:13px">
    Free official search from the California State Controller for money owed to you —
    forgotten bank accounts, refunds, uncashed checks, insurance, deposits. Search each
    household name (and prior addresses / maiden names). Filing a claim is always free.
  </p>
  <% if (household.length) { %>
    <div style="display:flex;flex-direction:column;gap:6px">
      <span class="subtle" style="font-size:11px;color:var(--text-dim);text-transform:uppercase;letter-spacing:.05em">Names to search</span>
      <div style="display:flex;flex-wrap:wrap;gap:8px">
        <% household.forEach(function (name) { %>
          <button type="button" class="chip" data-copy="<%= name %>"
            style="cursor:pointer;border:1px solid var(--border,#3a3a3a);background:transparent;color:inherit;border-radius:999px;padding:5px 12px;font-size:12px"
            title="Copy name, then paste into claimit.ca.gov">
            <%= name %>
          </button>
        <% }); %>
      </div>
      <span class="subtle" style="font-size:11px;color:var(--text-dim)">Tap a name to copy it, then paste into the search on claimit.ca.gov (it opens in a new tab).</span>
    </div>
  <% } else { %>
    <span class="subtle" style="font-size:12px;color:var(--text-dim)">Tip: add people in <a href="/household">Household</a> and their names will appear here as one-tap searches.</span>
  <% } %>
</section>

<%
  var properties = (typeof properties !== 'undefined' && properties) ? properties : [];
  var ucpTotals = (typeof ucpTotals !== 'undefined' && ucpTotals) ? ucpTotals : { count: 0, staged: 0, filed: 0, paid: 0, found: 0, totalCents: 0, totalDisplay: '$0.00' };
  var statusOptions = ['found', 'staged', 'filed', 'paid', 'not_mine'];
%>
<% if (properties.length) { %>
  <section class="glass" style="padding:16px 18px;margin-bottom:20px;display:flex;flex-direction:column;gap:12px">
    <header style="display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap">
      <span class="name" style="display:flex;align-items:center;gap:10px">
        <span class="icon">💰</span>
        <strong>Tracked Properties</strong>
      </span>
      <span class="subtle" style="font-size:12px;color:var(--text-dim);display:flex;align-items:center;gap:10px;flex-wrap:wrap">
        <strong style="color:inherit"><%= ucpTotals.count %></strong> propert<%= ucpTotals.count === 1 ? 'y' : 'ies' %>
        · <strong style="color:#7dd88a"><%= ucpTotals.totalDisplay %></strong> total
        <span style="opacity:.7">·</span>
        <span title="staged">staged <strong><%= ucpTotals.staged %></strong></span>
        <span style="opacity:.7">·</span>
        <span title="filed">filed <strong><%= ucpTotals.filed %></strong></span>
        <span style="opacity:.7">·</span>
        <span title="paid">paid <strong><%= ucpTotals.paid %></strong></span>
      </span>
    </header>
    <div style="overflow-x:auto">
      <table style="width:100%;border-collapse:collapse;font-size:12px">
        <thead>
          <tr style="text-align:left;color:var(--text-dim);text-transform:uppercase;letter-spacing:.05em;font-size:11px">
            <th style="padding:8px 10px;border-bottom:1px solid var(--border,#3a3a3a)">Amount</th>
            <th style="padding:8px 10px;border-bottom:1px solid var(--border,#3a3a3a)">Holder</th>
            <th style="padding:8px 10px;border-bottom:1px solid var(--border,#3a3a3a)">Address</th>
            <th style="padding:8px 10px;border-bottom:1px solid var(--border,#3a3a3a)">Type</th>
            <th style="padding:8px 10px;border-bottom:1px solid var(--border,#3a3a3a)">Property ID</th>
            <th style="padding:8px 10px;border-bottom:1px solid var(--border,#3a3a3a)">Status</th>
            <th style="padding:8px 10px;border-bottom:1px solid var(--border,#3a3a3a)">Found</th>
          </tr>
        </thead>
        <tbody>
          <% properties.forEach(function (p) {
               var st = p.status || 'found';
               var stColor = st === 'paid' ? '#7dd88a' : st === 'staged' ? '#e0b24a' : st === 'not_mine' ? 'var(--text-dim,#8a8a8a)' : 'inherit';
               var addrParts = [];
               if (p.address) addrParts.push(p.address);
               var cityLine = [p.city, [p.state, p.zip].filter(Boolean).join(' ')].filter(Boolean).join(', ');
               if (cityLine) addrParts.push(cityLine);
               var foundIso = p.found_at ? String(p.found_at) : '';
               var foundLabel = '';
               if (p.found_at) {
                 try { foundLabel = new Date(p.found_at).toLocaleString(undefined, { year:'numeric', month:'short', day:'numeric', hour:'numeric', minute:'2-digit' }); }
                 catch (e) { foundLabel = foundIso; }
               }
          %>
            <tr style="border-bottom:1px solid var(--border,#2a2a2a)">
              <td style="padding:8px 10px;white-space:nowrap">
                <a href="<%= claimitUrl %>" target="_blank" rel="noopener noreferrer" style="color:inherit;text-decoration:none;font-weight:600" title="Search this on claimit.ca.gov">
                  <%= p.amount_display || (p.amount_cents != null ? ('$' + (p.amount_cents / 100).toFixed(2)) : '—') %> ↗
                </a>
              </td>
              <td style="padding:8px 10px">
                <span title="<%= p.owner_name || '' %>"><%= p.holder_name || '—' %></span>
                <% if (p.owner_name) { %><div class="subtle" style="font-size:11px;color:var(--text-dim)"><%= p.owner_name %><% if (p.co_owner) { %> · <%= p.co_owner %><% } %></div><% } %>
              </td>
              <td style="padding:8px 10px;color:var(--text-dim)">
                <% if (addrParts.length) { %><%= addrParts.join(' · ') %><% } else { %>—<% } %>
              </td>
              <td style="padding:8px 10px"><%= p.property_type || '—' %></td>
              <td style="padding:8px 10px;white-space:nowrap">
                <a href="<%= claimitUrl %>" target="_blank" rel="noopener noreferrer" style="color:inherit;text-decoration:none" title="Search Property ID on claimit.ca.gov">
                  <%= p.property_id || '—' %> ↗
                </a>
              </td>
              <td style="padding:8px 10px;white-space:nowrap">
                <select class="ucp-status" data-id="<%= p.id %>" style="background:transparent;color:<%= stColor %>;border:1px solid var(--border,#3a3a3a);border-radius:6px;padding:4px 6px;font-size:12px">
                  <% statusOptions.forEach(function (opt) { %>
                    <option value="<%= opt %>"<%= st === opt ? ' selected' : '' %>><%= opt %></option>
                  <% }); %>
                </select>
                <span class="ucp-saved" style="display:none;font-size:11px;color:#7dd88a;margin-left:6px">saved ✓</span>
              </td>
              <td style="padding:8px 10px;white-space:nowrap;color:var(--text-dim)">
                <% if (foundLabel) { %><span title="<%= foundIso %>">🕓 <%= foundLabel %></span><% } else { %>—<% } %>
              </td>
            </tr>
          <% }); %>
        </tbody>
      </table>
    </div>
  </section>
  <script>
    // Inline per-row status update for tracked unclaimed-property records.
    document.querySelectorAll('select.ucp-status').forEach(function (sel) {
      sel.addEventListener('change', function () {
        var id = sel.getAttribute('data-id');
        var status = sel.value;
        var saved = sel.parentNode.querySelector('.ucp-saved');
        var colors = { paid: '#7dd88a', staged: '#e0b24a', not_mine: '#8a8a8a', filed: '', found: '' };
        sel.disabled = true;
        fetch('/api/unclaimed/' + encodeURIComponent(id) + '/status', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ status: status })
        }).then(function (res) {
          if (!res.ok) throw new Error('HTTP ' + res.status);
          return res.json().catch(function () { return {}; });
        }).then(function () {
          sel.style.color = (colors[status] || 'inherit');
          if (saved) {
            saved.style.display = 'inline';
            setTimeout(function () { saved.style.display = 'none'; }, 1400);
          }
        }).catch(function () {
          if (saved) {
            saved.textContent = 'failed';
            saved.style.color = '#e07a7a';
            saved.style.display = 'inline';
            setTimeout(function () { saved.style.display = 'none'; saved.textContent = 'saved ✓'; saved.style.color = '#7dd88a'; }, 1800);
          }
        }).finally(function () {
          sel.disabled = false;
        });
      });
    });
  </script>
<% } else if (typeof properties !== 'undefined') { %>
  <p class="subtle" style="font-size:12px;color:var(--text-dim);margin:0 0 20px">No tracked properties yet.</p>
<% } %>

<% if (!claims.length) { %>
  <section class="empty glass">
    <p>No claims yet. Claims are created automatically when a reminder fires (returns window closing, warranty expiry, recall match).</p>
    <a class="button" href="/import">Go to Import</a>
  </section>
<% } else { %>
  <section class="connector-grid">
    <% claims.forEach(c => { %>
      <a class="connector-card glass" href="/claims/<%= c.id %>" style="text-decoration:none;color:inherit;display:flex;flex-direction:column;gap:10px">
        <header>
          <span class="name">
            <span class="icon"><%= c.routing[0].toUpperCase() %></span>
            <%= c.draft_subject || (c.claim_type + ' — ' + c.routing) %>
          </span>
          <span class="status <%= c.state === 'sent' ? 'connected' : c.state === 'draft' ? 'syncing' : 'not_connected' %>">
            <%= c.state %>
          </span>
        </header>
        <p class="desc">
          <strong><%= c.claim_type %></strong> →
          <%= c.routing %>
          <% if (c.due_at) { %> · due <%= new Date(c.due_at).toLocaleDateString() %><% } %>
        </p>
        <p class="subtle" style="font-size:11px;color:var(--text-dim)">created <%= new Date(c.created_at).toLocaleString() %></p>
      </a>
    <% }) %>
  </section>
<% } %>

<script>
  // Copy a household name to the clipboard so it can be pasted into claimit.ca.gov.
  document.querySelectorAll('.chip[data-copy]').forEach(function (btn) {
    btn.addEventListener('click', function () {
      var name = btn.getAttribute('data-copy') || '';
      var done = function () {
        var prev = btn.textContent;
        btn.textContent = 'Copied ✓';
        setTimeout(function () { btn.textContent = prev; }, 1200);
      };
      if (navigator.clipboard && navigator.clipboard.writeText) {
        navigator.clipboard.writeText(name).then(done).catch(done);
      } else {
        var ta = document.createElement('textarea');
        ta.value = name; document.body.appendChild(ta); ta.select();
        try { document.execCommand('copy'); } catch (e) {}
        document.body.removeChild(ta); done();
      }
    });
  });
</script>

<%- include('partials/footer') %>