After "mix phx.gen.live Biddings Bidding biddings bidding_round:integer amount:integer depot_wish_one:string depot_wish_two:string".

This commit is contained in:
2026-02-11 16:14:19 +01:00
parent 7ad08fa91d
commit 2bec68b9ed
9 changed files with 677 additions and 0 deletions

View File

@ -0,0 +1,147 @@
defmodule BeetRoundServer.Biddings do
@moduledoc """
The Biddings context.
"""
import Ecto.Query, warn: false
alias BeetRoundServer.Repo
alias BeetRoundServer.Biddings.Bidding
alias BeetRoundServer.Accounts.Scope
@doc """
Subscribes to scoped notifications about any bidding changes.
The broadcasted messages match the pattern:
* {:created, %Bidding{}}
* {:updated, %Bidding{}}
* {:deleted, %Bidding{}}
"""
def subscribe_biddings(%Scope{} = scope) do
key = scope.user.id
Phoenix.PubSub.subscribe(BeetRoundServer.PubSub, "user:#{key}:biddings")
end
defp broadcast_bidding(%Scope{} = scope, message) do
key = scope.user.id
Phoenix.PubSub.broadcast(BeetRoundServer.PubSub, "user:#{key}:biddings", message)
end
@doc """
Returns the list of biddings.
## Examples
iex> list_biddings(scope)
[%Bidding{}, ...]
"""
def list_biddings(%Scope{} = scope) do
Repo.all_by(Bidding, user_id: scope.user.id)
end
@doc """
Gets a single bidding.
Raises `Ecto.NoResultsError` if the Bidding does not exist.
## Examples
iex> get_bidding!(scope, 123)
%Bidding{}
iex> get_bidding!(scope, 456)
** (Ecto.NoResultsError)
"""
def get_bidding!(%Scope{} = scope, id) do
Repo.get_by!(Bidding, id: id, user_id: scope.user.id)
end
@doc """
Creates a bidding.
## Examples
iex> create_bidding(scope, %{field: value})
{:ok, %Bidding{}}
iex> create_bidding(scope, %{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def create_bidding(%Scope{} = scope, attrs) do
with {:ok, bidding = %Bidding{}} <-
%Bidding{}
|> Bidding.changeset(attrs, scope)
|> Repo.insert() do
broadcast_bidding(scope, {:created, bidding})
{:ok, bidding}
end
end
@doc """
Updates a bidding.
## Examples
iex> update_bidding(scope, bidding, %{field: new_value})
{:ok, %Bidding{}}
iex> update_bidding(scope, bidding, %{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def update_bidding(%Scope{} = scope, %Bidding{} = bidding, attrs) do
true = bidding.user_id == scope.user.id
with {:ok, bidding = %Bidding{}} <-
bidding
|> Bidding.changeset(attrs, scope)
|> Repo.update() do
broadcast_bidding(scope, {:updated, bidding})
{:ok, bidding}
end
end
@doc """
Deletes a bidding.
## Examples
iex> delete_bidding(scope, bidding)
{:ok, %Bidding{}}
iex> delete_bidding(scope, bidding)
{:error, %Ecto.Changeset{}}
"""
def delete_bidding(%Scope{} = scope, %Bidding{} = bidding) do
true = bidding.user_id == scope.user.id
with {:ok, bidding = %Bidding{}} <-
Repo.delete(bidding) do
broadcast_bidding(scope, {:deleted, bidding})
{:ok, bidding}
end
end
@doc """
Returns an `%Ecto.Changeset{}` for tracking bidding changes.
## Examples
iex> change_bidding(scope, bidding)
%Ecto.Changeset{data: %Bidding{}}
"""
def change_bidding(%Scope{} = scope, %Bidding{} = bidding, attrs \\ %{}) do
true = bidding.user_id == scope.user.id
Bidding.changeset(bidding, attrs, scope)
end
end

View File

@ -0,0 +1,24 @@
defmodule BeetRoundServer.Biddings.Bidding do
use Ecto.Schema
import Ecto.Changeset
@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
schema "biddings" do
field :bidding_round, :integer
field :amount, :integer
field :depot_wish_one, :string
field :depot_wish_two, :string
field :user_id, :binary_id
timestamps(type: :utc_datetime)
end
@doc false
def changeset(bidding, attrs, user_scope) do
bidding
|> cast(attrs, [:bidding_round, :amount, :depot_wish_one, :depot_wish_two])
|> validate_required([:bidding_round, :amount, :depot_wish_one, :depot_wish_two])
|> put_change(:user_id, user_scope.user.id)
end
end

View File

@ -0,0 +1,101 @@
defmodule BeetRoundServerWeb.BiddingLive.Form do
use BeetRoundServerWeb, :live_view
alias BeetRoundServer.Biddings
alias BeetRoundServer.Biddings.Bidding
@impl true
def render(assigns) do
~H"""
<Layouts.app flash={@flash} current_scope={@current_scope}>
<.header>
{@page_title}
<:subtitle>Use this form to manage bidding records in your database.</:subtitle>
</.header>
<.form for={@form} id="bidding-form" phx-change="validate" phx-submit="save">
<.input field={@form[:bidding_round]} type="number" label="Bidding round" />
<.input field={@form[:amount]} type="number" label="Amount" />
<.input field={@form[:depot_wish_one]} type="text" label="Depot wish one" />
<.input field={@form[:depot_wish_two]} type="text" label="Depot wish two" />
<footer>
<.button phx-disable-with="Saving..." variant="primary">Save Bidding</.button>
<.button navigate={return_path(@current_scope, @return_to, @bidding)}>Cancel</.button>
</footer>
</.form>
</Layouts.app>
"""
end
@impl true
def mount(params, _session, socket) do
{:ok,
socket
|> assign(:return_to, return_to(params["return_to"]))
|> apply_action(socket.assigns.live_action, params)}
end
defp return_to("show"), do: "show"
defp return_to(_), do: "index"
defp apply_action(socket, :edit, %{"id" => id}) do
bidding = Biddings.get_bidding!(socket.assigns.current_scope, id)
socket
|> assign(:page_title, "Edit Bidding")
|> assign(:bidding, bidding)
|> assign(:form, to_form(Biddings.change_bidding(socket.assigns.current_scope, bidding)))
end
defp apply_action(socket, :new, _params) do
bidding = %Bidding{user_id: socket.assigns.current_scope.user.id}
socket
|> assign(:page_title, "New Bidding")
|> assign(:bidding, bidding)
|> assign(:form, to_form(Biddings.change_bidding(socket.assigns.current_scope, bidding)))
end
@impl true
def handle_event("validate", %{"bidding" => bidding_params}, socket) do
changeset = Biddings.change_bidding(socket.assigns.current_scope, socket.assigns.bidding, bidding_params)
{:noreply, assign(socket, form: to_form(changeset, action: :validate))}
end
def handle_event("save", %{"bidding" => bidding_params}, socket) do
save_bidding(socket, socket.assigns.live_action, bidding_params)
end
defp save_bidding(socket, :edit, bidding_params) do
case Biddings.update_bidding(socket.assigns.current_scope, socket.assigns.bidding, bidding_params) do
{:ok, bidding} ->
{:noreply,
socket
|> put_flash(:info, "Bidding updated successfully")
|> push_navigate(
to: return_path(socket.assigns.current_scope, socket.assigns.return_to, bidding)
)}
{:error, %Ecto.Changeset{} = changeset} ->
{:noreply, assign(socket, form: to_form(changeset))}
end
end
defp save_bidding(socket, :new, bidding_params) do
case Biddings.create_bidding(socket.assigns.current_scope, bidding_params) do
{:ok, bidding} ->
{:noreply,
socket
|> put_flash(:info, "Bidding created successfully")
|> push_navigate(
to: return_path(socket.assigns.current_scope, socket.assigns.return_to, bidding)
)}
{:error, %Ecto.Changeset{} = changeset} ->
{:noreply, assign(socket, form: to_form(changeset))}
end
end
defp return_path(_scope, "index", _bidding), do: ~p"/biddings"
defp return_path(_scope, "show", bidding), do: ~p"/biddings/#{bidding}"
end

View File

@ -0,0 +1,76 @@
defmodule BeetRoundServerWeb.BiddingLive.Index do
use BeetRoundServerWeb, :live_view
alias BeetRoundServer.Biddings
@impl true
def render(assigns) do
~H"""
<Layouts.app flash={@flash} current_scope={@current_scope}>
<.header>
Listing Biddings
<:actions>
<.button variant="primary" navigate={~p"/biddings/new"}>
<.icon name="hero-plus" /> New Bidding
</.button>
</:actions>
</.header>
<.table
id="biddings"
rows={@streams.biddings}
row_click={fn {_id, bidding} -> JS.navigate(~p"/biddings/#{bidding}") end}
>
<:col :let={{_id, bidding}} label="Bidding round">{bidding.bidding_round}</:col>
<:col :let={{_id, bidding}} label="Amount">{bidding.amount}</:col>
<:col :let={{_id, bidding}} label="Depot wish one">{bidding.depot_wish_one}</:col>
<:col :let={{_id, bidding}} label="Depot wish two">{bidding.depot_wish_two}</:col>
<:action :let={{_id, bidding}}>
<div class="sr-only">
<.link navigate={~p"/biddings/#{bidding}"}>Show</.link>
</div>
<.link navigate={~p"/biddings/#{bidding}/edit"}>Edit</.link>
</:action>
<:action :let={{id, bidding}}>
<.link
phx-click={JS.push("delete", value: %{id: bidding.id}) |> hide("##{id}")}
data-confirm="Are you sure?"
>
Delete
</.link>
</:action>
</.table>
</Layouts.app>
"""
end
@impl true
def mount(_params, _session, socket) do
if connected?(socket) do
Biddings.subscribe_biddings(socket.assigns.current_scope)
end
{:ok,
socket
|> assign(:page_title, "Listing Biddings")
|> stream(:biddings, list_biddings(socket.assigns.current_scope))}
end
@impl true
def handle_event("delete", %{"id" => id}, socket) do
bidding = Biddings.get_bidding!(socket.assigns.current_scope, id)
{:ok, _} = Biddings.delete_bidding(socket.assigns.current_scope, bidding)
{:noreply, stream_delete(socket, :biddings, bidding)}
end
@impl true
def handle_info({type, %BeetRoundServer.Biddings.Bidding{}}, socket)
when type in [:created, :updated, :deleted] do
{:noreply, stream(socket, :biddings, list_biddings(socket.assigns.current_scope), reset: true)}
end
defp list_biddings(current_scope) do
Biddings.list_biddings(current_scope)
end
end

View File

@ -0,0 +1,67 @@
defmodule BeetRoundServerWeb.BiddingLive.Show do
use BeetRoundServerWeb, :live_view
alias BeetRoundServer.Biddings
@impl true
def render(assigns) do
~H"""
<Layouts.app flash={@flash} current_scope={@current_scope}>
<.header>
Bidding {@bidding.id}
<:subtitle>This is a bidding record from your database.</:subtitle>
<:actions>
<.button navigate={~p"/biddings"}>
<.icon name="hero-arrow-left" />
</.button>
<.button variant="primary" navigate={~p"/biddings/#{@bidding}/edit?return_to=show"}>
<.icon name="hero-pencil-square" /> Edit bidding
</.button>
</:actions>
</.header>
<.list>
<:item title="Bidding round">{@bidding.bidding_round}</:item>
<:item title="Amount">{@bidding.amount}</:item>
<:item title="Depot wish one">{@bidding.depot_wish_one}</:item>
<:item title="Depot wish two">{@bidding.depot_wish_two}</:item>
</.list>
</Layouts.app>
"""
end
@impl true
def mount(%{"id" => id}, _session, socket) do
if connected?(socket) do
Biddings.subscribe_biddings(socket.assigns.current_scope)
end
{:ok,
socket
|> assign(:page_title, "Show Bidding")
|> assign(:bidding, Biddings.get_bidding!(socket.assigns.current_scope, id))}
end
@impl true
def handle_info(
{:updated, %BeetRoundServer.Biddings.Bidding{id: id} = bidding},
%{assigns: %{bidding: %{id: id}}} = socket
) do
{:noreply, assign(socket, :bidding, bidding)}
end
def handle_info(
{:deleted, %BeetRoundServer.Biddings.Bidding{id: id}},
%{assigns: %{bidding: %{id: id}}} = socket
) do
{:noreply,
socket
|> put_flash(:error, "The current bidding was deleted.")
|> push_navigate(to: ~p"/biddings")}
end
def handle_info({type, %BeetRoundServer.Biddings.Bidding{}}, socket)
when type in [:created, :updated, :deleted] do
{:noreply, socket}
end
end