First Commit
This commit is contained in:
@@ -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">×</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">×</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>
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
require_login();
|
||||
|
||||
$user = current_user();
|
||||
$blocknote_id = $_GET['id'] ?? '';
|
||||
$bn = get_blocknote_by_id($blocknote_id);
|
||||
|
||||
if (!$bn || !can_access_blocknote($bn, $user['username'], is_admin())) {
|
||||
header("Location: index.php?page=home");
|
||||
exit;
|
||||
}
|
||||
|
||||
// Clean output buffer before outputting binary/file response
|
||||
if (ob_get_level()) {
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
$safe_title = preg_replace('/[^a-zA-Z0-9_\-]/', '_', $bn['title']);
|
||||
$filename = "blocknote_" . $safe_title . "_" . $bn['id'] . ".json";
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
header('Content-Disposition: attachment; filename="' . $filename . '"');
|
||||
header('Pragma: no-cache');
|
||||
header('Expires: 0');
|
||||
|
||||
echo json_encode($bn, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
||||
exit;
|
||||
+231
-4
@@ -1,6 +1,233 @@
|
||||
<?php
|
||||
require_login();
|
||||
|
||||
$user = current_user();
|
||||
|
||||
// Check landing page redirection if default blocknote is set and user is not requesting explicitly view=all
|
||||
if (!isset($_GET['view']) && !empty($user['default_blocknote'])) {
|
||||
$def_bn = get_blocknote_by_id($user['default_blocknote']);
|
||||
if ($def_bn && can_access_blocknote($def_bn, $user['username'], is_admin())) {
|
||||
header("Location: index.php?page=view_blocknote&id=" . urlencode($user['default_blocknote']));
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
$msg_success = "";
|
||||
$msg_error = "";
|
||||
|
||||
// Handle Form Submissions
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$action = $_POST['action'] ?? '';
|
||||
|
||||
if ($action === 'create_blocknote') {
|
||||
$res = create_blocknote($_POST['title'] ?? '', $user['username']);
|
||||
if ($res['success']) {
|
||||
$msg_success = $res['message'];
|
||||
} else {
|
||||
$msg_error = $res['message'];
|
||||
}
|
||||
} elseif ($action === 'rename_blocknote') {
|
||||
$res = rename_blocknote($_POST['id'] ?? '', $_POST['title'] ?? '', $user['username'], is_admin());
|
||||
if ($res['success']) {
|
||||
$msg_success = $res['message'];
|
||||
} else {
|
||||
$msg_error = $res['message'];
|
||||
}
|
||||
} elseif ($action === 'delete_blocknote') {
|
||||
$res = delete_blocknote($_POST['id'] ?? '', $user['username'], is_admin());
|
||||
if ($res['success']) {
|
||||
$msg_success = $res['message'];
|
||||
} else {
|
||||
$msg_error = $res['message'];
|
||||
}
|
||||
} elseif ($action === 'import_blocknote') {
|
||||
$json_content = "";
|
||||
if (!empty($_FILES['json_file']['tmp_name'])) {
|
||||
$json_content = file_get_contents($_FILES['json_file']['tmp_name']);
|
||||
} else {
|
||||
$json_content = $_POST['json_text'] ?? '';
|
||||
}
|
||||
$res = import_blocknote_json($json_content, $user['username'], $_POST['title'] ?? '');
|
||||
if ($res['success']) {
|
||||
$msg_success = $res['message'];
|
||||
} else {
|
||||
$msg_error = $res['message'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch blocknotes
|
||||
$blocknotes = get_user_blocknotes($user['username'], is_admin());
|
||||
?>
|
||||
|
||||
<main class="main-content">
|
||||
<section>
|
||||
<h1>Welcome to the Home Page</h1>
|
||||
<p>This is the home page.</p>
|
||||
</section>
|
||||
<div class="page-header">
|
||||
<div class="page-title-group">
|
||||
<h1>📓 <?= is_admin() ? __('dashboard_title_admin') : __('dashboard_title_user') ?></h1>
|
||||
<p><?= is_admin() ? __('dashboard_desc_admin') : __('dashboard_desc_user') ?></p>
|
||||
</div>
|
||||
<div style="display: flex; gap: 0.5rem; flex-wrap: wrap;">
|
||||
<button class="btn btn-dark" data-modal-target="modal-import-blocknote">
|
||||
<?= __('btn_import_json') ?>
|
||||
</button>
|
||||
<button class="btn btn-primary" data-modal-target="modal-create-blocknote">
|
||||
<?= __('btn_new_blocknote') ?>
|
||||
</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 (empty($blocknotes)): ?>
|
||||
<div class="empty-state">
|
||||
<div class="empty-state-icon">📋</div>
|
||||
<h3><?= __('empty_blocknotes_title') ?></h3>
|
||||
<p><?= is_admin() ? __('empty_blocknotes_desc_admin') : __('empty_blocknotes_desc_user') ?></p>
|
||||
<button class="btn btn-primary" data-modal-target="modal-create-blocknote">
|
||||
<?= __('btn_new_blocknote') ?>
|
||||
</button>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="blocknotes-grid">
|
||||
<?php foreach ($blocknotes as $bn): ?>
|
||||
<?php
|
||||
$note_count = count($bn['notes'] ?? []);
|
||||
$is_owner = (strtolower($bn['username'] ?? '') === strtolower($user['username']));
|
||||
?>
|
||||
<div class="blocknote-card">
|
||||
<div class="blocknote-card-header">
|
||||
<h2 class="blocknote-title">
|
||||
<a href="index.php?page=view_blocknote&id=<?= urlencode($bn['id']) ?>">
|
||||
<?= htmlspecialchars($bn['title']) ?>
|
||||
</a>
|
||||
</h2>
|
||||
<?php if (is_admin() || !$is_owner): ?>
|
||||
<span class="blocknote-owner-tag">
|
||||
👤 <?= htmlspecialchars($bn['username'] ?? __('label_unknown')) ?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="blocknote-card-body">
|
||||
<div class="blocknote-meta">
|
||||
<span>📄 <?= $note_count ?> <?= ($note_count === 1) ? __('note_single') : __('note_plural') ?></span>
|
||||
<span>🕒 <?= date('d/m/Y H:i', strtotime($bn['updated_at'] ?? 'now')) ?></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="blocknote-card-actions">
|
||||
<a href="index.php?page=view_blocknote&id=<?= urlencode($bn['id']) ?>" class="btn btn-sm btn-secondary" style="flex:1; justify-content:center;">
|
||||
<?= __('btn_open_edit') ?>
|
||||
</a>
|
||||
|
||||
<a href="index.php?page=export_blocknote&id=<?= urlencode($bn['id']) ?>" class="btn btn-sm btn-dark" title="<?= __('btn_export_json') ?>">
|
||||
💾
|
||||
</a>
|
||||
|
||||
<button class="btn btn-sm btn-dark" title="<?= __('btn_rename') ?>" onclick="openRenameModal('<?= htmlspecialchars($bn['id']) ?>', '<?= htmlspecialchars(addslashes($bn['title'])) ?>')">
|
||||
✏️
|
||||
</button>
|
||||
|
||||
<form action="index.php?page=home&view=all" method="POST" onsubmit="return confirm('<?= htmlspecialchars(addslashes(__('confirm_delete_blocknote'))) ?>');" style="display:inline;">
|
||||
<input type="hidden" name="action" value="delete_blocknote">
|
||||
<input type="hidden" name="id" value="<?= htmlspecialchars($bn['id']) ?>">
|
||||
<button type="submit" class="btn btn-sm btn-danger" title="<?= __('btn_delete') ?>">
|
||||
🗑️
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</main>
|
||||
|
||||
<!-- MODAL CREA BLOCKNOTE -->
|
||||
<div class="modal-backdrop" id="modal-create-blocknote">
|
||||
<div class="modal-card">
|
||||
<div class="modal-header">
|
||||
<h3><?= __('modal_create_title') ?></h3>
|
||||
<button class="modal-close-btn">×</button>
|
||||
</div>
|
||||
<form action="index.php?page=home&view=all" method="POST">
|
||||
<input type="hidden" name="action" value="create_blocknote">
|
||||
<div class="form-group">
|
||||
<label for="create_title"><?= __('label_title') ?></label>
|
||||
<input type="text" name="title" id="create_title" class="form-control" required placeholder="<?= htmlspecialchars(__('placeholder_bn_title')) ?>">
|
||||
</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_create') ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- MODAL RINOMINA BLOCKNOTE -->
|
||||
<div class="modal-backdrop" id="modal-rename-blocknote">
|
||||
<div class="modal-card">
|
||||
<div class="modal-header">
|
||||
<h3><?= __('modal_rename_title') ?></h3>
|
||||
<button class="modal-close-btn">×</button>
|
||||
</div>
|
||||
<form action="index.php?page=home&view=all" method="POST">
|
||||
<input type="hidden" name="action" value="rename_blocknote">
|
||||
<input type="hidden" name="id" id="rename_id">
|
||||
<div class="form-group">
|
||||
<label for="rename_title"><?= __('label_title') ?></label>
|
||||
<input type="text" name="title" id="rename_title" class="form-control" required placeholder="<?= htmlspecialchars(__('placeholder_rename_title')) ?>">
|
||||
</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>
|
||||
|
||||
<!-- MODAL IMPORTA BLOCKNOTE -->
|
||||
<div class="modal-backdrop" id="modal-import-blocknote">
|
||||
<div class="modal-card">
|
||||
<div class="modal-header">
|
||||
<h3><?= __('modal_import_title') ?></h3>
|
||||
<button class="modal-close-btn">×</button>
|
||||
</div>
|
||||
<form action="index.php?page=home&view=all" method="POST" enctype="multipart/form-data">
|
||||
<input type="hidden" name="action" value="import_blocknote">
|
||||
<div class="form-group">
|
||||
<label for="import_title"><?= __('label_title') ?></label>
|
||||
<input type="text" name="title" id="import_title" class="form-control" placeholder="<?= htmlspecialchars(__('placeholder_import_title')) ?>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="json_file"><?= __('label_file_json') ?></label>
|
||||
<input type="file" name="json_file" id="json_file" class="form-control" accept=".json">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="json_text"><?= __('label_paste_json') ?></label>
|
||||
<textarea name="json_text" id="json_text" class="form-control" style="font-family: monospace; min-height: 120px;" placeholder="<?= htmlspecialchars(__('placeholder_paste_json')) ?>"></textarea>
|
||||
</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_import') ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function openRenameModal(id, currentTitle) {
|
||||
document.getElementById('rename_id').value = id;
|
||||
document.getElementById('rename_title').value = currentTitle;
|
||||
document.getElementById('modal-rename-blocknote').classList.add('active');
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
if (is_logged_in()) {
|
||||
header("Location: index.php?page=home");
|
||||
exit;
|
||||
}
|
||||
|
||||
$error_msg = "";
|
||||
$success_msg = "";
|
||||
|
||||
if (isset($_GET['installed'])) {
|
||||
$success_msg = __('login_installed_success');
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$username = $_POST['username'] ?? '';
|
||||
$password = $_POST['password'] ?? '';
|
||||
|
||||
$res = login_user($username, $password);
|
||||
if ($res['success']) {
|
||||
header("Location: index.php?page=home");
|
||||
exit;
|
||||
} else {
|
||||
$error_msg = $res['message'];
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<main class="main-content">
|
||||
<div style="max-width: 420px; margin: 3rem auto;">
|
||||
<div class="card" style="padding: 2.25rem;">
|
||||
<div style="text-align: center; margin-bottom: 2rem;">
|
||||
<span style="font-size: 3rem;">📝</span>
|
||||
<h2 style="font-size: 1.6rem; font-weight: 700; color: #fff; margin-top: 0.5rem;"><?= __('login_title') ?></h2>
|
||||
<p style="color: #94a3b8; font-size: 0.9rem; margin-top: 0.25rem;"><?= __('login_subtitle') ?></p>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($success_msg)): ?>
|
||||
<div class="alert alert-success">
|
||||
✅ <?= htmlspecialchars($success_msg) ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($error_msg)): ?>
|
||||
<div class="alert alert-danger">
|
||||
⚠️ <?= htmlspecialchars($error_msg) ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form action="index.php?page=login" method="POST">
|
||||
<div class="form-group">
|
||||
<label for="username"><?= __('label_username') ?></label>
|
||||
<input type="text" name="username" id="username" class="form-control" required placeholder="<?= __('placeholder_username') ?>" autofocus value="<?= htmlspecialchars($_POST['username'] ?? '') ?>">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password"><?= __('label_password') ?></label>
|
||||
<input type="password" name="password" id="password" class="form-control" required placeholder="<?= __('placeholder_password') ?>">
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary" style="width: 100%; justify-content: center; margin-top: 1rem; padding: 0.8rem;">
|
||||
<?= __('btn_submit_login') ?>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div style="margin-top: 1.5rem; text-align: center; padding-top: 1rem; border-top: 1px solid rgba(255,255,255,0.08); font-size: 0.82rem; color: #64748b;">
|
||||
<?= __('login_hint_footer') ?>:<br>
|
||||
<strong style="color: #94a3b8;"><?= __('label_username') ?>:</strong> admin | <strong style="color: #94a3b8;"><?= __('label_password') ?>:</strong> admin123
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
logout_user();
|
||||
header("Location: index.php?page=login");
|
||||
exit;
|
||||
@@ -0,0 +1,235 @@
|
||||
<?php
|
||||
require_login();
|
||||
|
||||
$user = current_user();
|
||||
$msg_password_success = "";
|
||||
$msg_password_error = "";
|
||||
$msg_theme_success = "";
|
||||
$msg_theme_error = "";
|
||||
$msg_lang_success = "";
|
||||
$msg_lang_error = "";
|
||||
$msg_landing_success = "";
|
||||
$msg_landing_error = "";
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$action = $_POST['action'] ?? '';
|
||||
|
||||
if ($action === 'change_password') {
|
||||
$new_pass = $_POST['new_password'] ?? '';
|
||||
$confirm_pass = $_POST['confirm_password'] ?? '';
|
||||
|
||||
if ($new_pass !== $confirm_pass) {
|
||||
$msg_password_error = "Le password inserite non coincidono.";
|
||||
} else {
|
||||
$res = update_user_password($user['id'], $new_pass);
|
||||
if ($res['success']) {
|
||||
$msg_password_success = $res['message'];
|
||||
} else {
|
||||
$msg_password_error = $res['message'];
|
||||
}
|
||||
}
|
||||
} elseif ($action === 'update_theme') {
|
||||
$pri = $_POST['theme_pri'] ?? 98;
|
||||
$sec = $_POST['theme_sec'] ?? 207;
|
||||
$thi = $_POST['theme_thi'] ?? 280;
|
||||
|
||||
$res = update_user_theme($user['id'], $pri, $sec, $thi);
|
||||
if ($res['success']) {
|
||||
$msg_theme_success = $res['message'];
|
||||
$user = current_user(); // Refresh session data
|
||||
} else {
|
||||
$msg_theme_error = $res['message'];
|
||||
}
|
||||
} elseif ($action === 'update_language') {
|
||||
$lang = $_POST['language'] ?? 'it';
|
||||
$res = update_user_language($user['id'], $lang);
|
||||
if ($res['success']) {
|
||||
$msg_lang_success = $res['message'];
|
||||
$user = current_user();
|
||||
} else {
|
||||
$msg_lang_error = $res['message'];
|
||||
}
|
||||
} elseif ($action === 'update_landing') {
|
||||
$bn_id = $_POST['default_blocknote'] ?? '';
|
||||
$res = update_user_default_blocknote($user['id'], $bn_id);
|
||||
if ($res['success']) {
|
||||
$msg_landing_success = $res['message'];
|
||||
$user = current_user();
|
||||
} else {
|
||||
$msg_landing_error = $res['message'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$pri = $user['theme_pri'] ?? 98;
|
||||
$sec = $user['theme_sec'] ?? 207;
|
||||
$thi = $user['theme_thi'] ?? 280;
|
||||
$current_lang = $user['language'] ?? 'it';
|
||||
$current_default_bn = $user['default_blocknote'] ?? '';
|
||||
$user_blocknotes = get_user_blocknotes($user['username'], is_admin());
|
||||
?>
|
||||
|
||||
<main class="main-content">
|
||||
<div class="page-header">
|
||||
<div class="page-title-group">
|
||||
<h1><?= __('profile_title') ?></h1>
|
||||
<p><?= __('profile_desc') ?></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(360px, 1fr)); gap: 2rem;">
|
||||
|
||||
<!-- CARD LINGUA INTERFACCIA -->
|
||||
<div class="card">
|
||||
<h2 style="font-size: 1.3rem; font-weight: 700; color: #fff; margin-bottom: 1.25rem;"><?= __('card_lang_title') ?></h2>
|
||||
|
||||
<?php if (!empty($msg_lang_success)): ?>
|
||||
<div class="alert alert-success">✅ <?= htmlspecialchars($msg_lang_success) ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($msg_lang_error)): ?>
|
||||
<div class="alert alert-danger">⚠️ <?= htmlspecialchars($msg_lang_error) ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form action="index.php?page=profile" method="POST">
|
||||
<input type="hidden" name="action" value="update_language">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="language"><?= __('label_select_lang') ?></label>
|
||||
<select name="language" id="language" class="form-control">
|
||||
<option value="it" <?= ($current_lang === 'it') ? 'selected' : '' ?>>🇮🇹 Italiano</option>
|
||||
<option value="en" <?= ($current_lang === 'en') ? 'selected' : '' ?>>🇬🇧 English</option>
|
||||
<option value="es" <?= ($current_lang === 'es') ? 'selected' : '' ?>>🇪🇸 Español</option>
|
||||
<option value="fr" <?= ($current_lang === 'fr') ? 'selected' : '' ?>>🇫🇷 Français</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-secondary" style="margin-top: 1rem; width: 100%; justify-content: center;">
|
||||
<?= __('btn_save_lang') ?>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- CARD PAGINA DI PRIMO ACCESSO (LANDING PAGE) -->
|
||||
<div class="card">
|
||||
<h2 style="font-size: 1.3rem; font-weight: 700; color: #fff; margin-bottom: 1.25rem;"><?= __('card_landing_title') ?></h2>
|
||||
|
||||
<?php if (!empty($msg_landing_success)): ?>
|
||||
<div class="alert alert-success">✅ <?= htmlspecialchars($msg_landing_success) ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($msg_landing_error)): ?>
|
||||
<div class="alert alert-danger">⚠️ <?= htmlspecialchars($msg_landing_error) ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form action="index.php?page=profile" method="POST">
|
||||
<input type="hidden" name="action" value="update_landing">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="default_blocknote"><?= __('label_select_landing') ?></label>
|
||||
<select name="default_blocknote" id="default_blocknote" class="form-control">
|
||||
<option value=""><?= __('landing_option_dashboard') ?></option>
|
||||
<?php foreach ($user_blocknotes as $bn): ?>
|
||||
<option value="<?= htmlspecialchars($bn['id']) ?>" <?= ($current_default_bn === $bn['id']) ? 'selected' : '' ?>>
|
||||
<?= __('landing_option_bn_prefix') ?><?= htmlspecialchars($bn['title']) ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary" style="margin-top: 1rem; width: 100%; justify-content: center;">
|
||||
<?= __('btn_save_landing') ?>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- CARD CAMBIO PASSWORD -->
|
||||
<div class="card">
|
||||
<h2 style="font-size: 1.3rem; font-weight: 700; color: #fff; margin-bottom: 1.25rem;"><?= __('card_password_title') ?></h2>
|
||||
|
||||
<?php if (!empty($msg_password_success)): ?>
|
||||
<div class="alert alert-success">✅ <?= htmlspecialchars($msg_password_success) ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($msg_password_error)): ?>
|
||||
<div class="alert alert-danger">⚠️ <?= htmlspecialchars($msg_password_error) ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form action="index.php?page=profile" method="POST">
|
||||
<input type="hidden" name="action" value="change_password">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="new_password"><?= __('label_new_pass') ?></label>
|
||||
<input type="password" name="new_password" id="new_password" class="form-control" required placeholder="<?= htmlspecialchars(__('placeholder_password_new')) ?>">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="confirm_password"><?= __('label_confirm_pass') ?></label>
|
||||
<input type="password" name="confirm_password" id="confirm_password" class="form-control" required placeholder="<?= htmlspecialchars(__('placeholder_password_confirm')) ?>">
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary" style="margin-top: 0.5rem; width: 100%; justify-content: center;">
|
||||
<?= __('btn_update_pass') ?>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- CARD PERSONALIZZAZIONE COLORI TEMA -->
|
||||
<div class="card">
|
||||
<h2 style="font-size: 1.3rem; font-weight: 700; color: #fff; margin-bottom: 1.25rem;"><?= __('card_colors_title') ?></h2>
|
||||
|
||||
<?php if (!empty($msg_theme_success)): ?>
|
||||
<div class="alert alert-success">✅ <?= htmlspecialchars($msg_theme_success) ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($msg_theme_error)): ?>
|
||||
<div class="alert alert-danger">⚠️ <?= htmlspecialchars($msg_theme_error) ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form action="index.php?page=profile" method="POST">
|
||||
<input type="hidden" name="action" value="update_theme">
|
||||
|
||||
<!-- Colore Primario -->
|
||||
<div class="form-group">
|
||||
<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:0.3rem;">
|
||||
<label for="theme_pri">Primary Color (HSL Hue)</label>
|
||||
<span id="pri_val" style="font-weight:700; color:var(--priCol10);"><?= (int)$pri ?>°</span>
|
||||
</div>
|
||||
<input type="range" min="0" max="360" name="theme_pri" id="theme_pri" value="<?= (int)$pri ?>" class="form-control" style="cursor:pointer; height: 10px;">
|
||||
<div class="color-preview-box" style="background: hsl(var(--pri), 100%, 50%); margin-top: 0.5rem; font-size: 0.82rem;">
|
||||
Preview Primary
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Colore Secondario -->
|
||||
<div class="form-group" style="margin-top: 1.5rem;">
|
||||
<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:0.3rem;">
|
||||
<label for="theme_sec">Secondary Color (HSL Hue)</label>
|
||||
<span id="sec_val" style="font-weight:700; color:var(--secCol10);"><?= (int)$sec ?>°</span>
|
||||
</div>
|
||||
<input type="range" min="0" max="360" name="theme_sec" id="theme_sec" value="<?= (int)$sec ?>" class="form-control" style="cursor:pointer; height: 10px;">
|
||||
<div class="color-preview-box" style="background: hsl(var(--sec), 100%, 50%); margin-top: 0.5rem; font-size: 0.82rem; color: #fff;">
|
||||
Preview Secondary
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Colore Terziario -->
|
||||
<div class="form-group" style="margin-top: 1.5rem;">
|
||||
<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:0.3rem;">
|
||||
<label for="theme_thi">Tertiary Color (HSL Hue)</label>
|
||||
<span id="thi_val" style="font-weight:700; color:var(--thiCol10);"><?= (int)$thi ?>°</span>
|
||||
</div>
|
||||
<input type="range" min="0" max="360" name="theme_thi" id="theme_thi" value="<?= (int)$thi ?>" class="form-control" style="cursor:pointer; height: 10px;">
|
||||
<div class="color-preview-box" style="background: hsl(var(--thi), 100%, 50%); margin-top: 0.5rem; font-size: 0.82rem; color: #fff;">
|
||||
Preview Tertiary
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-secondary" style="margin-top: 1.5rem; width: 100%; justify-content: center;">
|
||||
<?= __('btn_save_colors') ?>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</main>
|
||||
@@ -0,0 +1,375 @@
|
||||
<?php
|
||||
require_login();
|
||||
|
||||
$user = current_user();
|
||||
$blocknote_id = $_GET['id'] ?? '';
|
||||
$bn = get_blocknote_by_id($blocknote_id);
|
||||
|
||||
// Check access permission
|
||||
if (!$bn || !can_access_blocknote($bn, $user['username'], is_admin())) {
|
||||
header("Location: index.php?page=home");
|
||||
exit;
|
||||
}
|
||||
|
||||
$msg_success = "";
|
||||
$msg_error = "";
|
||||
|
||||
// Handle Form Submissions
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$action = $_POST['action'] ?? '';
|
||||
|
||||
if ($action === 'add_note') {
|
||||
$res = add_note_to_blocknote($blocknote_id, $_POST['title'] ?? '', $_POST['description'] ?? '', $user['username'], is_admin());
|
||||
if ($res['success']) $msg_success = $res['message']; else $msg_error = $res['message'];
|
||||
} elseif ($action === 'edit_note') {
|
||||
$res = edit_note_in_blocknote($blocknote_id, $_POST['note_id'] ?? '', $_POST['title'] ?? '', $_POST['description'] ?? '', $user['username'], is_admin());
|
||||
if ($res['success']) $msg_success = $res['message']; else $msg_error = $res['message'];
|
||||
} elseif ($action === 'delete_note') {
|
||||
$res = delete_note_from_blocknote($blocknote_id, $_POST['note_id'] ?? '', $user['username'], is_admin());
|
||||
if ($res['success']) $msg_success = $res['message']; else $msg_error = $res['message'];
|
||||
} elseif ($action === 'add_subnote') {
|
||||
$res = add_subnote_to_note($blocknote_id, $_POST['note_id'] ?? '', $_POST['sub_title'] ?? '', $_POST['type'] ?? 'text', $_POST['content'] ?? '', $user['username'], is_admin());
|
||||
if ($res['success']) $msg_success = $res['message']; else $msg_error = $res['message'];
|
||||
} elseif ($action === 'edit_subnote') {
|
||||
$res = edit_subnote_in_note($blocknote_id, $_POST['note_id'] ?? '', $_POST['sub_id'] ?? '', $_POST['sub_title'] ?? '', $_POST['type'] ?? 'text', $_POST['content'] ?? '', $user['username'], is_admin());
|
||||
if ($res['success']) $msg_success = $res['message']; else $msg_error = $res['message'];
|
||||
} elseif ($action === 'delete_subnote') {
|
||||
$res = delete_subnote_from_note($blocknote_id, $_POST['note_id'] ?? '', $_POST['sub_id'] ?? '', $user['username'], is_admin());
|
||||
if ($res['success']) $msg_success = $res['message']; else $msg_error = $res['message'];
|
||||
}
|
||||
|
||||
// Refresh blocknote data
|
||||
$bn = get_blocknote_by_id($blocknote_id);
|
||||
}
|
||||
|
||||
$notes = $bn['notes'] ?? [];
|
||||
?>
|
||||
|
||||
<main class="main-content">
|
||||
<div style="margin-bottom: 1.5rem;">
|
||||
<a href="index.php?page=home&view=all" class="btn btn-sm btn-dark"><?= __('btn_back_list') ?></a>
|
||||
</div>
|
||||
|
||||
<div class="page-header" style="border-bottom: 1px solid rgba(255,255,255,0.08); padding-bottom: 1.5rem; margin-bottom: 2rem;">
|
||||
<div class="page-title-group">
|
||||
<h1>📓 <?= htmlspecialchars($bn['title']) ?></h1>
|
||||
<p>
|
||||
<?= __('label_owner_prefix') ?><strong style="color: #cbd5e1;"><?= htmlspecialchars($bn['username'] ?? '') ?></strong> •
|
||||
<?= __('label_updated_prefix') ?><?= date('d/m/Y H:i', strtotime($bn['updated_at'] ?? 'now')) ?>
|
||||
</p>
|
||||
</div>
|
||||
<div style="display: flex; gap: 0.5rem; flex-wrap: wrap;">
|
||||
<a href="index.php?page=export_blocknote&id=<?= urlencode($blocknote_id) ?>" class="btn btn-dark btn-sm" title="<?= __('btn_export_json') ?>">
|
||||
<?= __('btn_export_json') ?>
|
||||
</a>
|
||||
<button class="btn btn-dark btn-sm" onclick="expandAllNotes()">
|
||||
<?= __('btn_expand_all') ?>
|
||||
</button>
|
||||
<button class="btn btn-dark btn-sm" onclick="collapseAllNotes()">
|
||||
<?= __('btn_collapse_all') ?>
|
||||
</button>
|
||||
<button class="btn btn-primary" data-modal-target="modal-add-note">
|
||||
<?= __('btn_new_note') ?>
|
||||
</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 (!empty($notes)): ?>
|
||||
<!-- SEARCH TOOLBAR FOR CURRENT BLOCKNOTE -->
|
||||
<div class="search-toolbar" style="margin-bottom: 1.5rem; display: flex; gap: 0.75rem; align-items: center;">
|
||||
<div style="position: relative; flex: 1;">
|
||||
<input type="text" id="note-search-input" class="form-control" placeholder="<?= __('search_placeholder') ?>" oninput="filterCurrentBlocknoteNotes(this.value)" style="padding-left: 2.5rem;">
|
||||
<span style="position: absolute; left: 0.9rem; top: 50%; transform: translateY(-50%); font-size: 1rem; opacity: 0.5;">🔍</span>
|
||||
</div>
|
||||
<button class="btn btn-dark btn-sm" onclick="clearNoteSearch()" id="clear-search-btn" style="display: none; align-items: center; gap: 0.3rem;">
|
||||
<?= __('btn_clear_search') ?>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- SEARCH NO RESULTS STATE -->
|
||||
<div id="no-search-results" class="empty-state" style="display: none; padding: 2.5rem 1rem;">
|
||||
<div class="empty-state-icon">🔍</div>
|
||||
<h3><?= __('search_no_results') ?></h3>
|
||||
<p><?= __('search_no_results_desc') ?></p>
|
||||
<button class="btn btn-dark btn-sm" onclick="clearNoteSearch()">
|
||||
🔄 Reset
|
||||
</button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (empty($notes)): ?>
|
||||
<div class="empty-state">
|
||||
<div class="empty-state-icon">📝</div>
|
||||
<h3><?= __('empty_blocknotes_title') ?></h3>
|
||||
<p><?= __('empty_blocknotes_desc_user') ?></p>
|
||||
<button class="btn btn-primary" data-modal-target="modal-add-note">
|
||||
<?= __('btn_new_note') ?>
|
||||
</button>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="notes-container">
|
||||
<?php foreach ($notes as $note): ?>
|
||||
<?php $subnotes = $note['subnotes'] ?? []; ?>
|
||||
<div class="note-block collapsed" id="note-block-<?= htmlspecialchars($note['id']) ?>">
|
||||
<div class="note-header" onclick="toggleNoteCollapse('<?= htmlspecialchars($note['id']) ?>')">
|
||||
<div class="note-title-area">
|
||||
<div class="note-title-wrapper">
|
||||
<span class="collapse-icon">▶</span>
|
||||
<h3>📌 <?= htmlspecialchars($note['title']) ?></h3>
|
||||
<span class="subnote-count-badge">
|
||||
<?= count($subnotes) ?> <?= (count($subnotes) === 1) ? __('subnote_single') : __('subnote_plural') ?>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="note-actions" onclick="event.stopPropagation();">
|
||||
<button class="btn btn-sm btn-secondary" onclick="openAddSubnoteModal('<?= htmlspecialchars($note['id']) ?>', '<?= htmlspecialchars(addslashes($note['title'])) ?>')">
|
||||
<?= __('btn_add_subnote') ?>
|
||||
</button>
|
||||
|
||||
<button class="btn btn-sm btn-dark" onclick="openEditNoteModal('<?= htmlspecialchars($note['id']) ?>', '<?= htmlspecialchars(addslashes($note['title'])) ?>', '<?= htmlspecialchars(addslashes($note['description'] ?? '')) ?>')">
|
||||
✏️
|
||||
</button>
|
||||
|
||||
<form action="index.php?page=view_blocknote&id=<?= urlencode($blocknote_id) ?>" method="POST" onsubmit="return confirm('<?= htmlspecialchars(addslashes(__('confirm_delete_note'))) ?>');" style="display:inline;">
|
||||
<input type="hidden" name="action" value="delete_note">
|
||||
<input type="hidden" name="note_id" value="<?= htmlspecialchars($note['id']) ?>">
|
||||
<button type="submit" class="btn btn-sm btn-danger" title="<?= __('btn_delete') ?>">
|
||||
🗑️
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="note-body">
|
||||
<?php if (!empty($note['description'])): ?>
|
||||
<div class="note-description-box">
|
||||
<p><?= htmlspecialchars($note['description']) ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="subnotes-list">
|
||||
<?php if (empty($subnotes)): ?>
|
||||
<div style="font-size: 0.88rem; color: #64748b; font-style: italic; text-align: center; padding: 1rem 0;">
|
||||
<?= __('empty_blocknotes_desc_user') ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<?php foreach ($subnotes as $sub): ?>
|
||||
<div class="subnote-card">
|
||||
<div class="subnote-header">
|
||||
<div class="subnote-title-group">
|
||||
<span class="subnote-title">📑 <?= htmlspecialchars($sub['title']) ?></span>
|
||||
<span class="type-badge <?= htmlspecialchars($sub['type']) ?>">
|
||||
<?= ($sub['type'] === 'command') ? __('badge_command') : __('badge_text') ?>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div style="display: flex; gap: 0.4rem;">
|
||||
<button class="btn btn-sm btn-dark" onclick="openEditSubnoteModal('<?= htmlspecialchars($note['id']) ?>', '<?= htmlspecialchars($sub['id']) ?>', '<?= htmlspecialchars(addslashes($sub['title'])) ?>', '<?= htmlspecialchars($sub['type']) ?>', '<?= htmlspecialchars(addslashes($sub['content'])) ?>')">
|
||||
✏️
|
||||
</button>
|
||||
|
||||
<form action="index.php?page=view_blocknote&id=<?= urlencode($blocknote_id) ?>" method="POST" onsubmit="return confirm('<?= htmlspecialchars(addslashes(__('confirm_delete_subnote'))) ?>');" style="display:inline;">
|
||||
<input type="hidden" name="action" value="delete_subnote">
|
||||
<input type="hidden" name="note_id" value="<?= htmlspecialchars($note['id']) ?>">
|
||||
<input type="hidden" name="sub_id" value="<?= htmlspecialchars($sub['id']) ?>">
|
||||
<button type="submit" class="btn btn-sm btn-danger" title="<?= __('btn_delete') ?>">
|
||||
🗑️
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Content rendering depending on type -->
|
||||
<?php if ($sub['type'] === 'command'): ?>
|
||||
<div class="command-block-wrapper">
|
||||
<div class="command-block-header">
|
||||
<span class="command-badge-title">⚡ <?= __('badge_command') ?></span>
|
||||
<button class="copy-btn" onclick="copyToClipboard(this, <?= htmlspecialchars(json_encode($sub['content'])) ?>)" data-copy-text="<?= htmlspecialchars(__('btn_copy')) ?>" data-copied-text="<?= htmlspecialchars(__('btn_copied')) ?>">
|
||||
<?= __('btn_copy') ?>
|
||||
</button>
|
||||
</div>
|
||||
<pre class="command-content-code"><code><?= htmlspecialchars($sub['content']) ?></code></pre>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="subnote-content-text">
|
||||
<?= nl2br(htmlspecialchars($sub['content'])) ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</main>
|
||||
|
||||
<!-- MODAL AGGIUNGI NOTA -->
|
||||
<div class="modal-backdrop" id="modal-add-note">
|
||||
<div class="modal-card">
|
||||
<div class="modal-header">
|
||||
<h3><?= __('modal_add_note') ?></h3>
|
||||
<button class="modal-close-btn">×</button>
|
||||
</div>
|
||||
<form action="index.php?page=view_blocknote&id=<?= urlencode($blocknote_id) ?>" method="POST">
|
||||
<input type="hidden" name="action" value="add_note">
|
||||
<div class="form-group">
|
||||
<label for="note_title"><?= __('label_title') ?></label>
|
||||
<input type="text" name="title" id="note_title" class="form-control" required placeholder="<?= htmlspecialchars(__('placeholder_note_title')) ?>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="note_description"><?= __('label_note_description') ?></label>
|
||||
<textarea name="description" id="note_description" class="form-control" placeholder="<?= htmlspecialchars(__('placeholder_note_desc')) ?>"></textarea>
|
||||
</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 MODIFICA NOTA -->
|
||||
<div class="modal-backdrop" id="modal-edit-note">
|
||||
<div class="modal-card">
|
||||
<div class="modal-header">
|
||||
<h3><?= __('modal_edit_note') ?></h3>
|
||||
<button class="modal-close-btn">×</button>
|
||||
</div>
|
||||
<form action="index.php?page=view_blocknote&id=<?= urlencode($blocknote_id) ?>" method="POST">
|
||||
<input type="hidden" name="action" value="edit_note">
|
||||
<input type="hidden" name="note_id" id="edit_note_id">
|
||||
<div class="form-group">
|
||||
<label for="edit_note_title"><?= __('label_title') ?></label>
|
||||
<input type="text" name="title" id="edit_note_title" class="form-control" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="edit_note_description"><?= __('label_note_description') ?></label>
|
||||
<textarea name="description" id="edit_note_description" class="form-control"></textarea>
|
||||
</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>
|
||||
|
||||
<!-- MODAL AGGIUNGI SOTTONOTA -->
|
||||
<div class="modal-backdrop" id="modal-add-subnote">
|
||||
<div class="modal-card">
|
||||
<div class="modal-header">
|
||||
<h3><?= __('modal_add_subnote') ?></h3>
|
||||
<button class="modal-close-btn">×</button>
|
||||
</div>
|
||||
<form action="index.php?page=view_blocknote&id=<?= urlencode($blocknote_id) ?>" method="POST">
|
||||
<input type="hidden" name="action" value="add_subnote">
|
||||
<input type="hidden" name="note_id" id="add_subnote_parent_id">
|
||||
|
||||
<div class="form-group">
|
||||
<label><?= __('note_single') ?></label>
|
||||
<input type="text" id="add_subnote_parent_name" class="form-control" disabled style="opacity: 0.7;">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="sub_title"><?= __('label_subnote_title') ?></label>
|
||||
<input type="text" name="sub_title" id="sub_title" class="form-control" required placeholder="<?= htmlspecialchars(__('placeholder_subnote_title')) ?>">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="sub_type"><?= __('label_subnote_type') ?></label>
|
||||
<select name="type" id="sub_type" class="form-control">
|
||||
<option value="text"><?= __('type_option_text') ?></option>
|
||||
<option value="command"><?= __('type_option_command') ?></option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="sub_content"><?= __('label_subnote_content') ?></label>
|
||||
<textarea name="content" id="sub_content" class="form-control" style="min-height: 120px; font-family: monospace;" required placeholder="<?= htmlspecialchars(__('placeholder_subnote_content')) ?>"></textarea>
|
||||
</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 MODIFICA SOTTONOTA -->
|
||||
<div class="modal-backdrop" id="modal-edit-subnote">
|
||||
<div class="modal-card">
|
||||
<div class="modal-header">
|
||||
<h3><?= __('modal_edit_subnote') ?></h3>
|
||||
<button class="modal-close-btn">×</button>
|
||||
</div>
|
||||
<form action="index.php?page=view_blocknote&id=<?= urlencode($blocknote_id) ?>" method="POST">
|
||||
<input type="hidden" name="action" value="edit_subnote">
|
||||
<input type="hidden" name="note_id" id="edit_subnote_parent_id">
|
||||
<input type="hidden" name="sub_id" id="edit_subnote_id">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="edit_sub_title"><?= __('label_subnote_title') ?></label>
|
||||
<input type="text" name="sub_title" id="edit_sub_title" class="form-control" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="edit_sub_type"><?= __('label_subnote_type') ?></label>
|
||||
<select name="type" id="edit_sub_type" class="form-control">
|
||||
<option value="text"><?= __('type_option_text') ?></option>
|
||||
<option value="command"><?= __('type_option_command') ?></option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="edit_sub_content"><?= __('label_subnote_content') ?></label>
|
||||
<textarea name="content" id="edit_sub_content" class="form-control" style="min-height: 120px; font-family: monospace;" required></textarea>
|
||||
</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 openEditNoteModal(noteId, currentTitle, currentDesc) {
|
||||
document.getElementById('edit_note_id').value = noteId;
|
||||
document.getElementById('edit_note_title').value = currentTitle;
|
||||
document.getElementById('edit_note_description').value = currentDesc;
|
||||
document.getElementById('modal-edit-note').classList.add('active');
|
||||
}
|
||||
|
||||
function openAddSubnoteModal(noteId, noteTitle) {
|
||||
document.getElementById('add_subnote_parent_id').value = noteId;
|
||||
document.getElementById('add_subnote_parent_name').value = noteTitle;
|
||||
document.getElementById('modal-add-subnote').classList.add('active');
|
||||
}
|
||||
|
||||
function openEditSubnoteModal(noteId, subId, title, type, content) {
|
||||
document.getElementById('edit_subnote_parent_id').value = noteId;
|
||||
document.getElementById('edit_subnote_id').value = subId;
|
||||
document.getElementById('edit_sub_title').value = title;
|
||||
document.getElementById('edit_sub_type').value = type;
|
||||
document.getElementById('edit_sub_content').value = content;
|
||||
document.getElementById('modal-edit-subnote').classList.add('active');
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user