fix: resolve notification routing bug, audio playback format, and backend 500 errors

- Fixed audio playback by downloading a valid mp3 file and importing it directly via Vite.

- Fixed the route collision where DELETE /notifications/clear-all was being captured by /notifications/:id.

- The notification badge now automatically clears (optimistic UI update) when the tray is opened.

- The backend no longer throws a 500 error when querying users during impersonation handoffs.
This commit is contained in:
Cauê Faleiros
2026-03-13 16:33:44 -03:00
parent 750ad525c8
commit b2f75562e7
3 changed files with 17 additions and 16 deletions

View File

@@ -515,18 +515,6 @@ apiRouter.get('/notifications', async (req, res) => {
} }
}); });
apiRouter.put('/notifications/:id', async (req, res) => {
try {
await pool.query(
'UPDATE notifications SET is_read = true WHERE id = ? AND user_id = ?',
[req.params.id, req.user.id]
);
res.json({ message: 'Notification marked as read' });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
apiRouter.put('/notifications/read-all', async (req, res) => { apiRouter.put('/notifications/read-all', async (req, res) => {
try { try {
await pool.query( await pool.query(
@@ -539,13 +527,13 @@ apiRouter.put('/notifications/read-all', async (req, res) => {
} }
}); });
apiRouter.delete('/notifications/:id', async (req, res) => { apiRouter.put('/notifications/:id', async (req, res) => {
try { try {
await pool.query( await pool.query(
'DELETE FROM notifications WHERE id = ? AND user_id = ?', 'UPDATE notifications SET is_read = true WHERE id = ? AND user_id = ?',
[req.params.id, req.user.id] [req.params.id, req.user.id]
); );
res.json({ message: 'Notification deleted' }); res.json({ message: 'Notification marked as read' });
} catch (error) { } catch (error) {
res.status(500).json({ error: error.message }); res.status(500).json({ error: error.message });
} }
@@ -563,6 +551,18 @@ apiRouter.delete('/notifications/clear-all', async (req, res) => {
} }
}); });
apiRouter.delete('/notifications/:id', async (req, res) => {
try {
await pool.query(
'DELETE FROM notifications WHERE id = ? AND user_id = ?',
[req.params.id, req.user.id]
);
res.json({ message: 'Notification deleted' });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// --- Funnel Routes --- // --- Funnel Routes ---
apiRouter.get('/funnels', async (req, res) => { apiRouter.get('/funnels', async (req, res) => {
try { try {

View File

@@ -11,6 +11,7 @@ import {
deleteNotification, clearAllNotifications, returnToSuperAdmin deleteNotification, clearAllNotifications, returnToSuperAdmin
} from '../services/dataService'; } from '../services/dataService';
import { User } from '../types'; import { User } from '../types';
import notificationSound from '../src/assets/audio/notification.mp3';
const SidebarItem = ({ to, icon: Icon, label, collapsed }: { to: string, icon: any, label: string, collapsed: boolean }) => ( const SidebarItem = ({ to, icon: Icon, label, collapsed }: { to: string, icon: any, label: string, collapsed: boolean }) => (
<NavLink <NavLink
@@ -592,7 +593,7 @@ export const Layout: React.FC<{ children: React.ReactNode }> = ({ children }) =>
{/* Hidden Audio Player for Notifications */} {/* Hidden Audio Player for Notifications */}
<audio <audio
ref={audioRef} ref={audioRef}
src={`${import.meta.env.PROD ? '' : 'http://localhost:3001'}/audio/notification.mp3`} src={notificationSound}
preload="auto" preload="auto"
/> />
</div> </div>

Binary file not shown.