inter-hub-haskell/Web/View/GovernanceTemplates/Index.hs

65 lines
2.3 KiB
Haskell
Raw Normal View History

module Web.View.GovernanceTemplates.Index where
import Web.Types
import Generated.Types
import IHP.Prelude
import IHP.ViewPrelude
import Data.Aeson (Value(..), decode, encode)
import qualified Data.ByteString.Lazy.Char8 as BL
type TemplateIndexRow = (GovernanceTemplate, Int)
data IndexView = IndexView
{ templates :: ![TemplateIndexRow]
}
instance View IndexView where
html IndexView { .. } = [hsx|
<div class="flex items-center justify-between mb-6">
<div>
<h1 class="text-2xl font-semibold">Governance Template Library</h1>
<p class="text-sm text-gray-500 mt-1">Published reusable governance templates.</p>
</div>
<a href={NewGovernanceTemplateAction}
class="text-sm bg-indigo-600 text-white px-3 py-1.5 rounded hover:bg-indigo-700">
New Template
</a>
</div>
<div class="space-y-3">
{forEach templates renderTemplateRow}
{if null templates
then [hsx|<p class="text-sm text-gray-400">No published templates yet.</p>|]
else mempty}
</div>
|]
renderTemplateRow :: TemplateIndexRow -> Html
renderTemplateRow (template, cloneCount) = [hsx|
<div class="bg-white rounded-lg border border-gray-200 p-4 hover:border-indigo-200">
<div class="flex items-center justify-between">
<div>
<a href={ShowGovernanceTemplateAction { governanceTemplateId = template.id }}
class="font-medium text-indigo-700 hover:underline">
{template.name}
</a>
{maybe mempty (\d -> [hsx|<p class="text-xs text-gray-500 mt-0.5">{d}</p>|]) template.description}
</div>
<span class="text-xs text-gray-400">{tshow cloneCount} clones</span>
</div>
<div class="mt-2 flex flex-wrap gap-1">
{forEach (jsonArrayTexts template.categories) renderCategoryTag}
</div>
</div>
|]
renderCategoryTag :: Text -> Html
renderCategoryTag cat = [hsx|
<span class="px-2 py-0.5 rounded text-xs bg-blue-100 text-blue-700 font-mono">{cat}</span>
|]
jsonArrayTexts :: Value -> [Text]
jsonArrayTexts val = case decode (encode val) of
Just (arr :: [Text]) -> arr
Nothing -> []