Files
Ty Clifford b57091e4ad - initial
2026-04-24 08:41:52 -04:00

110 lines
6.5 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
$adminTitle = 'Users';
include __DIR__.'/admin_header.php';
if (isPost()) {
csrfCheck();
$act = p('_act');
if ($act === 'add') {
$un = ps('username'); $em = ps('email'); $pw = ps('password');
if (!$un || !$pw) { flash('Username and password required.','error'); go('/admin/users.php'); }
if (qval("SELECT id FROM users WHERE username=?",[$un])) { flash('Username taken.','error'); go('/admin/users.php'); }
qrun("INSERT INTO users(username,email,password,is_admin,is_active)VALUES(?,?,?,?,?)",[$un,$em?:null,password_hash($pw,PASSWORD_BCRYPT),(int)p('is_admin',0),(int)p('is_active',1)]);
flash('User added!','success'); go('/admin/users.php');
}
if ($act === 'edit') {
$id = (int)p('id');
$un = ps('username'); $em = ps('email'); $pw = ps('password');
if (!$un) { flash('Username required.','error'); go('/admin/users.php'); }
if (qval("SELECT id FROM users WHERE username=? AND id!=?",[$un,$id])) { flash('Username taken.','error'); go('/admin/users.php'); }
if ($pw) {
qrun("UPDATE users SET username=?,email=?,password=?,is_admin=?,is_active=? WHERE id=?",[$un,$em?:null,password_hash($pw,PASSWORD_BCRYPT),(int)p('is_admin',0),(int)p('is_active',1),$id]);
} else {
qrun("UPDATE users SET username=?,email=?,is_admin=?,is_active=? WHERE id=?",[$un,$em?:null,(int)p('is_admin',0),(int)p('is_active',1),$id]);
}
flash('User updated!','success'); go('/admin/users.php');
}
if ($act === 'delete') {
$id = (int)p('id');
if ($id === uid()) { flash('You cannot delete your own account.','error'); go('/admin/users.php'); }
qrun("DELETE FROM users WHERE id=?",[$id]);
flash('User deleted.','success'); go('/admin/users.php');
}
if ($act === 'toggle_active') {
$id = (int)p('id');
if ($id !== uid()) { qrun("UPDATE users SET is_active=1-is_active WHERE id=?",[$id]); }
go('/admin/users.php');
}
}
$editId = iget('edit');
$editing = $editId ? qone("SELECT * FROM users WHERE id=?",[$editId]) : null;
$page = max(1,iget('page')); $perPage = 30;
$total = (int)qval("SELECT COUNT(*) FROM users");
$pages = max(1,(int)ceil($total/$perPage));
$page = min($page,$pages);
$offset = ($page-1)*$perPage;
$users = qall("SELECT * FROM users ORDER BY is_admin DESC,username ASC LIMIT $perPage OFFSET $offset");
?>
<?php adminTitle($editing ? 'Edit User: '.e($editing['username']) : 'Manage Users') ?>
<div class="ibox" style="border-color:var(--gold-d);margin-bottom:2rem">
<div class="ibox-title"><?=$editing ? '✏️ EDIT USER: '.strtoupper(e($editing['username'])) : ' ADD NEW USER'?></div>
<form method="POST">
<?=csrfField()?>
<input type="hidden" name="_act" value="<?=$editing?'edit':'add'?>">
<?php if($editing): ?><input type="hidden" name="id" value="<?=$editing['id']?>"><?php endif; ?>
<div class="form-row">
<div class="fg"><label class="flabel">USERNAME *</label><input type="text" name="username" class="finput" value="<?=e($editing['username']??'')?>" required></div>
<div class="fg"><label class="flabel">EMAIL</label><input type="email" name="email" class="finput" value="<?=e($editing['email']??'')?>"></div>
</div>
<div class="form-row">
<div class="fg"><label class="flabel"><?=$editing?'NEW PASSWORD (leave blank to keep)':'PASSWORD *'?></label><input type="password" name="password" class="finput" <?=$editing?'':'required'?>><div class="fhint">Minimum 6 characters.</div></div>
<div class="fg" style="display:grid;grid-template-columns:1fr 1fr;gap:.75rem">
<div class="fg"><label class="flabel">ROLE</label><select name="is_admin" class="fselect"><option value="0"<?=!($editing['is_admin']??0)?' selected':''?>>Regular User</option><option value="1"<?=($editing['is_admin']??0)?' selected':''?>>Administrator</option></select></div>
<div class="fg"><label class="flabel">STATUS</label><select name="is_active" class="fselect"><option value="1"<?=($editing['is_active']??1)?' selected':''?>>Active</option><option value="0"<?=isset($editing)&&!$editing['is_active']?' selected':''?>>Suspended</option></select></div>
</div>
</div>
<div class="flex-row">
<button type="submit" class="btn btn-primary"><?=$editing?'Update User':'Add User'?></button>
<?php if($editing): ?><a href="/admin/users.php" class="btn btn-secondary">Cancel</a><?php endif; ?>
</div>
</form>
</div>
<div class="admin-sec-title">ALL USERS (<?=$total?>)</div>
<div class="tbl-wrap">
<table class="dtbl">
<thead><tr><th>USERNAME</th><th>EMAIL</th><th>ROLE</th><th>STATUS</th><th>JOINED</th><th>LAST LOGIN</th><th>ACTIONS</th></tr></thead>
<tbody>
<?php foreach($users as $u): ?>
<tr>
<td class="td-name"><?=e($u['username'])?></td>
<td style="font-size:.8rem"><?=e($u['email']??'—')?></td>
<td><?=$u['is_admin']?'<span class="badge badge-gold">ADMIN</span>':'<span class="badge badge-gray">User</span>'?></td>
<td><?=$u['is_active']?'<span class="badge badge-green">Active</span>':'<span class="badge badge-red">Suspended</span>'?></td>
<td style="font-size:.8rem"><?=fdate($u['created_at'])?></td>
<td style="font-size:.8rem"><?=$u['last_login']?ago($u['last_login']):'Never'?></td>
<td>
<div class="flex-row" style="gap:.3rem">
<a href="/admin/users.php?edit=<?=$u['id']?>" class="btn btn-xs btn-outline">✏️ Edit</a>
<a href="/admin/owners.php?user_id=<?=$u['id']?>" class="btn btn-xs btn-secondary">🔑 Assign</a>
<?php if($u['id']!==uid()): ?>
<form method="POST" style="display:inline"><?=csrfField()?><input type="hidden" name="_act" value="toggle_active"><input type="hidden" name="id" value="<?=$u['id']?>"><button class="btn btn-xs btn-secondary"><?=$u['is_active']?'Suspend':'Restore'?></button></form>
<form method="POST" style="display:inline"><?=csrfField()?><input type="hidden" name="_act" value="delete"><input type="hidden" name="id" value="<?=$u['id']?>"><button class="btn btn-xs btn-danger" data-confirm="Delete user '<?=e($u['username'])?>'?">🗑️</button></form>
<?php endif; ?>
</div>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php if($pages>1): ?>
<div style="display:flex;gap:.5rem;margin-top:1rem;flex-wrap:wrap">
<?php for($i=1;$i<=$pages;$i++): ?><a href="?page=<?=$i?>" class="btn btn-sm<?=$i===$page?' btn-primary':' btn-outline'?>"><?=$i?></a><?php endfor; ?>
</div>
<?php endif; ?>
<?php include __DIR__.'/admin_footer.php'; ?>