Skip to content

Commit

Permalink
Add events and qrcodes to activities (#284)
Browse files Browse the repository at this point in the history
  • Loading branch information
MarioRodrigues10 authored Jun 30, 2023
1 parent 44ade10 commit 2798b1f
Show file tree
Hide file tree
Showing 43 changed files with 370 additions and 35 deletions.
5 changes: 4 additions & 1 deletion assets/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@ import {Socket} from "phoenix"
import {LiveSocket} from "phoenix_live_view"
import "../vendor/alpine.js";
import topbar from "../vendor/topbar"
import { QrScanner } from "./qr_reading.js";

let Hooks = {};
let Hooks = {
QrScanner: QrScanner
};

let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
let liveSocket = new LiveSocket("/live", Socket, {
Expand Down
54 changes: 54 additions & 0 deletions assets/js/qr_reading.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Html5Qrcode, Html5QrcodeSupportedFormats } from "../vendor/html5-qrcode.js"

function parseURL(url) {
try {
const url_obj = new URL(url);

if (url_obj.host !== window.location.host) return null;
return url_obj.pathname.split("/").splice(1).join("/");
} catch {
return null;
}
}

export const QrScanner = {

mounted() {
const config = { fps: 4, qrbox: (width, height) => {return { width: width * 0.8, height: height * 0.9 }}};
this.scanner = new Html5Qrcode(this.el.id, { formatsToSupport: [ Html5QrcodeSupportedFormats.QR_CODE ] });

const onScanSuccess = (decodedText, decodedResult) => {
const pathname = parseURL(decodedText);
if (pathname != null && pathname !== this.lastRead) {
this.lastRead = pathname;
if (this.el.dataset.on_success)
Function("hook", "pathname", this.el.dataset.on_success)(this, pathname);
}
}

const startScanner = () => {
this.scanner.start({ facingMode: "environment" }, config, onScanSuccess)
.then((_) => {
if (this.el.dataset.on_start)
Function("hook", this.el.dataset.on_start)(this);
}, (e) => {
if (this.el.dataset.on_error)
Function("hook", this.el.dataset.on_error)(this);
});
}

if (this.el.dataset.ask_perm) {
document.getElementById(this.el.dataset.ask_perm).addEventListener("click", startScanner);
}

if (this.el.dataset.open_on_mount !== undefined)
startScanner();
},

destroyed() {
this.scanner.stop().then((_) => {
if (this.el.dataset.on_stop)
Function("hook", this.el.dataset.on_stop)(this);
});
}
}
6 changes: 6 additions & 0 deletions assets/vendor/html5-qrcode.js

Large diffs are not rendered by default.

36 changes: 33 additions & 3 deletions lib/atomic/accounts.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ defmodule Atomic.Accounts do
import Ecto.Query, warn: false
alias Atomic.Repo

alias Atomic.Accounts.{Course, User, UserToken, UserNotifier}
alias Atomic.Accounts.{Course, User, UserNotifier, UserToken}

## Database getters

Expand Down Expand Up @@ -80,11 +80,41 @@ defmodule Atomic.Accounts do
|> Repo.insert()
end

def list_users() do
def list_users do
User
|> Repo.all()
end

def get_course(id) do
Repo.get(Course, id)
end

@doc """
Return the initials of a name.
## Examples
iex> extract_initials("John Doe")
"JD"
iex> extract_initials("John")
"J"
iex> extract_initials(nil)
""
"""
def extract_initials(nil), do: ""

def extract_initials(name) do
initials = name |> String.upcase() |> String.split(" ") |> Enum.map(&String.slice(&1, 0, 1))

case length(initials) do
1 -> hd(initials)
_ -> List.first(initials) <> List.last(initials)
end
end

@doc """
Returns an `%Ecto.Changeset{}` for tracking user changes.
Expand Down Expand Up @@ -373,7 +403,7 @@ defmodule Atomic.Accounts do
|> User.changeset(attrs)
end

def list_courses() do
def list_courses do
Repo.all(Course)
end

Expand Down
1 change: 1 addition & 0 deletions lib/atomic/accounts/user_notifier.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
defmodule Atomic.Accounts.UserNotifier do
@moduledoc false
import Swoosh.Email

alias Atomic.Mailer
Expand Down
3 changes: 3 additions & 0 deletions lib/atomic/accounts/user_token.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
defmodule Atomic.Accounts.UserToken do
@moduledoc """
The UserToken context.
"""
use Atomic.Schema

alias Atomic.Accounts.UserToken
Expand Down
30 changes: 30 additions & 0 deletions lib/atomic/activities.ex
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ defmodule Atomic.Activities do
|> Repo.preload(preloads)
end

alias Atomic.Activities.Enrollment

def is_participating?(activity_id, user_id) do
Enrollment
|> where(activity_id: ^activity_id, user_id: ^user_id)
|> Repo.one()
|> case do
nil -> false
_ -> true
end
end

@doc """
Creates a activity.
Expand Down Expand Up @@ -233,6 +245,24 @@ defmodule Atomic.Activities do
"""
def get_enrollment!(id), do: Repo.get!(Enrollment, id)

def get_enrollment!(activity_id, user_id) do
Enrollment
|> where(activity_id: ^activity_id, user_id: ^user_id)
|> Repo.one()
end

def get_user_enrolled(user, activity) do
enrollment =
Enrollment
|> where(user_id: ^user.id, activity_id: ^activity.id)
|> Repo.one()

case enrollment do
nil -> create_enrollment(activity, user)
_ -> enrollment
end
end

@doc """
Creates an enrollment.
Expand Down
4 changes: 3 additions & 1 deletion lib/atomic/activities/activity.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ defmodule Atomic.Activities.Activity do
alias Atomic.Activities.Speaker
alias Atomic.Departments
alias Atomic.Departments.Department
alias Atomic.Events.Event
@required_fields ~w(title description
minimum_entries maximum_entries)a

@optional_fields []
@optional_fields ~w(event_id)a

schema "activities" do
field :title, :string
Expand All @@ -35,6 +36,7 @@ defmodule Atomic.Activities.Activity do
preload_order: [asc: :start]

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

timestamps()
end
Expand Down
24 changes: 24 additions & 0 deletions lib/atomic/events/enrollment.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
defmodule Atomic.Events.Enrollment do
@moduledoc """
An event enrollment.
"""
use Atomic.Schema

alias Atomic.Accounts.User
alias Atomic.Events.Event

schema "enrollments" do
field :present, :boolean
belongs_to :event, Event
belongs_to :user, User

timestamps()
end

@doc false
def changeset(enrollment, attrs) do
enrollment
|> cast(attrs, [:event_id, :user_id, :present])
|> validate_required([:event_id, :user_id])
end
end
29 changes: 29 additions & 0 deletions lib/atomic/events/event.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
defmodule Atomic.Events.Event do
@moduledoc false
use Ecto.Schema
import Ecto.Changeset

alias Atomic.Activities.Activity
alias Atomic.Activities.Location
alias Atomic.Events.Enrollment
alias Atomic.Events.EventOrganization
@required_fields ~w(name location_id)a

schema "events" do
field :name, :string
field :description, :string
belongs_to :event_organization, EventOrganization
embeds_one :location, Location, on_replace: :delete
has_many :activities, Activity
has_many :enrollments, Enrollment

timestamps()
end

@doc false
def changeset(events, attrs) do
events
|> cast(attrs, @required_fields)
|> validate_required([])
end
end
22 changes: 22 additions & 0 deletions lib/atomic/events/event_organization.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
defmodule Atomic.Events.EventOrganization do
@moduledoc false
use Ecto.Schema
import Ecto.Changeset

alias Atomic.Events.Event
alias Atomic.Organizations.Organization

schema "event_organizations" do
belongs_to :event, Event
belongs_to :organization, Organization

timestamps()
end

@doc false
def changeset(event_organization, attrs) do
event_organization
|> cast(attrs, [:event_id, :organization_id])
|> validate_required([])
end
end
1 change: 1 addition & 0 deletions lib/atomic/mailer.ex
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
defmodule Atomic.Mailer do
@moduledoc false
use Swoosh.Mailer, otp_app: :atomic
end
3 changes: 1 addition & 2 deletions lib/atomic/organizations.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@ defmodule Atomic.Organizations do

use Atomic.Context

alias Atomic.Organizations.UserOrganization
alias Atomic.Repo
alias Atomic.Accounts.User
alias Atomic.Organizations.Membership
alias Atomic.Organizations.Organization
alias Atomic.Organizations.UserOrganization
alias Atomic.Repo

@doc """
Returns the list of organizations.
Expand Down
2 changes: 0 additions & 2 deletions lib/atomic/organizations/card.ex
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ defmodule Atomic.Organizations.Card do
field :number_y, :float
end

# TODO: Validations

def changeset(card, attrs) do
card
|> cast(attrs, @optional_fields)
Expand Down
1 change: 1 addition & 0 deletions lib/atomic/organizations/membership.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
defmodule Atomic.Organizations.Membership do
@moduledoc false
use Atomic.Schema

alias Atomic.Accounts.User
Expand Down
5 changes: 3 additions & 2 deletions lib/atomic/organizations/organization.ex
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
defmodule Atomic.Organizations.Organization do
@moduledoc false
use Atomic.Schema
alias Atomic.Accounts.User
alias Atomic.Departments.Department
alias Atomic.Activities.Location
alias Atomic.Departments.Department
alias Atomic.Organizations.Card
alias Atomic.Organizations.Membership
alias Atomic.Partnerships.Partner
alias Atomic.Organizations.Card
alias Atomic.Uploaders

@required_fields ~w(name description)a
Expand Down
3 changes: 2 additions & 1 deletion lib/atomic/organizations/users_organizations.ex
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
defmodule Atomic.Organizations.UserOrganization do
@moduledoc false
use Atomic.Schema

alias Atomic.Accounts.User
alias Atomic.Organizations.Organization
alias Atomic.Ecto.Year
alias Atomic.Organizations.Organization

@required_fields ~w(year title user_id organization_id)a

Expand Down
2 changes: 1 addition & 1 deletion lib/atomic/partnerships/partner.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ defmodule Atomic.Partnerships.Partner do
"""
use Atomic.Schema
import Ecto.Changeset
alias Atomic.Uploaders
alias Atomic.Organizations.Organization
alias Atomic.Uploaders

@required_fields ~w(name description)a

Expand Down
7 changes: 3 additions & 4 deletions lib/atomic/quantum/certificate_delivery.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ defmodule Atomic.Quantum.CertificateDelivery do
"""
import Ecto.Query, warn: false
alias Atomic.Repo
alias Atomic.Mailer

alias Atomic.Repo
alias Atomic.Activities.{Enrollment, Session}

alias AtomicWeb.ActivityEmails
Expand Down Expand Up @@ -91,7 +90,7 @@ defmodule Atomic.Quantum.CertificateDelivery do

# The result of the query is the IDs of the activities, not the structs
# themselves.
defp last_sessions_query() do
defp last_sessions_query do
now = DateTime.utc_now()
minimum_finish = DateTime.add(now, -24, :hour)

Expand All @@ -115,7 +114,7 @@ defmodule Atomic.Quantum.CertificateDelivery do
# - The user has participated in the session (meaning the present field
# of the enrollment will be true)

defp included_enrollments() do
defp included_enrollments do
enrollments =
from s in subquery(last_sessions_query()),
inner_join: e in Enrollment,
Expand Down
1 change: 1 addition & 0 deletions lib/atomic/scheduler.ex
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
defmodule Atomic.Scheduler do
@moduledoc false
use Quantum, otp_app: :atomic
end
1 change: 1 addition & 0 deletions lib/atomic/uploaders/card.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
defmodule Atomic.Uploaders.Card do
@moduledoc false
use Waffle.Definition
use Waffle.Ecto.Definition
alias Atomic.Organizations.Organization
Expand Down
Loading

0 comments on commit 2798b1f

Please sign in to comment.