lib/dashboard/user_list.ex

defmodule ZoonkWeb.Live.Dashboard.UserList do
  @moduledoc """
  Renders a list of users for a school based on their role.
  """
  use ZoonkWeb, :live_view

  alias Zoonk.Organizations

  @impl Phoenix.LiveView
  def mount(_params, _session, socket) do
    role = socket.assigns.live_action
    school = socket.assigns.school
    users = Organizations.list_school_users_by_role(school, role)
    can_demote_user? = length(users) > 1

    socket =
      socket
      |> assign(:page_title, get_page_title(role))
      |> stream(:users, users)
      |> assign(:can_demote_user?, can_demote_user?)

    {:ok, socket}
  end

  @impl Phoenix.LiveView
  def handle_event("approve", %{"school-user-id" => school_user_id}, socket) do
    approved_by_id = socket.assigns.current_user.id

    case Organizations.approve_school_user(school_user_id, approved_by_id) do
      {:ok, _school_user} ->
        socket =
          socket
          |> put_flash(:info, gettext("User approved!"))
          |> push_navigate(to: get_user_list_route(socket.assigns.live_action))

        {:noreply, socket}

      {:error, _changeset} ->
        {:noreply, put_flash(socket, :error, gettext("Could not approve user!"))}
    end
  end

  @impl Phoenix.LiveView
  def handle_event("reject", %{"school-user-id" => school_user_id}, socket) do
    case Organizations.delete_school_user(school_user_id) do
      {:ok, _school_user} ->
        socket =
          socket
          |> put_flash(:info, gettext("User rejected!"))
          |> push_navigate(to: get_user_list_route(socket.assigns.live_action))

        {:noreply, socket}

      {:error, _changeset} ->
        {:noreply, put_flash(socket, :error, gettext("Could not reject user!"))}
    end
  end

  @impl Phoenix.LiveView
  def handle_event("update-role", %{"school-user-id" => school_user_id, "role" => role}, socket) do
    case Organizations.change_school_user_role(school_user_id, role) do
      {:ok, _school_user} ->
        socket =
          socket
          |> put_flash(:info, dgettext("manager", "User role updated!"))
          |> push_navigate(to: get_user_list_route(socket.assigns.live_action))

        {:noreply, socket}

      {:error, _changeset} ->
        {:noreply, put_flash(socket, :error, dgettext("manager", "Could not update user role"))}
    end
  end

  @impl Phoenix.LiveView
  def handle_event("remove", %{"school-user-id" => school_user_id}, socket) do
    case Organizations.delete_school_user(school_user_id) do
      {:ok, _school_user} ->
        socket =
          socket
          |> put_flash(:info, gettext("User removed!"))
          |> push_navigate(to: get_user_list_route(socket.assigns.live_action))

        {:noreply, socket}

      {:error, _changeset} ->
        {:noreply, put_flash(socket, :error, gettext("Could not remove user!"))}
    end
  end

  defp get_user_list_route(:manager), do: ~p"/dashboard/managers"
  defp get_user_list_route(:teacher), do: ~p"/dashboard/teachers"
  defp get_user_list_route(:student), do: ~p"/dashboard/students"

  defp get_page_title(:manager), do: gettext("Managers")
  defp get_page_title(:teacher), do: gettext("Teachers")
  defp get_page_title(:student), do: gettext("Students")

  defp get_promote_label(role) do
    if role == :student,
      do: dgettext("manager", "Promote to teacher"),
      else: dgettext("manager", "Promote to manager")
  end
end