Files
adopt-a-street/frontend/src/App.js
William Valentin a2d30385b5 feat: implement real-time notification toast system
Implemented comprehensive notification toast system integrating Socket.IO
with react-toastify for real-time user notifications.

Features:
- NotificationProvider component for automatic Socket.IO event handling
- Custom Bootstrap-themed toast styles with mobile responsiveness
- Four toast types: success, error, info, warning
- Auto-dismiss after 5 seconds with manual dismiss option
- Duplicate prevention using toast IDs
- Mobile-optimized full-width toasts
- Dark mode support
- 16 passing tests with full coverage

Toast notifications for:
- Connection status (connect/disconnect/reconnect)
- Event updates (new, updated, deleted, participants)
- Task updates (new, completed, updated, deleted)
- Street adoptions/unadoptions
- Achievement unlocks and badge awards
- Social updates (new posts, comments)
- Generic notifications with type-based styling

Usage:
import { notify } from '../context/NotificationProvider';
notify.success('Operation completed!');
notify.error('Something went wrong!');

Configuration:
- Position: top-right (configurable)
- Auto-close: 5 seconds (configurable)
- Max toasts: 5 concurrent
- Mobile responsive: full-width on ≤480px screens

Documentation:
- NOTIFICATION_SYSTEM.md: Complete usage guide
- NOTIFICATION_IMPLEMENTATION.md: Implementation summary
- frontend/src/examples/notificationExamples.js: Code examples

Co-Authored-By: AI Assistant <noreply@ai-assistant.com>
2025-11-03 13:20:15 -08:00

64 lines
2.4 KiB
JavaScript

import React from "react";
import { BrowserRouter as Router, Routes, Route, Navigate } from "react-router-dom";
import { ToastContainer } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import "./styles/toastStyles.css";
import AuthProvider from "./context/AuthContext";
import SocketProvider from "./context/SocketContext";
import NotificationProvider from "./context/NotificationProvider";
import Login from "./components/Login";
import Register from "./components/Register";
import MapView from "./components/MapView";
import TaskList from "./components/TaskList";
import SocialFeed from "./components/SocialFeed";
import Profile from "./components/Profile";
import Events from "./components/Events";
import Rewards from "./components/Rewards";
import Premium from "./components/Premium";
import Navbar from "./components/Navbar";
import PrivateRoute from "./components/PrivateRoute";
function App() {
return (
<AuthProvider>
<SocketProvider>
<NotificationProvider>
<Router>
<Navbar />
<div className="container">
<Routes>
<Route path="/login" element={<Login />} />
<Route path="/register" element={<Register />} />
<Route path="/map" element={<PrivateRoute><MapView /></PrivateRoute>} />
<Route path="/tasks" element={<PrivateRoute><TaskList /></PrivateRoute>} />
<Route path="/feed" element={<PrivateRoute><SocialFeed /></PrivateRoute>} />
<Route path="/profile" element={<PrivateRoute><Profile /></PrivateRoute>} />
<Route path="/events" element={<PrivateRoute><Events /></PrivateRoute>} />
<Route path="/rewards" element={<PrivateRoute><Rewards /></PrivateRoute>} />
<Route path="/premium" element={<PrivateRoute><Premium /></PrivateRoute>} />
<Route path="/" element={<Navigate to="/map" replace />} />
</Routes>
</div>
<ToastContainer
position="top-right"
autoClose={5000}
hideProgressBar={false}
newestOnTop={true}
closeOnClick
rtl={false}
pauseOnFocusLoss
draggable
pauseOnHover
theme="light"
limit={5}
/>
</Router>
</NotificationProvider>
</SocketProvider>
</AuthProvider>
);
}
export default App;