Skip to content

Commit

Permalink
feat: companies (#405)
Browse files Browse the repository at this point in the history
  • Loading branch information
joaodiaslobo authored Oct 14, 2024
1 parent 30cd59e commit 72afbc9
Show file tree
Hide file tree
Showing 25 changed files with 1,210 additions and 16 deletions.
5 changes: 3 additions & 2 deletions assets/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ import "phoenix_html"
import {Socket} from "phoenix"
import {LiveSocket} from "phoenix_live_view"
import topbar from "../vendor/topbar"
import { QrScanner, Wheel, Confetti } from "./hooks";
import { QrScanner, Wheel, Confetti, Sorting } from "./hooks";

let Hooks = {
QrScanner: QrScanner,
Wheel: Wheel,
Confetti: Confetti
Confetti: Confetti,
Sorting: Sorting
};

let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
Expand Down
3 changes: 2 additions & 1 deletion assets/js/hooks/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { QrScanner } from "./qr_reading.js";
export { Wheel } from "./wheel.js";
export { Confetti } from "./confetti.js";
export { Confetti } from "./confetti.js";
export { Sorting } from "./sorting.js";
21 changes: 21 additions & 0 deletions assets/js/hooks/sorting.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Sortable from "../../vendor/sortable";

export const Sorting = {
mounted() {
const placeholder = document.createElement('div');
new Sortable(this.el, {
animation: 150,
ghostClass: "opacity-20",
dragClass: "shadow-2xl",
handle: ".handle",
onEnd: () => {
const elements = Array.from(this.el.children)
const ids = elements.map(elm => elm.id)
this.pushEventTo(this.el, "update-sorting", {ids: ids})
},
setData: (dataTransfer, _) => {
dataTransfer.setDragImage(placeholder, 0, 0);
}
})
}
}
2 changes: 2 additions & 0 deletions assets/vendor/sortable.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions lib/safira/accounts/roles/permissions.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ defmodule Safira.Accounts.Roles.Permissions do
%{
"attendees" => ["show", "edit"],
"staffs" => ["show", "edit", "roles_edit"],
"companies" => ["edit"],
"products" => ["show", "edit", "delete"],
"purchases" => ["show", "redeem", "refund"],
"badges" => ["show", "edit", "delete", "give", "revoke", "give_without_restrictions"],
Expand Down
253 changes: 253 additions & 0 deletions lib/safira/companies.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
defmodule Safira.Companies do
@moduledoc """
The Companies context.
"""

use Safira.Context

alias Safira.Companies.Company

@doc """
Returns the list of companies.
## Examples
iex> list_companies()
[%Company{}, ...]
"""
def list_companies do
Company
|> Repo.all()
end

def list_companies(opts) when is_list(opts) do
Company
|> apply_filters(opts)
|> Repo.all()
end

def list_companies(params) do
Company
|> join(:left, [c], t in assoc(c, :tier), as: :tier)
|> preload(:tier)
|> Flop.validate_and_run(params, for: Company)
end

def list_companies(%{} = params, opts) when is_list(opts) do
Company
|> apply_filters(opts)
|> join(:left, [c], t in assoc(c, :tier), as: :tier)
|> preload(:tier)
|> Flop.validate_and_run(params, for: Company)
end

@doc """
Gets a single company.
Raises `Ecto.NoResultsError` if the Company does not exist.
## Examples
iex> get_company!(123)
%Company{}
iex> get_company!(456)
** (Ecto.NoResultsError)
"""
def get_company!(id), do: Repo.get!(Company, id)

@doc """
Creates a company.
## Examples
iex> create_company(%{field: value})
{:ok, %Company{}}
iex> create_company(%{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def create_company(attrs \\ %{}) do
%Company{}
|> Company.changeset(attrs)
|> Repo.insert()
end

@doc """
Updates a company.
## Examples
iex> update_company(company, %{field: new_value})
{:ok, %Company{}}
iex> update_company(company, %{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def update_company(%Company{} = company, attrs) do
company
|> Company.changeset(attrs)
|> Repo.update()
end

@doc """
Updates a company logo.
## Examples
iex> update_company_logo(company, %{logo: image})
{:ok, %Company{}}
iex> update_company_logo(company, %{logo: bad_image})
{:error, %Ecto.Changeset{}}
"""
def update_company_logo(%Company{} = company, attrs) do
company
|> Company.image_changeset(attrs)
|> Repo.update()
end

@doc """
Deletes a company.
## Examples
iex> delete_company(company)
{:ok, %Company{}}
iex> delete_company(company)
{:error, %Ecto.Changeset{}}
"""
def delete_company(%Company{} = company) do
Repo.delete(company)
end

@doc """
Returns an `%Ecto.Changeset{}` for tracking company changes.
## Examples
iex> change_company(company)
%Ecto.Changeset{data: %Company{}}
"""
def change_company(%Company{} = company, attrs \\ %{}) do
Company.changeset(company, attrs)
end

alias Safira.Companies.Tier

@doc """
Returns the list of tiers.
## Examples
iex> list_tiers()
[%Tier{}, ...]
"""
def list_tiers do
Tier
|> order_by(:priority)
|> Repo.all()
end

@doc """
Gets a single tier.
Raises `Ecto.NoResultsError` if the Tier does not exist.
## Examples
iex> get_tier!(123)
%Tier{}
iex> get_tier!(456)
** (Ecto.NoResultsError)
"""
def get_tier!(id), do: Repo.get!(Tier, id)

@doc """
Creates a tier.
## Examples
iex> create_tier(%{field: value})
{:ok, %Tier{}}
iex> create_tier(%{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def create_tier(attrs \\ %{}) do
%Tier{}
|> Tier.changeset(attrs)
|> Repo.insert()
end

@doc """
Updates a tier.
## Examples
iex> update_tier(tier, %{field: new_value})
{:ok, %Tier{}}
iex> update_tier(tier, %{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def update_tier(%Tier{} = tier, attrs) do
tier
|> Tier.changeset(attrs)
|> Repo.update()
end

@doc """
Deletes a tier.
## Examples
iex> delete_tier(tier)
{:ok, %Tier{}}
iex> delete_tier(tier)
{:error, %Ecto.Changeset{}}
"""
def delete_tier(%Tier{} = tier) do
Repo.delete(tier)
end

@doc """
Returns an `%Ecto.Changeset{}` for tracking tier changes.
## Examples
iex> change_tier(tier)
%Ecto.Changeset{data: %Tier{}}
"""
def change_tier(%Tier{} = tier, attrs \\ %{}) do
Tier.changeset(tier, attrs)
end

@doc """
Returns the next priority a tier should have.
## Examples
iex> get_next_tier_priority()
5
"""
def get_next_tier_priority do
(Repo.aggregate(from(t in Tier), :max, :priority) || -1) + 1
end
end
52 changes: 52 additions & 0 deletions lib/safira/companies/company.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
defmodule Safira.Companies.Company do
@moduledoc """
Companies present at the event.
"""
use Safira.Schema

@derive {
Flop.Schema,
filterable: [:name],
sortable: [:name, :tier],
default_limit: 11,
join_fields: [
tier: [
binding: :tier,
field: :priority,
path: [:tier, :priority],
ecto_type: :integer
]
]
}

@required_fields ~w(name tier_id)a
@optional_fields ~w(badge_id url)a

schema "companies" do
field :name, :string
field :url, :string
field :logo, Uploaders.Company.Type

belongs_to :badge, Safira.Contest.Badge
belongs_to :tier, Safira.Companies.Tier

timestamps(type: :utc_datetime)
end

@doc false
def changeset(company, attrs) do
company
|> cast(attrs, @required_fields ++ @optional_fields)
|> unique_constraint(:badge_id)
|> cast_assoc(:badge)
|> cast_assoc(:tier)
|> validate_required(@required_fields)
|> validate_url(:url)
end

@doc false
def image_changeset(badge, attrs) do
badge
|> cast_attachments(attrs, [:logo])
end
end
26 changes: 26 additions & 0 deletions lib/safira/companies/tier.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
defmodule Safira.Companies.Tier do
@moduledoc """
Sponsor tiers for companies.
"""
use Safira.Schema

@required_fields ~w(name priority)a

@derive {Flop.Schema, sortable: [:priority], filterable: []}

schema "tiers" do
field :name, :string
field :priority, :integer

has_many :companies, Safira.Companies.Company, foreign_key: :tier_id

timestamps(type: :utc_datetime)
end

@doc false
def changeset(tier, attrs) do
tier
|> cast(attrs, @required_fields)
|> validate_required(@required_fields)
end
end
Loading

0 comments on commit 72afbc9

Please sign in to comment.