basic admin endgame view and add

This commit is contained in:
2026-06-22 20:43:09 +02:00
parent e955e40930
commit 006a2ca1c5
82 changed files with 2031 additions and 2 deletions
@@ -0,0 +1,55 @@
defmodule ChesstrainerWeb.Board.BoardComponent do
@moduledoc """
Chess board component
"""
use Phoenix.Component
import ChesstrainerWeb.Board.SquareComponent
attr :game, :map, required: true
attr :myself, :any, required: true
def board(assigns) do
files_list = [:a, :b, :c, :d, :e, :f, :g, :h]
assigns =
assigns
|> assign(:files_list, files_list)
|> assign(
:files,
case assigns.game.orientation do
:white -> files_list
:black -> Enum.reverse(files_list)
end
)
|> assign(
:ranks,
case assigns.game.orientation do
:white -> Enum.reverse(1..8)
:black -> 1..8
end
)
~H"""
<div class="w-[388px] m-auto left-0 right-0 mt-6">
<div class="border border-2 border-zinc-700 grid grid-rows-8 grid-cols-8">
<%= for rank <- @ranks do %>
<%= for file <- @files do %>
<% square = {file, rank} %>
<% piece = Map.get(@game.board, square) %>
<.square
file={file}
rank={rank}
piece={piece}
files_list={@files_list}
move_from_square={@game.move_from_square}
myself={@myself}
/>
<% end %>
<% end %>
</div>
</div>
"""
end
end
@@ -0,0 +1,33 @@
defmodule ChesstrainerWeb.Board.PieceComponent do
@moduledoc """
Chess pieces component
"""
use Phoenix.Component
attr :piece, :any, required: true
attr :class, :string, default: ""
def piece(assigns) do
assigns = assign(assigns, :path, piece_path(assigns.piece))
~H"""
<%= if @path do %>
<img src={@path} class={@class} />
<% end %>
"""
end
def piece_path({:king, :white, _square}), do: "/images/pieces/white/king.svg"
def piece_path({:queen, :white, _square}), do: "/images/pieces/white/queen.svg"
def piece_path({:rook, :white, _square}), do: "/images/pieces/white/rook.svg"
def piece_path({:bishop, :white, _square}), do: "/images/pieces/white/bishop.svg"
def piece_path({:knight, :white, _square}), do: "/images/pieces/white/knight.svg"
def piece_path({:pawn, :white, _square}), do: "/images/pieces/white/pawn.svg"
def piece_path({:king, :black, _square}), do: "/images/pieces/black/king.svg"
def piece_path({:queen, :black, _square}), do: "/images/pieces/black/queen.svg"
def piece_path({:rook, :black, _square}), do: "/images/pieces/black/rook.svg"
def piece_path({:bishop, :black, _square}), do: "/images/pieces/black/bishop.svg"
def piece_path({:knight, :black, _square}), do: "/images/pieces/black/knight.svg"
def piece_path({:pawn, :black, _square}), do: "/images/pieces/black/pawn.svg"
def piece_path(_), do: nil
end
@@ -0,0 +1,48 @@
defmodule ChesstrainerWeb.Board.SquareComponent do
@moduledoc """
Renders a single chess square with optional piece and highlighting.
"""
use Phoenix.Component
import ChesstrainerWeb.Board.PieceComponent
attr :file, :atom, required: true
attr :rank, :integer, required: true
attr :piece, :any, default: nil
attr :files_list, :list, required: true
attr :move_from_square, :any, default: nil
attr :myself, :any, required: true
def square(assigns) do
current_square = {assigns.file, assigns.rank}
assigns =
assigns
|> assign(:highlight_square, current_square === assigns.move_from_square)
~H"""
<div
class={[
"w-12 h-12 flex items-center justify-center",
background(
Enum.find_index(@files_list, fn f -> f == @file end),
@rank - 1
),
highlight_square(@highlight_square)
]}
phx-click="square-click"
phx-value-file={@file}
phx-value-rank={@rank}
phx-value-type="move"
phx-target={@myself}
>
<.piece piece={@piece} class="w-10 h-10" />
</div>
"""
end
def background(file_idx, rank_idx) when rem(file_idx + rank_idx, 2) != 0, do: "bg-boardwhite"
def background(_, _), do: "bg-boardblack"
def highlight_square(true), do: "ring-inset ring-2 ring-yellow-400"
def highlight_square(false), do: ""
end