Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
53d5309d65 | |||
a131fc8077 | |||
deec62fec0 | |||
9e5906943d | |||
cabe628875 | |||
35ecba348b | |||
31b1c12dcb | |||
95ed606796 | |||
52eac7530a |
24
README.md
24
README.md
@@ -42,7 +42,7 @@ Diese moderne Python-Webanwendung (Flask) ermöglicht verschiedene Datumsberechn
|
|||||||
|
|
||||||
Datumsrechner Live: [https://date.elpatron.me](https://date.elpatron.me)
|
Datumsrechner Live: [https://date.elpatron.me](https://date.elpatron.me)
|
||||||
|
|
||||||

|
[](https://date.elpatron.me)
|
||||||
|
|
||||||
**[Lighthouse](https://en.wikipedia.org/wiki/Lighthouse_(software))-Performance-Score:**
|
**[Lighthouse](https://en.wikipedia.org/wiki/Lighthouse_(software))-Performance-Score:**
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ Die Webanwendung erreicht hervorragende Performance-Werte in allen Kategorien (P
|
|||||||
- Datum plus/minus X Wochen/Monate
|
- Datum plus/minus X Wochen/Monate
|
||||||
- Kalenderwoche zu Datum
|
- Kalenderwoche zu Datum
|
||||||
- Start-/Enddatum einer Kalenderwoche eines Jahres
|
- Start-/Enddatum einer Kalenderwoche eines Jahres
|
||||||
- **Integrierter Taschenrechner** mit History und Sprachausgabe
|
- Integrierter Taschenrechner mit History und Sprachausgabe
|
||||||
- Mehrsprachige Unterstützung (Deutsch/Englisch) mit automatischer Browser-Spracherkennung
|
- Mehrsprachige Unterstützung (Deutsch/Englisch) mit automatischer Browser-Spracherkennung
|
||||||
- Sprachausgabe für alle Ergebnisse (barrierefrei)
|
- Sprachausgabe für alle Ergebnisse (barrierefrei)
|
||||||
- Statistik-Dashboard mit Passwortschutz unter `/stats`
|
- Statistik-Dashboard mit Passwortschutz unter `/stats`
|
||||||
@@ -70,6 +70,7 @@ Die Webanwendung erreicht hervorragende Performance-Werte in allen Kategorien (P
|
|||||||
Die Werktagsberechnung kann optional bundeslandspezifische Feiertage berücksichtigen. Dazu wird die kostenlose API von [feiertage-api.de](https://feiertage-api.de) verwendet.
|
Die Werktagsberechnung kann optional bundeslandspezifische Feiertage berücksichtigen. Dazu wird die kostenlose API von [feiertage-api.de](https://feiertage-api.de) verwendet.
|
||||||
|
|
||||||
**Verfügbare Bundesländer:**
|
**Verfügbare Bundesländer:**
|
||||||
|
|
||||||
- Baden-Württemberg (BW)
|
- Baden-Württemberg (BW)
|
||||||
- Bayern (BY)
|
- Bayern (BY)
|
||||||
- Berlin (BE)
|
- Berlin (BE)
|
||||||
@@ -94,18 +95,21 @@ Die Feiertage werden automatisch für den gewählten Zeitraum abgerufen und bei
|
|||||||
Die Anwendung unterstützt Deutsch und Englisch mit folgenden Features:
|
Die Anwendung unterstützt Deutsch und Englisch mit folgenden Features:
|
||||||
|
|
||||||
### Automatische Spracherkennung:
|
### Automatische Spracherkennung:
|
||||||
|
|
||||||
- *Browser-Sprache*: Automatische Erkennung der Browser-Einstellung
|
- *Browser-Sprache*: Automatische Erkennung der Browser-Einstellung
|
||||||
- *URL-Parameter*: Sprachauswahl über `?lang=de` oder `?lang=en`
|
- *URL-Parameter*: Sprachauswahl über `?lang=de` oder `?lang=en`
|
||||||
- *localStorage*: Persistente Sprachauswahl im Browser
|
- *localStorage*: Persistente Sprachauswahl im Browser
|
||||||
- *Fallback*: Deutsch als Standardsprache
|
- *Fallback*: Deutsch als Standardsprache
|
||||||
|
|
||||||
### *Datenschutzfreundliche Implementierung:*
|
### *Datenschutzfreundliche Implementierung:*
|
||||||
|
|
||||||
- *Keine Cookies*: Sprachauswahl ohne Cookies
|
- *Keine Cookies*: Sprachauswahl ohne Cookies
|
||||||
- *URL-Parameter*: Transparente Sprachauswahl in der URL
|
- *URL-Parameter*: Transparente Sprachauswahl in der URL
|
||||||
- *localStorage*: Lokale Speicherung im Browser
|
- *localStorage*: Lokale Speicherung im Browser
|
||||||
- *Teilbare URLs*: URLs mit Sprachauswahl können geteilt werden
|
- *Teilbare URLs*: URLs mit Sprachauswahl können geteilt werden
|
||||||
|
|
||||||
### *Barrierefreiheit:*
|
### *Barrierefreiheit:*
|
||||||
|
|
||||||
- *Screenreader*: Vollständige Unterstützung
|
- *Screenreader*: Vollständige Unterstützung
|
||||||
- *Tastatur-Navigation*: Vollständig bedienbar
|
- *Tastatur-Navigation*: Vollständig bedienbar
|
||||||
- *ARIA-Attribute*: Korrekte Beschriftungen
|
- *ARIA-Attribute*: Korrekte Beschriftungen
|
||||||
@@ -113,6 +117,7 @@ Die Anwendung unterstützt Deutsch und Englisch mit folgenden Features:
|
|||||||
- *Taschenrechner*: Vollständig barrierefrei mit Tastatur-Bedienung und Sprachausgabe
|
- *Taschenrechner*: Vollständig barrierefrei mit Tastatur-Bedienung und Sprachausgabe
|
||||||
|
|
||||||
### *Technische Details:*
|
### *Technische Details:*
|
||||||
|
|
||||||
- *Flask-Babel*: Professionelle i18n-Implementierung
|
- *Flask-Babel*: Professionelle i18n-Implementierung
|
||||||
- *Gettext*: Standard für Übersetzungen
|
- *Gettext*: Standard für Übersetzungen
|
||||||
- *Responsive Design*: Angepasst für alle Geräte
|
- *Responsive Design*: Angepasst für alle Geräte
|
||||||
@@ -202,8 +207,11 @@ docker-compose up --build
|
|||||||
## REST API
|
## REST API
|
||||||
|
|
||||||
Alle Datumsfunktionen stehen auch als REST-API zur Verfügung. Die API akzeptiert und liefert JSON.
|
Alle Datumsfunktionen stehen auch als REST-API zur Verfügung. Die API akzeptiert und liefert JSON.
|
||||||
|
|
||||||
**Basis-URL:** `http://localhost:5000/api/`
|
**Basis-URL:** `http://localhost:5000/api/`
|
||||||
|
|
||||||
|
**Swagger Dokumentation:** [https://date.elpatron.me/api-docs](https://date.elpatron.me/api-docs)
|
||||||
|
|
||||||
**Hinweis:** Die Nutzung der REST API wird im Statistik-Dashboard ausgewertet und als Diagramm angezeigt.
|
**Hinweis:** Die Nutzung der REST API wird im Statistik-Dashboard ausgewertet und als Diagramm angezeigt.
|
||||||
|
|
||||||
### Endpunkte und Beispiele
|
### Endpunkte und Beispiele
|
||||||
@@ -411,9 +419,7 @@ Die App bietet einen Monitoring-Endpunkt unter `/monitor`, der Statusinformation
|
|||||||
|
|
||||||
Beispiel-Aufruf:
|
Beispiel-Aufruf:
|
||||||
|
|
||||||
```
|
`GET https://date.elpatron.me/monitor`
|
||||||
GET https://date.elpatron.me/monitor
|
|
||||||
```
|
|
||||||
|
|
||||||
Antwort:
|
Antwort:
|
||||||
|
|
||||||
@@ -477,23 +483,23 @@ Damit ist die App für Menschen mit unterschiedlichen Einschränkungen (z.B. Seh
|
|||||||
|
|
||||||
### Code Statistik
|
### Code Statistik
|
||||||
|
|
||||||
cloc|github.com/AlDanial/cloc v 2.06 T=0.22 s (114.3 files/s, 32032.3 lines/s)
|
cloc|github.com/AlDanial/cloc v 2.06 T=0.23 s (109.5 files/s, 30735.0 lines/s)
|
||||||
--- | ---
|
--- | ---
|
||||||
|
|
||||||
Language|files|blank|comment|code
|
Language|files|blank|comment|code
|
||||||
:-------|-------:|-------:|-------:|-------:
|
:-------|-------:|-------:|-------:|-------:
|
||||||
HTML|8|159|8|2800
|
HTML|8|159|8|2805
|
||||||
Python|2|66|74|739
|
Python|2|66|74|739
|
||||||
JavaScript|2|95|88|580
|
JavaScript|2|95|88|580
|
||||||
PO File|2|260|266|544
|
PO File|2|260|266|544
|
||||||
Markdown|3|177|0|497
|
Markdown|3|184|0|498
|
||||||
JSON|3|0|0|243
|
JSON|3|0|0|243
|
||||||
CSS|1|186|3|188
|
CSS|1|186|3|188
|
||||||
SVG|2|0|0|14
|
SVG|2|0|0|14
|
||||||
Dockerfile|1|5|6|8
|
Dockerfile|1|5|6|8
|
||||||
DOS Batch|1|0|0|1
|
DOS Batch|1|0|0|1
|
||||||
--------|--------|--------|--------|--------
|
--------|--------|--------|--------|--------
|
||||||
SUM:|25|948|445|5614
|
SUM:|25|955|445|5620
|
||||||
|
|
||||||
## Lizenz
|
## Lizenz
|
||||||
|
|
||||||
|
27
app.py
27
app.py
@@ -1,5 +1,5 @@
|
|||||||
from flask import Flask, render_template, request, redirect, url_for, session, abort, jsonify, g, make_response
|
from flask import Flask, render_template, request, redirect, url_for, session, jsonify, make_response
|
||||||
from flask_babel import Babel, gettext, ngettext, get_locale
|
from flask_babel import Babel, gettext, get_locale
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from dateutil.relativedelta import relativedelta
|
from dateutil.relativedelta import relativedelta
|
||||||
@@ -20,7 +20,7 @@ app.config['BABEL_TRANSLATION_DIRECTORIES'] = 'translations'
|
|||||||
babel = Babel()
|
babel = Babel()
|
||||||
|
|
||||||
# Version der App
|
# Version der App
|
||||||
APP_VERSION = "1.4.13"
|
APP_VERSION = "1.4.15"
|
||||||
|
|
||||||
def add_cache_headers(response):
|
def add_cache_headers(response):
|
||||||
"""Fügt Cache-Control-Header hinzu, die den Back-Forward-Cache ermöglichen"""
|
"""Fügt Cache-Control-Header hinzu, die den Back-Forward-Cache ermöglichen"""
|
||||||
@@ -118,7 +118,7 @@ def index():
|
|||||||
with open(log_path, 'a', encoding='utf-8') as f:
|
with open(log_path, 'a', encoding='utf-8') as f:
|
||||||
from datetime import datetime as dt
|
from datetime import datetime as dt
|
||||||
f.write(f"{dt.now().isoformat()} PAGEVIEW\n")
|
f.write(f"{dt.now().isoformat()} PAGEVIEW\n")
|
||||||
tage = werktage = wochentag = datumsrechnung = werktagsrechnung = kw_berechnen = kw_datum = wochen_monate = None
|
tage = wochentag = kw_berechnen = kw_datum = None
|
||||||
feiertage_anzahl = wochenendtage_anzahl = None
|
feiertage_anzahl = wochenendtage_anzahl = None
|
||||||
active_idx = 0
|
active_idx = 0
|
||||||
plusminus_result = None
|
plusminus_result = None
|
||||||
@@ -245,7 +245,7 @@ def index():
|
|||||||
plusminus_result = f"Datum {d.strftime('%d.%m.%Y')} {'plus' if anzahl_int>=0 else 'minus'} {abs(anzahl_int)} Monate: {result.strftime('%d.%m.%Y')}"
|
plusminus_result = f"Datum {d.strftime('%d.%m.%Y')} {'plus' if anzahl_int>=0 else 'minus'} {abs(anzahl_int)} Monate: {result.strftime('%d.%m.%Y')}"
|
||||||
except Exception:
|
except Exception:
|
||||||
plusminus_result = gettext('Ungültige Eingabe')
|
plusminus_result = gettext('Ungültige Eingabe')
|
||||||
response = make_response(render_template('index.html', tage=tage, werktage=werktage, wochentag=wochentag, plusminus_result=plusminus_result, kw_berechnen=kw_berechnen, kw_datum=kw_datum, active_idx=active_idx
|
response = make_response(render_template('index.html', tage=tage, wochentag=wochentag, plusminus_result=plusminus_result, kw_berechnen=kw_berechnen, kw_datum=kw_datum, active_idx=active_idx
|
||||||
, feiertage_anzahl=feiertage_anzahl, wochenendtage_anzahl=wochenendtage_anzahl, app_version=APP_VERSION, get_locale=get_locale
|
, feiertage_anzahl=feiertage_anzahl, wochenendtage_anzahl=wochenendtage_anzahl, app_version=APP_VERSION, get_locale=get_locale
|
||||||
))
|
))
|
||||||
return add_cache_headers(response)
|
return add_cache_headers(response)
|
||||||
@@ -321,10 +321,13 @@ def stats():
|
|||||||
session['stats_auth'] = True
|
session['stats_auth'] = True
|
||||||
return redirect(url_for('stats'))
|
return redirect(url_for('stats'))
|
||||||
else:
|
else:
|
||||||
response = make_response(render_template('stats_login.html', error='Falsches Passwort!'))
|
response = make_response(render_template('stats_login.html', error='Falsches Passwort!'))
|
||||||
return add_cache_headers(response)
|
return add_cache_headers(response)
|
||||||
response = make_response(render_template('stats_login.html', error=None))
|
else:
|
||||||
return add_cache_headers(response)
|
response = make_response(render_template('stats_login.html', error=None))
|
||||||
|
return add_cache_headers(response)
|
||||||
|
|
||||||
|
# Wenn authentifiziert, zeige Dashboard
|
||||||
log_path = os.path.join('log', 'pageviews.log')
|
log_path = os.path.join('log', 'pageviews.log')
|
||||||
pageviews, func_counts, func_counts_hourly, impressions_per_day, impressions_per_hour, api_counts, api_counts_hourly = parse_log_stats(log_path)
|
pageviews, func_counts, func_counts_hourly, impressions_per_day, impressions_per_hour, api_counts, api_counts_hourly = parse_log_stats(log_path)
|
||||||
response = make_response(render_template('stats_dashboard.html', pageviews=pageviews, func_counts=func_counts, func_counts_hourly=func_counts_hourly, impressions_per_day=impressions_per_day, impressions_per_hour=impressions_per_hour, api_counts=api_counts, api_counts_hourly=api_counts_hourly))
|
response = make_response(render_template('stats_dashboard.html', pageviews=pageviews, func_counts=func_counts, func_counts_hourly=func_counts_hourly, impressions_per_day=impressions_per_day, impressions_per_hour=impressions_per_hour, api_counts=api_counts, api_counts_hourly=api_counts_hourly))
|
||||||
@@ -500,6 +503,12 @@ def api_docs():
|
|||||||
response = make_response(render_template('swagger.html'))
|
response = make_response(render_template('swagger.html'))
|
||||||
return add_cache_headers(response)
|
return add_cache_headers(response)
|
||||||
|
|
||||||
|
@app.route('/sitemap.xml')
|
||||||
|
def sitemap():
|
||||||
|
"""Serviert die Sitemap für Suchmaschinen"""
|
||||||
|
from flask import send_file
|
||||||
|
return send_file('sitemap.xml', mimetype='application/xml')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app.run(debug=True, host="0.0.0.0")
|
app.run(debug=True, host="0.0.0.0")
|
Binary file not shown.
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 57 KiB |
@@ -1,5 +1,6 @@
|
|||||||
Flask==3.0.0
|
Flask==3.1.1
|
||||||
numpy==1.26.4
|
numpy==2.3.2
|
||||||
python-dateutil==2.9.0.post0
|
python-dateutil==2.9.0.post0
|
||||||
requests==2.31.0
|
requests==2.32.4
|
||||||
Flask-Babel==4.0.0
|
Flask-Babel==4.0.0
|
||||||
|
pytest==8.4.1
|
14
robots.txt
14
robots.txt
@@ -1,2 +1,14 @@
|
|||||||
User-agent: *
|
User-agent: *
|
||||||
Allow: /
|
Allow: /
|
||||||
|
|
||||||
|
# Sitemap
|
||||||
|
Sitemap: https://date.elpatron.me/sitemap.xml
|
||||||
|
|
||||||
|
# Disallow private areas
|
||||||
|
Disallow: /stats
|
||||||
|
Disallow: /log/
|
||||||
|
Disallow: /htmlcov/
|
||||||
|
|
||||||
|
# Allow API endpoints for documentation
|
||||||
|
Allow: /api-docs
|
||||||
|
Allow: /static/swagger.json
|
83
sitemap.xml
Normal file
83
sitemap.xml
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||||
|
<!-- Hauptseite -->
|
||||||
|
<url>
|
||||||
|
<loc>https://date.elpatron.me/</loc>
|
||||||
|
<lastmod>2025-08-03</lastmod>
|
||||||
|
<changefreq>weekly</changefreq>
|
||||||
|
<priority>1.0</priority>
|
||||||
|
</url>
|
||||||
|
|
||||||
|
<!-- API-Dokumentation -->
|
||||||
|
<url>
|
||||||
|
<loc>https://date.elpatron.me/api-docs</loc>
|
||||||
|
<lastmod>2025-08-03</lastmod>
|
||||||
|
<changefreq>monthly</changefreq>
|
||||||
|
<priority>0.8</priority>
|
||||||
|
</url>
|
||||||
|
|
||||||
|
<!-- Statische Ressourcen -->
|
||||||
|
<url>
|
||||||
|
<loc>https://date.elpatron.me/static/favicon.ico</loc>
|
||||||
|
<lastmod>2025-08-03</lastmod>
|
||||||
|
<changefreq>yearly</changefreq>
|
||||||
|
<priority>0.1</priority>
|
||||||
|
</url>
|
||||||
|
|
||||||
|
<url>
|
||||||
|
<loc>https://date.elpatron.me/static/favicon.png</loc>
|
||||||
|
<lastmod>2025-08-03</lastmod>
|
||||||
|
<changefreq>yearly</changefreq>
|
||||||
|
<priority>0.1</priority>
|
||||||
|
</url>
|
||||||
|
|
||||||
|
<url>
|
||||||
|
<loc>https://date.elpatron.me/static/favicon.svg</loc>
|
||||||
|
<lastmod>2025-08-03</lastmod>
|
||||||
|
<changefreq>yearly</changefreq>
|
||||||
|
<priority>0.1</priority>
|
||||||
|
</url>
|
||||||
|
|
||||||
|
<url>
|
||||||
|
<loc>https://date.elpatron.me/static/logo.svg</loc>
|
||||||
|
<lastmod>2025-08-03</lastmod>
|
||||||
|
<changefreq>yearly</changefreq>
|
||||||
|
<priority>0.1</priority>
|
||||||
|
</url>
|
||||||
|
|
||||||
|
<url>
|
||||||
|
<loc>https://date.elpatron.me/static/manifest.json</loc>
|
||||||
|
<lastmod>2025-08-03</lastmod>
|
||||||
|
<changefreq>monthly</changefreq>
|
||||||
|
<priority>0.3</priority>
|
||||||
|
</url>
|
||||||
|
|
||||||
|
<url>
|
||||||
|
<loc>https://date.elpatron.me/static/service-worker.js</loc>
|
||||||
|
<lastmod>2025-08-03</lastmod>
|
||||||
|
<changefreq>monthly</changefreq>
|
||||||
|
<priority>0.3</priority>
|
||||||
|
</url>
|
||||||
|
|
||||||
|
<url>
|
||||||
|
<loc>https://date.elpatron.me/static/swagger.json</loc>
|
||||||
|
<lastmod>2025-08-03</lastmod>
|
||||||
|
<changefreq>monthly</changefreq>
|
||||||
|
<priority>0.5</priority>
|
||||||
|
</url>
|
||||||
|
|
||||||
|
<!-- Sprachversionen der Hauptseite -->
|
||||||
|
<url>
|
||||||
|
<loc>https://date.elpatron.me/?lang=de</loc>
|
||||||
|
<lastmod>2025-08-03</lastmod>
|
||||||
|
<changefreq>weekly</changefreq>
|
||||||
|
<priority>0.9</priority>
|
||||||
|
</url>
|
||||||
|
|
||||||
|
<url>
|
||||||
|
<loc>https://date.elpatron.me/?lang=en</loc>
|
||||||
|
<lastmod>2025-08-03</lastmod>
|
||||||
|
<changefreq>weekly</changefreq>
|
||||||
|
<priority>0.9</priority>
|
||||||
|
</url>
|
||||||
|
</urlset>
|
@@ -107,9 +107,7 @@ body {
|
|||||||
background: var(--primary);
|
background: var(--primary);
|
||||||
color: white;
|
color: white;
|
||||||
border: none;
|
border: none;
|
||||||
padding: 0.8em 1.5em;
|
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
font-size: 1em;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: background-color 0.2s;
|
transition: background-color 0.2s;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
@@ -117,6 +115,9 @@ body {
|
|||||||
max-width: 480px;
|
max-width: 480px;
|
||||||
min-height: 44px;
|
min-height: 44px;
|
||||||
min-width: 44px;
|
min-width: 44px;
|
||||||
|
padding: 1em 1.2em;
|
||||||
|
font-size: 1.1em;
|
||||||
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.calculator-btn:hover {
|
.calculator-btn:hover {
|
||||||
@@ -205,14 +206,15 @@ body {
|
|||||||
|
|
||||||
.calc-btn {
|
.calc-btn {
|
||||||
padding: 0.7em;
|
padding: 0.7em;
|
||||||
font-size: 1em;
|
font-size: 1.1em !important;
|
||||||
|
font-family: 'Segoe UI', Arial, sans-serif !important;
|
||||||
border: 2px solid #374151;
|
border: 2px solid #374151;
|
||||||
background: #f9fafb;
|
background: #f9fafb;
|
||||||
color: #111827;
|
color: #111827;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
font-weight: 600;
|
font-weight: 600 !important;
|
||||||
min-width: 44px;
|
min-width: 44px;
|
||||||
min-height: 44px;
|
min-height: 44px;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -496,9 +498,9 @@ button:focus, .accordion-header:focus {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0.5em;
|
top: 0.5em;
|
||||||
right: 0.5em;
|
right: 0.5em;
|
||||||
background: rgba(37, 99, 235, 0.15);
|
background: #ffffff;
|
||||||
color: var(--primary-dark);
|
color: #000000;
|
||||||
border: 1px solid var(--border);
|
border: 2px solid #000000;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
padding: 0.3em 0.6em;
|
padding: 0.3em 0.6em;
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
@@ -512,19 +514,20 @@ button:focus, .accordion-header:focus {
|
|||||||
z-index: 5;
|
z-index: 5;
|
||||||
}
|
}
|
||||||
.read-aloud-btn:hover {
|
.read-aloud-btn:hover {
|
||||||
background: rgba(37, 99, 235, 0.25);
|
background: #f0f0f0;
|
||||||
border-color: var(--primary);
|
border-color: #333333;
|
||||||
}
|
}
|
||||||
.read-aloud-btn:focus {
|
.read-aloud-btn:focus {
|
||||||
outline: 3px solid #facc15;
|
outline: 3px solid #facc15;
|
||||||
outline-offset: 2px;
|
outline-offset: 2px;
|
||||||
box-shadow: 0 0 0 4px #1e293b;
|
box-shadow: 0 0 0 4px #1e293b;
|
||||||
background: rgba(37, 99, 235, 0.25);
|
background: #f0f0f0;
|
||||||
border-color: var(--primary);
|
border-color: #333333;
|
||||||
}
|
}
|
||||||
.read-aloud-btn.playing {
|
.read-aloud-btn.playing {
|
||||||
background: var(--primary);
|
background: #000000;
|
||||||
color: white;
|
color: #ffffff;
|
||||||
|
border-color: #000000;
|
||||||
}
|
}
|
||||||
.accordion {
|
.accordion {
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
@@ -714,7 +717,10 @@ button:focus, .accordion-header:focus {
|
|||||||
|
|
||||||
.calc-btn {
|
.calc-btn {
|
||||||
padding: 0.6em;
|
padding: 0.6em;
|
||||||
font-size: 1em;
|
font-size: 1.1em;
|
||||||
|
padding: 1em 1.2em;
|
||||||
|
font-weight: 600;
|
||||||
|
/* font-family: 'Segoe UI', Arial, sans-serif; */
|
||||||
min-width: 44px;
|
min-width: 44px;
|
||||||
min-height: 44px;
|
min-height: 44px;
|
||||||
}
|
}
|
||||||
@@ -1494,7 +1500,7 @@ footer br + a {
|
|||||||
{% if request.form.get('werktage') %}
|
{% if request.form.get('werktage') %}
|
||||||
{{ _('Anzahl der Werktage zwischen') }} <b>{{ format_date(request.form.get('start1', '')) }}</b> {{ _('und') }} <b>{{ format_date(request.form.get('end1', '')) }}:</b>{% if request.form.get('bundesland') %} {{ _('(Feiertage:') }} {{ request.form.get('bundesland') }}){% endif %}: {{ tage }}
|
{{ _('Anzahl der Werktage zwischen') }} <b>{{ format_date(request.form.get('start1', '')) }}</b> {{ _('und') }} <b>{{ format_date(request.form.get('end1', '')) }}:</b>{% if request.form.get('bundesland') %} {{ _('(Feiertage:') }} {{ request.form.get('bundesland') }}){% endif %}: {{ tage }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ _('Anzahl der Tage zwischen') }} <b>{{ format_date(request.form.get('start1', '')) }}</b> {{ _('und') }} <b>{{ format_date(request.form.get('end1', '')) }}</b>: {{ tage }}.
|
{{ _('Anzahl der Tage zwischen') }} <b>{{ format_date(request.form.get('start1', '')) }}</b> {{ _('und') }} <b>{{ format_date(request.form.get('end1', '')) }}</b>: {{ tage }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if wochenendtage_anzahl is not none or (feiertage_anzahl is not none and request.form.get('bundesland')) %}
|
{% if wochenendtage_anzahl is not none or (feiertage_anzahl is not none and request.form.get('bundesland')) %}
|
||||||
<br>
|
<br>
|
||||||
|
Reference in New Issue
Block a user