module Web.Controller.MarketplaceDashboard where import Web.Types import Web.View.MarketplaceDashboard.Show import Generated.Types import IHP.Prelude import IHP.ControllerPrelude instance Controller MarketplaceDashboardController where beforeAction = ensureIsUser action MarketplaceDashboardAction = autoRefresh do let mSearch = paramOrNothing @Text "q" let mWType = paramOrNothing @Text "widgetType" let sortBy = paramOrDefault @Text "adopted" "sort" -- Widget patterns: fetch then count adoptions basePatterns <- query @WidgetPattern |> filterWhere (#isPublished, True) |> orderByAsc #name |> limit 50 |> fetch patterns <- mapM (\p -> do cnt <- sqlQueryScalar "SELECT COUNT(*) FROM pattern_adoptions WHERE widget_pattern_id = ?" (Only p.id) pure (p, fromMaybe 0 cnt)) basePatterns -- Governance templates: fetch then count clones baseTemplates <- query @GovernanceTemplate |> filterWhere (#isPublished, True) |> limit 50 |> fetch templates <- mapM (\t -> do cnt <- sqlQueryScalar "SELECT COUNT(*) FROM governance_template_clones WHERE governance_template_id = ?" (Only t.id) pure (t, fromMaybe 0 cnt)) baseTemplates -- Trending patterns (most adoptions in last 30 days) trendingRaw :: [(Id WidgetPattern, Text, Text, Int)] <- sqlQuery "SELECT wp.id, wp.name, wp.widget_type, CAST(COUNT(pa.id) AS integer) AS recent_adoptions \ \ FROM widget_patterns wp \ \ JOIN pattern_adoptions pa ON pa.widget_pattern_id = wp.id \ \ WHERE wp.is_published = TRUE \ \ AND pa.adopted_at >= NOW() - INTERVAL '30 days' \ \ GROUP BY wp.id, wp.name, wp.widget_type \ \ ORDER BY recent_adoptions DESC \ \ LIMIT 5" () let trending = trendingRaw widgetTypeOptions <- sqlQuery "SELECT name, label FROM widget_type_registry WHERE status = 'active' ORDER BY label" () render ShowView { patterns, templates, trending , widgetTypeOptions , searchQuery = mSearch , selectedType = mWType , sortOrder = sortBy }