feat: add dev tools page and update sidebar toggle and team mood dashboard UI
This commit is contained in:
@@ -91,6 +91,14 @@ if($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
else notify_group($parts[1], $msg);
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($_POST['remove_note_share'])) {
|
||||
$share_id = (int)$_POST['share_id'];
|
||||
$chk = query("SELECT ns.id FROM note_shares ns JOIN notes n ON ns.note_id=n.id WHERE ns.id=? AND n.owner_id=?", [$share_id, $user_id])->fetch();
|
||||
if($chk) {
|
||||
$pdo->prepare("DELETE FROM note_shares WHERE id=?")->execute([$share_id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Fetch Notes ───────────────────────────────────────────────────────────────
|
||||
@@ -287,7 +295,8 @@ $note_colors = [
|
||||
|
||||
<!-- Share section (only for owner) -->
|
||||
<div id="edit-share-section" style="border-top:1px solid var(--border); padding-top:0.75rem; margin-top:0.5rem;">
|
||||
<label style="font-size:0.8rem; color:var(--text-light); margin-bottom:0.4rem; display:block;">Share this note</label>
|
||||
<label style="font-size:0.8rem; color:var(--text-light); margin-bottom:0.4rem; display:block;">Shared with</label>
|
||||
<div id="note-shares-list" style="display:flex; flex-wrap:wrap; gap:0.35rem; margin-bottom:0.75rem;"></div>
|
||||
<div style="display:flex; gap:0.5rem; flex-wrap:wrap;">
|
||||
<select name="share_target" id="edit-share-target" class="form-control" style="flex:1; min-width:150px; padding:0.4rem;">
|
||||
<?php foreach($all_users as $u): ?>
|
||||
@@ -327,6 +336,11 @@ $note_colors = [
|
||||
<input type="hidden" name="share_target" id="share-note-standalone-target">
|
||||
</form>
|
||||
|
||||
<form method="POST" id="remove-note-share-form" style="display:none;">
|
||||
<input type="hidden" name="remove_note_share" value="1">
|
||||
<input type="hidden" name="share_id" id="remove-note-share-id">
|
||||
</form>
|
||||
|
||||
<!-- Markdown Libs -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
||||
|
||||
@@ -343,6 +357,11 @@ $note_colors = [
|
||||
$bg = $n['color'] ?: 'var(--surface)';
|
||||
$preview = strip_tags(isset($n['content']) ? (function_exists('marked') ? $n['content'] : $n['content']) : '');
|
||||
$preview = mb_substr($preview, 0, 120) . (mb_strlen($preview) > 120 ? '...' : '');
|
||||
$note_shares = [];
|
||||
if($n['is_mine']) {
|
||||
$note_shares = query("SELECT ns.id, ns.share_type, ns.share_id, u.username, g.name as gname FROM note_shares ns LEFT JOIN users u ON (ns.share_type='user' AND ns.share_id=u.id) LEFT JOIN groups g ON (ns.share_type='group' AND ns.share_id=g.id) WHERE ns.note_id=?", [$n['id']])->fetchAll();
|
||||
}
|
||||
$shares_json = htmlspecialchars(json_encode($note_shares), ENT_QUOTES, 'UTF-8');
|
||||
?>
|
||||
<div class="note-card note-filter-item"
|
||||
style="background:<?= htmlspecialchars($bg) ?>;"
|
||||
@@ -353,6 +372,7 @@ $note_colors = [
|
||||
data-label-raw="<?= htmlspecialchars(trim((string)($n['label_name'] ?? ''))) ?>"
|
||||
data-color="<?= htmlspecialchars((string)$n['color']) ?>"
|
||||
data-image="<?= htmlspecialchars((string)($n['image_path'] ?? '')) ?>"
|
||||
data-shares="<?= $shares_json ?>"
|
||||
data-mine="<?= $n['is_mine'] ?>"
|
||||
onclick="openNote(this)">
|
||||
<?php if($n['image_path'] && file_exists($n['image_path'])): ?>
|
||||
@@ -479,6 +499,9 @@ function openNote(card) {
|
||||
|
||||
// Share section
|
||||
document.getElementById('edit-share-section').style.display = isMine ? 'block' : 'none';
|
||||
if(isMine) {
|
||||
renderNoteShares(card.dataset.shares || '[]');
|
||||
}
|
||||
|
||||
// Wire up share button
|
||||
const shareBtn = document.querySelector('#edit-note-form button[name="share_note"]');
|
||||
@@ -495,6 +518,35 @@ function openNote(card) {
|
||||
document.getElementById('edit-note-modal').classList.add('active');
|
||||
}
|
||||
|
||||
function renderNoteShares(jsonShares) {
|
||||
const list = document.getElementById('note-shares-list');
|
||||
list.innerHTML = '';
|
||||
let shares = [];
|
||||
try { shares = JSON.parse(jsonShares || '[]'); } catch(e) { shares = []; }
|
||||
if(shares.length === 0) return;
|
||||
shares.forEach(sh => {
|
||||
const label = sh.share_type === 'user' ? ('👤 ' + (sh.username || 'User')) : ('👥 ' + (sh.gname || 'Group'));
|
||||
const chip = document.createElement('div');
|
||||
chip.style.display = 'inline-flex';
|
||||
chip.style.alignItems = 'center';
|
||||
chip.style.gap = '0.35rem';
|
||||
chip.style.fontSize = '0.72rem';
|
||||
chip.style.padding = '3px 7px';
|
||||
chip.style.borderRadius = '999px';
|
||||
chip.style.background = 'rgba(var(--primary-rgb),0.12)';
|
||||
chip.style.color = 'var(--primary)';
|
||||
chip.innerHTML = `<span>${label}</span><button type="button" style="border:none;background:transparent;color:inherit;cursor:pointer;line-height:1;" title="Unshare" onclick="removeNoteShare(${Number(sh.id)})">×</button>`;
|
||||
list.appendChild(chip);
|
||||
});
|
||||
}
|
||||
|
||||
function removeNoteShare(shareId) {
|
||||
if(!shareId) return;
|
||||
if(!confirm('Unshare this note access?')) return;
|
||||
document.getElementById('remove-note-share-id').value = String(shareId);
|
||||
document.getElementById('remove-note-share-form').submit();
|
||||
}
|
||||
|
||||
function filterNotes() {
|
||||
const q = (document.getElementById('notes-search-input')?.value || '').toLowerCase().trim();
|
||||
const lbl = (document.getElementById('notes-label-filter')?.value || '').trim();
|
||||
|
||||
Reference in New Issue
Block a user