Changes to the generall customer pool
This commit is contained in:
@@ -392,6 +392,29 @@ def _get_collection(name: str):
|
||||
return client, db[name]
|
||||
|
||||
|
||||
HOMEPAGE_MODES = {"choose", "school", "business"}
|
||||
|
||||
|
||||
def _get_homepage_mode() -> str:
|
||||
client = None
|
||||
try:
|
||||
client, collection = _get_collection("site_settings")
|
||||
setting = collection.find_one({"key": "homepage_mode"}) or {}
|
||||
mode = setting.get("value", "choose")
|
||||
return mode if mode in HOMEPAGE_MODES else "choose"
|
||||
except PyMongoError:
|
||||
return "choose"
|
||||
finally:
|
||||
if client:
|
||||
client.close()
|
||||
|
||||
|
||||
def _render_audience_page(audience: str):
|
||||
if audience == "business":
|
||||
return render_template("business.html")
|
||||
return render_template("main.html")
|
||||
|
||||
|
||||
def _list_users_for_admin() -> list:
|
||||
docs = user_store.get_all_users() or []
|
||||
users = []
|
||||
@@ -1846,9 +1869,37 @@ def admin_required(view_func):
|
||||
|
||||
@app.route("/", methods=["GET", "POST"])
|
||||
def default():
|
||||
mode = _get_homepage_mode()
|
||||
audience = mode if mode != "choose" else session.get("homepage_audience")
|
||||
if audience in {"school", "business"}:
|
||||
return _render_audience_page(audience)
|
||||
return render_template("audience.html")
|
||||
|
||||
|
||||
@app.route("/audience", methods=["GET", "POST"])
|
||||
def audience():
|
||||
if request.method == "POST":
|
||||
selected = (request.form.get("audience") or "").strip().lower()
|
||||
if selected not in {"school", "business"}:
|
||||
flash("Bitte wählen Sie einen gültigen Bereich aus.", "error")
|
||||
return redirect(url_for("audience"))
|
||||
session["homepage_audience"] = selected
|
||||
return redirect(url_for("default"))
|
||||
return render_template("audience.html")
|
||||
|
||||
|
||||
@app.route("/school")
|
||||
def school_homepage():
|
||||
session["homepage_audience"] = "school"
|
||||
return render_template("main.html")
|
||||
|
||||
|
||||
@app.route("/business")
|
||||
def business_homepage():
|
||||
session["homepage_audience"] = "business"
|
||||
return render_template("business.html")
|
||||
|
||||
|
||||
@app.route('/health')
|
||||
def health():
|
||||
return jsonify({"status": "ok", "time": _utc_now_iso()}), 200
|
||||
@@ -3529,6 +3580,34 @@ def admin_instances():
|
||||
parent_domain=INSTANCE_PARENT_DOMAIN,
|
||||
)
|
||||
|
||||
|
||||
@app.route('/admin/site-settings', methods=['GET', 'POST'])
|
||||
@admin_required
|
||||
def admin_site_settings():
|
||||
if request.method == "POST":
|
||||
mode = (request.form.get("homepage_mode") or "").strip().lower()
|
||||
if mode not in HOMEPAGE_MODES:
|
||||
flash("Ungültige Startseiten-Einstellung.", "error")
|
||||
return redirect(url_for("admin_site_settings"))
|
||||
client = None
|
||||
try:
|
||||
client, collection = _get_collection("site_settings")
|
||||
collection.update_one(
|
||||
{"key": "homepage_mode"},
|
||||
{"$set": {"key": "homepage_mode", "value": mode, "updated_at": _utc_now_iso()}},
|
||||
upsert=True,
|
||||
)
|
||||
flash("Startseiten-Modus gespeichert.", "success")
|
||||
except PyMongoError:
|
||||
flash("Die Startseiten-Einstellung konnte nicht gespeichert werden.", "error")
|
||||
finally:
|
||||
if client:
|
||||
client.close()
|
||||
return redirect(url_for("admin_site_settings"))
|
||||
|
||||
return render_template("admin_site_settings.html", homepage_mode=_get_homepage_mode())
|
||||
|
||||
|
||||
@app.route('/admin/blog', methods=['GET', 'POST'])
|
||||
@admin_required
|
||||
def admin_blog():
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Admin | Startseite verwalten{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section style="max-width: 760px; margin: 2rem auto;">
|
||||
<div style="padding: 2rem; border: 1px solid #d0d7d0; border-radius: 18px; background: #fff; box-shadow: 0 14px 30px rgba(28,45,41,.07);">
|
||||
<p style="color:#1c5a63; font-weight:800; text-transform:uppercase; letter-spacing:.06em;">Admin-Einstellung</p>
|
||||
<h1 style="margin:.45rem 0 .7rem;">Startseiten-Modus</h1>
|
||||
<p>Steuern Sie, ob Besucher zuerst wählen oder direkt auf eine Zielgruppen-Seite gelangen.</p>
|
||||
<form method="post" style="display:grid; gap:1rem; margin-top:1.5rem;">
|
||||
<label style="display:flex; gap:.7rem; align-items:flex-start; padding:1rem; border:1px solid #d8e1da; border-radius:12px;">
|
||||
<input type="radio" name="homepage_mode" value="choose" {% if homepage_mode == "choose" %}checked{% endif %}>
|
||||
<span><strong>Auswahl anzeigen</strong><br><small>Neue Besucher wählen zwischen Schulen und Betrieben.</small></span>
|
||||
</label>
|
||||
<label style="display:flex; gap:.7rem; align-items:flex-start; padding:1rem; border:1px solid #d8e1da; border-radius:12px;">
|
||||
<input type="radio" name="homepage_mode" value="school" {% if homepage_mode == "school" %}checked{% endif %}>
|
||||
<span><strong>Schule als Standard</strong><br><small>Die bestehende Schul-Startseite wird direkt angezeigt.</small></span>
|
||||
</label>
|
||||
<label style="display:flex; gap:.7rem; align-items:flex-start; padding:1rem; border:1px solid #d8e1da; border-radius:12px;">
|
||||
<input type="radio" name="homepage_mode" value="business" {% if homepage_mode == "business" %}checked{% endif %}>
|
||||
<span><strong>Betriebe als Standard</strong><br><small>Die Business-Startseite wird direkt angezeigt.</small></span>
|
||||
</label>
|
||||
<button type="submit" style="justify-self:start; border:0; border-radius:999px; padding:.75rem 1.2rem; background:#1c5a63; color:#fff; font-weight:800; cursor:pointer;">Einstellung speichern</button>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,66 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% set meta_title = "Invario – die passende Lösung für Ihre Organisation" %}
|
||||
{% set meta_description = "Wählen Sie Invario für Schulen oder für Werkzeug- und Asset-Management in Betrieben." %}
|
||||
|
||||
{% block title %}Ihre Invario-Lösung{% endblock %}
|
||||
|
||||
{% block head %}
|
||||
{{ super() }}
|
||||
<style>
|
||||
.audience-page { padding: clamp(1.5rem, 5vw, 4rem) 0 2rem; }
|
||||
.audience-intro { max-width: 700px; margin: 0 auto 2rem; text-align: center; }
|
||||
.audience-intro .eyebrow { color: #1c5a63; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; }
|
||||
.audience-intro h1 { margin: .55rem 0 .8rem; color: #173d44; }
|
||||
.audience-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.1rem; }
|
||||
.audience-card { padding: clamp(1.3rem, 3vw, 2rem); border: 1px solid #d5ded8; border-radius: 22px; background: #fff; box-shadow: 0 18px 40px rgba(27, 55, 58, .08); }
|
||||
.audience-card.business { background: linear-gradient(145deg, #102e35, #1d5e62); color: #fff; border-color: #1d5e62; }
|
||||
.audience-card h2 { margin: .8rem 0 .55rem; font-size: clamp(1.35rem, 3vw, 2rem); }
|
||||
.audience-card p { margin-bottom: 1.1rem; }
|
||||
.business p { color: #d7edeb; }
|
||||
.audience-icon { display: grid; place-items: center; width: 3rem; height: 3rem; border-radius: 14px; background: #e7f1ed; color: #1b6164; font-size: 1.45rem; }
|
||||
.business .audience-icon { background: rgba(255,255,255,.14); color: #fff; }
|
||||
.audience-list { display: grid; gap: .45rem; margin: 0 0 1.35rem; padding: 0; list-style: none; }
|
||||
.audience-list li::before { content: "✓"; margin-right: .55rem; font-weight: 800; color: #2b8876; }
|
||||
.business .audience-list li::before { color: #a7e5b7; }
|
||||
.audience-button { display: inline-flex; padding: .7rem 1rem; border-radius: 999px; background: #1d6970; color: #fff; font-weight: 800; }
|
||||
.business .audience-button { background: #d9f29a; color: #183d3a; }
|
||||
@media (max-width: 700px) { .audience-grid { grid-template-columns: 1fr; } }
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<main class="audience-page">
|
||||
<div class="audience-intro">
|
||||
<span class="eyebrow">Willkommen bei Invario</span>
|
||||
<h1>Welche Lösung passt zu Ihnen?</h1>
|
||||
<p>Wählen Sie Ihren Bereich. Sie sehen anschließend Inhalte, Beispiele und Vorteile, die zu Ihrem Alltag passen.</p>
|
||||
</div>
|
||||
<div class="audience-grid">
|
||||
<form method="post" action="{{ url_for('audience') }}" class="audience-card">
|
||||
<input type="hidden" name="audience" value="school">
|
||||
<div class="audience-icon" aria-hidden="true">▦</div>
|
||||
<h2>Für Schulen</h2>
|
||||
<p>Lehrmittel, iPads, Bücher und Ausleihe klar und sicher verwalten.</p>
|
||||
<ul class="audience-list">
|
||||
<li>Inventar und Medien zentral im Blick</li>
|
||||
<li>Barcode-gestützte Ausgabe und Rückgabe</li>
|
||||
<li>Nachvollziehbare Abläufe für Kollegium und Verwaltung</li>
|
||||
</ul>
|
||||
<button class="audience-button" type="submit">Schul-Lösung ansehen</button>
|
||||
</form>
|
||||
<form method="post" action="{{ url_for('audience') }}" class="audience-card business">
|
||||
<input type="hidden" name="audience" value="business">
|
||||
<div class="audience-icon" aria-hidden="true">⌁</div>
|
||||
<h2>Für Betriebe</h2>
|
||||
<p>Werkzeuge, Fahrzeuge und Assets im Team zuverlässig organisieren.</p>
|
||||
<ul class="audience-list">
|
||||
<li>Werkzeug in Sekunden finden und zuordnen</li>
|
||||
<li>Transporter, Baustellen und Termine koordinieren</li>
|
||||
<li>Weniger Verluste, weniger Rückfragen, mehr Überblick</li>
|
||||
</ul>
|
||||
<button class="audience-button" type="submit">Business-Lösung ansehen</button>
|
||||
</form>
|
||||
</div>
|
||||
</main>
|
||||
{% endblock %}
|
||||
@@ -534,6 +534,7 @@
|
||||
<a href="{{ url_for('dienstleistungen') }}">Module</a>
|
||||
<a href="{{ url_for('blog') }}">Neuigkeiten</a>
|
||||
<a href="{{ url_for('kontakt') }}">Kontakt</a>
|
||||
<a href="{{ url_for('audience') }}">Bereich wechseln</a>
|
||||
|
||||
{% if session.get('is_admin') %}
|
||||
<a class="nav-user-link" href="{{ url_for('user_profile') }}">Mein Profil</a>
|
||||
@@ -543,6 +544,7 @@
|
||||
<a class="nav-user-link" href="{{ url_for('admin_chats') }}">Admin-Chat</a>
|
||||
<a class="nav-user-link" href="{{ url_for('admin_tickets') }}">Support-Center</a>
|
||||
<a class="nav-user-link" href="{{ url_for('admin_instances') }}">Schul-Instanzen</a>
|
||||
<a class="nav-user-link" href="{{ url_for('admin_site_settings') }}">Startseite verwalten</a>
|
||||
{% elif 'username' in session %}
|
||||
<a class="nav-user-link" href="{{ url_for('user_profile') }}">Mein Profil</a>
|
||||
<a class="nav-user-link" href="{{ url_for('my_tutorials') }}">Tutorials</a>
|
||||
@@ -569,6 +571,7 @@
|
||||
<a href="{{ url_for('admin_tickets') }}">Support-Center</a>
|
||||
<a href="{{ url_for('admin_blog') }}">Blog verwalten</a>
|
||||
<a href="{{ url_for('admin_instances') }}">Schul-Instanzen</a>
|
||||
<a href="{{ url_for('admin_site_settings') }}">Startseite verwalten</a>
|
||||
</div>
|
||||
</details>
|
||||
<a class="nav-btn" href="{{ url_for('logout') }}">Logout</a>
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% set meta_title = "Werkzeug- und Asset-Management für Betriebe | Invario" %}
|
||||
{% set meta_description = "Invario bringt Ordnung in Werkzeug, Fahrzeuge und Assets von Handwerks-, Elektro- und Bauunternehmen." %}
|
||||
|
||||
{% block title %}Werkzeugverwaltung, die mitarbeitet{% endblock %}
|
||||
|
||||
{% block head %}
|
||||
{{ super() }}
|
||||
<style>
|
||||
.business-home { --ink:#102f35; --muted:#557074; --lime:#d9f29a; --teal:#1f696c; }
|
||||
.business-hero { margin-top:1rem; padding:clamp(1.7rem,5vw,4.6rem); border-radius:28px; color:#fff; background: radial-gradient(circle at 90% 15%, rgba(217,242,154,.25), transparent 28%), linear-gradient(125deg,#0d2930,#1d5e62 68%,#286b67); overflow:hidden; }
|
||||
.business-hero .eyebrow { color:var(--lime); font-weight:800; letter-spacing:.08em; text-transform:uppercase; }
|
||||
.business-hero h1 { max-width: 760px; margin:.8rem 0 1rem; font-size:clamp(2.2rem,6vw,5rem); line-height:1.02; letter-spacing:-.04em; }
|
||||
.business-hero p { max-width:650px; color:#d5e9e6; font-size:clamp(1.05rem,1.5vw,1.25rem); }
|
||||
.business-actions { display:flex; flex-wrap:wrap; gap:.7rem; margin-top:1.7rem; }
|
||||
.business-btn { display:inline-flex; padding:.78rem 1.15rem; border-radius:999px; background:var(--lime); color:#183c3b; font-weight:800; }
|
||||
.business-btn.secondary { background:rgba(255,255,255,.1); border:1px solid rgba(255,255,255,.45); color:#fff; }
|
||||
.business-section { margin-top:1.1rem; padding:clamp(1.3rem,3vw,2.2rem); border:1px solid #d5e0dc; border-radius:22px; background:#fff; }
|
||||
.business-section h2 { color:var(--ink); margin-bottom:.45rem; }
|
||||
.business-grid { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:.8rem; margin-top:1.2rem; }
|
||||
.business-card { padding:1.1rem; border-radius:15px; background:#f2f7f2; border:1px solid #dbe7dc; }
|
||||
.business-card strong { display:block; color:var(--teal); margin-bottom:.35rem; font-size:1.08rem; }
|
||||
.business-proof { display:grid; grid-template-columns:1.1fr .9fr; gap:1rem; align-items:stretch; }
|
||||
.business-proof .highlight { padding:1.5rem; border-radius:18px; color:#fff; background:var(--ink); }
|
||||
.business-proof .highlight p { color:#cfe1dd; }
|
||||
.business-proof ul { margin:1rem 0 0; padding:0; list-style:none; display:grid; gap:.5rem; }
|
||||
.business-proof li::before { content:"✓"; color:var(--lime); font-weight:800; margin-right:.5rem; }
|
||||
.business-cta { display:flex; justify-content:space-between; align-items:center; gap:1rem; background:#e9f1e7; }
|
||||
@media (max-width:780px) { .business-grid,.business-proof { grid-template-columns:1fr; } .business-cta { align-items:flex-start; flex-direction:column; } }
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<main class="business-home">
|
||||
<header class="business-hero">
|
||||
<span class="eyebrow">Für Handwerk, Elektro & Bau</span>
|
||||
<h1>Werkzeug finden. Auftrag starten. Feierabend machen.</h1>
|
||||
<p>Invario macht aus verstreuten Werkzeugkisten, Transportern und Excel-Listen einen klaren digitalen Bestand. Damit Ihr Team weiß, was wo ist – und wer es zuletzt hatte.</p>
|
||||
<div class="business-actions">
|
||||
<a class="business-btn" href="{{ url_for('kontakt') }}">Persönliche Demo anfragen</a>
|
||||
<a class="business-btn secondary" href="#module">Module entdecken</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<section class="business-section" id="module">
|
||||
<h2>Die tägliche Unordnung verschwindet</h2>
|
||||
<p>Die bestehende Invario-Modul-Suite ist für den Betrieb gedacht: schnell erfassbar, mobil nutzbar und ohne langes Einführungsprojekt.</p>
|
||||
<div class="business-grid">
|
||||
<article class="business-card"><strong>Inventar & Assets</strong><p>Werkzeuge, Maschinen, Verbrauchsmaterial und Schutzausrüstung mit Status, Standort und Verantwortlichkeit.</p></article>
|
||||
<article class="business-card"><strong>Barcode-Scanner</strong><p>Ausgabe und Rücknahme direkt am Fahrzeug oder auf der Baustelle. Jeder Vorgang bleibt nachvollziehbar.</p></article>
|
||||
<article class="business-card"><strong>Termine & Objekte</strong><p>Aufträge, Baustellen, Fahrzeuge und Material zusammenführen – damit die Vorbereitung nicht im Chat verloren geht.</p></article>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="business-section business-proof">
|
||||
<div>
|
||||
<h2>Für Inhaber gemacht, die entscheiden</h2>
|
||||
<p>Kurze Vertriebs- und Einführungszyklen statt monatelanger Softwareprojekte. Wir zeigen Ihnen am echten Bestand, wie Invario in Ihren Ablauf passt.</p>
|
||||
<ul>
|
||||
<li>Weniger Suchzeit und weniger Ersatzkäufe</li>
|
||||
<li>Klare Verantwortlichkeiten im Team</li>
|
||||
<li>Schlanke Fixkosten, die sich schnell rechnen</li>
|
||||
</ul>
|
||||
</div>
|
||||
<aside class="highlight"><h3>Einfach starten</h3><p>Bestand aufnehmen, QR- oder Barcodes vergeben, Team einladen – und sofort den ersten Auftrag digital vorbereiten.</p></aside>
|
||||
</section>
|
||||
|
||||
<section class="business-section business-cta">
|
||||
<div><h2>Sehen Sie, was in Ihrem Betrieb möglich ist.</h2><p>Ein kurzes Gespräch genügt für eine konkrete Einschätzung.</p></div>
|
||||
<a class="business-btn" href="{{ url_for('kontakt') }}">Gespräch vereinbaren</a>
|
||||
</section>
|
||||
</main>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user