created user settings in the settings page
This commit is contained in:
@@ -1,10 +1,20 @@
|
|||||||
from flask import Flask
|
from flask import Flask
|
||||||
|
from flask_sqlalchemy import SQLAlchemy
|
||||||
|
|
||||||
|
db = SQLAlchemy()
|
||||||
|
|
||||||
def create_app():
|
def create_app():
|
||||||
app = Flask(__name__)
|
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
|
from .routes import bp
|
||||||
app.register_blueprint(bp)
|
app.register_blueprint(bp)
|
||||||
|
|
||||||
|
with app.app_context():
|
||||||
|
db.create_all() # Create database tables if they don't exist
|
||||||
|
|
||||||
return app
|
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 flask import Blueprint, render_template, redirect, url_for, request, flash, session
|
||||||
|
from .models import User
|
||||||
|
from . import db
|
||||||
|
|
||||||
bp = Blueprint('main', __name__)
|
bp = Blueprint('main', __name__)
|
||||||
|
|
||||||
# Dummy user data
|
|
||||||
users = {"admin@home.com": "1234"}
|
|
||||||
|
|
||||||
@bp.route('/login', methods=['GET', 'POST'])
|
@bp.route('/login', methods=['GET', 'POST'])
|
||||||
def login():
|
def login():
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
email = request.form['email']
|
username = request.form['username']
|
||||||
password = request.form['password']
|
password = request.form['password']
|
||||||
if email in users and users[email] == password:
|
user = User.query.filter_by(username=username, password=password).first()
|
||||||
session['user'] = email
|
if user:
|
||||||
|
session['user'] = user.username
|
||||||
|
session['role'] = user.role
|
||||||
return redirect(url_for('main.dashboard'))
|
return redirect(url_for('main.dashboard'))
|
||||||
else:
|
else:
|
||||||
flash('Invalid credentials. Please try again.')
|
flash('Invalid credentials. Please try again.')
|
||||||
@@ -23,11 +24,108 @@ def dashboard():
|
|||||||
return redirect(url_for('main.login'))
|
return redirect(url_for('main.login'))
|
||||||
return render_template('dashboard.html')
|
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')
|
@bp.route('/logout')
|
||||||
def logout():
|
def logout():
|
||||||
session.pop('user', None)
|
session.pop('user', None)
|
||||||
|
session.pop('role', None)
|
||||||
return redirect(url_for('main.login'))
|
return redirect(url_for('main.login'))
|
||||||
|
|
||||||
@bp.route('/settings')
|
@bp.route('/create_user', methods=['POST'])
|
||||||
def settings():
|
def create_user():
|
||||||
return render_template('settings.html')
|
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';
|
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 {
|
.container {
|
||||||
width: 98%;
|
width: 100%;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding: 0; /* Remove padding */
|
padding: 0; /* Remove padding */
|
||||||
@@ -17,10 +17,11 @@ body {
|
|||||||
|
|
||||||
.login-page {
|
.login-page {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center; /* Vertically center the content */
|
||||||
justify-content: center;
|
justify-content: space-between; /* Space between the logo and the form container */
|
||||||
height: 100vh;
|
height: 100vh; /* Full height of the viewport */
|
||||||
background-color: #f4f4f9;
|
background-color: #f4f4f9;
|
||||||
|
padding: 0 20px; /* Add padding to the sides */
|
||||||
}
|
}
|
||||||
|
|
||||||
header {
|
header {
|
||||||
@@ -92,12 +93,13 @@ header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.form-container {
|
.form-container {
|
||||||
width: 600px; /* Set a fixed width for the login container */
|
width: 600px; /* Fixed width for the login container */
|
||||||
background: #fff;
|
background: #fff;
|
||||||
padding: 15px 30px 15px 15px; /* Add 30px padding to the right */
|
padding: 15px 30px; /* Add padding inside the container */
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
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 {
|
.form-container h2 {
|
||||||
@@ -228,18 +230,17 @@ body.dark-mode .card {
|
|||||||
|
|
||||||
/* Common card styles */
|
/* Common card styles */
|
||||||
.card {
|
.card {
|
||||||
width: 400px; /* Fixed width */
|
width: 600px;
|
||||||
height: 150px; /* Fixed height */
|
background: #fff;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||||
margin: 20px auto; /* Center the card horizontally */
|
margin: 20px auto;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
transition: background-color 0.3s ease, color 0.3s ease, border 0.3s ease;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.card h3 {
|
.card h3 {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 20px;
|
||||||
font-size: 1.5em;
|
font-size: 1.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,4 +262,134 @@ body.dark-mode .card {
|
|||||||
|
|
||||||
.card .btn:hover {
|
.card .btn:hover {
|
||||||
background-color: #0056b3;
|
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">
|
<div class="form-container">
|
||||||
<h2>Login</h2>
|
<h2>Login</h2>
|
||||||
<form method="POST">
|
<form method="POST">
|
||||||
<label for="email">Email:</label>
|
<label for="username">Username:</label>
|
||||||
<input type="email" name="email" required>
|
<input type="text" id="username" name="username" required>
|
||||||
<label for="password">Password:</label>
|
<label for="password">Password:</label>
|
||||||
<input type="password" name="password" required>
|
<input type="password" id="password" name="password" required>
|
||||||
<button type="submit">Login</button>
|
<button type="submit">Login</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</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 title %}Settings{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h2>Settings Page</h2>
|
<div class="card">
|
||||||
<p>This is the settings page. Add your settings here.</p>
|
<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 %}
|
{% 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 %}
|
||||||
BIN
py_app/instance/users.db
Normal file
BIN
py_app/instance/users.db
Normal file
Binary file not shown.
@@ -1,4 +1,5 @@
|
|||||||
Flask==2.2.2
|
Flask==2.2.2
|
||||||
Flask-SSLify==0.1.5
|
Flask-SSLify==0.1.5
|
||||||
Werkzeug==2.2.2
|
Werkzeug==2.2.2
|
||||||
gunicorn==20.1.0
|
gunicorn==20.1.0
|
||||||
|
flask-sqlalchemy==2.5.1
|
||||||
|
|||||||
22
py_app/seed.py
Normal file
22
py_app/seed.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
from app import create_app, db
|
||||||
|
from app.models import User
|
||||||
|
|
||||||
|
app = create_app()
|
||||||
|
|
||||||
|
with app.app_context():
|
||||||
|
# Add default users
|
||||||
|
users = [
|
||||||
|
User(username='superadmin', password='superadmin123', role='superadmin'),
|
||||||
|
User(username='admin', password='admin123', role='administrator'),
|
||||||
|
User(username='quality_user', password='quality123', role='quality'),
|
||||||
|
User(username='warehouse_user', password='warehouse123', role='warehouse'),
|
||||||
|
User(username='scan_user', password='scan123', role='scan'),
|
||||||
|
]
|
||||||
|
|
||||||
|
# Add users to the database
|
||||||
|
for user in users:
|
||||||
|
if not User.query.filter_by(username=user.username).first():
|
||||||
|
db.session.add(user)
|
||||||
|
|
||||||
|
db.session.commit()
|
||||||
|
print("Database seeded with default users.")
|
||||||
Reference in New Issue
Block a user