feat: add dark mode, navigation, and Web Vitals tracking to marketplace

Backend:
- Simplify DatabaseConfig: remove effective_url property and project root finder
- Update to Pydantic v2 model_config (replace nested Config class)
- Add web_vitals router to main.py and __init__.py
- Fix ExplorerService datetime handling (ensure timezone-naive comparisons)
- Fix status_label extraction to handle both enum and string job states

Frontend (Marketplace):
- Add dark mode toggle with system preference detection
This commit is contained in:
oib
2026-02-15 19:02:51 +01:00
parent 72e21fd07f
commit 7062b2cc78
26 changed files with 1945 additions and 769 deletions

View File

@@ -70,7 +70,8 @@ class ExplorerService:
items: list[TransactionSummary] = []
for index, job in enumerate(jobs):
height = _DEFAULT_HEIGHT_BASE + offset + index
status_label = _STATUS_LABELS.get(job.state, job.state.value.title())
state_val = job.state.value if hasattr(job.state, "value") else job.state
status_label = _STATUS_LABELS.get(job.state) or state_val.title()
# Try to get payment amount from receipt
value_str = "0"
@@ -118,14 +119,26 @@ class ExplorerService:
}
)
def touch(address: Optional[str], tx_id: str, when: datetime, earned: float = 0.0, spent: float = 0.0) -> None:
def _ensure_dt(val: object) -> datetime:
if isinstance(val, datetime):
return val.replace(tzinfo=None)
if isinstance(val, str):
try:
dt = datetime.fromisoformat(val.replace("Z", "+00:00"))
return dt.replace(tzinfo=None)
except ValueError:
return datetime.min
return datetime.min
def touch(address: Optional[str], tx_id: str, when: object, earned: float = 0.0, spent: float = 0.0) -> None:
if not address:
return
entry = address_map[address]
entry["address"] = address
entry["tx_count"] = int(entry["tx_count"]) + 1
if when > entry["last_active"]:
entry["last_active"] = when
when_dt = _ensure_dt(when)
if when_dt > _ensure_dt(entry["last_active"]):
entry["last_active"] = when_dt
# Track earnings and spending
entry["earned"] = float(entry["earned"]) + earned
entry["spent"] = float(entry["spent"]) + spent