Merge branch 'main' of https://gitea.hrasci.eu/ondra/vwa_project
# Conflicts: # web/templates/home.html
This commit is contained in:
BIN
drateny_model.png
Normal file
BIN
drateny_model.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 MiB |
165
web/app.py
165
web/app.py
@@ -1,8 +1,10 @@
|
|||||||
from flask import Flask, render_template, request, redirect, url_for, flash, session
|
from flask import Flask, render_template, request, redirect, url_for, flash, session
|
||||||
import logging
|
import logging
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import sqlite3
|
|
||||||
from werkzeug.security import check_password_hash, generate_password_hash
|
from werkzeug.security import check_password_hash, generate_password_hash
|
||||||
|
from db import get_db_connection, fetch_users, fetch_orders, fetch_roles, fetch_repairs, fetch_employees
|
||||||
|
from auth import encrypt_password, check_password
|
||||||
|
import random
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.secret_key = 'aezakmi'
|
app.secret_key = 'aezakmi'
|
||||||
@@ -30,32 +32,6 @@ def log_request(response):
|
|||||||
app.logger.info(f"{client_ip} - - [{request.date}] \"{request.method} {request.full_path} {request.environ.get('SERVER_PROTOCOL')}\" {response.status_code}")
|
app.logger.info(f"{client_ip} - - [{request.date}] \"{request.method} {request.full_path} {request.environ.get('SERVER_PROTOCOL')}\" {response.status_code}")
|
||||||
return response
|
return response
|
||||||
# ----------------- End of logging part -----------------
|
# ----------------- End of logging part -----------------
|
||||||
# Database connection
|
|
||||||
def get_db_connection():
|
|
||||||
conn = sqlite3.connect('./static/db/db.sqlite')
|
|
||||||
conn.row_factory = sqlite3.Row
|
|
||||||
return conn
|
|
||||||
|
|
||||||
# Function to convert row to dictionary
|
|
||||||
def dict_from_row(row):
|
|
||||||
return {key: row[key] for key in row.keys()}
|
|
||||||
|
|
||||||
# Function to fetch users from database
|
|
||||||
def fetch_users(role_id):
|
|
||||||
conn = get_db_connection()
|
|
||||||
users = conn.execute('SELECT * FROM Zamestnanci WHERE Role_ID >= ?', (role_id,)).fetchall()
|
|
||||||
users = [dict_from_row(user) for user in users]
|
|
||||||
conn.close()
|
|
||||||
app.logger.debug(f"Fetched users: {users}")
|
|
||||||
return users
|
|
||||||
|
|
||||||
# Function to encrypt password
|
|
||||||
def encrypt_password(password):
|
|
||||||
return generate_password_hash(password)
|
|
||||||
|
|
||||||
# Function to check password
|
|
||||||
def check_password(stored_password, provided_password):
|
|
||||||
return check_password_hash(stored_password, provided_password)
|
|
||||||
|
|
||||||
# Routes
|
# Routes
|
||||||
@app.route('/logout')
|
@app.route('/logout')
|
||||||
@@ -117,7 +93,9 @@ def administrator():
|
|||||||
flash('Nemáte oprávnění k přístupu na tuto stránku.', 'error')
|
flash('Nemáte oprávnění k přístupu na tuto stránku.', 'error')
|
||||||
return redirect(url_for('login'))
|
return redirect(url_for('login'))
|
||||||
users = fetch_users(session.get('role_id'))
|
users = fetch_users(session.get('role_id'))
|
||||||
return render_template('administrator.html', users=users)
|
orders = fetch_orders()
|
||||||
|
roles = fetch_roles()
|
||||||
|
return render_template('administrator.html', users=users, orders=orders, roles=roles)
|
||||||
|
|
||||||
@app.route('/create_user', methods=['GET', 'POST'])
|
@app.route('/create_user', methods=['GET', 'POST'])
|
||||||
def create_user():
|
def create_user():
|
||||||
@@ -205,6 +183,137 @@ def delete_user(user_id):
|
|||||||
conn.close()
|
conn.close()
|
||||||
return redirect(url_for('administrator'))
|
return redirect(url_for('administrator'))
|
||||||
|
|
||||||
|
@app.route('/edit_order/<int:order_id>', methods=['GET', 'POST'])
|
||||||
|
def edit_order(order_id):
|
||||||
|
if not session.get('logged_in') or session.get('role_id') != 1:
|
||||||
|
flash('Nemáte oprávnění k přístupu na tuto stránku.', 'error')
|
||||||
|
return redirect(url_for('login'))
|
||||||
|
|
||||||
|
conn = get_db_connection()
|
||||||
|
order = conn.execute('SELECT * FROM Objednavky WHERE ID_Objednavky = ?', (order_id,)).fetchone()
|
||||||
|
|
||||||
|
if request.method == 'POST':
|
||||||
|
stav = request.form['stav']
|
||||||
|
id_zamestnance = request.form['id_zamestnance']
|
||||||
|
popis = request.form['popis']
|
||||||
|
datum_konce = request.form['datum_konce']
|
||||||
|
|
||||||
|
conn.execute('UPDATE Objednavky SET Stav = ?, ID_Zamestnance = ?, Popis = ?, Datum_Konce = ? WHERE ID_Objednavky = ?',
|
||||||
|
(stav, id_zamestnance, popis, datum_konce, order_id))
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
flash('Objednávka byla úspěšně aktualizována.')
|
||||||
|
return redirect(url_for('administrator'))
|
||||||
|
|
||||||
|
conn.close()
|
||||||
|
return render_template('edit_order.html', order=order)
|
||||||
|
|
||||||
|
@app.route('/repairs')
|
||||||
|
def repairs():
|
||||||
|
if not session.get('logged_in'):
|
||||||
|
flash('Nemáte oprávnění k přístupu na tuto stránku.', 'error')
|
||||||
|
return redirect(url_for('login'))
|
||||||
|
repairs = fetch_repairs()
|
||||||
|
return render_template('repairs.html', repairs=repairs)
|
||||||
|
|
||||||
|
@app.route('/create_repair', methods=['GET', 'POST'])
|
||||||
|
def create_repair():
|
||||||
|
if not session.get('logged_in') or session.get('role_id') != 1:
|
||||||
|
flash('Nemáte oprávnění k přístupu na tuto stránku.', 'error')
|
||||||
|
return redirect(url_for('login'))
|
||||||
|
|
||||||
|
if request.method == 'POST':
|
||||||
|
id_zamestnance = request.form['id_zamestnance']
|
||||||
|
nazev = request.form['nazev']
|
||||||
|
popis = request.form['popis']
|
||||||
|
|
||||||
|
conn = get_db_connection()
|
||||||
|
try:
|
||||||
|
conn.execute('INSERT INTO Opravy (ID_Zamestnance, Nazev, Popis) VALUES (?, ?, ?)',
|
||||||
|
(id_zamestnance, nazev, popis))
|
||||||
|
conn.commit()
|
||||||
|
flash('Nová oprava byla úspěšně vytvořena.', 'success')
|
||||||
|
return redirect(url_for('repairs'))
|
||||||
|
except sqlite3.Error as e:
|
||||||
|
flash(f'Chyba při vytváření opravy: {e}', 'error')
|
||||||
|
finally:
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
employees = fetch_employees()
|
||||||
|
return render_template('create_repair.html', employees=employees)
|
||||||
|
|
||||||
|
@app.route('/edit_repair/<int:repair_id>', methods=['GET', 'POST'])
|
||||||
|
def edit_repair(repair_id):
|
||||||
|
if not session.get('logged_in') or session.get('role_id') != 1:
|
||||||
|
flash('Nemáte oprávnění k přístupu na tuto stránku.', 'error')
|
||||||
|
return redirect(url_for('login'))
|
||||||
|
|
||||||
|
conn = get_db_connection()
|
||||||
|
repair = conn.execute('SELECT * FROM Opravy WHERE ID_Opravy = ?', (repair_id,)).fetchone()
|
||||||
|
|
||||||
|
if request.method == 'POST':
|
||||||
|
id_zamestnance = request.form['id_zamestnance']
|
||||||
|
nazev = request.form['nazev']
|
||||||
|
popis = request.form['popis']
|
||||||
|
|
||||||
|
conn.execute('UPDATE Opravy SET ID_Zamestnance = ?, Nazev = ?, Popis = ? WHERE ID_Opravy = ?',
|
||||||
|
(id_zamestnance, nazev, popis, repair_id))
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
flash('Oprava byla úspěšně aktualizována.')
|
||||||
|
return redirect(url_for('repairs'))
|
||||||
|
|
||||||
|
employees = fetch_employees()
|
||||||
|
conn.close()
|
||||||
|
return render_template('edit_repair.html', repair=repair, employees=employees)
|
||||||
|
|
||||||
|
@app.route('/delete_repair/<int:repair_id>', methods=['POST'])
|
||||||
|
def delete_repair(repair_id):
|
||||||
|
if not session.get('logged_in') or session.get('role_id') != 1:
|
||||||
|
flash('Nemáte oprávnění k přístupu na tuto stránku.', 'error')
|
||||||
|
return redirect(url_for('login'))
|
||||||
|
|
||||||
|
conn = get_db_connection()
|
||||||
|
conn.execute('DELETE FROM Opravy WHERE ID_Opravy = ?', (repair_id,))
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
flash('Oprava byla úspěšně smazána.')
|
||||||
|
return redirect(url_for('repairs'))
|
||||||
|
|
||||||
|
@app.route('/create_reservation', methods=['POST'])
|
||||||
|
def create_reservation():
|
||||||
|
full_name = request.form['fullName']
|
||||||
|
email = request.form['email']
|
||||||
|
date = request.form['date']
|
||||||
|
description = request.form['description']
|
||||||
|
|
||||||
|
# Convert date to DD.MM.YYYY format
|
||||||
|
formatted_date = datetime.strptime(date, '%Y-%m-%d').strftime('%d.%m.%Y')
|
||||||
|
|
||||||
|
conn = get_db_connection()
|
||||||
|
try:
|
||||||
|
# Fetch a random user with role_id 2
|
||||||
|
user = conn.execute('SELECT ID_Uzivatele FROM Zamestnanci WHERE Role_ID = 2 ORDER BY RANDOM() LIMIT 1').fetchone()
|
||||||
|
if user:
|
||||||
|
user_id = user['ID_Uzivatele']
|
||||||
|
else:
|
||||||
|
user_id = 1 # Fallback to a default user ID if no user with role_id 2 is found
|
||||||
|
|
||||||
|
conn.execute('INSERT INTO Objednavky (Stav, ID_Zamestnance, Popis, ID_Vozidla, Datum_Zacatku, Cena) VALUES (?, ?, ?, ?, ?, ?)',
|
||||||
|
('Nová', user_id, description, 1, formatted_date, 0.0)) # Example values for ID_Vozidla
|
||||||
|
conn.commit()
|
||||||
|
flash('Rezervace byla úspěšně vytvořena.', 'success')
|
||||||
|
except sqlite3.Error as e:
|
||||||
|
flash(f'Chyba při vytváření rezervace: {e}', 'error')
|
||||||
|
finally:
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
return redirect(url_for('home'))
|
||||||
|
|
||||||
# Always redirect back home
|
# Always redirect back home
|
||||||
@app.errorhandler(404)
|
@app.errorhandler(404)
|
||||||
def default_page(e):
|
def default_page(e):
|
||||||
|
|||||||
8
web/auth.py
Normal file
8
web/auth.py
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
from werkzeug.security import check_password_hash, generate_password_hash
|
||||||
|
|
||||||
|
def encrypt_password(password):
|
||||||
|
return generate_password_hash(password)
|
||||||
|
|
||||||
|
def check_password(stored_password, provided_password):
|
||||||
|
return check_password_hash(stored_password, provided_password)
|
||||||
65
web/db.py
Normal file
65
web/db.py
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
|
||||||
|
import sqlite3
|
||||||
|
from flask import current_app as app
|
||||||
|
|
||||||
|
def get_db_connection():
|
||||||
|
conn = sqlite3.connect('./static/db/db.sqlite')
|
||||||
|
conn.row_factory = sqlite3.Row
|
||||||
|
return conn
|
||||||
|
|
||||||
|
def dict_from_row(row):
|
||||||
|
return {key: row[key] for key in row.keys()}
|
||||||
|
|
||||||
|
def fetch_users(role_id):
|
||||||
|
conn = get_db_connection()
|
||||||
|
users = conn.execute('SELECT * FROM Zamestnanci WHERE Role_ID >= ?', (role_id,)).fetchall()
|
||||||
|
users = [dict_from_row(user) for user in users]
|
||||||
|
conn.close()
|
||||||
|
app.logger.debug(f"Fetched users: {users}")
|
||||||
|
return users
|
||||||
|
|
||||||
|
def fetch_orders():
|
||||||
|
conn = get_db_connection()
|
||||||
|
orders = conn.execute('SELECT * FROM Objednavky').fetchall()
|
||||||
|
orders = [dict_from_row(order) for order in orders]
|
||||||
|
conn.close()
|
||||||
|
app.logger.debug(f"Fetched orders: {orders}")
|
||||||
|
return orders
|
||||||
|
|
||||||
|
def fetch_roles():
|
||||||
|
conn = get_db_connection()
|
||||||
|
roles = conn.execute('SELECT * FROM Role').fetchall()
|
||||||
|
roles = [dict_from_row(role) for role in roles]
|
||||||
|
conn.close()
|
||||||
|
app.logger.debug(f"Fetched roles: {roles}")
|
||||||
|
return roles
|
||||||
|
|
||||||
|
def fetch_repairs():
|
||||||
|
conn = get_db_connection()
|
||||||
|
repairs = conn.execute('''
|
||||||
|
SELECT Opravy.ID_Opravy, Zamestnanci.Jmeno, Zamestnanci.Prijmeni, Opravy.Nazev, Opravy.Popis
|
||||||
|
FROM Opravy
|
||||||
|
JOIN Zamestnanci ON Opravy.ID_Zamestnance = Zamestnanci.ID_Uzivatele
|
||||||
|
''').fetchall()
|
||||||
|
repairs = [dict_from_row(repair) for repair in repairs]
|
||||||
|
|
||||||
|
for repair in repairs:
|
||||||
|
products = conn.execute('''
|
||||||
|
SELECT Produkty.Nazev, Pouzite_Produkty.Pocet_Produktu
|
||||||
|
FROM Pouzite_Produkty
|
||||||
|
JOIN Produkty ON Pouzite_Produkty.ID_Produktu = Produkty.ID_Produktu
|
||||||
|
WHERE Pouzite_Produkty.ID_Opravy = ?
|
||||||
|
''', (repair['ID_Opravy'],)).fetchall()
|
||||||
|
repair['products'] = [dict_from_row(product) for product in products]
|
||||||
|
|
||||||
|
conn.close()
|
||||||
|
app.logger.debug(f"Fetched repairs: {repairs}")
|
||||||
|
return repairs
|
||||||
|
|
||||||
|
def fetch_employees():
|
||||||
|
conn = get_db_connection()
|
||||||
|
employees = conn.execute('SELECT ID_Uzivatele, Jmeno, Prijmeni FROM Zamestnanci').fetchall()
|
||||||
|
employees = [dict_from_row(employee) for employee in employees]
|
||||||
|
conn.close()
|
||||||
|
app.logger.debug(f"Fetched employees: {employees}")
|
||||||
|
return employees
|
||||||
@@ -75,6 +75,26 @@ footer {
|
|||||||
right: 0;
|
right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.navbar-users-table {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
background-color: #444;
|
||||||
|
padding: 10px;
|
||||||
|
margin-top: 1.5em;
|
||||||
|
border-top-left-radius: 0.5em;
|
||||||
|
border-top-right-radius: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-orders-table {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
background-color: #444;
|
||||||
|
padding: 10px;
|
||||||
|
margin-top: 1.5em;
|
||||||
|
border-top-left-radius: 0.5em;
|
||||||
|
border-top-right-radius: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
/* Navbar */
|
/* Navbar */
|
||||||
.navbar {
|
.navbar {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -115,6 +135,7 @@ footer {
|
|||||||
.container {
|
.container {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
width: 75%;
|
width: 75%;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Section styles */
|
/* Section styles */
|
||||||
@@ -378,9 +399,8 @@ footer {
|
|||||||
table {
|
table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
margin: 20px 0;
|
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
text-align: left;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
table th, table td {
|
table th, table td {
|
||||||
@@ -519,3 +539,28 @@ table tr:hover {
|
|||||||
border-bottom-left-radius: 1em;
|
border-bottom-left-radius: 1em;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Dropdown menu styles */
|
||||||
|
select {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
margin: 5px 0 20px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: #555;
|
||||||
|
color: white;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
select:focus {
|
||||||
|
outline: none;
|
||||||
|
box-shadow: 0 0 5px rgba(81, 203, 238, 1);
|
||||||
|
border: 1px solid rgba(81, 203, 238, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Option styles */
|
||||||
|
option {
|
||||||
|
background-color: #333;
|
||||||
|
color: white;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|||||||
76
web/static/db/databaze.txt
Normal file
76
web/static/db/databaze.txt
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
-- Table for Roles
|
||||||
|
CREATE TABLE Role (
|
||||||
|
Role_ID INTEGER PRIMARY KEY,
|
||||||
|
Nazev TEXT NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Table for Employees (Zamestnanci)
|
||||||
|
CREATE TABLE Zamestnanci (
|
||||||
|
ID_Uzivatele INTEGER PRIMARY KEY,
|
||||||
|
Jmeno TEXT NOT NULL,
|
||||||
|
Prijmeni TEXT NOT NULL,
|
||||||
|
Role_ID INTEGER NOT NULL,
|
||||||
|
Heslo TEXT NOT NULL,
|
||||||
|
Email TEXT,
|
||||||
|
Username TEXT NOT NULL UNIQUE,
|
||||||
|
FOREIGN KEY (Role_ID) REFERENCES Role (Role_ID)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Table for Vehicles (Vozidla)
|
||||||
|
CREATE TABLE Vozidla (
|
||||||
|
ID_Vozidla INTEGER PRIMARY KEY,
|
||||||
|
Majitel TEXT NOT NULL,
|
||||||
|
Barva TEXT NOT NULL,
|
||||||
|
Typ TEXT NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Table for Orders (Objednavky)
|
||||||
|
CREATE TABLE Objednavky (
|
||||||
|
ID_Objednavky INTEGER PRIMARY KEY,
|
||||||
|
Stav TEXT NOT NULL,
|
||||||
|
ID_Zamestnance INTEGER NOT NULL,
|
||||||
|
Popis TEXT,
|
||||||
|
ID_Vozidla INTEGER NOT NULL,
|
||||||
|
Datum_Zacatku DATE NOT NULL,
|
||||||
|
Datum_Konce DATE,
|
||||||
|
Cena REAL NOT NULL,
|
||||||
|
FOREIGN KEY (ID_Zamestnance) REFERENCES Zamestnanci (ID_Uzivatele),
|
||||||
|
FOREIGN KEY (ID_Vozidla) REFERENCES Vozidla (ID_Vozidla)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Table for Repairs (Opravy)
|
||||||
|
CREATE TABLE Opravy (
|
||||||
|
ID_Opravy INTEGER PRIMARY KEY,
|
||||||
|
ID_Zamestnance INTEGER NOT NULL,
|
||||||
|
Nazev TEXT NOT NULL,
|
||||||
|
Popis TEXT,
|
||||||
|
FOREIGN KEY (ID_Zamestnance) REFERENCES Zamestnanci (ID_Uzivatele)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Linking table for Orders and Repairs (Objednavky_Opravy)
|
||||||
|
CREATE TABLE Objednavky_Opravy (
|
||||||
|
ID_Objednavky_Opravy INTEGER PRIMARY KEY,
|
||||||
|
ID_Objednavky INTEGER NOT NULL,
|
||||||
|
ID_Opravy INTEGER NOT NULL,
|
||||||
|
FOREIGN KEY (ID_Objednavky) REFERENCES Objednavky (ID_Objednavky),
|
||||||
|
FOREIGN KEY (ID_Opravy) REFERENCES Opravy (ID_Opravy)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Table for Products (Produkty)
|
||||||
|
CREATE TABLE Produkty (
|
||||||
|
ID_Produktu INTEGER PRIMARY KEY,
|
||||||
|
Minimalni_Zasoba INTEGER NOT NULL,
|
||||||
|
Momentalni_Zasoba INTEGER NOT NULL,
|
||||||
|
Nazev TEXT NOT NULL,
|
||||||
|
Popis TEXT
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Table for Product Usage (Pouzite_Produkty)
|
||||||
|
CREATE TABLE Pouzite_Produkty (
|
||||||
|
ID_Pouziti INTEGER PRIMARY KEY,
|
||||||
|
ID_Opravy INTEGER NOT NULL,
|
||||||
|
ID_Produktu INTEGER NOT NULL,
|
||||||
|
Pocet_Produktu INTEGER NOT NULL,
|
||||||
|
FOREIGN KEY (ID_Opravy) REFERENCES Opravy (ID_Opravy),
|
||||||
|
FOREIGN KEY (ID_Produktu) REFERENCES Produkty (ID_Produktu)
|
||||||
|
);
|
||||||
Binary file not shown.
@@ -1,8 +1,10 @@
|
|||||||
|
|
||||||
function openReservationForm() {
|
function openReservationForm() {
|
||||||
document.getElementById("reservationForm").style.display = "block";
|
const now = new Date();
|
||||||
|
const formattedDate = now.toLocaleDateString('cs-CZ', { day: '2-digit', month: '2-digit', year: 'numeric' });
|
||||||
|
document.getElementById('date').value = formattedDate;
|
||||||
|
document.getElementById('reservationForm').style.display = 'block';
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeReservationForm() {
|
function closeReservationForm() {
|
||||||
document.getElementById("reservationForm").style.display = "none";
|
document.getElementById('reservationForm').style.display = 'none';
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<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>Uživatelská Tabulka</title>
|
<title>Administrativní pracovníci</title>
|
||||||
<link rel="stylesheet" href="{{url_for('static', filename='css/style.css')}}">
|
<link rel="stylesheet" href="{{url_for('static', filename='css/style.css')}}">
|
||||||
<script src="{{url_for('static', filename='scripts/user_table.js')}}"></script>
|
<script src="{{url_for('static', filename='scripts/user_table.js')}}"></script>
|
||||||
</head>
|
</head>
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
<a href="{{ url_for('home') }}" style="text-decoration: none;">
|
<a href="{{ url_for('home') }}" style="text-decoration: none;">
|
||||||
<img src="{{url_for('static', filename='img/logo.webp')}}" alt="Logo" class="logo">
|
<img src="{{url_for('static', filename='img/logo.webp')}}" alt="Logo" class="logo">
|
||||||
</a>
|
</a>
|
||||||
Uživatelská Tabulka
|
Administrativní pracovníci
|
||||||
</h1>
|
</h1>
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<a href="{{ url_for('home') }}" class="button">Zpět na Domovskou Stránku</a>
|
<a href="{{ url_for('home') }}" class="button">Zpět na Domovskou Stránku</a>
|
||||||
@@ -28,9 +28,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<nav class="navbar">
|
|
||||||
<h2 id="users-table">Tabulka Uživatelů</h2>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
@@ -39,8 +37,10 @@
|
|||||||
{% elif session.get('role_id') != 1 %}
|
{% elif session.get('role_id') != 1 %}
|
||||||
<p>Nemáte oprávnění zobrazit tuto stránku.</p>
|
<p>Nemáte oprávnění zobrazit tuto stránku.</p>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
||||||
<div class="user-table">
|
<div class="user-table">
|
||||||
|
<nav class="navbar-users-table">
|
||||||
|
<h2 id="users-table">Správa Uživatelů</h2>
|
||||||
|
</nav>
|
||||||
{% if users %}
|
{% if users %}
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
@@ -61,7 +61,13 @@
|
|||||||
<td>{{ user['Jmeno'] }}</td>
|
<td>{{ user['Jmeno'] }}</td>
|
||||||
<td>{{ user['Prijmeni'] }}</td>
|
<td>{{ user['Prijmeni'] }}</td>
|
||||||
<td>{{ user['Email'] }}</td>
|
<td>{{ user['Email'] }}</td>
|
||||||
<td>{{ user['Role_ID'] }}</td>
|
<td>
|
||||||
|
{% for role in roles %}
|
||||||
|
{% if role['Role_ID'] == user['Role_ID'] %}
|
||||||
|
{{ role['Nazev'] }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</td>
|
||||||
<td>{{ user['Username'] }}</td>
|
<td>{{ user['Username'] }}</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ url_for('edit_user', user_id=user['ID_Uzivatele']) }}">Edit</a>
|
<a href="{{ url_for('edit_user', user_id=user['ID_Uzivatele']) }}">Edit</a>
|
||||||
@@ -79,8 +85,55 @@
|
|||||||
<p>No users found.</p>
|
<p>No users found.</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="order-management">
|
||||||
|
<nav class="navbar-orders-table">
|
||||||
|
<h2 id="orders-table">Správa objednávek</h2>
|
||||||
|
</nav>
|
||||||
|
{% if orders %}
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Číslo objednávky</th>
|
||||||
|
<th>Datum začátku</th>
|
||||||
|
<th>Datum konce</th>
|
||||||
|
<th>Stav</th>
|
||||||
|
<th>Přiřazený zaměstnanec</th>
|
||||||
|
<th>Popis</th>
|
||||||
|
<th>Akce</th> <!-- New column for actions -->
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for order in orders %}
|
||||||
|
<tr style="text-align: center;">
|
||||||
|
<td>{{ order['ID_Objednavky'] }}</td>
|
||||||
|
<td>{{ order['Datum_Zacatku'] }}</td>
|
||||||
|
<td>{{ order['Datum_Konce'] }}</td>
|
||||||
|
<td>{{ order['Stav'] }}</td>
|
||||||
|
<td>
|
||||||
|
{% for user in users %}
|
||||||
|
{% if user['ID_Uzivatele'] == order['ID_Zamestnance'] %}
|
||||||
|
{{ user['Jmeno'] }} {{ user['Prijmeni'] }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</td>
|
||||||
|
<td>{{ order['Popis'] }}</td>
|
||||||
|
<td>
|
||||||
|
<a href="{{ url_for('edit_order', order_id=order['ID_Objednavky']) }}">Edit</a>
|
||||||
|
</td> <!-- Edit button -->
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% else %}
|
||||||
|
<table>
|
||||||
|
<tr style="text-align: center;">
|
||||||
|
<td colspan="7">Nenalezeny žádné objednávky k zobrazení.</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<footer class="footer" id="kontakt">
|
<footer class="footer" id="kontakt">
|
||||||
<div>Made by Hrachovina</div>
|
<div>Made by Hrachovina</div>
|
||||||
|
|||||||
42
web/templates/create_repair.html
Normal file
42
web/templates/create_repair.html
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="cs">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Vytvořit Novou Opravu</title>
|
||||||
|
<link rel="stylesheet" href="{{url_for('static', filename='css/style.css')}}">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<div class="header">
|
||||||
|
<h1>Vytvořit Novou Opravu</h1>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<form action="{{ url_for('create_repair') }}" method="post" class="form-container">
|
||||||
|
<label for="id_zamestnance">Zaměstnanec:</label>
|
||||||
|
<select id="id_zamestnance" name="id_zamestnance" required>
|
||||||
|
<option value="" disabled selected>Vyberte zaměstnance</option>
|
||||||
|
{% for employee in employees %}
|
||||||
|
<option value="{{ employee['ID_Uzivatele'] }}">{{ employee['Jmeno'] }} {{ employee['Prijmeni'] }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<label for="nazev">Název:</label>
|
||||||
|
<input type="text" id="nazev" name="nazev" required>
|
||||||
|
|
||||||
|
<label for="popis">Popis:</label>
|
||||||
|
<textarea id="popis" name="popis" required></textarea>
|
||||||
|
|
||||||
|
<button type="submit" class="button">Vytvořit</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer class="footer">
|
||||||
|
<div>Made by Hrachovina</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
55
web/templates/edit_order.html
Normal file
55
web/templates/edit_order.html
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="cs">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Editovat Objednávku</title>
|
||||||
|
<link rel="stylesheet" href="{{url_for('static', filename='css/style.css')}}">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<div class="header">
|
||||||
|
<div class="contact-info">
|
||||||
|
<span>Kontakt: 123 123 123 | Otevírací doba: 9-18 hod | auto@servis.cz </span>
|
||||||
|
</div>
|
||||||
|
<h1 class="nazev">
|
||||||
|
<a href="{{ url_for('home') }}" style="text-decoration: none;">
|
||||||
|
<img src="{{url_for('static', filename='img/logo.webp')}}" alt="Logo" class="logo">
|
||||||
|
</a>
|
||||||
|
Editovat Objednávku
|
||||||
|
</h1>
|
||||||
|
<div class="buttons">
|
||||||
|
<a href="{{ url_for('administrator') }}" class="button">Zpět na Tabulku Objednávek</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="content">
|
||||||
|
<h2>Editovat Objednávku</h2>
|
||||||
|
<form action="{{ url_for('edit_order', order_id=order['ID_Objednavky']) }}" method="post" class="form-container">
|
||||||
|
<label for="stav">Stav:</label>
|
||||||
|
<input type="text" id="stav" name="stav" value="{{ order['Stav'] }}" required>
|
||||||
|
|
||||||
|
<label for="id_zamestnance">Přiřazený zaměstnanec:</label>
|
||||||
|
<input type="text" id="id_zamestnance" name="id_zamestnance" value="{{ order['ID_Zamestnance'] }}" required>
|
||||||
|
|
||||||
|
<label for="popis">Popis:</label>
|
||||||
|
<input type="text" id="popis" name="popis" value="{{ order['Popis'] }}" required>
|
||||||
|
|
||||||
|
<label for="datum_konce">Datum expedice:</label>
|
||||||
|
<input type="date" id="datum_konce" name="datum_konce" value="{{ order['Datum_Konce'] }}">
|
||||||
|
|
||||||
|
<button type="submit" class="button">Aktualizovat</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer class="footer" id="kontakt">
|
||||||
|
<div>Made by Hrachovina and Kirsch</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
55
web/templates/edit_repair.html
Normal file
55
web/templates/edit_repair.html
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="cs">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Editovat Opravu</title>
|
||||||
|
<link rel="stylesheet" href="{{url_for('static', filename='css/style.css')}}">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<div class="header">
|
||||||
|
<div class="contact-info">
|
||||||
|
<span>Kontakt: 123 123 123 | Otevírací doba: 9-18 hod | auto@servis.cz </span>
|
||||||
|
</div>
|
||||||
|
<h1 class="nazev">
|
||||||
|
<a href="{{ url_for('home') }}" style="text-decoration: none;">
|
||||||
|
<img src="{{url_for('static', filename='img/logo.webp')}}" alt="Logo" class="logo">
|
||||||
|
</a>
|
||||||
|
Editovat Opravu
|
||||||
|
</h1>
|
||||||
|
<div class="buttons">
|
||||||
|
<a href="{{ url_for('repairs') }}" class="button">Zpět na Seznam Oprav</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="content">
|
||||||
|
<h2>Editovat Opravu</h2>
|
||||||
|
<form action="{{ url_for('edit_repair', repair_id=repair['ID_Opravy']) }}" method="post" class="form-container">
|
||||||
|
<label for="id_zamestnance">Zaměstnanec:</label>
|
||||||
|
<select id="id_zamestnance" name="id_zamestnance" required>
|
||||||
|
{% for employee in employees %}
|
||||||
|
<option value="{{ employee['ID_Uzivatele'] }}" {% if employee['ID_Uzivatele'] == repair['ID_Zamestnance'] %}selected{% endif %}>{{ employee['Jmeno'] }} {{ employee['Prijmeni'] }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<label for="nazev">Název:</label>
|
||||||
|
<input type="text" id="nazev" name="nazev" value="{{ repair['Nazev'] }}" required>
|
||||||
|
|
||||||
|
<label for="popis">Popis:</label>
|
||||||
|
<textarea id="popis" name="popis" required>{{ repair['Popis'] }}</textarea>
|
||||||
|
|
||||||
|
<button type="submit" class="button">Aktualizovat</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer class="footer" id="kontakt">
|
||||||
|
<div>Made by Hrachovina</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
{% if session.get('logged_in') %}
|
{% if session.get('logged_in') %}
|
||||||
<a href="{{ url_for('administrator') }}" class="button">Administrace</a>
|
<a href="{{ url_for('administrator') }}" class="button">Administrace</a>
|
||||||
|
<a href="{{ url_for('repairs') }}" class="button">Správa Oprav</a>
|
||||||
<a href="{{ url_for('logout') }}" class="button">Odhlásit se</a>
|
<a href="{{ url_for('logout') }}" class="button">Odhlásit se</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="{{ url_for('login') }}" class="button">Administrace</a>
|
<a href="{{ url_for('login') }}" class="button">Administrace</a>
|
||||||
@@ -128,13 +129,13 @@
|
|||||||
<div class="form-container">
|
<div class="form-container">
|
||||||
<span class="close-button" onclick="closeReservationForm()">×</span>
|
<span class="close-button" onclick="closeReservationForm()">×</span>
|
||||||
<h2>Rezervace</h2>
|
<h2>Rezervace</h2>
|
||||||
<form>
|
<form action="{{ url_for('create_reservation') }}" method="post">
|
||||||
<label for="fullName">Celé jméno: <span class="required">*</span></label>
|
<label for="fullName">Celé jméno: <span class="required">*</span></label>
|
||||||
<input type="text" id="fullName" name="fullName" required>
|
<input type="text" id="fullName" name="fullName" required>
|
||||||
<label for="email">Email: <span class="required">*</span></label>
|
<label for="email">Email: <span class="required">*</span></label>
|
||||||
<input type="email" id="email" name="email" required>
|
<input type="email" id="email" name="email" required>
|
||||||
<label for="date">Datum: <span class="required">*</span></label>
|
<label for="date">Datum: <span class="required">*</span></label>
|
||||||
<input type="date" id="date" name="date" required>
|
<input type="text" id="date" name="date" required readonly>
|
||||||
<label for="description">Popis: <span class="required">*</span></label>
|
<label for="description">Popis: <span class="required">*</span></label>
|
||||||
<textarea id="description" name="description" rows="4" required></textarea>
|
<textarea id="description" name="description" rows="4" required></textarea>
|
||||||
<button type="submit" class="button">Odeslat</button>
|
<button type="submit" class="button">Odeslat</button>
|
||||||
@@ -147,6 +148,7 @@
|
|||||||
document.querySelector(target).scrollIntoView({ behavior: 'smooth' });
|
document.querySelector(target).scrollIntoView({ behavior: 'smooth' });
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
<script src="{{ url_for('static', filename='scripts/reservation.js') }}"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
80
web/templates/repairs.html
Normal file
80
web/templates/repairs.html
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="cs">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Správa Oprav</title>
|
||||||
|
<link rel="stylesheet" href="{{url_for('static', filename='css/style.css')}}">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<div class="header">
|
||||||
|
<div class="contact-info">
|
||||||
|
<span>Kontakt: 123 123 123 | Otevírací doba: 9-18 hod | auto@servis.cz </span>
|
||||||
|
</div>
|
||||||
|
<h1 class="nazev">
|
||||||
|
<a href="{{ url_for('home') }}" style="text-decoration: none;">
|
||||||
|
<img src="{{url_for('static', filename='img/logo.webp')}}" alt="Logo" class="logo">
|
||||||
|
</a>
|
||||||
|
Správa Oprav
|
||||||
|
</h1>
|
||||||
|
<div class="buttons">
|
||||||
|
<a href="{{ url_for('home') }}" class="button">Zpět na Domovskou Stránku</a>
|
||||||
|
<a href="{{ url_for('create_repair') }}" class="button">Vytvořit Novou Opravu</a>
|
||||||
|
<a href="{{ url_for('logout') }}" class="button">Odhlásit se</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="content">
|
||||||
|
<h2>Opravy</h2>
|
||||||
|
<div class="repair-table">
|
||||||
|
{% if repairs %}
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>ID Opravy</th>
|
||||||
|
<th>Jméno Zaměstnance</th>
|
||||||
|
<th>Název</th>
|
||||||
|
<th>Popis</th>
|
||||||
|
<th>Použité Produkty</th>
|
||||||
|
<th>Akce</th> <!-- New column for actions -->
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for repair in repairs %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ repair['ID_Opravy'] }}</td>
|
||||||
|
<td>{{ repair['Jmeno'] }} {{ repair['Prijmeni'] }}</td>
|
||||||
|
<td>{{ repair['Nazev'] }}</td>
|
||||||
|
<td>{{ repair['Popis'] }}</td>
|
||||||
|
<td>
|
||||||
|
{% for product in repair['products'] %}
|
||||||
|
{{ product['Nazev'] }} ({{ product['Pocet_Produktu'] }})<br>
|
||||||
|
{% endfor %}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="{{ url_for('edit_repair', repair_id=repair['ID_Opravy']) }}">Edit</a>
|
||||||
|
<form action="{{ url_for('delete_repair', repair_id=repair['ID_Opravy']) }}" method="post" style="display:inline;" onsubmit="return confirm('Opravdu chcete smazat tuto opravu?');">
|
||||||
|
<button type="submit" class="button-link">Delete</button>
|
||||||
|
</form>
|
||||||
|
</td> <!-- Edit and Delete buttons -->
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% else %}
|
||||||
|
<p>No repairs found.</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer class="footer" id="kontakt">
|
||||||
|
<div>Made by Hrachovina</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user