b8831d2573
- .article-content vollstaendig gestylt: h1/h2/h3, p, a, ul/ol/li - Tabellen: Gradient-Header #20228a, Hover-Zeilen, Border-Radius - CTA-Boxen (.cta): Blau-Gradient + Weisser CTA-Button + Shadow - Blockquotes: 4px blauer Left-Border + hellblauer Hintergrund - Stat-Cards: Zentriert, grosse Zahl in BSN-Blau - Meta: Datum + Lesezeit mit blauem Punkt - Listen-Marker in BSN-Blau
501 lines
30 KiB
Python
501 lines
30 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 h1{{font-size:2.2rem;font-weight:800;letter-spacing:-0.02em;line-height:1.25;margin-bottom:0.5rem;color:#1a1a2e}}
|
|
.article-content h2{{font-size:1.45rem;font-weight:700;color:#20228a;margin:2.5rem 0 1rem;padding-bottom:0.5rem;border-bottom:2px solid #e8ecf1}}
|
|
.article-content h3{{font-size:1.15rem;font-weight:700;color:#1a1a2e;margin:1.75rem 0 0.75rem}}
|
|
.article-content p{{margin-bottom:1.25rem;line-height:1.8;color:#374151;font-size:1.02rem}}
|
|
.article-content p:first-of-type{{font-size:1.12rem;color:#1a1a2e;line-height:1.75}}
|
|
.article-content strong{{color:#1a1a2e;font-weight:600}}
|
|
.article-content a{{color:#20228a;text-decoration:underline;text-underline-offset:2px;text-decoration-thickness:1px}}
|
|
.article-content a:hover{{color:#161e6e}}
|
|
.article-content ul,.article-content ol{{margin:1rem 0 1.5rem 1.5rem}}
|
|
.article-content li{{margin-bottom:0.6rem;line-height:1.7;color:#374151;padding-left:0.25rem}}
|
|
.article-content li::marker{{color:#20228a;font-weight:600}}
|
|
.article-content img{{max-width:100%;border-radius:8px;margin:1.5rem 0}}
|
|
.article-content table{{width:100%;border-collapse:collapse;margin:1.5rem 0;font-size:0.95rem;border-radius:8px;overflow:hidden;box-shadow:0 1px 3px rgba(0,0,0,0.06)}}
|
|
.article-content thead{{background:linear-gradient(135deg,#20228a,#2d3496)}}
|
|
.article-content th{{color:#fff;font-weight:600;text-align:left;padding:0.85rem 1rem;font-size:0.9rem}}
|
|
.article-content td{{padding:0.8rem 1rem;border-bottom:1px solid #f0f2f5;background:#fff;color:#374151}}
|
|
.article-content tr:last-child td{{border-bottom:none}}
|
|
.article-content tr:hover td{{background:#f8f9ff}}
|
|
.article-content blockquote{{border-left:4px solid #20228a;background:#f0f2ff;padding:1.25rem 1.5rem;margin:1.5rem 0;border-radius:0 8px 8px 0;color:#374151;font-style:italic;font-size:1rem}}
|
|
.article-content blockquote p{{margin-bottom:0.5rem;color:#374151}}
|
|
.article-content .meta{{color:#6b7280;font-size:0.9rem;margin-bottom:2rem;display:flex;gap:1.5rem;align-items:center}}
|
|
.article-content .meta::before{{content:'';display:inline-block;width:4px;height:4px;background:#20228a;border-radius:50%}}
|
|
.article-content .cta{{background:linear-gradient(135deg,#20228a,#2d3496);color:#fff;padding:2rem;border-radius:12px;margin:2.5rem 0;text-align:center}}
|
|
.article-content .cta p{{color:rgba(255,255,255,0.9);margin-bottom:1rem;font-size:1.05rem}}
|
|
.article-content .cta strong{{color:#fff}}
|
|
.article-content .cta a{{display:inline-block;background:#fff;color:#20228a;padding:0.75rem 2rem;border-radius:8px;font-weight:700;text-decoration:none;font-size:0.95rem;transition:all 0.2s;box-shadow:0 2px 8px rgba(0,0,0,0.15)}}
|
|
.article-content .cta a:hover{{background:#f0f2ff;transform:translateY(-1px);box-shadow:0 4px 16px rgba(0,0,0,0.2)}}
|
|
.article-content .stat-card{{background:#fff;border:1px solid #e8ecf1;border-radius:10px;padding:1.5rem;margin:1.5rem 0;text-align:center;box-shadow:0 2px 8px rgba(0,0,0,0.04)}}
|
|
.article-content .stat-card strong{{display:block;font-size:2rem;font-weight:800;color:#20228a;margin-bottom:0.25rem}}
|
|
.article-content .stat-card p{{color:#6b7280;font-size:0.9rem;margin-bottom: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)
|