From cf0421c94b8ca14e819bad45e7db6875b92d547b Mon Sep 17 00:00:00 2001 From: Biswakalyan Bhuyan Date: Thu, 18 Jul 2024 15:49:21 +0530 Subject: added and setup dashboard login auth and many more --- server/config/db.js | 2 + server/models/User.js | 14 +++++-- server/routes/auth.js | 63 +++++++++++++------------------- server/server.js | 20 +++++++--- src/App.js | 21 +++++------ src/components/Dashboard.js | 83 ++++++++++++++++++++++++++++++++++++++++++ src/components/Login.js | 39 ++++++++++---------- src/components/PrivateRoute.js | 17 +++++++++ src/firebase/firebaseConfig.js | 20 +++++----- src/index.js | 16 +------- 10 files changed, 194 insertions(+), 101 deletions(-) create mode 100644 src/components/Dashboard.js create mode 100644 src/components/PrivateRoute.js diff --git a/server/config/db.js b/server/config/db.js index c1f628a..9ae3c6b 100644 --- a/server/config/db.js +++ b/server/config/db.js @@ -1,4 +1,6 @@ const mongoose = require('mongoose'); +require('dotenv').config(); + const connectDB = async () => { try { await mongoose.connect(process.env.MONGO_URI, { diff --git a/server/models/User.js b/server/models/User.js index 6773c64..968673e 100644 --- a/server/models/User.js +++ b/server/models/User.js @@ -1,7 +1,15 @@ const mongoose = require('mongoose'); + const UserSchema = new mongoose.Schema({ - username: { type: String, reauired: true, unique: true }, - password: { type: String, required: true }, - role: { type: String, default: 'admin' }, + email: { + type: String, + required: true, + unique: true, + }, + password: { + type: String, + required: true, + }, }); + module.exports = mongoose.model('User', UserSchema); diff --git a/server/routes/auth.js b/server/routes/auth.js index 3fb0986..04a9d5b 100644 --- a/server/routes/auth.js +++ b/server/routes/auth.js @@ -1,57 +1,46 @@ const express = require('express'); const bcrypt = require('bcryptjs'); -const jwt = require('jsonwebtoken'); +const jwt = require('jwt-simple'); const User = require('../models/User'); +require('dotenv').config(); + const router = express.Router(); +const secret = process.env.JWT_SECRET; -// Register +// Register new user router.post('/register', async (req, res) => { - const { username, password } = req.body; + const { email, password } = req.body; try { - let user = await User.findOne({ username }); - if (user) { - return res.status(400).json({ msg: 'User already exists' }); - } - user = new User({ - username, - password, - }); + const user = await User.findOne({ email }); + if (user) return res.status(400).json({ msg: 'User already exists' }); + + const newUser = new User({ email, password }); const salt = await bcrypt.genSalt(10); - user.password = await bcrypt.hash(password, salt); - await user.save(); - res.status(200).send('User registered'); + newUser.password = await bcrypt.hash(password, salt); + await newUser.save(); + + const payload = { id: newUser.id }; + const token = jwt.encode(payload, secret); + res.json({ token }); } catch (err) { console.error(err.message); res.status(500).send('Server error'); } }); -// Login +// Login user router.post('/login', async (req, res) => { - const { username, password } = req.body; + const { email, password } = req.body; try { - const user = await User.findOne({ username }); - if (!user) { - return res.status(400).json({ msg: 'Invalid credentials' }); - } + const user = await User.findOne({ email }); + if (!user) return res.status(400).json({ msg: 'Invalid credentials' }); + const isMatch = await bcrypt.compare(password, user.password); - if (!isMatch) { - return res.status(400).json({ msg: 'Invalid credentials' }); - } - const payload = { - user: { - id: user.id, - }, - }; - jwt.sign( - payload, - process.env.JWT_SECRET, - { expiresIn: '1h' }, - (err, token) => { - if (err) throw err; - res.json({ token }); - } - ); + if (!isMatch) return res.status(400).json({ msg: 'Invalid credentials' }); + + const payload = { id: user.id }; + const token = jwt.encode(payload, secret); + res.json({ token }); } catch (err) { console.error(err.message); res.status(500).send('Server error'); diff --git a/server/server.js b/server/server.js index caf4d9c..fcd02f6 100644 --- a/server/server.js +++ b/server/server.js @@ -1,14 +1,22 @@ const express = require('express'); -const connectDB = require('./config/db'); const cors = require('cors'); -const app = express(); +const bodyParser = require('body-parser'); +const connectDB = require('./config/db'); +const authRoutes = require('./routes/auth'); + require('dotenv').config(); -connectDB(); +const app = express(); +const PORT = process.env.PORT || 8080; + +// Middleware app.use(cors()); -app.use(express.json()); +app.use(bodyParser.json()); -app.use('/api/auth', require('./routes/auth')); +// Connect to MongoDB +connectDB(); + +// Routes +app.use('/api/auth', authRoutes); -const PORT = process.env.PORT || 8080; app.listen(PORT, () => console.log(`Server started on port ${PORT}`)); diff --git a/src/App.js b/src/App.js index ffc907d..437278a 100644 --- a/src/App.js +++ b/src/App.js @@ -1,19 +1,18 @@ -import React, { useState } from 'react'; +import React from 'react'; +import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'; import Login from './components/Login'; +import Dashboard from './components/Dashboard'; +import PrivateRoute from './components/PrivateRoute'; const App = () => { - const [isAuth, setIsAuth] = useState(false); - return ( -
- {isAuth ? : } -
+ + + + + + ); }; -const AdminPanel = () => { - // Admin panel logic - return
Admin Panel
; -}; - export default App; diff --git a/src/components/Dashboard.js b/src/components/Dashboard.js new file mode 100644 index 0000000..cb14e26 --- /dev/null +++ b/src/components/Dashboard.js @@ -0,0 +1,83 @@ +import React, { useState, useEffect } from 'react'; +import { useHistory } from 'react-router-dom'; +import { auth, firestore } from '../firebase/firebaseConfig'; +import { getStorage, ref, uploadBytes, deleteObject } from "firebase/storage"; +import { collection, getDocs, addDoc, deleteDoc, doc } from "firebase/firestore"; +import { Bar } from 'react-chartjs-2'; + +const Dashboard = () => { + const history = useHistory(); + const [ads, setAds] = useState([]); + const [views, setViews] = useState([]); + const storage = getStorage(); + const adsCollectionRef = collection(firestore, "ads"); + + useEffect(() => { + const fetchAds = async () => { + const adsSnapshot = await getDocs(adsCollectionRef); + setAds(adsSnapshot.docs.map(doc => ({ ...doc.data(), id: doc.id }))); + }; + + const fetchViews = async () => { + // Assume we have a 'views' collection to track ad views + const viewsSnapshot = await getDocs(collection(firestore, "views")); + setViews(viewsSnapshot.docs.map(doc => doc.data())); + }; + + fetchAds(); + fetchViews(); + }, []); + + const handleLogout = () => { + auth.signOut(); + localStorage.removeItem('token'); + history.push('/login'); + }; + + const handleUpload = async (event) => { + const file = event.target.files[0]; + const storageRef = ref(storage, `ads/${file.name}`); + await uploadBytes(storageRef, file); + await addDoc(adsCollectionRef, { name: file.name, url: `ads/${file.name}` }); + setAds([...ads, { name: file.name, url: `ads/${file.name}` }]); + }; + + const handleDelete = async (id, url) => { + const storageRef = ref(storage, url); + await deleteObject(storageRef); + await deleteDoc(doc(firestore, "ads", id)); + setAds(ads.filter(ad => ad.id !== id)); + }; + + const viewData = { + labels: ads.map(ad => ad.name), + datasets: [ + { + label: 'Ad Views', + data: views.map(view => view.count), + backgroundColor: 'rgba(75, 192, 192, 0.6)', + }, + ], + }; + + return ( +
+

Dashboard

+ + +
+ {ads.map(ad => ( +
+

{ad.name}

+ +
+ ))} +
+
+ +
+
+ ); +}; + +export default Dashboard; diff --git a/src/components/Login.js b/src/components/Login.js index 9a67051..64539c6 100644 --- a/src/components/Login.js +++ b/src/components/Login.js @@ -1,33 +1,32 @@ import React, { useState } from 'react'; import axios from 'axios'; +import { useHistory } from 'react-router-dom'; -const Login = ({ setAuth }) => { - const [formData, setFormData] = useState({ - username: '', - password: '', - }); +const Login = () => { + const [email, setEmail] = useState(''); + const [password, setPassword] = useState(''); + const history = useHistory(); - const { username, password } = formData; - - const onChange = (e) => setFormData({ ...formData, [e.target.name]: e.target.value }); - - const onSubmit = async (e) => { + const handleSubmit = async (e) => { e.preventDefault(); try { - const res = await axios.post('/api/auth/login', formData); - localStorage.setItem('token', res.data.token); - setAuth(true); - } catch (err) { - console.error(err.response.data); + const response = await axios.post('/api/auth/login', { email, password }); + localStorage.setItem('token', response.data.token); + history.push('/dashboard'); + } catch (error) { + console.error('Error logging in:', error); } }; return ( -
- - - -
+
+

Login

+
+ setEmail(e.target.value)} required /> + setPassword(e.target.value)} required /> + +
+
); }; diff --git a/src/components/PrivateRoute.js b/src/components/PrivateRoute.js new file mode 100644 index 0000000..1296935 --- /dev/null +++ b/src/components/PrivateRoute.js @@ -0,0 +1,17 @@ +import React from 'react'; +import { Route, Redirect } from 'react-router-dom'; + +const PrivateRoute = ({ component: Component, ...rest }) => { + const isAuthenticated = !!localStorage.getItem('token'); + + return ( + + isAuthenticated ? : + } + /> + ); +}; + +export default PrivateRoute; diff --git a/src/firebase/firebaseConfig.js b/src/firebase/firebaseConfig.js index 12f2a35..87546fd 100644 --- a/src/firebase/firebaseConfig.js +++ b/src/firebase/firebaseConfig.js @@ -1,17 +1,17 @@ import firebase from 'firebase/app'; -import 'firebase/storage'; +import 'firebase/auth'; +import 'firebase/firestore'; const firebaseConfig = { - apiKey: process.env.REACT_APP_FIREBASE_API_KEY, - authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN, - projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID, - storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET, - messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGING_SENDER_ID, - appId: process.env.REACT_APP_FIREBASE_APP_ID, + apiKey: "YOUR_API_KEY", + authDomain: "YOUR_AUTH_DOMAIN", + projectId: "YOUR_PROJECT_ID", + storageBucket: "YOUR_STORAGE_BUCKET", + messagingSenderId: "YOUR_MESSAGING_SENDER_ID", + appId: "YOUR_APP_ID" }; firebase.initializeApp(firebaseConfig); -const storage = firebase.storage(); - -export { storage, firebase as default }; +export const auth = firebase.auth(); +export const firestore = firebase.firestore(); diff --git a/src/index.js b/src/index.js index d563c0f..b597a44 100644 --- a/src/index.js +++ b/src/index.js @@ -1,17 +1,5 @@ import React from 'react'; -import ReactDOM from 'react-dom/client'; -import './index.css'; +import ReactDOM from 'react-dom'; import App from './App'; -import reportWebVitals from './reportWebVitals'; -const root = ReactDOM.createRoot(document.getElementById('root')); -root.render( - - - -); - -// If you want to start measuring performance in your app, pass a function -// to log results (for example: reportWebVitals(console.log)) -// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals -reportWebVitals(); +ReactDOM.render(, document.getElementById('root')); -- cgit v1.2.3-59-g8ed1b