Skip to content

Commit

Permalink
Add session_image and fix associations
Browse files Browse the repository at this point in the history
  • Loading branch information
MarioRodrigues10 committed Aug 5, 2023
1 parent 5600472 commit f944f90
Show file tree
Hide file tree
Showing 14 changed files with 149 additions and 109 deletions.
61 changes: 34 additions & 27 deletions lib/atomic/activities.ex
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ defmodule Atomic.Activities do
|> where([a, d], d.organization_id == ^organization_id)
|> select([a, _d], a)
|> Repo.all()
|> Repo.preload(activity_sessions: :enrollments)
end

@doc """
Expand Down Expand Up @@ -97,25 +98,26 @@ defmodule Atomic.Activities do
iex> get_activity_organizations!(activity)
** (Ecto.NoResultsError)
"""
def get_activity_organizations!(activity, _preloads \\ []) do
Map.get(activity, :departments, [])
def get_activity_organizations!(activity, preloads \\ []) do
Repo.preload(activity, preloads)
|> Map.get(:departments, [])
|> Enum.map(& &1.organization_id)
end

@doc """
Verifies if an user is enrolled in an activity.
Verifies if an user is enrolled in an activity session.
## Examples
iex> is_participating?(activity_id, user_id)
iex> is_participating?(session_id, user_id)
true
iex> is_participating?(activity_id, user_id)
iex> is_participating?(session_id, user_id)
false
"""
def is_participating?(activity_id, user_id) do
def is_participating?(session_id, user_id) do
Enrollment
|> where(activity_id: ^activity_id, user_id: ^user_id)
|> where(session_id: ^session_id, user_id: ^user_id)
|> Repo.exists?()
end

Expand Down Expand Up @@ -189,12 +191,14 @@ defmodule Atomic.Activities do
## Examples
iex> list_sessions()
iex> list_sessions(opts)
[%Session{}, ...]
"""
def list_sessions do
Repo.all(Session)
def list_sessions(opts) when is_list(opts) do
Session
|> apply_filters(opts)
|> Repo.all()
end

@doc """
Expand All @@ -211,7 +215,10 @@ defmodule Atomic.Activities do
** (Ecto.NoResultsError)
"""
def get_session!(id), do: Repo.get!(Session, id)
def get_session!(id, preloads \\ []) do
Repo.get!(Session, id)
|> Repo.preload(preloads)
end

@doc """
Creates a session.
Expand Down Expand Up @@ -324,12 +331,12 @@ defmodule Atomic.Activities do
iex> get_user_enrolled(user, activity)
** (Ecto.NoResultsError)
"""
def get_user_enrolled(user, activity) do
def get_user_enrolled(user, session_id) do
Enrollment
|> where(user_id: ^user.id, activity_id: ^activity.id)
|> where(user_id: ^user.id, session_id: ^session_id)
|> Repo.one()
|> case do
nil -> create_enrollment(activity, user)
nil -> create_enrollment(session_id, user)
enrollment -> enrollment
end
end
Expand Down Expand Up @@ -367,17 +374,17 @@ defmodule Atomic.Activities do
## Examples
iex> create_enrollment(%Activity{} = activity, %User{} = user)
iex> create_enrollment(session_id, %User{} = user)
{:ok, %Enrollment{}}
iex> create_enrollment(%Activity{} = activity, %User{} = user)
iex> create_enrollment(session_id, %User{} = user)
{:error, %Ecto.Changeset{}}
"""
def create_enrollment(%Activity{} = activity, %User{} = user) do
def create_enrollment(session_id, %User{} = user) do
%Enrollment{}
|> Enrollment.changeset(%{
activity_id: activity.id,
session_id: session_id,
user_id: user.id
})
|> Repo.insert()
Expand Down Expand Up @@ -407,35 +414,35 @@ defmodule Atomic.Activities do
## Examples
iex> delete_enrollment(enrollment)
iex> delete_enrollment(session_id, %User{})
{:ok, %Enrollment{}}
iex> delete_enrollment(enrollment)
iex> delete_enrollment(session_id, %User{})
{:error, %Ecto.Changeset{}}
"""
def delete_enrollment(%Activity{} = activity, %User{} = user) do
def delete_enrollment(session_id, %User{} = user) do
Repo.delete_all(
from e in Enrollment,
where: e.user_id == ^user.id and e.activity_id == ^activity.id
where: e.user_id == ^user.id and e.session_id == ^session_id
)
|> broadcast(:deleted_enrollment)
end

@doc """
Returns the total number of enrolled users in an activity.
Returns the total number of enrolled users in an activity session.
## Examples
iex> get_total_enrolled(activity)
iex> get_total_enrolled(session_id)
10
iex> get_total_enrolled(activity)
iex> get_total_enrolled(session_id)
0
"""
def get_total_enrolled(%Activity{} = activity) do
def get_total_enrolled(session_id) do
Enrollment
|> where(activity_id: ^activity.id)
|> where(session_id: ^session_id)
|> Repo.aggregate(:count, :id)
end

Expand Down
2 changes: 0 additions & 2 deletions lib/atomic/activities/activity.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ defmodule Atomic.Activities.Activity do
alias Atomic.Activities
alias Atomic.Activities.ActivityDepartment
alias Atomic.Activities.ActivitySpeaker
alias Atomic.Activities.Enrollment
alias Atomic.Activities.Session
alias Atomic.Activities.Speaker
alias Atomic.Departments
Expand Down Expand Up @@ -36,7 +35,6 @@ defmodule Atomic.Activities.Activity do
foreign_key: :activity_id,
preload_order: [asc: :start]

has_many :enrollments, Enrollment, foreign_key: :activity_id
belongs_to :event, Event

timestamps()
Expand Down
8 changes: 4 additions & 4 deletions lib/atomic/activities/enrollment.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ defmodule Atomic.Activities.Enrollment do
use Atomic.Schema

alias Atomic.Accounts.User
alias Atomic.Activities.Activity
alias Atomic.Activities.Session

schema "enrollments" do
field :present, :boolean

belongs_to :activity, Activity
belongs_to :session, Session

belongs_to :user, User

Expand All @@ -20,7 +20,7 @@ defmodule Atomic.Activities.Enrollment do
@doc false
def changeset(enrollment, attrs) do
enrollment
|> cast(attrs, [:activity_id, :user_id, :present])
|> validate_required([:activity_id, :user_id])
|> cast(attrs, [:session_id, :user_id, :present])
|> validate_required([:session_id, :user_id])
end
end
7 changes: 5 additions & 2 deletions lib/atomic/activities/session.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,22 @@ defmodule Atomic.Activities.Session do
use Atomic.Schema

alias Atomic.Activities.Activity
alias Atomic.Activities.Enrollment
alias Atomic.Activities.Location
alias Atomic.Uploaders

@required_fields ~w(start finish)a
@optional_fields ~w(delete)a
@optional_fields ~w(delete session_image)a

schema "sessions" do
field :start, :naive_datetime
field :finish, :naive_datetime
field :session_image, Uploaders.Post.Type

embeds_one :location, Location, on_replace: :delete

field :delete, :boolean, virtual: true

has_many :enrollments, Enrollment, foreign_key: :session_id
belongs_to :activity, Activity

timestamps()
Expand Down
1 change: 0 additions & 1 deletion lib/atomic/organizations/department.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ defmodule Atomic.Organizations.Department do
field :description, :string

many_to_many :activities, Activity, join_through: ActivityDepartment, on_replace: :delete

belongs_to :organization, Organization, on_replace: :delete_if_exists

timestamps()
Expand Down
28 changes: 28 additions & 0 deletions lib/atomic/uploaders/post.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
defmodule Atomic.Uploaders.Post do
@moduledoc false
use Waffle.Definition
use Waffle.Ecto.Definition
alias Atomic.Activities.Session

@versions [:original]
@extension_whitelist ~w(.svg .jpg .jpeg .gif .png)

def validate({file, _}) do
file.file_name
|> Path.extname()
|> String.downcase()
|> then(&Enum.member?(@extension_whitelist, &1))
|> case do
true -> :ok
false -> {:error, "invalid file type"}
end
end

def filename(version, _) do
version
end

def storage_dir(_version, {_file, %Session{} = scope}) do
"uploads/atomic/sessions/#{scope.id}"
end
end
11 changes: 5 additions & 6 deletions lib/atomic_web/live/activity_live/index.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ defmodule AtomicWeb.ActivityLive.Index do

@impl true
def mount(params, _session, socket) do
{:ok, assign(socket, :activities, list_activities(params["organization_id"]))}
{:ok, assign(socket, :activities, list_sessions(params["organization_id"]))}
end

@impl true
Expand Down Expand Up @@ -52,12 +52,11 @@ defmodule AtomicWeb.ActivityLive.Index do
activity = Activities.get_activity!(id)
{:ok, _} = Activities.delete_activity(activity)

{:noreply, assign(socket, :activies, list_activities(socket.assigns.current_organization.id))}
{:noreply, assign(socket, :activies, list_sessions(socket.assigns.current_organization.id))}
end

def handle_event("open-enrollments", _payload, socket) do
{:noreply,
assign(socket, :activities, list_activities(socket.assigns.current_organization.id))}
{:noreply, assign(socket, :activities, list_sessions(socket.assigns.current_organization.id))}
end

def handle_event("activities-enrolled", _payload, socket) do
Expand All @@ -67,9 +66,9 @@ defmodule AtomicWeb.ActivityLive.Index do
{:noreply, assign(socket, :activities, activities)}
end

defp list_activities(organization_id) do
defp list_sessions(organization_id) do
Activities.list_activities_by_organization_id(organization_id,
preloads: [:activity_sessions, :enrollments, :speakers]
preloads: [:activity_sessions, :speakers]
)
end
end
90 changes: 46 additions & 44 deletions lib/atomic_web/live/activity_live/index.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -33,58 +33,60 @@
<div class="overflow-hidden bg-white">
<ul role="list" class="divide-y divide-zinc-200">
<%= for activity <- @activities do %>
<li>
<%= live_redirect to: Routes.activity_show_path(@socket, :show, @current_organization, activity), class: "block hover:bg-zinc-50", replace: false do %>
<div class="px-4 py-4 lg:px-6">
<div class="flex items-center justify-between">
<p class="truncate text-sm font-medium text-zinc-900">
<%= activity.title %>
</p>
</div>
<div class="mt-2 lg:flex lg:justify-between">
<div class="lg:flex lg:space-x-3">
<p class="mt-2 flex items-center text-sm text-zinc-500 lg:mt-0">
<Heroicons.Solid.users class="flex-shrink-0 mr-1.5 w-5 h-5 text-zinc-400" />
<%= Enum.count(activity.enrollments) %> / <%= activity.maximum_entries %>
</p>
<p class="mt-2 flex items-center text-sm text-zinc-500 lg:mt-0">
<Heroicons.Solid.calendar class="flex-shrink-0 mr-1.5 w-5 h-5 text-zinc-400" />
<%= if hd(activity.activity_sessions) do %>
<%= AtomicWeb.ViewUtils.display_date(hd(activity.activity_sessions).start) %>
<% end %>
<%= for session <- activity.activity_sessions do %>
<li>
<%= live_redirect to: Routes.activity_show_path(@socket, :show, @current_organization, session), class: "block hover:bg-zinc-50", replace: false do %>
<div class="px-4 py-4 lg:px-6">
<div class="flex items-center justify-between">
<p class="truncate text-sm font-medium text-zinc-900">
<%= activity.title %>
</p>
<%= if not is_nil(hd(activity.activity_sessions).location) do %>
</div>
<div class="mt-2 lg:flex lg:justify-between">
<div class="lg:flex lg:space-x-3">
<p class="mt-2 flex items-center text-sm text-zinc-500 lg:mt-0">
<Heroicons.Solid.users class="flex-shrink-0 mr-1.5 w-5 h-5 text-zinc-400" />
<%= Enum.count(session.enrollments) %> / <%= activity.maximum_entries %>
</p>
<p class="mt-2 flex items-center text-sm text-zinc-500 lg:mt-0">
<Heroicons.Solid.location_marker class="flex-shrink-0 mr-1.5 w-5 h-5 text-zinc-400" />
<%= if hd(activity.activity_sessions).location do %>
<%= hd(activity.activity_sessions).location && hd(activity.activity_sessions).location.name %>
<Heroicons.Solid.calendar class="flex-shrink-0 mr-1.5 w-5 h-5 text-zinc-400" />
<%= if hd(activity.activity_sessions) do %>
<%= AtomicWeb.ViewUtils.display_date(hd(activity.activity_sessions).start) %>
<% end %>
</p>
<% end %>
</div>
</div>
<div class="flex flex-col-reverse lg:flex-row-reverse lg:items-center lg:justify-between">
<div class="mt-2 flex items-center text-sm text-zinc-500 lg:mt-0">
<Heroicons.Solid.bell class="flex-shrink-0 mr-1.5 w-5 h-5 text-zinc-400" /> Closing
<%= if not is_nil(hd(activity.activity_sessions).location) do %>
<p class="mt-2 flex items-center text-sm text-zinc-500 lg:mt-0">
<Heroicons.Solid.location_marker class="flex-shrink-0 mr-1.5 w-5 h-5 text-zinc-400" />
<%= if hd(activity.activity_sessions).location do %>
<%= hd(activity.activity_sessions).location && hd(activity.activity_sessions).location.name %>
<% end %>
</p>
<% end %>
</div>
</div>
<div class="flex flex-row space-x-2">
<%= for speaker <- activity.speakers do %>
<div class="mt-2 flex items-center">
<span class="inline-flex justify-center items-center mr-1.5 w-6 h-6 bg-zinc-500 rounded-full">
<span class="text-xs font-medium leading-none text-white">
<%= Accounts.extract_initials(speaker.name) %>
<div class="flex flex-col-reverse lg:flex-row-reverse lg:items-center lg:justify-between">
<div class="mt-2 flex items-center text-sm text-zinc-500 lg:mt-0">
<Heroicons.Solid.bell class="flex-shrink-0 mr-1.5 w-5 h-5 text-zinc-400" /> Closing
</div>
<div class="flex flex-row space-x-2">
<%= for speaker <- activity.speakers do %>
<div class="mt-2 flex items-center">
<span class="inline-flex justify-center items-center mr-1.5 w-6 h-6 bg-zinc-500 rounded-full">
<span class="text-xs font-medium leading-none text-white">
<%= Accounts.extract_initials(speaker.name) %>
</span>
</span>
</span>
<p class="text-sm text-zinc-500">
<%= Accounts.extract_first_last_name(speaker.name) %>
</p>
</div>
<% end %>
<p class="text-sm text-zinc-500">
<%= Accounts.extract_first_last_name(speaker.name) %>
</p>
</div>
<% end %>
</div>
</div>
</div>
</div>
<% end %>
</li>
<% end %>
</li>
<% end %>
<% end %>
</ul>
</div>
Expand Down
Loading

0 comments on commit f944f90

Please sign in to comment.