Files
it-hilf-sofort/app.py
T
Hermes Agent b86cb1742a fix: Blog-Routen + modernes Design + §400-Hinweis
- Blog-Route nutzt jetzt _ARTIKEL-Mapping (statt falscher Dateinamen-Konstruktion)
- Vollstaendiges CSS-Redesign: White Cards, Shadows, Sticky-Header, Gradient-Hero
- Kontakt-CTA-Banner auf jeder Seite vor dem Footer
- §400 BGB Vermittlungshinweis im Footer aller Seiten
- FAQ mit details/summary-Akkordeon + CSS-Indikatoren
- Verbesserte Typografie und Spacing
2026-06-25 18:20:05 +02:00

472 lines
27 KiB
Python

#!/usr/bin/env python3
"""IT-Hilfe-Sofort.de — Flask-Webapp fuer IT-Dienstleistungen im Gesundheitswesen."""
import os
import re
from pathlib import Path
from flask import Flask
BASE_DIR = Path(__file__).parent
ARTIKEL_DIR = BASE_DIR
PORT = int(os.environ.get("PORT", "5003"))
app = Flask(__name__)
def _base_template(title: str, content: str, active: str = "") -> str:
"""Wrapper fuer einheitliches Seitenlayout.
Args:
title: Seitentitel als String.
content: HTML-Inhalt der Seite.
active: Aktiver Navigationspunkt.
Returns:
Vollstaendiges HTML-Dokument als String.
"""
# Kontakt-Banner (auf jeder Seite)
kontakt_banner = """
<section class="cta-banner">
<div class="cta-inner">
<div class="cta-text">
<h2>Bereit fuer die digitale Zukunft?</h2>
<p>Kostenlose Erstberatung — wir finden die passende IT-Loesung fuer Ihre Einrichtung.</p>
</div>
<a href="/kontakt" class="btn-primary btn-large">Jetzt Beratungsgespraech vereinbaren</a>
</div>
</section>"""
# Footer mit §400-Hinweis
footer_vermittlung = """
<p style="margin-top:1rem;font-size:0.8rem;color:#6B7280;max-width:600px;margin-left:auto;margin-right:auto">
* Wir vermitteln IT-Dienstleistungen und -Produkte. Es faellt eine Vermittlungsgebuehr
gemaess § 400 BGB an — diese fuehrt nicht zu hoeheren Preisen fuer Sie.
</p>"""
return f"""<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{title} | IT-Hilfe-Sofort.de</title>
<style>
*,*::before,*::after{{box-sizing:border-box;margin:0;padding:0}}
body{{font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;background:#FAFBFC;color:#1a1a2e;line-height:1.7;font-size:16px}}
.site-header{{background:#fff;border-bottom:1px solid #e8ecf1;padding:0 2rem;display:flex;align-items:center;justify-content:space-between;position:sticky;top:0;z-index:100;height:64px;box-shadow:0 1px 3px rgba(0,0,0,0.04)}}
.site-header .logo{{color:#20228a;font-weight:800;font-size:1.05rem;letter-spacing:-0.01em;text-decoration:none;display:flex;align-items:center;gap:0.5rem}}
.site-header .logo::before{{content:'';display:inline-block;width:28px;height:28px;background:linear-gradient(135deg,#20228a,#3b4fd4);border-radius:6px}}
.nav-link{{color:#4a5568;text-decoration:none;font-size:0.9rem;padding:0.5rem 0.75rem;border-radius:6px;transition:all 0.15s;font-weight:500}}
.nav-link:hover,.nav-link.active{{color:#20228a;background:#f0f2ff}}
.menu-toggle{{background:none;border:none;color:#4a5568;font-size:0.9rem;font-weight:600;cursor:pointer;padding:0.5rem;display:none}}
.hero{{background:linear-gradient(135deg,#20228a 0%,#2d3496 40%,#1a1e6e 100%);color:#fff;padding:6rem 2rem;text-align:center;position:relative;overflow:hidden}}
.hero::after{{content:'';position:absolute;top:-50%;right:-20%;width:500px;height:500px;background:rgba(255,255,255,0.03);border-radius:50%;pointer-events:none}}
.hero h1{{font-size:2.8rem;font-weight:800;letter-spacing:-0.03em;line-height:1.15;margin-bottom:1.25rem;position:relative;z-index:1}}
.hero p{{color:rgba(255,255,255,0.85);font-size:1.15rem;max-width:650px;margin:0 auto;position:relative;z-index:1;line-height:1.6}}
.hero .btn-primary{{margin-top:2rem;position:relative;z-index:1}}
.card{{background:#fff;border:1px solid #e8ecf1;border-radius:12px;padding:2rem;transition:box-shadow 0.2s,transform 0.2s}}
.card:hover{{box-shadow:0 8px 30px rgba(32,34,138,0.08);transform:translateY(-2px)}}
.card h2,.card h3{{font-size:1.15rem;font-weight:700;margin-bottom:0.75rem;color:#20228a}}
.card p{{color:#4a5568;font-size:0.95rem;line-height:1.65}}
.card-grid{{display:grid;grid-template-columns:1fr;gap:1.5rem;max-width:1100px;margin:0 auto;padding:0 2rem}}
@media(min-width:768px){{.card-grid{{grid-template-columns:repeat(3,1fr)}}}}
@media(min-width:768px){{.card-grid-4{{grid-template-columns:repeat(2,1fr)}}}}
@media(min-width:1024px){{.card-grid-4{{grid-template-columns:repeat(4,1fr)}}}}
.btn-primary{{display:inline-block;background:#20228a;color:#fff;border:none;border-radius:8px;padding:0.8rem 2rem;font-size:0.95rem;font-weight:600;text-decoration:none;cursor:pointer;transition:all 0.2s;box-shadow:0 2px 8px rgba(32,34,138,0.2)}}
.btn-primary:hover{{background:#161e6e;box-shadow:0 4px 16px rgba(32,34,138,0.3);transform:translateY(-1px)}}
.btn-large{{padding:1rem 2.5rem;font-size:1.05rem}}
.content{{max-width:760px;margin:3rem auto;padding:0 2rem}}
.content h1{{font-size:2.2rem;font-weight:800;letter-spacing:-0.02em;margin-bottom:1rem;color:#1a1a2e}}
.content h2{{font-size:1.5rem;font-weight:700;margin:2.5rem 0 1rem;color:#20228a}}
.content h3{{font-size:1.15rem;font-weight:700;margin:1.5rem 0 0.75rem;color:#1a1a2e}}
.content p{{margin-bottom:1.25rem;line-height:1.75;color:#4a5568}}
.content ul,.content ol{{margin:1rem 0 1.5rem 1.5rem;color:#4a5568}}
.content li{{margin-bottom:0.5rem;line-height:1.65}}
.section{{padding:5rem 2rem}}
.section h2{{font-size:2rem;font-weight:800;text-align:center;margin-bottom:2.5rem;letter-spacing:-0.02em;color:#1a1a2e}}
.section-sub{{color:#6b7280;text-align:center;max-width:600px;margin:-1.5rem auto 2.5rem;font-size:1.05rem}}
.site-footer{{background:#1a1a2e;color:#94a3b8;padding:3rem 2rem;font-size:0.9rem;text-align:center}}
.site-footer a{{color:#cbd5e1;text-decoration:none;margin:0 0.75rem;transition:color 0.15s}}
.site-footer a:hover{{color:#fff}}
.cta-banner{{background:linear-gradient(135deg,#f0f2ff,#e8ecf5);padding:4rem 2rem;border-top:1px solid #e8ecf1;border-bottom:1px solid #e8ecf1}}
.cta-inner{{max-width:900px;margin:0 auto;display:flex;align-items:center;justify-content:space-between;gap:2rem;flex-wrap:wrap}}
.cta-text h2{{font-size:1.5rem;font-weight:700;color:#1a1a2e;margin-bottom:0.5rem}}
.cta-text p{{color:#4a5568;font-size:1rem}}
.article-layout{{display:grid;grid-template-columns:1fr 280px;gap:3rem;max-width:1100px;margin:0 auto;padding:3rem 2rem}}
@media(max-width:860px){{.article-layout{{grid-template-columns:1fr}}}}
.article-content{{max-width:680px}}
.article-content img{{max-width:100%;border-radius:8px;margin:1.5rem 0}}
.article-sidebar{{background:#fff;border:1px solid #e8ecf1;border-radius:12px;padding:1.5rem;align-self:start;position:sticky;top:80px}}
.sidebar-title{{font-size:0.85rem;font-weight:700;text-transform:uppercase;letter-spacing:0.05em;color:#94a3b8;margin-bottom:1rem}}
.sidebar-link{{display:block;color:#20228a;text-decoration:none;padding:0.5rem 0;font-size:0.9rem;font-weight:500;border-bottom:1px solid #f0f2f5;transition:color 0.15s}}
.sidebar-link:last-child{{border-bottom:none}}
.sidebar-link:hover{{color:#161e6e}}
.faq-item{{background:#fff;border:1px solid #e8ecf1;border-radius:10px;padding:1.25rem 1.5rem;margin-bottom:0.75rem;cursor:pointer;transition:box-shadow 0.15s}}
.faq-item:hover{{box-shadow:0 4px 12px rgba(0,0,0,0.04)}}
.faq-item summary{{font-weight:600;color:#1a1a2e;list-style:none;display:flex;justify-content:space-between;align-items:center}}
.faq-item summary::after{{content:'+';font-size:1.3rem;color:#20228a;font-weight:400}}
.faq-item[open] summary::after{{content:'-'}}
.faq-item .answer{{margin-top:0.75rem;color:#4a5568;line-height:1.65}}
.badge{{display:inline-block;background:#f0f2ff;color:#20228a;font-size:0.8rem;font-weight:600;padding:0.25rem 0.75rem;border-radius:20px}}
.contact-info{{background:#fff;border:1px solid #e8ecf1;border-radius:12px;padding:2rem}}
.contact-info h3{{margin-bottom:1rem}}
.contact-info p{{margin-bottom:0.5rem}}
@media(max-width:767px){{
.menu-toggle{{display:block}}
nav#mainNav{{display:none}}
nav#mainNav.open{{display:flex;flex-direction:column;position:fixed;top:64px;left:0;right:0;background:#fff;padding:1rem;gap:0.25rem;z-index:1000;box-shadow:0 4px 12px rgba(0,0,0,0.08)}}
.hero h1{{font-size:2rem}}
.hero{{padding:4rem 1.25rem}}
.cta-inner{{flex-direction:column;text-align:center}}
.content h1{{font-size:1.75rem}}
}}
</style>
</head>
<body>
<header class="site-header">
<a href="/" class="logo">IT-Hilfe-Sofort.de</a>
<button class="menu-toggle" onclick="document.getElementById('mainNav').classList.toggle('open')">Menü</button>
<nav id="mainNav" style="display:flex;align-items:center;gap:0.25rem">
<a href="/" class="nav-link{" active" if active == "home" else ""}">Startseite</a>
<a href="/blog/telematik-vorschriften" class="nav-link{" active" if active == "blog" else ""}">Blog</a>
<a href="/leistungen/pflegedienste" class="nav-link{" active" if active == "leistungen" else ""}">Leistungen</a>
<a href="/it-service/hardware" class="nav-link{" active" if active == "it-service" else ""}">IT-Service</a>
<a href="/ueber-uns" class="nav-link{" active" if active == "ueber-uns" else ""}">Über uns</a>
<a href="/kontakt" class="btn-primary" style="padding:0.55rem 1.25rem;font-size:0.85rem;margin-left:0.5rem">Kontakt</a>
</nav>
</header>
<main>{content}</main>
{kontakt_banner}
<footer class="site-footer">
<p><strong style="color:#e2e8f0">IT-Hilfe-Sofort.de</strong> — Spezialisiert auf Pflegeeinrichtungen</p>
<p style="margin-top:0.5rem"><a href="/impressum">Impressum</a> · <a href="/datenschutz">Datenschutz</a> · <a href="/faq">FAQ</a></p>
{footer_vermittlung}
</footer>
</body>
</html>"""
@app.route("/")
def index() -> str:
"""Startseite."""
content = """
<section class="hero">
<h1>IT-Hilfe fuer das Gesundheitswesen</h1>
<p>Sicher, schnell, spezialisiert auf Pflegeeinrichtungen — mit persoenlicher Beratung und massgeschneiderten Loesungen.</p>
<a href="/kontakt" class="btn-primary btn-large">Kostenloses Beratungsgespraech</a>
</section>
<section class="section">
<h2>Warum IT-Hilfe-Sofort?</h2>
<p class="section-sub">Wir verstehen die besonderen Anforderungen im Gesundheitswesen und liefern passgenaue IT-Loesungen.</p>
<div class="card-grid">
<div class="card">
<h2>DSGVO-konform</h2>
<p>Patientendaten in absolut sicheren Haenden — mit zertifizierten Prozessen und Hosting in Deutschland.</p>
</div>
<div class="card">
<h2>Schnelle Reaktion</h2>
<p>Garantierte Reaktionszeiten mit persoenlichem Ansprechpartner — weil im Gesundheitswesen jede Minute zaehlt.</p>
</div>
<div class="card">
<h2>Foerderfaehig</h2>
<p>KfW-Antraege stellen wir gemeinsam — digitale Infrastruktur ohne finanzielle Huerden.</p>
</div>
</div>
</section>
<section class="section" style="background:#fff">
<h2>Unsere Leistungen</h2>
<p class="section-sub">Vom Pflegedienst bis zur Tagespflege — wir haben die passende IT-Loesung.</p>
<div class="card-grid">
<div class="card">
<h2>Pflegedienste</h2>
<p>Tourenplanung, mobile Datenerfassung und Abrechnung aus einer Hand.</p>
</div>
<div class="card">
<h2>Pflegeheime</h2>
<p>Heimverwaltung, Biometrie und digitale Dokumentationssysteme.</p>
</div>
<div class="card">
<h2>Tagespflegen</h2>
<p>Terminbuchung, Fahrdienst und Aktivierungsangebote digital organisiert.</p>
</div>
<div class="card">
<h2>Hardware</h2>
<p>Server, Thin Clients und Drucker — Beschaffung, Einrichtung und Wartung.</p>
</div>
<div class="card">
<h2>Netzwerk</h2>
<p>WLAN-Ausleuchtung, VPN, Firewall und Netzwerksegmentierung.</p>
</div>
<div class="card">
<h2>IT-Support</h2>
<p>SLA-Stufen, Fernwartung und 24/7-Monitoring — massgeschneidert.</p>
</div>
</div>
</section>
"""
return _base_template("Startseite", content)
@app.route("/impressum")
def impressum() -> str:
"""Impressum."""
content = '<div class="content"><h1>Impressum</h1><p>Daniel Krause<br>Musterstraße 1<br>12345 Musterstadt</p><p>E-Mail: info@it-hilfe-sofort.de</p></div>'
return _base_template("Impressum", content)
@app.route("/datenschutz")
def datenschutz() -> str:
"""Datenschutzerklaerung."""
content = '<div class="content"><h1>Datenschutzerklaerung</h1><p>Platzhalter — vollstaendige Datenschutzerklaerung folgt.</p></div>'
return _base_template("Datenschutz", content)
# ── Blog-Artikel-Datenbank ───────────────────────────────
_ARTIKEL = [
("/blog/telematik-vorschriften", "TI-Anschlusspflicht 2025", "artikel-01-ti-anschlusspflicht.html"),
("/blog/telematik-vorschriften", "Elektronische Abrechnung ab 12/2026", "artikel-02-elektronische-abrechnung.html"),
("/blog/telematik-vorschriften", "SMC-B-Karte — 33% Abdeckung", "artikel-03-smc-b-karte.html"),
("/blog/dsgvo-it-sicherheit", "46,9 Mio. EUR DSGVO-Bussgelder", "artikel-04-dsgvo-bussgelder.html"),
("/blog/dsgvo-it-sicherheit", "BSI: 16 Schwachstellen Pflegesoftware", "artikel-05-bsi-schwachstellen.html"),
("/blog/dsgvo-it-sicherheit", "138 Sicherheitsvorfaelle Gesundheitswesen", "artikel-06-sicherheitsvorfaelle.html"),
("/blog/telematik-vorschriften", "NIS-2 Registrierungsfrist", "artikel-07-nis2.html"),
("/blog/fachkraeftemangel", "200.000 unbesetzte Pflegestellen", "artikel-08-fachkraeftemangel.html"),
("/blog/fachkraeftemangel", "62% Altenpflege — Personalplanung", "artikel-09-personalplanung.html"),
("/blog/fachkraeftemangel", "KI-Sprachassistent spart 27% Zeit", "artikel-10-ki-sprachassistent.html"),
("/blog/foerderung-finanzierung", "Bis 12.000 EUR Digitalisierungszuschuss", "artikel-11-digitalisierungszuschuss.html"),
("/blog/foerderung-finanzierung", "DiPA — 70 EUR monatlich ab 2026", "artikel-12-dipa.html"),
("/blog/foerderung-finanzierung", "Pflegeversicherung 1 Mrd. Defizit", "artikel-13-pflegeversicherung.html"),
("/blog/qualitaet-pruefung", "QPR ambulant ab Juli 2026", "artikel-14-qpr-ambulant.html"),
("/blog/qualitaet-pruefung", "PeBeM verpflichtend ab 2026", "artikel-15-pebem.html"),
("/blog/qualitaet-pruefung", "MDK-Pruefung digital bestehen", "artikel-16-mdk-pruefung.html"),
("/blog/telematik-vorschriften", "ePA fuer alle — Opt-out", "artikel-17-epa.html"),
("/blog/dsgvo-it-sicherheit", "Cloud-Hosting Deutschland", "artikel-18-cloud-hosting.html"),
("/blog/praxis-tipps", "Tablets fuer die Pflege — Top 5", "artikel-19-tablets.html"),
("/blog/praxis-tipps", "WLAN im Pflegeheim", "artikel-20-wlan.html"),
("/blog/praxis-tipps", "Offline-Dokumentation", "artikel-21-offline.html"),
("/blog/dsgvo-it-sicherheit", "E-Mail-Verschluesselung", "artikel-22-email-verschluesselung.html"),
("/blog/praxis-tipps", "Medikationsplan digital", "artikel-23-medikationsplan.html"),
("/blog/praxis-tipps", "IT-Notfallplan 10-Punkte", "artikel-24-it-notfallplan.html"),
]
# ── Leistungen-Daten ─────────────────────────────────────
_LEISTUNGEN = {
"pflegedienste": {
"titel": "IT-Loesungen fuer ambulante Pflegedienste",
"cards": [
("Tourenplanung", "Digitale Tourenplanung und mobile Datenerfassung vor Ort. Effizientere Routen und Dokumentation auf dem Tablet."),
("Mobile Dokumentation", "Echtzeit-Dokumentation von Pflegemassnahmen direkt im Einsatz. Synchronisiert mit der zentralen Verwaltung."),
("Abrechnung und Reporting", "Automatisierte Abrechnung und Auswertungen. Weniger Verwaltungszeit, mehr Zeit fuer Patienten."),
],
},
"pflegeheime": {
"titel": "IT-Loesungen fuer stationaere Pflegeheime",
"cards": [
("Heimverwaltung", "Digitale Heimpleitung: Dienstplanung, Raummanagement, Budget-Controller. Alles in einer Plattform."),
("Biometrie und Zutrittssysteme", "Fingerabdruck- und Gesichtserkennung fuer sicheren Zutritt. DSGVO-konform und benutzerfreundlich."),
("Dokumentationssysteme", "Komplette digitale Dokumentation von Pflegeplanung bis Medikationsueberwachung. Vollstaendig auditfaehig."),
],
},
"tagespflegen": {
"titel": "IT-Loesungen fuer Tagespflegen",
"cards": [
("Terminbuchung", "Online-Terminbuchung mit Kalendersynchronisation. Patienten koennen Termine direkt vereinbaren."),
("Fahrdienstverwaltung", "Organisation von Fahrdiensten und Kurieren. Automatische Zuweisung und Echtzeit-Tracking."),
("Aktivierungsangebote", "Digitales Planungs- und Monitoring-System fuer Aktivitaeten und Therapie-Programme im Tagesverlauf."),
],
},
}
# ── IT-Service-Daten ─────────────────────────────────────
_IT_SERVICE = {
"hardware": {
"titel": "IT-Hardware fuer das Gesundheitswesen",
"cards": [
("Server und Workstations", "Auswahl, Installation und Wartung von Servern und Workstations. DSGVO-konform und skalierbar."),
("Thin Clients und Endgeraete", "Kosteneffiziente Thin Clients mit zentralem Management. Einfache Administration, hohe Sicherheit."),
("Drucker und Peripherie", "Medizinische Geraete und Drucker mit Spezialtreibern. Integration in bestehende Netzwerke."),
("Beschaffung und Consulting", "Unabhaengige Beratung zur Hardware-Auswahl. Gutes Preis-Leistungs-Verhaeltnis garantiert."),
],
},
"netzwerk": {
"titel": "IT-Netzwerk fuer Pflegeeinrichtungen",
"cards": [
("WLAN-Ausleuchtung", "Professionelle WLAN-Planung und -Implementierung fuer komplette Einrichtungen. Lueckenlose Abdeckung."),
("VPN und Remote-Zugang", "Verschluesselte Verbindung fuer mobiles Arbeiten. Sichere Fernwartung und Fernadministration."),
("Firewall und Segmentierung", "Zwei-Wege-Firewall mit medizinischen Geraete-Portabilitaet. Trennung von Betriebs- und Pflegedaten."),
("Netzwerkmonitoring", "24/7 Ueberwachung aller Netzwerk-Komponenten. Proaktive Stoerungserkennung und automatische Eskalation."),
],
},
"email-kommunikation": {
"titel": "E-Mail und Kommunikation",
"cards": [
("Microsoft 365", "Vollstaendige Implementierung und Verwaltung von Microsoft 365. Cloud-Hosting in Deutschland verfuegbar."),
("Exchange und VoIP", "E-Mail-Server mit Exchange-Integration und VoIP-Telefonie. Nahtlose Kommunikation aller Abteilungen."),
("Spam-Schutz und Archivierung", "Mehrschichtiger Spam-Schutz und automatische Archivierung fuer Compliance und Aufbewahrungspflichten."),
],
},
"support-wartung": {
"titel": "IT-Support und Wartung",
"cards": [
("SLA-Stufen", "Flexible Service-Level-Agreements: von Standard bis Mission-Critical. Garantierte Reaktionszeiten fuer alle Stoerungen."),
("Reaktionszeiten", "Erste Antwort innerhalb von 30 Minuten. Vollstaendige Loesung innerhalb von 4 Stunden bei schwerwiegenden Problemen."),
("Fernwartung und Hosting", "Sichere Fernwartung mit Echtzeit-Desktop-Zugriff. DSGVO-konforme Hostung aller Systeme."),
("Monitoring und Wartung", "Automatisiertes Monitoring aller IT-Komponenten. Regelmaessige Sicherheitsupdates und Wartung in Einweisungszeiten."),
],
},
}
# ── Helper: Seitenleiste ──────────────────────────────────
def _sidebar(routes: list[tuple[str, str, str]]) -> str:
"""Erstelle Seitenleiste mit Artikel-Links.
Args:
routes: Liste von (Route, Titel, Datei)-Tupeln.
"""
links = []
for route, titel, _datei in routes:
links.append('<a href="' + route + '" class="sidebar-link">' + titel + "</a>")
return (
"<div class='article-sidebar'><div class='sidebar-title'>Weitere Artikel</div>"
+ "".join(links)
+ "</div>"
)
# ── Helper: Karten bauen ─────────────────────────────────
def _cards(titel: str, beschreibung: str) -> str:
"""Erstelle eine Service-Karte."""
return '<div class="card"><h3>' + titel + "</h3><p>" + beschreibung + "</p></div>"
# ── Blog-Route (FIX: Nutzt _ARTIKEL-Mapping) ─────────────
@app.route("/blog/<path:slug>")
def blog(slug: str) -> str:
"""Blog-Artikel — nutzt _ARTIKEL-Mapping fuer korrekte Dateinamen."""
route_key = "/blog/" + slug
# Finde ALLE Artikel dieser Sektion
sektions_artikel = [(r, t, d) for r, t, d in _ARTIKEL if r == route_key]
if sektions_artikel:
# Ersten Artikel als Hauptinhalt laden
_, haupt_titel, datei = sektions_artikel[0]
pfad = ARTIKEL_DIR / datei
if pfad.exists():
inhalt = pfad.read_text(encoding="utf-8")
match = re.search(r"<body[^>]*>(.*?)</body>", inhalt, re.DOTALL | re.IGNORECASE)
inhalt = match.group(1) if match else inhalt
else:
inhalt = "<p>Artikeltext folgt in Kuerze.</p>"
else:
inhalt = "<p>Artikel nicht gefunden.</p>"
sektions_artikel = _ARTIKEL
haupt_titel = slug.replace("-", " ").title()
# Seitenleiste: alle Artikel dieser Sektion
sidebar = _sidebar(sektions_artikel)
content = (
"<div class='article-layout'><div class='article-content'><h1>"
+ haupt_titel
+ "</h1>"
+ inhalt
+ "</div>"
+ sidebar
+ "</div>"
)
return _base_template("Blog: " + haupt_titel, content, active="blog")
# ── Weitere Routen ───────────────────────────────────────
@app.route("/ueber-uns")
def ueber_uns() -> str:
"""Ueber uns."""
content = (
'<div class="content">'
"<h1>Ueber uns</h1>"
"<p>Daniel Krause ist IT-Berater im Gesundheitswesen mit langjaehriger Erfahrung in der Digitalisierung von Pflegeeinrichtungen.</p>"
"<h2>Unsere Werte</h2>"
'<div class="card-grid" style="max-width:100%;padding:0">'
'<div class="card"><h3>Transparenz</h3><p>Klare Kommunikation und faire Preise — keine versteckten Kosten.</p></div>'
'<div class="card"><h3>Schnelligkeit</h3><p>Reaktionszeit unter 30 Minuten — weil im Gesundheitswesen Zeit zaehlt.</p></div>'
'<div class="card"><h3>DSGVO-Compliance</h3><p>Hosting in Deutschland, Ende-zu-Ende-Verschluesselung und regelmaessige Audits.</p></div>'
"</div></div>"
)
return _base_template("Ueber uns", content)
@app.route("/kontakt")
def kontakt() -> str:
"""Kontakt mit CRM-Formular."""
content = (
'<div class="content" style="max-width:900px">'
"<h1>Kontakt</h1>"
'<div style="display:grid;gap:2rem">'
'<div class="contact-info">'
"<h3>Wir beraten Sie gerne persoenlich</h3>"
"<p>Sprechen Sie uns an — wir finden die passende IT-Loesung fuer Ihre Einrichtung.</p>"
'<p style="margin-top:1rem"><strong>E-Mail:</strong> info@it-hilfe-sofort.de</p>'
"</div>"
'<div style="border:1px solid #e8ecf1;border-radius:12px;overflow:hidden;box-shadow:0 4px 12px rgba(0,0,0,0.04)">'
'<iframe src="https://crm.companyhub.io/widget/form/iEDHWbU9iII32UkhXj2b" style="width:100%;height:946px;border:none" title="Kontaktformular"></iframe>'
"</div>"
"</div></div>"
)
return _base_template("Kontakt", content)
@app.route("/faq")
def faq() -> str:
"""FAQ."""
fragen: list[tuple[str, str]] = [
("Wie schnell sind Sie vor Ort?", "Innerhalb von 24—48 Stunden."),
("Was kostet der IT-Support?", "Ab 29 EUR/Monat pro Geraet."),
("Uebernehmen Sie die komplette IT?", "Ja, von der Installation bis zum 24/7-Monitoring."),
("Wie stellen Sie DSGVO-Compliance sicher?", "Hosting in Deutschland, Verschluesselung, Zugangskontrollen und regelmaessige Audits."),
("Bieten Sie auch Schulungen an?", "Ja, fuer alle Mitarbeiter Ihrer Einrichtung — vor Ort oder remote."),
("Wie laeuft das Onboarding ab?", "Kostenlose Erstberatung, dann Umsetzung in 2—4 Wochen."),
("Koennen Sie auf bestehende Systeme aufsetzen?", "Ja, wir arbeiten mit allen gaengigen Pflegesoftwaren."),
("Gibt es einen Notfallservice?", "Ja, 24/7 Notfallservice fuer kritische Stoerungen."),
]
fragen_html_parts: list[str] = []
for f, t in fragen:
fragen_html_parts.append(
"<details class='faq-item'><summary>" + f + "</summary><div class='answer'>" + t + "</div></details>"
)
fragen_html = "".join(fragen_html_parts)
content = "<div class='content'><h1>Haeufige Fragen</h1><p style='color:#6b7280;margin-bottom:2rem'>Hier finden Sie Antworten auf die haeufigsten Fragen. Falls Ihre Frage nicht dabei ist — <a href='/kontakt' style='color:#20228a'>kontaktieren Sie uns direkt</a>.</p>" + fragen_html + "</div>"
return _base_template("FAQ", content)
@app.route("/leistungen/<path:slug>")
def leistungen(slug: str) -> str:
"""Leistungs-Seite."""
data = _LEISTUNGEN.get(slug)
if not data:
content = "<div class='content'><h1>Leistung nicht gefunden</h1></div>"
return _base_template("Leistungen", content)
cards_items = [_cards(titel, beschreibung) for titel, beschreibung in data["cards"]]
cards_all = '<div class="card-grid" style="margin-top:2rem">' + "".join(cards_items) + "</div>"
content = "<div class='content'><h1>" + data["titel"] + "</h1><p style='color:#6b7280;margin-bottom:1rem'>Massgeschneiderte IT-Loesungen fuer Ihre Einrichtung.</p>" + cards_all + "</div>"
return _base_template(data["titel"], content, active="leistungen")
@app.route("/it-service/<path:slug>")
def it_service(slug: str) -> str:
"""IT-Service-Seite."""
data = _IT_SERVICE.get(slug)
if not data:
content = "<div class='content'><h1>Service nicht gefunden</h1></div>"
return _base_template("IT-Service", content)
cards_items = [_cards(titel, beschreibung) for titel, beschreibung in data["cards"]]
cards_all = '<div class="card-grid card-grid-4" style="margin-top:2rem">' + "".join(cards_items) + "</div>"
content = "<div class='content' style='max-width:1100px'><h1>" + data["titel"] + "</h1><p style='color:#6b7280;margin-bottom:1rem'>Professionelle IT-Infrastruktur aus einer Hand.</p>" + cards_all + "</div>"
return _base_template(data["titel"], content, active="it-service")
# ── Main ──────────────────────────────────────────────────────────────
if __name__ == "__main__":
print(f"IT-Hilfe-Sofort.de startet auf http://127.0.0.1:{PORT}")
app.run(host="127.0.0.1", port=PORT, debug=False)