Diff -- /var/www/vhosts/webstls.com/httpdocs/TEMPLATES/webstls_admin_users.html
Diff
/var/www/vhosts/webstls.com/httpdocs/TEMPLATES/webstls_admin_users.html
added on WebSTLs (webstls.com) at 2026-07-11 18:31:19
Added
+68
lines
Removed
-0
lines
Context
0
unchanged
Blobs
from
to 0274f0de5f19
to 0274f0de5f19
Unified diff
Naive LCS-based line diff. Additions in emerald, deletions in rose. Both sides decompressed live from BLOB_STORE.| 1 | <div class="page-header"> | |
| 2 | <div><h1>All Users</h1><p class="subtitle">Click a row to view details, or impersonate any user across the platform.</p></div> | |
| 3 | </div> | |
| 4 | <div class="card mb-2"> | |
| 5 | <form method="GET" action="/admin_users.cgi" style="display:flex;gap:8px"> | |
| 6 | <input class="input" name="q" value="$q" placeholder="Email, name, or display name..."> | |
| 7 | <button type="submit" class="btn btn-primary">Search</button> | |
| 8 | </form> | |
| 9 | </div> | |
| 10 | <style> | |
| 11 | tr.au-clickable { cursor: pointer; transition: background 0.12s; } | |
| 12 | tr.au-clickable:hover { background: rgba(255,255,255,0.04); } | |
| 13 | .au-av { width: 32px; height: 32px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; color: #fff; font-weight: 700; font-size: 12px; flex-shrink: 0; } | |
| 14 | .au-imp-btn { background: #fbbf24; color: #1a1303; border: 1px solid #fbbf24; padding: 6px 12px; border-radius: 6px; font-weight: 700; font-size: 12px; cursor: pointer; } | |
| 15 | .au-imp-btn:hover { background: #f59e0b; border-color: #f59e0b; } | |
| 16 | </style> | |
| 17 | <div class="card"> | |
| 18 | [if:$has_users] | |
| 19 | <table class="table"> | |
| 20 | <thead><tr> | |
| 21 | <th><a href="?sort=name&q=$q" style="color:inherit;text-decoration:none">Member[if:$sort_is_name] ▼[/if]</a></th> | |
| 22 | <th>Email</th> | |
| 23 | <th>Storefront</th> | |
| 24 | <th><a href="?sort=plan&q=$q" style="color:inherit;text-decoration:none">Plan[if:$sort_is_plan] ▼[/if]</a></th> | |
| 25 | <th>Status</th> | |
| 26 | <th><a href="?sort=storage&q=$q" style="color:inherit;text-decoration:none">Storage[if:$sort_is_storage] ▼[/if]</a></th> | |
| 27 | <th><a href="?sort=recent&q=$q" style="color:inherit;text-decoration:none">Last login[if:$sort_is_recent] ▼[/if]</a></th> | |
| 28 | <th></th> | |
| 29 | </tr></thead> | |
| 30 | <tbody> | |
| 31 | [loop:@users] | |
| 32 | <tr class="au-clickable" data-href="/admin_user.cgi?u=$loop1.id"> | |
| 33 | <td><div style="display:flex;align-items:center;gap:10px"><div class="au-av" style="background:$loop1.avatar_color">$loop1.initials</div><div>$loop1.display_name [if:$loop1.is_admin_flag]<span class="badge danger">ADMIN</span>[/if]</div></div></td> | |
| 34 | <td>$loop1.email</td> | |
| 35 | <td>$loop1.storefront_name</td> | |
| 36 | <td><span class="badge">$loop1.plan_tier</span></td> | |
| 37 | <td><span class="badge">$loop1.account_status</span></td> | |
| 38 | <td style="font-size:12px;min-width:160px"> | |
| 39 | <div style="height:6px;border-radius:4px;background:#1f2937;overflow:hidden;margin-bottom:3px"> | |
| 40 | <div style="height:100%;width:${loop1.storage_pct}%;background:$loop1.storage_color"></div> | |
| 41 | </div> | |
| 42 | <span style="color:var(--col-text-dim)">$loop1.storage_label ($loop1.storage_pct%)</span> | |
| 43 | </td> | |
| 44 | <td style="font-size:12px;color:var(--col-text-dim)"><span class="ts" data-ts="$loop1.last_login_epoch" data-fmt="relative">$loop1.last_login_at</span></td> | |
| 45 | <td> | |
| 46 | [if:!$loop1.is_self] | |
| 47 | <form method="POST" action="/admin_action.cgi" style="display:inline;margin:0" onclick="event.stopPropagation()"> | |
| 48 | <input type="hidden" name="act" value="impersonate"> | |
| 49 | <input type="hidden" name="u" value="$loop1.id"> | |
| 50 | <button type="submit" class="au-imp-btn">Impersonate</button> | |
| 51 | </form> | |
| 52 | [/if] | |
| 53 | </td> | |
| 54 | </tr> | |
| 55 | [/loop] | |
| 56 | </tbody> | |
| 57 | </table> | |
| 58 | <script> | |
| 59 | document.querySelectorAll('tr.au-clickable').forEach(function(tr){ | |
| 60 | tr.addEventListener('click', function(e){ | |
| 61 | if (e.target.closest('a,button,form,input')) return; | |
| 62 | window.location.href = tr.dataset.href; | |
| 63 | }); | |
| 64 | }); | |
| 65 | </script> | |
| 66 | [/if] | |
| 67 | [if:!$has_users]<div class="muted-empty"><h3>No users found</h3></div>[/if] | |
| 68 | </div> |