diff --git a/lib/atomic/accounts.ex b/lib/atomic/accounts.ex index a53cf0a8f..b451b0aca 100644 --- a/lib/atomic/accounts.ex +++ b/lib/atomic/accounts.ex @@ -472,6 +472,24 @@ defmodule Atomic.Accounts do |> Repo.update() end + @doc """ + Updates the user cv. + + ## Examples + + iex> update_user_cv(user, %{cv: ...}) + {:ok, %User{}} + + iex> update_user_cv(user, %{cv: ...}) + {:error, %Ecto.Changeset{}} + + """ + def update_user_cv(%User{} = user, attrs \\ %{}) do + user + |> User.cv_changeset(attrs) + |> Repo.update() + end + @doc """ Updates the user. @@ -484,10 +502,17 @@ defmodule Atomic.Accounts do {:error, %Ecto.Changeset{}} """ - def update_user(%User{} = user, attrs \\ %{}, _after_save \\ &{:ok, &1}) do + def update_user( + %User{} = user, + attrs \\ %{}, + after_save_cv \\ &{:ok, &1}, + after_save_image \\ &{:ok, &1} + ) do user |> User.changeset(attrs) |> Repo.update() + |> after_save(after_save_cv) + |> after_save(after_save_image) end @doc """ diff --git a/lib/atomic/accounts/user.ex b/lib/atomic/accounts/user.ex index ca67ec77a..9e76462c0 100644 --- a/lib/atomic/accounts/user.ex +++ b/lib/atomic/accounts/user.ex @@ -7,7 +7,7 @@ defmodule Atomic.Accounts.User do alias Atomic.Accounts.Course alias Atomic.Activities.ActivityEnrollment alias Atomic.Organizations.{Membership, Organization} - alias Atomic.Uploaders.ProfilePicture + alias Atomic.Uploaders.{CV, ProfilePicture} @required_fields ~w(email password)a @optional_fields ~w(name slug role phone_number confirmed_at course_id current_organization_id)a @@ -26,6 +26,7 @@ defmodule Atomic.Accounts.User do field :phone_number, :string field :profile_picture, ProfilePicture.Type + field :cv, CV.Type field :role, Ecto.Enum, values: @roles, default: :student belongs_to :course, Course belongs_to :current_organization, Organization @@ -60,12 +61,24 @@ defmodule Atomic.Accounts.User do |> validate_password(opts) end + @doc """ + A user changeset for updating the user's profile picture. + """ def picture_changeset(user, attrs) do user |> cast(attrs, @required_fields ++ @optional_fields) |> cast_attachments(attrs, [:profile_picture]) end + @doc """ + A user changeset for updating the user's CV. + """ + def cv_changeset(user, attrs) do + user + |> cast(attrs, @required_fields ++ @optional_fields) + |> cast_attachments(attrs, [:cv]) + end + @doc """ A user changeset for updating the user. """ diff --git a/lib/atomic/uploader.ex b/lib/atomic/uploader.ex index 6e0f8d049..fa5407941 100644 --- a/lib/atomic/uploader.ex +++ b/lib/atomic/uploader.ex @@ -5,7 +5,7 @@ defmodule Atomic.Uploader do """ @versions [:original, :medium, :thumb] - @extensions_whitelist ~w(.svg .jpg .jpeg .png) + @extensions_whitelist ~w(.svg .jpg .jpeg .png .pdf .docx) defmacro __using__(_) do quote do diff --git a/lib/atomic/uploaders/cv.ex b/lib/atomic/uploaders/cv.ex new file mode 100644 index 000000000..6e75529e1 --- /dev/null +++ b/lib/atomic/uploaders/cv.ex @@ -0,0 +1,11 @@ +defmodule Atomic.Uploaders.CV do + @moduledoc """ + Uploader for CVs. + """ + use Atomic.Uploader + alias Atomic.Accounts.User + + def storage_dir(_version, {_file, %User{} = scope}) do + "uploads/atomic/user_cvs/#{scope.id}" + end +end diff --git a/lib/atomic_web/live/profile_live/form_component.ex b/lib/atomic_web/live/profile_live/form_component.ex index 82fe062f4..35bcea9ef 100644 --- a/lib/atomic_web/live/profile_live/form_component.ex +++ b/lib/atomic_web/live/profile_live/form_component.ex @@ -3,12 +3,13 @@ defmodule AtomicWeb.ProfileLive.FormComponent do alias Atomic.Accounts - @extensions_whitelist ~w(.jpg .jpeg .gif .png) + @extensions_whitelist ~w(.jpg .jpeg .gif .png .pdf .docx) @impl true def mount(socket) do {:ok, socket + |> allow_upload(:cv, accept: @extensions_whitelist, max_entries: 1) |> allow_upload(:picture, accept: @extensions_whitelist, max_entries: 1)} end @@ -54,6 +55,7 @@ defmodule AtomicWeb.ProfileLive.FormComponent do case Accounts.update_user( user, Map.put(user_params, "email", user.email), + &consume_cv_data(socket, &1), &consume_image_data(socket, &1) ) do {:ok, _user} -> @@ -68,21 +70,48 @@ defmodule AtomicWeb.ProfileLive.FormComponent do end defp consume_image_data(socket, user) do - consume_uploaded_entries(socket, :image, fn %{path: path}, entry -> - Accounts.update_user(user, %{ - "image" => %Plug.Upload{ - content_type: entry.client_type, - filename: entry.client_name, - path: path - } - }) - end) - |> case do - [{:ok, user}] -> - {:ok, user} - - _errors -> - {:ok, user} + if Map.has_key?(socket.assigns.uploads, :image) do + consume_uploaded_entries(socket, :image, fn %{path: path}, entry -> + Accounts.update_user_picture(user, %{ + "image" => %Plug.Upload{ + content_type: entry.client_type, + filename: entry.client_name, + path: path + } + }) + end) + |> case do + [{:ok, user}] -> + {:ok, user} + + _errors -> + {:ok, user} + end end + + {:ok, user} + end + + defp consume_cv_data(socket, user) do + if Map.has_key?(socket.assigns.uploads, :cv) do + consume_uploaded_entries(socket, :cv, fn %{path: path}, entry -> + Accounts.update_user_cv(user, %{ + "cv" => %Plug.Upload{ + content_type: entry.client_type, + filename: entry.client_name, + path: path + } + }) + end) + |> case do + [{:ok, user}] -> + {:ok, user} + + _errors -> + {:ok, user} + end + end + + {:ok, user} end end diff --git a/lib/atomic_web/live/profile_live/form_component.html.heex b/lib/atomic_web/live/profile_live/form_component.html.heex index f9de1c7f2..e046ac809 100644 --- a/lib/atomic_web/live/profile_live/form_component.html.heex +++ b/lib/atomic_web/live/profile_live/form_component.html.heex @@ -46,6 +46,10 @@ ) %>