From 327f40adec928f620f53e63110f303f495166043 Mon Sep 17 00:00:00 2001 From: Lars Gebhardt-Kusche Date: Thu, 23 Apr 2026 00:01:20 +0200 Subject: [PATCH] Boersenchecker UI --- .../boersenchecker/assets/boersenchecker.css | 350 +++++++++++++---- modules/boersenchecker/partials/dashboard.php | 106 ++--- modules/boersenchecker/partials/home.php | 364 ++++++++++-------- 3 files changed, 526 insertions(+), 294 deletions(-) diff --git a/modules/boersenchecker/assets/boersenchecker.css b/modules/boersenchecker/assets/boersenchecker.css index 520442e..ef6996b 100644 --- a/modules/boersenchecker/assets/boersenchecker.css +++ b/modules/boersenchecker/assets/boersenchecker.css @@ -1,51 +1,215 @@ -.bc-module-nav { - display: flex; - gap: 10px; - flex-wrap: wrap; - margin: 1rem 0 1.15rem; +.bc-app { + --bc-accent: #5eead4; + --bc-accent-strong: #79d7ff; + --bc-ink: #09111f; + --bc-text: rgba(236, 245, 255, 0.96); + --bc-muted: rgba(203, 218, 234, 0.78); + --bc-line: rgba(148, 163, 184, 0.22); + --bc-panel: rgba(15, 23, 42, 0.68); + --bc-panel-soft: rgba(15, 23, 42, 0.52); + --bc-positive: #86efac; + --bc-negative: #fca5a5; + color: var(--bc-text); } -.bc-module-tab { - display: inline-flex; - align-items: center; - justify-content: center; - min-height: 46px; - padding: 12px 18px; - border-radius: 16px; - text-decoration: none; - color: #09111f; - border: 1px solid rgba(255,255,255,0.16); - background: rgba(255,255,255,0.9); - font-weight: 700; - box-shadow: 0 10px 22px rgba(0,0,0,0.10); - transition: transform .18s ease, background .18s ease, border-color .18s ease, box-shadow .18s ease; +.bc-grid-bg { + position: relative; + padding: 8px 0 32px; } -.bc-module-tab:hover, -.bc-module-tab:focus-visible, -.bc-module-tab.is-active { - transform: translateY(-1px); - box-shadow: 0 14px 28px rgba(0,0,0,0.14); +.bc-grid-bg::before { + content: ""; + position: absolute; + inset: 0; + pointer-events: none; + background: + radial-gradient(circle at top right, rgba(94, 234, 212, 0.16), transparent 28%), + radial-gradient(circle at bottom left, rgba(121, 215, 255, 0.14), transparent 30%), + linear-gradient(180deg, rgba(255,255,255,0.02), rgba(255,255,255,0)); } -.bc-module-tab.is-active { - background: linear-gradient(135deg, #79d7ff, #5eead4); - border-color: rgba(94, 234, 212, 0.35); +.bc-shell { + position: relative; + display: grid; + gap: 18px; } -.bc-module-tab:hover, -.bc-module-tab:focus-visible { - background: #ffffff; +.bc-stack { + display: grid; + gap: 18px; } .bc-hero { + display: grid; + gap: 18px; + padding: 28px; + border-radius: 28px; background: - radial-gradient(circle at top right, rgba(71, 169, 255, 0.22), transparent 32%), - radial-gradient(circle at bottom left, rgba(81, 214, 141, 0.18), transparent 28%), - linear-gradient(145deg, rgba(255,255,255,0.04), rgba(255,255,255,0.01)); + radial-gradient(circle at top right, rgba(94, 234, 212, 0.18), transparent 28%), + radial-gradient(circle at bottom left, rgba(121, 215, 255, 0.14), transparent 32%), + linear-gradient(145deg, rgba(15, 23, 42, 0.9), rgba(15, 23, 42, 0.78)); + border: 1px solid var(--bc-line); + box-shadow: 0 18px 40px rgba(2, 6, 23, 0.22); +} + +.bc-hero-top { + display: grid; + gap: 16px; + grid-template-columns: minmax(0, 1.6fr) minmax(240px, 0.7fr); + align-items: start; +} + +.bc-hero-copy { + display: grid; + gap: 10px; +} + +.bc-eyebrow { + display: inline-flex; + align-items: center; + width: fit-content; + padding: 8px 12px; + border-radius: 999px; + background: color-mix(in srgb, var(--bc-accent) 18%, transparent); + border: 1px solid color-mix(in srgb, var(--bc-accent) 28%, transparent); + color: var(--bc-text); + font-size: 0.86rem; + font-weight: 700; +} + +.bc-title { + margin: 0; + font-size: clamp(2rem, 3vw, 2.8rem); + line-height: 1.05; +} + +.bc-text { + color: var(--bc-muted); + margin: 0; +} + +.bc-hero-controls { + display: grid; + gap: 12px; + justify-items: stretch; +} + +.bc-form-card, +.bc-panel, +.bc-stat, +.bc-chart-card, +.bc-position-row { + border: 1px solid var(--bc-line); + border-radius: 22px; + background: var(--bc-panel); + box-shadow: inset 0 1px 0 rgba(255,255,255,0.03); +} + +.bc-form-card, +.bc-panel, +.bc-chart-card { + padding: 18px; +} + +.bc-stat { + padding: 16px; +} + +.bc-field-label { + font-size: 0.85rem; + text-transform: uppercase; + letter-spacing: 0.08em; + color: var(--bc-muted); +} + +.bc-tabs { + display: flex; + flex-wrap: wrap; + gap: 10px; +} + +.bc-button, +.bc-tabs a, +.bc-app button, +.bc-app input, +.bc-app select, +.bc-app textarea { + font: inherit; +} + +.bc-button { + display: inline-flex; + align-items: center; + justify-content: center; + border: 1px solid transparent; + border-radius: 16px; + padding: 12px 16px; + cursor: pointer; + text-decoration: none; + transition: 160ms ease; +} + +.bc-button:hover { + transform: translateY(-1px); +} + +.bc-button--tab { + background: rgba(255, 255, 255, 0.92); + color: var(--bc-ink); + font-weight: 700; +} + +.bc-button--tab-active { + background: linear-gradient(135deg, var(--bc-accent-strong), var(--bc-accent)); + color: var(--bc-ink); + font-weight: 700; +} + +.bc-button--primary { + background: linear-gradient(135deg, var(--bc-accent), var(--bc-accent-strong)); + color: var(--bc-ink); + font-weight: 700; +} + +.bc-button--secondary { + background: rgba(255, 255, 255, 0.92); + color: var(--bc-ink); + font-weight: 700; +} + +.bc-button--ghost { + background: color-mix(in srgb, var(--bc-accent) 14%, transparent); + border-color: color-mix(in srgb, var(--bc-accent) 34%, transparent); + color: var(--bc-accent-strong); + font-weight: 700; +} + +.bc-actions { + display: flex; + gap: 10px; + flex-wrap: wrap; +} + +.bc-alert { + padding: 16px 18px; + border-radius: 20px; + border: 1px solid transparent; +} + +.bc-alert--error { + background: rgba(127, 29, 29, 0.28); + border-color: rgba(252, 165, 165, 0.24); + color: #fecaca; +} + +.bc-alert--success { + background: rgba(6, 78, 59, 0.28); + border-color: rgba(134, 239, 172, 0.24); + color: #bbf7d0; } .bc-toolbar, +.bc-overview-grid, .bc-card-grid { display: grid; gap: 14px; @@ -55,37 +219,20 @@ grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); } -.bc-card-grid { +.bc-overview-grid { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); } -.bc-overview-grid { - display: grid; - gap: 14px; - grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); -} - -.bc-stat { - padding: 16px; - border-radius: 18px; - background: linear-gradient(180deg, rgba(255,255,255,0.06), rgba(255,255,255,0.02)); - border: 1px solid rgba(255,255,255,0.08); - box-shadow: inset 0 1px 0 rgba(255,255,255,0.04); +.bc-card-grid { + grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); } .bc-stat-value { - margin-top: 6px; - font-size: 1.35rem; + margin-top: 8px; + font-size: 1.42rem; font-weight: 700; } -.bc-surface { - padding: 18px; - border-radius: 22px; - background: linear-gradient(180deg, rgba(255,255,255,0.05), rgba(255,255,255,0.02)); - border: 1px solid rgba(255,255,255,0.08); -} - .bc-chart-shell { position: relative; min-height: 360px; @@ -100,11 +247,11 @@ .bc-chart-path { fill: none; - stroke: #5eead4; + stroke: var(--bc-accent); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; - filter: drop-shadow(0 12px 24px rgba(94, 234, 212, 0.25)); + filter: drop-shadow(0 12px 24px rgba(94, 234, 212, 0.22)); } .bc-chart-area { @@ -116,17 +263,16 @@ stroke-dasharray: 4 6; } -.bc-range-list, -.bc-inline-actions { +.bc-range-list { display: flex; gap: 10px; flex-wrap: wrap; } .bc-range-button { - border: 1px solid rgba(255,255,255,0.12); - background: rgba(255,255,255,0.04); - color: var(--text); + border: 1px solid color-mix(in srgb, var(--bc-accent) 26%, transparent); + background: color-mix(in srgb, var(--bc-accent) 8%, transparent); + color: var(--bc-text); padding: 8px 12px; border-radius: 999px; cursor: pointer; @@ -136,8 +282,8 @@ .bc-range-button:hover, .bc-range-button[aria-pressed="true"] { transform: translateY(-1px); - background: rgba(94, 234, 212, 0.12); - border-color: rgba(94, 234, 212, 0.45); + background: color-mix(in srgb, var(--bc-accent) 18%, transparent); + border-color: color-mix(in srgb, var(--bc-accent) 42%, transparent); } .bc-panel-fade { @@ -151,18 +297,15 @@ .bc-position-list { display: grid; - gap: 12px; + gap: 14px; } .bc-position-row { display: grid; - grid-template-columns: minmax(0, 1.8fr) repeat(4, minmax(100px, .75fr)); - gap: 12px; + grid-template-columns: minmax(0, 1.8fr) repeat(4, minmax(96px, .72fr)); + gap: 14px; align-items: center; - padding: 14px 16px; - border-radius: 16px; - background: rgba(255,255,255,0.03); - border: 1px solid rgba(255,255,255,0.06); + padding: 16px 18px; } .bc-performance { @@ -170,24 +313,81 @@ } .bc-performance.is-positive { - color: #84f2b7; + color: var(--bc-positive); } .bc-performance.is-negative { - color: #ff9b8d; + color: var(--bc-negative); } .bc-pill-soft { display: inline-flex; align-items: center; + width: fit-content; padding: 6px 10px; border-radius: 999px; background: rgba(255,255,255,0.06); - color: var(--muted); + color: var(--bc-muted); font-size: .85rem; } -@media (max-width: 900px) { +.bc-table-shell { + overflow: auto; + border-radius: 18px; + border: 1px solid var(--bc-line); +} + +.bc-table { + width: 100%; + border-collapse: collapse; +} + +.bc-table th, +.bc-table td { + padding: 10px 12px; + text-align: left; + border-bottom: 1px solid rgba(255,255,255,0.06); + vertical-align: top; +} + +.bc-table thead { + background: rgba(255,255,255,0.04); +} + +.bc-app .setup-field { + display: grid; + gap: 6px; +} + +.bc-app input, +.bc-app select, +.bc-app textarea { + width: 100%; + border: 1px solid var(--bc-line); + border-radius: 14px; + padding: 10px 12px; + background: rgba(2, 6, 23, 0.42); + color: var(--bc-text); +} + +.bc-app input::placeholder, +.bc-app textarea::placeholder { + color: rgba(203, 218, 234, 0.48); +} + +.bc-app a { + color: inherit; +} + +.bc-app .muted { + color: var(--bc-muted); +} + +@media (max-width: 980px) { + .bc-hero-top { + grid-template-columns: 1fr; + } + .bc-position-row { grid-template-columns: 1fr; } diff --git a/modules/boersenchecker/partials/dashboard.php b/modules/boersenchecker/partials/dashboard.php index c69225f..688e8bd 100644 --- a/modules/boersenchecker/partials/dashboard.php +++ b/modules/boersenchecker/partials/dashboard.php @@ -1,29 +1,35 @@ -
- -
Boersenchecker
-

Depotverwaltung

-

- Depots, Positionen und manuelle Kursverlaeufe. Die Waehrungsumrechnung nutzt, sofern verfuegbar, - die bestehende FX-Logik des Mining-Checkers weiter. -

+
+
+
+
+
+
+
Boersenchecker Modul
+

Depotverwaltung

+

Depots, Positionen und Kurs-Historien verwalten. Die Waehrungsumrechnung nutzt weiterhin die bestehende FX-Logik des Mining-Checkers.

+
+ +
- -
- -
- -
- -
- + +
- -
+ +
+ +
+ + + +
Benutzer-Scope
- +
-
- +
+ -
-
+
+
@@ -61,15 +67,15 @@
- + - Abbrechen + Abbrechen
-
+
API / FX

Die Umrechnung liest gespeicherte FX-Daten aus dem Mining-Checker. Eine Aktualisierung wird nur manuell @@ -82,12 +88,12 @@

- +
- +
@@ -102,7 +108,7 @@
-
+
Bitte zuerst ein Depot anlegen.
@@ -176,16 +182,16 @@
- + - Abbrechen + Abbrechen
-
+
API-Symbol suchen

Suche nach Firma oder Ticker ueber den Alpha-Vantage-`SYMBOL_SEARCH`-Endpoint und uebernimm einen Treffer direkt ins Positionsformular. @@ -197,12 +203,12 @@ Suchbegriff - + -

- +
+
@@ -224,7 +230,7 @@ @@ -236,7 +242,7 @@ -
+
Manuellen Kurs erfassen
Sobald Positionen vorhanden sind, koennen hier Kurse mit Uhrzeit gespeichert werden.
@@ -274,7 +280,7 @@
- +
@@ -416,14 +422,14 @@
-
+
Kursverlauf
Noch keine Kursdaten vorhanden.
$instrument): ?> -
+
@@ -431,13 +437,13 @@ ·
- Neuen Kurs erfassen + Neuen Kurs erfassen
Noch keine historischen Kurse vorhanden.
-
-
Symbol - + In Formular uebernehmen
+
+
@@ -457,7 +463,7 @@ - + @@ -470,4 +476,6 @@ + + diff --git a/modules/boersenchecker/partials/home.php b/modules/boersenchecker/partials/home.php index 85b9d66..e2597d2 100644 --- a/modules/boersenchecker/partials/home.php +++ b/modules/boersenchecker/partials/home.php @@ -1,185 +1,209 @@ -
- - -
Boersenchecker
-

Ueberblick

-

Depotauswahl, Aktienauswahl und animierte Kurscharts auf Basis von Schlusskursen.

+
+
+
+ - -
- -
- +
+
+
+
Boersenchecker Modul
+

Depot-Ueberblick

+

Depots, Aktien und Kursverlaeufe in einer Oberflaeche. Die Navigation folgt jetzt dem gleichen sichtbaren Prinzip wie beim Mining-Checker.

+
+
+ Zur Startseite +
+
Aktives Depot
+
0 && $portfolios !== [] ? e((string) (($portfolios[array_search($selectedPortfolioId, array_column($portfolios, 'id'), true)]['name'] ?? 'Auswahl aktiv'))) : 'Kein Depot ausgewaehlt' ?>
+
+
+
-
-
- Depot - -
Keine Depots vorhanden.
- - + +
+ + +
+ +
- -
- - Aktie - -
Keine Aktien im ausgewaehlten Depot.
- - - - +
+
+
Depotauswahl
+ +
Keine Depots vorhanden.
+ + + + -
- - - Aktuelle Kurse -

Abruf der aktuellen Kurse fuer das gewaehlte Depot.

- - -
+
+ +
Aktienauswahl
+ +
Keine Aktien im ausgewaehlten Depot.
+ + + + -
-
-
Positionen
-
-
Aktien im aktuell gewaehlten Depot
-
-
-
Investiert
-
-
Auf Berichtswahrung umgerechnet
-
-
-
Aktueller Wert
-
-
Basierend auf letztem verfuegbarem Kurs
-
-
-
Performance
-
-
-
-
- -
-
-
Bester Wert
- -
-
%
- -
Noch keine Performance verfuegbar.
- -
-
-
Schwaechster Wert
- -
-
%
- -
Noch keine Performance verfuegbar.
- -
- -
-
-
-
+
+ + +
Marktdaten
+

Aktuelle Kurse fuer das gewaehlte Depot ueber Alpha Vantage abrufen.

+
+ +
+
- -
-
-
-
- - -
·
- +
+
+
Positionen
+
+
Aktien im aktuell gewaehlten Depot
+
+
+
Investiert
+
+
In Berichtswahrung bewertet
+
+
+
Aktueller Wert
+
+
Basierend auf dem letzten gespeicherten Kurs
+
+
+
Performance
+
+
+
-
- - - - - - - -
-
-
Chartdaten werden geladen...
-
-
-
-
-
- Aktien im Depot - -
Keine Aktien im ausgewaehlten Depot.
- -
- - = 0) ? 'is-positive' : 'is-negative'; ?> -
-
- -
·
- -
- -
-
-
Stueckzahl
-
-
-
-
Kaufpreis
-
-
-
-
Letzter Kurs
-
-
-
-
Performance
-
- -
-
+
+
+
Bester Wert
+ +
+
%
+ +
Noch keine Performance verfuegbar.
+ +
+ +
+
Schwaechster Wert
+ +
+
%
+ +
Noch keine Performance verfuegbar.
+ +
+ + +
+
+
+
- + +
+
+
+
Kursverlauf
+
+ +
·
+ +
+
+ + + + + + + +
+
+
Chartdaten werden geladen...
+
-
+
+
+ +
+
Aktien im Depot
+ +
Keine Aktien im ausgewaehlten Depot.
+ +
+ + = 0) ? 'is-positive' : 'is-negative'; ?> +
+
+ +
·
+ +
+ +
+
+
Stueckzahl
+
+
+
+
Kaufpreis
+
+
+
+
Letzter Kurs
+
+
+
+
Performance
+
+ +
+
+
+ +
+ +
+
Zeitpunkt