diff --git a/web/public/config.json b/web/public/config.json index 7203327..40c96ca 100644 --- a/web/public/config.json +++ b/web/public/config.json @@ -1,4 +1,5 @@ { + "hide_miners": true, "miner_names": { "020100008c675349": "Miner 3", "020100001a0f0bc8": "Miner 1", diff --git a/web/src/App.tsx b/web/src/App.tsx index 56ba0f0..0e9d4f1 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -136,33 +136,7 @@ function App() {
-
-

Scheduler Status

-
- - - - -
-
+ {currentPrice !== undefined && priceLimit !== undefined && (
@@ -180,6 +154,7 @@ function App() {
)} + {!config.hide_miners && (

Discovered Miners @@ -257,6 +232,7 @@ function App() {

No miners discovered yet.

)}

+ )}

Devices

@@ -360,7 +336,38 @@ function App() { - +
+

Scheduler Status

+
+ + + {!config.hide_miners && ( + + )} + +
+

System Information

@@ -390,7 +397,12 @@ function App() { setShowDemoInfo(false)} /> )} - {showConfig && setShowConfig(false)} />} + {showConfig && ( + setShowConfig(false)} + hideMiners={config.hide_miners} + /> + )} {showMarketDataUpload && ( setShowMarketDataUpload(false)} /> diff --git a/web/src/components/ConfigMenu.tsx b/web/src/components/ConfigMenu.tsx index bdd2888..45cc93b 100644 --- a/web/src/components/ConfigMenu.tsx +++ b/web/src/components/ConfigMenu.tsx @@ -5,6 +5,8 @@ import "./ConfigMenu.css"; interface ConfigMenuProps { onClose: () => void; + /** Hide miner-related sections and fields. */ + hideMiners?: boolean; } type FieldType = "text" | "number" | "boolean" | "select" | "duration" | "numericSelect"; @@ -618,7 +620,25 @@ function ConfigField({ def, value, onChange }: FieldProps) { // ─── Main component ───────────────────────────────────────────────────────── -export function ConfigMenu({ onClose }: ConfigMenuProps) { +const MINER_SECTION_TITLES = new Set(["Miner Power Modes"]); +const MINER_FIELD_KEYS = new Set([ + "miners_state_check_interval", + "miner_discovery_interval", + "miner_max_consecutive_errors", + "miner_timeout", +]); + +const MINERLESS_SECTIONS: Section[] = SECTIONS.filter( + (s) => !MINER_SECTION_TITLES.has(s.title), +) + .map((s) => ({ + ...s, + fields: s.fields.filter((f) => !MINER_FIELD_KEYS.has(f.key)), + })) + .filter((s) => s.fields.length > 0); + +export function ConfigMenu({ onClose, hideMiners = false }: ConfigMenuProps) { + const sections = hideMiners ? MINERLESS_SECTIONS : SECTIONS; const { config, loading, @@ -680,7 +700,7 @@ export function ConfigMenu({ onClose }: ConfigMenuProps) { }, [onClose]); const currentSection = - SECTIONS.find((s) => s.title === activeSection) ?? SECTIONS[0]; + sections.find((s) => s.title === activeSection) ?? sections[0]; return (
{/* Sidebar navigation */}
-
+
{loading && (
Loading... @@ -222,36 +302,26 @@ export function MetricsSummary() {
)} {metricsSummary && !loading && ( - <> -
- Import Cost: - - €{metricsSummary.total_import_cost.toFixed(2)} ( - {metricsSummary.total_import_kwh.toFixed(2)} kWh) - -
-
- Export Revenue: - - €{metricsSummary.total_export_cost.toFixed(2)} ( - {metricsSummary.total_export_kwh.toFixed(2)} kWh) - +
+

Day

+
+
-
- - {netActualCost !== null && netActualCost <= 0 - ? "Net Revenue:" - : "Net Cost:"} - - - {netActualCost !== null - ? `€${Math.abs(netActualCost).toFixed(2)}` - : "N/A"} - +
+ )} + {monthlySummary && !loading && ( +
+

+ Month -{" "} + {selectedDate.toLocaleDateString("en-US", { + year: "numeric", + month: "long", + })} +

+
+
- +
)}
diff --git a/web/src/hooks/useConfig.ts b/web/src/hooks/useConfig.ts index 1785762..b3490a7 100644 --- a/web/src/hooks/useConfig.ts +++ b/web/src/hooks/useConfig.ts @@ -2,10 +2,13 @@ import { useState, useEffect } from "react"; export interface AppConfig { miner_names: Record; + /** Hide all miner-related UI elements. Enabled by default. */ + hide_miners: boolean; } const defaultConfig: AppConfig = { miner_names: {}, + hide_miners: true, }; let cachedConfig: AppConfig | null = null; @@ -24,9 +27,10 @@ export function useConfig(): AppConfig { if (!res.ok) throw new Error(`Failed to load config: ${res.status}`); return res.json(); }) - .then((data: AppConfig) => { - cachedConfig = data; - setConfig(data); + .then((data: Partial) => { + const merged: AppConfig = { ...defaultConfig, ...data }; + cachedConfig = merged; + setConfig(merged); }) .catch((err) => { console.warn("Could not load config.json, using defaults:", err);