Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated Collaborator Handle + Add Notification Email #39

Merged
merged 14 commits into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions lib/cursif/notebooks.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ defmodule Cursif.Notebooks do
import Ecto.Query, warn: false
alias Cursif.Repo

alias CursifWeb.Emails.UserEmail
alias Cursif.Notebooks.{Notebook, Collaborator, Favorite}
alias Cursif.Accounts.{User}
alias Cursif.Accounts
Expand Down Expand Up @@ -208,4 +209,11 @@ defmodule Cursif.Notebooks do
Repo.delete_all(from n in Favorite,
where: n.user_id == ^user_id and n.notebook_id == ^notebook_id)
end

@doc """
Send invite to a collaborator.
"""
def send_notification(%User{} = user, notebook_id, owner) do
UserEmail.send_collaborator_email(user, notebook_id, owner)
end
end
14 changes: 12 additions & 2 deletions lib/cursif_web/emails/user_email.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ defmodule CursifWeb.Emails.UserEmail do
@client_url Application.compile_env(:cursif, :client_url)
@client_email Application.compile_env(:cursif, :email_sender)

defp send_email(user, subject, base_url, context) do
defp send_email(user, subject, base_url, context, extra_context \\ %{}) do
email_context = Map.merge(%{username: user.username, base_url: base_url}, extra_context)

email =
new()
|> from({"Cursif", @client_email})
|> to(user.email)
|> subject(subject)
|> render_body(context, %{username: user.username, base_url: base_url})
|> render_body(context, email_context)

with {:ok, _metadata} <- Mailer.deliver(email) do
{:ok, email}
Expand All @@ -37,4 +39,12 @@ defmodule CursifWeb.Emails.UserEmail do
base_url = "#{@client_url}/reset-password?token=#{token}"
send_email(user, "Cursif ~ Password Reset", base_url, "reset.html")
end

@doc """
Sends a collaboration invitation email to a user.
"""
def send_collaborator_email(user, notebook, owner) do
base_url = "#{@client_url}/notebooks/#{notebook}"
send_email(user, "Cursif ~ Collaboration Notification", base_url, "add.html", %{owner: owner})
end
end
14 changes: 11 additions & 3 deletions lib/cursif_web/resolvers/collaborators.ex
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
defmodule CursifWeb.Resolvers.Collaborators do
alias Cursif.Notebooks
alias Cursif.Notebooks.Collaborator
alias Cursif.Accounts

@spec add_collaborator(map(), map()) :: {:ok, Collaborator.t()} | {:error, atom()}
def add_collaborator(collaborator, %{context: %{current_user: current_user}}) do
Notebooks.get_notebook!(
collaborator.notebook_id,
owner: current_user
)

case Notebooks.add_collaborator(collaborator) do
{:ok, collaborator} -> {:ok, collaborator}

user = Accounts.get_user_by_email!(collaborator.email)
collaborator_attrs = %{notebook_id: collaborator.notebook_id, user_id: user.id}
case Notebooks.add_collaborator(collaborator_attrs) do
{:ok, collaborator} ->
case Notebooks.send_notification(user, collaborator.notebook_id, current_user) do
{:ok, _} -> {:ok, collaborator}
{:error, reason} -> {:error, reason}
end
{:ok, collaborator}
{:error, changeset} -> {:error, changeset}
end
end
Expand Down
5 changes: 3 additions & 2 deletions lib/cursif_web/schemas/notebook.ex
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ defmodule CursifWeb.Schemas.Notebook do
arg(:title, non_null(:string))
arg(:description, :string)
arg(:owner_id, non_null(:id))
arg(:owner_type, :string, default_value: "User")
arg(:owner_type, :string, default_value: "user")

resolve(&Notebooks.create_notebook/2)
end
Expand Down Expand Up @@ -93,7 +93,8 @@ defmodule CursifWeb.Schemas.Notebook do
@desc "Add a collaborator"
field :add_collaborator, :collaborator do
arg(:notebook_id, non_null(:id))
arg(:user_id, non_null(:id))
arg(:user_id, :id)
arg(:email, non_null(:string))

resolve(&Collaborators.add_collaborator/2)
end
Expand Down
1 change: 1 addition & 0 deletions lib/cursif_web/schemas/types/notebook_types.ex
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ defmodule CursifWeb.Schemas.NotebookTypes do
field :id, :id
field :notebook_id, :string
field :user_id, :string
field :email, :string
end

@desc "Favorite representation"
Expand Down
29 changes: 29 additions & 0 deletions lib/cursif_web/templates/email/add.html.eex
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html>
<body>
<div class="email-container">
<div class="header">
<span style="font-family: Montez; font-size: 1.2em;">Cursif</span>
</div>
<div class="content">
<div class="email-body">
<p>Hi <strong><%= @username %></strong>,</p>
<p>
You have been added to a notebook by <%= @owner.username%> (<strong><%= @owner.email%></strong>).
</p>
</div>
<div class="button-container">
<a class="button" href="<%= @base_url %>">See Notebook</a>
<div class="message signature">
<p>If it isn't you, please disregard this email.</p>
</div>
</div>
<div style="margin-left: 20px" class="email-signature signature">
<p>
Best regards,<br />
The Cursif Team
</p>
</div>
</div>
</body>
</html>
Loading