defmodule TarakanWeb.BountyLive.Index do @moduledoc "Open contracts - the public reward board." use TarakanWeb, :live_view import TarakanWeb.BountyComponents alias Tarakan.Market @filters [ {"all", "All"}, {"repository", "Repositories"}, {"infestation", "Infestations"}, {"finding", "Findings"} ] @impl true def mount(_params, _session, socket) do {:ok, socket |> assign(:page_title, "Contracts") |> assign( :meta_description, "Open contracts on Tarakan. Sponsors post rewards for security work on public targets." ) |> assign(:canonical_path, ~p"/bounties") |> assign(:filters, @filters)} end @impl true def handle_params(params, _uri, socket) do filter = normalize_filter(params["type"]) bounties = Market.list_open(target_type: filter) {:noreply, socket |> assign(:filter, filter || "all") |> assign(:bounties, bounties) |> assign(:bounty_count, length(bounties)) |> assign(:open_cents, sum_by(bounties, :amount_cents)) |> assign(:open_credits, sum_by(bounties, :credit_amount))} end defp sum_by(bounties, key) do Enum.reduce(bounties, 0, fn bounty, total -> total + (Map.get(bounty, key) || 0) end) end defp normalize_filter(filter) when filter in ["repository", "infestation", "finding"], do: filter defp normalize_filter(_), do: nil @impl true def render(assigns) do ~H"""

Contracts

{@bounty_count} open

0} class="font-mono text-sm tabular-nums text-ink"> ${div(@open_cents, 100)} escrowed

0} class="font-mono text-sm tabular-nums text-ink"> {@open_credits} credits

<.link navigate={~p"/bounties/new"} class="border-2 border-signal px-4 py-1.5 font-display text-xs uppercase tracking-[0.12em] text-signal transition hover:bg-signal hover:text-ground" > Post a contract
<.link :for={{value, label} <- @filters} patch={~p"/bounties?#{%{type: value}}"} class={[ "wire-badge font-display text-[10px] uppercase tracking-[0.12em] transition", @filter == value && "bg-signal text-ground", @filter != value && "text-ink-muted hover:text-ink" ]} > {label}

No open contracts right now

<.link navigate={~p"/bounties/new"} class="font-semibold text-signal hover:underline"> Post the first one or browse the <.link navigate={~p"/jobs"} class="font-semibold text-signal hover:underline" >jobs queue.

""" end end