inter-hub-haskell/Web/Controller/MarketplaceDashboard.hs

64 lines
2.4 KiB
Haskell
Raw Normal View History

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
}