Skip to content

Commit

Permalink
Aaa
Browse files Browse the repository at this point in the history
  • Loading branch information
nhattpn committed Apr 14, 2024
1 parent a192c97 commit 83c0c16
Show file tree
Hide file tree
Showing 13 changed files with 1,890 additions and 0 deletions.
1,634 changes: 1,634 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

23 changes: 23 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "login-app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"bcrypt": "^5.1.1",
"bcryptjs": "^2.4.3",
"body-parser": "^1.20.2",
"cors": "^2.8.5",
"dotenv": "^16.4.5",
"express": "^4.19.2",
"express-validator": "^7.0.1",
"jsonwebtoken": "^9.0.2",
"mongoose": "^8.3.1"
}
}
43 changes: 43 additions & 0 deletions qlsv_be/controllers/admin/admin.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const { validationResult } = require('express-validator');
const adminModel = require('../../models/admin.model');

exports.login = async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}

const { email, password } = req.body;
try {
const admin = await adminModel.findOne({ email: email });
if (!admin) {
return res.status(404).json({ message: "No admin record found" });
}
const isMatch = await bcrypt.compare(password, admin.password);
if (!isMatch) {
return res.status(401).json({ message: "Incorrect password" });
}
const token = jwt.sign({ email: admin.email, role: admin.role }, process.env.JWT_SECRET, { expiresIn: '1d' });
res.json({ message: "Login successful", token: token });
} catch (err) {
res.status(500).json({ message: "Login error", error: err.message });
}
};

exports.register = async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}

const { name, email, password } = req.body;
try {
const hash = await bcrypt.hash(password, 10);
const admin = await adminModel.create({ name, email, password: hash });
res.status(201).json({ message: "Admin registered successfully", admin: { id: admin._id, name: admin.name, email: admin.email } });
} catch (err) {
res.status(500).json({ message: "Error registering admin", error: err.message });
}
};
14 changes: 14 additions & 0 deletions qlsv_be/models/admin.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const mongoose = require('mongoose');

const adminSchema = new mongoose.Schema({
name: String,
email: String,
password: String,
role: {
type: String,
default: 'admin'
}
});

const adminModel = mongoose.model('admin', adminSchema);
module.exports = adminModel;
18 changes: 18 additions & 0 deletions qlsv_be/routes/admin/admin.route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const express = require('express');
const { body } = require('express-validator');
const adminController = require('../../controllers/admin/admin.controller');

const router = express.Router();

router.post('/', [
body('email').isEmail().withMessage('Invalid email address'),
body('password').notEmpty().withMessage('Password is required')
], adminController.login);

router.post('/register', [
body('name').notEmpty().withMessage('Name is required'),
body('email').isEmail().withMessage('Invalid email address'),
body('password').isLength({ min: 6 }).withMessage('Password must be at least 6 characters long')
], adminController.register);

module.exports = router;
8 changes: 8 additions & 0 deletions qlsv_be/routes/admin/index.route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const adminRoutes = require('./admin.route');


module.exports = (app) => {
const PATH_ADMIN = '/admin';
app.use(PATH_ADMIN + '/', adminRoutes);

}
22 changes: 22 additions & 0 deletions qlsv_be/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const mongoose = require('mongoose');
const adminRoute = require('./routes/admin/index.route');
require('dotenv').config();

const app = express();

// Connect to MongoDB
mongoose.connect('mongodb://localhost:27017/MUT_LMS')
.then(() => console.log('MongoDB connected'))
.catch(err => console.error(err));

app.use(cors());
app.use(bodyParser.json());

// Admin route setup
adminRoute(app);

const PORT = 5000;
app.listen(PORT, () => console.log(`Server running on http://localhost:${PORT}`));
18 changes: 18 additions & 0 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react';
import { AuthProvider } from './context/authContext';
import Login from './components/auth/login';
import Register from './components/auth/register';

function App() {
return (
<AuthProvider>
<div className="App">
<h1>Welcome to the Admin Panel</h1>
<Login />
<Register />
</div>
</AuthProvider>
);
}

export default App;
29 changes: 29 additions & 0 deletions src/component\auth/login.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React, { useState } from 'react';
import { useAuth } from '../../hooks/useAuth';

function Login() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const auth = useAuth();

const handleLogin = async (event) => {
event.preventDefault();
auth.login(email, password);
};

return (
<form onSubmit={handleLogin}>
<label>
Email:
<input type="email" value={email} onChange={(e) => setEmail(e.target.value)} required />
</label>
<label>
Password:
<input type="password" value={password} onChange={(e) => setPassword(e.target.value)} required />
</label>
<button type="submit">Login</button>
</form>
);
}

export default Login;
34 changes: 34 additions & 0 deletions src/component\auth/register.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React, { useState } from 'react';
import { useAuth } from '../../hooks/useAuth';

function Register() {
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const auth = useAuth();

const handleRegister = async (event) => {
event.preventDefault();
auth.register(name, email, password);
};

return (
<form onSubmit={handleRegister}>
<label>
Name:
<input type="text" value={name} onChange={(e) => setName(e.target.value)} required />
</label>
<label>
Email:
<input type="email" value={email} onChange={(e) => setEmail(e.target.value)} required />
</label>
<label>
Password:
<input type="password" value={password} onChange={(e) => setPassword(e.target.value)} required />
</label>
<button type="submit">Register</button>
</form>
);
}

export default Register;
22 changes: 22 additions & 0 deletions src/context/authContext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React, { createContext, useState } from 'react';
import * as authService from '../services/authServices';

export const AuthContext = createContext(null);

export function AuthProvider({ children }) {
const [user, setUser] = useState(null);

const login = async (email, password) => {
const data = await authService.login(email, password);
setUser(data);
};

const register = async (name, email, password) => {
const data = await authService.register(name, email, password);
setUser(data);
};

const value = { user, login, register };

return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
}
6 changes: 6 additions & 0 deletions src/hooks/useAuth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { useContext } from 'react';
import { AuthContext } from '../context/authContext';

export function useAuth() {
return useContext(AuthContext);
}
19 changes: 19 additions & 0 deletions src/services/authServices.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const API_URL = 'http://localhost:5000/admin';

export const login = async (email, password) => {
const response = await fetch('http://localhost:5000/admin', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password })
});
return response.json();
};

export const register = async (name, email, password) => {
const response = await fetch('http://localhost:5000/admin/register', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name, email, password })
});
return response.json();
};

0 comments on commit 83c0c16

Please sign in to comment.