defmodule TarakanWeb.BountyComponents do @moduledoc """ Shared display helpers and components for the bounty marketplace. """ use TarakanWeb, :html alias Tarakan.Market.Bounty alias TarakanWeb.RepositoryPaths @doc "Human-facing reward amount: `$1,234` for fiat, `1,234 credits` for credit bounties." def amount_label(%Bounty{funding: "fiat", amount_cents: cents}) when is_integer(cents) do "$#{format_number(div(cents, 100))}" end def amount_label(%Bounty{funding: "credits", credit_amount: amount}) when is_integer(amount) do "#{format_number(amount)} credits" end def amount_label(_bounty), do: " - " def status_label("pending_funding"), do: "awaiting funding" def status_label("open"), do: "open" def status_label("claimed"), do: "claimed" def status_label("fulfilled"), do: "fulfilled" def status_label("payout_pending"), do: "payout pending" def status_label("paid"), do: "paid" def status_label("cancelled"), do: "cancelled" def status_label("expired"), do: "expired" def status_label(other), do: other @doc "Path to the bounty's public target page." def target_path(%Bounty{target_type: "repository", repository: %_{} = repository}), do: RepositoryPaths.repository_security_path(repository) def target_path(%Bounty{target_type: "infestation", pattern_key: pattern_key}), do: ~p"/infestations/#{pattern_key}" def target_path(%Bounty{target_type: "finding", canonical_finding: %_{} = finding}), do: ~p"/findings/#{finding.public_id}" def target_path(_bounty), do: nil @doc "Short label identifying the bounty's target." def target_label(%Bounty{target_type: "repository", repository: %_{} = repository}), do: "#{repository.owner}/#{repository.name}" def target_label(%Bounty{target_type: "infestation", pattern_key: pattern_key}), do: pattern_key def target_label(%Bounty{target_type: "finding", canonical_finding: %_{} = finding}), do: finding.title def target_label(_bounty), do: "unknown target" @doc """ Compact "Contract" strip rendered on target pages when open bounties exist. Links to the richest open contract for the target. """ attr :bounties, :list, required: true def wanted_banner(assigns) do ~H"""
<.notch_badge class="bg-signal text-ground">Contract

{amount_label(hd(@bounties))} offered for work on this target 1}> (+ {length(@bounties) - 1} more {if length(@bounties) == 2, do: "contract", else: "contracts"})

<.link navigate={~p"/bounties/#{hd(@bounties).public_id}"} class="ml-auto font-mono text-xs text-signal transition hover:underline" > View contract →
""" end defp format_number(number) do number |> Integer.to_string() |> String.reverse() |> String.replace(~r/(\d{3})(?=\d)/, "\\1,") |> String.reverse() end end