Skip to content

Commit 716dbdd

Browse files
authored
fix: attendee credential association (#434)
1 parent b20f659 commit 716dbdd

File tree

16 files changed

+182
-174
lines changed

16 files changed

+182
-174
lines changed

lib/safira/accounts.ex

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,27 @@ defmodule Safira.Accounts do
585585
|> Repo.update()
586586
end
587587

588+
@doc """
589+
Links a credential to an attendee.
590+
591+
## Examples
592+
593+
iex> link_credential(credential_id, attendee_id)
594+
{:ok, %Credential{}}
595+
596+
iex> link_credential(credential_id, attendee_id)
597+
{:error, %Ecto.Changeset{}}
598+
599+
"""
600+
def link_credential(credential_id, attendee_id) do
601+
credential = get_credential!(credential_id)
602+
attendee = get_attendee!(attendee_id)
603+
604+
credential
605+
|> Credential.changeset(%{attendee_id: attendee.id})
606+
|> Repo.update()
607+
end
608+
588609
@doc """
589610
Deletes a credential.
590611
@@ -614,6 +635,42 @@ defmodule Safira.Accounts do
614635
Credential.changeset(credential, attrs)
615636
end
616637

638+
@doc """
639+
Checks if a credential exists.
640+
641+
## Examples
642+
643+
iex> credential_exists?(123)
644+
true
645+
646+
iex> credential_exists?(456)
647+
false
648+
649+
"""
650+
def credential_exists?(id) do
651+
Credential
652+
|> where([c], c.id == ^id)
653+
|> Repo.exists?()
654+
end
655+
656+
@doc """
657+
Checks if a credential is linked to an attendee.
658+
659+
## Examples
660+
661+
iex> credential_linked?(credential_id)
662+
true
663+
664+
iex> credential_linked?(credential_id)
665+
false
666+
667+
"""
668+
def credential_linked?(credential_id) do
669+
credential = get_credential!(credential_id)
670+
671+
credential.attendee_id != nil
672+
end
673+
617674
@doc """
618675
Gets a single credential associated to the given attendee.
619676

lib/safira_web/components/layouts/app.html.heex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
</button>
2727
</div>
2828
<main class="text-light bg-primaryDark flex-1 relative z-0 overflow-y-auto focus:outline-none">
29-
<div class="px-4 sm:px-6 lg:px-8 py-8">
29+
<div class="px-6 sm:px-6 lg:px-8 py-8">
3030
<.flash_group flash={@flash} />
3131
<%= @inner_content %>
3232
</div>

lib/safira_web/helpers.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ defmodule SafiraWeb.Helpers do
1818

1919
case URI.parse(url) do
2020
%URI{host: host, path: path} ->
21-
if host == app_host or Mix.env() == :dev do
21+
if (host == app_host or Mix.env() == :dev) and not is_nil(path) do
2222
case extract_id_from_url_path(path) do
2323
:error -> {:error, "not a valid id"}
2424
result -> result
@@ -154,7 +154,7 @@ defmodule SafiraWeb.Helpers do
154154
end
155155

156156
def draw_qr_code(qr_code) do
157-
internal_route = "/qr_codes/#{qr_code.id}"
157+
internal_route = "/app/attendees/#{qr_code.id}"
158158
url = build_url() <> internal_route
159159

160160
url
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
defmodule SafiraWeb.App.CredentialLive.Edit do
2+
use SafiraWeb, :app_view
3+
4+
alias Safira.Accounts
5+
6+
@impl true
7+
def mount(_params, _session, socket) do
8+
{:ok, socket}
9+
end
10+
11+
@impl true
12+
def handle_params(_params, _url, socket) do
13+
{:noreply, socket |> assign(:modal_data, nil)}
14+
end
15+
16+
@impl true
17+
def handle_event("scan", data, socket) do
18+
case safely_extract_id_from_url(data) do
19+
{:ok, id} ->
20+
if Accounts.credential_exists?(id) do
21+
if Accounts.credential_linked?(id) do
22+
{:noreply, socket |> assign(:modal_data, :already_linked)}
23+
else
24+
Accounts.link_credential(id, socket.assigns.current_user.attendee.id)
25+
{:noreply, socket |> push_navigate(to: ~p"/app")}
26+
end
27+
else
28+
{:noreply, socket |> assign(:modal_data, :not_found)}
29+
end
30+
31+
{:error, _} ->
32+
{:noreply, socket |> assign(:modal_data, :invalid)}
33+
end
34+
end
35+
36+
@impl true
37+
def handle_event("close-modal", _, socket) do
38+
{:noreply, socket |> assign(:modal_data, nil)}
39+
end
40+
41+
def error_message(:not_found),
42+
do: gettext("This credential is not registered in the event's system! (404)")
43+
44+
def error_message(:already_linked),
45+
do: gettext("This credential is already linked to another attendee! (400)")
46+
47+
def error_message(:invalid), do: gettext("Not a valid credential! (400)")
48+
end

lib/safira_web/live/backoffice/scanner_live/index.html.heex renamed to lib/safira_web/live/app/credential_live/edit.html.heex

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<.page title="Identify an attendee">
1+
<.page title="Link Credential" size={:xl} title_class="font-terminal uppercase">
22
<div
33
id="qr-scanner"
44
phx-hook="QrScanner"
@@ -33,10 +33,8 @@
3333
<div class="flex flex-row gap-4 items-center">
3434
<.icon name="hero-x-circle" class="text-red-500 w-8" />
3535
<p>
36-
<%= if @modal_data == :not_found do %>
37-
<%= gettext("This credential is not associated with an attendee!") %>
38-
<% else %>
39-
<%= gettext("Not a valid credential!") %>
36+
<%= if @modal_data do %>
37+
<%= error_message(@modal_data) %>
4038
<% end %>
4139
</p>
4240
</div>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
defmodule SafiraWeb.App.CredentialLive.Index do
2+
use SafiraWeb, :app_view
3+
4+
alias Safira.Accounts
5+
6+
@impl true
7+
def mount(_params, _session, socket) do
8+
{:ok,
9+
socket
10+
|> assign(:current_page, :credential)
11+
|> assign(
12+
:credential,
13+
Accounts.get_credential_of_attendee!(socket.assigns.current_user.attendee)
14+
)}
15+
end
16+
end
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<.page title="Credential" size={:xl} title_class="font-terminal uppercase">
2+
<p>
3+
<%= gettext(
4+
"The code below is used to identify you in case you are missing your physical credential."
5+
) %>
6+
</p>
7+
<div class="mt-24 mx-auto w-fit scale-125 sm:scale-150 p-1 bg-white rounded-xl select-none">
8+
<%= draw_qr_code(@credential) |> raw %>
9+
<p class="text-center text-xs text-primaryDark font-semibold pb-1">
10+
<%= @current_user.name %>
11+
</p>
12+
</div>
13+
</.page>

lib/safira_web/live/backoffice/scanner_live/index.ex

Lines changed: 0 additions & 33 deletions
This file was deleted.

lib/safira_web/live/credential_live/edit.ex

Lines changed: 0 additions & 37 deletions
This file was deleted.

lib/safira_web/live/credential_live/edit.html.heex

Lines changed: 0 additions & 17 deletions
This file was deleted.

0 commit comments

Comments
 (0)