Refactor terminology and improve clarity across templates

- Updated "Termin" to "Buchung" in admin_dashboard.html and appointments.html for consistency.
- Enhanced language for better understanding in various templates, including base.html, dienstleistungen.html, inventarsystem.html, kontakt.html, login.html, main.html, projekte.html, register.html, team.html, and added a new tutorial.html.
- Corrected spelling and grammatical errors throughout the templates.
- Improved user guidance and descriptions for better user experience.
This commit is contained in:
2026-03-30 21:36:30 +02:00
parent 84185c35ae
commit 2fc49e3dfa
15 changed files with 305 additions and 1259 deletions
+1
View File
@@ -5,3 +5,4 @@ main.dist
.mongo-data .mongo-data
db db
build build
mongodb.log
+76 -17
View File
@@ -114,6 +114,49 @@ def _sanitize_text(text: str, max_length: int = 255) -> str:
return text return text
def _activate_test_license_for_user(username: str, school_name: str) -> tuple[bool, str]:
"""Create a one-time test license for the user if none exists yet."""
user_name = _sanitize_text(username or "", 80)
school = _sanitize_text(school_name or "", 200)
if not user_name:
return False, "Benutzername fehlt fuer Test-Key."
client = None
try:
client, col = _get_collection("licenses")
existing = col.find_one(
{
"username": user_name,
"plan": "Test",
"status": {"$in": ["Aktiv", "Pausiert"]},
}
)
if existing:
return False, "Ein Test-Key ist fuer dieses Schulkonto bereits vorhanden."
test_key = f"TEST-{verify.key_generator()[:18].upper()}"
col.insert_one(
{
"username": user_name,
"school_name": school or user_name,
"license_key": test_key,
"plan": "Test",
"status": "Aktiv",
"valid_until": (datetime.utcnow() + timedelta(days=30)).date().isoformat(),
"hwid_uuid": "",
"created_at": _utc_now_iso(),
"updated_at": _utc_now_iso(),
}
)
return True, test_key
except PyMongoError:
return False, "Test-Key konnte nicht aktiviert werden."
finally:
if client:
client.close()
def _with_public_id(doc: dict | None) -> dict | None: def _with_public_id(doc: dict | None) -> dict | None:
if not doc: if not doc:
return doc return doc
@@ -277,6 +320,11 @@ def inventarsystem():
return render_template("inventarsystem.html") return render_template("inventarsystem.html")
@app.route('/tutorial')
def tutorial():
return render_template("tutorial.html")
@app.route('/team') @app.route('/team')
def team(): def team():
return render_template("team.html") return render_template("team.html")
@@ -333,11 +381,13 @@ def login():
def register(): def register():
if request.method == "POST": if request.method == "POST":
username = (request.form.get("username") or "").strip() username = (request.form.get("username") or "").strip()
display_name = (request.form.get("display_name") or "").strip() school_name = (request.form.get("school_name") or "").strip()
contact_person = (request.form.get("contact_person") or "").strip()
activate_test_key = (request.form.get("activate_test_key") or "").strip().lower() in {"1", "on", "true", "yes"}
password = request.form.get("password") or "" password = request.form.get("password") or ""
password_repeat = request.form.get("password_repeat") or "" password_repeat = request.form.get("password_repeat") or ""
if not username or not display_name or not password or not password_repeat: if not username or not school_name or not contact_person or not password or not password_repeat:
flash("Bitte alle Felder ausfuellen.", "error") flash("Bitte alle Felder ausfuellen.", "error")
return redirect(url_for("register")) return redirect(url_for("register"))
@@ -357,21 +407,30 @@ def register():
flash("Benutzername bereits vergeben.", "error") flash("Benutzername bereits vergeben.", "error")
return redirect(url_for("register")) return redirect(url_for("register"))
display_name = _sanitize_text(display_name, 100) school_name = _sanitize_text(school_name, 120)
contact_person = _sanitize_text(contact_person, 120)
try: try:
existing_users = user_store.get_all_users() or [] existing_users = user_store.get_all_users() or []
is_first_user = len(existing_users) == 0 is_first_user = len(existing_users) == 0
if not user_store.add_user(username, password, display_name, ""): if not user_store.add_user(username, password, school_name, contact_person):
flash("Benutzer konnte nicht erstellt werden.", "error") flash("Benutzer konnte nicht erstellt werden.", "error")
return redirect(url_for("register")) return redirect(url_for("register"))
if activate_test_key:
activated, message = _activate_test_license_for_user(username, school_name)
if activated:
flash(f"Test-Key aktiviert: {message}", "success")
else:
flash(message, "error")
if is_first_user: if is_first_user:
user_store.make_admin(username) user_store.make_admin(username)
except Exception: except Exception:
flash("MongoDB ist derzeit nicht erreichbar.", "error") flash("MongoDB ist derzeit nicht erreichbar.", "error")
return redirect(url_for("register")) return redirect(url_for("register"))
flash("Registrierung erfolgreich. Bitte jetzt einloggen.", "success") flash("Schulregistrierung erfolgreich. Bitte jetzt einloggen.", "success")
return redirect(url_for("login")) return redirect(url_for("login"))
return render_template("register.html") return render_template("register.html")
@@ -401,11 +460,11 @@ def appointments():
try: try:
date.fromisoformat(selected_date) date.fromisoformat(selected_date)
except ValueError: except ValueError:
flash("Bitte einen gueltigen Termin im Kalender auswaehlen.", "error") flash("Bitte eine gueltige Buchung im Kalender auswaehlen.", "error")
return redirect(url_for("appointments", month=month, year=year)) return redirect(url_for("appointments", month=month, year=year))
if selected_date in blocked_day_map: if selected_date in blocked_day_map:
flash("Dieser Tag ist im Kalender gesperrt. Bitte einen anderen Termin waehlen.", "error") flash("Dieser Tag ist im Kalender gesperrt. Bitte eine andere Buchung waehlen.", "error")
return redirect(url_for("appointments", month=month, year=year)) return redirect(url_for("appointments", month=month, year=year))
if not appointment_time or not subject: if not appointment_time or not subject:
@@ -413,11 +472,11 @@ def appointments():
return redirect(url_for("appointments", month=month, year=year)) return redirect(url_for("appointments", month=month, year=year))
if meeting_type not in ["digital", "vor_ort"]: if meeting_type not in ["digital", "vor_ort"]:
flash("Bitte eine gueltige Terminart waehlen.", "error") flash("Bitte eine gueltige Buchungsart waehlen.", "error")
return redirect(url_for("appointments", month=month, year=year)) return redirect(url_for("appointments", month=month, year=year))
if meeting_type == "vor_ort" and not location_name: if meeting_type == "vor_ort" and not location_name:
flash("Bei Vor-Ort-Terminen ist ein Ort erforderlich.", "error") flash("Bei Vor-Ort-Buchungen ist ein Ort erforderlich.", "error")
return redirect(url_for("appointments", month=month, year=year)) return redirect(url_for("appointments", month=month, year=year))
if meeting_type == "digital": if meeting_type == "digital":
@@ -448,13 +507,13 @@ def appointments():
} }
) )
except PyMongoError: except PyMongoError:
flash("Termin konnte nicht gespeichert werden.", "error") flash("Buchung konnte nicht gespeichert werden.", "error")
return redirect(url_for("appointments", month=month, year=year)) return redirect(url_for("appointments", month=month, year=year))
finally: finally:
if client: if client:
client.close() client.close()
flash("Termin erfolgreich angefragt.", "success") flash("Buchung erfolgreich angefragt.", "success")
selected = date.fromisoformat(selected_date) selected = date.fromisoformat(selected_date)
return redirect(url_for("appointments", month=selected.month, year=selected.year)) return redirect(url_for("appointments", month=selected.month, year=selected.year))
@@ -482,7 +541,7 @@ def appointments():
for item in user_appointments: for item in user_appointments:
_with_public_id(item) _with_public_id(item)
except PyMongoError: except PyMongoError:
flash("Termine konnten nicht geladen werden.", "error") flash("Buchungen konnten nicht geladen werden.", "error")
finally: finally:
if client: if client:
client.close() client.close()
@@ -516,7 +575,7 @@ def admin_dashboard():
for item in all_appointments: for item in all_appointments:
_with_public_id(item) _with_public_id(item)
except PyMongoError: except PyMongoError:
flash("Terminanfragen konnten nicht geladen werden.", "error") flash("Buchungsanfragen konnten nicht geladen werden.", "error")
finally: finally:
if client: if client:
client.close() client.close()
@@ -610,7 +669,7 @@ def update_appointment(appointment_id):
query = _appointment_query_from_id(appointment_id) query = _appointment_query_from_id(appointment_id)
if not query: if not query:
flash("Termin nicht gefunden.", "error") flash("Buchung nicht gefunden.", "error")
return redirect(url_for("admin_dashboard")) return redirect(url_for("admin_dashboard"))
new_status = "Bestaetigt" if action == "confirm" else "Abgelehnt" new_status = "Bestaetigt" if action == "confirm" else "Abgelehnt"
@@ -630,16 +689,16 @@ def update_appointment(appointment_id):
}, },
) )
if result.matched_count == 0: if result.matched_count == 0:
flash("Termin nicht gefunden.", "error") flash("Buchung nicht gefunden.", "error")
return redirect(url_for("admin_dashboard")) return redirect(url_for("admin_dashboard"))
except PyMongoError: except PyMongoError:
flash("Termin konnte nicht aktualisiert werden.", "error") flash("Buchung konnte nicht aktualisiert werden.", "error")
return redirect(url_for("admin_dashboard")) return redirect(url_for("admin_dashboard"))
finally: finally:
if client: if client:
client.close() client.close()
flash(f"Termin wurde {('bestaetigt' if action == 'confirm' else 'abgelehnt')}.", "success") flash(f"Buchung wurde {('bestaetigt' if action == 'confirm' else 'abgelehnt')}.", "success")
return redirect(url_for("admin_dashboard")) return redirect(url_for("admin_dashboard"))
-1127
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -248,7 +248,7 @@
</section> </section>
<section class="appointments-section"> <section class="appointments-section">
<h2>Terminanfragen verwalten</h2> <h2>Buchungsanfragen verwalten</h2>
<div class="block-days-section"> <div class="block-days-section">
<h3>Kalender-Tage sperren</h3> <h3>Kalender-Tage sperren</h3>
<form method="POST" action="{{ url_for('admin_block_day') }}" class="block-form"> <form method="POST" action="{{ url_for('admin_block_day') }}" class="block-form">
@@ -285,7 +285,7 @@
<div class="appointment-info"> <div class="appointment-info">
<strong>{{ appointment.display_name }} - {{ appointment.subject }}</strong> <strong>{{ appointment.display_name }} - {{ appointment.subject }}</strong>
<p><strong>Datum:</strong> {{ appointment.date }} um {{ appointment.time }}</p> <p><strong>Datum:</strong> {{ appointment.date }} um {{ appointment.time }}</p>
<p><strong>Terminart:</strong> {{ appointment.meeting_label or ('Vor Ort' if appointment.meeting_type == 'vor_ort' else 'Digital') }}</p> <p><strong>Buchungsart:</strong> {{ appointment.meeting_label or ('Vor Ort' if appointment.meeting_type == 'vor_ort' else 'Digital') }}</p>
{% if appointment.location_name %} {% if appointment.location_name %}
<p><strong>Ort:</strong> {{ appointment.location_name }}</p> <p><strong>Ort:</strong> {{ appointment.location_name }}</p>
{% endif %} {% endif %}
@@ -315,7 +315,7 @@
</article> </article>
{% endfor %} {% endfor %}
{% else %} {% else %}
<p>Keine Terminanfragen vorhanden.</p> <p>Keine Buchungsanfragen vorhanden.</p>
{% endif %} {% endif %}
</section> </section>
+7 -7
View File
@@ -1,6 +1,6 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block title %}Termin anfragen{% endblock %} {% block title %}Buchungsoption{% endblock %}
{% block head %} {% block head %}
{{ super() }} {{ super() }}
@@ -283,8 +283,8 @@
</article> </article>
<aside class="panel booking-form"> <aside class="panel booking-form">
<h2>Termin anfragen</h2> <h2>Buchung anfragen</h2>
<p class="meeting-note">Persoenliches Gespraechstermin: Digital oder Vor Ort.</p> <p class="meeting-note">Persoenliche Buchungsoption: Digital oder Vor Ort.</p>
<span class="selected-date-badge" id="selectedDateBadge">Kein Datum gewählt</span> <span class="selected-date-badge" id="selectedDateBadge">Kein Datum gewählt</span>
<form method="POST" action="{{ url_for('appointments', month=month, year=year) }}"> <form method="POST" action="{{ url_for('appointments', month=month, year=year) }}">
<input type="hidden" id="selectedDateInput" name="selected_date" required> <input type="hidden" id="selectedDateInput" name="selected_date" required>
@@ -293,7 +293,7 @@
<input id="appointment_time" name="appointment_time" type="time" required> <input id="appointment_time" name="appointment_time" type="time" required>
</div> </div>
<div class="field"> <div class="field">
<label for="meeting_type">Terminart</label> <label for="meeting_type">Buchungsart</label>
<select id="meeting_type" name="meeting_type" required> <select id="meeting_type" name="meeting_type" required>
<option value="digital">Digital</option> <option value="digital">Digital</option>
<option value="vor_ort">Vor Ort</option> <option value="vor_ort">Vor Ort</option>
@@ -316,13 +316,13 @@
<label for="note">Notiz (optional)</label> <label for="note">Notiz (optional)</label>
<textarea id="note" name="note" placeholder="Kurzbeschreibung der Anfrage"></textarea> <textarea id="note" name="note" placeholder="Kurzbeschreibung der Anfrage"></textarea>
</div> </div>
<button class="submit-btn" type="submit">Termin anfragen</button> <button class="submit-btn" type="submit">Buchung anfragen</button>
</form> </form>
</aside> </aside>
</section> </section>
<section class="panel appointment-list" style="margin-top: 1rem;"> <section class="panel appointment-list" style="margin-top: 1rem;">
<h2>Meine Terminanfragen</h2> <h2>Meine Buchungsanfragen</h2>
{% if user_appointments %} {% if user_appointments %}
{% for item in user_appointments %} {% for item in user_appointments %}
<article class="entry"> <article class="entry">
@@ -330,7 +330,7 @@
{% if item.note %} {% if item.note %}
<p>{{ item.note }}</p> <p>{{ item.note }}</p>
{% endif %} {% endif %}
<p class="entry-meta"><strong>Terminart:</strong> {{ item.meeting_label or ('Vor Ort' if item.meeting_type == 'vor_ort' else 'Digital') }}</p> <p class="entry-meta"><strong>Buchungsart:</strong> {{ item.meeting_label or ('Vor Ort' if item.meeting_type == 'vor_ort' else 'Digital') }}</p>
{% if item.location_name %} {% if item.location_name %}
<p class="entry-meta"><strong>Ort:</strong> {{ item.location_name }}</p> <p class="entry-meta"><strong>Ort:</strong> {{ item.location_name }}</p>
{% endif %} {% endif %}
+8 -6
View File
@@ -354,15 +354,16 @@
<div class="site-shell site-nav-inner"> <div class="site-shell site-nav-inner">
<a class="brand" href="{{ url_for('default') }}">Invario Schule</a> <a class="brand" href="{{ url_for('default') }}">Invario Schule</a>
<div class="nav-links" aria-label="Main Navigation"> <div class="nav-links" aria-label="Main Navigation">
<a href="{{ url_for('dienstleistungen') }}">Leistungen fuer Schulen</a> <a href="{{ url_for('dienstleistungen') }}">Leistungen für Schulen</a>
<a href="{{ url_for('projekte') }}">Praxisbeispiele</a> <a href="{{ url_for('projekte') }}">Praxisbeispiele</a>
<a href="{{ url_for('tutorial') }}">Tutorial</a>
<a href="{{ url_for('team') }}">Unser Ansatz</a> <a href="{{ url_for('team') }}">Unser Ansatz</a>
<a href="{{ url_for('kontakt') }}">Kontakt</a> <a href="{{ url_for('kontakt') }}">Kontakt</a>
<a href="{{ url_for('inventarsystem') }}">Inventarsystem</a> <a href="{{ url_for('inventarsystem') }}">Inventarsystem</a>
</div> </div>
<div class="nav-actions"> <div class="nav-actions">
{% if 'username' in session %} {% if 'username' in session %}
<a class="nav-btn" href="{{ url_for('appointments') }}">Beratungstermin</a> <a class="nav-btn" href="{{ url_for('appointments') }}">Buchungsoption</a>
<details class="nav-dropdown"> <details class="nav-dropdown">
<summary class="nav-btn">Nutzerbereich</summary> <summary class="nav-btn">Nutzerbereich</summary>
@@ -416,16 +417,17 @@
<div class="footer-content"> <div class="footer-content">
<div class="footer-section"> <div class="footer-section">
<h4>Über uns</h4> <h4>Über uns</h4>
<p>Digitale Verwaltungsablaeufe fuer Schulsekretariate und Schulleitungen in Deutschland.</p> <p>Digitale Verwaltungsabläufe für Bildungseinrichtungen in Deutschland.</p>
</div> </div>
<div class="footer-section"> <div class="footer-section">
<h4>Schnelllinks</h4> <h4>Schnelllinks</h4>
<ul class="footer-links"> <ul class="footer-links">
<li><a href="{{ url_for('default') }}">Start</a></li> <li><a href="{{ url_for('default') }}">Start</a></li>
<li><a href="{{ url_for('dienstleistungen') }}">Leistungsuebersicht</a></li> <li><a href="{{ url_for('dienstleistungen') }}">Leistungsübersicht</a></li>
<li><a href="{{ url_for('tutorial') }}">Tutorial</a></li>
<li><a href="{{ url_for('blog') }}">Neuigkeiten</a></li> <li><a href="{{ url_for('blog') }}">Neuigkeiten</a></li>
{% if 'username' in session %} {% if 'username' in session %}
<li><a href="{{ url_for('appointments') }}">Beratungstermine</a></li> <li><a href="{{ url_for('appointments') }}">Buchungsoption</a></li>
{% endif %} {% endif %}
</ul> </ul>
</div> </div>
@@ -525,7 +527,7 @@
</style> </style>
</footer> </footer>
<div class="cookie-banner hidden" id="cookieBanner" role="dialog" aria-live="polite" aria-label="Cookie Hinweis"> <div class="cookie-banner hidden" id="cookieBanner" role="dialog" aria-live="polite" aria-label="Cookie Hinweis">
<p>Wir verwenden Cookies, um die Website sicher und benutzerfreundlich zu betreiben. Mit "Cookies akzeptieren" stimmen Sie der Nutzung zu. Details in <a href="{{ url_for('datenschutz') }}">Datenschutz</a>.</p> <p>Wir verwenden Cookies, um die Website sicher und benutzerfreundlich zu betreiben. Mit "Cookies akzeptieren" wird die Nutzung bestätigt. Details in <a href="{{ url_for('datenschutz') }}">Datenschutz</a>.</p>
<div class="cookie-actions"> <div class="cookie-actions">
<button type="button" class="cookie-btn" id="cookieAcceptBtn">Cookies akzeptieren</button> <button type="button" class="cookie-btn" id="cookieAcceptBtn">Cookies akzeptieren</button>
<button type="button" class="cookie-btn secondary" id="cookieDeclineBtn">Ablehnen und zu Ecosia</button> <button type="button" class="cookie-btn secondary" id="cookieDeclineBtn">Ablehnen und zu Ecosia</button>
+15 -11
View File
@@ -1,43 +1,47 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block title %}Leistungen fuer Schulen | Invario{% endblock %} {% block title %}Leistungen für Schulen | Invario{% endblock %}
{% block content %} {% block content %}
<section class="page-hero"> <section class="page-hero">
<h1>Leistungen fuer Schulsekretariat und Schulleitung</h1> <h1>Leistungen für Bildungseinrichtungen</h1>
<p>Praxisnahe Module fuer Schulen in Deutschland: verstaendlich, sicher und ohne unnoetige Komplexitaet.</p> <p>Praxisnahe Module für Schulen in Deutschland: verständlich, sicher und ohne unnötige Komplexität.</p>
</section> </section>
<section class="cards"> <section class="cards">
<article class="card"> <article class="card">
<h2>Digitale Inventarverwaltung</h2> <h2>Digitale Inventarverwaltung</h2>
<p>Alle Geraete, Raeume und Zustaendigkeiten an einem Ort. So finden Sie Informationen schneller und reduzieren Rueckfragen.</p> <p>Alle Geräte, Räume und Zuständigkeiten an einem Ort. Das verkürzt Suchzeiten und reduziert Rückfragen.</p>
</article> </article>
<article class="card"> <article class="card">
<h2>Lizenz- und Fristenkontrolle</h2> <h2>Lizenz- und Fristenkontrolle</h2>
<p>Lizenzlaufzeiten werden transparent angezeigt, inklusive Hinweise auf bald ablaufende Nutzungen.</p> <p>Lizenzlaufzeiten werden transparent angezeigt, inklusive Hinweise auf bald ablaufende Nutzungen.</p>
</article> </article>
<article class="card"> <article class="card">
<h2>Support mit klaren Prioritaeten</h2> <h2>Support mit klaren Prioritäten</h2>
<p>Stoerungen werden strukturiert aufgenommen, priorisiert und mit nachvollziehbarem Status bearbeitet.</p> <p>Störungen werden strukturiert aufgenommen, priorisiert und mit nachvollziehbarem Status bearbeitet.</p>
</article> </article>
<article class="card"> <article class="card">
<h2>DSGVO-konforme Dokumentation</h2> <h2>DSGVO-konforme Dokumentation</h2>
<p>Vorgaenge und Aenderungen bleiben nachvollziehbar dokumentiert, damit Pruefungen und Abstimmungen einfacher werden.</p> <p>Vorgänge und Änderungen bleiben nachvollziehbar dokumentiert, damit Prüfungen und Abstimmungen einfacher werden.</p>
</article> </article>
<article class="card"> <article class="card">
<h2>Einrichtung und Schulung</h2> <h2>Einrichtung und Schulung</h2>
<p>Wir richten das System gemeinsam mit Ihrem Team ein und schulen in klaren, alltagsnahen Schritten.</p> <p>Die Einführung erfolgt in klaren, alltagsnahen Schritten, damit der laufende Betrieb stabil bleibt.</p>
</article> </article>
<article class="card"> <article class="card">
<h2>Begleitung im laufenden Betrieb</h2> <h2>Begleitung im laufenden Betrieb</h2>
<p>Feste Ansprechpartner unterstuetzen Ihr Team bei Fragen, Erweiterungen und organisatorischen Anpassungen.</p> <p>Feste Ansprechpartner unterstützen bei Fragen, Erweiterungen und organisatorischen Anpassungen.</p>
</article>
<article class="card">
<h2>Technische Sicherheitsbasis</h2>
<p>Rollenrechte, sichere Sitzungen, Schutz-Header und protokollierte Änderungen bilden die Grundlage für einen verlässlichen Betrieb.</p>
</article> </article>
</section> </section>
<section class="highlight"> <section class="highlight">
<h2>Besonders geeignet fuer Teams mit wenig Zeit</h2> <h2>Besonders geeignet für Teams mit wenig Zeit</h2>
<p>Die Oberflaeche ist bewusst reduziert aufgebaut: grosse, klare Bedienelemente, eindeutige Bezeichnungen und kurze Klickwege fuer taegliche Verwaltungsaufgaben.</p> <p>Die Oberfläche ist bewusst reduziert aufgebaut: große, klare Bedienelemente, eindeutige Bezeichnungen und kurze Klickwege für tägliche Verwaltungsaufgaben.</p>
</section> </section>
<style> <style>
+21 -20
View File
@@ -1,30 +1,30 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block title %}Inventarsystem fuer Schulen | Uebersicht{% endblock %} {% block title %}Inventarsystem für Schulen | Übersicht{% endblock %}
{% block content %} {% block content %}
<section class="page-hero"> <section class="page-hero">
<h1>Inventarsystem fuer Schulen</h1> <h1>Inventarsystem für Schulen</h1>
<p>Alle wichtigen Funktionen fuer den Schulalltag in einer klaren Oberflaeche: von Inventar ueber Lizenzen bis zur nachvollziehbaren Historie.</p> <p>Alle wichtigen Funktionen für den Schulalltag in einer klaren Oberfläche: von Inventar über Lizenzen bis zur nachvollziehbaren Historie.</p>
</section> </section>
<section class="split"> <section class="split">
<article class="panel"> <article class="panel">
<h2>1. Bestand einfach pflegen</h2> <h2>1. Bestand einfach pflegen</h2>
<p>Jedes Geraet erhaelt eine eindeutige Akte mit Standort, Status, Kaufdaten und zustaendiger Person.</p> <p>Jedes Gerät erhält eine eindeutige Akte mit Standort, Status, Kaufdaten und zuständiger Person.</p>
<ul> <ul>
<li>Suche nach Seriennummer, Raum oder Geraetetyp</li> <li>Suche nach Seriennummer, Raum oder Gerätetyp</li>
<li>Einheitliche Datenfelder fuer alle Standorte</li> <li>Einheitliche Datenfelder für alle Standorte</li>
<li>Schnelle Erfassung neuer Geraete</li> <li>Schnelle Erfassung neuer Geräte</li>
</ul> </ul>
</article> </article>
<article class="panel"> <article class="panel">
<h2>2. Standorte nachvollziehbar verwalten</h2> <h2>2. Standorte nachvollziehbar verwalten</h2>
<p>Raeume, Etagen und Gebaeude werden klar strukturiert, damit jederzeit ersichtlich ist, wo sich ein Geraet befindet.</p> <p>Räume, Etagen und Gebäude werden klar strukturiert, damit jederzeit ersichtlich ist, wo sich ein Gerät befindet.</p>
<ul> <ul>
<li>Uebersicht je Raum oder Fachbereich</li> <li>Übersicht je Raum oder Fachbereich</li>
<li>Sammelverschiebung mehrerer Geraete</li> <li>Sammelverschiebung mehrerer Geräte</li>
<li>Einfacher Abgleich bei Inventurterminen</li> <li>Einfacher Abgleich bei Inventurterminen</li>
</ul> </ul>
</article> </article>
@@ -32,8 +32,8 @@
<section class="split" style="margin-top:0.9rem;"> <section class="split" style="margin-top:0.9rem;">
<article class="panel"> <article class="panel">
<h2>3. QR-Code Unterstuetzung</h2> <h2>3. QR-Code Unterstützung</h2>
<p>Mit QR-Codes lassen sich Geraete vor Ort direkt identifizieren und aktualisieren.</p> <p>Mit QR-Codes lassen sich Geräte vor Ort direkt identifizieren und aktualisieren.</p>
<ul> <ul>
<li>Labels direkt aus dem System erzeugen</li> <li>Labels direkt aus dem System erzeugen</li>
<li>Scannen und sofort zur richtigen Akte springen</li> <li>Scannen und sofort zur richtigen Akte springen</li>
@@ -43,23 +43,24 @@
<article class="panel"> <article class="panel">
<h2>4. Historie und Verantwortung</h2> <h2>4. Historie und Verantwortung</h2>
<p>Aenderungen bleiben dokumentiert, damit Entscheidungen und Vorgaenge transparent bleiben.</p> <p>Änderungen bleiben dokumentiert, damit Entscheidungen und Vorgänge transparent bleiben.</p>
<ul> <ul>
<li>Wer hat wann was geaendert</li> <li>Wer hat wann was geändert</li>
<li>Leihvorgaenge und Rueckgaben nachvollziehen</li> <li>Leihvorgänge und Rückgaben nachvollziehen</li>
<li>Klare Nachweise fuer interne Abstimmungen</li> <li>Klare Nachweise für interne Abstimmungen</li>
</ul> </ul>
</article> </article>
</section> </section>
<section class="panel" style="margin-top:0.9rem;"> <section class="panel" style="margin-top:0.9rem;">
<h2>5. Rollen, Rechte und Exporte</h2> <h2>5. Rollen, Rechte und Exporte</h2>
<p>Das System unterscheidet klar zwischen Verwaltung, Schulleitung und technischen Rollen.</p> <p>Das System unterscheidet klar zwischen Verwaltungs- und Technikrollen.</p>
<ul class="wide-list"> <ul class="wide-list">
<li><strong>Rollenbasiert:</strong> Nur relevante Funktionen pro Nutzergruppe sichtbar.</li> <li><strong>Rollenbasiert:</strong> Nur relevante Funktionen pro Nutzergruppe sichtbar.</li>
<li><strong>Datenschutzgerecht:</strong> Zugriff und Aenderungen werden protokolliert.</li> <li><strong>Datenschutzgerecht:</strong> Zugriff und Änderungen werden protokolliert.</li>
<li><strong>Exportierbar:</strong> Berichte und Bestandslisten koennen fuer Termine und Pruefungen ausgegeben werden.</li> <li><strong>Exportierbar:</strong> Berichte und Bestandslisten können für Termine und Prüfungen ausgegeben werden.</li>
<li><strong>Erweiterbar:</strong> Das System waechst mit Ihren organisatorischen Anforderungen.</li> <li><strong>Sicher betrieben:</strong> Session-Schutz, sichere Header und Zugriffskontrollen sind standardmäßig aktiv.</li>
<li><strong>Erweiterbar:</strong> Das System wächst mit organisatorischen Anforderungen.</li>
</ul> </ul>
</section> </section>
+8 -8
View File
@@ -1,11 +1,11 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block title %}Kontakt fuer Schulen | Invario{% endblock %} {% block title %}Kontakt für Schulen | Invario{% endblock %}
{% block content %} {% block content %}
<section class="page-hero"> <section class="page-hero">
<h1>Kontakt</h1> <h1>Kontakt</h1>
<p>Wir beantworten Anfragen aus Schulsekretariat und Schulleitung schnell und klar. Fuer neue Projekte empfehlen wir einen kurzen Beratungstermin.</p> <p>Anfragen rund um Einführung, Betrieb und Support werden schnell und klar beantwortet. Für neue Projekte empfiehlt sich eine kurze Buchungsoption.</p>
</section> </section>
<section class="contact-grid"> <section class="contact-grid">
@@ -13,23 +13,23 @@
<h2>Allgemeine Anfrage</h2> <h2>Allgemeine Anfrage</h2>
<p><strong>E-Mail:</strong> info@invario.de</p> <p><strong>E-Mail:</strong> info@invario.de</p>
<p><strong>Telefon:</strong> +49 (0) 123 / 456789</p> <p><strong>Telefon:</strong> +49 (0) 123 / 456789</p>
<p>Geeignet fuer organisatorische Fragen, Erstkontakt und allgemeine Informationen.</p> <p>Geeignet für organisatorische Fragen, Erstkontakt und allgemeine Informationen.</p>
</article> </article>
<article class="contact-card"> <article class="contact-card">
<h2>Support</h2> <h2>Support</h2>
<p><strong>E-Mail:</strong> support@invario.de</p> <p><strong>E-Mail:</strong> support@invario.de</p>
<p><strong>Telefon:</strong> +49 (0) 123 / 456790</p> <p><strong>Telefon:</strong> +49 (0) 123 / 456790</p>
<p>Bei laufendem Betrieb, stoerenden Fehlern oder dringenden Rueckfragen im Schulalltag.</p> <p>Bei laufendem Betrieb, störenden Fehlern oder dringenden Rückfragen im Schulalltag.</p>
</article> </article>
<article class="contact-card"> <article class="contact-card">
<h2>Beratungstermin</h2> <h2>Buchungsoption</h2>
<p>In 30 Minuten besprechen wir Ihre aktuelle Situation und priorisieren sinnvolle erste Schritte fuer Ihre Schule.</p> <p>In 30 Minuten werden aktuelle Rahmenbedingungen bewertet und sinnvolle erste Schritte priorisiert.</p>
{% if 'username' in session %} {% if 'username' in session %}
<a class="btn" href="{{ url_for('appointments') }}">Beratungstermin buchen</a> <a class="btn" href="{{ url_for('appointments') }}">Buchungsoption nutzen</a>
{% else %} {% else %}
<a class="btn" href="{{ url_for('login') }}">Login fuer Terminbuchung</a> <a class="btn" href="{{ url_for('login') }}">Login für Buchung</a>
{% endif %} {% endif %}
</article> </article>
</section> </section>
+1 -1
View File
@@ -93,7 +93,7 @@
{% block content %} {% block content %}
<section class="auth-wrap"> <section class="auth-wrap">
<h1>Login</h1> <h1>Login</h1>
<p>Bitte melden Sie sich mit Ihrem Konto an, um Termine anzufragen.</p> <p>Bitte melden Sie sich mit Ihrem Konto an, um Buchungen anzufragen.</p>
<form method="POST" action="{{ url_for('login') }}"> <form method="POST" action="{{ url_for('login') }}">
<div class="field"> <div class="field">
<label for="username">Benutzername</label> <label for="username">Benutzername</label>
+46 -26
View File
@@ -1,6 +1,6 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block title %}Digitale Schulverwaltung fuer Sekretariat und Schulleitung{% endblock %} {% block title %}Digitale Schulverwaltung mit Sicherheitsfokus{% endblock %}
{% block head %} {% block head %}
{{ super() }} {{ super() }}
@@ -320,24 +320,25 @@
{% block content %} {% block content %}
<section class="hero" id="top"> <section class="hero" id="top">
<div> <div>
<span class="eyebrow">Fuer Schulsekretariat und Schulleitung</span> <span class="eyebrow">Für moderne Schulverwaltung</span>
<h1>Mehr Ruhe im Schulalltag durch klare digitale Verwaltung.</h1> <h1>Mehr Ruhe im Schulalltag durch klare digitale Verwaltung.</h1>
<p> <p>
Invario unterstützt Schulen in Deutschland dabei, Inventar, Lizenzen und Anfragen nachvollziehbar zu organisieren. Die Bedienung ist bewusst einfach gehalten, damit auch Teams ohne IT-Spezialisierung schnell und sicher arbeiten koennen. Invario unterstützt Bildungseinrichtungen in Deutschland dabei, Inventar, Lizenzen und Anfragen nachvollziehbar zu organisieren. Die Bedienung bleibt bewusst einfach, während zentrale Sicherheitsfunktionen wie Rollenrechte, Protokollierung und geschützte Verbindungen standardmäßig integriert sind.
</p> </p>
<div class="cta-row"> <div class="cta-row">
{% if 'username' in session %} {% if 'username' in session %}
<a class="btn btn-primary" href="{{ url_for('appointments') }}">Beratungstermin buchen</a> <a class="btn btn-primary" href="{{ url_for('appointments') }}">Buchungsoption nutzen</a>
{% else %} {% else %}
<a class="btn btn-primary" href="{{ url_for('login') }}">Beratungstermin buchen</a> <a class="btn btn-primary" href="{{ url_for('login') }}">Buchungsoption nutzen</a>
{% endif %} {% endif %}
<a class="btn btn-secondary" href="{{ url_for('dienstleistungen') }}">Leistungen ansehen</a> <a class="btn btn-secondary" href="{{ url_for('dienstleistungen') }}">Leistungen ansehen</a>
<a class="btn btn-secondary" href="{{ url_for('tutorial') }}">Tutorial ansehen</a>
<a class="btn btn-secondary" href="{{ url_for('kontakt') }}">Direkt kontaktieren</a> <a class="btn btn-secondary" href="{{ url_for('kontakt') }}">Direkt kontaktieren</a>
</div> </div>
</div> </div>
<aside class="hero-card" aria-label="Kurzfakten fuer Schulen"> <aside class="hero-card" aria-label="Kurzfakten für Schulen">
<h3>Was Schulen besonders schaetzen</h3> <h3>Was Schulen besonders schätzen</h3>
<p>Klare Ablaeufe, feste Ansprechpartner und verstaendliche Oberflaechen fuer den taeglichen Einsatz.</p> <p>Klare Abläufe, feste Ansprechpartner und verständliche Oberflächen für den täglichen Einsatz.</p>
<div class="stats"> <div class="stats">
<div><strong>5 Min</strong><span>Einstieg pro Aufgabe</span></div> <div><strong>5 Min</strong><span>Einstieg pro Aufgabe</span></div>
<div><strong>1 Klick</strong><span>Status und Historie</span></div> <div><strong>1 Klick</strong><span>Status und Historie</span></div>
@@ -347,20 +348,20 @@
</section> </section>
<section class="section" id="nutzen" style="animation-delay: 100ms;"> <section class="section" id="nutzen" style="animation-delay: 100ms;">
<h2>Was Ihr Sekretariat sofort entlastet</h2> <h2>Vorteile für Ihr Sekretariat</h2>
<p>Alle Informationen sind gebuendelt, Vorgaenge sind standardisiert, und Rueckfragen lassen sich schneller beantworten.</p> <p>Alle Informationen sind gebündelt, Vorgänge sind standardisiert, und Rückfragen lassen sich schneller beantworten.</p>
<div class="section-grid"> <div class="section-grid">
<article class="card"> <article class="card">
<h3>Inventar auf einen Blick</h3> <h3>Inventar auf einen Blick</h3>
<p>Geraete, Standorte und Zustaendigkeiten sind zentral erfasst. Das reduziert Suchzeiten und doppelte Rueckfragen.</p> <p>Geräte, Standorte und Zuständigkeiten sind zentral erfasst. Das reduziert Suchzeiten und doppelte Rückfragen.</p>
</article> </article>
<article class="card"> <article class="card">
<h3>Lizenzfristen im Blick</h3> <h3>Lizenzfristen im Blick</h3>
<p>Auslaufende Lizenzen werden rechtzeitig sichtbar, damit keine Unterrichtsausfaelle durch fehlende Software entstehen.</p> <p>Auslaufende Lizenzen werden rechtzeitig sichtbar, damit keine Unterrichtsausfälle durch fehlende Software entstehen.</p>
</article> </article>
<article class="card"> <article class="card">
<h3>Verstaendliche Prozesse</h3> <h3>Verständliche Prozesse</h3>
<p>Statt technischer Fachsprache sehen Sie klare Schritte und eindeutige Statusmeldungen fuer jede Aufgabe.</p> <p>Statt technischer Fachsprache zeigt die Plattform klare Schritte und eindeutige Statusmeldungen für jede Aufgabe.</p>
</article> </article>
</div> </div>
</section> </section>
@@ -371,15 +372,15 @@
<div class="routine-list"> <div class="routine-list">
<div class="routine"> <div class="routine">
<div> <div>
<b>Neues Geraet kommt an</b> <b>Neues Gerät kommt an</b>
Seriennummer, Raum und Ansprechpartner werden in wenigen Schritten eingetragen und sind sofort nachvollziehbar. Seriennummer, Raum und Ansprechperson werden in wenigen Schritten eingetragen und sind sofort nachvollziehbar.
</div> </div>
<span>Inventar</span> <span>Inventar</span>
</div> </div>
<div class="routine"> <div class="routine">
<div> <div>
<b>Rueckfrage der Schulleitung</b> <b>Rückfrage zur Gerätehistorie</b>
Status zu Bestellung, Nutzung oder Defekt ist direkt sichtbar, ohne mehrere Listen durchsuchen zu muessen. Status zu Bestellung, Nutzung oder Defekt ist direkt sichtbar, ohne mehrere Listen durchsuchen zu müssen.
</div> </div>
<span>Transparenz</span> <span>Transparenz</span>
</div> </div>
@@ -393,27 +394,46 @@
</div> </div>
</section> </section>
<section class="section" id="sicherheit" style="animation-delay: 220ms;">
<h2>Allgemeine Sicherheit des Programms</h2>
<p>Das Sicherheitskonzept verbindet technische Schutzmaßnahmen mit klaren Arbeitsabläufen, damit Daten im laufenden Betrieb zuverlässig geschützt bleiben.</p>
<div class="section-grid">
<article class="card">
<h3>Rollenbasierte Zugriffe</h3>
<p>Nutzerkonten sehen nur Funktionen, die für die jeweilige Aufgabe benötigt werden. Das reduziert Fehlbedienungen und ungewollte Änderungen.</p>
</article>
<article class="card">
<h3>Dokumentierte Änderungen</h3>
<p>Wichtige Aktionen werden nachvollziehbar protokolliert. Dadurch lassen sich Abläufe prüfen und Sicherheitsereignisse schneller einordnen.</p>
</article>
<article class="card">
<h3>Geschützte Übertragung</h3>
<p>Verbindungen laufen über sichere Protokolle, ergänzt durch Sicherheits-Header und strikte Session-Regeln für den täglichen Webbetrieb.</p>
</article>
</div>
</section>
<section class="section" id="ablauf" style="animation-delay: 260ms;"> <section class="section" id="ablauf" style="animation-delay: 260ms;">
<h2>So verlaeuft die Zusammenarbeit</h2> <h2>So verläuft die Zusammenarbeit</h2>
<p>Ein klarer Prozess sorgt fuer Sicherheit, besonders bei begrenzten Zeitfenstern im Schulbetrieb.</p> <p>Ein klarer Prozess sorgt für Sicherheit, besonders bei begrenzten Zeitfenstern im Schulbetrieb.</p>
<div class="process" aria-label="Ablauf in fuenf Schritten"> <div class="process" aria-label="Ablauf in fünf Schritten">
<div class="step"><strong>1. Kennenlernen</strong><small>Ziele klären</small></div> <div class="step"><strong>1. Kennenlernen</strong><small>Ziele klären</small></div>
<div class="step"><strong>2. Struktur</strong><small>Bestehende Abläufe erfassen</small></div> <div class="step"><strong>2. Struktur</strong><small>Bestehende Abläufe erfassen</small></div>
<div class="step"><strong>3. Einrichtung</strong><small>System passgenau einstellen</small></div> <div class="step"><strong>3. Einrichtung</strong><small>System passgenau einstellen</small></div>
<div class="step"><strong>4. Schulung</strong><small>Praxisnah einführen</small></div> <div class="step"><strong>4. Schulung</strong><small>Praxisnah einführen</small></div>
<div class="step"><strong>5. Betrieb</strong><small>Persoenlich begleiten</small></div> <div class="step"><strong>5. Betrieb</strong><small>Persönlich begleiten</small></div>
</div> </div>
</section> </section>
<section class="contact" id="kontakt"> <section class="contact" id="kontakt">
<div> <div>
<h2>Sie moechten den Verwaltungsaufwand spuerbar reduzieren?</h2> <h2>Beratung für den nächsten Digitalisierungsschritt</h2>
<p>In einem kurzen Gespraech klaeren wir gemeinsam, welche Prozesse in Ihrem Sekretariat zuerst vereinfacht werden sollten. Auf Wunsch erhalten Sie danach einen konkreten Einfuehrungsplan fuer Ihre Schule.</p> <p>Ein kurzes Gespräch schafft Klarheit über Prioritäten, Sicherheitsanforderungen und realistische Einführungsetappen für den Schulbetrieb.</p>
</div> </div>
{% if 'username' in session %} {% if 'username' in session %}
<a class="btn btn-secondary" href="{{ url_for('appointments') }}">Beratungstermin buchen</a> <a class="btn btn-secondary" href="{{ url_for('appointments') }}">Buchungsoption nutzen</a>
{% else %} {% else %}
<a class="btn btn-secondary" href="{{ url_for('login') }}">Beratungstermin buchen</a> <a class="btn btn-secondary" href="{{ url_for('login') }}">Buchungsoption nutzen</a>
{% endif %} {% endif %}
</section> </section>
{% endblock %} {% endblock %}
+16 -15
View File
@@ -5,46 +5,47 @@
{% block content %} {% block content %}
<section class="page-hero"> <section class="page-hero">
<h1>Praxisbeispiele aus dem Schulalltag</h1> <h1>Praxisbeispiele aus dem Schulalltag</h1>
<p>So setzen Schulen unsere Loesung ein, um Verwaltungsaufwand zu reduzieren und Ablaeufe transparent zu machen.</p> <p>So setzen Schulen unsere Lösung ein, um Verwaltungsaufwand zu reduzieren und Abläufe transparent zu machen.</p>
</section> </section>
<section class="split"> <section class="split">
<article class="panel"> <article class="panel">
<h2>Beispiel 1: Gymnasium mit 1.100 Schuelern</h2> <h2>Beispiel 1: Gymnasium mit 1.100 Schülern</h2>
<ul> <ul>
<li><strong>Ausgangslage:</strong> Inventardaten lagen in mehreren Excel-Listen und Papierordnern.</li> <li><strong>Ausgangslage:</strong> Inventardaten lagen in mehreren Excel-Listen und Papierordnern.</li>
<li><strong>Umsetzung:</strong> Zentralisierung von Geraeten, Raeumen und Verantwortlichkeiten in einer Plattform.</li> <li><strong>Umsetzung:</strong> Zentralisierung von Geräten, Räumen und Verantwortlichkeiten in einer Plattform.</li>
<li><strong>Ergebnis:</strong> Rueckfragen aus Schulleitung und Fachbereichen werden deutlich schneller beantwortet.</li> <li><strong>Ergebnis:</strong> Rückfragen aus Fachbereichen werden deutlich schneller beantwortet.</li>
</ul> </ul>
</article> </article>
<article class="panel"> <article class="panel">
<h2>Beispiel 2: Verbundschule mit mehreren Standorten</h2> <h2>Beispiel 2: Verbundschule mit mehreren Standorten</h2>
<ul> <ul>
<li><strong>Ausgangslage:</strong> Unterschiedliche Ablaeufe je Standort, keine gemeinsame Fristenuebersicht.</li> <li><strong>Ausgangslage:</strong> Unterschiedliche Abläufe je Standort, keine gemeinsame Fristenübersicht.</li>
<li><strong>Umsetzung:</strong> Einheitliche Prozesse fuer Inventar, Lizenzen und Supporttickets.</li> <li><strong>Umsetzung:</strong> Einheitliche Prozesse für Inventar, Lizenzen und Supporttickets.</li>
<li><strong>Ergebnis:</strong> Standortuebergreifende Transparenz und bessere Planbarkeit im Sekretariat.</li> <li><strong>Ergebnis:</strong> Standortübergreifende Transparenz und bessere Planbarkeit in der Verwaltung.</li>
</ul> </ul>
</article> </article>
</section> </section>
<section class="split" style="margin-top:0.9rem;"> <section class="split" style="margin-top:0.9rem;">
<article class="panel"> <article class="panel">
<h2>Beispiel 3: Berufskolleg mit Fokus IT-Raeume</h2> <h2>Beispiel 3: Berufskolleg mit Fokus IT-Räume</h2>
<ul> <ul>
<li><strong>Ausgangslage:</strong> Hohe Anzahl technischer Geraete mit haeufigen Aenderungen.</li> <li><strong>Ausgangslage:</strong> Hohe Anzahl technischer Geräte mit häufigen Änderungen.</li>
<li><strong>Umsetzung:</strong> QR-gestuetzte Bestandsfuehrung und klare Historie je Geraet.</li> <li><strong>Umsetzung:</strong> QR-gestützte Bestandsführung und klare Historie je Gerät.</li>
<li><strong>Ergebnis:</strong> Schnellere Inventur und weniger Fehler bei Standort- oder Statusaenderungen.</li> <li><strong>Ergebnis:</strong> Schnellere Inventur und weniger Fehler bei Standort- oder Statusänderungen.</li>
</ul> </ul>
</article> </article>
<article class="panel"> <article class="panel">
<h2>Was diese Projekte gemeinsam haben</h2> <h2>Was diese Projekte gemeinsam haben</h2>
<ul> <ul>
<li>Verstaendliche Bedienung ohne IT-Fachwissen</li> <li>Verständliche Bedienung ohne IT-Fachwissen</li>
<li>Klare Rollen fuer Sekretariat, Schulleitung und Administration</li> <li>Klare Rollen für Verwaltung und technische Aufgaben</li>
<li>Nachvollziehbare Dokumentation fuer interne Abstimmungen</li> <li>Nachvollziehbare Dokumentation für interne Abstimmungen</li>
<li>Schrittweise Einfuehrung im laufenden Schulbetrieb</li> <li>Schrittweise Einführung im laufenden Schulbetrieb</li>
<li>Sicherheitsorientierte Prozesse mit klaren Freigaben</li>
</ul> </ul>
</article> </article>
</section> </section>
+25 -4
View File
@@ -51,6 +51,19 @@
box-shadow: 0 0 0 3px rgba(58, 133, 180, 0.2); box-shadow: 0 0 0 3px rgba(58, 133, 180, 0.2);
} }
.checkbox-line {
display: flex;
align-items: flex-start;
gap: 0.6rem;
margin: 0.35rem 0 1rem;
color: #244f66;
}
.checkbox-line input {
width: auto;
margin-top: 0.2rem;
}
.auth-btn { .auth-btn {
width: 100%; width: 100%;
border: none; border: none;
@@ -77,12 +90,16 @@
{% block content %} {% block content %}
<section class="auth-wrap"> <section class="auth-wrap">
<h1>Registrierung</h1> <h1>Schulregistrierung</h1>
<p>Legen Sie ein Konto an, um den Kalender für Terminanfragen zu nutzen.</p> <p>Registrieren Sie Ihre Schule, um Buchungen, Lizenzen und Support zentral zu verwalten.</p>
<form method="POST" action="{{ url_for('register') }}"> <form method="POST" action="{{ url_for('register') }}">
<div class="field"> <div class="field">
<label for="display_name">Name</label> <label for="school_name">Name der Schule</label>
<input id="display_name" name="display_name" type="text" autocomplete="name" required> <input id="school_name" name="school_name" type="text" autocomplete="organization" required>
</div>
<div class="field">
<label for="contact_person">Ansprechpartner der Schule</label>
<input id="contact_person" name="contact_person" type="text" autocomplete="name" required>
</div> </div>
<div class="field"> <div class="field">
<label for="username">Benutzername</label> <label for="username">Benutzername</label>
@@ -96,6 +113,10 @@
<label for="password_repeat">Passwort wiederholen</label> <label for="password_repeat">Passwort wiederholen</label>
<input id="password_repeat" name="password_repeat" type="password" autocomplete="new-password" required> <input id="password_repeat" name="password_repeat" type="password" autocomplete="new-password" required>
</div> </div>
<label class="checkbox-line" for="activate_test_key">
<input id="activate_test_key" name="activate_test_key" type="checkbox" value="1">
<span>Direkt bei Registrierung einen Test-Key aktivieren</span>
</label>
<button class="auth-btn" type="submit">Konto erstellen</button> <button class="auth-btn" type="submit">Konto erstellen</button>
</form> </form>
<p class="auth-meta">Bereits registriert? <a href="{{ url_for('login') }}">Zum Login</a></p> <p class="auth-meta">Bereits registriert? <a href="{{ url_for('login') }}">Zum Login</a></p>
+13 -13
View File
@@ -4,34 +4,34 @@
{% block content %} {% block content %}
<section class="page-hero"> <section class="page-hero">
<h1>Unser Ansatz fuer Schulen</h1> <h1>Unser Ansatz für Schulen</h1>
<p>Wir arbeiten strukturiert, persoenlich und mit Fokus auf den praktischen Nutzen im Sekretariat und in der Schulleitung.</p> <p>Die Arbeitsweise ist strukturiert, persönlich und auf den praktischen Nutzen in der täglichen Verwaltung ausgerichtet.</p>
</section> </section>
<section class="grid"> <section class="grid">
<article class="member"> <article class="member">
<h2>Verstaendliche Beratung</h2> <h2>Verständliche Beratung</h2>
<p>Wir uebersetzen technische Moeglichkeiten in klare Entscheidungen: Was bringt im Schulalltag wirklich Entlastung und was nicht.</p> <p>Technische Möglichkeiten werden in klare Entscheidungen übersetzt: Was bringt im Schulalltag wirklich Entlastung und was nicht.</p>
<p><strong>Ihr Vorteil:</strong> Keine unnoetigen Funktionen, sondern ein klarer Fahrplan mit nachvollziehbaren Prioritaeten.</p> <p><strong>Ergebnis:</strong> Keine unnötigen Funktionen, sondern ein klarer Fahrplan mit nachvollziehbaren Prioritäten.</p>
</article> </article>
<article class="member"> <article class="member">
<h2>Saubere Einfuehrung</h2> <h2>Saubere Einführung</h2>
<p>Das System wird gemeinsam mit Ihrem Team eingerichtet, ohne den laufenden Betrieb zu ueberlasten.</p> <p>Das System wird gemeinsam mit den verantwortlichen Teams eingerichtet, ohne den laufenden Betrieb zu überlasten.</p>
<p><strong>Ihr Vorteil:</strong> Schrittweise Umstellung mit Schulung direkt an Ihren typischen Arbeitsablaeufen.</p> <p><strong>Ergebnis:</strong> Schrittweise Umstellung mit Schulung direkt an typischen Arbeitsabläufen.</p>
</article> </article>
<article class="member"> <article class="member">
<h2>Zuverlaessige Begleitung</h2> <h2>Zuverlässige Begleitung</h2>
<p>Nach der Einfuehrung bleiben wir erreichbar und unterstuetzen bei Anpassungen, Fragen und neuen Anforderungen.</p> <p>Nach der Einführung bleibt das Team erreichbar und unterstützt bei Anpassungen, Fragen und neuen Anforderungen.</p>
<p><strong>Ihr Vorteil:</strong> Feste Ansprechpartner und verlässliche Rueckmeldung statt wechselnder Kontaktwege.</p> <p><strong>Ergebnis:</strong> Feste Ansprechpartner und verlässliche Rückmeldung statt wechselnder Kontaktwege.</p>
</article> </article>
</section> </section>
<section class="references"> <section class="references">
<h2>Werte, nach denen wir arbeiten</h2> <h2>Werte, nach denen wir arbeiten</h2>
<ul> <ul>
<li>Klarheit vor Komplexitaet</li> <li>Klarheit vor Komplexität</li>
<li>Datenschutz als Standard, nicht als Zusatz</li> <li>Datenschutz als Standard, nicht als Zusatz</li>
<li>Respekt fuer die Arbeitsrealitaet in Schulen</li> <li>Respekt für die Arbeitsrealität in Schulen</li>
<li>Verbindliche Kommunikation und transparente Schritte</li> <li>Verbindliche Kommunikation und transparente Schritte</li>
</ul> </ul>
</section> </section>
+64
View File
@@ -0,0 +1,64 @@
{% extends "base.html" %}
{% block title %}Tutorial | Invario{% endblock %}
{% block content %}
<section class="page-hero">
<h1>Tutorial: Sicherer Start mit Invario</h1>
<p>Diese Schritt-für-Schritt-Anleitung zeigt den Einstieg in Inventar, Lizenzen und Supportprozesse mit besonderem Fokus auf Sicherheit im Alltag.</p>
</section>
<section class="grid">
<article class="card">
<h2>1. Nutzerkonten und Rollen anlegen</h2>
<p>Zuerst werden Rollen für Verwaltung und Technik eingerichtet. Jede Rolle erhält nur die benötigten Rechte, um Risiken durch Überberechtigungen zu vermeiden.</p>
</article>
<article class="card">
<h2>2. Inventardaten strukturiert übernehmen</h2>
<p>Geräte, Räume und Zuständigkeiten werden einheitlich erfasst. Klare Datenstrukturen verbessern die Nachvollziehbarkeit und unterstützen Prüfungen.</p>
</article>
<article class="card">
<h2>3. Lizenzfristen aktiv überwachen</h2>
<p>Lizenzlaufzeiten und Erinnerungen werden zentral gepflegt. So lassen sich Ausfälle vermeiden und Fristen rechtzeitig bearbeiten.</p>
</article>
<article class="card">
<h2>4. Supportabläufe definieren</h2>
<p>Tickets erhalten klare Prioritäten und feste Statuswerte. Das schafft Transparenz und beschleunigt die Bearbeitung im Tagesbetrieb.</p>
</article>
</section>
<section class="security-box">
<h2>Sicherheitsleitfaden für den Betrieb</h2>
<ul>
<li><strong>Zugriffsschutz:</strong> Rollenbasiertes Arbeiten mit getrennten Zuständigkeiten.</li>
<li><strong>Sitzungssicherheit:</strong> Session-Cookies mit sicheren Standardeinstellungen.</li>
<li><strong>Übertragung:</strong> Einsatz sicherer Protokolle und Schutz-Header für Webanfragen.</li>
<li><strong>Nachvollziehbarkeit:</strong> Protokollierung relevanter Änderungen und Aktionen.</li>
<li><strong>Datenschutz:</strong> Datenminimierung und dokumentierte Verarbeitungsprozesse.</li>
<li><strong>Kontinuität:</strong> Regelmäßige Backups und Wiederanlaufplanung.</li>
</ul>
</section>
<section class="next-step">
<h2>Nächster Schritt</h2>
<p>Für die Einführung empfiehlt sich ein kurzer Pilotbetrieb mit realen Beispieldaten, bevor die vollständige Übernahme in den Produktivbetrieb erfolgt.</p>
{% if 'username' in session %}
<a class="btn" href="{{ url_for('appointments') }}">Pilotstart planen</a>
{% else %}
<a class="btn" href="{{ url_for('login') }}">Login für Buchung</a>
{% endif %}
</section>
<style>
.page-hero { margin-bottom: 1.2rem; }
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 0.9rem; }
.card { background: #fff; border: 1px solid #d8dfd7; border-radius: 14px; padding: 1rem; box-shadow: 0 10px 24px rgba(25, 45, 41, 0.04); }
.card h2 { color: #265057; margin-bottom: 0.45rem; font-size: clamp(1.05rem, 1.8vw, 1.35rem); }
.security-box { margin-top: 0.9rem; background: linear-gradient(135deg, #f8f4eb 0%, #eef3eb 100%); border: 1px solid #d4dbd2; border-radius: 14px; padding: 1.1rem; }
.security-box h2 { color: #2a4d53; margin-bottom: 0.45rem; font-size: clamp(1.1rem, 2.2vw, 1.55rem); }
.security-box ul { margin: 0; padding-left: 1.1rem; color: #4a6267; display: grid; gap: 0.5rem; }
.next-step { margin-top: 0.9rem; background: #fff; border: 1px solid #d8dfd7; border-radius: 14px; padding: 1rem; box-shadow: 0 10px 24px rgba(25, 45, 41, 0.04); }
.next-step h2 { color: #265057; margin-bottom: 0.45rem; font-size: clamp(1.05rem, 1.8vw, 1.35rem); }
.btn { margin-top: 0.5rem; display: inline-flex; align-items: center; justify-content: center; border-radius: 999px; border: 1px solid #1d5a63; background: linear-gradient(120deg, #296f78 0%, #1a5057 100%); color: #fff; padding: 0.54rem 0.92rem; font-weight: 700; }
</style>
{% endblock %}