Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: create staff #488

Merged
merged 5 commits into from
Feb 8, 2025
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
38 changes: 32 additions & 6 deletions lib/safira/accounts.ex
Original file line number Diff line number Diff line change
Expand Up @@ -182,15 +182,16 @@ defmodule Safira.Accounts do
|> Flop.validate_and_run(params, for: User)
end

def update_staff(%Staff{} = staff, attrs) do
Staff.changeset(staff, attrs)
def update_user(%User{} = user, attrs) do
user
|> User.changeset(attrs)
|> Repo.update()
end

@doc """
Changes a staff
"""
def change_staff(%Staff{} = staff, attrs) do
def change_staff(%Staff{} = staff, attrs \\ %{}) do
Staff.changeset(staff, attrs)
end

Expand Down Expand Up @@ -289,9 +290,34 @@ defmodule Safira.Accounts do

"""
def register_staff_user(attrs) do
%User{}
|> User.registration_changeset(attrs |> Map.put(:type, :staff))
|> Repo.insert()
attrs = attrs |> Map.put("type", :staff)

Ecto.Multi.new()
|> Ecto.Multi.insert(
:user,
User.registration_changeset(
%User{},
Map.delete(attrs, "staff"),
hash_password: true,
validate_email: true
)
)
|> Ecto.Multi.insert(
:staff,
fn %{user: user} ->
staff_attrs =
attrs
|> Map.get("staff")
|> Map.put("user_id", user.id)

Staff.changeset(%Staff{}, staff_attrs)
end
)
|> Ecto.Multi.update(
:new_user,
fn %{user: user} -> User.confirm_changeset(user) end
)
|> Repo.transaction()
end

@doc """
Expand Down
5 changes: 3 additions & 2 deletions lib/safira/accounts/staff.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ defmodule Safira.Accounts.Staff do
"""
use Safira.Schema

alias Safira.Accounts.User

@required_fields ~w(user_id role_id)a
@optional_fields ~w()a

schema "staffs" do
belongs_to :user, Safira.Accounts.User
belongs_to :user, User
belongs_to :role, Safira.Accounts.Role

timestamps(type: :utc_datetime)
Expand All @@ -17,7 +19,6 @@ defmodule Safira.Accounts.Staff do
def changeset(staff, attrs) do
staff
|> cast(attrs, @required_fields ++ @optional_fields)
|> cast_assoc(:user)
|> validate_required(@required_fields)
end
end
14 changes: 13 additions & 1 deletion lib/safira/accounts/user.ex
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ defmodule Safira.Accounts.User do
field :allows_marketing, :boolean, default: false

has_one :attendee, Attendee, on_delete: :delete_all
has_one :staff, Staff, on_delete: :delete_all
has_one :staff, Staff, on_delete: :delete_all, on_replace: :update
has_one :company, Company, on_delete: :delete_all

timestamps(type: :utc_datetime)
Expand Down Expand Up @@ -81,6 +81,18 @@ defmodule Safira.Accounts.User do
|> validate_handle()
|> validate_password(opts)
|> cast_assoc(:attendee, with: &Attendee.changeset/2)
|> cast_assoc(:staff, with: &Staff.changeset/2)
end

def changeset(user, attrs, opts \\ []) do
user
|> cast(attrs, @required_fields ++ @optional_fields)
|> validate_required(@required_fields |> Enum.reject(&(&1 in [:email, :password, :handle])))
|> validate_email(opts)
|> validate_handle()
|> validate_length(:password, min: 12, max: 72)
|> cast_assoc(:attendee, with: &Attendee.changeset/2)
|> cast_assoc(:staff, with: &Staff.changeset/2)
end

@doc """
Expand Down
20 changes: 7 additions & 13 deletions lib/safira/release.ex
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,13 @@ defmodule Safira.Release do
end

# Create user
case Safira.Accounts.register_staff_user(%{
name: name,
email: email,
password: password,
handle: handle
}) do
{:ok, user} ->
# Assign role to user
Safira.Accounts.create_staff(%{user_id: user.id, role_id: role.id})

{:error, changeset} ->
{:error, changeset}
end
Safira.Accounts.register_staff_user(%{
name: name,
email: email,
password: password,
handle: handle,
role_id: role.id
})
end

defp repos do
Expand Down
73 changes: 47 additions & 26 deletions lib/safira_web/live/backoffice/staff_live/form_component.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ defmodule SafiraWeb.Backoffice.StaffLive.FormComponent do

import SafiraWeb.Components.Forms
alias Safira.Accounts
alias Safira.Roles
alias Safira.Accounts.User
alias Safira.Repo

@impl true
def render(assigns) do
Expand All @@ -19,7 +20,18 @@ defmodule SafiraWeb.Backoffice.StaffLive.FormComponent do
>
<div class="flex flex-col md:flex-row w-full gap-4">
<div class="w-full space-y-2">
<.field field={@form[:role_id]} type="select" label="Role" options={@roles} required />
<.field field={@form[:name]} type="text" label="Name" required />
<.field field={@form[:email]} type="email" label="Email" required />
<.field
field={@form[:password]}
type="password"
label="Password"
required={@action == :new}
/>
<.field field={@form[:handle]} type="text" label="Handle" required />
<.inputs_for :let={u} field={@form[:staff]}>
<.field field={u[:role_id]} type="select" label="Role" options={@roles} required />
</.inputs_for>
</div>
</div>
<:actions>
Expand All @@ -33,41 +45,51 @@ defmodule SafiraWeb.Backoffice.StaffLive.FormComponent do

@impl true
def mount(socket) do
roles =
Roles.list_roles()
|> Enum.map(&{&1.name, &1.id})

{:ok,
socket
|> assign(:roles, roles)}
{:ok, socket}
end

@impl true
def update(%{id: id} = assigns, socket) do
staff = Accounts.get_staff!(id)
change_staff = Accounts.change_staff(staff, %{})
form = to_form(change_staff, as: "staff")
def update(%{user: user} = assigns, socket) do
user = user |> Repo.preload(:staff)
user_changeset = Accounts.change_user_registration(user)

{:ok,
socket
|> assign(assigns)
|> assign(:staff, staff)
|> assign(:form, form)}
|> assign(:user, user)
|> assign(:form, to_form(user_changeset))}
end

@impl true
def handle_event("validate", %{"staff" => staff_params}, socket) do
{:noreply,
socket
|> assign_new(:form, fn ->
to_form(Accounts.change_staff(socket.assigns.staff, staff_params))
end)}
def handle_event("validate", %{"user" => user_params}, socket) do
changeset =
Accounts.change_user_registration(%User{}, user_params)

{:noreply, assign(socket, form: to_form(changeset, action: :validate))}
end

def handle_event("save", %{"staff" => staff_params}, socket) do
staff = socket.assigns.staff
def handle_event("save", %{"user" => user_params}, socket) do
save_staff(socket, socket.assigns.action, user_params)
end

case Accounts.update_staff(staff, staff_params) do
defp save_staff(socket, :new, user_params) do
case Accounts.register_staff_user(user_params) do
{:ok, _staff} ->
{:noreply,
socket
|> put_flash(:info, "Staff created successfully")
|> push_patch(to: socket.assigns.patch)}

{:error, _, %Ecto.Changeset{} = changeset, _} ->
{:noreply,
socket
|> put_flash(:error, gettext("Something went wrong while creating the staff."))
|> assign(:form, to_form(changeset, action: :validate))}
end
end

defp save_staff(socket, :edit, user_params) do
case Accounts.update_user(socket.assigns.user, user_params) do
{:ok, _staff} ->
{:noreply,
socket
Expand All @@ -78,8 +100,7 @@ defmodule SafiraWeb.Backoffice.StaffLive.FormComponent do
{:noreply,
socket
|> put_flash(:error, gettext("Something went wrong when updating the staff."))
|> assign(:form, to_form(changeset))
|> push_patch(to: socket.assigns.patch)}
|> assign(:form, to_form(changeset))}
end
end
end
42 changes: 41 additions & 1 deletion lib/safira_web/live/backoffice/staff_live/index.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@ defmodule SafiraWeb.Backoffice.StaffLive.Index do

import SafiraWeb.Components.{Table, TableSearch}

alias Safira.Accounts.User
alias Safira.Repo
alias Safira.Roles

on_mount {SafiraWeb.StaffRoles,
index: %{"staffs" => ["show"]},
new: %{"staffs" => ["edit"]},
edit: %{"staffs" => ["edit"]},
roles: %{"staffs" => ["roles_edit"]},
roles_edit: %{"staffs" => ["roles_edit"]},
Expand All @@ -32,7 +37,8 @@ defmodule SafiraWeb.Backoffice.StaffLive.Index do
|> assign(:meta, meta)
|> assign(:params, params)
|> assign(:current_page, :staffs)
|> assign(:staffs, staffs)}
|> assign(:staffs, staffs)
|> apply_action(socket.assigns.live_action, params)}

{:error, _} ->
{:noreply, socket}
Expand Down Expand Up @@ -67,4 +73,38 @@ defmodule SafiraWeb.Backoffice.StaffLive.Index do
_ -> Map.put(staff, :is_online, value)
end
end

defp apply_action(socket, :index, _params) do
socket
|> assign(:page_title, "Listing Staffs")
end

defp apply_action(socket, :new, _params) do
roles =
Roles.list_roles()
|> Enum.map(&{&1.name, &1.id})

socket
|> assign(:page_title, "New Staff")
|> assign(:user, %User{})
|> assign(:roles, roles)
end

defp apply_action(socket, :edit, %{"id" => id}) do
roles =
Roles.list_roles()
|> Enum.map(&{&1.name, &1.id})

staff = Accounts.get_staff!(id) |> Repo.preload(:user)
user = if staff.user, do: staff.user, else: %User{}

socket
|> assign(:page_title, "Edit Staff")
|> assign(:user, user)
|> assign(:roles, roles)
end

defp apply_action(socket, _live_action, _params) do
socket
end
end
Loading