diff --git a/backend/src/tools/whiteboard/routes.js b/backend/src/tools/whiteboard/routes.js index 1820c1b..8752cc7 100644 --- a/backend/src/tools/whiteboard/routes.js +++ b/backend/src/tools/whiteboard/routes.js @@ -125,7 +125,7 @@ router.get('/users-list', authenticate, (req, res) => { }); // ── Berechtigungen setzen ───────────────────────────────────────────────────── -router.put('/:id/permissions', authenticate, (req, res) => { +router.put('/:id/permissions', authenticate, async (req, res) => { const me = uid(req); const wb = db.prepare('SELECT * FROM whiteboards WHERE id=?').get(req.params.id); if (!wb) return res.status(404).json({ error: 'Nicht gefunden' }); @@ -133,16 +133,41 @@ router.put('/:id/permissions', authenticate, (req, res) => { const { permissions } = req.body; // [{user_id, role: 'edit'|'view'|null}] if (!Array.isArray(permissions)) return res.status(400).json({ error: 'permissions fehlt' }); - const upsert = db.prepare("INSERT INTO whiteboard_permissions (whiteboard_id,user_id,role) VALUES (?,?,?) ON CONFLICT(whiteboard_id,user_id) DO UPDATE SET role=excluded.role"); - const remove = db.prepare("DELETE FROM whiteboard_permissions WHERE whiteboard_id=? AND user_id=?"); - const tx = db.transaction(() => { + // Vorherigen Stand merken um neue User zu erkennen + const before = db.prepare('SELECT user_id FROM whiteboard_permissions WHERE whiteboard_id=?').all(req.params.id).map(r => r.user_id); + + const upsert = db.prepare("INSERT INTO whiteboard_permissions (whiteboard_id,user_id,role) VALUES (?,?,?) ON CONFLICT(whiteboard_id,user_id) DO UPDATE SET role=excluded.role"); + const remove = db.prepare("DELETE FROM whiteboard_permissions WHERE whiteboard_id=? AND user_id=?"); + db.transaction(() => { for (const p of permissions) { if (!p.user_id) continue; if (p.role === null || p.role === 'none') remove.run(req.params.id, p.user_id); else upsert.run(req.params.id, p.user_id, p.role); } - }); - tx(); + })(); + + // Pushover an neu hinzugekommene User (fire & forget) + const owner = db.prepare('SELECT username FROM users WHERE id=?').get(me); + const newlyAdded = permissions.filter(p => p.role && p.role !== 'none' && !before.includes(p.user_id)); + for (const p of newlyAdded) { + try { + const poCfg = db.prepare('SELECT user_key, app_token FROM pushover_settings WHERE user_id=?').get(p.user_id); + if (!poCfg?.app_token || !poCfg?.user_key) continue; + const roleLabel = p.role === 'edit' ? 'bearbeiten' : 'ansehen'; + fetch('https://api.pushover.net/1/messages.json', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + token: poCfg.app_token, + user: poCfg.user_key, + title: '🖊 Whiteboard geteilt', + message: `${owner.username} hat das Whiteboard "${wb.title}" mit dir geteilt (${roleLabel}).`, + priority: 0, + }), + }).catch(() => {}); + } catch {} + } + const updated = db.prepare(` SELECT p.*, u.username FROM whiteboard_permissions p JOIN users u ON u.id=p.user_id WHERE p.whiteboard_id=? diff --git a/frontend/src/tools/whiteboard.jsx b/frontend/src/tools/whiteboard.jsx index 9d6d894..5a5523a 100644 --- a/frontend/src/tools/whiteboard.jsx +++ b/frontend/src/tools/whiteboard.jsx @@ -186,6 +186,8 @@ export default function Whiteboard({ toast, mobile }) { const [boards, setBoards] = useState([]); const [loading, setLoading] = useState(true); const [current, setCurrent] = useState(null); // { id, title, role } + const [creating, setCreating] = useState(false); + const [newTitle, setNewTitle] = useState(''); // ── Canvas-State ────────────────────────────────────────────────────────── const [elements, setElements] = useState([]); @@ -516,12 +518,36 @@ export default function Whiteboard({ toast, mobile }) { WHITEBOARD
- + {creating ? ( +