diff --git a/assets/css/app.css b/assets/css/app.css index 060d3e7..ed81fd8 100644 --- a/assets/css/app.css +++ b/assets/css/app.css @@ -12,6 +12,7 @@ @theme { --color-primary: #ee7749; + --color-app-bg: #F9F9F9; } diff --git a/config/config.exs b/config/config.exs index f161645..3f55d12 100644 --- a/config/config.exs +++ b/config/config.exs @@ -24,6 +24,12 @@ config :yearbook, ecto_repos: [Yearbook.Repo], generators: [timestamp_type: :utc_datetime, binary_id: true] +# Waffle configuration +config :waffle, + storage: Waffle.Storage.Local, + storage_dir_prefix: "priv", + asset_host: {:system, "ASSET_HOST"} + # Configures the endpoint config :yearbook, YearbookWeb.Endpoint, url: [host: "localhost"], diff --git a/lib/yearbook/entries.ex b/lib/yearbook/entries.ex index 3155198..f2278ce 100644 --- a/lib/yearbook/entries.ex +++ b/lib/yearbook/entries.ex @@ -86,6 +86,34 @@ defmodule Yearbook.Entries do } end + @doc """ + Returns a paginated map of accepted entries based on filters and page. + """ + def list_accepted_entries_pagination(params \\ %{}) do + query = from e in Entry, where: e.status == :accepted + + query = + case Map.get(params, "masters") do + "true" -> from e in query, where: e.masters == true + "false" -> from e in query, where: e.masters == false + _ -> query + end + + query = + case Map.get(params, "year") do + year_str when year_str in [nil, ""] -> + query + + year_str -> + year_int = if is_binary(year_str), do: String.to_integer(year_str), else: year_str + from e in query, where: e.year == ^year_int + end + + query = from e in query, order_by: [asc: e.name] + + paginate(query, params) + end + @doc """ Gets a single entry. diff --git a/lib/yearbook/entries/entry.ex b/lib/yearbook/entries/entry.ex index 47afdc5..6076224 100644 --- a/lib/yearbook/entries/entry.ex +++ b/lib/yearbook/entries/entry.ex @@ -6,8 +6,8 @@ defmodule Yearbook.Entries.Entry do use Ecto.Schema import Ecto.Changeset - @required_fields ~w(photo name text)a - @optional_fields ~w(status)a + @required_fields ~w(photo name text year)a + @optional_fields ~w(status masters)a @primary_key {:id, :binary_id, autogenerate: true} @foreign_key_type :binary_id schema "entries" do @@ -15,14 +15,20 @@ defmodule Yearbook.Entries.Entry do field :name, :string field :text, :string field :status, Ecto.Enum, values: [:accepted, :pending, :denied], default: :pending + field :masters, :boolean, default: false + field :year, :integer timestamps(type: :utc_datetime) end @doc false def changeset(entry, attrs) do + current_year = Date.utc_today().year + entry |> cast(attrs, @required_fields ++ @optional_fields) |> validate_required(@required_fields) + |> validate_number(:year, greater_than: 2020, less_than_or_equal_to: current_year) + |> validate_length(:text, max: 200) end end diff --git a/lib/yearbook/schema.ex b/lib/yearbook/schema.ex new file mode 100644 index 0000000..14ebd4d --- /dev/null +++ b/lib/yearbook/schema.ex @@ -0,0 +1,27 @@ +defmodule Yearbook.Schema do + @moduledoc """ + Base schema module. + """ + defmacro __using__(_) do + quote do + use Ecto.Schema + use Waffle.Ecto.Schema + + import Ecto.Changeset + + alias Yearbook.Uploaders + + @primary_key {:id, :binary_id, autogenerate: true} + @foreign_key_type :binary_id + + def validate_url(changeset, field) do + changeset + |> validate_format( + field, + ~r/^https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_\+.~#?&\/=]*)$/, + message: "must start with http:// or https:// and have a valid domain" + ) + end + end + end +end diff --git a/lib/yearbook/uploader.ex b/lib/yearbook/uploader.ex new file mode 100644 index 0000000..6af382e --- /dev/null +++ b/lib/yearbook/uploader.ex @@ -0,0 +1,15 @@ +defmodule Yearbook.Uploader do + @moduledoc """ + Base uploader module. + """ + defmacro __using__(_) do + quote do + use Waffle.Definition + use Waffle.Ecto.Definition + + def s3_object_headers(_version, {file, _scope}) do + [content_type: MIME.from_path(file.file_name)] + end + end + end +end diff --git a/lib/yearbook_web.ex b/lib/yearbook_web.ex index 1c7e6a5..dad6485 100644 --- a/lib/yearbook_web.ex +++ b/lib/yearbook_web.ex @@ -64,6 +64,14 @@ defmodule YearbookWeb do end end + def component do + quote do + use Phoenix.Component + + unquote(html_helpers()) + end + end + def auth_view do quote do use Phoenix.LiveView, @@ -120,6 +128,8 @@ defmodule YearbookWeb do # Routes generation with the ~p sigil unquote(verified_routes()) + + alias Yearbook.Uploaders end end diff --git a/lib/yearbook_web/components/core_components.ex b/lib/yearbook_web/components/core_components.ex index 2afbc11..f744f65 100644 --- a/lib/yearbook_web/components/core_components.ex +++ b/lib/yearbook_web/components/core_components.ex @@ -521,27 +521,41 @@ defmodule YearbookWeb.CoreComponents do phx-mounted={@show && show_modal(@id)} phx-remove={hide_modal(@id)} data-cancel={JS.exec(@on_cancel, "phx-remove") |> hide_modal(@id)} - class="relative z-60 hidden" + class="relative z-50 hidden" >