fix: setUnackedFavs als Prop, user-notify beim Favoriten-Tab, Admin-Badge in Liste
This commit is contained in:
@@ -503,6 +503,12 @@ router.get('/favorites/all', authenticate, requireAdmin, (req, res) => {
|
|||||||
res.json(favs);
|
res.json(favs);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// POST /favorites/user-notify – User hat quittierte Favoriten gesehen
|
||||||
|
router.post('/favorites/user-notify', authenticate, (req, res) => {
|
||||||
|
db.prepare('UPDATE movie_favorites SET user_notified=1 WHERE user_id=? AND acknowledged=1 AND user_notified=0').run(req.user.id);
|
||||||
|
res.json({ ok: true });
|
||||||
|
});
|
||||||
|
|
||||||
// GET /favorites/unacked – unquittierte Zählung (Admin: neue Favoriten; User: quittierte aber unbestätigte)
|
// GET /favorites/unacked – unquittierte Zählung (Admin: neue Favoriten; User: quittierte aber unbestätigte)
|
||||||
router.get('/favorites/unacked', authenticate, (req, res) => {
|
router.get('/favorites/unacked', authenticate, (req, res) => {
|
||||||
const isAdmin = req.user.role === 'admin';
|
const isAdmin = req.user.role === 'admin';
|
||||||
@@ -511,7 +517,7 @@ router.get('/favorites/unacked', authenticate, (req, res) => {
|
|||||||
res.json({ count: count.n, isAdmin: true });
|
res.json({ count: count.n, isAdmin: true });
|
||||||
} else {
|
} else {
|
||||||
// User: Favoriten die vom Admin quittiert wurden aber User noch nicht gesehen hat
|
// User: Favoriten die vom Admin quittiert wurden aber User noch nicht gesehen hat
|
||||||
const count = db.prepare('SELECT COUNT(*) as n FROM movie_favorites WHERE user_id=? AND acknowledged=1').get(req.user.id);
|
const count = db.prepare('SELECT COUNT(*) as n FROM movie_favorites WHERE user_id=? AND acknowledged=1 AND user_notified=0').get(req.user.id);
|
||||||
res.json({ count: count.n, isAdmin: false });
|
res.json({ count: count.n, isAdmin: false });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1903,7 +1903,7 @@ function GlobalSearch({ setActive, setDevToolsNav, mobile }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function Dashboard({ toast, mobile, setActive, setDevToolsNav, unreadMsgs=0, unreadBoard=0, unreadPromoted=0, onBoardRead, unreadChangelog=0, onChangelogRead, unackedFavs, user }) {
|
function Dashboard({ toast, mobile, setActive, setDevToolsNav, unreadMsgs=0, unreadBoard=0, unreadPromoted=0, onBoardRead, unreadChangelog=0, onChangelogRead, unackedFavs, onClearUnackedFavs, user }) {
|
||||||
const [now, setNow] = useState(new Date());
|
const [now, setNow] = useState(new Date());
|
||||||
const [showBoard, setShowBoard] = useState(false);
|
const [showBoard, setShowBoard] = useState(false);
|
||||||
const [showChangelog, setShowChangelog] = useState(false);
|
const [showChangelog, setShowChangelog] = useState(false);
|
||||||
@@ -1988,7 +1988,7 @@ function Dashboard({ toast, mobile, setActive, setDevToolsNav, unreadMsgs=0, unr
|
|||||||
setActive('media');
|
setActive('media');
|
||||||
setTimeout(()=>window.dispatchEvent(new CustomEvent('media-navigate',{detail:'favoriten'})),200);
|
setTimeout(()=>window.dispatchEvent(new CustomEvent('media-navigate',{detail:'favoriten'})),200);
|
||||||
} else {
|
} else {
|
||||||
setUnackedFavs({count:0,isAdmin:false});
|
onClearUnackedFavs?.();
|
||||||
setActive('media');
|
setActive('media');
|
||||||
setTimeout(()=>window.dispatchEvent(new CustomEvent('media-navigate',{detail:'favoriten'})),200);
|
setTimeout(()=>window.dispatchEvent(new CustomEvent('media-navigate',{detail:'favoriten'})),200);
|
||||||
}
|
}
|
||||||
@@ -3734,7 +3734,7 @@ export default function App() {
|
|||||||
unreadMsgs={unreadMsgs}/>
|
unreadMsgs={unreadMsgs}/>
|
||||||
)}
|
)}
|
||||||
<main ref={mainRef} style={mainStyle}>
|
<main ref={mainRef} style={mainStyle}>
|
||||||
{active==='dashboard' && <Dashboard key={dashboardKey} toast={toast} mobile={mobile} setActive={setActive} setDevToolsNav={setDevToolsNav} unreadMsgs={unreadMsgs} unreadBoard={unreadBoard} unreadPromoted={unreadPromoted} onBoardRead={()=>{ setUnreadBoard(0); setUnreadPromoted(0); }} unreadChangelog={unreadChangelog} onChangelogRead={()=>setUnreadChangelog(0)} unackedFavs={unackedFavs} user={user}/>}
|
{active==='dashboard' && <Dashboard key={dashboardKey} toast={toast} mobile={mobile} setActive={setActive} setDevToolsNav={setDevToolsNav} unreadMsgs={unreadMsgs} unreadBoard={unreadBoard} unreadPromoted={unreadPromoted} onBoardRead={()=>{ setUnreadBoard(0); setUnreadPromoted(0); }} unreadChangelog={unreadChangelog} onChangelogRead={()=>setUnreadChangelog(0)} unackedFavs={unackedFavs} onClearUnackedFavs={()=>setUnackedFavs({count:0,isAdmin:false})} user={user}/>}
|
||||||
{active==='admin' && <AdminPanel toast={toast} mobile={mobile} user={user} nav={devToolsNav}/>}
|
{active==='admin' && <AdminPanel toast={toast} mobile={mobile} user={user} nav={devToolsNav}/>}
|
||||||
{activeTool && <activeTool.component toast={toast} mobile={mobile} setActive={setActive} {...(activeTool.id==='devtools'?{nav:devToolsNav}:{})} {...(activeTool.id==='media' ? {initTab:mediaInitTab, onInitTabConsumed:()=>setMediaInitTab(null)} : {})}/>}
|
{activeTool && <activeTool.component toast={toast} mobile={mobile} setActive={setActive} {...(activeTool.id==='devtools'?{nav:devToolsNav}:{})} {...(activeTool.id==='media' ? {initTab:mediaInitTab, onInitTabConsumed:()=>setMediaInitTab(null)} : {})}/>}
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@@ -48,6 +48,13 @@ export default function Media({ toast, mobile, initTab, onInitTabConsumed }) {
|
|||||||
window.addEventListener('media-navigate', handler);
|
window.addEventListener('media-navigate', handler);
|
||||||
return () => window.removeEventListener('media-navigate', handler);
|
return () => window.removeEventListener('media-navigate', handler);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
// Wenn Favoriten-Tab geöffnet wird → user-notify (Badge verschwindet)
|
||||||
|
useEffect(() => {
|
||||||
|
if (activeTool === 'favoriten') {
|
||||||
|
api('/tools/media/favorites/user-notify', { method:'POST', body:{} }).catch(()=>{});
|
||||||
|
}
|
||||||
|
}, [activeTool]);
|
||||||
const [modal, setModal] = useState(null); // { id, media_type }
|
const [modal, setModal] = useState(null); // { id, media_type }
|
||||||
const [xrelIds, setXrelIds] = useState(new Set()); // tmdb_ids mit bekannten Releases
|
const [xrelIds, setXrelIds] = useState(new Set()); // tmdb_ids mit bekannten Releases
|
||||||
|
|
||||||
@@ -627,11 +634,17 @@ function FavoritenKalender({ onOpenModal }) {
|
|||||||
← Meine Favoriten
|
← Meine Favoriten
|
||||||
</button>
|
</button>
|
||||||
{unacked > 0 && (
|
{unacked > 0 && (
|
||||||
<button onClick={ackAll}
|
<>
|
||||||
style={{background:'rgba(245,158,11,0.12)',border:'1px solid rgba(245,158,11,0.35)',
|
<span style={{background:'rgba(245,158,11,0.12)',border:'1px solid rgba(245,158,11,0.35)',
|
||||||
borderRadius:7,padding:'5px 12px',color:'#f59e0b',fontFamily:'monospace',fontSize:11,cursor:'pointer'}}>
|
borderRadius:7,padding:'5px 12px',color:'#f59e0b',fontFamily:'monospace',fontSize:11}}>
|
||||||
✓ Alle {unacked} quittieren
|
⚠ {unacked} unquittiert
|
||||||
</button>
|
</span>
|
||||||
|
<button onClick={ackAll}
|
||||||
|
style={{background:'rgba(74,222,128,0.12)',border:'1px solid rgba(74,222,128,0.35)',
|
||||||
|
borderRadius:7,padding:'5px 12px',color:'#4ade80',fontFamily:'monospace',fontSize:11,cursor:'pointer'}}>
|
||||||
|
✓ Alle quittieren
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{!allFavs.length
|
{!allFavs.length
|
||||||
|
|||||||
Reference in New Issue
Block a user