diff --git a/notification_system/backend/config/db.js b/notification_system/backend/config/db.js new file mode 100644 index 0000000..f5b072b --- /dev/null +++ b/notification_system/backend/config/db.js @@ -0,0 +1,16 @@ +const mongoose = require('mongoose'); + +const connectDB = async () => { + try { + await mongoose.connect(process.env.MONGO_URI, { + useNewUrlParser: true, + useUnifiedTopology: true, + }); + console.log('MongoDB Connected'); + } catch (error) { + console.error(error.message); + process.exit(1); + } +}; + +module.exports = connectDB; diff --git a/notification_system/backend/controllers/notificationController.js b/notification_system/backend/controllers/notificationController.js new file mode 100644 index 0000000..1f09782 --- /dev/null +++ b/notification_system/backend/controllers/notificationController.js @@ -0,0 +1,31 @@ +const Notification = require('../models/Notification'); +const User = require('../models/User'); +const io = require('../server'); + +// Create new notification +const sendNotification = async (req, res) => { + const { userId, title, message, type } = req.body; + + const notification = new Notification({ + userId, + title, + message, + type, + }); + + await notification.save(); + + // Emit real-time notification to user via Socket.io + io.to(userId).emit('notification', { title, message, type }); + + res.status(201).json({ message: 'Notification sent successfully' }); +}; + +// Get notifications for user +const getUserNotifications = async (req, res) => { + const userId = req.params.userId; + const notifications = await Notification.find({ userId }); + res.json(notifications); +}; + +module.exports = { sendNotification, getUserNotifications }; diff --git a/notification_system/backend/models/Notification.js b/notification_system/backend/models/Notification.js new file mode 100644 index 0000000..9c93254 --- /dev/null +++ b/notification_system/backend/models/Notification.js @@ -0,0 +1,14 @@ +const mongoose = require('mongoose'); + +const notificationSchema = new mongoose.Schema({ + userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }, + title: String, + message: String, + type: String, + read: { type: Boolean, default: false }, + createdAt: { type: Date, default: Date.now }, +}); + +const Notification = mongoose.model('Notification', notificationSchema); + +module.exports = Notification; diff --git a/notification_system/backend/models/User.js b/notification_system/backend/models/User.js new file mode 100644 index 0000000..28223b8 --- /dev/null +++ b/notification_system/backend/models/User.js @@ -0,0 +1,13 @@ +const mongoose = require('mongoose'); + +const userSchema = new mongoose.Schema({ + email: String, + notificationPreferences: { + type: Map, + of: Boolean, // Preferences for notifications like 'events', 'updates', etc. + }, +}); + +const User = mongoose.model('User', userSchema); + +module.exports = User; diff --git a/notification_system/backend/package.json b/notification_system/backend/package.json new file mode 100644 index 0000000..27fc53f --- /dev/null +++ b/notification_system/backend/package.json @@ -0,0 +1,26 @@ +{ + "name": "notification-backend", + "version": "1.0.0", + "description": "Notification system backend with Node.js, Express, Socket.io, MongoDB, and Nodemailer", + "main": "server.js", + "scripts": { + "start": "node server.js", + "dev": "nodemon server.js" + }, + "dependencies": { + "express": "^4.18.1", + "mongoose": "^6.0.0", + "nodemailer": "^6.7.2", + "socket.io": "^4.4.1", + "dotenv": "^16.0.1" + }, + "devDependencies": { + "nodemon": "^2.0.15" + }, + "engines": { + "node": ">=14.0.0" + }, + "author": "Your Name", + "license": "ISC" + } + \ No newline at end of file diff --git a/notification_system/backend/routes/notificationRoutes.js b/notification_system/backend/routes/notificationRoutes.js new file mode 100644 index 0000000..f874109 --- /dev/null +++ b/notification_system/backend/routes/notificationRoutes.js @@ -0,0 +1,11 @@ +const express = require('express'); +const { sendNotification, getUserNotifications } = require('../controllers/notificationController'); +const router = express.Router(); + +// POST route to send a notification +router.post('/send', sendNotification); + +// GET route to fetch user notifications +router.get('/:userId', getUserNotifications); + +module.exports = router; diff --git a/notification_system/backend/routes/userRoutes.js b/notification_system/backend/routes/userRoutes.js new file mode 100644 index 0000000..0d9d223 --- /dev/null +++ b/notification_system/backend/routes/userRoutes.js @@ -0,0 +1,14 @@ +const express = require('express'); +const User = require('../models/User'); +const router = express.Router(); + +// Update user notification preferences +router.put('/:userId/preferences', async (req, res) => { + const { userId } = req.params; + const preferences = req.body; + + await User.findByIdAndUpdate(userId, { notificationPreferences: preferences }); + res.json({ message: 'Preferences updated successfully' }); +}); + +module.exports = router; diff --git a/notification_system/backend/server.js b/notification_system/backend/server.js new file mode 100644 index 0000000..229a585 --- /dev/null +++ b/notification_system/backend/server.js @@ -0,0 +1,34 @@ +const express = require('express'); +const http = require('http'); +const { Server } = require('socket.io'); +const connectDB = require('./config/db'); +const notificationRoutes = require('./routes/notificationRoutes'); +const userRoutes = require('./routes/userRoutes'); + +const app = express(); +const server = http.createServer(app); +const io = new Server(server); + +app.use(express.json()); + +// Connect to MongoDB +connectDB(); + +// Use routes +app.use('/api/notifications', notificationRoutes); +app.use('/api/users', userRoutes); + +// Socket.io setup +io.on('connection', (socket) => { + console.log('User connected'); + + socket.on('disconnect', () => { + console.log('User disconnected'); + }); +}); + +const PORT = process.env.PORT || 5000; +server.listen(PORT, () => console.log(`Server running on port ${PORT}`)); + +module.exports = io; + diff --git a/notification_system/backend/services/emailServices.js b/notification_system/backend/services/emailServices.js new file mode 100644 index 0000000..3d856d1 --- /dev/null +++ b/notification_system/backend/services/emailServices.js @@ -0,0 +1,22 @@ +const nodemailer = require('nodemailer'); + +const sendEmail = async (email, subject, text) => { + let transporter = nodemailer.createTransport({ + service: 'Gmail', + auth: { + user: process.env.EMAIL_USER, + pass: process.env.EMAIL_PASS, + }, + }); + + let mailOptions = { + from: process.env.EMAIL_USER, + to: email, + subject, + text, + }; + + await transporter.sendMail(mailOptions); +}; + +module.exports = sendEmail; diff --git a/notification_system/frontend/package.json b/notification_system/frontend/package.json new file mode 100644 index 0000000..3d77651 --- /dev/null +++ b/notification_system/frontend/package.json @@ -0,0 +1,37 @@ +{ + "name": "notification-frontend", + "version": "1.0.0", + "private": true, + "dependencies": { + "axios": "^0.27.2", + "react": "^18.0.0", + "react-dom": "^18.0.0", + "react-scripts": "5.0.0", + "socket.io-client": "^4.5.1" + }, + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test", + "eject": "react-scripts eject" + }, + "eslintConfig": { + "extends": [ + "react-app", + "react-app/jest" + ] + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + } + } + \ No newline at end of file diff --git a/notification_system/frontend/public/service-worker.js b/notification_system/frontend/public/service-worker.js new file mode 100644 index 0000000..02fd72c --- /dev/null +++ b/notification_system/frontend/public/service-worker.js @@ -0,0 +1,9 @@ +self.addEventListener('push', function (event) { + const data = event.data.json(); + event.waitUntil( + self.registration.showNotification(data.title, { + body: data.message, + }) + ); + }); + \ No newline at end of file diff --git a/notification_system/frontend/src/app.js b/notification_system/frontend/src/app.js new file mode 100644 index 0000000..6c5401d --- /dev/null +++ b/notification_system/frontend/src/app.js @@ -0,0 +1,21 @@ +import React from 'react'; +import NotificationCenter from './components/NotificationCenter'; +import NotificationSettings from './components/NotificationSettings'; + +function App() { + const userId = 'USER_ID'; // Replace with actual user ID logic from auth + + return ( +