module Web.View.LearningDashboard.Show where import Web.View.Prelude import Data.Time (diffUTCTime, getCurrentTime, nominalDay) data ShowView = ShowView { topCorrelations :: ![OutcomeCorrelation] , patternRankings :: ![PatternPerformanceRecord] , thresholdStatus :: ![(Hub, Maybe AdaptiveThresholdConfig)] , recentInsights :: ![LearningInsight] , knowledgeHighlights :: ![InstitutionalKnowledgeEntry] } instance View ShowView where html ShowView { .. } = [hsx|

Learning Dashboard

{-- Panel 1: Top annotation predictors --}

Top Annotation Predictors

{if null topCorrelations then [hsx|

No data — run correlation analysis per hub.

|] else [hsx|
{forM_ topCorrelations renderCorrelation}
|]}
{-- Panel 2: Pattern performance ranking --}

Pattern Performance Ranking

{if null patternRankings then [hsx|

No data — run pattern performance per hub.

|] else [hsx|
{forM_ patternRankings renderPatternRank}
|]}
{-- Panel 3: Adaptive threshold status --}

Adaptive Threshold Status

{forM_ thresholdStatus renderThresholdStatus}
{-- Panel 4: Recent learning insights --}

Recent Insights

{if null recentInsights then [hsx|

No insights yet.

|] else [hsx|
{forM_ recentInsights renderInsight}
|]}
{-- Panel 5: Knowledge base highlights --}

Knowledge Highlights

{if null knowledgeHighlights then [hsx|

No entries yet — distil a decision.

|] else [hsx|
{forM_ knowledgeHighlights renderKnowledge}
|]}
|] where renderCorrelation c = [hsx|
{c.annotationCategory}
show (round (c.correlationScore * 100) :: Int) <> "%"}>
{show (round (c.correlationScore * 100) :: Int)}%
|] barColor s | s >= 0.7 = "h-2 rounded-full bg-green-500" :: Text | s >= 0.4 = "h-2 rounded-full bg-yellow-500" | otherwise = "h-2 rounded-full bg-red-400" renderPatternRank r = let rate = if r.totalOutcomeCount > 0 then fromIntegral r.positiveOutcomeCount / fromIntegral r.totalOutcomeCount :: Double else 0.0 in [hsx|
{maybe "-" show r.outcomeRank} {show r.widgetPatternId} {show (round (rate * 100) :: Int)}%
|] renderThresholdStatus (h, mCfg) = let driftClass = case mCfg of Nothing -> "text-red-500" :: Text Just cfg -> "text-green-600" label = case mCfg of Nothing -> "Not calibrated" Just cfg -> "Calibrated" in [hsx|
{h.name} {label}
|] renderInsight i = [hsx|

{i.title}

{insightTypeBadge i.insightType}

|] insightTypeBadge t = case t of "annotation_predictor" -> "Annotation predictor" :: Text "threshold_calibration" -> "Threshold calibration" "pattern_ranking" -> "Pattern ranking" "routing_improvement" -> "Routing improvement" _ -> t renderKnowledge e = [hsx|
{take 80 e.summary <> if length e.summary > 80 then "…" else ""}
|]