| <%- include("partials/shared_header", { title: "Users - OAI Reverse Proxy Admin" }) %> | |
| <h1>User Token List</h1> | |
| <% if (users.length === 0) { %> | |
| <p>No users found.</p> | |
| <% } else { %> | |
| <label for="toggle-nicknames"><input type="checkbox" id="toggle-nicknames" onchange="toggleNicknames()" /> Show Nicknames</label> | |
| <table class="striped full-width"> | |
| <thead> | |
| <tr> | |
| <th>User</th> | |
| <th <% if (sort.includes("ip")) { %>class="active"<% } %> ><a href="/admin/manage/list-users?sort=ip">IPs</a></th> | |
| <th <% if (sort.includes("promptCount")) { %>class="active"<% } %> ><a href="/admin/manage/list-users?sort=promptCount">Prompts</a></th> | |
| <th <% if (sort.includes("sumCost")) { %>class="active"<% } %> ><a href="/admin/manage/list-users?sort=sumCost">Usage</a></th> | |
| <th>Type</th> | |
| <th <% if (sort.includes("createdAt")) { %>class="active"<% } %> ><a href="/admin/manage/list-users?sort=createdAt">Created (UTC)</a></th> | |
| <th <% if (sort.includes("lastUsedAt")) { %>class="active"<% } %> ><a href="/admin/manage/list-users?sort=lastUsedAt">Last Used (UTC)</a></th> | |
| <th colspan="2">Banned?</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| <% users.forEach(function(user){ %> | |
| <tr> | |
| <td> | |
| <a href="/admin/manage/view-user/<%= user.token %>"> | |
| <code class="usertoken"><%= user.token %></code> | |
| <% if (user.nickname) { %> | |
| <span class="nickname" style="display: none"><%= user.nickname %></span> | |
| <% } else { %> | |
| <code class="nickname" style="display: none"><%= "..." + user.token.slice(-5) %></code> | |
| <% } %> | |
| </a> | |
| </td> | |
| <td><%= user.ip.length %></td> | |
| <td><%= user.promptCount %></td> | |
| <td><%= user.prettyUsage %></td> | |
| <td><%= user.type %></td> | |
| <td><%= user.createdAt %></td> | |
| <td><%= user.lastUsedAt ?? "never" %></td> | |
| <td class="actions"> | |
| <% if (user.disabledAt) { %> | |
| <a title="Unban" href="#" class="unban" data-token="<%= user.token %>">🔄️</a> | |
| <% } else { %> | |
| <a title="Ban" href="#" class="ban" data-token="<%= user.token %>">🚫</a> | |
| <% } %> | |
| <td><%= user.disabledAt ? "Yes" : "No" %> <%= user.disabledReason ? `(${user.disabledReason})` : "" %></td> | |
| </td> | |
| </tr> | |
| <% }); %> | |
| </table> | |
| <ul class="pagination"> | |
| <% if (page > 1) { %> | |
| <li><a href="/admin/manage/list-users?sort=<%= sort %>&page=<%= page - 1 %>">«</a></li> | |
| <% } %> <% for (var i = 1; i <= pageCount; i++) { %> | |
| <li <% if (i === page) { %>class="active"<% } %>><a href="/admin/manage/list-users?sort=<%= sort %>&page=<%= i %>"><%= i %></a></li> | |
| <% } %> <% if (page < pageCount) { %> | |
| <li><a href="/admin/manage/list-users?sort=<%= sort %>&page=<%= page + 1 %>">»</a></li> | |
| <% } %> | |
| </ul> | |
| <p>Showing <%= page * pageSize - pageSize + 1 %> to <%= users.length + page * pageSize - pageSize %> of <%= totalCount %> users.</p> | |
| <%- include("partials/shared_pagination") %> | |
| <% } %> | |
| <script> | |
| function toggleNicknames() { | |
| const checked = document.getElementById("toggle-nicknames").checked; | |
| const visibleSelector = checked ? ".nickname" : ".usertoken"; | |
| const hiddenSelector = checked ? ".usertoken" : ".nickname"; | |
| document.querySelectorAll(visibleSelector).forEach(function (el) { | |
| el.style.display = "inline"; | |
| }); | |
| document.querySelectorAll(hiddenSelector).forEach(function (el) { | |
| el.style.display = "none"; | |
| }); | |
| localStorage.setItem("showNicknames", checked); | |
| } | |
| const state = localStorage.getItem("showNicknames") === "true"; | |
| document.getElementById("toggle-nicknames").checked = state; | |
| toggleNicknames(); | |
| </script> | |
| <%- include("partials/admin-ban-xhr-script") %> | |
| <%- include("partials/admin-footer") %> | |