feat: Add MicroDAO Dashboard with activity feed and statistics

- Add microdao_activity table for news/updates/events
- Add statistics columns to microdaos table
- Implement dashboard API endpoints
- Create UI components (HeaderCard, ActivitySection, TeamSection)
- Add seed data for DAARION DAO
- Update backend models and repositories
- Add frontend types and API client
This commit is contained in:
Apple
2025-12-02 06:37:16 -08:00
parent 95c9a17a7a
commit ace183e136
15 changed files with 686 additions and 9 deletions

View File

@@ -4792,12 +4792,47 @@ async def trigger_node_self_healing(node_id: str):
async def api_get_microdao_dashboard(slug: str):
"""Отримати повний дашборд для MicroDAO"""
try:
dashboard = await repo_city.get_microdao_dashboard(slug)
dashboard_dict = await repo_city.get_microdao_dashboard(slug)
# Конвертувати dict в Pydantic моделі
# MicrodaoSummary вже правильно сформований
# Stats потрібно конвертувати
stats = dashboard_dict["stats"]
if stats.get("last_update_at"):
try:
if isinstance(stats["last_update_at"], str):
stats["last_update_at"] = datetime.fromisoformat(stats["last_update_at"].replace("Z", "+00:00"))
elif hasattr(stats["last_update_at"], "isoformat"):
pass # Вже datetime
except Exception:
stats["last_update_at"] = None
# Activity потрібно конвертувати
activity_list = []
for act in dashboard_dict["recent_activity"]:
act_dict = dict(act)
if act_dict.get("created_at"):
try:
if isinstance(act_dict["created_at"], str):
act_dict["created_at"] = datetime.fromisoformat(act_dict["created_at"].replace("Z", "+00:00"))
except Exception:
pass
activity_list.append(MicrodaoActivity(**act_dict))
# Створити повний об'єкт
dashboard = MicrodaoDashboard(
microdao=MicrodaoSummary(**dashboard_dict["microdao"]),
stats=MicrodaoStats(**stats),
recent_activity=activity_list,
rooms=[CityRoomSummary(**r) for r in dashboard_dict["rooms"]],
citizens=[PublicCitizenSummary(**c) for c in dashboard_dict["citizens"]]
)
return dashboard
except ValueError as e:
raise HTTPException(status_code=404, detail=str(e))
except Exception as e:
logger.error(f"Failed to get microdao dashboard for {slug}: {e}")
logger.error(f"Failed to get microdao dashboard for {slug}: {e}", exc_info=True)
raise HTTPException(status_code=500, detail="Failed to load dashboard")