day of hard work with xkirsch #2

This commit is contained in:
2024-12-10 23:02:58 +01:00
parent 6c55c1701c
commit 72fb73cb5f
18 changed files with 841 additions and 64 deletions

View File

@@ -1,8 +1,8 @@
from flask import Flask, render_template, request, redirect, url_for, flash, session
from flask import Flask, render_template, request, redirect, url_for, flash, session, jsonify
import logging
from datetime import datetime
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 db import get_db_connection, fetch_users, fetch_orders, fetch_roles, fetch_repairs, fetch_employees, fetch_products, update_product, add_product_stock
from auth import encrypt_password, check_password
import random
@@ -72,6 +72,10 @@ def login():
flash('Úspěšně přihlášen.', 'success')
if user['Role_ID'] == 1:
return redirect(url_for('administrator'))
elif user['Role_ID'] == 2:
return redirect(url_for('managers'))
elif user['Role_ID'] == 3:
return redirect(url_for('repairs'))
else:
return redirect(url_for('home'))
@@ -95,7 +99,18 @@ def administrator():
users = fetch_users(session.get('role_id'))
orders = fetch_orders()
roles = fetch_roles()
return render_template('administrator.html', users=users, orders=orders, roles=roles)
products = fetch_products()
return render_template('administrator.html', users=users, orders=orders, roles=roles, products=products)
@app.route('/managers')
def managers():
if not session.get('logged_in') or session.get('role_id') != 2:
flash('Nemáte oprávnění k přístupu na tuto stránku.', 'error')
return redirect(url_for('login'))
users = fetch_users(session.get('role_id'))
orders = fetch_orders()
roles = fetch_roles()
return render_template('managers.html', users=users, orders=orders, roles=roles)
@app.route('/create_user', methods=['GET', 'POST'])
def create_user():
@@ -128,7 +143,8 @@ def create_user():
finally:
conn.close()
return render_template('create_user.html')
roles = fetch_roles()
return render_template('create_user.html', roles=roles)
@app.route('/edit_user/<int:user_id>', methods=['GET', 'POST'])
def edit_user(user_id):
@@ -191,6 +207,7 @@ def edit_order(order_id):
conn = get_db_connection()
order = conn.execute('SELECT * FROM Objednavky WHERE ID_Objednavky = ?', (order_id,)).fetchone()
users = fetch_users(session.get('role_id'))
if request.method == 'POST':
stav = request.form['stav']
@@ -208,7 +225,21 @@ def edit_order(order_id):
return redirect(url_for('administrator'))
conn.close()
return render_template('edit_order.html', order=order)
return render_template('edit_order.html', order=order, users=users)
@app.route('/delete_order/<int:order_id>', methods=['POST'])
def delete_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()
conn.execute('DELETE FROM Objednavky WHERE ID_Objednavky = ?', (order_id,))
conn.commit()
conn.close()
flash('Objednávka byla úspěšně smazána.')
return redirect(url_for('administrator'))
@app.route('/repairs')
def repairs():
@@ -216,7 +247,9 @@ def repairs():
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)
orders = fetch_orders()
users = fetch_users(session.get('role_id'))
return render_template('repairs.html', repairs=repairs, orders=orders, users=users)
@app.route('/create_repair', methods=['GET', 'POST'])
def create_repair():
@@ -288,12 +321,9 @@ def delete_repair(repair_id):
def create_reservation():
full_name = request.form['fullName']
email = request.form['email']
date = request.form['date']
datum_konce = request.form['datum_konce']
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
@@ -303,8 +333,8 @@ def create_reservation():
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.execute('INSERT INTO Objednavky (Stav, ID_Zamestnance, Popis, ID_Vozidla, Datum_Zacatku, Datum_Konce, Cena) VALUES (?, ?, ?, ?, ?, ?, ?)',
('Nová', user_id, description, 1, datetime.now().strftime('%Y-%m-%d'), datum_konce, 0.0)) # Use the current date for Datum_Zacatku
conn.commit()
flash('Rezervace byla úspěšně vytvořena.', 'success')
except sqlite3.Error as e:
@@ -314,6 +344,105 @@ def create_reservation():
return redirect(url_for('home'))
@app.route('/edit_product/<int:product_id>', methods=['GET', 'POST'])
def edit_product(product_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()
product = conn.execute('SELECT * FROM Produkty WHERE ID_Produktu = ?', (product_id,)).fetchone()
if request.method == 'POST':
nazev = request.form['nazev']
popis = request.form['popis']
momentalni_zasoba = request.form['momentalni_zasoba']
minimalni_zasoba = request.form['minimalni_zasoba']
update_product(product_id, nazev, popis, momentalni_zasoba, minimalni_zasoba)
flash('Produkt byl úspěšně aktualizován.')
return redirect(url_for('administrator'))
conn.close()
return render_template('edit_product.html', product=product)
@app.route('/add_product_stock/<int:product_id>', methods=['GET', 'POST'])
def add_product_stock(product_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()
product = conn.execute('SELECT * FROM Produkty WHERE ID_Produktu = ?', (product_id,)).fetchone()
if request.method == 'POST':
quantity = request.form['quantity']
add_product_stock(product_id, quantity)
flash('Zásoba byla úspěšně přidána.')
return redirect(url_for('administrator'))
conn.close()
return render_template('add_product_stock.html', product=product)
@app.route('/create_product', methods=['GET', 'POST'])
def create_product():
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':
nazev = request.form['nazev']
popis = request.form['popis']
momentalni_zasoba = request.form['momentalni_zasoba']
minimalni_zasoba = request.form['minimalni_zasoba']
conn = get_db_connection()
try:
conn.execute('INSERT INTO Produkty (Nazev, Popis, Momentalni_Zasoba, Minimalni_Zasoba) VALUES (?, ?, ?, ?)',
(nazev, popis, momentalni_zasoba, minimalni_zasoba))
conn.commit()
flash('Nový produkt byl úspěšně přidán.', 'success')
return redirect(url_for('administrator'))
except sqlite3.Error as e:
flash(f'Chyba při přidávání produktu: {e}', 'error')
finally:
conn.close()
return render_template('create_product.html')
@app.route('/statistics')
def statistics():
conn = get_db_connection()
repairs_data = conn.execute('''
SELECT Zamestnanci.Jmeno || ' ' || Zamestnanci.Prijmeni AS employee, COUNT(Opravy.ID_Opravy) AS count
FROM Opravy
JOIN Zamestnanci ON Opravy.ID_Zamestnance = Zamestnanci.ID_Uzivatele
GROUP BY Zamestnanci.ID_Uzivatele
''').fetchall()
repairs_data = [dict(employee=row['employee'], count=row['count']) for row in repairs_data]
conn.close()
return render_template('statistics.html', repairs_data=repairs_data)
@app.route('/repairs_by_date')
def repairs_by_date():
start_date = request.args.get('start')
end_date = request.args.get('end')
conn = get_db_connection()
repairs_data = conn.execute('''
SELECT DATE(Datum_Zacatku) AS date, COUNT(*) AS count
FROM Objednavky
WHERE Datum_Zacatku BETWEEN ? AND ?
GROUP BY DATE(Datum_Zacatku)
''', (start_date, end_date)).fetchall()
repairs_data = [dict(date=row['date'], count=row['count']) for row in repairs_data]
conn.close()
return jsonify(repairs_data)
# Always redirect back home
@app.errorhandler(404)
def default_page(e):

View File

@@ -1,4 +1,3 @@
import sqlite3
from flask import current_app as app
@@ -63,3 +62,40 @@ def fetch_employees():
conn.close()
app.logger.debug(f"Fetched employees: {employees}")
return employees
def fetch_products():
conn = get_db_connection()
products = conn.execute('SELECT * FROM Produkty').fetchall()
products = [dict_from_row(product) for product in products]
conn.close()
app.logger.debug(f"Fetched products: {products}")
return products
def update_product(product_id, nazev, popis, momentalni_zasoba, minimalni_zasoba):
conn = get_db_connection()
conn.execute('''
UPDATE Produkty
SET Nazev = ?, Popis = ?, Momentalni_Zasoba = ?, Minimalni_Zasoba = ?
WHERE ID_Produktu = ?
''', (nazev, popis, momentalni_zasoba, minimalni_zasoba, product_id))
conn.commit()
conn.close()
def add_product_stock(product_id, quantity):
conn = get_db_connection()
conn.execute('''
UPDATE Produkty
SET Momentalni_Zasoba = Momentalni_Zasoba + ?
WHERE ID_Produktu = ?
''', (quantity, product_id))
conn.commit()
conn.close()
def create_product(nazev, popis, momentalni_zasoba, minimalni_zasoba):
conn = get_db_connection()
conn.execute('''
INSERT INTO Produkty (Nazev, Popis, Momentalni_Zasoba, Minimalni_Zasoba)
VALUES (?, ?, ?, ?)
''', (nazev, popis, momentalni_zasoba, minimalni_zasoba))
conn.commit()
conn.close()

View File

@@ -4,10 +4,6 @@
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
/* Body styling */
body {
font-family: Arial, sans-serif;
@@ -75,17 +71,7 @@ footer {
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 {
.table-header {
display: flex;
justify-content: space-around;
background-color: #444;
@@ -564,3 +550,72 @@ option {
color: white;
padding: 10px;
}
/* Graph container styling */
.graph-container {
background-color: #222;
border: 1px solid #555;
border-radius: 1em;
padding: 20px;
margin-top: 20px;
color: white;
text-align: center;
}
/* Canvas styling */
canvas {
width: 100% !important; /* Make the canvas span the whole container */
height: auto;
margin: 0 auto;
background-color: #333; /* Make the background of the graph darker */
}
/* Statistics page styling */
.statistics-container {
background-color: #222;
border: 1px solid #555;
border-radius: 1em;
padding: 20px;
margin-top: 20px;
color: white;
text-align: center;
}
.statistics-header {
margin-bottom: 20px;
}
.statistics-form {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 20px;
}
.statistics-form label {
margin: 0 10px;
}
.statistics-form input {
padding: 10px;
margin: 0 10px;
border: none;
border-radius: 5px;
background-color: #555;
color: white;
}
.statistics-form button {
background-color: #808080;
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
transition: transform 0.3s, box-shadow 0.3s;
}
.statistics-form button:hover {
transform: scale(1.05);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}

Binary file not shown.

View File

@@ -1,6 +1,6 @@
function openReservationForm() {
const now = new Date();
const formattedDate = now.toLocaleDateString('cs-CZ', { day: '2-digit', month: '2-digit', year: 'numeric' });
const formattedDate = now.toISOString().split('T')[0]; // Format date as YYYY-MM-DD
document.getElementById('date').value = formattedDate;
document.getElementById('reservationForm').style.display = 'block';
}

View File

@@ -0,0 +1,61 @@
document.addEventListener('DOMContentLoaded', function() {
const ctx = document.getElementById('repairsChart').getContext('2d');
const repairsData = JSON.parse(document.getElementById('repairsData').textContent);
const labels = repairsData.map(data => data.employee);
const data = repairsData.map(data => data.count);
new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: [{
label: 'Počet Oprav',
data: data,
backgroundColor: 'rgba(255, 99, 132, 0.2)',
borderColor: 'rgba(255, 99, 132, 1)',
borderWidth: 1
}]
},
options: {
scales: {
y: {
beginAtZero: true
}
}
}
});
});
function fetchRepairsByDate() {
const startDate = document.getElementById('startDate').value;
const endDate = document.getElementById('endDate').value;
fetch(`/repairs_by_date?start=${startDate}&end=${endDate}`)
.then(response => response.json())
.then(data => {
const ctx = document.getElementById('timeRepairsChart').getContext('2d');
const labels = data.map(item => item.date);
const counts = data.map(item => item.count);
new Chart(ctx, {
type: 'line',
data: {
labels: labels,
datasets: [{
label: 'Počet Oprav',
data: counts,
backgroundColor: 'rgba(54, 162, 235, 0.2)',
borderColor: 'rgba(54, 162, 235, 1)',
borderWidth: 1
}]
},
options: {
scales: {
y: {
beginAtZero: true
}
}
}
});
});
}

View File

@@ -0,0 +1,47 @@
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Přidat Zásobu</title>
<link rel="icon" href="{{url_for('static', filename='img/logo.webp')}}" type="image/x-icon">
<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>
Přidat Zásobu
</h1>
<div class="buttons">
<a href="{{ url_for('administrator') }}" class="button">Zpět na Tabulku Produktů</a>
</div>
</div>
</header>
<div class="container">
<div class="content">
<h2>Přidat Zásobu</h2>
<form action="{{ url_for('add_product_stock', product_id=product['ID_Produktu']) }}" method="post" class="form-container">
<label for="quantity">Množství:</label>
<input type="number" id="quantity" name="quantity" required>
<button type="submit" class="button">Přidat</button>
</form>
</div>
</div>
<footer class="footer" id="kontakt">
<div>Made by Hrachovina and Kirsch</div>
</footer>
</body>
</html>

View File

@@ -4,6 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Administrativní pracovníci</title>
<link rel="icon" href="{{url_for('static', filename='img/logo.webp')}}" type="image/x-icon">
<link rel="stylesheet" href="{{url_for('static', filename='css/style.css')}}">
<script src="{{url_for('static', filename='scripts/user_table.js')}}"></script>
</head>
@@ -23,7 +24,8 @@
<div class="buttons">
<a href="{{ url_for('home') }}" class="button">Zpět na Domovskou Stránku</a>
<a href="{{ url_for('create_user') }}" class="button">Vytvořit Nového Uživatele</a>
<a href="{{ url_for('logout') }}" class="button">Odhlásit se</a> <!-- New Log Out button -->
<a href="{{ url_for('create_product') }}" class="button">Přidat Nový Produkt</a> <!-- Fixed route -->
<a href="{{ url_for('logout') }}" class="button">Odhlásit se</a>
</div>
</div>
</header>
@@ -38,7 +40,7 @@
<p>Nemáte oprávnění zobrazit tuto stránku.</p>
{% else %}
<div class="user-table">
<nav class="navbar-users-table">
<nav class="table-header">
<h2 id="users-table">Správa Uživatelů</h2>
</nav>
{% if users %}
@@ -51,7 +53,7 @@
<th>Email</th>
<th>Role</th>
<th>Username</th>
<th>Akce</th> <!-- New column for actions -->
<th>Akce</th>
</tr>
</thead>
<tbody>
@@ -76,7 +78,7 @@
<button type="submit" class="button-link">Delete</button>
</form>
{% endif %}
</td> <!-- Edit and Delete buttons -->
</td>
</tr>
{% endfor %}
</tbody>
@@ -86,20 +88,20 @@
{% endif %}
</div>
<div class="order-management">
<nav class="navbar-orders-table">
<nav class="table-header">
<h2 id="orders-table">Správa objednávek</h2>
</nav>
{% if orders %}
<table>
<thead>
<tr>
<th>Číslo objednávky</th>
<th>ID</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 -->
<th>Akce</th>
</tr>
</thead>
<tbody>
@@ -118,8 +120,11 @@
</td>
<td>{{ order['Popis'] }}</td>
<td>
<a href="{{ url_for('edit_order', order_id=order['ID_Objednavky']) }}">Edit</a>
</td> <!-- Edit button -->
<a href="{{ url_for('edit_order', order_id=order['ID_Objednavky']) }}">Edit</a> /
<form action="{{ url_for('delete_order', order_id=order['ID_Objednavky']) }}" method="post" style="display:inline;" onsubmit="return confirm('Opravdu chcete smazat tuto objednávku?');">
<button type="submit" class="button-link">Delete</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
@@ -132,10 +137,50 @@
</table>
{% endif %}
</div>
<div class="stock-management">
<nav class="table-header">
<h2 id="stock-table">Správa produktových zásob</h2>
</nav>
{% if products %}
<table>
<thead>
<tr>
<th>ID</th>
<th>Název</th>
<th>Popis</th>
<th>Momentální Zásoba</th>
<th>Minimální Zásoba</th>
<th>Akce</th>
</tr>
</thead>
<tbody>
{% for product in products %}
<tr style="text-align: center;">
<td>{{ product['ID_Produktu'] }}</td>
<td>{{ product['Nazev'] }}</td>
<td>{{ product['Popis'] }}</td>
<td>{{ product['Momentalni_Zasoba'] }}</td>
<td>{{ product['Minimalni_Zasoba'] }}</td>
<td>
<a href="{{ url_for('edit_product', product_id=product['ID_Produktu']) }}">Edit</a> /
<a href="{{ url_for('add_product_stock', product_id=product['ID_Produktu']) }}">Add</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<table>
<tr style="text-align: center;">
<td colspan="6">Nenalezeny žádné produkty k zobrazení.</td>
</tr>
</table>
{% endif %}
</div>
{% endif %}
</div>
</div>
<footer class="footer" id="kontakt">
<footer class="footer">
<div>Made by Hrachovina</div>
</footer>

View File

@@ -0,0 +1,59 @@
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Přidat Nový Produkt</title>
<link rel="icon" href="{{url_for('static', filename='img/logo.webp')}}" type="image/x-icon">
<link rel="stylesheet" href="{{url_for('static', filename='css/style.css')}}">
<script src="{{url_for('static', filename='scripts/create_product.js')}}"></script>
</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>
Přidat Nový Produkt
</h1>
<div class="buttons">
<a href="{{ url_for('administrator') }}" class="button">Zpět na Administraci</a>
</div>
</div>
</header>
<div class="container">
<div class="content">
{% if not session.get('logged_in') or session.get('role_id') != 1 %}
<p>Nemáte oprávnění k přístupu na tuto stránku.</p>
{% else %}
<form action="{{ url_for('create_product') }}" method="post" class="form-container" onsubmit="handleCreateProduct(event)">
<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>
<label for="momentalni_zasoba">Momentální Zásoba:</label>
<input type="number" id="momentalni_zasoba" name="momentalni_zasoba" required>
<label for="minimalni_zasoba">Minimální Zásoba:</label>
<input type="number" id="minimalni_zasoba" name="minimalni_zasoba" required>
<button type="submit" class="button">Přidat</button>
</form>
{% endif %}
</div>
</div>
<footer class="footer" id="kontakt">
<div>Made by Hrachovina and Kirsch</div>
</footer>
</body>
</html>

View File

@@ -4,6 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vytvořit Nového Uživatele</title>
<link rel="icon" href="{{url_for('static', filename='img/logo.webp')}}" type="image/x-icon">
<link rel="stylesheet" href="{{url_for('static', filename='css/style.css')}}">
<script src="{{url_for('static', filename='scripts/create_user.js')}}"></script>
</head>
@@ -42,7 +43,11 @@
<input type="email" id="email" name="email" required>
<label for="role">Role:</label>
<input type="text" id="role" name="role" required>
<select id="role" name="role" required>
{% for role in roles %}
<option value="{{ role['Role_ID'] }}">{{ role['Nazev'] }}</option>
{% endfor %}
</select>
<label for="username">Username:</label>
<input type="text" id="username" name="username" required>

View File

@@ -1,10 +1,10 @@
<!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="icon" href="{{url_for('static', filename='img/logo.webp')}}" type="image/x-icon">
<link rel="stylesheet" href="{{url_for('static', filename='css/style.css')}}">
</head>
<body>
@@ -34,12 +34,18 @@
<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>
<select id="id_zamestnance" name="id_zamestnance" required>
{% for user in users %}
<option value="{{ user['ID_Uzivatele'] }}" {% if user['ID_Uzivatele'] == order['ID_Zamestnance'] %}selected{% endif %}>
{{ user['Jmeno'] }} {{ user['Prijmeni'] }}
</option>
{% endfor %}
</select>
<label for="popis">Popis:</label>
<input type="text" id="popis" name="popis" value="{{ order['Popis'] }}" required>
<textarea id="popis" name="popis" rows="4" required>{{ order['Popis'] }}</textarea>
<label for="datum_konce">Datum expedice:</label>
<label for="datum_konce">Datum konce:</label>
<input type="date" id="datum_konce" name="datum_konce" value="{{ order['Datum_Konce'] }}">
<button type="submit" class="button">Aktualizovat</button>

View File

@@ -0,0 +1,56 @@
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Editovat Produkt</title>
<link rel="icon" href="{{url_for('static', filename='img/logo.webp')}}" type="image/x-icon">
<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 Produkt
</h1>
<div class="buttons">
<a href="{{ url_for('administrator') }}" class="button">Zpět na Tabulku Produktů</a>
</div>
</div>
</header>
<div class="container">
<div class="content">
<h2>Editovat Produkt</h2>
<form action="{{ url_for('edit_product', product_id=product['ID_Produktu']) }}" method="post" class="form-container">
<label for="nazev">Název:</label>
<input type="text" id="nazev" name="nazev" value="{{ product['Nazev'] }}" required>
<label for="popis">Popis:</label>
<textarea id="popis" name="popis" rows="4" required>{{ product['Popis'] }}</textarea>
<label for="momentalni_zasoba">Momentální Zásoba:</label>
<input type="number" id="momentalni_zasoba" name="momentalni_zasoba" value="{{ product['Momentalni_Zasoba'] }}" required>
<label for="minimalni_zasoba">Minimální Zásoba:</label>
<input type="number" id="minimalni_zasoba" name="minimalni_zasoba" value="{{ product['Minimalni_Zasoba'] }}" required>
<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>

View File

@@ -4,6 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Editovat Uživatele</title>
<link rel="icon" href="{{url_for('static', filename='img/logo.webp')}}" type="image/x-icon">
<link rel="stylesheet" href="{{url_for('static', filename='css/style.css')}}">
</head>
<body>
@@ -27,6 +28,7 @@
<div class="container">
<div class="content">
<h2>Editovat Uživatele</h2>
<form action="{{ url_for('edit_user', user_id=user['ID_Uzivatele']) }}" method="post" class="form-container">
<label for="jmeno">Jméno:</label>
<input type="text" id="jmeno" name="jmeno" value="{{ user['Jmeno'] }}" required>

View File

@@ -4,6 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Autoservis</title>
<link rel="icon" href="{{url_for('static', filename='img/logo.webp')}}" type="image/x-icon">
<link rel="stylesheet" href="{{url_for('static', filename='css/style.css')}}">
<script src="{{url_for('static', filename='scripts/reservation.js')}}"></script>
</head>
@@ -22,11 +23,17 @@
</h1>
<div class="buttons">
{% if session.get('logged_in') %}
<a href="{{ url_for('administrator') }}" class="button">Administrace</a>
<a href="{{ url_for('repairs') }}" class="button">Správa Oprav</a>
{% if session.get('role_id') == 1 %}
<a href="{{ url_for('administrator') }}" class="button">Administrace</a>
{% elif session.get('role_id') == 2 %}
<a href="{{ url_for('managers') }}" class="button">Manažerský panel</a>
<a href="{{ url_for('statistics') }}" class="button">Statistiky</a>
{% elif session.get('role_id') == 3 %}
<a href="{{ url_for('repairs') }}" class="button">Správa Oprav</a>
{% endif %}
<a href="{{ url_for('logout') }}" class="button">Odhlásit se</a>
{% else %}
<a href="{{ url_for('login') }}" class="button">Administrace</a>
<a href="{{ url_for('login') }}" class="button">Přihlásit se</a>
{% endif %}
<button class="button" onclick="openReservationForm()">Objednat se</button>
</div>
@@ -40,10 +47,10 @@
{% endif %}
<nav class="navbar">
<button class="button" onclick="smoothScroll('#about-header')">O nás</button>
<button class="button" onclick="smoothScroll('#directions')">K nám</button>
<button class="button" onclick="smoothScroll('#nabidka-sluzeb')">Služby</button>
<button class="button" onclick="smoothScroll('#recenze')">Recenze</button>
<button class="button" onclick="location.href='#about-header'">O nás</button>
<button class="button" onclick="location.href='#directions'">K nám</button>
<button class="button" onclick="location.href='#nabidka-sluzeb'">Služby</button>
<button class="button" onclick="location.href='#recenze'">Recenze</button>
</nav>
<div class="container">
@@ -120,7 +127,7 @@
</div>
</div>
</div>
<footer class="footer" id="kontakt">
<footer class="footer">
<div>Made by Hrachovina and Kirsch</div>
</footer>
@@ -134,8 +141,8 @@
<input type="text" id="fullName" name="fullName" required>
<label for="email">Email: <span class="required">*</span></label>
<input type="email" id="email" name="email" required>
<label for="date">Datum: <span class="required">*</span></label>
<input type="text" id="date" name="date" required readonly>
<label for="datum_konce">Požadované datum vrácení vozidla: <span class="required">*</span></label>
<input type="date" id="datum_konce" name="datum_konce" required>
<label for="description">Popis: <span class="required">*</span></label>
<textarea id="description" name="description" rows="4" required></textarea>
<button type="submit" class="button">Odeslat</button>
@@ -144,11 +151,19 @@
</div>
<script>
function smoothScroll(target) {
document.querySelector(target).scrollIntoView({ behavior: 'smooth' });
function openReservationForm() {
const now = new Date();
const minDate = new Date();
minDate.setDate(now.getDate() + 3); // Exclude today and the next 2 days
const formattedMinDate = minDate.toISOString().split('T')[0];
document.getElementById('datum_konce').setAttribute('min', formattedMinDate);
document.getElementById('reservationForm').style.display = 'block';
}
function closeReservationForm() {
document.getElementById('reservationForm').style.display = 'none';
}
</script>
<script src="{{ url_for('static', filename='scripts/reservation.js') }}"></script>
</body>
</html>

View File

@@ -4,6 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Přihlášení</title>
<link rel="icon" href="{{url_for('static', filename='img/logo.webp')}}" type="image/x-icon">
<link rel="stylesheet" href="{{url_for('static', filename='css/style.css')}}">
</head>
<body>

146
web/templates/managers.html Normal file
View File

@@ -0,0 +1,146 @@
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Správa Manažerů</title>
<link rel="icon" href="{{url_for('static', filename='img/logo.webp')}}" type="image/x-icon">
<link rel="stylesheet" href="{{url_for('static', filename='css/style.css')}}">
<script src="{{url_for('static', filename='scripts/user_table.js')}}"></script>
</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 Manažerů
</h1>
<div class="buttons">
<a href="{{ url_for('home') }}" class="button">Zpět na Domovskou Stránku</a>
<a href="{{ url_for('create_user') }}" class="button">Vytvořit Nového Uživatele</a>
<a href="{{ url_for('logout') }}" class="button">Odhlásit se</a>
</div>
</div>
</header>
<div class="container">
<div class="content">
{% if not session.get('logged_in') %}
<p>Musíte se přihlásit, abyste mohli zobrazit tuto stránku.</p>
{% elif session.get('role_id') not in [1, 2] %}
<p>Nemáte oprávnění zobrazit tuto stránku.</p>
{% else %}
<div class="user-table">
<nav class="table-header">
<h2 id="users-table">Správa Uživatelů</h2>
</nav>
{% if users %}
<table>
<thead>
<tr>
<th>ID</th>
<th>Jméno</th>
<th>Prijmeni</th>
<th>Email</th>
<th>Role</th>
<th>Username</th>
<th>Akce</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<td>{{ user['ID_Uzivatele'] }}</td>
<td>{{ user['Jmeno'] }}</td>
<td>{{ user['Prijmeni'] }}</td>
<td>{{ user['Email'] }}</td>
<td>
{% for role in roles %}
{% if role['Role_ID'] == user['Role_ID'] %}
{{ role['Nazev'] }}
{% endif %}
{% endfor %}
</td>
<td>{{ user['Username'] }}</td>
<td>
<a href="{{ url_for('edit_user', user_id=user['ID_Uzivatele']) }}">Edit</a>
{% if user['Role_ID'] > session.get('role_id') %}
/ <form action="{{ url_for('delete_user', user_id=user['ID_Uzivatele']) }}" method="post" style="display:inline;" onsubmit="return confirm('Opravdu chcete smazat tohoto uživatele?');">
<button type="submit" class="button-link">Delete</button>
</form>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>No users found.</p>
{% endif %}
</div>
<div class="order-management">
<nav class="table-header">
<h2 id="orders-table">Správa objednávek</h2>
</nav>
{% if orders %}
<table>
<thead>
<tr>
<th>ID</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>
</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> /
<form action="{{ url_for('delete_order', order_id=order['ID_Objednavky']) }}" method="post" style="display:inline;" onsubmit="return confirm('Opravdu chcete smazat tuto objednávku?');">
<button type="submit" class="button-link">Delete</button>
</form>
</td>
</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 %}
</div>
</div>
<footer class="footer">
<div>Made by Hrachovina</div>
</footer>
</body>
</html>

View File

@@ -29,8 +29,13 @@
<div class="container">
<div class="content">
<h2>Opravy</h2>
<div class="repair-table">
{% if not session.get('logged_in') %}
<p>Musíte se přihlásit, abyste mohli zobrazit tuto stránku.</p>
{% else %}
<div class="user-table">
<nav class="table-header">
<h2 id="users-table">Správa Oprav</h2>
</nav>
{% if repairs %}
<table>
<thead>
@@ -40,7 +45,7 @@
<th>Název</th>
<th>Popis</th>
<th>Použité Produkty</th>
<th>Akce</th> <!-- New column for actions -->
<th>Akce</th>
</tr>
</thead>
<tbody>
@@ -56,11 +61,11 @@
{% endfor %}
</td>
<td>
<a href="{{ url_for('edit_repair', repair_id=repair['ID_Opravy']) }}">Edit</a>
<a href="{{ url_for('edit_repair', repair_id=repair['ID_Opravy']) }}" class="button-link">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 -->
</td>
</tr>
{% endfor %}
</tbody>
@@ -69,10 +74,62 @@
<p>No repairs found.</p>
{% endif %}
</div>
<div class="order-management">
<nav class="table-header">
<h2 id="orders-table">Správa Objednávek</h2>
</nav>
{% if orders %}
<table>
<thead>
<tr>
<th>ID</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>
</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> /
<form action="{{ url_for('delete_order', order_id=order['ID_Objednavky']) }}" method="post" style="display:inline;" onsubmit="return confirm('Opravdu chcete smazat tuto objednávku?');">
<button type="submit" class="button-link">Delete</button>
</form>
</td>
</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 %}
</div>
</div>
<footer class="footer" id="kontakt">
<footer class="footer">
<div>Made by Hrachovina</div>
</footer>

View File

@@ -0,0 +1,57 @@
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Statistiky</title>
<link rel="icon" href="{{url_for('static', filename='img/logo.webp')}}" type="image/x-icon">
<link rel="stylesheet" href="{{url_for('static', filename='css/style.css')}}">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</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>
Statistika Oprav
</h1>
<div class="buttons">
<a href="{{ url_for('home') }}" class="button">Zpět na Domovskou Stránku</a>
<a href="{{ url_for('logout') }}" class="button">Odhlásit se</a>
</div>
</div>
</header>
<div class="container">
<div class="statistics-container">
<h2 class="statistics-header">Počet Oprav podle Zaměstnance</h2>
<canvas id="repairsChart"></canvas>
<script id="repairsData" type="application/json">{{ repairs_data | tojson }}</script>
</div>
<div class="statistics-container">
<h2 class="statistics-header">Počet Oprav podle Času</h2>
<div class="statistics-form">
<label for="startDate">Začátek:</label>
<input type="date" id="startDate" name="startDate">
<label for="endDate">Konec:</label>
<input type="date" id="endDate" name="endDate">
<button onclick="fetchRepairsByDate()">Zobrazit</button>
</div>
<canvas id="timeRepairsChart"></canvas>
</div>
</div>
<footer class="footer">
<div>Made by Hrachovina</div>
</footer>
<script src="{{url_for('static', filename='scripts/statistics.js')}}"></script>
</body>
</html>