Compare commits
10 Commits
14f04befd0
...
c994ea171e
| Author | SHA1 | Date | |
|---|---|---|---|
| c994ea171e | |||
| 15c02deb7a | |||
| 97cc49975a | |||
| 2bec68b9ed | |||
| 7ad08fa91d | |||
| 1eb6cbe0e6 | |||
| e91d36b9c0 | |||
| 18f883c9ad | |||
| 56ec80623d | |||
| 8ef1e76788 |
@ -22,7 +22,7 @@ config :beet_round_server, BeetRoundServerWeb.Endpoint,
|
||||
http: [ip: {127, 0, 0, 1}, port: String.to_integer(System.get_env("PORT") || "4000")],
|
||||
check_origin: false,
|
||||
code_reloader: true,
|
||||
debug_errors: true,
|
||||
debug_errors: false,
|
||||
secret_key_base: "ha7k0JD3LvWrZgupXaVbXq6SQhvTwc6R/HyqCJIpANEtcSni88QELgaYgvr5I49M",
|
||||
watchers: [
|
||||
esbuild: {Esbuild, :install_and_run, [:beet_round_server, ~w(--sourcemap=inline --watch)]},
|
||||
|
||||
@ -10,6 +10,19 @@ defmodule BeetRoundServer.Accounts do
|
||||
|
||||
## Database getters
|
||||
|
||||
@doc """
|
||||
Returns the list of users.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> list_users()
|
||||
[%User{}, ...]
|
||||
|
||||
"""
|
||||
def list_users do
|
||||
Repo.all(User)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets a user by email.
|
||||
|
||||
|
||||
147
lib/beet_round_server/biddings.ex
Normal 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
|
||||
24
lib/beet_round_server/biddings/bidding.ex
Normal 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
|
||||
@ -17,7 +17,9 @@ defmodule BeetRoundServerWeb do
|
||||
those modules here.
|
||||
"""
|
||||
|
||||
def static_paths, do: ~w(assets fonts images favicon.ico robots.txt)
|
||||
def static_paths,
|
||||
do:
|
||||
~w(assets fonts images favicon.ico apple-touch-icon.png favicon-32x32.png favicon-16x16.png manifest.json robots.txt)
|
||||
|
||||
def router do
|
||||
quote do
|
||||
|
||||
@ -35,29 +35,25 @@ defmodule BeetRoundServerWeb.Layouts do
|
||||
|
||||
def app(assigns) do
|
||||
~H"""
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
|
||||
<header class="navbar px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex-1">
|
||||
<a href="/" class="flex-1 flex w-fit items-center gap-2">
|
||||
<img src={~p"/images/logo.svg"} width="36" />
|
||||
<span class="text-sm font-semibold">v{Application.spec(:phoenix, :vsn)}</span>
|
||||
<img src={~p"/images/BeetRound.png"} width="36" />
|
||||
<span class="text-sm font-semibold">
|
||||
BeetRound v{Application.spec(:beet_round_server, :vsn)} | Das grüne Zebra
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="flex-none">
|
||||
<ul class="flex flex-column px-1 space-x-4 items-center">
|
||||
<li>
|
||||
<a href="https://phoenixframework.org/" class="btn btn-ghost">Website</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://github.com/phoenixframework/phoenix" class="btn btn-ghost">GitHub</a>
|
||||
</li>
|
||||
<li>
|
||||
<.theme_toggle />
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://hexdocs.pm/phoenix/overview.html" class="btn btn-primary">
|
||||
Get Started <span aria-hidden="true">→</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="csrf-token" content={get_csrf_token()} />
|
||||
<.live_title default="BeetRoundServer" suffix=" · Phoenix Framework">
|
||||
<.live_title default="BeetRound" suffix=" · Das grüne Zebra">
|
||||
{assigns[:page_title]}
|
||||
</.live_title>
|
||||
<link phx-track-static rel="stylesheet" href={~p"/assets/css/app.css"} />
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
defmodule BeetRoundServerWeb.DefaultApiController do
|
||||
use BeetRoundServerWeb, :controller
|
||||
|
||||
def index(conn, _params) do
|
||||
text(conn, "The Beet Round API (#{Mix.env()}) is running.")
|
||||
end
|
||||
end
|
||||
@ -1,188 +1,42 @@
|
||||
<Layouts.flash_group flash={@flash} />
|
||||
<div class="left-[40rem] fixed inset-y-0 right-0 z-0 hidden lg:block xl:left-[50rem]">
|
||||
<svg
|
||||
viewBox="0 0 1480 957"
|
||||
fill="none"
|
||||
aria-hidden="true"
|
||||
class="absolute inset-0 h-full w-full"
|
||||
preserveAspectRatio="xMinYMid slice"
|
||||
>
|
||||
<path fill="#EE7868" d="M0 0h1480v957H0z" />
|
||||
<path
|
||||
d="M137.542 466.27c-582.851-48.41-988.806-82.127-1608.412 658.2l67.39 810 3083.15-256.51L1535.94-49.622l-98.36 8.183C1269.29 281.468 734.115 515.799 146.47 467.012l-8.928-.742Z"
|
||||
fill="#FF9F92"
|
||||
/>
|
||||
<path
|
||||
d="M371.028 528.664C-169.369 304.988-545.754 149.198-1361.45 665.565l-182.58 792.025 3014.73 694.98 389.42-1689.25-96.18-22.171C1505.28 697.438 924.153 757.586 379.305 532.09l-8.277-3.426Z"
|
||||
fill="#FA8372"
|
||||
/>
|
||||
<path
|
||||
d="M359.326 571.714C-104.765 215.795-428.003-32.102-1349.55 255.554l-282.3 1224.596 3047.04 722.01 312.24-1354.467C1411.25 1028.3 834.355 935.995 366.435 577.166l-7.109-5.452Z"
|
||||
fill="#E96856"
|
||||
fill-opacity=".6"
|
||||
/>
|
||||
<path
|
||||
d="M1593.87 1236.88c-352.15 92.63-885.498-145.85-1244.602-613.557l-5.455-7.105C-12.347 152.31-260.41-170.8-1225-131.458l-368.63 1599.048 3057.19 704.76 130.31-935.47Z"
|
||||
fill="#C42652"
|
||||
fill-opacity=".2"
|
||||
/>
|
||||
<path
|
||||
d="M1411.91 1526.93c-363.79 15.71-834.312-330.6-1085.883-863.909l-3.822-8.102C72.704 125.95-101.074-242.476-1052.01-408.907l-699.85 1484.267 2837.75 1338.01 326.02-886.44Z"
|
||||
fill="#A41C42"
|
||||
fill-opacity=".2"
|
||||
/>
|
||||
<path
|
||||
d="M1116.26 1863.69c-355.457-78.98-720.318-535.27-825.287-1115.521l-1.594-8.816C185.286 163.833 112.786-237.016-762.678-643.898L-1822.83 608.665 571.922 2635.55l544.338-771.86Z"
|
||||
fill="#A41C42"
|
||||
fill-opacity=".2"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="px-4 py-10 sm:px-6 sm:py-28 lg:px-8 xl:px-28 xl:py-32">
|
||||
<div class="mx-auto max-w-xl lg:mx-0">
|
||||
<svg viewBox="0 0 71 48" class="h-12" aria-hidden="true">
|
||||
<path
|
||||
d="m26.371 33.477-.552-.1c-3.92-.729-6.397-3.1-7.57-6.829-.733-2.324.597-4.035 3.035-4.148 1.995-.092 3.362 1.055 4.57 2.39 1.557 1.72 2.984 3.558 4.514 5.305 2.202 2.515 4.797 4.134 8.347 3.634 3.183-.448 5.958-1.725 8.371-3.828.363-.316.761-.592 1.144-.886l-.241-.284c-2.027.63-4.093.841-6.205.735-3.195-.16-6.24-.828-8.964-2.582-2.486-1.601-4.319-3.746-5.19-6.611-.704-2.315.736-3.934 3.135-3.6.948.133 1.746.56 2.463 1.165.583.493 1.143 1.015 1.738 1.493 2.8 2.25 6.712 2.375 10.265-.068-5.842-.026-9.817-3.24-13.308-7.313-1.366-1.594-2.7-3.216-4.095-4.785-2.698-3.036-5.692-5.71-9.79-6.623C12.8-.623 7.745.14 2.893 2.361 1.926 2.804.997 3.319 0 4.149c.494 0 .763.006 1.032 0 2.446-.064 4.28 1.023 5.602 3.024.962 1.457 1.415 3.104 1.761 4.798.513 2.515.247 5.078.544 7.605.761 6.494 4.08 11.026 10.26 13.346 2.267.852 4.591 1.135 7.172.555ZM10.751 3.852c-.976.246-1.756-.148-2.56-.962 1.377-.343 2.592-.476 3.897-.528-.107.848-.607 1.306-1.336 1.49Zm32.002 37.924c-.085-.626-.62-.901-1.04-1.228-1.857-1.446-4.03-1.958-6.333-2-1.375-.026-2.735-.128-4.031-.61-.595-.22-1.26-.505-1.244-1.272.015-.78.693-1 1.31-1.184.505-.15 1.026-.247 1.6-.382-1.46-.936-2.886-1.065-4.787-.3-2.993 1.202-5.943 1.06-8.926-.017-1.684-.608-3.179-1.563-4.735-2.408l-.043.03a2.96 2.96 0 0 0 .04-.029c-.038-.117-.107-.12-.197-.054l.122.107c1.29 2.115 3.034 3.817 5.004 5.271 3.793 2.8 7.936 4.471 12.784 3.73A66.714 66.714 0 0 1 37 40.877c1.98-.16 3.866.398 5.753.899Zm-9.14-30.345c-.105-.076-.206-.266-.42-.069 1.745 2.36 3.985 4.098 6.683 5.193 4.354 1.767 8.773 2.07 13.293.51 3.51-1.21 6.033-.028 7.343 3.38.19-3.955-2.137-6.837-5.843-7.401-2.084-.318-4.01.373-5.962.94-5.434 1.575-10.485.798-15.094-2.553Zm27.085 15.425c.708.059 1.416.123 2.124.185-1.6-1.405-3.55-1.517-5.523-1.404-3.003.17-5.167 1.903-7.14 3.972-1.739 1.824-3.31 3.87-5.903 4.604.043.078.054.117.066.117.35.005.699.021 1.047.005 3.768-.17 7.317-.965 10.14-3.7.89-.86 1.685-1.817 2.544-2.71.716-.746 1.584-1.159 2.645-1.07Zm-8.753-4.67c-2.812.246-5.254 1.409-7.548 2.943-1.766 1.18-3.654 1.738-5.776 1.37-.374-.066-.75-.114-1.124-.17l-.013.156c.135.07.265.151.405.207.354.14.702.308 1.07.395 4.083.971 7.992.474 11.516-1.803 2.221-1.435 4.521-1.707 7.013-1.336.252.038.503.083.756.107.234.022.479.255.795.003-2.179-1.574-4.526-2.096-7.094-1.872Zm-10.049-9.544c1.475.051 2.943-.142 4.486-1.059-.452.04-.643.04-.827.076-2.126.424-4.033-.04-5.733-1.383-.623-.493-1.257-.974-1.889-1.457-2.503-1.914-5.374-2.555-8.514-2.5.05.154.054.26.108.315 3.417 3.455 7.371 5.836 12.369 6.008Zm24.727 17.731c-2.114-2.097-4.952-2.367-7.578-.537 1.738.078 3.043.632 4.101 1.728.374.388.763.768 1.182 1.106 1.6 1.29 4.311 1.352 5.896.155-1.861-.726-1.861-.726-3.601-2.452Zm-21.058 16.06c-1.858-3.46-4.981-4.24-8.59-4.008a9.667 9.667 0 0 1 2.977 1.39c.84.586 1.547 1.311 2.243 2.055 1.38 1.473 3.534 2.376 4.962 2.07-.656-.412-1.238-.848-1.592-1.507Zm17.29-19.32c0-.023.001-.045.003-.068l-.006.006.006-.006-.036-.004.021.018.012.053Zm-20 14.744a7.61 7.61 0 0 0-.072-.041.127.127 0 0 0 .015.043c.005.008.038 0 .058-.002Zm-.072-.041-.008-.034-.008.01.008-.01-.022-.006.005.026.024.014Z"
|
||||
fill="#FD4F00"
|
||||
/>
|
||||
</svg>
|
||||
<a href="/">
|
||||
<img src={~p"/images/BeetRound.png"} width="64" />
|
||||
</a>
|
||||
<div class="mt-10 flex justify-between items-center">
|
||||
<h1 class="flex items-center text-sm font-semibold leading-6">
|
||||
Phoenix Framework
|
||||
BeetRound
|
||||
<small class="badge badge-warning badge-sm ml-3">
|
||||
v{Application.spec(:phoenix, :vsn)}
|
||||
v{Application.spec(:beet_round_server, :vsn)}
|
||||
</small>
|
||||
</h1>
|
||||
<Layouts.theme_toggle />
|
||||
</div>
|
||||
|
||||
<p class="text-[2rem] mt-4 font-semibold leading-10 tracking-tighter text-balance">
|
||||
Peace of mind from prototype to production.
|
||||
Digitales Bieten in einer SoLaWi.
|
||||
</p>
|
||||
<p class="mt-4 leading-7 text-base-content/70">
|
||||
Build rich, interactive web applications quickly, with less code and fewer moving parts. Join our growing community of developers using Phoenix to craft APIs, HTML5 apps and more, for fun or at scale.
|
||||
Server zum Sammeln der digital abgegeben Gebote.
|
||||
</p>
|
||||
|
||||
<%= if true do %>
|
||||
<br />
|
||||
<a
|
||||
href={~p"/biddings"}
|
||||
class="group text-brand -mx-2 -my-0.5 inline-flex items-center gap-3 rounded-lg px-2 py-0.5 hover:bg-zinc-50 hover:text-zinc-900"
|
||||
>
|
||||
Zu meinen Geboten
|
||||
</a>
|
||||
<% end %>
|
||||
|
||||
<div class="flex">
|
||||
<div class="w-full sm:w-auto">
|
||||
<div class="mt-10 grid grid-cols-1 gap-x-6 gap-y-4 sm:grid-cols-3">
|
||||
<a
|
||||
href="https://hexdocs.pm/phoenix/overview.html"
|
||||
class="group relative rounded-box px-6 py-4 text-sm font-semibold leading-6 sm:py-6"
|
||||
>
|
||||
<span class="absolute inset-0 rounded-box bg-base-200 transition group-hover:bg-base-300 sm:group-hover:scale-105">
|
||||
</span>
|
||||
<span class="relative flex items-center gap-4 sm:flex-col">
|
||||
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true" class="h-6 w-6">
|
||||
<path d="m12 4 10-2v18l-10 2V4Z" fill="currentColor" fill-opacity=".15" />
|
||||
<path
|
||||
d="M12 4 2 2v18l10 2m0-18v18m0-18 10-2v18l-10 2"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
Guides & Docs
|
||||
</span>
|
||||
</a>
|
||||
<a
|
||||
href="https://github.com/phoenixframework/phoenix"
|
||||
class="group relative rounded-box px-6 py-4 text-sm font-semibold leading-6 sm:py-6"
|
||||
>
|
||||
<span class="absolute inset-0 rounded-box bg-base-200 transition group-hover:bg-base-300 sm:group-hover:scale-105">
|
||||
</span>
|
||||
<span class="relative flex items-center gap-4 sm:flex-col">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true" class="h-6 w-6">
|
||||
<path
|
||||
fill="currentColor"
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M12 0C5.37 0 0 5.506 0 12.303c0 5.445 3.435 10.043 8.205 11.674.6.107.825-.262.825-.585 0-.292-.015-1.261-.015-2.291C6 21.67 5.22 20.346 4.98 19.654c-.135-.354-.72-1.446-1.23-1.738-.42-.23-1.02-.8-.015-.815.945-.015 1.62.892 1.845 1.261 1.08 1.86 2.805 1.338 3.495 1.015.105-.8.42-1.338.765-1.645-2.67-.308-5.46-1.37-5.46-6.075 0-1.338.465-2.446 1.23-3.307-.12-.308-.54-1.569.12-3.26 0 0 1.005-.323 3.3 1.26.96-.276 1.98-.415 3-.415s2.04.139 3 .416c2.295-1.6 3.3-1.261 3.3-1.261.66 1.691.24 2.952.12 3.26.765.861 1.23 1.953 1.23 3.307 0 4.721-2.805 5.767-5.475 6.075.435.384.81 1.122.81 2.276 0 1.645-.015 2.968-.015 3.383 0 .323.225.707.825.585a12.047 12.047 0 0 0 5.919-4.489A12.536 12.536 0 0 0 24 12.304C24 5.505 18.63 0 12 0Z"
|
||||
/>
|
||||
</svg>
|
||||
Source Code
|
||||
</span>
|
||||
</a>
|
||||
<a
|
||||
href={"https://github.com/phoenixframework/phoenix/blob/v#{Application.spec(:phoenix, :vsn)}/CHANGELOG.md"}
|
||||
class="group relative rounded-box px-6 py-4 text-sm font-semibold leading-6 sm:py-6"
|
||||
>
|
||||
<span class="absolute inset-0 rounded-box bg-base-200 transition group-hover:bg-base-300 sm:group-hover:scale-105">
|
||||
</span>
|
||||
<span class="relative flex items-center gap-4 sm:flex-col">
|
||||
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true" class="h-6 w-6">
|
||||
<path
|
||||
d="M12 1v6M12 17v6"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<circle
|
||||
cx="12"
|
||||
cy="12"
|
||||
r="4"
|
||||
fill="currentColor"
|
||||
fill-opacity=".15"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
Changelog
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="mt-10 grid grid-cols-1 gap-y-4 text-sm leading-6 text-base-content/80 sm:grid-cols-2">
|
||||
<div>
|
||||
<a
|
||||
href="https://elixirforum.com"
|
||||
class="group -mx-2 -my-0.5 inline-flex items-center gap-3 rounded-lg px-2 py-0.5 hover:bg-base-200 hover:text-base-content"
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 16 16"
|
||||
aria-hidden="true"
|
||||
class="h-4 w-4 fill-base-content/40 group-hover:fill-base-content"
|
||||
>
|
||||
<path d="M8 13.833c3.866 0 7-2.873 7-6.416C15 3.873 11.866 1 8 1S1 3.873 1 7.417c0 1.081.292 2.1.808 2.995.606 1.05.806 2.399.086 3.375l-.208.283c-.285.386-.01.905.465.85.852-.098 2.048-.318 3.137-.81a3.717 3.717 0 0 1 1.91-.318c.263.027.53.041.802.041Z" />
|
||||
</svg>
|
||||
Discuss on the Elixir Forum
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a
|
||||
href="https://discord.gg/elixir"
|
||||
class="group -mx-2 -my-0.5 inline-flex items-center gap-3 rounded-lg px-2 py-0.5 hover:bg-base-200 hover:text-base-content"
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 16 16"
|
||||
aria-hidden="true"
|
||||
class="h-4 w-4 fill-base-content/40 group-hover:fill-base-content"
|
||||
>
|
||||
<path d="M13.545 2.995c-1.02-.46-2.114-.8-3.257-.994a.05.05 0 0 0-.052.024c-.141.246-.297.567-.406.82a12.377 12.377 0 0 0-3.658 0 8.238 8.238 0 0 0-.412-.82.052.052 0 0 0-.052-.024 13.315 13.315 0 0 0-3.257.994.046.046 0 0 0-.021.018C.356 6.063-.213 9.036.066 11.973c.001.015.01.029.02.038a13.353 13.353 0 0 0 3.996 1.987.052.052 0 0 0 .056-.018c.308-.414.582-.85.818-1.309a.05.05 0 0 0-.028-.069 8.808 8.808 0 0 1-1.248-.585.05.05 0 0 1-.005-.084c.084-.062.168-.126.248-.191a.05.05 0 0 1 .051-.007c2.619 1.176 5.454 1.176 8.041 0a.05.05 0 0 1 .053.006c.08.065.164.13.248.192a.05.05 0 0 1-.004.084c-.399.23-.813.423-1.249.585a.05.05 0 0 0-.027.07c.24.457.514.893.817 1.307a.051.051 0 0 0 .056.019 13.31 13.31 0 0 0 4.001-1.987.05.05 0 0 0 .021-.037c.334-3.396-.559-6.345-2.365-8.96a.04.04 0 0 0-.021-.02Zm-8.198 7.19c-.789 0-1.438-.712-1.438-1.587 0-.874.637-1.586 1.438-1.586.807 0 1.45.718 1.438 1.586 0 .875-.637 1.587-1.438 1.587Zm5.316 0c-.788 0-1.438-.712-1.438-1.587 0-.874.637-1.586 1.438-1.586.807 0 1.45.718 1.438 1.586 0 .875-.63 1.587-1.438 1.587Z" />
|
||||
</svg>
|
||||
Join our Discord server
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a
|
||||
href="https://elixir-slack.community/"
|
||||
class="group -mx-2 -my-0.5 inline-flex items-center gap-3 rounded-lg px-2 py-0.5 hover:bg-base-200 hover:text-base-content"
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 16 16"
|
||||
aria-hidden="true"
|
||||
class="h-4 w-4 fill-base-content/40 group-hover:fill-base-content"
|
||||
>
|
||||
<path d="M3.361 10.11a1.68 1.68 0 1 1-1.68-1.681h1.68v1.682ZM4.209 10.11a1.68 1.68 0 1 1 3.361 0v4.21a1.68 1.68 0 1 1-3.361 0v-4.21ZM5.89 3.361a1.68 1.68 0 1 1 1.681-1.68v1.68H5.89ZM5.89 4.209a1.68 1.68 0 1 1 0 3.361H1.68a1.68 1.68 0 1 1 0-3.361h4.21ZM12.639 5.89a1.68 1.68 0 1 1 1.68 1.681h-1.68V5.89ZM11.791 5.89a1.68 1.68 0 1 1-3.361 0V1.68a1.68 1.68 0 0 1 3.361 0v4.21ZM10.11 12.639a1.68 1.68 0 1 1-1.681 1.68v-1.68h1.682ZM10.11 11.791a1.68 1.68 0 1 1 0-3.361h4.21a1.68 1.68 0 1 1 0 3.361h-4.21Z" />
|
||||
</svg>
|
||||
Join us on Slack
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a
|
||||
href="https://fly.io/docs/elixir/getting-started/"
|
||||
href="https://working-copy.org/projects/beetround/"
|
||||
class="group -mx-2 -my-0.5 inline-flex items-center gap-3 rounded-lg px-2 py-0.5 hover:bg-base-200 hover:text-base-content"
|
||||
>
|
||||
<svg
|
||||
@ -192,7 +46,7 @@
|
||||
>
|
||||
<path d="M1 12.5A4.5 4.5 0 005.5 17H15a4 4 0 001.866-7.539 3.504 3.504 0 00-4.504-4.272A4.5 4.5 0 004.06 8.235 4.502 4.502 0 001 12.5z" />
|
||||
</svg>
|
||||
Deploy your application
|
||||
by Working-Copy Collective
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
43
lib/beet_round_server_web/controllers/user_controller.ex
Normal file
@ -0,0 +1,43 @@
|
||||
defmodule BeetRoundServerWeb.UserController do
|
||||
use BeetRoundServerWeb, :controller
|
||||
|
||||
alias BeetRoundServer.Accounts
|
||||
alias BeetRoundServer.Accounts.User
|
||||
|
||||
action_fallback BeetRoundServerWeb.FallbackController
|
||||
|
||||
def index(conn, _params) do
|
||||
users = Accounts.list_users()
|
||||
render(conn, :index, users: users)
|
||||
end
|
||||
|
||||
def create(conn, %{"user" => user_params}) do
|
||||
with {:ok, %User{} = user} <- Accounts.register_user(user_params) do
|
||||
conn
|
||||
|> put_status(:created)
|
||||
|> put_resp_header("location", ~p"/api/users/#{user}")
|
||||
|> render(:show, user: user)
|
||||
end
|
||||
end
|
||||
|
||||
def show(conn, %{"id" => id}) do
|
||||
user = Accounts.get_user!(id)
|
||||
render(conn, :show, user: user)
|
||||
end
|
||||
|
||||
# def update(conn, %{"id" => id, "user" => user_params}) do
|
||||
# user = Accounts.get_user!(id)
|
||||
|
||||
# with {:ok, %User{} = user} <- Accounts.update_user(user, user_params) do
|
||||
# render(conn, :show, user: user)
|
||||
# end
|
||||
# end
|
||||
|
||||
# def delete(conn, %{"id" => id}) do
|
||||
# user = Accounts.get_user!(id)
|
||||
|
||||
# with {:ok, %User{}} <- Accounts.delete_user(user) do
|
||||
# send_resp(conn, :no_content, "")
|
||||
# end
|
||||
# end
|
||||
end
|
||||
24
lib/beet_round_server_web/controllers/user_json.ex
Normal file
@ -0,0 +1,24 @@
|
||||
defmodule BeetRoundServerWeb.UserJSON do
|
||||
alias BeetRoundServer.Accounts.User
|
||||
|
||||
@doc """
|
||||
Renders a list of users.
|
||||
"""
|
||||
def index(%{users: users}) do
|
||||
%{data: for(user <- users, do: data(user))}
|
||||
end
|
||||
|
||||
@doc """
|
||||
Renders a single user.
|
||||
"""
|
||||
def show(%{user: user}) do
|
||||
%{data: data(user)}
|
||||
end
|
||||
|
||||
defp data(%User{} = user) do
|
||||
%{
|
||||
id: user.id,
|
||||
email: user.email
|
||||
}
|
||||
end
|
||||
end
|
||||
101
lib/beet_round_server_web/live/bidding_live/form.ex
Normal 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
|
||||
76
lib/beet_round_server_web/live/bidding_live/index.ex
Normal 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
|
||||
67
lib/beet_round_server_web/live/bidding_live/show.ex
Normal 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
|
||||
@ -27,7 +27,10 @@ defmodule BeetRoundServerWeb.Router do
|
||||
scope "/api", BeetRoundServerWeb do
|
||||
pipe_through :api
|
||||
|
||||
get "/", DefaultApiController, :index
|
||||
|
||||
resources "/bidding_rounds", BiddingRoundController, except: [:new, :edit]
|
||||
resources "/users", UserController, except: [:new, :edit]
|
||||
end
|
||||
|
||||
# Enable LiveDashboard and Swoosh mailbox preview in development
|
||||
@ -56,6 +59,11 @@ defmodule BeetRoundServerWeb.Router do
|
||||
on_mount: [{BeetRoundServerWeb.UserAuth, :require_authenticated}] do
|
||||
live "/users/settings", UserLive.Settings, :edit
|
||||
live "/users/settings/confirm-email/:token", UserLive.Settings, :confirm_email
|
||||
|
||||
live "/biddings", BiddingLive.Index, :index
|
||||
live "/biddings/new", BiddingLive.Form, :new
|
||||
live "/biddings/:id", BiddingLive.Show, :show
|
||||
live "/biddings/:id/edit", BiddingLive.Form, :edit
|
||||
end
|
||||
|
||||
post "/users/update-password", UserSessionController, :update_password
|
||||
|
||||
@ -262,7 +262,7 @@ defmodule BeetRoundServerWeb.UserAuth do
|
||||
~p"/users/settings"
|
||||
end
|
||||
|
||||
def signed_in_path(_), do: ~p"/"
|
||||
def signed_in_path(_), do: ~p"/biddings"
|
||||
|
||||
@doc """
|
||||
Plug for routes that require the user to be authenticated.
|
||||
|
||||
18
priv/repo/migrations/20260211151210_create_biddings.exs
Normal file
@ -0,0 +1,18 @@
|
||||
defmodule BeetRoundServer.Repo.Migrations.CreateBiddings do
|
||||
use Ecto.Migration
|
||||
|
||||
def change do
|
||||
create table(:biddings, primary_key: false) do
|
||||
add :id, :binary_id, primary_key: true
|
||||
add :bidding_round, :integer
|
||||
add :amount, :integer
|
||||
add :depot_wish_one, :string
|
||||
add :depot_wish_two, :string
|
||||
add :user_id, references(:users, type: :binary_id, on_delete: :delete_all)
|
||||
|
||||
timestamps(type: :utc_datetime)
|
||||
end
|
||||
|
||||
create index(:biddings, [:user_id])
|
||||
end
|
||||
end
|
||||
BIN
priv/static/android-chrome-192x192.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
priv/static/android-chrome-512x512.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
priv/static/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
priv/static/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 791 B |
BIN
priv/static/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 152 B After Width: | Height: | Size: 15 KiB |
BIN
priv/static/images/BeetRound.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
priv/static/images/android-chrome-192x192.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
priv/static/images/android-chrome-512x512.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
priv/static/images/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
priv/static/images/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 791 B |
BIN
priv/static/images/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
priv/static/images/favicon.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
@ -1,6 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 71 48" fill="currentColor" aria-hidden="true">
|
||||
<path
|
||||
d="m26.371 33.477-.552-.1c-3.92-.729-6.397-3.1-7.57-6.829-.733-2.324.597-4.035 3.035-4.148 1.995-.092 3.362 1.055 4.57 2.39 1.557 1.72 2.984 3.558 4.514 5.305 2.202 2.515 4.797 4.134 8.347 3.634 3.183-.448 5.958-1.725 8.371-3.828.363-.316.761-.592 1.144-.886l-.241-.284c-2.027.63-4.093.841-6.205.735-3.195-.16-6.24-.828-8.964-2.582-2.486-1.601-4.319-3.746-5.19-6.611-.704-2.315.736-3.934 3.135-3.6.948.133 1.746.56 2.463 1.165.583.493 1.143 1.015 1.738 1.493 2.8 2.25 6.712 2.375 10.265-.068-5.842-.026-9.817-3.24-13.308-7.313-1.366-1.594-2.7-3.216-4.095-4.785-2.698-3.036-5.692-5.71-9.79-6.623C12.8-.623 7.745.14 2.893 2.361 1.926 2.804.997 3.319 0 4.149c.494 0 .763.006 1.032 0 2.446-.064 4.28 1.023 5.602 3.024.962 1.457 1.415 3.104 1.761 4.798.513 2.515.247 5.078.544 7.605.761 6.494 4.08 11.026 10.26 13.346 2.267.852 4.591 1.135 7.172.555ZM10.751 3.852c-.976.246-1.756-.148-2.56-.962 1.377-.343 2.592-.476 3.897-.528-.107.848-.607 1.306-1.336 1.49Zm32.002 37.924c-.085-.626-.62-.901-1.04-1.228-1.857-1.446-4.03-1.958-6.333-2-1.375-.026-2.735-.128-4.031-.61-.595-.22-1.26-.505-1.244-1.272.015-.78.693-1 1.31-1.184.505-.15 1.026-.247 1.6-.382-1.46-.936-2.886-1.065-4.787-.3-2.993 1.202-5.943 1.06-8.926-.017-1.684-.608-3.179-1.563-4.735-2.408l-.077.057c1.29 2.115 3.034 3.817 5.004 5.271 3.793 2.8 7.936 4.471 12.784 3.73A66.714 66.714 0 0 1 37 40.877c1.98-.16 3.866.398 5.753.899Zm-9.14-30.345c-.105-.076-.206-.266-.42-.069 1.745 2.36 3.985 4.098 6.683 5.193 4.354 1.767 8.773 2.07 13.293.51 3.51-1.21 6.033-.028 7.343 3.38.19-3.955-2.137-6.837-5.843-7.401-2.084-.318-4.01.373-5.962.94-5.434 1.575-10.485.798-15.094-2.553Zm27.085 15.425c.708.059 1.416.123 2.124.185-1.6-1.405-3.55-1.517-5.523-1.404-3.003.17-5.167 1.903-7.14 3.972-1.739 1.824-3.31 3.87-5.903 4.604.043.078.054.117.066.117.35.005.699.021 1.047.005 3.768-.17 7.317-.965 10.14-3.7.89-.86 1.685-1.817 2.544-2.71.716-.746 1.584-1.159 2.645-1.07Zm-8.753-4.67c-2.812.246-5.254 1.409-7.548 2.943-1.766 1.18-3.654 1.738-5.776 1.37-.374-.066-.75-.114-1.124-.17l-.013.156c.135.07.265.151.405.207.354.14.702.308 1.07.395 4.083.971 7.992.474 11.516-1.803 2.221-1.435 4.521-1.707 7.013-1.336.252.038.503.083.756.107.234.022.479.255.795.003-2.179-1.574-4.526-2.096-7.094-1.872Zm-10.049-9.544c1.475.051 2.943-.142 4.486-1.059-.452.04-.643.04-.827.076-2.126.424-4.033-.04-5.733-1.383-.623-.493-1.257-.974-1.889-1.457-2.503-1.914-5.374-2.555-8.514-2.5.05.154.054.26.108.315 3.417 3.455 7.371 5.836 12.369 6.008Zm24.727 17.731c-2.114-2.097-4.952-2.367-7.578-.537 1.738.078 3.043.632 4.101 1.728a13 13 0 0 0 1.182 1.106c1.6 1.29 4.311 1.352 5.896.155-1.861-.726-1.861-.726-3.601-2.452Zm-21.058 16.06c-1.858-3.46-4.981-4.24-8.59-4.008a9.667 9.667 0 0 1 2.977 1.39c.84.586 1.547 1.311 2.243 2.055 1.38 1.473 3.534 2.376 4.962 2.07-.656-.412-1.238-.848-1.592-1.507Zl-.006.006-.036-.004.021.018.012.053Za.127.127 0 0 0 .015.043c.005.008.038 0 .058-.002Zl-.008.01.005.026.024.014Z"
|
||||
fill="#FD4F00"
|
||||
/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.0 KiB |
@ -1,5 +1,5 @@
|
||||
# See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file
|
||||
#
|
||||
# To ban all spiders from the entire site uncomment the next two lines:
|
||||
# User-agent: *
|
||||
# Disallow: /
|
||||
User-agent: *
|
||||
Disallow: /
|
||||
|
||||
97
test/beet_round_server/biddings_test.exs
Normal file
@ -0,0 +1,97 @@
|
||||
defmodule BeetRoundServer.BiddingsTest do
|
||||
use BeetRoundServer.DataCase
|
||||
|
||||
alias BeetRoundServer.Biddings
|
||||
|
||||
describe "biddings" do
|
||||
alias BeetRoundServer.Biddings.Bidding
|
||||
|
||||
import BeetRoundServer.AccountsFixtures, only: [user_scope_fixture: 0]
|
||||
import BeetRoundServer.BiddingsFixtures
|
||||
|
||||
@invalid_attrs %{amount: nil, bidding_round: nil, depot_wish_one: nil, depot_wish_two: nil}
|
||||
|
||||
test "list_biddings/1 returns all scoped biddings" do
|
||||
scope = user_scope_fixture()
|
||||
other_scope = user_scope_fixture()
|
||||
bidding = bidding_fixture(scope)
|
||||
other_bidding = bidding_fixture(other_scope)
|
||||
assert Biddings.list_biddings(scope) == [bidding]
|
||||
assert Biddings.list_biddings(other_scope) == [other_bidding]
|
||||
end
|
||||
|
||||
test "get_bidding!/2 returns the bidding with given id" do
|
||||
scope = user_scope_fixture()
|
||||
bidding = bidding_fixture(scope)
|
||||
other_scope = user_scope_fixture()
|
||||
assert Biddings.get_bidding!(scope, bidding.id) == bidding
|
||||
assert_raise Ecto.NoResultsError, fn -> Biddings.get_bidding!(other_scope, bidding.id) end
|
||||
end
|
||||
|
||||
test "create_bidding/2 with valid data creates a bidding" do
|
||||
valid_attrs = %{amount: 42, bidding_round: 42, depot_wish_one: "some depot_wish_one", depot_wish_two: "some depot_wish_two"}
|
||||
scope = user_scope_fixture()
|
||||
|
||||
assert {:ok, %Bidding{} = bidding} = Biddings.create_bidding(scope, valid_attrs)
|
||||
assert bidding.amount == 42
|
||||
assert bidding.bidding_round == 42
|
||||
assert bidding.depot_wish_one == "some depot_wish_one"
|
||||
assert bidding.depot_wish_two == "some depot_wish_two"
|
||||
assert bidding.user_id == scope.user.id
|
||||
end
|
||||
|
||||
test "create_bidding/2 with invalid data returns error changeset" do
|
||||
scope = user_scope_fixture()
|
||||
assert {:error, %Ecto.Changeset{}} = Biddings.create_bidding(scope, @invalid_attrs)
|
||||
end
|
||||
|
||||
test "update_bidding/3 with valid data updates the bidding" do
|
||||
scope = user_scope_fixture()
|
||||
bidding = bidding_fixture(scope)
|
||||
update_attrs = %{amount: 43, bidding_round: 43, depot_wish_one: "some updated depot_wish_one", depot_wish_two: "some updated depot_wish_two"}
|
||||
|
||||
assert {:ok, %Bidding{} = bidding} = Biddings.update_bidding(scope, bidding, update_attrs)
|
||||
assert bidding.amount == 43
|
||||
assert bidding.bidding_round == 43
|
||||
assert bidding.depot_wish_one == "some updated depot_wish_one"
|
||||
assert bidding.depot_wish_two == "some updated depot_wish_two"
|
||||
end
|
||||
|
||||
test "update_bidding/3 with invalid scope raises" do
|
||||
scope = user_scope_fixture()
|
||||
other_scope = user_scope_fixture()
|
||||
bidding = bidding_fixture(scope)
|
||||
|
||||
assert_raise MatchError, fn ->
|
||||
Biddings.update_bidding(other_scope, bidding, %{})
|
||||
end
|
||||
end
|
||||
|
||||
test "update_bidding/3 with invalid data returns error changeset" do
|
||||
scope = user_scope_fixture()
|
||||
bidding = bidding_fixture(scope)
|
||||
assert {:error, %Ecto.Changeset{}} = Biddings.update_bidding(scope, bidding, @invalid_attrs)
|
||||
assert bidding == Biddings.get_bidding!(scope, bidding.id)
|
||||
end
|
||||
|
||||
test "delete_bidding/2 deletes the bidding" do
|
||||
scope = user_scope_fixture()
|
||||
bidding = bidding_fixture(scope)
|
||||
assert {:ok, %Bidding{}} = Biddings.delete_bidding(scope, bidding)
|
||||
assert_raise Ecto.NoResultsError, fn -> Biddings.get_bidding!(scope, bidding.id) end
|
||||
end
|
||||
|
||||
test "delete_bidding/2 with invalid scope raises" do
|
||||
scope = user_scope_fixture()
|
||||
other_scope = user_scope_fixture()
|
||||
bidding = bidding_fixture(scope)
|
||||
assert_raise MatchError, fn -> Biddings.delete_bidding(other_scope, bidding) end
|
||||
end
|
||||
|
||||
test "change_bidding/2 returns a bidding changeset" do
|
||||
scope = user_scope_fixture()
|
||||
bidding = bidding_fixture(scope)
|
||||
assert %Ecto.Changeset{} = Biddings.change_bidding(scope, bidding)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -0,0 +1,84 @@
|
||||
defmodule BeetRoundServerWeb.UserControllerTest do
|
||||
use BeetRoundServerWeb.ConnCase
|
||||
|
||||
import BeetRoundServer.AccountsFixtures
|
||||
alias BeetRoundServer.Accounts.User
|
||||
|
||||
@create_attrs %{
|
||||
email: "some email"
|
||||
}
|
||||
@update_attrs %{
|
||||
email: "some updated email"
|
||||
}
|
||||
@invalid_attrs %{email: nil}
|
||||
|
||||
setup %{conn: conn} do
|
||||
{:ok, conn: put_req_header(conn, "accept", "application/json")}
|
||||
end
|
||||
|
||||
describe "index" do
|
||||
test "lists all users", %{conn: conn} do
|
||||
conn = get(conn, ~p"/api/users")
|
||||
assert json_response(conn, 200)["data"] == []
|
||||
end
|
||||
end
|
||||
|
||||
describe "create user" do
|
||||
test "renders user when data is valid", %{conn: conn} do
|
||||
conn = post(conn, ~p"/api/users", user: @create_attrs)
|
||||
assert %{"id" => id} = json_response(conn, 201)["data"]
|
||||
|
||||
conn = get(conn, ~p"/api/users/#{id}")
|
||||
|
||||
assert %{
|
||||
"id" => ^id,
|
||||
"email" => "some email"
|
||||
} = json_response(conn, 200)["data"]
|
||||
end
|
||||
|
||||
test "renders errors when data is invalid", %{conn: conn} do
|
||||
conn = post(conn, ~p"/api/users", user: @invalid_attrs)
|
||||
assert json_response(conn, 422)["errors"] != %{}
|
||||
end
|
||||
end
|
||||
|
||||
describe "update user" do
|
||||
setup [:create_user]
|
||||
|
||||
test "renders user when data is valid", %{conn: conn, user: %User{id: id} = user} do
|
||||
conn = put(conn, ~p"/api/users/#{user}", user: @update_attrs)
|
||||
assert %{"id" => ^id} = json_response(conn, 200)["data"]
|
||||
|
||||
conn = get(conn, ~p"/api/users/#{id}")
|
||||
|
||||
assert %{
|
||||
"id" => ^id,
|
||||
"email" => "some updated email"
|
||||
} = json_response(conn, 200)["data"]
|
||||
end
|
||||
|
||||
test "renders errors when data is invalid", %{conn: conn, user: user} do
|
||||
conn = put(conn, ~p"/api/users/#{user}", user: @invalid_attrs)
|
||||
assert json_response(conn, 422)["errors"] != %{}
|
||||
end
|
||||
end
|
||||
|
||||
describe "delete user" do
|
||||
setup [:create_user]
|
||||
|
||||
test "deletes chosen user", %{conn: conn, user: user} do
|
||||
conn = delete(conn, ~p"/api/users/#{user}")
|
||||
assert response(conn, 204)
|
||||
|
||||
assert_error_sent 404, fn ->
|
||||
get(conn, ~p"/api/users/#{user}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defp create_user(_) do
|
||||
user = user_fixture()
|
||||
|
||||
%{user: user}
|
||||
end
|
||||
end
|
||||
125
test/beet_round_server_web/live/bidding_live_test.exs
Normal file
@ -0,0 +1,125 @@
|
||||
defmodule BeetRoundServerWeb.BiddingLiveTest do
|
||||
use BeetRoundServerWeb.ConnCase
|
||||
|
||||
import Phoenix.LiveViewTest
|
||||
import BeetRoundServer.BiddingsFixtures
|
||||
|
||||
@create_attrs %{amount: 42, bidding_round: 42, depot_wish_one: "some depot_wish_one", depot_wish_two: "some depot_wish_two"}
|
||||
@update_attrs %{amount: 43, bidding_round: 43, depot_wish_one: "some updated depot_wish_one", depot_wish_two: "some updated depot_wish_two"}
|
||||
@invalid_attrs %{amount: nil, bidding_round: nil, depot_wish_one: nil, depot_wish_two: nil}
|
||||
|
||||
setup :register_and_log_in_user
|
||||
|
||||
defp create_bidding(%{scope: scope}) do
|
||||
bidding = bidding_fixture(scope)
|
||||
|
||||
%{bidding: bidding}
|
||||
end
|
||||
|
||||
describe "Index" do
|
||||
setup [:create_bidding]
|
||||
|
||||
test "lists all biddings", %{conn: conn, bidding: bidding} do
|
||||
{:ok, _index_live, html} = live(conn, ~p"/biddings")
|
||||
|
||||
assert html =~ "Listing Biddings"
|
||||
assert html =~ bidding.depot_wish_one
|
||||
end
|
||||
|
||||
test "saves new bidding", %{conn: conn} do
|
||||
{:ok, index_live, _html} = live(conn, ~p"/biddings")
|
||||
|
||||
assert {:ok, form_live, _} =
|
||||
index_live
|
||||
|> element("a", "New Bidding")
|
||||
|> render_click()
|
||||
|> follow_redirect(conn, ~p"/biddings/new")
|
||||
|
||||
assert render(form_live) =~ "New Bidding"
|
||||
|
||||
assert form_live
|
||||
|> form("#bidding-form", bidding: @invalid_attrs)
|
||||
|> render_change() =~ "can't be blank"
|
||||
|
||||
assert {:ok, index_live, _html} =
|
||||
form_live
|
||||
|> form("#bidding-form", bidding: @create_attrs)
|
||||
|> render_submit()
|
||||
|> follow_redirect(conn, ~p"/biddings")
|
||||
|
||||
html = render(index_live)
|
||||
assert html =~ "Bidding created successfully"
|
||||
assert html =~ "some depot_wish_one"
|
||||
end
|
||||
|
||||
test "updates bidding in listing", %{conn: conn, bidding: bidding} do
|
||||
{:ok, index_live, _html} = live(conn, ~p"/biddings")
|
||||
|
||||
assert {:ok, form_live, _html} =
|
||||
index_live
|
||||
|> element("#biddings-#{bidding.id} a", "Edit")
|
||||
|> render_click()
|
||||
|> follow_redirect(conn, ~p"/biddings/#{bidding}/edit")
|
||||
|
||||
assert render(form_live) =~ "Edit Bidding"
|
||||
|
||||
assert form_live
|
||||
|> form("#bidding-form", bidding: @invalid_attrs)
|
||||
|> render_change() =~ "can't be blank"
|
||||
|
||||
assert {:ok, index_live, _html} =
|
||||
form_live
|
||||
|> form("#bidding-form", bidding: @update_attrs)
|
||||
|> render_submit()
|
||||
|> follow_redirect(conn, ~p"/biddings")
|
||||
|
||||
html = render(index_live)
|
||||
assert html =~ "Bidding updated successfully"
|
||||
assert html =~ "some updated depot_wish_one"
|
||||
end
|
||||
|
||||
test "deletes bidding in listing", %{conn: conn, bidding: bidding} do
|
||||
{:ok, index_live, _html} = live(conn, ~p"/biddings")
|
||||
|
||||
assert index_live |> element("#biddings-#{bidding.id} a", "Delete") |> render_click()
|
||||
refute has_element?(index_live, "#biddings-#{bidding.id}")
|
||||
end
|
||||
end
|
||||
|
||||
describe "Show" do
|
||||
setup [:create_bidding]
|
||||
|
||||
test "displays bidding", %{conn: conn, bidding: bidding} do
|
||||
{:ok, _show_live, html} = live(conn, ~p"/biddings/#{bidding}")
|
||||
|
||||
assert html =~ "Show Bidding"
|
||||
assert html =~ bidding.depot_wish_one
|
||||
end
|
||||
|
||||
test "updates bidding and returns to show", %{conn: conn, bidding: bidding} do
|
||||
{:ok, show_live, _html} = live(conn, ~p"/biddings/#{bidding}")
|
||||
|
||||
assert {:ok, form_live, _} =
|
||||
show_live
|
||||
|> element("a", "Edit")
|
||||
|> render_click()
|
||||
|> follow_redirect(conn, ~p"/biddings/#{bidding}/edit?return_to=show")
|
||||
|
||||
assert render(form_live) =~ "Edit Bidding"
|
||||
|
||||
assert form_live
|
||||
|> form("#bidding-form", bidding: @invalid_attrs)
|
||||
|> render_change() =~ "can't be blank"
|
||||
|
||||
assert {:ok, show_live, _html} =
|
||||
form_live
|
||||
|> form("#bidding-form", bidding: @update_attrs)
|
||||
|> render_submit()
|
||||
|> follow_redirect(conn, ~p"/biddings/#{bidding}")
|
||||
|
||||
html = render(show_live)
|
||||
assert html =~ "Bidding updated successfully"
|
||||
assert html =~ "some updated depot_wish_one"
|
||||
end
|
||||
end
|
||||
end
|
||||
22
test/support/fixtures/biddings_fixtures.ex
Normal file
@ -0,0 +1,22 @@
|
||||
defmodule BeetRoundServer.BiddingsFixtures do
|
||||
@moduledoc """
|
||||
This module defines test helpers for creating
|
||||
entities via the `BeetRoundServer.Biddings` context.
|
||||
"""
|
||||
|
||||
@doc """
|
||||
Generate a bidding.
|
||||
"""
|
||||
def bidding_fixture(scope, attrs \\ %{}) do
|
||||
attrs =
|
||||
Enum.into(attrs, %{
|
||||
amount: 42,
|
||||
bidding_round: 42,
|
||||
depot_wish_one: "some depot_wish_one",
|
||||
depot_wish_two: "some depot_wish_two"
|
||||
})
|
||||
|
||||
{:ok, bidding} = BeetRoundServer.Biddings.create_bidding(scope, attrs)
|
||||
bidding
|
||||
end
|
||||
end
|
||||