created user settings in the settings page
This commit is contained in:
@@ -1,10 +1,20 @@
|
||||
from flask import Flask
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
|
||||
db = SQLAlchemy()
|
||||
|
||||
def create_app():
|
||||
app = Flask(__name__)
|
||||
app.config['SECRET_KEY'] = 'Recticel a plecat Aquinos a falimentat Innofa a venit'
|
||||
app.config['SECRET_KEY'] = 'your_secret_key'
|
||||
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db'
|
||||
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
||||
|
||||
db.init_app(app)
|
||||
|
||||
from .routes import bp
|
||||
app.register_blueprint(bp)
|
||||
|
||||
with app.app_context():
|
||||
db.create_all() # Create database tables if they don't exist
|
||||
|
||||
return app
|
||||
Binary file not shown.
BIN
py_app/app/__pycache__/models.cpython-311.pyc
Normal file
BIN
py_app/app/__pycache__/models.cpython-311.pyc
Normal file
Binary file not shown.
Binary file not shown.
10
py_app/app/models.py
Normal file
10
py_app/app/models.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from . import db
|
||||
|
||||
class User(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
username = db.Column(db.String(80), unique=True, nullable=False)
|
||||
password = db.Column(db.String(120), nullable=False)
|
||||
role = db.Column(db.String(20), nullable=False) # Role: superadmin, administrator, quality, warehouse, scan
|
||||
|
||||
def __repr__(self):
|
||||
return f'<User {self.username}>'
|
||||
@@ -1,17 +1,18 @@
|
||||
from flask import Blueprint, render_template, redirect, url_for, request, flash, session
|
||||
from .models import User
|
||||
from . import db
|
||||
|
||||
bp = Blueprint('main', __name__)
|
||||
|
||||
# Dummy user data
|
||||
users = {"admin@home.com": "1234"}
|
||||
|
||||
@bp.route('/login', methods=['GET', 'POST'])
|
||||
def login():
|
||||
if request.method == 'POST':
|
||||
email = request.form['email']
|
||||
username = request.form['username']
|
||||
password = request.form['password']
|
||||
if email in users and users[email] == password:
|
||||
session['user'] = email
|
||||
user = User.query.filter_by(username=username, password=password).first()
|
||||
if user:
|
||||
session['user'] = user.username
|
||||
session['role'] = user.role
|
||||
return redirect(url_for('main.dashboard'))
|
||||
else:
|
||||
flash('Invalid credentials. Please try again.')
|
||||
@@ -23,11 +24,108 @@ def dashboard():
|
||||
return redirect(url_for('main.login'))
|
||||
return render_template('dashboard.html')
|
||||
|
||||
@bp.route('/settings')
|
||||
def settings():
|
||||
if 'role' not in session or session['role'] != 'superadmin':
|
||||
flash('Access denied: Superadmin only.')
|
||||
return redirect(url_for('main.dashboard'))
|
||||
|
||||
# Fetch all users from the database
|
||||
users = User.query.all()
|
||||
return render_template('settings.html', users=users)
|
||||
|
||||
@bp.route('/quality')
|
||||
def quality():
|
||||
if 'role' not in session or session['role'] not in ['superadmin', 'quality']:
|
||||
flash('Access denied: Quality users only.')
|
||||
return redirect(url_for('main.dashboard'))
|
||||
return render_template('quality.html')
|
||||
|
||||
@bp.route('/warehouse')
|
||||
def warehouse():
|
||||
if 'role' not in session or session['role'] not in ['superadmin', 'warehouse']:
|
||||
flash('Access denied: Warehouse users only.')
|
||||
return redirect(url_for('main.dashboard'))
|
||||
return render_template('warehouse.html')
|
||||
|
||||
@bp.route('/scan')
|
||||
def scan():
|
||||
if 'role' not in session or session['role'] not in ['superadmin', 'scan']:
|
||||
flash('Access denied: Scan users only.')
|
||||
return redirect(url_for('main.dashboard'))
|
||||
return render_template('scan.html')
|
||||
|
||||
@bp.route('/logout')
|
||||
def logout():
|
||||
session.pop('user', None)
|
||||
session.pop('role', None)
|
||||
return redirect(url_for('main.login'))
|
||||
|
||||
@bp.route('/settings')
|
||||
def settings():
|
||||
return render_template('settings.html')
|
||||
@bp.route('/create_user', methods=['POST'])
|
||||
def create_user():
|
||||
if 'role' not in session or session['role'] != 'superadmin':
|
||||
flash('Access denied: Superadmin only.')
|
||||
return redirect(url_for('main.settings'))
|
||||
|
||||
username = request.form['username']
|
||||
password = request.form['password']
|
||||
role = request.form['role']
|
||||
|
||||
# Check if the username already exists
|
||||
if User.query.filter_by(username=username).first():
|
||||
flash('User already exists.')
|
||||
return redirect(url_for('main.settings'))
|
||||
|
||||
# Create a new user
|
||||
new_user = User(username=username, password=password, role=role)
|
||||
db.session.add(new_user)
|
||||
db.session.commit()
|
||||
|
||||
flash('User created successfully.')
|
||||
return redirect(url_for('main.settings'))
|
||||
|
||||
@bp.route('/edit_user', methods=['POST'])
|
||||
def edit_user():
|
||||
if 'role' not in session or session['role'] != 'superadmin':
|
||||
flash('Access denied: Superadmin only.')
|
||||
return redirect(url_for('main.settings'))
|
||||
|
||||
user_id = request.form['user_id']
|
||||
password = request.form['password']
|
||||
role = request.form['role']
|
||||
|
||||
# Fetch the user from the database
|
||||
user = User.query.get(user_id)
|
||||
if not user:
|
||||
flash('User not found.')
|
||||
return redirect(url_for('main.settings'))
|
||||
|
||||
# Update the user's details
|
||||
if password:
|
||||
user.password = password
|
||||
user.role = role
|
||||
db.session.commit()
|
||||
|
||||
flash('User updated successfully.')
|
||||
return redirect(url_for('main.settings'))
|
||||
|
||||
@bp.route('/delete_user', methods=['POST'])
|
||||
def delete_user():
|
||||
if 'role' not in session or session['role'] != 'superadmin':
|
||||
flash('Access denied: Superadmin only.')
|
||||
return redirect(url_for('main.settings'))
|
||||
|
||||
user_id = request.form['user_id']
|
||||
|
||||
# Fetch the user from the database
|
||||
user = User.query.get(user_id)
|
||||
if not user:
|
||||
flash('User not found.')
|
||||
return redirect(url_for('main.settings'))
|
||||
|
||||
# Delete the user
|
||||
db.session.delete(user)
|
||||
db.session.commit()
|
||||
|
||||
flash('User deleted successfully.')
|
||||
return redirect(url_for('main.settings'))
|
||||
@@ -31,4 +31,93 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
themeToggle.textContent = 'Change to light theme';
|
||||
}
|
||||
}
|
||||
|
||||
const createUserBtn = document.getElementById('create-user-btn');
|
||||
const createUserPopup = document.getElementById('create-user-popup');
|
||||
const closePopupBtn = document.getElementById('close-popup-btn');
|
||||
|
||||
// Open the popup
|
||||
createUserBtn.addEventListener('click', () => {
|
||||
createUserPopup.style.display = 'flex';
|
||||
});
|
||||
|
||||
// Close the popup
|
||||
closePopupBtn.addEventListener('click', () => {
|
||||
createUserPopup.style.display = 'none';
|
||||
});
|
||||
|
||||
// Close the popup when clicking outside the popup content
|
||||
createUserPopup.addEventListener('click', (e) => {
|
||||
if (e.target === createUserPopup) {
|
||||
createUserPopup.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
const editButtons = document.querySelectorAll('.edit-btn');
|
||||
const editUserPopup = document.getElementById('edit-user-popup');
|
||||
const closeEditPopupBtn = document.getElementById('close-edit-popup-btn');
|
||||
|
||||
// Open the edit user popup
|
||||
editButtons.forEach((button) => {
|
||||
button.addEventListener('click', (e) => {
|
||||
const userElement = e.target.closest('li');
|
||||
const username = userElement.querySelector('.user-name').textContent;
|
||||
const role = userElement.querySelector('.user-role').textContent.split(': ')[1];
|
||||
const userId = userElement.dataset.userId;
|
||||
|
||||
// Populate the form fields
|
||||
document.getElementById('edit-user-id').value = userId;
|
||||
document.getElementById('edit-username').value = username;
|
||||
document.getElementById('edit-role').value = role;
|
||||
|
||||
// Show the popup
|
||||
editUserPopup.style.display = 'flex';
|
||||
});
|
||||
});
|
||||
|
||||
// Close the edit user popup
|
||||
closeEditPopupBtn.addEventListener('click', () => {
|
||||
editUserPopup.style.display = 'none';
|
||||
});
|
||||
|
||||
// Close the popup when clicking outside the popup content
|
||||
editUserPopup.addEventListener('click', (e) => {
|
||||
if (e.target === editUserPopup) {
|
||||
editUserPopup.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
const deleteButtons = document.querySelectorAll('.delete-btn');
|
||||
const deleteUserPopup = document.getElementById('delete-user-popup');
|
||||
const closeDeletePopupBtn = document.getElementById('close-delete-popup-btn');
|
||||
const deleteUsernameSpan = document.getElementById('delete-username');
|
||||
const deleteUserIdInput = document.getElementById('delete-user-id');
|
||||
|
||||
// Open the delete user popup
|
||||
deleteButtons.forEach((button) => {
|
||||
button.addEventListener('click', (e) => {
|
||||
const userElement = e.target.closest('li');
|
||||
const username = userElement.querySelector('.user-name').textContent;
|
||||
const userId = userElement.dataset.userId;
|
||||
|
||||
// Populate the popup with user details
|
||||
deleteUsernameSpan.textContent = username;
|
||||
deleteUserIdInput.value = userId;
|
||||
|
||||
// Show the popup
|
||||
deleteUserPopup.style.display = 'flex';
|
||||
});
|
||||
});
|
||||
|
||||
// Close the delete user popup
|
||||
closeDeletePopupBtn.addEventListener('click', () => {
|
||||
deleteUserPopup.style.display = 'none';
|
||||
});
|
||||
|
||||
// Close the popup when clicking outside the popup content
|
||||
deleteUserPopup.addEventListener('click', (e) => {
|
||||
if (e.target === deleteUserPopup) {
|
||||
deleteUserPopup.style.display = 'none';
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -6,7 +6,7 @@ body {
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 98%;
|
||||
width: 100%;
|
||||
margin: auto;
|
||||
overflow: hidden;
|
||||
padding: 0; /* Remove padding */
|
||||
@@ -17,10 +17,11 @@ body {
|
||||
|
||||
.login-page {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
align-items: center; /* Vertically center the content */
|
||||
justify-content: space-between; /* Space between the logo and the form container */
|
||||
height: 100vh; /* Full height of the viewport */
|
||||
background-color: #f4f4f9;
|
||||
padding: 0 20px; /* Add padding to the sides */
|
||||
}
|
||||
|
||||
header {
|
||||
@@ -92,12 +93,13 @@ header {
|
||||
}
|
||||
|
||||
.form-container {
|
||||
width: 600px; /* Set a fixed width for the login container */
|
||||
width: 600px; /* Fixed width for the login container */
|
||||
background: #fff;
|
||||
padding: 15px 30px 15px 15px; /* Add 30px padding to the right */
|
||||
padding: 15px 30px; /* Add padding inside the container */
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||
margin: 0 0 0 20px; /* Move the container closer to the picture */
|
||||
margin: 0; /* Remove any extra margin */
|
||||
align-self: center; /* Vertically center the form container */
|
||||
}
|
||||
|
||||
.form-container h2 {
|
||||
@@ -228,18 +230,17 @@ body.dark-mode .card {
|
||||
|
||||
/* Common card styles */
|
||||
.card {
|
||||
width: 400px; /* Fixed width */
|
||||
height: 150px; /* Fixed height */
|
||||
width: 600px;
|
||||
background: #fff;
|
||||
border-radius: 5px;
|
||||
padding: 20px;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||
margin: 20px auto; /* Center the card horizontally */
|
||||
margin: 20px auto;
|
||||
text-align: center;
|
||||
transition: background-color 0.3s ease, color 0.3s ease, border 0.3s ease;
|
||||
}
|
||||
|
||||
.card h3 {
|
||||
margin-bottom: 10px;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
@@ -261,4 +262,134 @@ body.dark-mode .card {
|
||||
|
||||
.card .btn:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
|
||||
.user-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0 0 20px 0;
|
||||
}
|
||||
|
||||
.user-list li {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: 1em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.user-role {
|
||||
font-size: 0.9em;
|
||||
color: #555;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 5px 10px;
|
||||
font-size: 1em;
|
||||
color: #fff;
|
||||
background-color: #007bff;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
|
||||
.create-btn {
|
||||
margin-top: 20px;
|
||||
background-color: #28a745;
|
||||
}
|
||||
|
||||
.create-btn:hover {
|
||||
background-color: #218838;
|
||||
}
|
||||
|
||||
.popup {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* Light mode styles for pop-ups */
|
||||
body.light-mode .popup-content {
|
||||
background: #fff;
|
||||
color: #000;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
/* Dark mode styles for pop-ups */
|
||||
body.dark-mode .popup-content {
|
||||
background: #1e1e1e;
|
||||
color: #fff;
|
||||
border: 1px solid #444;
|
||||
}
|
||||
|
||||
/* Common styles for pop-ups */
|
||||
.popup-content {
|
||||
padding: 20px;
|
||||
border-radius: 5px;
|
||||
width: 400px;
|
||||
text-align: center;
|
||||
transition: background-color 0.3s ease, color 0.3s ease, border 0.3s ease;
|
||||
}
|
||||
|
||||
.popup-content h3 {
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.popup-content form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.popup-content label {
|
||||
margin-bottom: 5px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.popup-content input,
|
||||
.popup-content select {
|
||||
margin-bottom: 15px;
|
||||
padding: 10px;
|
||||
font-size: 1em;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.popup-content input[readonly] {
|
||||
background-color: #e9ecef;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.cancel-btn {
|
||||
background-color: #dc3545;
|
||||
}
|
||||
|
||||
.cancel-btn:hover {
|
||||
background-color: #c82333;
|
||||
}
|
||||
|
||||
.delete-confirm-btn {
|
||||
background-color: #dc3545;
|
||||
}
|
||||
|
||||
.delete-confirm-btn:hover {
|
||||
background-color: #c82333;
|
||||
}
|
||||
@@ -10,10 +10,10 @@
|
||||
<div class="form-container">
|
||||
<h2>Login</h2>
|
||||
<form method="POST">
|
||||
<label for="email">Email:</label>
|
||||
<input type="email" name="email" required>
|
||||
<label for="username">Username:</label>
|
||||
<input type="text" id="username" name="username" required>
|
||||
<label for="password">Password:</label>
|
||||
<input type="password" name="password" required>
|
||||
<input type="password" id="password" name="password" required>
|
||||
<button type="submit">Login</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
6
py_app/app/templates/quality.html
Normal file
6
py_app/app/templates/quality.html
Normal file
@@ -0,0 +1,6 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Quality Module{% endblock %}
|
||||
{% block content %}
|
||||
<h2>Quality Module</h2>
|
||||
<p>Welcome to the Quality Module.</p>
|
||||
{% endblock %}
|
||||
6
py_app/app/templates/scan.html
Normal file
6
py_app/app/templates/scan.html
Normal file
@@ -0,0 +1,6 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Scan Module{% endblock %}
|
||||
{% block content %}
|
||||
<h2>Scan Module</h2>
|
||||
<p>Welcome to the Scan Module.</p>
|
||||
{% endblock %}
|
||||
@@ -3,6 +3,77 @@
|
||||
{% block title %}Settings{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h2>Settings Page</h2>
|
||||
<p>This is the settings page. Add your settings here.</p>
|
||||
<div class="card">
|
||||
<h3>Manage Users</h3>
|
||||
<ul class="user-list">
|
||||
{% for user in users %}
|
||||
<li data-user-id="{{ user.id }}">
|
||||
<span class="user-name">{{ user.username }}</span>
|
||||
<span class="user-role">Role: {{ user.role }}</span>
|
||||
<button class="btn edit-btn">Edit Rights</button>
|
||||
<button class="btn delete-btn">Delete User</button>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<button id="create-user-btn" class="btn create-btn">Create User</button>
|
||||
</div>
|
||||
|
||||
<!-- Popup for creating a new user -->
|
||||
<div id="create-user-popup" class="popup">
|
||||
<div class="popup-content">
|
||||
<h3>Create User</h3>
|
||||
<form id="create-user-form" method="POST" action="{{ url_for('main.create_user') }}">
|
||||
<label for="username">Username:</label>
|
||||
<input type="text" id="username" name="username" required>
|
||||
<label for="password">Password:</label>
|
||||
<input type="password" id="password" name="password" required>
|
||||
<label for="role">Role:</label>
|
||||
<select id="role" name="role" required>
|
||||
<option value="superadmin">Superadmin</option>
|
||||
<option value="administrator">Administrator</option>
|
||||
<option value="quality">Quality</option>
|
||||
<option value="warehouse">Warehouse</option>
|
||||
<option value="scan">Scan</option>
|
||||
</select>
|
||||
<button type="submit" class="btn">Create</button>
|
||||
<button type="button" id="close-popup-btn" class="btn cancel-btn">Cancel</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Popup for editing a user -->
|
||||
<div id="edit-user-popup" class="popup">
|
||||
<div class="popup-content">
|
||||
<h3>Edit User</h3>
|
||||
<form id="edit-user-form" method="POST" action="{{ url_for('main.edit_user') }}">
|
||||
<input type="hidden" id="edit-user-id" name="user_id">
|
||||
<label for="edit-username">Username:</label>
|
||||
<input type="text" id="edit-username" name="username" readonly>
|
||||
<label for="edit-password">New Password:</label>
|
||||
<input type="password" id="edit-password" name="password">
|
||||
<label for="edit-role">Role:</label>
|
||||
<select id="edit-role" name="role" required>
|
||||
<option value="superadmin">Superadmin</option>
|
||||
<option value="administrator">Administrator</option>
|
||||
<option value="quality">Quality</option>
|
||||
<option value="warehouse">Warehouse</option>
|
||||
<option value="scan">Scan</option>
|
||||
</select>
|
||||
<button type="submit" class="btn">Update</button>
|
||||
<button type="button" id="close-edit-popup-btn" class="btn cancel-btn">Cancel</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Popup for confirming user deletion -->
|
||||
<div id="delete-user-popup" class="popup">
|
||||
<div class="popup-content">
|
||||
<h3>Do you really want to delete the user <span id="delete-username"></span>?</h3>
|
||||
<form id="delete-user-form" method="POST" action="{{ url_for('main.delete_user') }}">
|
||||
<input type="hidden" id="delete-user-id" name="user_id">
|
||||
<button type="submit" class="btn delete-confirm-btn">Yes</button>
|
||||
<button type="button" id="close-delete-popup-btn" class="btn cancel-btn">No</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
6
py_app/app/templates/warehouse.html
Normal file
6
py_app/app/templates/warehouse.html
Normal file
@@ -0,0 +1,6 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Warehouse Module{% endblock %}
|
||||
{% block content %}
|
||||
<h2>Warehouse Module</h2>
|
||||
<p>Welcome to the Warehouse Module.</p>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user