Navigations-Pfeile an allen Datumseingaben
Links/Rechts-Pfeile (zurueck/vorwaerts) neben jeder Datumsauswahl fuer schnelle Navigation. Schrittweite je nach Auswahl: Tag (24h, 7d), Monat (31d), Jahr (365d). Nach dem Klick wird direkt neu geladen. - Vorwaerts-Pfeil wird deaktiviert, sobald der aktuelle Zeitraum erreicht ist (keine Navigation in die Zukunft) - bei leerem 24h-Feld (rollierend) wird ab heute gerechnet Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -22,6 +22,22 @@ function thisMonthStr(): string {
|
|||||||
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`;
|
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function fmtDate(d: Date): string {
|
||||||
|
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addDays(dateStr: string, delta: number): string {
|
||||||
|
const d = dateStr ? new Date(`${dateStr}T00:00:00`) : new Date();
|
||||||
|
d.setDate(d.getDate() + delta);
|
||||||
|
return fmtDate(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addMonths(monthStr: string, delta: number): string {
|
||||||
|
const [y, m] = (monthStr || thisMonthStr()).split('-').map(Number);
|
||||||
|
const d = new Date(y, m - 1 + delta, 1);
|
||||||
|
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`;
|
||||||
|
}
|
||||||
|
|
||||||
const CURRENT_YEAR = new Date().getFullYear();
|
const CURRENT_YEAR = new Date().getFullYear();
|
||||||
const YEARS = Array.from({ length: 11 }, (_, i) => CURRENT_YEAR - i);
|
const YEARS = Array.from({ length: 11 }, (_, i) => CURRENT_YEAR - i);
|
||||||
|
|
||||||
@@ -118,6 +134,25 @@ function ChartCard({ range, every, title, color, selector }: ChartCardProps) {
|
|||||||
fetchLaden(value);
|
fetchLaden(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Navigation per Pfeil: einen Tag/Monat/Jahr zurueck (-1) oder vor (+1)
|
||||||
|
const step = (delta: number) => {
|
||||||
|
let nv: string;
|
||||||
|
if (selector === 'month') nv = addMonths(value, delta);
|
||||||
|
else if (selector === 'year') nv = String(Number(value || CURRENT_YEAR) + delta);
|
||||||
|
else nv = addDays(value, delta); // date24 + date
|
||||||
|
setValue(nv);
|
||||||
|
fetchData(nv);
|
||||||
|
fetchLaden(nv);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Vorwaerts nicht in die Zukunft
|
||||||
|
const canForward =
|
||||||
|
selector === 'month'
|
||||||
|
? (value || thisMonthStr()) < thisMonthStr()
|
||||||
|
: selector === 'year'
|
||||||
|
? Number(value || CURRENT_YEAR) < CURRENT_YEAR
|
||||||
|
: (value || todayStr()) < todayStr();
|
||||||
|
|
||||||
// Jahres-Chart: Achse immer ueber das komplette Kalenderjahr -> alle 12 Monate
|
// Jahres-Chart: Achse immer ueber das komplette Kalenderjahr -> alle 12 Monate
|
||||||
// sichtbar, Restmonate bleiben ohne Balken.
|
// sichtbar, Restmonate bleiben ohne Balken.
|
||||||
let xMin: number | undefined;
|
let xMin: number | undefined;
|
||||||
@@ -147,6 +182,17 @@ function ChartCard({ range, every, title, color, selector }: ChartCardProps) {
|
|||||||
{selector === 'year' && 'Jahr:'}
|
{selector === 'year' && 'Jahr:'}
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
{/* Pfeil zurueck */}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => step(-1)}
|
||||||
|
aria-label="zurück"
|
||||||
|
title="zurück"
|
||||||
|
className="bg-[#85B7D7] hover:bg-[#6a9fc5] px-2.5 py-1.5 text-sm rounded shadow-sm transition-colors"
|
||||||
|
>
|
||||||
|
◀
|
||||||
|
</button>
|
||||||
|
|
||||||
{selector === 'year' ? (
|
{selector === 'year' ? (
|
||||||
<select
|
<select
|
||||||
value={value}
|
value={value}
|
||||||
@@ -167,6 +213,18 @@ function ChartCard({ range, every, title, color, selector }: ChartCardProps) {
|
|||||||
className="border border-gray-400 rounded px-3 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-gray-500"
|
className="border border-gray-400 rounded px-3 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-gray-500"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Pfeil vorwaerts (nicht in die Zukunft) */}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => step(1)}
|
||||||
|
disabled={!canForward}
|
||||||
|
aria-label="vorwärts"
|
||||||
|
title="vorwärts"
|
||||||
|
className="bg-[#85B7D7] hover:bg-[#6a9fc5] px-2.5 py-1.5 text-sm rounded shadow-sm transition-colors disabled:opacity-40 disabled:cursor-not-allowed"
|
||||||
|
>
|
||||||
|
▶
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
|||||||
Reference in New Issue
Block a user