mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-27 13:47:58 +01:00
add commission listings
This commit is contained in:
parent
fa8f969529
commit
eb3e24c04d
7 changed files with 223 additions and 0 deletions
|
@ -2,12 +2,14 @@ defmodule Philomena.Commissions.Commission do
|
|||
use Ecto.Schema
|
||||
import Ecto.Changeset
|
||||
|
||||
alias Philomena.Commissions.Item
|
||||
alias Philomena.Images.Image
|
||||
alias Philomena.Users.User
|
||||
|
||||
schema "commissions" do
|
||||
belongs_to :user, User
|
||||
belongs_to :sheet_image, Image
|
||||
has_many :items, Item
|
||||
|
||||
field :open, :boolean
|
||||
field :categories, {:array, :string}, default: []
|
||||
|
|
86
lib/philomena_web/controllers/commission_controller.ex
Normal file
86
lib/philomena_web/controllers/commission_controller.ex
Normal file
|
@ -0,0 +1,86 @@
|
|||
defmodule PhilomenaWeb.CommissionController do
|
||||
use PhilomenaWeb, :controller
|
||||
|
||||
alias Philomena.Commissions.{Item, Commission}
|
||||
alias Philomena.Repo
|
||||
import Ecto.Query
|
||||
|
||||
plug PhilomenaWeb.FilterBannedUsersPlug when action in [:new, :create, :edit, :update, :destroy]
|
||||
plug :load_and_authorize_resource, model: Commission
|
||||
|
||||
def index(conn, params) do
|
||||
commissions =
|
||||
commission_search(params["commission"])
|
||||
|> Repo.paginate(conn.assigns.scrivener)
|
||||
|
||||
render(conn, "index.html", commissions: commissions, layout_class: "layout--wide")
|
||||
end
|
||||
|
||||
defp commission_search(attrs) when is_map(attrs) do
|
||||
item_type = presence(attrs["item_type"])
|
||||
categories = presence(attrs["category"])
|
||||
keywords = presence(attrs["keywords"])
|
||||
price_min = to_f(presence(attrs["price_min"]) || 0)
|
||||
price_max = to_f(presence(attrs["price_max"]) || 9999)
|
||||
|
||||
query =
|
||||
commission_search(nil)
|
||||
|> where([_c, ci], ci.base_price > ^price_min and ci.base_price < ^price_max)
|
||||
|
||||
query =
|
||||
if item_type do
|
||||
query
|
||||
|> where([_c, ci], ci.item_type == ^item_type)
|
||||
else
|
||||
query
|
||||
end
|
||||
|
||||
query =
|
||||
if categories do
|
||||
query
|
||||
|> where([c, _ci], fragment("? @> ?", c.categories, ^categories))
|
||||
else
|
||||
query
|
||||
end
|
||||
|
||||
query =
|
||||
if keywords do
|
||||
query
|
||||
|> where([c, _ci], ilike(c.information, ^like_sanitize(keywords)) or ilike(c.will_create, ^like_sanitize(keywords)))
|
||||
else
|
||||
query
|
||||
end
|
||||
|
||||
query
|
||||
end
|
||||
|
||||
defp commission_search(_attrs) do
|
||||
from c in Commission,
|
||||
where: c.open == true,
|
||||
where: c.commission_items_count > 0,
|
||||
inner_join: ci in Item, on: ci.commission_id == c.id,
|
||||
group_by: c.id,
|
||||
order_by: [asc: fragment("random()")],
|
||||
preload: [user: [awards: :badge], items: [example_image: :tags]]
|
||||
end
|
||||
|
||||
defp presence(nil),
|
||||
do: nil
|
||||
defp presence([]),
|
||||
do: nil
|
||||
defp presence(string) when is_binary(string),
|
||||
do: if(String.trim(string) == "", do: nil, else: string)
|
||||
defp presence(object),
|
||||
do: object
|
||||
|
||||
defp to_f(input) do
|
||||
case Float.parse(to_string(input)) do
|
||||
{float, _rest} -> float
|
||||
_error -> 0.0
|
||||
end
|
||||
end
|
||||
|
||||
defp like_sanitize(input) do
|
||||
"%" <> String.replace(input, ["\\", "%", "_"], &<<"\\", &1>>) <> "%"
|
||||
end
|
||||
end
|
|
@ -97,6 +97,7 @@ defmodule PhilomenaWeb.Router do
|
|||
resources "/profiles", ProfileController, only: [:show]
|
||||
resources "/captchas", CaptchaController, only: [:create]
|
||||
resources "/posts", PostController, only: [:index]
|
||||
resources "/commissions", CommissionController, only: [:index, :show]
|
||||
|
||||
get "/:id", ImageController, :show
|
||||
end
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
elixir:
|
||||
route = fn p -> Routes.commission_path(@conn, :index, p) end
|
||||
pagination = render PhilomenaWeb.PaginationView, "_pagination.html", page: @commissions, route: route, conn: @conn
|
||||
|
||||
.block
|
||||
.block__header
|
||||
span.block__header__title Open Commissions
|
||||
= pagination
|
||||
|
||||
.block__content
|
||||
= cond do
|
||||
- Enum.any?(@commissions) ->
|
||||
= for c <- @commissions do
|
||||
.block.commission
|
||||
.block__content.flex.flex--no-wrap
|
||||
.flex__fixed.spacing-right
|
||||
= render PhilomenaWeb.UserAttributionView, "_user_avatar.html", object: c, conn: @conn
|
||||
|
||||
.flex__grow.commission__listing_body
|
||||
span.commission__listing_artist
|
||||
= render PhilomenaWeb.UserAttributionView, "_user.html", object: c, badges: true, conn: @conn
|
||||
|
||||
.commission__listing__body_text
|
||||
p
|
||||
strong> Price Range:
|
||||
= :io_lib.format("$~.2f - $~.2f USD", [c.minimum_price, c.maximum_price])
|
||||
|
||||
p
|
||||
strong> Categories:
|
||||
= Enum.join(c.categories, ", ")
|
||||
|
||||
p
|
||||
strong> Offers:
|
||||
= Enum.map(c.items, & &1.item_type) |> Enum.join(", ")
|
||||
|
||||
p
|
||||
strong> Example Artwork:
|
||||
|
||||
br
|
||||
|
||||
= for item <- Enum.take_random(c.items, 5) do
|
||||
= render PhilomenaWeb.ImageView, "_image_container.html", image: item.example_image, conn: @conn
|
||||
|
||||
p
|
||||
strong
|
||||
= link "More information", to: Routes.commission_path(@conn, :show, c)
|
||||
|
||||
- true ->
|
||||
p We couldn't find any commission listings to display. Sorry!
|
|
@ -0,0 +1,64 @@
|
|||
elixir:
|
||||
categories = [
|
||||
"Anthro": :category_anthro,
|
||||
"Canon Characters": :category_canon_characters,
|
||||
"Comics": :category_comics,
|
||||
"Fetish Art": :category_fetish_art,
|
||||
"Human and EqG": :category_human_and_eqg,
|
||||
"NSFW": :category_nsfw,
|
||||
"Original Characters": :category_original_characters,
|
||||
"Original Species": :category_original_species,
|
||||
"Pony": :category_pony,
|
||||
"Requests": :category_requests,
|
||||
"Safe": :category_safe,
|
||||
"Shipping": :category_shipping,
|
||||
"Violence and Gore": :category_violence_and_gore
|
||||
]
|
||||
|
||||
types = [
|
||||
[key: "-", value: ""],
|
||||
"Sketch",
|
||||
"Colored Sketch",
|
||||
"Inked",
|
||||
"Flat Color",
|
||||
"Vector",
|
||||
"Cel Shaded",
|
||||
"Fully Shaded",
|
||||
"Traditional",
|
||||
"Pixel Art",
|
||||
"Animation",
|
||||
"Crafted Item",
|
||||
"Sculpture",
|
||||
"Plushie",
|
||||
"Other"
|
||||
]
|
||||
|
||||
.block
|
||||
.block__header
|
||||
span.block__header__title Search
|
||||
.block__content
|
||||
= form_for @conn, Routes.commission_path(@conn, :index), [as: :commission, method: "get", class: "hform"], fn f ->
|
||||
.field = label f, :categories, "Art Categories:"
|
||||
|
||||
= for {name, value} <- categories do
|
||||
.field
|
||||
=> checkbox f, value, checked_value: name, name: "commission[category][]", class: "checkbox spacing-right", hidden_input: false
|
||||
=> label f, value, name
|
||||
|
||||
br
|
||||
|
||||
.field = label f, :item_type, "Commission Type:"
|
||||
.field = select f, :item_type, types, class: "input"
|
||||
|
||||
br
|
||||
|
||||
.field = label f, :price_min, "Price:"
|
||||
.field = number_input f, :price_min, class: "input input--short", placeholder: "At Least", step: "any", min: 0
|
||||
.field = number_input f, :price_max, class: "input input--short", placeholder: "At Most", step: "any", min: 0
|
||||
|
||||
br
|
||||
|
||||
.field = label f, :keywords, "Search:"
|
||||
.field = text_input f, :keywords, class: "input input--short", placeholder: "Keywords"
|
||||
|
||||
= submit "Search", class: "button"
|
18
lib/philomena_web/templates/commission/index.html.slime
Normal file
18
lib/philomena_web/templates/commission/index.html.slime
Normal file
|
@ -0,0 +1,18 @@
|
|||
h1 Commissions Directory
|
||||
|
||||
.dnp-warning
|
||||
h4 Disclaimer
|
||||
p
|
||||
' This is only a directory meant to help connect artists offering
|
||||
' commissions with potential commissioners. We don't have any way
|
||||
' for users to make payments through the site, so we can't be held
|
||||
' responsible for any issues regarding payment.
|
||||
a href="/pages/rules#9" More info.
|
||||
|
||||
br
|
||||
|
||||
.column-layout
|
||||
.column-layout__left
|
||||
= render PhilomenaWeb.CommissionView, "_directory_sidebar.html", conn: @conn
|
||||
.column-layout__main
|
||||
= render PhilomenaWeb.CommissionView, "_directory_results.html", commissions: @commissions, conn: @conn
|
3
lib/philomena_web/views/commission_view.ex
Normal file
3
lib/philomena_web/views/commission_view.ex
Normal file
|
@ -0,0 +1,3 @@
|
|||
defmodule PhilomenaWeb.CommissionView do
|
||||
use PhilomenaWeb, :view
|
||||
end
|
Loading…
Reference in a new issue