Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions lib/ares_web/components/core_components.ex
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,77 @@ defmodule AresWeb.CoreComponents do
alias Phoenix.HTML.Form
alias Phoenix.LiveView.JS

@doc """
Renders a modal.

## Examples

<.modal id="confirm-modal">
This is a modal.
</.modal>

JS commands may be passed to the `:on_cancel` to configure
the closing/cancel event, for example:

<.modal id="confirm" on_cancel={JS.navigate(~p"/posts")}>
This is another modal.
</.modal>

"""
attr :id, :string, required: true
attr :show, :boolean, default: false
attr :wrapper_class, :string, default: ""
attr :on_cancel, JS, default: %JS{}
slot :inner_block, required: true

def modal(assigns) do
~H"""
<div
id={@id}
phx-mounted={@show && show_modal(@id)}
phx-remove={hide_modal(@id)}
data-cancel={JS.exec(@on_cancel, "phx-remove")}
class="relative z-50 hidden"
>
<div id={"#{@id}-bg"} class="bg-black/90 fixed inset-0 transition-opacity" aria-hidden="true" />
<div
class={"fixed inset-0 overflow-y-auto #{@wrapper_class}"}
aria-labelledby={"#{@id}-title"}
aria-describedby={"#{@id}-description"}
role="dialog"
aria-modal="true"
tabindex="0"
>
<div class="flex min-h-full items-center justify-center m-4">
<div class="w-full max-w-xl">
<.focus_wrap
id={"#{@id}-container"}
phx-window-keydown={JS.exec("data-cancel", to: "##{@id}")}
phx-key="escape"
phx-click-away={JS.exec("data-cancel", to: "##{@id}")}
class="p-6 bg-[#0A0A0A] border border-zinc-800 text-white shadow-2xl shadow-primary/10 relative rounded-2xl transition"
>
<div class="absolute top-6 right-5">
<button
phx-click={JS.exec("data-cancel", to: "##{@id}")}
type="button"
class="-m-3 flex-none p-3 opacity-20 text-white black:text-black cursor-pointer hover:opacity-40"
aria-label={gettext("close")}
>
<.icon name="hero-x-mark-solid" class="h-5 w-5" />
</button>
</div>
<div id={"#{@id}-content"}>
{render_slot(@inner_block)}
</div>
</.focus_wrap>
</div>
</div>
</div>
</div>
"""
end

@doc """
Renders flash notices.

Expand Down Expand Up @@ -443,6 +514,30 @@ defmodule AresWeb.CoreComponents do
)
end

def show_modal(js \\ %JS{}, id) when is_binary(id) do
js
|> JS.show(to: "##{id}")
|> JS.show(
to: "##{id}-bg",
transition: {"transition-all transform ease-out duration-300", "opacity-0", "opacity-100"}
)
|> show("##{id}-container")
|> JS.add_class("overflow-hidden", to: "body")
|> JS.focus_first(to: "##{id}-content")
end

def hide_modal(js \\ %JS{}, id) do
js
|> JS.hide(
to: "##{id}-bg",
transition: {"transition-all transform ease-in duration-200", "opacity-100", "opacity-0"}
)
|> hide("##{id}-container")
|> JS.hide(to: "##{id}", transition: {"block", "block", "hidden"})
|> JS.remove_class("overflow-hidden", to: "body")
|> JS.pop_focus()
end

@doc """
Translates an error message using gettext.
"""
Expand Down
2 changes: 1 addition & 1 deletion lib/ares_web/components/layouts/root.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -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="Ares" suffix="">
<.live_title default="BugsByte" suffix="">
{assigns[:page_title]}
</.live_title>
<link phx-track-static rel="stylesheet" href={~p"/assets/css/app.css"} />
Expand Down
30 changes: 22 additions & 8 deletions lib/ares_web/components/navbar.ex
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,14 @@ defmodule AresWeb.Components.Navbar do
Previous edition
</.link>
</li>
<li>
<%!-- <li>
<.link
class="hover:text-primary transition-colors"
navigate="/app/team-formation"
>
Teams
</.link>
</li>
</li> --%>
<%= if @user && @user.is_admin do %>
<li>
<.link
Expand Down Expand Up @@ -94,19 +94,25 @@ defmodule AresWeb.Components.Navbar do
>
View Profile
</.link>
<.link
navigate="/users/settings"
class="block px-4 py-2 text-black hover:bg-gray-300 rounded-t-lg transition-colors"
>
Settings
</.link>
<.link href="/users/log-out" method="delete" class="border-t border-gray-700">
<p class="w-full text-left px-4 py-2 text-black hover:bg-gray-300 rounded-b-lg transition-colors cursor-pointer">
Log out
</p>
</.link>
</div>
<% else %>
<.link
<%!-- <.link
navigate="/register"
class="rounded-full px-3 py-2 text-sm font-semibold text-white shadow-sm ring-1 ring-inset ring-white hover:ring-primary hover:text-primary transition-all"
>
Register
</.link>
</.link> --%>
<% end %>
</li>
</ul>
Expand Down Expand Up @@ -177,12 +183,12 @@ defmodule AresWeb.Components.Navbar do
Profile
</.link>
<% else %>
<a
<%!-- <.link
class="block py-3 sm:py-4 text-center text-lg sm:text-xl hover:text-primary transition-colors"
href="/register"
>
Register
</a>
</.link> --%>
<% end %>
</li>
<%= if @user do %>
Expand All @@ -196,6 +202,14 @@ defmodule AresWeb.Components.Navbar do
</.link>
</li>
<% end %>
<li>
<.link
navigate="/users/settings"
class="block w-full py-3 sm:py-4 text-center text-lg sm:text-xl hover:text-primary transition-colors"
>
Settings
</.link>
</li>
<li>
<.link
href="/users/log-out"
Expand Down Expand Up @@ -238,14 +252,14 @@ defmodule AresWeb.Components.Navbar do
Previous edition
</.link>
</li>
<li>
<%!-- <li>
<.link
class="block py-3 sm:py-4 text-center text-lg sm:text-xl hover:text-primary transition-colors"
navigate="/app/team-formation"
>
Team formation
</.link>
</li>
</li> --%>
</ul>
</nav>
</div>
Expand Down
68 changes: 66 additions & 2 deletions lib/ares_web/live/app/team-formation.ex
Original file line number Diff line number Diff line change
Expand Up @@ -186,10 +186,9 @@ defmodule AresWeb.AppLive.TeamFormation do

<div class="flex items-center font-inter">
<.button
phx-click="join-team"
phx-click="open-join-modal"
class="btn btn-primary flex items-center"
phx-value-team_code={team.code}
data-confirm={"Are you sure you want to join #{team.name}?"}
>
<.icon name="hero-user-plus" class="w-5 h-5 mr-2" /> Join
</.button>
Expand Down Expand Up @@ -276,6 +275,42 @@ defmodule AresWeb.AppLive.TeamFormation do
</div>
</div>
</div>

<.modal
:if={@live_action == :join}
id="join-team-modal"
show
on_cancel={JS.patch(~p"/app/team-formation?#{[tab: @tab]}")}
>
<div class="space-y-8 flex flex-col items-center">
<div class="p-4 rounded-full border-2 border-primary">
<span class="hero-users text-primary size-6" />
</div>
<div class="space-y-2 text-center">
<h2 class="text-2xl font-resegrg">Join Team?</h2>
<p class="text-xl">
You are about to join <span class="text-primary font-bold">{@selected_team.name}</span>. Confirm that this is the team you want to participate with.
</p>
</div>
<div class="flex flex-col gap-4 sm:flex-row w-full">
<button
type="button"
phx-click="join-team"
phx-value-team_code={@selected_team.code}
class="cursor-pointer bg-primary w-full sm:w-1/2 text-white py-2 px-6 rounded-lg hover:bg-primary/50 transition-colors"
>
Join Team
</button>
<button
type="button"
phx-click={JS.patch(~p"/app/team-formation?#{[tab: @tab]}")}
class="cursor-pointer bg-gray-600 w-full sm:w-1/2 text-white py-2 px-6 rounded-lg hover:bg-gray-500 transition-colors"
>
Cancel
</button>
</div>
</div>
</.modal>
</Layouts.app>
"""
end
Expand Down Expand Up @@ -314,6 +349,25 @@ defmodule AresWeb.AppLive.TeamFormation do
|> assign_form(Teams.change_team(%Teams.Team{}, %{}))}
end

@impl true
def handle_params(params, _url, socket) do
{:noreply, apply_action(socket, socket.assigns.live_action, params)}
end

defp apply_action(socket, :index, params) do
tab = Map.get(params, "tab", "create")

socket
|> assign(:tab, tab)
end

defp apply_action(socket, :join, params) do
tab = Map.get(params, "tab", "join")

socket
|> assign(:tab, tab)
end

@impl true
def handle_event("save", %{"team" => team_params}, socket) do
case Teams.create_and_join_team(socket.assigns.user, team_params) do
Expand Down Expand Up @@ -353,6 +407,16 @@ defmodule AresWeb.AppLive.TeamFormation do
end
end

@impl true
def handle_event("open-join-modal", %{"team_code" => team_code}, socket) do
selected_team = Enum.find(socket.assigns.available_teams, &(&1.code == team_code))

{:noreply,
socket
|> assign(:selected_team, selected_team)
|> push_patch(to: ~p"/app/team-formation/join?#{[tab: socket.assigns.tab]}")}
end

@impl true
def handle_event("join-team", %{"team_code" => team_code}, socket) do
case Teams.add_user_to_team_by_code(socket.assigns.user, team_code) do
Expand Down
2 changes: 1 addition & 1 deletion lib/ares_web/live/auth/login.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ defmodule AresWeb.UserLive.Login do
<% else %>
<p class="text-2xl">
Don't have an account? <.link
navigate={~p"/register"}
navigate="/register"
class="font-semibold text-primary hover:underline"
phx-no-format
>Register</.link> to participate now.
Expand Down
Loading