Skip to content

Commit

Permalink
Merge pull request #327 from snehas-05/main
Browse files Browse the repository at this point in the history
closes : #302
  • Loading branch information
dhairyagothi authored Oct 20, 2024
2 parents a7b4eaf + cae786d commit fcdccfb
Show file tree
Hide file tree
Showing 15 changed files with 353 additions and 0 deletions.
16 changes: 16 additions & 0 deletions notification_system/backend/config/db.js
Original file line number Diff line number Diff line change
@@ -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;
31 changes: 31 additions & 0 deletions notification_system/backend/controllers/notificationController.js
Original file line number Diff line number Diff line change
@@ -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 };
14 changes: 14 additions & 0 deletions notification_system/backend/models/Notification.js
Original file line number Diff line number Diff line change
@@ -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;
13 changes: 13 additions & 0 deletions notification_system/backend/models/User.js
Original file line number Diff line number Diff line change
@@ -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;
26 changes: 26 additions & 0 deletions notification_system/backend/package.json
Original file line number Diff line number Diff line change
@@ -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"
}

11 changes: 11 additions & 0 deletions notification_system/backend/routes/notificationRoutes.js
Original file line number Diff line number Diff line change
@@ -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;
14 changes: 14 additions & 0 deletions notification_system/backend/routes/userRoutes.js
Original file line number Diff line number Diff line change
@@ -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;
34 changes: 34 additions & 0 deletions notification_system/backend/server.js
Original file line number Diff line number Diff line change
@@ -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;

22 changes: 22 additions & 0 deletions notification_system/backend/services/emailServices.js
Original file line number Diff line number Diff line change
@@ -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;
37 changes: 37 additions & 0 deletions notification_system/frontend/package.json
Original file line number Diff line number Diff line change
@@ -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"
]
}
}

9 changes: 9 additions & 0 deletions notification_system/frontend/public/service-worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
self.addEventListener('push', function (event) {
const data = event.data.json();
event.waitUntil(
self.registration.showNotification(data.title, {
body: data.message,
})
);
});

21 changes: 21 additions & 0 deletions notification_system/frontend/src/app.js
Original file line number Diff line number Diff line change
@@ -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 (
<div className="App">
<h1>Welcome to the Notification System</h1>

{/* Notification Center Component */}
<NotificationCenter userId={userId} />

{/* Notification Settings Component */}
<NotificationSettings userId={userId} />
</div>
);
}

export default App;
41 changes: 41 additions & 0 deletions notification_system/frontend/src/components/NotificationCentre.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React, { useEffect, useState } from 'react';
import axios from 'axios';
import { io } from 'socket.io-client';

const NotificationCenter = ({ userId }) => {
const [notifications, setNotifications] = useState([]);

useEffect(() => {
// Fetch notifications from API
const fetchNotifications = async () => {
const { data } = await axios.get(`/api/notifications/${userId}`);
setNotifications(data);
};

fetchNotifications();

// Socket.io connection for real-time notifications
const socket = io();

socket.on('notification', (notification) => {
setNotifications((prev) => [...prev, notification]);
});

return () => socket.disconnect();
}, [userId]);

return (
<div>
<h2>Notification Center</h2>
<ul>
{notifications.map((notification) => (
<li key={notification._id}>
<strong>{notification.title}</strong>: {notification.message}
</li>
))}
</ul>
</div>
);
};

export default NotificationCenter;
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React, { useState, useEffect } from 'react';
import axios from 'axios';

const NotificationSettings = ({ userId }) => {
const [preferences, setPreferences] = useState({
events: true,
updates: true,
});

useEffect(() => {
// Fetch user preferences from the backend
const fetchPreferences = async () => {
const { data } = await axios.get(`/api/users/${userId}/preferences`);
setPreferences(data.notificationPreferences);
};

fetchPreferences();
}, [userId]);

const handleSave = async () => {
await axios.put(`/api/users/${userId}/preferences`, preferences);
alert('Preferences saved');
};

return (
<div>
<h2>Notification Settings</h2>
<label>
<input
type="checkbox"
checked={preferences.events}
onChange={(e) => setPreferences({ ...preferences, events: e.target.checked })}
/>
Events
</label>
<label>
<input
type="checkbox"
checked={preferences.updates}
onChange={(e) => setPreferences({ ...preferences, updates: e.target.checked })}
/>
Updates
</label>
<button onClick={handleSave}>Save</button>
</div>
);
};

export default NotificationSettings;
15 changes: 15 additions & 0 deletions notification_system/frontend/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';

// Register service worker for push notifications
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js').then((registration) => {
console.log('Service worker registered:', registration);
}).catch((error) => {
console.log('Service worker registration failed:', error);
});
}

ReactDOM.render(<App />, document.getElementById('root'));

0 comments on commit fcdccfb

Please sign in to comment.