Skip to content

Commit

Permalink
Add organization index page
Browse files Browse the repository at this point in the history
  • Loading branch information
MarioRodrigues10 committed Aug 9, 2023
1 parent f04e40a commit 4f69414
Show file tree
Hide file tree
Showing 12 changed files with 137 additions and 90 deletions.
7 changes: 5 additions & 2 deletions lib/atomic/organizations.ex
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ defmodule Atomic.Organizations do
[%Organization{}, ...]
"""
def list_organizations do
Repo.all(Organization)

def list_organizations(opts) do
Organization
|> apply_filters(opts)
|> Repo.all()
end

@doc """
Expand Down
19 changes: 10 additions & 9 deletions lib/atomic_web/live/activity_live/show.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,15 @@

<div class="flex flex-row space-x-1">
<%= if @current_user.role in [:admin] or is_admin?(@current_user, @activity) do %>
<span class="w-fit rounded bg-zinc-400 py-2 px-3.5 text-sm font-medium text-white shadow-sm hover:bg-zinc-600 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">
<%= live_patch("Edit", to: Routes.activity_edit_path(@socket, :edit, @activity, @current_organization), class: "button") %>
</span>
<span class="w-fit rounded bg-zinc-400 py-2 px-3.5 text-sm font-medium text-white shadow-sm hover:bg-zinc-600 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">
<%= link("Delete", to: "#", phx_click: "delete", phx_value_id: @activity.id, data: [confirm: "Are you sure?"]) %>
</span>
<%= live_patch to: Routes.activity_edit_path(@socket, :edit, @activity, @current_organization), class: "button" do %>
<div type="button" class="inline-flex justify-center py-2 px-4 w-fit text-sm font-medium text-gray-700 bg-white rounded-md border border-gray-300 shadow-sm hover:bg-gray-50" id="sort-menu-button" aria-expanded="false" aria-haspopup="true">
<Heroicons.Solid.pencil class="mr-3 w-5 h-5 text-gray-400" /> Edit
</div>
<% end %>
<%= link to: "#", phx_click: "delete", phx_value_id: @activity.id, data: [confirm: "Are you sure?"] do %>
<div type="button" class="inline-flex justify-center py-2 px-4 w-fit text-sm font-medium text-gray-700 bg-white rounded-md border border-gray-300 shadow-sm hover:bg-gray-50" id="sort-menu-button" aria-expanded="false" aria-haspopup="true">
<Heroicons.Solid.x class="mr-3 w-5 h-5 text-gray-400" /> Delete
</div>
<% end %>
<% end %>
<span class="w-fit rounded bg-zinc-400 py-2 px-3.5 text-sm font-medium text-white shadow-sm hover:bg-zinc-600 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">
<%= live_redirect("Back", to: Routes.activity_index_path(@socket, :index, @current_organization)) %>
</span>
</div>
27 changes: 18 additions & 9 deletions lib/atomic_web/live/department_live/index.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -49,21 +49,30 @@
</div>
<%= if Organizations.get_role(@current_user.id, @current_organization.id) in [:owner, :admin] do %>
<div>
<div class="-mt-px flex divide-x divide-gray-200">
<div class="-ml-px flex w-0 flex-1 z-1">
<%= live_patch("Edit",
<div class="-mt-px flex py-2">
<div class="flex flex-1 z-1">
<%= live_patch(
to: Routes.department_index_path(@socket, :edit, @current_organization, department),
class: "relative -mr-px inline-flex w-0 flex-1 items-center justify-center gap-x-3 rounded-bl-lg border border-transparent py-4 text-sm font-semibold text-gray-900 hover:bg-gray-300"
) %>
class: "w-full relative inline-flex flex-1 items-center justify-center gap-x-3 rounded-bl-lg border border-transparent text-sm font-semibold text-gray-900"
) do %>
<div type="button" class="inline-flex justify-center py-2 px-4 w-fit text-sm font-medium text-gray-700 bg-white rounded-md border border-gray-300 shadow-sm hover:bg-gray-200" id="sort-menu-button" aria-expanded="false" aria-haspopup="true">
<Heroicons.Solid.pencil class="mr-3 w-5 h-5 text-gray-400" /> Edit
</div>
<% end %>
</div>

<div class="-ml-px flex w-0 flex-1">
<%= link("Delete",
<%= link(
to: "#",
phx_click: "delete",
class: "relative -mr-px inline-flex w-0 flex-1 items-center justify-center gap-x-3 rounded-bl-lg border border-transparent py-4 text-sm font-semibold text-gray-900 hover:bg-gray-300",
class: "w-full relative inline-flex flex-1 items-center justify-center gap-x-3 rounded-bl-lg border border-transparent text-sm font-semibold text-gray-900",
phx_value_id: department.id,
data: [confirm: "Are you sure?"]
) %>
data: [confirm: "Are you sure?"])
do %>
<div type="button" class="inline-flex justify-center py-2 px-4 w-fit text-sm font-medium text-gray-700 bg-white rounded-md border border-gray-300 shadow-sm hover:bg-gray-50" id="sort-menu-button" aria-expanded="false" aria-haspopup="true">
<Heroicons.Solid.x class="mr-3 w-5 h-5 text-gray-400" /> Delete
</div>
<% end %>
</div>
</div>
</div>
Expand Down
13 changes: 12 additions & 1 deletion lib/atomic_web/live/department_live/show.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,13 @@
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500"><%= capitalize_first_letter(collaborator.accepted) %></td>
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500"><%= display_date(collaborator.inserted_at) %> <%= display_time(collaborator.inserted_at) %></td>
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500"><%= display_date(collaborator.updated_at) %> <%= display_time(collaborator.updated_at) %></td>
<td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6">
<%= live_patch to: Routes.department_show_path(@socket, :edit, @current_organization, @department), class: "button" do %>
<div type="button" class="inline-flex justify-center py-2 px-4 w-fit text-sm font-medium text-gray-700 bg-white rounded-md border border-gray-300 shadow-sm hover:bg-gray-50" id="sort-menu-button" aria-expanded="false" aria-haspopup="true">
<Heroicons.Solid.pencil class="mr-3 w-5 h-5 text-gray-400" /> Edit
</div>
<% end %>
</td>
</tr>
<% end %>
</tbody>
Expand All @@ -114,5 +121,9 @@
</div>

<%= if Organizations.get_role(@current_user.id, @current_organization.id) in [:owner, :admin] do %>
<span><%= live_patch("Edit", to: Routes.department_show_path(@socket, :edit, @current_organization, @department), class: "button") %></span>
<%= live_patch to: Routes.department_show_path(@socket, :edit, @current_organization, @department), class: "button" do %>
<div type="button" class="inline-flex justify-center py-2 px-4 w-fit text-sm font-medium text-gray-700 bg-white rounded-md border border-gray-300 shadow-sm hover:bg-gray-50" id="sort-menu-button" aria-expanded="false" aria-haspopup="true">
<Heroicons.Solid.pencil class="mr-3 w-5 h-5 text-gray-400" /> Edit
</div>
<% end %>
<% end %>
4 changes: 3 additions & 1 deletion lib/atomic_web/live/membership_live/index.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500"><%= display_date(membership.updated_at) %> <%= display_time(membership.updated_at) %></td>
<td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6">
<%= link to: Routes.membership_edit_path(@socket, :edit, membership.organization_id, membership), class: "text-indigo-600 hover:text-indigo-900" do %>
Edit
<div type="button" class="inline-flex justify-center py-2 px-4 w-fit text-sm font-medium text-gray-700 bg-white rounded-md border border-gray-300 shadow-sm hover:bg-gray-50" id="sort-menu-button" aria-expanded="false" aria-haspopup="true">
<Heroicons.Solid.pencil class="mr-3 w-5 h-5 text-gray-400" /> Edit
</div>
<% end %>
</td>
</tr>
Expand Down
5 changes: 1 addition & 4 deletions lib/atomic_web/live/organization_live/form_component.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,18 @@ defmodule AtomicWeb.OrganizationLive.FormComponent do
use AtomicWeb, :live_component

alias Atomic.Activities
alias Atomic.Departments
alias Atomic.Organizations

@extensions_whitelist ~w(.svg .jpg .jpeg .gif .png)

@impl true
def mount(socket) do
departments = Departments.list_departments()
speakers = Activities.list_speakers()

{:ok,
socket
|> allow_upload(:card, accept: @extensions_whitelist, max_entries: 1)
|> assign(:speakers, speakers)
|> assign(:departments, departments)}
|> assign(:speakers, speakers)}
end

@impl true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@
<%= text_input(f, :description) %>
<%= error_tag(f, :description) %>

<%= label(f, :departments) %>
<%= multiple_select(f, :departments, Enum.map(@departments, &{&1.name, &1.id}), selected: Enum.map(@departments, & &1.id)) %>

<div class="py-5 px-4 sm:px-6 shrink-0 1.5xl:py-5 1.5xl:px-6 1.5xl:shrink-0">
<%= live_file_input(@uploads.card, class: "hidden") %>
<div
Expand Down
33 changes: 10 additions & 23 deletions lib/atomic_web/live/organization_live/index.ex
Original file line number Diff line number Diff line change
@@ -1,34 +1,19 @@
defmodule AtomicWeb.OrganizationLive.Index do
use AtomicWeb, :live_view

alias Atomic.Accounts
alias Atomic.Organizations
alias Atomic.Organizations.Organization
alias Atomic.Uploaders

@impl true
def mount(_params, session, socket) do
case session["user_token"] do
nil ->
{:ok,
socket
|> assign(:organizations, list_organizations())}

token ->
user = Accounts.get_user_by_session_token(token)

{:ok,
socket
|> assign(:organizations, list_organizations())
|> assign(:current_user, user)
|> assign(
:current_organization,
session["current_organization"]
)}
end
def mount(_params, _session, socket) do
{:ok, socket}
end

@impl true
def handle_params(params, _url, socket) do
organizations = list_organizations(params)

entries = [
%{
name: gettext("Organizations"),
Expand All @@ -40,6 +25,8 @@ defmodule AtomicWeb.OrganizationLive.Index do
socket
|> apply_action(socket.assigns.live_action, params)
|> assign(:breadcrumb_entries, entries)
|> assign(:params, params)
|> assign(:organizations, organizations)
|> assign(:current_page, :organizations)}
end

Expand Down Expand Up @@ -72,10 +59,10 @@ defmodule AtomicWeb.OrganizationLive.Index do
organization = Organizations.get_organization!(id)
{:ok, _} = Organizations.delete_organization(organization)

{:noreply, assign(socket, :organizations, list_organizations())}
{:noreply, assign(socket, :organizations, list_organizations(socket.assigns.params))}
end

defp list_organizations do
Organizations.list_organizations()
defp list_organizations(params) do
Organizations.list_organizations(params)
end
end
73 changes: 44 additions & 29 deletions lib/atomic_web/live/organization_live/index.html.heex
Original file line number Diff line number Diff line change
@@ -1,32 +1,47 @@
<%= if @live_action in [:new, :edit] do %>
<.modal return_to={Routes.organization_index_path(@socket, :index)}>
<.live_component module={AtomicWeb.OrganizationLive.FormComponent} id={@organization || :new} title={@page_title} action={@live_action} organization={@organization} return_to={Routes.organization_index_path(@socket, :index)} />
</.modal>
<% end %>
<div class="min-h-full bg-white">
<div class="pt-5 pr-6 pb-5 pl-4 border-gray-200 sm:pl-6 lg:pl-8 xl:pt-6 xl:pl-6">
<div class="flex justify-between items-center h-10">
<h1 class="text-xl font-bold leading-7 text-zinc-900 sm:truncate sm:text-4xl"><%= gettext("Organizations") %></h1>
<%= if @current_user.role in [:admin] do %>
<div class="flex flex-col sm:flex-row xl:flex-col">
<%= live_patch("+ New Organization", to: Routes.organization_index_path(@socket, :new), class: "border-2 rounded-md bg-white text-lg border-orange-500 py-2 px-3.5 text-sm font-medium text-orange-500 shadow-sm hover:bg-orange-500 hover:text-white") %>
</div>
<% end %>
</div>
</div>

<table>
<thead>
<tr>
<th>Name</th>
<th>Description</th>

<th></th>
</tr>
</thead>
<tbody id="organizations">
<ul role="list" class="relative z-0 border border-gray-200 rounded">
<%= for organization <- @organizations do %>
<tr id={"organization-#{organization.id}"}>
<td><%= organization.name %></td>
<td><%= organization.description %></td>

<td>
<span><%= live_patch("Show", to: Routes.organization_show_path(@socket, :show, organization.id)) %></span>
<span><%= live_patch("Edit", to: Routes.organization_index_path(@socket, :edit, organization.id)) %></span>
<span><%= link("Delete", to: "#", phx_click: "delete", phx_value_id: organization.id, data: [confirm: "Are you sure?"]) %></span>
</td>
</tr>
<%= live_redirect to: Routes.organization_show_path(@socket, :show, organization) do %>
<li id={"organization-#{organization.id}"} class="relative pr-6 border-b border-gray-200 hover:bg-gray-50">
<div class="flex justify-between items-center">
<div class="py-4 pr-3 pl-4 text-sm whitespace-nowrap sm:pl-6">
<div class="flex items-center">
<div>
<%= if is_nil(Uploaders.Logo.url({organization.logo, organization}, :original)) do %>
<div class="relative flex-shrink-0 rounded-2xl min-w-24 min-h-24 sm:min-w-32 sm:min-h-32">
<span class="inline-flex justify-center items-center w-24 h-24 rounded-2xl sm:w-32 sm:h-32 bg-gray-400">
<span class="text-4xl font-medium leading-none text-white select-none sm:text-5xl">
<%= Atomic.Accounts.extract_initials(organization.name) %>
</span>
</span>
</div>
<% else %>
<div class="relative flex-shrink-0 w-24 h-24 rounded-2xl sm:w-32 sm:h-32">
<img src={Uploaders.Logo.url({organization.logo, organization}, :original)} class="object-center absolute rounded-2xl w-[98px] h-[98px] sm:w-[130px] sm:h-[130px]" />
</div>
<% end %>
</div>
<div class="ml-4">
<div class="font-medium text-lg text-gray-900">
<%= organization.name %>
</div>
</div>
</div>
</div>
</div>
</li>
<% end %>
<% end %>
</tbody>
</table>

<span><%= live_patch("New Organization", to: Routes.organization_index_path(@socket, :new)) %></span>
</ul>
</div>
29 changes: 21 additions & 8 deletions lib/atomic_web/live/organization_live/show.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,28 @@
<img src={Routes.static_path(@socket, "/images/atomic.png")} class="mb-2 w-64 h-64 block lg:mb-8" />
<% end %>
</div>
<div class="flex-1">
<h1 class="text-2xl font-bold text-zinc-900 sm:text-3xl inline-flex w-full">
<%= @organization.name %>
<%= if not @following do %>
<button phx-click="follow" class="ml-4 w-32 border-2 rounded-md bg-orange-500 text-lg border-orange-500 py-2 px-3.5 text-sm font-medium text-white shadow-sm inline hover:bg-white hover:text-orange-500">Follow</button>
<% else %>
<button phx-click="unfollow" class="ml-4 w-32 border-2 rounded-md bg-white text-lg border-orange-500 py-2 px-3.5 text-sm font-medium text-orange-500 shadow-sm inline hover:bg-orange-500 hover:text-white">Unfollow</button>
<div class="flex-1 space-x-2">
<%= if Organizations.get_role(@current_user.id, @organization.id) in [:owner, :admin] do %>
<%= live_patch to: Routes.organization_index_path(@socket, :edit, @organization), class: "button" do %>
<div type="button" class="inline-flex justify-center py-2 px-4 w-fit text-sm font-medium text-gray-700 bg-white rounded-md border border-gray-300 shadow-sm hover:bg-gray-50" id="sort-menu-button" aria-expanded="false" aria-haspopup="true">
<Heroicons.Solid.pencil class="mr-3 w-5 h-5 text-gray-400" /> Edit
</div>
<% end %>
</h1>
<%= link to: "#", phx_click: "delete", phx_value_id: @organization.id, data: [confirm: "Are you sure?"] do %>
<div type="button" class="inline-flex justify-center py-2 px-4 w-fit text-sm font-medium text-gray-700 bg-white rounded-md border border-gray-300 shadow-sm hover:bg-gray-50" id="sort-menu-button" aria-expanded="false" aria-haspopup="true">
<Heroicons.Solid.x class="mr-3 w-5 h-5 text-gray-400" /> Delete
</div>
<% end %>
<% else %>
<h1 class="text-2xl font-bold text-zinc-900 sm:text-3xl inline-flex w-full">
<%= @organization.name %>
<%= if not @following do %>
<button phx-click="follow" class="ml-4 w-32 border-2 rounded-md bg-orange-500 text-lg border-orange-500 py-2 px-3.5 text-sm font-medium text-white shadow-sm inline hover:bg-white hover:text-orange-500">Follow</button>
<% else %>
<button phx-click="unfollow" class="ml-4 w-32 border-2 rounded-md bg-white text-lg border-orange-500 py-2 px-3.5 text-sm font-medium text-orange-500 shadow-sm inline hover:bg-orange-500 hover:text-white">Unfollow</button>
<% end %>
</h1>
<% end %>
</div>
</div>
<span class="break-normal"><%= @organization.description %></span>
Expand Down
12 changes: 12 additions & 0 deletions lib/atomic_web/live/scanner_live/index.ex
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ defmodule AtomicWeb.ScannerLive.Index do
|> assign(:breadcrumb_entries, entries)}
end

@doc """
Handles the scan event.
Basically it does two checks:
1) Verifies if current_organization is in organizations that are related to the session of the activity.
2) Verifies if current_user is admin or owner of the organization, or , if current_user is admin of the system.
If 1) and 2) are true, then confirm_participation is called.
Else a flash message is shown and the user is redirected to the scanner index.
"""
@impl true
def handle_event("scan", pathname, socket) do
[_, session_id, user_id | _] = String.split(pathname, "/")
Expand All @@ -47,6 +56,9 @@ defmodule AtomicWeb.ScannerLive.Index do
end
end

# Updates the enrollment of the user in the session, setting present to true.
# If the update is successful, a flash message is shown and the user is redirected to the scanner index.
# Else a flash message is shown and the user is redirected to the scanner index.
defp confirm_participation(socket, session_id, user_id) do
case Activities.update_enrollment(Activities.get_enrollment!(session_id, user_id), %{
present: true
Expand Down
2 changes: 1 addition & 1 deletion test/atomic/organizations_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ defmodule Atomic.OrganizationsTest do
organization = insert(:organization)

organizations =
Organizations.list_organizations()
Organizations.list_organizations([])
|> Enum.map(& &1.id)

assert organizations == [organization.id]
Expand Down

0 comments on commit 4f69414

Please sign in to comment.