← back to Ventura Claw Leads

views/admin/team.ejs

86 lines

<%- include('../partials/head', { title }) %>
<%- include('../partials/header') %>

<section class="long-form" style="max-width:720px">
  <p class="kicker">Team</p>
  <h1 class="display-sm">Manage who can edit <%= currentBusiness.business_name %>.</h1>
  <p class="lede">Add team members so multiple people can respond to leads. Each member gets the same dashboard.</p>

  <% if (flash.invited) { %><p class="callout" style="background:#dcfce7;border-left:3px solid #16a34a;color:#166534;padding:12px 16px;margin:16px 0;border-radius:4px">Invitation sent to <strong><%= flash.invited %></strong>. They have 7 days to accept.</p><% } %>
  <% if (flash.removed) { %><p class="callout" style="background:#dcfce7;border-left:3px solid #16a34a;color:#166534;padding:12px 16px;margin:16px 0;border-radius:4px">Team member removed.</p><% } %>
  <% if (flash.error === 'bad_email') { %><p class="callout" style="background:#fee2e2;border-left:3px solid #dc2626;padding:12px 16px;margin:16px 0;border-radius:4px">That doesn't look like a valid email address.</p><% } %>
  <% if (flash.error === 'already_member') { %><p class="callout" style="background:#fee2e2;border-left:3px solid #dc2626;padding:12px 16px;margin:16px 0;border-radius:4px">That email is already a team member.</p><% } %>
  <% if (flash.error === 'last_user') { %><p class="callout" style="background:#fee2e2;border-left:3px solid #dc2626;padding:12px 16px;margin:16px 0;border-radius:4px">Can't remove the last team member — invite someone else first.</p><% } %>
  <% if (flash.error === 'self_remove') { %><p class="callout" style="background:#fee2e2;border-left:3px solid #dc2626;padding:12px 16px;margin:16px 0;border-radius:4px">Can't remove yourself. Have another team member do it, or contact support.</p><% } %>

  <h2 style="margin-top:32px">Active members</h2>
  <table style="width:100%;border-collapse:collapse;margin:16px 0;font-size:14px">
    <thead>
      <tr style="border-bottom:1px solid var(--border);text-align:left">
        <th style="padding:10px 8px;font-size:11px;letter-spacing:0.08em;text-transform:uppercase;color:var(--fg-muted);font-weight:500">Email</th>
        <th style="padding:10px 8px;font-size:11px;letter-spacing:0.08em;text-transform:uppercase;color:var(--fg-muted);font-weight:500">Joined</th>
        <th style="padding:10px 8px;font-size:11px;letter-spacing:0.08em;text-transform:uppercase;color:var(--fg-muted);font-weight:500">Last sign-in</th>
        <th style="padding:10px 8px;font-size:11px;letter-spacing:0.08em;text-transform:uppercase;color:var(--fg-muted);font-weight:500"></th>
      </tr>
    </thead>
    <tbody>
      <% team.forEach(function(u){ %>
        <tr style="border-bottom:1px solid var(--border)">
          <td style="padding:12px 8px"><%= u.email %><% if (u.is_self) { %> <span class="muted" style="font-size:11px">(you)</span><% } %></td>
          <td style="padding:12px 8px;color:var(--fg-muted)"><%= new Date(u.created_at).toLocaleDateString('en-US',{ month:'short', day:'numeric', year:'numeric' }) %></td>
          <td style="padding:12px 8px;color:var(--fg-muted)"><%= u.last_login_at ? new Date(u.last_login_at).toLocaleDateString('en-US',{ month:'short', day:'numeric' }) : '—' %></td>
          <td style="padding:12px 8px;text-align:right">
            <% if (!u.is_self) { %>
              <form method="post" action="/admin/team/<%= u.id %>/remove" style="margin:0" onsubmit="return confirm('Remove <%= u.email %>?');">
                <input type="hidden" name="_csrf" value="<%= csrfToken %>">
                <button type="submit" class="btn btn-ghost btn-sm" style="font-size:11px;padding:4px 10px">Remove</button>
              </form>
            <% } %>
          </td>
        </tr>
      <% }); %>
    </tbody>
  </table>

  <% if (pendingInvites.length > 0) { %>
    <h2 style="margin-top:32px">Pending invitations</h2>
    <table style="width:100%;border-collapse:collapse;margin:16px 0;font-size:14px">
      <thead>
        <tr style="border-bottom:1px solid var(--border);text-align:left">
          <th style="padding:10px 8px;font-size:11px;letter-spacing:0.08em;text-transform:uppercase;color:var(--fg-muted);font-weight:500">Email</th>
          <th style="padding:10px 8px;font-size:11px;letter-spacing:0.08em;text-transform:uppercase;color:var(--fg-muted);font-weight:500">Sent</th>
          <th style="padding:10px 8px;font-size:11px;letter-spacing:0.08em;text-transform:uppercase;color:var(--fg-muted);font-weight:500">Expires</th>
          <th style="padding:10px 8px"></th>
        </tr>
      </thead>
      <tbody>
        <% pendingInvites.forEach(function(inv){ %>
          <tr style="border-bottom:1px solid var(--border)">
            <td style="padding:12px 8px"><%= inv.email %></td>
            <td style="padding:12px 8px;color:var(--fg-muted)"><%= new Date(inv.issued_at).toLocaleDateString('en-US',{ month:'short', day:'numeric' }) %></td>
            <td style="padding:12px 8px;color:var(--fg-muted)"><%= new Date(inv.expires_at).toLocaleDateString('en-US',{ month:'short', day:'numeric' }) %></td>
            <td style="padding:12px 8px;text-align:right">
              <form method="post" action="/admin/team/invite/<%= inv.id %>/cancel" style="margin:0">
                <input type="hidden" name="_csrf" value="<%= csrfToken %>">
                <button type="submit" class="btn btn-ghost btn-sm" style="font-size:11px;padding:4px 10px">Cancel</button>
              </form>
            </td>
          </tr>
        <% }); %>
      </tbody>
    </table>
  <% } %>

  <h2 style="margin-top:32px">Invite a teammate</h2>
  <form method="post" action="/admin/team/invite" style="display:flex;gap:8px;flex-wrap:wrap;align-items:flex-end">
    <input type="hidden" name="_csrf" value="<%= csrfToken %>">
    <label style="flex:1;min-width:240px">Email
      <input type="email" name="email" required placeholder="teammate@example.com">
    </label>
    <button type="submit" class="btn btn-primary">Send invitation</button>
  </form>
  <p class="muted" style="margin-top:12px;font-size:12px">They'll get a magic link valid for 7 days. Once they pick a password, they'll see the same dashboard you see now.</p>
</section>

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