Merge branch 'main' into new
This commit is contained in:
commit
9b5ac4fa3a
@ -370,14 +370,15 @@ app.post(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Hash the password
|
// Hash the password
|
||||||
const hashedPassword = await bcrypt.hash(password, 10);
|
const saltRounds = 10;
|
||||||
|
const hashedPassword = await bcrypt.hash(password, saltRounds);
|
||||||
|
|
||||||
// Start a transaction
|
// Start a transaction
|
||||||
const t = await sequelize.transaction();
|
const t = await sequelize.transaction();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Create the user
|
// Create the user
|
||||||
const newUser = await User.create({
|
await User.create({
|
||||||
name,
|
name,
|
||||||
username,
|
username,
|
||||||
email,
|
email,
|
||||||
@ -535,8 +536,9 @@ app.post("/forgot-password", async (req, res) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hash the new password
|
// Hash the new password
|
||||||
const hashedPassword = await bcrypt.hash(sanitizedPassword, 10);
|
const saltRounds = 10;
|
||||||
|
const hashedPassword = await bcrypt.hash(sanitizedPassword, saltRounds);
|
||||||
|
|
||||||
// Update user's password and clear reset token
|
// Update user's password and clear reset token
|
||||||
const updateQuery = {
|
const updateQuery = {
|
||||||
|
BIN
Sean/views/3.jpg
Normal file
BIN
Sean/views/3.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.6 KiB |
@ -7,69 +7,29 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Home</title>
|
<title>Home</title>
|
||||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;700&display=swap">
|
||||||
<style>
|
|
||||||
.chart-container {
|
|
||||||
width: 400px;
|
|
||||||
height: 250px;
|
|
||||||
margin: 20px;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
font-family: 'Arial', sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
#navbar {
|
|
||||||
background-color: #333;
|
|
||||||
overflow: hidden;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#navbar h1 {
|
|
||||||
color: white;
|
|
||||||
padding: 14px 16px;
|
|
||||||
margin: 0;
|
|
||||||
font-size: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#navbar a {
|
|
||||||
display: inline-block;
|
|
||||||
color: white;
|
|
||||||
text-align: center;
|
|
||||||
padding: 14px 16px;
|
|
||||||
text-decoration: none;
|
|
||||||
font-size: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#navbar a:hover {
|
|
||||||
background-color: #555;
|
|
||||||
}
|
|
||||||
|
|
||||||
#content {
|
|
||||||
padding: 16px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<h1>ECOSAVER MANAGEMENT</h1>
|
||||||
|
</header>
|
||||||
|
|
||||||
<div id="navbar">
|
<nav>
|
||||||
<h1>Eco Saver</h1>
|
|
||||||
<a href="/inusers">In-House Users</a>
|
<a href="/inusers">In-House Users</a>
|
||||||
<a href="#">Users</a>
|
<a href="#">Users</a>
|
||||||
<a href="#">Sensors</a>
|
<a href="#">Sensors</a>
|
||||||
<a href="/logout">Logout</a>
|
<a href="/logout">Logout</a>
|
||||||
</div>
|
</nav>
|
||||||
|
|
||||||
<div id="content">
|
<main>
|
||||||
<h2>Welcome to the Home Page, <%= username %>!</h2>
|
<h2>Welcome to the Home Page, <%= username %>!</h2>
|
||||||
|
</main>
|
||||||
|
<footer>
|
||||||
|
Any Issue faced, Please contact the administrator at 11111111 or ecosaverAdmin@gmail.com
|
||||||
|
</footer>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
@ -7,35 +7,34 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>In-House Users</title>
|
<title>In-House Users</title>
|
||||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/5.3.0/css/bootstrap.min.css">
|
|
||||||
<link rel="stylesheet" href="/style.css">
|
<link rel="stylesheet" href="/style.css">
|
||||||
<link rel="stylesheet" href="/user-creation.css">
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;700&display=swap">
|
||||||
|
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
<header>
|
||||||
<div id="navbar">
|
<h1>ECOSAVER MANAGEMENT</h1>
|
||||||
<h1>Eco Saver</h1>
|
</header>
|
||||||
|
<nav>
|
||||||
<a href="#" id="userDataLink">User Data</a>
|
<a href="#" id="userDataLink">User Data</a>
|
||||||
<a href="#" id="addUserLink">Add User</a>
|
<a href="#" id="addUserLink">Add User</a>
|
||||||
<a href="#" id="deleteUserLink">Delete User</a>
|
<a href="#" id="deleteUserLink">Delete User</a>
|
||||||
<a href="#" id="resetPasswordLink">Reset Password</a>
|
<a href="#" id="resetPasswordLink">Reset Password</a>
|
||||||
<a href="#" id="logsLink">Logs</a>
|
<a href="#" id="logsLink">Logs</a>
|
||||||
<a href="/home" id="homeLink">Home</a>
|
<a href="/home" id="homeLink">Home</a>
|
||||||
</div>
|
</nav>
|
||||||
|
|
||||||
<div id="content">
|
<main>
|
||||||
<h2>Welcome to the In-House Users Page</h2>
|
<h2>Welcome to the In-House Users Page</h2>
|
||||||
|
</main>
|
||||||
<div id="downloadButtonContainer">
|
<div id="downloadButtonContainer">
|
||||||
<button id="downloadButton">Download as Excel</button>
|
<button id="downloadButton">Download as Excel</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div id="userDataContainer">
|
<div id="userDataContainer">
|
||||||
<h3>All Users</h3>
|
<table class="nice-table">
|
||||||
<table>
|
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
@ -63,7 +62,7 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div id="createUserForm" class="user-creation-container" style="display: none;">
|
<div id="createUserForm" class="user-creation-container" style="display: none;">
|
||||||
<div class="title">Registration</div>
|
<h3>Registration</h3>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<form action="/createUser" id="userForm" method="post">
|
<form action="/createUser" id="userForm" method="post">
|
||||||
<div class="user-details">
|
<div class="user-details">
|
||||||
@ -102,9 +101,21 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="additional-text" style="display: none;">
|
||||||
|
<div class="condition">
|
||||||
|
<span>Conditions for creating a user:</span>
|
||||||
|
<ul>
|
||||||
|
<li class="error">Username has to be different.</li>
|
||||||
|
<li class="error">Email has to be different.</li>
|
||||||
|
<li class="error">Password must be at least 10 characters long and include at least one uppercase letter, one lowercase letter, one digit, and one symbol.</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="resetPasswordFormContainer" style="display: none;">
|
<div id="resetPasswordFormContainer" style="display: none;">
|
||||||
|
<h3>Reset Password</h3>
|
||||||
<div id="resetPasswordForm" class="user-creation-container">
|
<div id="resetPasswordForm" class="user-creation-container">
|
||||||
<div class="title">Reset Password</div>
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<form id="resetPasswordForm">
|
<form id="resetPasswordForm">
|
||||||
<div class="user-details">
|
<div class="user-details">
|
||||||
@ -129,6 +140,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="additional-text2" style="display: none;">
|
||||||
|
<div class="condition">
|
||||||
|
<span>Please remind user to reset their password again for safety reason</span>
|
||||||
|
<span>Conditions for Reseting user Password:</span>
|
||||||
|
<ul>
|
||||||
|
<li class="error">Password must be at least 10 characters long and include at least one uppercase letter, one lowercase letter, one digit, and one symbol.</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="deleteUserContainer" style="display: none;">
|
<div id="deleteUserContainer" style="display: none;">
|
||||||
<h3>Delete User</h3>
|
<h3>Delete User</h3>
|
||||||
@ -143,7 +163,11 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="additional-text3" style="display: none;">
|
||||||
|
<div class="condition">
|
||||||
|
<span>Please ensure correct user is being deleted user cannot be retived again upon deletion</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div id="logsContainer" style="display: none;">
|
<div id="logsContainer" style="display: none;">
|
||||||
<!-- Content for logs will be added here -->
|
<!-- Content for logs will be added here -->
|
||||||
|
|
||||||
@ -152,8 +176,7 @@
|
|||||||
<script>
|
<script>
|
||||||
const allUsers = <%- JSON.stringify(allUsers) %>;
|
const allUsers = <%- JSON.stringify(allUsers) %>;
|
||||||
const currentUsername = '<%= currentUsername %>';
|
const currentUsername = '<%= currentUsername %>';
|
||||||
|
</script>
|
||||||
</script>
|
|
||||||
|
|
||||||
<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
|
<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
|
||||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/5.3.0/js/bootstrap.bundle.min.js"></script>
|
<script src="https://stackpath.bootstrapcdn.com/bootstrap/5.3.0/js/bootstrap.bundle.min.js"></script>
|
||||||
@ -163,8 +186,7 @@
|
|||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.js"></script>
|
||||||
<script src="inusers.js"></script>
|
<script src="inusers.js"></script>
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
$('#resetPasswordLink').on('click', function () {
|
$('#resetPasswordLink').on('click', function () {
|
||||||
$('#resetPasswordFormContainer').show();
|
$('#resetPasswordFormContainer').show();
|
||||||
@ -6,15 +7,21 @@ $(document).ready(function () {
|
|||||||
$('#downloadButtonContainer').hide();
|
$('#downloadButtonContainer').hide();
|
||||||
$('#deleteUserContainer').hide();
|
$('#deleteUserContainer').hide();
|
||||||
$('#logsContainer').hide();
|
$('#logsContainer').hide();
|
||||||
|
$('#additional-text').hide();
|
||||||
|
$('#additional-text2').show();
|
||||||
|
$('#additional-text3').hide();
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#addUserLink').on('click', function () {
|
$('#addUserLink').on('click', function () {
|
||||||
$('#resetPasswordFormContainer').hide();
|
$('#resetPasswordFormContainer').hide();
|
||||||
$('#createUserForm').show();
|
$('#createUserForm').show();
|
||||||
|
$('#additional-text').show();
|
||||||
$('#userDataContainer').hide();
|
$('#userDataContainer').hide();
|
||||||
$('#downloadButtonContainer').hide();
|
$('#downloadButtonContainer').hide();
|
||||||
$('#deleteUserContainer').hide();
|
$('#deleteUserContainer').hide();
|
||||||
$('#logsContainer').hide();
|
$('#logsContainer').hide();
|
||||||
|
$('#additional-text2').hide();
|
||||||
|
$('#additional-text3').hide();
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#userDataLink').on('click', function () {
|
$('#userDataLink').on('click', function () {
|
||||||
@ -24,6 +31,9 @@ $(document).ready(function () {
|
|||||||
$('#downloadButtonContainer').show();
|
$('#downloadButtonContainer').show();
|
||||||
$('#deleteUserContainer').hide();
|
$('#deleteUserContainer').hide();
|
||||||
$('#logsContainer').hide();
|
$('#logsContainer').hide();
|
||||||
|
$('#additional-text').hide();
|
||||||
|
$('#additional-text2').hide();
|
||||||
|
$('#additional-text2').hide();
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#searchUserButton').on('click', function () {
|
$('#searchUserButton').on('click', function () {
|
||||||
@ -41,6 +51,9 @@ $('#deleteUserContainer').show();
|
|||||||
$('#userDataContainer').hide();
|
$('#userDataContainer').hide();
|
||||||
$('#downloadButtonContainer').hide();
|
$('#downloadButtonContainer').hide();
|
||||||
$('#logsContainer').hide();
|
$('#logsContainer').hide();
|
||||||
|
$('#additional-text').hide();
|
||||||
|
$('#additional-text2').hide();
|
||||||
|
$('#additional-text3').show();
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#downloadButton').on('click', function () {
|
$('#downloadButton').on('click', function () {
|
||||||
@ -54,10 +67,10 @@ $('#logsLink').on('click', function () {
|
|||||||
$('#userDataContainer').hide();
|
$('#userDataContainer').hide();
|
||||||
$('#downloadButtonContainer').hide();
|
$('#downloadButtonContainer').hide();
|
||||||
$('#deleteUserContainer').hide();
|
$('#deleteUserContainer').hide();
|
||||||
|
$('#additional-text').hide();
|
||||||
// Show logs container
|
|
||||||
$('#logsContainer').show();
|
$('#logsContainer').show();
|
||||||
|
$('#additional-text2').hide();
|
||||||
|
$('#additional-text3').hide();
|
||||||
fetchLogs();
|
fetchLogs();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -69,6 +82,7 @@ function searchUser(username) {
|
|||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
return response.json();
|
return response.json();
|
||||||
} else {
|
} else {
|
||||||
|
alert('No user found with the given username.');
|
||||||
throw new Error(`HTTP error! Status: ${response.status}`);
|
throw new Error(`HTTP error! Status: ${response.status}`);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -393,12 +407,12 @@ function displayLogs(logs) {
|
|||||||
|
|
||||||
// Create the table and header row
|
// Create the table and header row
|
||||||
const table = $('<table>').addClass('logs-table');
|
const table = $('<table>').addClass('logs-table');
|
||||||
const headerRow = '<tr><th>ID</th><th>Username</th><th>Activity</th><th>Timestamp</th></tr>';
|
const headerRow = '<thead><tr><th>ID</th><th>Username</th><th>Activity</th><th>Timestamp</th></tr></thead>';
|
||||||
table.append(headerRow);
|
table.append(headerRow);
|
||||||
|
|
||||||
// Add each log as a row in the table
|
// Add each log as a row in the table
|
||||||
logs.forEach(log => {
|
logs.forEach(log => {
|
||||||
const row = `<tr><td>${log.id}</td><td>${log.username}</td><td>${log.activity}</td><td>${log.timestamp}</td></tr>`;
|
const row = `<tbody><tr><td>${log.id}</td><td>${log.username}</td><td>${log.activity}</td><td>${log.timestamp}</td></tr></tbody>`;
|
||||||
table.append(row);
|
table.append(row);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,35 +1,63 @@
|
|||||||
/* style.css */
|
/* style.css */
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
font-family: 'Open Sans', sans-serif;
|
||||||
font-family: 'Arial', sans-serif;
|
background-color: #f4f4f4;
|
||||||
}
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
#navbar {
|
display: flex;
|
||||||
background-color: #333;
|
flex-direction: column;
|
||||||
overflow: hidden;
|
min-height: 100vh; /* Ensure the body takes at least the full height of the viewport */
|
||||||
text-align: center;
|
}
|
||||||
}
|
|
||||||
|
header {
|
||||||
#navbar h1 {
|
background-color: #333;
|
||||||
color: white;
|
color: #fff;
|
||||||
padding: 14px 16px;
|
text-align: center;
|
||||||
margin: 0;
|
padding: 1em;
|
||||||
font-size: 24px;
|
|
||||||
}
|
text-align: left; /* Adjust text alignment to the left */
|
||||||
|
}
|
||||||
#navbar a {
|
|
||||||
display: inline-block;
|
nav {
|
||||||
color: white;
|
background-color: #444;
|
||||||
text-align: center;
|
padding: 0.5em;
|
||||||
padding: 14px 16px;
|
}
|
||||||
text-decoration: none;
|
|
||||||
font-size: 18px;
|
nav a {
|
||||||
}
|
color: #fff;
|
||||||
|
text-decoration: none;
|
||||||
#navbar a:hover {
|
padding: 0.5em 1em;
|
||||||
background-color: #555;
|
margin: 0 0.5em;
|
||||||
}
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav a:hover {
|
||||||
|
background-color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 20px auto;
|
||||||
|
padding: 20px;
|
||||||
|
background-image: url('3.jpg');
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center ;
|
||||||
|
color: #000;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||||
|
border-radius: 5px;
|
||||||
|
margin-left: 20px; /* Adjust the margin-left to shift the entire content to the left */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
text-align: center;
|
||||||
|
padding: 1em;
|
||||||
|
background-color: #333;
|
||||||
|
color: #fff;
|
||||||
|
margin-top: auto; /* Push the footer to the bottom */
|
||||||
|
}
|
||||||
|
|
||||||
#content {
|
#content {
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
@ -60,7 +88,41 @@ body {
|
|||||||
td {
|
td {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
.nice-table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nice-table th, .nice-table td {
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
padding: 12px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nice-table th {
|
||||||
|
background-color: #333;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nice-table tbody tr:nth-child(even) {
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nice-table tbody tr:hover {
|
||||||
|
background-color: #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nice-table td:last-child {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Style for the "No users available" message */
|
||||||
|
.nice-table td[colspan="4"] {
|
||||||
|
text-align: center;
|
||||||
|
font-style: italic;
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
/* Additional styles for Bootstrap form */
|
/* Additional styles for Bootstrap form */
|
||||||
form {
|
form {
|
||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
@ -81,146 +143,346 @@ body {
|
|||||||
border-color: #0056b3;
|
border-color: #0056b3;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* User Creation Form Styles */
|
/* User Creation Form Styles */
|
||||||
.user-creation-container .input-box {
|
form#createUserForm {
|
||||||
margin-bottom: 20px;
|
margin-left: 20px;
|
||||||
width: 100%;
|
}
|
||||||
}
|
.user-creation-container {
|
||||||
|
|
||||||
.user-creation-container .input-box span.details {
|
|
||||||
display: block;
|
|
||||||
font-weight: 500;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-creation-container .user-details .input-box input {
|
|
||||||
height: 45px;
|
|
||||||
width: 100%;
|
|
||||||
outline: none;
|
|
||||||
font-size: 16px;
|
|
||||||
border-radius: 5px;
|
|
||||||
padding-left: 15px;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
border-bottom-width: 2px;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-creation-container .user-details .input-box input:focus,
|
|
||||||
.user-creation-container .user-details .input-box input:valid {
|
|
||||||
border-color: #9b59b6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-creation-container form .gender-details .gender-title {
|
|
||||||
font-size: 20px;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-creation-container form .category {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
|
||||||
margin: 14px 0;
|
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
align-items: flex-start; /* Add this line to align items at the start of the cross-axis */
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-creation-container form .category label {
|
.form-container {
|
||||||
|
width: 70%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-creation-container .user-details {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
flex-wrap: wrap; /* Allow items to wrap to the next line if needed */
|
||||||
cursor: pointer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-creation-container form .category label .dot {
|
.user-creation-container .user-details .input-box {
|
||||||
height: 18px;
|
width: 48%; /* Adjust as needed, leave some space for margins */
|
||||||
width: 18px;
|
margin-bottom: 10px; /* Add margin between input boxes */
|
||||||
border-radius: 50%;
|
|
||||||
margin-right: 10px;
|
|
||||||
background: #d9d9d9;
|
|
||||||
border: 5px solid transparent;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#dot-1:checked ~ .user-creation-container form .category label .one,
|
.user-creation-container .user-details .input-box select {
|
||||||
#dot-2:checked ~ .user-creation-container form .category label .two,
|
width: calc(100% - 6px); /* Adjust as needed, considering the select border */
|
||||||
#dot-3:checked ~ .user-creation-container form .category label .three {
|
}
|
||||||
background: #9b59b6;
|
|
||||||
border-color: #d9d9d9;
|
/* Add this to your existing styles */
|
||||||
|
|
||||||
|
.user-creation-container {
|
||||||
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-creation-container form input[type="radio"] {
|
#additional-text {
|
||||||
display: none;
|
width: 30%; /* Adjust the width as needed */
|
||||||
|
margin-left: 800px; /* Push it to the right */
|
||||||
|
margin-top: -750px; /* Adjust the negative margin to move it up */
|
||||||
|
padding: 10px; /* Add padding for spacing */
|
||||||
|
background-color: #f4f4f4; /* Add background color if desired */
|
||||||
|
border-radius: 5px; /* Add border-radius for rounded corners */
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); /* Add box shadow for a subtle effect */
|
||||||
|
border: 1px solid #ddd; /* Add a 1px solid border with light gray color */
|
||||||
|
font-family: 'Open Sans', sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-creation-container form .button {
|
#additional-text p {
|
||||||
height: 45px;
|
font-size: 16px; /* Adjust font size as needed */
|
||||||
margin: 35px 0;
|
line-height: 1.6; /* Adjust line height for better readability */
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-creation-container form .button input {
|
#additional-text .condition {
|
||||||
height: 100%;
|
margin-bottom: 10px; /* Add space between conditions */
|
||||||
width: 100%;
|
|
||||||
border-radius: 5px;
|
|
||||||
border: none;
|
|
||||||
color: #fff;
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: 500;
|
|
||||||
letter-spacing: 1px;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
background: linear-gradient(135deg, #71b7e6, #9b59b6);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-creation-container form .button input:hover {
|
#additional-text .condition span {
|
||||||
background: linear-gradient(-135deg, #71b7e6, #9b59b6);
|
font-weight: bold; /* Make condition labels bold */
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 584px) {
|
#additional-text .condition.error {
|
||||||
.user-creation-container .user-details .input-box {
|
color: red; /* Change text color for error conditions */
|
||||||
margin-bottom: 20px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.user-creation-container form .category {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.user-creation-container .content form .user-details {
|
|
||||||
max-height: 300px;
|
|
||||||
overflow-y: scroll;
|
|
||||||
}
|
|
||||||
.user-creation-container .user-details::-webkit-scrollbar {
|
|
||||||
width: 5px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 459px) {
|
#additional-text .condition.success {
|
||||||
.user-creation-container .container .content .category {
|
color: green; /* Change text color for success conditions */
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#createUserForm {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#createUserForm .container {
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#createUserForm form {
|
|
||||||
max-width: 400px;
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
#createUserForm .mb-3 {
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
#createUserForm .btn-primary {
|
|
||||||
background-color: #007bff;
|
|
||||||
border-color: #007bff;
|
|
||||||
}
|
|
||||||
|
|
||||||
#createUserForm .btn-primary:hover {
|
|
||||||
background-color: #0056b3;
|
|
||||||
border-color: #0056b3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.user-creation-container .input-box {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-creation-container .input-box span.details {
|
||||||
|
display: block;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-creation-container .user-details .input-box input {
|
||||||
|
height: 45px;
|
||||||
|
width: 100%;
|
||||||
|
outline: none;
|
||||||
|
font-size: 16px;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding-left: 15px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-bottom-width: 2px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-creation-container .user-details .input-box input:focus,
|
||||||
|
.user-creation-container .user-details .input-box input:valid {
|
||||||
|
border-color: #9b59b6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-creation-container form .gender-details .gender-title {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-creation-container form .category {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
margin: 14px 0;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-creation-container form .category label {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-creation-container form .category label .dot {
|
||||||
|
height: 18px;
|
||||||
|
width: 18px;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-right: 10px;
|
||||||
|
background: #d9d9d9;
|
||||||
|
border: 5px solid transparent;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
#dot-1:checked ~ .user-creation-container form .category label .one,
|
||||||
|
#dot-2:checked ~ .user-creation-container form .category label .two,
|
||||||
|
#dot-3:checked ~ .user-creation-container form .category label .three {
|
||||||
|
background: #9b59b6;
|
||||||
|
border-color: #d9d9d9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-creation-container form input[type="radio"] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-creation-container form .button {
|
||||||
|
height: 45px;
|
||||||
|
margin: 35px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-creation-container form .button input {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 5px;
|
||||||
|
border: none;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 500;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
background: linear-gradient(135deg, #71b7e6, #9b59b6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-creation-container form .button input:hover {
|
||||||
|
background: linear-gradient(-135deg, #71b7e6, #9b59b6);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 584px) {
|
||||||
|
.user-creation-container .user-details .input-box {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.user-creation-container form .category {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.user-creation-container .content form .user-details {
|
||||||
|
max-height: 300px;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
.user-creation-container .user-details::-webkit-scrollbar {
|
||||||
|
width: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 459px) {
|
||||||
|
.user-creation-container .container .content .category {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#createUserForm {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#createUserForm .container {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#createUserForm form {
|
||||||
|
max-width: 400px;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#createUserForm .mb-3 {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#createUserForm .btn-primary {
|
||||||
|
background-color: #007bff;
|
||||||
|
border-color: #007bff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#createUserForm .btn-primary:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
border-color: #0056b3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Shift the form to the left */
|
||||||
|
#createUserForm {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
#createUserForm.user-creation-container {
|
||||||
|
margin-left: 0; /* Reset the margin-left */
|
||||||
|
max-width: 400px; /* Set a maximum width to the form container */
|
||||||
|
margin: 20px; /* Add margin for spacing */
|
||||||
|
}
|
||||||
|
|
||||||
|
#createUserForm h3 {
|
||||||
|
text-align: left; /* Align the heading to the left */
|
||||||
|
margin-bottom: 20px; /* Add spacing below the heading */
|
||||||
|
}
|
||||||
|
|
||||||
|
#createUserForm .content {
|
||||||
|
padding: 16px; /* Add padding to the form content */
|
||||||
|
text-align: left; /* Align the form content to the left */
|
||||||
|
}
|
||||||
|
|
||||||
|
#createUserForm .user-details {
|
||||||
|
width: 100%; /* Make the user-details section full-width */
|
||||||
|
}
|
||||||
|
|
||||||
|
#createUserForm .input-box {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#createUserForm .input-box span.details {
|
||||||
|
display: block;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#createUserForm .user-details .input-box input {
|
||||||
|
height: 45px;
|
||||||
|
width: 100%;
|
||||||
|
outline: none;
|
||||||
|
font-size: 16px;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding-left: 15px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-bottom-width: 2px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
#resetPasswordFormContainer {
|
||||||
|
margin-left: 20px; /* Adjust the margin-left to shift the form container to the left */
|
||||||
|
max-width: 400px; /* Set a maximum width to the form container */
|
||||||
|
margin: 20px; /* Add margin for spacing */
|
||||||
|
}
|
||||||
|
|
||||||
|
#resetPasswordFormContainer h3 {
|
||||||
|
text-align: left; /* Align the heading to the left */
|
||||||
|
margin-bottom: 20px; /* Add spacing below the heading */
|
||||||
|
}
|
||||||
|
|
||||||
|
#resetPasswordFormContainer .content {
|
||||||
|
padding: 16px; /* Add padding to the form content */
|
||||||
|
text-align: left; /* Align the form content to the left */
|
||||||
|
}
|
||||||
|
|
||||||
|
#resetPasswordFormContainer .user-details {
|
||||||
|
width: 100%; /* Make the user-details section full-width */
|
||||||
|
}
|
||||||
|
|
||||||
|
#resetPasswordFormContainer .input-box {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#resetPasswordFormContainer .input-box span.details {
|
||||||
|
display: block;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#resetPasswordFormContainer .user-details .input-box input {
|
||||||
|
height: 45px;
|
||||||
|
width: 100%;
|
||||||
|
outline: none;
|
||||||
|
font-size: 16px;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding-left: 15px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-bottom-width: 2px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
#deleteUserContainer {
|
||||||
|
margin-left: 20px; /* Adjust the margin-left to shift the container to the left */
|
||||||
|
max-width: 400px; /* Set a maximum width to the container */
|
||||||
|
margin: 20px; /* Add margin for spacing */
|
||||||
|
}
|
||||||
|
|
||||||
|
#deleteUserContainer h3 {
|
||||||
|
text-align: left; /* Align the heading to the left */
|
||||||
|
margin-bottom: 20px; /* Add spacing below the heading */
|
||||||
|
}
|
||||||
|
|
||||||
|
#deleteUserContainer .search-container {
|
||||||
|
text-align: left; /* Align the search container to the left */
|
||||||
|
margin-bottom: 20px; /* Add spacing below the search container */
|
||||||
|
}
|
||||||
|
|
||||||
|
#deleteUserContainer .search-container input {
|
||||||
|
width: 80%; /* Adjust the width of the search input */
|
||||||
|
padding: 10px; /* Add padding to the search input */
|
||||||
|
margin-right: 10px; /* Add spacing to the right of the search input */
|
||||||
|
}
|
||||||
|
|
||||||
|
#deleteUserContainer .search-container button {
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #007bff; /* Set background color to match other buttons */
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
|
||||||
|
/* Hover styles */
|
||||||
|
&:hover {
|
||||||
|
background-color: #0056b3; /* Change background color on hover */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#searchResultsContainer {
|
||||||
|
display: none;
|
||||||
|
text-align: left; /* Align the search results container to the left */
|
||||||
|
}
|
||||||
|
|
||||||
|
#searchResultsContainer h4 {
|
||||||
|
margin-bottom: 10px; /* Add spacing below the search results heading */
|
||||||
|
}
|
||||||
|
|
||||||
.logs-table {
|
.logs-table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
@ -235,4 +497,63 @@ body {
|
|||||||
|
|
||||||
.logs-table th {
|
.logs-table th {
|
||||||
background-color: #f2f2f2;
|
background-color: #f2f2f2;
|
||||||
}
|
}
|
||||||
|
#additional-text2 {
|
||||||
|
width: 30%; /* Adjust the width as needed */
|
||||||
|
margin-left: 800px; /* Push it to the right */
|
||||||
|
margin-top: -500px; /* Adjust the negative margin to move it up */
|
||||||
|
padding: 10px; /* Add padding for spacing */
|
||||||
|
background-color: #f4f4f4; /* Add background color if desired */
|
||||||
|
border-radius: 5px; /* Add border-radius for rounded corners */
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); /* Add box shadow for a subtle effect */
|
||||||
|
border: 1px solid #ddd; /* Add a 1px solid border with light gray color */
|
||||||
|
font-family: 'Open Sans', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
#additional-text2 p {
|
||||||
|
font-size: 16px; /* Adjust font size as needed */
|
||||||
|
line-height: 1.6; /* Adjust line height for better readability */
|
||||||
|
}
|
||||||
|
|
||||||
|
#additional-text2 .condition {
|
||||||
|
margin-bottom: 10px; /* Add space between conditions */
|
||||||
|
}
|
||||||
|
|
||||||
|
#additional-text2 .condition span {
|
||||||
|
font-weight: bold; /* Make condition labels bold */
|
||||||
|
}
|
||||||
|
|
||||||
|
#additional-text2 .condition.error {
|
||||||
|
color: red; /* Change text color for error conditions */
|
||||||
|
}
|
||||||
|
|
||||||
|
#additional-text2 .condition.success {
|
||||||
|
color: green; /* Change text color for success conditions */
|
||||||
|
}
|
||||||
|
|
||||||
|
#additional-text3 {
|
||||||
|
width: 30%; /* Adjust the width as needed */
|
||||||
|
margin-left: 800px; /* Push it to the right */
|
||||||
|
margin-top: -150px; /* Adjust the negative margin to move it up */
|
||||||
|
padding: 10px; /* Add padding for spacing */
|
||||||
|
background-color: #f4f4f4; /* Add background color if desired */
|
||||||
|
border-radius: 5px; /* Add border-radius for rounded corners */
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); /* Add box shadow for a subtle effect */
|
||||||
|
border: 1px solid #ddd; /* Add a 1px solid border with light gray color */
|
||||||
|
font-family: 'Open Sans', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
#additional-text3 p {
|
||||||
|
font-size: 16px; /* Adjust font size as needed */
|
||||||
|
line-height: 1.6; /* Adjust line height for better readability */
|
||||||
|
}
|
||||||
|
|
||||||
|
#additional-text3 .condition {
|
||||||
|
margin-bottom: 10px; /* Add space between conditions */
|
||||||
|
}
|
||||||
|
|
||||||
|
#additional-text3 .condition span {
|
||||||
|
font-weight: bold; /* Make condition labels bold */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,101 +0,0 @@
|
|||||||
/* user-creation.css */
|
|
||||||
|
|
||||||
.user-creation-container {
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-creation-container form {
|
|
||||||
max-width: 400px;
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-creation-container .user-details .input-box {
|
|
||||||
margin-bottom: 15px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-creation-container .user-details .input-box input,
|
|
||||||
.user-creation-container .user-details .input-box select {
|
|
||||||
height: 45px;
|
|
||||||
width: 100%;
|
|
||||||
outline: none;
|
|
||||||
font-size: 16px;
|
|
||||||
border-radius: 5px;
|
|
||||||
padding-left: 15px;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
border-bottom-width: 2px;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-creation-container .user-details .input-box input:focus,
|
|
||||||
.user-creation-container .user-details .input-box input:valid,
|
|
||||||
.user-creation-container .user-details .input-box select:focus {
|
|
||||||
border-color: #9b59b6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-creation-container form .category {
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
margin: 14px 0;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-creation-container form .category select {
|
|
||||||
height: 45px;
|
|
||||||
width: 100%; /* Adjusted width to match other input boxes */
|
|
||||||
outline: none;
|
|
||||||
font-size: 16px;
|
|
||||||
border-radius: 5px;
|
|
||||||
padding-left: 15px;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-creation-container form .button {
|
|
||||||
height: 45px;
|
|
||||||
margin: 35px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-creation-container form .button input {
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
border-radius: 5px;
|
|
||||||
border: none;
|
|
||||||
color: #fff;
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: 500;
|
|
||||||
letter-spacing: 1px;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
background: linear-gradient(135deg, #71b7e6, #9b59b6);
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-creation-container form .button input:hover {
|
|
||||||
background: linear-gradient(-135deg, #71b7e6, #9b59b6);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 584px) {
|
|
||||||
.user-creation-container .user-details .input-box {
|
|
||||||
margin-bottom: 15px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-creation-container form .category {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-creation-container .content form .user-details {
|
|
||||||
max-height: 300px;
|
|
||||||
overflow-y: scroll;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-creation-container .user-details::-webkit-scrollbar {
|
|
||||||
width: 5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 459px) {
|
|
||||||
.user-creation-container .container .content .category {
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
}
|
|
@ -64,7 +64,6 @@ const apikeyModel = sequelize.define(
|
|||||||
|
|
||||||
module.exports = { apikeyModel };
|
module.exports = { apikeyModel };
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
class AuthToken extends Model {
|
class AuthToken extends Model {
|
||||||
check(){
|
check(){
|
||||||
|
@ -2,14 +2,12 @@ const { sequelize } = require("../database/mySql.js");
|
|||||||
const { apikeyModel } = require("../database/model/apikeyModel.js");
|
const { apikeyModel } = require("../database/model/apikeyModel.js");
|
||||||
const { userModel } = require("../database/model/userModel.js");
|
const { userModel } = require("../database/model/userModel.js");
|
||||||
const { Op, Sequelize } = require("sequelize");
|
const { Op, Sequelize } = require("sequelize");
|
||||||
const { hashAPIKey } = require("../functions/bcrypt.js");
|
|
||||||
const { generateUUID } = require("../functions/generateUUID.js");
|
const { generateUUID } = require("../functions/generateUUID.js");
|
||||||
const { hashPassword } = require("../functions/bcrypt.js");
|
const { hashPassword , comparePassword , hashAPIKey } = require("../functions/bcrypt.js");
|
||||||
|
|
||||||
|
//helper function
|
||||||
|
|
||||||
|
|
||||||
async function getUser() {
|
|
||||||
const user = await userModel.findAll();
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
//api/v0/user/register
|
//api/v0/user/register
|
||||||
|
|
||||||
/* Registering new user
|
/* Registering new user
|
||||||
@ -22,15 +20,76 @@ async function addUser(user) {
|
|||||||
//hash password
|
//hash password
|
||||||
let hash = await hashPassword(user.password);
|
let hash = await hashPassword(user.password);
|
||||||
|
|
||||||
await userModel.create({
|
const addRes = await userModel.create({
|
||||||
username: user.username,
|
username: user.username,
|
||||||
password: hash,
|
password: hash,
|
||||||
email: user.email,
|
email: user.email,
|
||||||
address: user.address,
|
address: user.address,
|
||||||
phone: user.phone,
|
phone: user.phone,
|
||||||
});
|
});
|
||||||
|
if (addRes){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//add token to db
|
||||||
|
async function addToken(userid , token) {
|
||||||
|
console.log(userid);
|
||||||
|
console.log(token);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loginUser(user) {
|
||||||
|
//look up username or email in db
|
||||||
|
const userRes = await userModel.findOne({
|
||||||
|
where: {
|
||||||
|
[Op.or]: [
|
||||||
|
{
|
||||||
|
username: user.userInfo,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
email: user.userInfo,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
//if user exists
|
||||||
|
if (userRes){
|
||||||
|
//compare password
|
||||||
|
let match = await comparePassword(user.password, userRes.password);
|
||||||
|
if (match){
|
||||||
|
console.log(userRes.id);
|
||||||
|
console.log(userRes.username);
|
||||||
|
|
||||||
|
//generate token
|
||||||
|
let token = await generateUUID();
|
||||||
|
|
||||||
|
//add to db
|
||||||
|
addToken(userRes.id, token);
|
||||||
|
|
||||||
|
|
||||||
|
//sucessful login
|
||||||
|
/*
|
||||||
|
1) generate token
|
||||||
|
2) store in db and localstorage (maybe hash it?)
|
||||||
|
3) return userid and username and token and store in localstorage
|
||||||
|
*/
|
||||||
|
return { token: token, userid: userRes.id, username: userRes.username };
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
async function getAPIKey() {
|
async function getAPIKey() {
|
||||||
const apikey = await apikeyModel.findAll();
|
const apikey = await apikeyModel.findAll();
|
||||||
return apikey;
|
return apikey;
|
||||||
@ -44,8 +103,6 @@ async function getAPIKey() {
|
|||||||
5) you give the user rowid-uuidv4
|
5) you give the user rowid-uuidv4
|
||||||
6) store in database
|
6) store in database
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
async function addAPIKey(userId, permission) {
|
async function addAPIKey(userId, permission) {
|
||||||
let token = await generateUUID();
|
let token = await generateUUID();
|
||||||
let usertoken = userId + "-" + token;
|
let usertoken = userId + "-" + token;
|
||||||
@ -66,8 +123,7 @@ async function addAPIKey(userId, permission) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
getUser,
|
|
||||||
addUser,
|
addUser,
|
||||||
getAPIKey,
|
loginUser,
|
||||||
addAPIKey,
|
addAPIKey,
|
||||||
};
|
};
|
||||||
|
@ -29,9 +29,14 @@ async function hashAPIKey(apikey) {
|
|||||||
return await bcrypt.hash(apikey, saltRounds);
|
return await bcrypt.hash(apikey, saltRounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function comparePassword(password, hash) {
|
||||||
|
return await bcrypt.compare(password, hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
hashPassword,
|
hashPassword,
|
||||||
hashAPIKey,
|
hashAPIKey,
|
||||||
|
comparePassword
|
||||||
};
|
};
|
@ -0,0 +1,4 @@
|
|||||||
|
/*v
|
||||||
|
1) check if token proided by JSON req is valid against db
|
||||||
|
2) if valid its passed to next()
|
||||||
|
*/
|
@ -28,12 +28,19 @@ app.use("/", require("../routes/render")); //consumerWebsite\routes\render.js
|
|||||||
// Catch 404 and forward to error handler. If none of the above routes are
|
// Catch 404 and forward to error handler. If none of the above routes are
|
||||||
// used, this is what will be called.
|
// used, this is what will be called.
|
||||||
app.use(function (req, res, next) {
|
app.use(function (req, res, next) {
|
||||||
|
if (req.is("application/json")) {
|
||||||
var err = new Error("Not Found");
|
var err = new Error("Not Found");
|
||||||
err.message = "Page not found";
|
err.message = "Page not found";
|
||||||
err.status = 404;
|
err.status = 404;
|
||||||
next(err);
|
next(err);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
res.status(404).render("404");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Error handler. This is where `next()` will go on error
|
// Error handler. This is where `next()` will go on error
|
||||||
app.use(function (err, req, res, next) {
|
app.use(function (err, req, res, next) {
|
||||||
console.error(err.status || res.status, err.name, req.method, req.url);
|
console.error(err.status || res.status, err.name, req.method, req.url);
|
||||||
|
@ -66,7 +66,7 @@ body {
|
|||||||
header {
|
header {
|
||||||
font-size: 30px;
|
font-size: 30px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #fff;
|
color: #000000;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
@ -93,6 +93,7 @@ body {
|
|||||||
margin-top: 50px;
|
margin-top: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
form
|
form
|
||||||
input {
|
input {
|
||||||
height: 60px;
|
height: 60px;
|
||||||
@ -106,6 +107,7 @@ form
|
|||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form.login
|
.form.login
|
||||||
input {
|
input {
|
||||||
border: 1px
|
border: 1px
|
||||||
|
@ -12,7 +12,7 @@ app.util = (function (app) {
|
|||||||
|
|
||||||
function actionMessage(message, $target, type, callback) {
|
function actionMessage(message, $target, type, callback) {
|
||||||
message = message || "";
|
message = message || "";
|
||||||
$target = $target.closest("div.card").find(".actionMessage");
|
$target = $target.closest("div.iot-card").find(".actionMessage");
|
||||||
type = type || "info";
|
type = type || "info";
|
||||||
callback = callback || function () {};
|
callback = callback || function () {};
|
||||||
|
|
||||||
@ -29,9 +29,6 @@ app.util = (function (app) {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (type) $target.addClass("bg-" + type);
|
if (type) $target.addClass("bg-" + type);
|
||||||
message =
|
|
||||||
'<button class="action-close btn btn-sm btn-outline-dark float-right"><i class="fa-solid fa-xmark"></i></button>' +
|
|
||||||
message;
|
|
||||||
$target.html(message).slideDown("fast");
|
$target.html(message).slideDown("fast");
|
||||||
}
|
}
|
||||||
setTimeout(callback, 10);
|
setTimeout(callback, 10);
|
||||||
@ -137,6 +134,7 @@ app.api = (function (app) {
|
|||||||
complete: function (res, text) {
|
complete: function (res, text) {
|
||||||
callback(
|
callback(
|
||||||
text !== "success" ? res.statusText : null,
|
text !== "success" ? res.statusText : null,
|
||||||
|
//console.log(res.responseText),
|
||||||
JSON.parse(res.responseText),
|
JSON.parse(res.responseText),
|
||||||
res.status
|
res.status
|
||||||
);
|
);
|
||||||
@ -153,6 +151,14 @@ app.auth = (function (app) {
|
|||||||
localStorage.setItem("APIToken", token);
|
localStorage.setItem("APIToken", token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setUserId(userId) {
|
||||||
|
localStorage.setItem("userId", userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setUsername(username) {
|
||||||
|
localStorage.setItem("username", username);
|
||||||
|
}
|
||||||
|
|
||||||
function getToken() {
|
function getToken() {
|
||||||
return localStorage.getItem("APIToken");
|
return localStorage.getItem("APIToken");
|
||||||
}
|
}
|
||||||
@ -167,7 +173,7 @@ app.auth = (function (app) {
|
|||||||
callback(null, false);
|
callback(null, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
function logIn(args, callback) {
|
function logIn(args, callback) {
|
||||||
app.api.post("auth/login", args, function (error, data) {
|
app.api.post("auth/login", args, function (error, data) {
|
||||||
if (data.login) {
|
if (data.login) {
|
||||||
@ -176,9 +182,14 @@ app.auth = (function (app) {
|
|||||||
callback(error, !!data.token);
|
callback(error, !!data.token);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
function logOut(callback) {
|
function logOut(callback) {
|
||||||
localStorage.removeItem("APIToken");
|
localStorage.removeItem("APIToken");
|
||||||
|
localStorage.removeItem("userId");
|
||||||
|
localStorage.removeItem("username");
|
||||||
|
|
||||||
|
//remove token from db NOT the api key.
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,46 +207,50 @@ app.auth = (function (app) {
|
|||||||
|
|
||||||
function logInRedirect() {
|
function logInRedirect() {
|
||||||
window.location.href =
|
window.location.href =
|
||||||
|
//window.location.href = location.href.replace(location.origin+'/login', '') || '/'
|
||||||
location.href.replace(location.replace(`/login`)) || "/";
|
location.href.replace(location.replace(`/login`)) || "/";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function homeRedirect() {
|
||||||
|
window.location.href = location.href.replace(location.replace(`/`)) || "/";
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
getToken: getToken,
|
getToken: getToken,
|
||||||
setToken: setToken,
|
setToken: setToken,
|
||||||
|
setUserId: setUserId,
|
||||||
|
setUsername: setUsername,
|
||||||
isLoggedIn: isLoggedIn,
|
isLoggedIn: isLoggedIn,
|
||||||
logIn: logIn,
|
//logIn: logIn,
|
||||||
logOut: logOut,
|
logOut: logOut,
|
||||||
forceLogin,
|
forceLogin,
|
||||||
logInRedirect,
|
logInRedirect,
|
||||||
|
homeRedirect,
|
||||||
};
|
};
|
||||||
})(app);
|
})(app);
|
||||||
|
|
||||||
//ajax form submit
|
//ajax form submit
|
||||||
function formAJAX( btn, del ) {
|
function formAJAX(btn, del) {
|
||||||
event.preventDefault(); // avoid to execute the actual submit of the form.
|
event.preventDefault(); // avoid to execute the actual submit of the form.
|
||||||
var $form = $(btn).closest( '[action]' ); // gets the 'form' parent
|
var $form = $(btn).closest("[action]"); // gets the 'form' parent
|
||||||
var formData = $form.find( '[name]' ).serializeObject(); // builds query formDataing
|
var formData = $form.find("[name]").serializeObject(); // builds query formDataing
|
||||||
var method = $form.attr('method') || 'post';
|
var method = $form.attr("method") || "post";
|
||||||
|
|
||||||
// if( !$form.validate()) {
|
// if( !$form.validate()) {
|
||||||
// app.util.actionMessage('Please fix the form errors.', $form, 'danger')
|
// app.util.actionMessage('Please fix the form errors.', $form, 'danger')
|
||||||
// return false;
|
// return false;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
app.util.actionMessage(
|
|
||||||
'<div class="spinner-border" role="status"><span class="sr-only">Loading...</span></div>',
|
|
||||||
$form,
|
|
||||||
'info'
|
|
||||||
);
|
|
||||||
|
|
||||||
//console.log('Data being sent to', $form.attr('action'), formData)
|
app.util.actionMessage("Loading...", $form, "info");
|
||||||
|
|
||||||
app.api[method]($form.attr('action'), formData, function(error, data){
|
//console.log('Data being sent to', $form.attr('action'), formData)
|
||||||
//console.log('Data back from the server', error, data)
|
|
||||||
app.util.actionMessage(data.message, $form, error ? 'danger' : 'success'); //re-populate table
|
app.api[method]($form.attr("action"), formData, function (error, data) {
|
||||||
if(!error){
|
//console.log('Data back from the server', error, data)
|
||||||
$form.trigger("reset");
|
app.util.actionMessage(data.message, $form, error ? "danger" : "success"); //re-populate table
|
||||||
eval($form.attr('evalAJAX')); //gets JS to run after completion
|
if (!error) {
|
||||||
}
|
$form.trigger("reset");
|
||||||
});
|
eval($form.attr("evalAJAX")); //gets JS to run after completion
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@ -77,10 +77,4 @@ router.get('/contact', function(req, res, next) {
|
|||||||
res.render('contact');
|
res.render('contact');
|
||||||
});
|
});
|
||||||
|
|
||||||
//404 page
|
|
||||||
router.get('*', function(req, res, next) {
|
|
||||||
res.render('404');
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
@ -1,41 +1,60 @@
|
|||||||
const { getUser, addUser } = require("../functions/apiDatabase.js");
|
const { addUser, loginUser } = require("../functions/apiDatabase.js");
|
||||||
|
|
||||||
const express = require("express");
|
const express = require("express");
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
//get all users
|
|
||||||
router.get("/", async (req, res, next) => {
|
|
||||||
try {
|
|
||||||
const location = await getUser();
|
|
||||||
res.status(200).json(location);
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
next(error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// /user/register
|
// /user/register
|
||||||
router.post("/register", async (req, res, next) => {
|
router.post("/register", async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
console.log("this is " , req.body);
|
let Res = await addUser(req.body);
|
||||||
await addUser(req.body);
|
if (Res == false) {
|
||||||
res.status(200).json({ register: true });
|
let error = new Error("UserRegFailed");
|
||||||
|
error.message = "The user failed to be craated";
|
||||||
|
error.status = 400;
|
||||||
|
return next(error);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return res.json({
|
||||||
|
message: "User created successfully",
|
||||||
|
});
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
//login
|
//login
|
||||||
|
router.post("/login", async (req, res, next) => {
|
||||||
|
try {
|
||||||
|
let Res = await loginUser(req.body);
|
||||||
|
if (Res == false) {
|
||||||
|
let error = new Error("User Login Failed");
|
||||||
|
error.status = 400;
|
||||||
|
return next(error);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
//pass res back to form to be set in local storage
|
||||||
|
console.log(Res);
|
||||||
|
return res.json({
|
||||||
|
message: "User login successfully",
|
||||||
|
token: Res.token,
|
||||||
|
userId: Res.userid,
|
||||||
|
username: Res.username,
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
next(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
//update
|
//update
|
||||||
//delete
|
//delete
|
||||||
//getbyid
|
//getbyid
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
curl localhost/api/v0/user/register -H "Content-Type: application/json" -X POST -d '{"username":
|
curl localhost/api/v0/user/register -H "Content-Type: application/json" -X POST -d '{"username":
|
||||||
@ -78,4 +97,4 @@ router.get('/:uid', async function(req, res, next){
|
|||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
@ -2,14 +2,11 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
<section class="wrapper">
|
<section class="wrapper">
|
||||||
<div class="form signup" >
|
<div class="form signup iot-card">
|
||||||
<!--<div class="form signup card" -->
|
<!--<div class="form signup card" -->
|
||||||
<header>Signup</header>
|
<header>Signup</header>
|
||||||
<!-- Return message from api -->
|
|
||||||
<div class="actionMessage" style="display:none"></div>
|
|
||||||
<!-- localhost/api/v0/user/register -->
|
<!-- localhost/api/v0/user/register -->
|
||||||
|
<!-- evalAjax Fires when status 200 is returned -->
|
||||||
<!-- evalAjax Fires when status is returned -->
|
|
||||||
<form action="user/register" onsubmit="formAJAX(this)" evalAJAX="app.auth.logInRedirect();">
|
<form action="user/register" onsubmit="formAJAX(this)" evalAJAX="app.auth.logInRedirect();">
|
||||||
<input type="text" name="username" placeholder="Username" required />
|
<input type="text" name="username" placeholder="Username" required />
|
||||||
<input type="text" name="email" placeholder="Email" required />
|
<input type="text" name="email" placeholder="Email" required />
|
||||||
@ -21,7 +18,7 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form login">
|
<div class="form login iot-card">
|
||||||
<header>Login</header>
|
<header>Login</header>
|
||||||
<div class="card-header shadow actionMessage" style="display:none"></div>
|
<div class="card-header shadow actionMessage" style="display:none"></div>
|
||||||
<!-- evalAjax Fires when status 200 is returned -->
|
<!-- evalAjax Fires when status 200 is returned -->
|
||||||
@ -34,7 +31,7 @@
|
|||||||
|
|
||||||
<input type="text" name="userInfo" placeholder="Email address | Username" required />
|
<input type="text" name="userInfo" placeholder="Email address | Username" required />
|
||||||
<input type="password" name="password" placeholder="Password" required />
|
<input type="password" name="password" placeholder="Password" required />
|
||||||
<a href="/forgotPassword">Forgot password?</a>
|
<a href="/resetPassword">Forgot password?</a>
|
||||||
<input type="submit" value="Login" />
|
<input type="submit" value="Login" />
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user