First Commit

This commit is contained in:
2026-08-19 17:26:06 +01:00
parent f782c6f531
commit 121f788c28
25 changed files with 5132 additions and 73 deletions
+270
View File
@@ -0,0 +1,270 @@
<?php
require_admin();
$msg_success = "";
$msg_error = "";
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$action = $_POST['action'] ?? '';
if ($action === 'create_user') {
$res = admin_create_user($_POST['username'] ?? '', $_POST['password'] ?? '', $_POST['role'] ?? 'user');
if ($res['success']) $msg_success = $res['message']; else $msg_error = $res['message'];
} elseif ($action === 'delete_user') {
$res = admin_delete_user($_POST['user_id'] ?? 0);
if ($res['success']) $msg_success = $res['message']; else $msg_error = $res['message'];
} elseif ($action === 'update_role') {
$res = admin_update_user_role($_POST['user_id'] ?? 0, $_POST['role'] ?? 'user');
if ($res['success']) $msg_success = $res['message']; else $msg_error = $res['message'];
} elseif ($action === 'reset_password') {
$res = update_user_password($_POST['user_id'] ?? 0, $_POST['new_password'] ?? '');
if ($res['success']) $msg_success = "Password resettata con successo!"; else $msg_error = $res['message'];
} elseif ($action === 'update_site_title' && is_owner()) {
$new_title = trim($_POST['site_title'] ?? '');
if (!empty($new_title)) {
update_site_setting('site_title', $new_title);
$msg_success = "Titolo del sito aggiornato con successo!";
} else {
$msg_error = "Il titolo del sito non può essere vuoto.";
}
} elseif ($action === 'upload_favicon' && is_owner()) {
$res = upload_site_favicon($_FILES['favicon_file'] ?? null);
if ($res['success']) $msg_success = $res['message']; else $msg_error = $res['message'];
}
}
// Fetch all users and all blocknotes to count per user
$users_list = get_all_users();
$all_blocknotes = get_all_blocknotes();
// Map blocknote count per username
$bn_counts = [];
foreach ($all_blocknotes as $bn) {
$uname = strtolower($bn['username'] ?? '');
if ($uname) {
$bn_counts[$uname] = ($bn_counts[$uname] ?? 0) + 1;
}
}
$site_title = get_site_setting('site_title', 'Blocknotes');
$site_favicon = get_site_setting('site_favicon', 'assets/img/favicon.png');
?>
<main class="main-content">
<div class="page-header">
<div class="page-title-group">
<h1><?= __('admin_title') ?></h1>
<p><?= __('admin_desc') ?></p>
</div>
<div>
<button class="btn btn-primary" data-modal-target="modal-create-user">
<?= __('btn_add_user') ?>
</button>
</div>
</div>
<?php if (!empty($msg_success)): ?>
<div class="alert alert-success">
✅ <?= htmlspecialchars($msg_success) ?>
</div>
<?php endif; ?>
<?php if (!empty($msg_error)): ?>
<div class="alert alert-danger">
⚠️ <?= htmlspecialchars($msg_error) ?>
</div>
<?php endif; ?>
<?php if (is_owner()): ?>
<!-- CARD IMPOSTAZIONI SITO (ESCLUSIVO OWNER) -->
<div class="card" style="margin-bottom: 2rem; border-color: rgba(234, 179, 8, 0.3); background: rgba(234, 179, 8, 0.03);">
<div style="display: flex; align-items: center; gap: 0.6rem; margin-bottom: 1.25rem;">
<span style="font-size: 1.5rem;">👑</span>
<h2 style="font-size: 1.3rem; font-weight: 700; color: #fde047; margin: 0;"><?= __('card_site_settings_title') ?></h2>
</div>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 2rem;">
<!-- Modifica Titolo Sito -->
<form action="index.php?page=admin_users" method="POST">
<input type="hidden" name="action" value="update_site_title">
<div class="form-group">
<label for="site_title"><?= __('label_site_title') ?></label>
<input type="text" name="site_title" id="site_title" class="form-control" value="<?= htmlspecialchars($site_title) ?>" required placeholder="<?= htmlspecialchars(__('placeholder_site_title')) ?>">
</div>
<button type="submit" class="btn btn-primary" style="margin-top: 0.5rem;">
<?= __('btn_save_site_title') ?>
</button>
</form>
<!-- Caricamento Favicon -->
<form action="index.php?page=admin_users" method="POST" enctype="multipart/form-data">
<input type="hidden" name="action" value="upload_favicon">
<div class="form-group">
<label for="favicon_file"><?= __('label_favicon') ?></label>
<div style="display: flex; align-items: center; gap: 1rem; margin-bottom: 0.75rem;">
<?php if (!empty($site_favicon) && file_exists(ROOT_DIR . $site_favicon)): ?>
<img src="<?= htmlspecialchars($site_favicon) ?>" alt="Favicon Preview" style="width: 42px; height: 42px; object-fit: contain; border-radius: 8px; border: 1px solid rgba(255,255,255,0.2); background: #000; padding: 4px;">
<?php endif; ?>
<span style="font-size: 0.82rem; color: #94a3b8;"><?= __('label_current_favicon') ?> <code><?= htmlspecialchars($site_favicon) ?></code></span>
</div>
<input type="file" name="favicon_file" id="favicon_file" class="form-control" accept=".png, .ico, .webp, .svg, .jpg, .jpeg" required>
</div>
<button type="submit" class="btn btn-secondary" style="margin-top: 0.5rem;">
<?= __('btn_upload_favicon') ?>
</button>
</form>
</div>
</div>
<?php endif; ?>
<!-- TABELLA UTENTI -->
<div class="card">
<div class="table-responsive">
<table class="custom-table">
<thead>
<tr>
<th>ID</th>
<th><?= __('col_username') ?></th>
<th><?= __('col_role') ?></th>
<th><?= __('col_bns') ?></th>
<th><?= __('col_created') ?></th>
<th style="text-align: right;"><?= __('col_actions') ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($users_list as $u): ?>
<?php
$uname_lower = strtolower($u['username']);
$count = $bn_counts[$uname_lower] ?? 0;
$is_self = (current_user()['id'] == $u['id']);
$is_user_owner = ($u['role'] === 'owner');
?>
<tr>
<td>#<?= (int)$u['id'] ?></td>
<td>
<strong style="color: #ffffff; font-size: 0.95rem;"><?= htmlspecialchars($u['username']) ?></strong>
<?php if ($is_self): ?>
<span style="font-size:0.75rem; color: #7dd3fc; background: rgba(14,165,233,0.15); padding: 0.15rem 0.4rem; border-radius: 4px; margin-left: 0.4rem;"><?= __('label_you') ?></span>
<?php endif; ?>
</td>
<td>
<?php if ($is_user_owner): ?>
<span class="user-badge badge-owner" style="background: rgba(234, 179, 8, 0.25); border-color: rgba(234, 179, 8, 0.5); color: #fde047;">
👑 <?= __('badge_owner') ?>
</span>
<?php else: ?>
<form action="index.php?page=admin_users" method="POST" style="display:inline-block;">
<input type="hidden" name="action" value="update_role">
<input type="hidden" name="user_id" value="<?= (int)$u['id'] ?>">
<select name="role" onchange="this.form.submit()" class="form-control" style="padding: 0.25rem 0.5rem; font-size: 0.8rem; width: auto; background: rgba(0,0,0,0.3); cursor: pointer;" <?= ($is_self || $is_user_owner) ? 'disabled' : '' ?>>
<option value="user" <?= ($u['role'] === 'user') ? 'selected' : '' ?>><?= __('role_standard') ?></option>
<option value="admin" <?= ($u['role'] === 'admin') ? 'selected' : '' ?>><?= __('role_admin') ?></option>
</select>
</form>
<?php endif; ?>
</td>
<td>
<a href="index.php?page=home&view=all" style="color: #4ade80; font-weight: 600;">
📓 <?= $count ?> Blocknotes
</a>
</td>
<td style="color: #94a3b8; font-size: 0.85rem;">
<?= date('d/m/Y H:i', strtotime($u['created_at'])) ?>
</td>
<td style="text-align: right;">
<div style="display: flex; gap: 0.4rem; justify-content: flex-end;">
<button class="btn btn-sm btn-dark" onclick="openResetPasswordModal(<?= (int)$u['id'] ?>, '<?= htmlspecialchars(addslashes($u['username'])) ?>')">
<?= __('btn_reset_pass') ?>
</button>
<?php if (!$is_self && !$is_user_owner): ?>
<form action="index.php?page=admin_users" method="POST" onsubmit="return confirm('<?= htmlspecialchars(addslashes(__('confirm_delete_user'))) ?>');" style="display:inline;">
<input type="hidden" name="action" value="delete_user">
<input type="hidden" name="user_id" value="<?= (int)$u['id'] ?>">
<button type="submit" class="btn btn-sm btn-danger" title="<?= __('btn_delete') ?>">
🗑️ <?= __('btn_delete') ?>
</button>
</form>
<?php endif; ?>
</div>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</main>
<!-- MODAL CREA UTENTE -->
<div class="modal-backdrop" id="modal-create-user">
<div class="modal-card">
<div class="modal-header">
<h3><?= __('modal_create_user') ?></h3>
<button class="modal-close-btn">&times;</button>
</div>
<form action="index.php?page=admin_users" method="POST">
<input type="hidden" name="action" value="create_user">
<div class="form-group">
<label for="new_username"><?= __('col_username') ?></label>
<input type="text" name="username" id="new_username" class="form-control" required placeholder="<?= htmlspecialchars(__('placeholder_username_new')) ?>">
</div>
<div class="form-group">
<label for="new_user_password"><?= __('label_password') ?></label>
<input type="password" name="password" id="new_user_password" class="form-control" required placeholder="<?= htmlspecialchars(__('placeholder_password')) ?>">
</div>
<div class="form-group">
<label for="new_role"><?= __('col_role') ?></label>
<select name="role" id="new_role" class="form-control">
<option value="user"><?= __('role_standard') ?></option>
<option value="admin"><?= __('role_admin') ?></option>
</select>
</div>
<div style="display: flex; gap: 0.75rem; justify-content: flex-end; margin-top: 1.5rem;">
<button type="button" class="btn btn-dark modal-close-trigger"><?= __('btn_cancel') ?></button>
<button type="submit" class="btn btn-primary"><?= __('btn_save') ?></button>
</div>
</form>
</div>
</div>
<!-- MODAL RESET PASSWORD UTENTE -->
<div class="modal-backdrop" id="modal-reset-password">
<div class="modal-card">
<div class="modal-header">
<h3><?= __('modal_reset_pass') ?></h3>
<button class="modal-close-btn">&times;</button>
</div>
<form action="index.php?page=admin_users" method="POST">
<input type="hidden" name="action" value="reset_password">
<input type="hidden" name="user_id" id="reset_user_id">
<div class="form-group">
<label><?= __('col_username') ?></label>
<input type="text" id="reset_username_display" class="form-control" disabled style="opacity: 0.7;">
</div>
<div class="form-group">
<label for="reset_new_password"><?= __('label_new_pass') ?></label>
<input type="password" name="new_password" id="reset_new_password" class="form-control" required placeholder="<?= htmlspecialchars(__('placeholder_password_new')) ?>">
</div>
<div style="display: flex; gap: 0.75rem; justify-content: flex-end; margin-top: 1.5rem;">
<button type="button" class="btn btn-dark modal-close-trigger"><?= __('btn_cancel') ?></button>
<button type="submit" class="btn btn-secondary"><?= __('btn_save') ?></button>
</div>
</form>
</div>
</div>
<script>
function openResetPasswordModal(userId, username) {
document.getElementById('reset_user_id').value = userId;
document.getElementById('reset_username_display').value = username;
document.getElementById('modal-reset-password').classList.add('active');
}
</script>