diff --git a/lib/philomena/commissions.ex b/lib/philomena/commissions.ex index f0d152cb..69aa8b80 100644 --- a/lib/philomena/commissions.ex +++ b/lib/philomena/commissions.ex @@ -145,8 +145,8 @@ defmodule Philomena.Commissions do {:error, %Ecto.Changeset{}} """ - def create_item(attrs \\ %{}) do - %Item{} + def create_item(commission, attrs \\ %{}) do + Ecto.build_assoc(commission, :items) |> Item.changeset(attrs) |> Repo.insert() end diff --git a/lib/philomena/commissions/item.ex b/lib/philomena/commissions/item.ex index a0863eed..15d08f09 100644 --- a/lib/philomena/commissions/item.ex +++ b/lib/philomena/commissions/item.ex @@ -20,7 +20,12 @@ defmodule Philomena.Commissions.Item do @doc false def changeset(item, attrs) do item - |> cast(attrs, []) - |> validate_required([]) + |> cast(attrs, [:item_type, :description, :base_price, :add_ons, :example_image_id]) + |> validate_required([:commission_id, :item_type, :description]) + |> validate_length(:description, max: 300, count: :bytes) + |> validate_length(:add_ons, max: 500, count: :bytes) + |> validate_number(:base_price, greater_than_or_equal_to: 0, less_than_or_equal_to: 500) + |> validate_inclusion(:item_type, Commission.types()) + |> foreign_key_constraint(:example_image_id, name: :fk_rails_56d368749a) end end diff --git a/lib/philomena_web/controllers/profile/commission/item_controller.ex b/lib/philomena_web/controllers/profile/commission/item_controller.ex new file mode 100644 index 00000000..d1a230e9 --- /dev/null +++ b/lib/philomena_web/controllers/profile/commission/item_controller.ex @@ -0,0 +1,89 @@ +defmodule PhilomenaWeb.Profile.Commission.ItemController do + use PhilomenaWeb, :controller + + alias Philomena.Commissions.Item + alias Philomena.Commissions + alias Philomena.Users.User + alias Philomena.Repo + + plug PhilomenaWeb.FilterBannedUsersPlug + plug :load_resource, model: User, id_name: "profile_id", id_field: "slug", preload: [:verified_links, commission: [sheet_image: :tags, user: [awards: :badge], items: [example_image: :tags]]], persisted: true + plug :ensure_commission + plug :ensure_correct_user + + def new(conn, _params) do + user = conn.assigns.user + commission = user.commission + + changeset = Commissions.change_item(%Item{}) + render(conn, "new.html", user: user, commission: commission, changeset: changeset) + end + + def create(conn, %{"item" => item_params}) do + user = conn.assigns.user + commission = user.commission + + case Commissions.create_item(commission, item_params) do + {:ok, _item} -> + conn + |> put_flash(:info, "Item successfully created.") + |> redirect(to: Routes.profile_commission_path(conn, :show, conn.assigns.user)) + + {:error, changeset} -> + render(conn, "new.html", user: user, commission: commission, changeset: changeset) + end + end + + def edit(conn, %{"id" => id}) do + user = conn.assigns.user + commission = user.commission + item = Repo.get_by!(Item, commission_id: commission.id, id: id) + + changeset = Commissions.change_item(item) + render(conn, "edit.html", user: user, commission: commission, item: item, changeset: changeset) + end + + def update(conn, %{"id" => id, "item" => item_params}) do + user = conn.assigns.user + commission = user.commission + item = Repo.get_by!(Item, commission_id: commission.id, id: id) + + case Commissions.update_item(item, item_params) do + {:ok, _commission} -> + conn + |> put_flash(:info, "Item successfully updated.") + |> redirect(to: Routes.profile_commission_path(conn, :show, conn.assigns.user)) + + {:error, changeset} -> + render(conn, "edit.html", user: user, commission: commission, item: item, changeset: changeset) + end + end + + def delete(conn, %{"id" => id}) do + user = conn.assigns.user + commission = user.commission + item = Repo.get_by!(Item, commission_id: commission.id, id: id) + + {:ok, _item} = Commissions.delete_item(item) + + conn + |> put_flash(:info, "Item deleted successfully.") + |> redirect(to: Routes.profile_commission_path(conn, :show, conn.assigns.user)) + end + + defp ensure_commission(conn, _opts) do + case is_nil(conn.assigns.user.commission) do + true -> PhilomenaWeb.NotFoundPlug.call(conn) + false -> conn + end + end + + defp ensure_correct_user(conn, _opts) do + user_id = conn.assigns.user.id + + case conn.assigns.current_user do + %{id: ^user_id} -> conn + _other -> PhilomenaWeb.NotAuthorizedPlug.call(conn) + end + end +end \ No newline at end of file diff --git a/lib/philomena_web/controllers/profile/commission/report_controller.ex b/lib/philomena_web/controllers/profile/commission/report_controller.ex new file mode 100644 index 00000000..fc85d3b8 --- /dev/null +++ b/lib/philomena_web/controllers/profile/commission/report_controller.ex @@ -0,0 +1,44 @@ +defmodule PhilomenaWeb.Profile.Commission.ReportController do + use PhilomenaWeb, :controller + + alias PhilomenaWeb.ReportController + alias PhilomenaWeb.ReportView + alias Philomena.Users.User + alias Philomena.Reports.Report + alias Philomena.Reports + + plug PhilomenaWeb.FilterBannedUsersPlug + plug PhilomenaWeb.UserAttributionPlug + plug PhilomenaWeb.CaptchaPlug when action in [:create] + plug PhilomenaWeb.CanaryMapPlug, new: :show, create: :show + plug :load_resource, model: User, id_name: "profile_id", id_field: "slug", preload: [:verified_links, commission: [sheet_image: :tags, user: [awards: :badge], items: [example_image: :tags]]], persisted: true + plug :ensure_commission + + def new(conn, _params) do + user = conn.assigns.user + commission = conn.assigns.user.commission + action = Routes.profile_commission_report_path(conn, :create, user) + changeset = + %Report{reportable_type: "Commission", reportable_id: commission.id} + |> Reports.change_report() + + conn + |> put_view(ReportView) + |> render("new.html", reportable: commission, changeset: changeset, action: action) + end + + def create(conn, params) do + user = conn.assigns.user + commission = conn.assigns.user.commission + action = Routes.profile_commission_report_path(conn, :create, user) + + ReportController.create(conn, action, commission, "Commission", params) + end + + defp ensure_commission(conn, _opts) do + case is_nil(conn.assigns.user.commission) do + true -> PhilomenaWeb.NotFoundPlug.call(conn) + false -> conn + end + end +end \ No newline at end of file diff --git a/lib/philomena_web/router.ex b/lib/philomena_web/router.ex index 79ae9e04..4dd08e10 100644 --- a/lib/philomena_web/router.ex +++ b/lib/philomena_web/router.ex @@ -113,7 +113,10 @@ defmodule PhilomenaWeb.Router do end resources "/profiles", ProfileController, only: [] do - resources "/commission", Profile.CommissionController, only: [:new, :create, :edit, :update, :delete], singleton: true + resources "/commission", Profile.CommissionController, only: [:new, :create, :edit, :update, :delete], singleton: true do + resources "/items", Profile.Commission.ItemController, only: [:new, :create, :edit, :update, :delete] + resources "/reports", Profile.Commission.ReportController, only: [:new, :create] + end end scope "/filters", Filter, as: :filter do @@ -179,7 +182,7 @@ defmodule PhilomenaWeb.Router do resources "/preview", PreviewController, only: [:create] end resources "/posts", PostController, only: [:index] - resources "/commissions", CommissionController, only: [:index, :show] + resources "/commissions", CommissionController, only: [:index] resources "/galleries", GalleryController, only: [:index, :show] resources "/adverts", AdvertController, only: [:show] resources "/pages", PageController, only: [:show] diff --git a/lib/philomena_web/templates/profile/commission/_listing_items.html.slime b/lib/philomena_web/templates/profile/commission/_listing_items.html.slime index 48ec4fd1..87e7a540 100644 --- a/lib/philomena_web/templates/profile/commission/_listing_items.html.slime +++ b/lib/philomena_web/templates/profile/commission/_listing_items.html.slime @@ -7,7 +7,10 @@ = if not Enum.any?(@commission.items) do = if current?(@user, @conn.assigns.current_user) do p You have not added any items to your commissions sheet yet. - p Your listing will not appear in search results until you list at least one item. + p + ' Your listing will not appear in search results until you + = link "list at least one item", to: Routes.profile_commission_item_path(@conn, :new, @user) + ' . - else p This artist has not added any items yet. Please check back later. @@ -18,6 +21,8 @@ th Description th Base Price th Add-Ons + = if can?(@conn, :edit, @commission) do + th Options tbody = for {description, add_ons, item} <- @items do tr @@ -40,4 +45,11 @@ = Decimal.round(item.base_price, 2) td - == add_ons \ No newline at end of file + == add_ons + + = if can?(@conn, :edit, @commission) do + td + = link "Edit item", to: Routes.profile_commission_item_path(@conn, :edit, @user, item) + br + br + = link "Delete item", to: Routes.profile_commission_item_path(@conn, :delete, @user, item), data: [confirm: "Are you really, really sure?", method: :delete] \ No newline at end of file diff --git a/lib/philomena_web/templates/profile/commission/_listing_sidebar.html.slime b/lib/philomena_web/templates/profile/commission/_listing_sidebar.html.slime index e9c52a8d..85adc8e0 100644 --- a/lib/philomena_web/templates/profile/commission/_listing_sidebar.html.slime +++ b/lib/philomena_web/templates/profile/commission/_listing_sidebar.html.slime @@ -75,14 +75,14 @@ br = link "Delete this listing", to: Routes.profile_commission_path(@conn, :delete, @user), data: [confirm: "Are you really, really sure about that?", method: :delete] br - /= link_to 'Report this listing', new_report_path(reportable_class: 'commission', reportable_id: @user.commission.id) + = link "Report this listing", to: Routes.profile_commission_report_path(@conn, :new, @user) / Share block .block .block__header span.block__header__title Share this listing .block__content - - url = Routes.commission_url(@conn, :show, @commission) + - url = Routes.profile_commission_url(@conn, :show, @user) .field label> for="commission_url" URL diff --git a/lib/philomena_web/templates/profile/commission/item/_form.html.slime b/lib/philomena_web/templates/profile/commission/item/_form.html.slime new file mode 100644 index 00000000..9883e7c8 --- /dev/null +++ b/lib/philomena_web/templates/profile/commission/item/_form.html.slime @@ -0,0 +1,31 @@ += form_for @changeset, @action, fn f -> + = if @changeset.action do + .alert.alert-danger + p Oops, something went wrong! Please check the errors below. + + .field + => label f, :item_type, "Type of item:" + = select f, :item_type, types(), class: "input" + = error_tag f, :item_type + br + .field + => label f, :base_price, "Base Price:" + = number_input f, :base_price, class: "input", placeholder: "20.00", step: "any", min: 0 + = error_tag f, :base_price + br + .field + => label f, :example_image_id, "ID of example image:" + = number_input f, :example_image_id, class: "input", placeholder: "1345604" + = error_tag f, :example_image_id + br + .field + => label f, :description, "Short description:" + = text_input f, :description, class: "input input--wide", placeholder: "Description" + = error_tag f, :description + br + .field + => label f, :add_ons, "Add-ons (optional):" + = textarea f, :add_ons, class: "input input--wide input--text", placeholder: "Additional character: $10.00" + = error_tag f, :add_ons + br + = submit "Submit", class: "button" diff --git a/lib/philomena_web/templates/profile/commission/item/edit.html.slime b/lib/philomena_web/templates/profile/commission/item/edit.html.slime new file mode 100644 index 00000000..cb8124be --- /dev/null +++ b/lib/philomena_web/templates/profile/commission/item/edit.html.slime @@ -0,0 +1,5 @@ +h1 Edit Item on Listing +p + = link "Back to listing", to: Routes.profile_commission_path(@conn, :show, @user) + += render PhilomenaWeb.Profile.Commission.ItemView, "_form.html", conn: @conn, changeset: @changeset, action: Routes.profile_commission_item_path(@conn, :update, @user, @item) diff --git a/lib/philomena_web/templates/profile/commission/item/new.html.slime b/lib/philomena_web/templates/profile/commission/item/new.html.slime new file mode 100644 index 00000000..b2a75690 --- /dev/null +++ b/lib/philomena_web/templates/profile/commission/item/new.html.slime @@ -0,0 +1,5 @@ +h1 New Item on Listing +p + = link "Back to listing", to: Routes.profile_commission_path(@conn, :show, @user) + += render PhilomenaWeb.Profile.Commission.ItemView, "_form.html", conn: @conn, changeset: @changeset, action: Routes.profile_commission_item_path(@conn, :create, @user) diff --git a/lib/philomena_web/templates/profile/commission/show.html.slime b/lib/philomena_web/templates/profile/commission/show.html.slime index 3589646c..c5d45474 100644 --- a/lib/philomena_web/templates/profile/commission/show.html.slime +++ b/lib/philomena_web/templates/profile/commission/show.html.slime @@ -1,6 +1,6 @@ h1 = @commission.user.name - | 's Commisisons + | 's Commissions .column-layout diff --git a/lib/philomena_web/views/profile/commission/item_view.ex b/lib/philomena_web/views/profile/commission/item_view.ex new file mode 100644 index 00000000..9f8d88af --- /dev/null +++ b/lib/philomena_web/views/profile/commission/item_view.ex @@ -0,0 +1,7 @@ +defmodule PhilomenaWeb.Profile.Commission.ItemView do + use PhilomenaWeb, :view + + alias Philomena.Commissions.Commission + + def types, do: Commission.types() +end diff --git a/lib/philomena_web/views/report_view.ex b/lib/philomena_web/views/report_view.ex index 0905593f..09fcc22d 100644 --- a/lib/philomena_web/views/report_view.ex +++ b/lib/philomena_web/views/report_view.ex @@ -50,7 +50,7 @@ defmodule PhilomenaWeb.ReportView do do: link "Conversation between #{r.from.name} and #{r.to.name}", to: Routes.conversation_path(conn, :show, r) def link_to_reported_thing(conn, %Commission{} = r), - do: link "#{r.user}'s commission page", to: Routes.commission_path(conn, :show, r) + do: link "#{r.user.name}'s commission page", to: Routes.profile_commission_path(conn, :show, r.user) def link_to_reported_thing(conn, %Post{} = r), do: link "Post in #{r.topic.title}", to: Routes.forum_topic_path(conn, :show, r.topic.forum, r.topic, post_id: r.id) <> "#post_#{r.id}"