improve invites, record usage

This commit is contained in:
shibao 2023-02-04 16:46:37 -05:00
parent 47dab6490d
commit 2c0a4dd7ca
46 changed files with 988 additions and 725 deletions

View File

@ -1,6 +1,7 @@
# v0.8.2
- Fix bug with public registration
- Improve templates
- Improve invites, record usage
# v0.8.1
- Update dependencies

View File

@ -5,7 +5,7 @@ defmodule Cannery.Accounts do
import Ecto.Query, warn: false
alias Cannery.{Mailer, Repo}
alias Cannery.Accounts.{User, UserToken}
alias Cannery.Accounts.{Invite, Invites, User, UserToken}
alias Ecto.{Changeset, Multi}
alias Oban.Job
@ -25,7 +25,9 @@ defmodule Cannery.Accounts do
"""
@spec get_user_by_email(email :: String.t()) :: User.t() | nil
def get_user_by_email(email) when is_binary(email), do: Repo.get_by(User, email: email)
def get_user_by_email(email) when is_binary(email) do
Repo.get_by(User, email: email)
end
@doc """
Gets a user by email and password.
@ -64,7 +66,9 @@ defmodule Cannery.Accounts do
"""
@spec get_user!(User.t()) :: User.t()
def get_user!(id), do: Repo.get!(User, id)
def get_user!(id) do
Repo.get!(User, id)
end
@doc """
Returns all users grouped by role.
@ -113,19 +117,27 @@ defmodule Cannery.Accounts do
:passed
"""
@spec register_user(attrs :: map()) :: {:ok, User.t()} | {:error, User.changeset()}
def register_user(attrs) do
@spec register_user(attrs :: map(), Invite.token() | nil) ::
{:ok, User.t()} | {:error, :invalid_token | User.changeset()}
def register_user(attrs, invite_token \\ nil) do
Multi.new()
|> Multi.one(:users_count, from(u in User, select: count(u.id), distinct: true))
|> Multi.insert(:add_user, fn %{users_count: count} ->
|> Multi.run(:use_invite, fn _changes_so_far, _repo ->
if allow_registration?() and invite_token |> is_nil() do
{:ok, nil}
else
Invites.use_invite(invite_token)
end
end)
|> Multi.insert(:add_user, fn %{users_count: count, use_invite: invite} ->
# if no registered users, make first user an admin
role = if count == 0, do: :admin, else: :user
User.registration_changeset(attrs) |> User.role_changeset(role)
User.registration_changeset(attrs, invite) |> User.role_changeset(role)
end)
|> Repo.transaction()
|> case do
{:ok, %{add_user: user}} -> {:ok, user}
{:error, :use_invite, :invalid_token, _changes_so_far} -> {:error, :invalid_token}
{:error, :add_user, changeset, _changes_so_far} -> {:error, changeset}
end
end
@ -144,8 +156,9 @@ defmodule Cannery.Accounts do
"""
@spec change_user_registration() :: User.changeset()
@spec change_user_registration(attrs :: map()) :: User.changeset()
def change_user_registration(attrs \\ %{}),
do: User.registration_changeset(attrs, hash_password: false)
def change_user_registration(attrs \\ %{}) do
User.registration_changeset(attrs, nil, hash_password: false)
end
## Settings
@ -160,7 +173,9 @@ defmodule Cannery.Accounts do
"""
@spec change_user_email(User.t()) :: User.changeset()
@spec change_user_email(User.t(), attrs :: map()) :: User.changeset()
def change_user_email(user, attrs \\ %{}), do: User.email_changeset(user, attrs)
def change_user_email(user, attrs \\ %{}) do
User.email_changeset(user, attrs)
end
@doc """
Returns an `%Changeset{}` for changing the user role.
@ -172,7 +187,9 @@ defmodule Cannery.Accounts do
"""
@spec change_user_role(User.t(), User.role()) :: User.changeset()
def change_user_role(user, role), do: User.role_changeset(user, role)
def change_user_role(user, role) do
User.role_changeset(user, role)
end
@doc """
Emulates that the email will change without actually changing
@ -262,8 +279,9 @@ defmodule Cannery.Accounts do
"""
@spec change_user_password(User.t(), attrs :: map()) :: User.changeset()
def change_user_password(user, attrs \\ %{}),
do: User.password_changeset(user, attrs, hash_password: false)
def change_user_password(user, attrs \\ %{}) do
User.password_changeset(user, attrs, hash_password: false)
end
@doc """
Updates the user password.
@ -314,7 +332,9 @@ defmodule Cannery.Accounts do
"""
@spec change_user_locale(User.t()) :: User.changeset()
def change_user_locale(%{locale: locale} = user), do: User.locale_changeset(user, locale)
def change_user_locale(%{locale: locale} = user) do
User.locale_changeset(user, locale)
end
@doc """
Updates the user locale.
@ -328,8 +348,9 @@ defmodule Cannery.Accounts do
"""
@spec update_user_locale(User.t(), locale :: String.t()) ::
{:ok, User.t()} | {:error, User.changeset()}
def update_user_locale(user, locale),
do: user |> User.locale_changeset(locale) |> Repo.update()
def update_user_locale(user, locale) do
user |> User.locale_changeset(locale) |> Repo.update()
end
@doc """
Deletes a user. must be performed by an admin or the same user!
@ -346,8 +367,13 @@ defmodule Cannery.Accounts do
"""
@spec delete_user!(user_to_delete :: User.t(), User.t()) :: User.t()
def delete_user!(user, %User{role: :admin}), do: user |> Repo.delete!()
def delete_user!(%User{id: user_id} = user, %User{id: user_id}), do: user |> Repo.delete!()
def delete_user!(user, %User{role: :admin}) do
user |> Repo.delete!()
end
def delete_user!(%User{id: user_id} = user, %User{id: user_id}) do
user |> Repo.delete!()
end
## Session
@ -375,7 +401,7 @@ defmodule Cannery.Accounts do
"""
@spec delete_session_token(token :: String.t()) :: :ok
def delete_session_token(token) do
Repo.delete_all(UserToken.token_and_context_query(token, "session"))
UserToken.token_and_context_query(token, "session") |> Repo.delete_all()
:ok
end

View File

@ -1,4 +1,4 @@
defmodule Cannery.Invites.Invite do
defmodule Cannery.Accounts.Invite do
@moduledoc """
An invite, created by an admin to allow someone to join their instance. An
invite can be enabled or disabled, and can have an optional number of uses if
@ -7,8 +7,8 @@ defmodule Cannery.Invites.Invite do
use Ecto.Schema
import Ecto.Changeset
alias Ecto.{Changeset, UUID}
alias Cannery.{Accounts.User, Invites.Invite}
alias Cannery.Accounts.User
alias Ecto.{Association, Changeset, UUID}
@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
@ -18,33 +18,37 @@ defmodule Cannery.Invites.Invite do
field :uses_left, :integer, default: nil
field :disabled_at, :naive_datetime
belongs_to :user, User
belongs_to :created_by, User
has_many :users, User
timestamps()
end
@type t :: %Invite{
@type t :: %__MODULE__{
id: id(),
name: String.t(),
token: String.t(),
token: token(),
uses_left: integer() | nil,
disabled_at: NaiveDateTime.t(),
user: User.t(),
user_id: User.id(),
created_by: User.t() | nil | Association.NotLoaded.t(),
created_by_id: User.id() | nil,
users: [User.t()] | Association.NotLoaded.t(),
inserted_at: NaiveDateTime.t(),
updated_at: NaiveDateTime.t()
}
@type new_invite :: %Invite{}
@type new_invite :: %__MODULE__{}
@type id :: UUID.t()
@type changeset :: Changeset.t(t() | new_invite())
@type token :: String.t()
@doc false
@spec create_changeset(User.t(), token :: binary(), attrs :: map()) :: changeset()
@spec create_changeset(User.t(), token(), attrs :: map()) :: changeset()
def create_changeset(%User{id: user_id}, token, attrs) do
%Invite{}
|> change(token: token, user_id: user_id)
%__MODULE__{}
|> change(token: token, created_by_id: user_id)
|> cast(attrs, [:name, :uses_left, :disabled_at])
|> validate_required([:name, :token, :user_id])
|> validate_required([:name, :token, :created_by_id])
|> validate_number(:uses_left, greater_than_or_equal_to: 0)
end

View File

@ -0,0 +1,196 @@
defmodule Cannery.Accounts.Invites do
@moduledoc """
The Invites context.
"""
import Ecto.Query, warn: false
alias Ecto.Multi
alias Cannery.Accounts.{Invite, User}
alias Cannery.Repo
@invite_token_length 20
@doc """
Returns the list of invites.
## Examples
iex> list_invites(%User{id: 123, role: :admin})
[%Invite{}, ...]
"""
@spec list_invites(User.t()) :: [Invite.t()]
def list_invites(%User{role: :admin}) do
Repo.all(from i in Invite, order_by: i.name)
end
@doc """
Gets a single invite for a user
Raises `Ecto.NoResultsError` if the Invite does not exist.
## Examples
iex> get_invite!(123, %User{id: 123, role: :admin})
%Invite{}
> get_invite!(456, %User{id: 123, role: :admin})
** (Ecto.NoResultsError)
"""
@spec get_invite!(Invite.id(), User.t()) :: Invite.t()
def get_invite!(id, %User{role: :admin}) do
Repo.get!(Invite, id)
end
@doc """
Returns if an invite token is still valid
## Examples
iex> valid_invite_token?("valid_token")
%Invite{}
iex> valid_invite_token?("invalid_token")
nil
"""
@spec valid_invite_token?(Invite.token() | nil) :: boolean()
def valid_invite_token?(token) when token in [nil, ""], do: false
def valid_invite_token?(token) do
Repo.exists?(
from i in Invite,
where: i.token == ^token,
where: i.disabled_at |> is_nil()
)
end
@doc """
Uses invite by decrementing uses_left, or marks invite invalid if it's been
completely used.
"""
@spec use_invite(Invite.token()) :: {:ok, Invite.t()} | {:error, :invalid_token}
def use_invite(invite_token) do
Multi.new()
|> Multi.run(:invite, fn _changes_so_far, _repo ->
invite_token |> get_invite_by_token()
end)
|> Multi.update(:decrement_invite, fn %{invite: invite} ->
decrement_invite_changeset(invite)
end)
|> Repo.transaction()
|> case do
{:ok, %{decrement_invite: invite}} -> {:ok, invite}
{:error, :invite, :invalid_token, _changes_so_far} -> {:error, :invalid_token}
end
end
@spec get_invite_by_token(Invite.token()) :: {:ok, Invite.t()} | {:error, :invalid_token}
defp get_invite_by_token(token) do
Repo.one(
from i in Invite,
where: i.token == ^token,
where: i.disabled_at |> is_nil()
)
|> case do
nil -> {:error, :invalid_token}
invite -> {:ok, invite}
end
end
@spec get_use_count(Invite.t(), User.t()) :: non_neg_integer()
def get_use_count(%Invite{id: invite_id}, %User{role: :admin}) do
Repo.one(
from u in User,
where: u.invite_id == ^invite_id,
select: count(u.id)
)
end
@spec decrement_invite_changeset(Invite.t()) :: Invite.changeset()
defp decrement_invite_changeset(%Invite{uses_left: nil} = invite) do
invite |> Invite.update_changeset(%{})
end
defp decrement_invite_changeset(%Invite{uses_left: 1} = invite) do
now = NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second)
invite |> Invite.update_changeset(%{uses_left: 0, disabled_at: now})
end
defp decrement_invite_changeset(%Invite{uses_left: uses_left} = invite) do
invite |> Invite.update_changeset(%{uses_left: uses_left - 1})
end
@doc """
Creates a invite.
## Examples
iex> create_invite(%User{id: 123, role: :admin}, %{field: value})
{:ok, %Invite{}}
iex> create_invite(%User{id: 123, role: :admin}, %{field: bad_value})
{:error, %Changeset{}}
"""
@spec create_invite(User.t(), attrs :: map()) ::
{:ok, Invite.t()} | {:error, Invite.changeset()}
def create_invite(%User{role: :admin} = user, attrs) do
token =
:crypto.strong_rand_bytes(@invite_token_length)
|> Base.url_encode64()
|> binary_part(0, @invite_token_length)
Invite.create_changeset(user, token, attrs) |> Repo.insert()
end
@doc """
Updates a invite.
## Examples
iex> update_invite(invite, %{field: new_value}, %User{id: 123, role: :admin})
{:ok, %Invite{}}
iex> update_invite(invite, %{field: bad_value}, %User{id: 123, role: :admin})
{:error, %Changeset{}}
"""
@spec update_invite(Invite.t(), attrs :: map(), User.t()) ::
{:ok, Invite.t()} | {:error, Invite.changeset()}
def update_invite(invite, attrs, %User{role: :admin}) do
invite |> Invite.update_changeset(attrs) |> Repo.update()
end
@doc """
Deletes a invite.
## Examples
iex> delete_invite(invite, %User{id: 123, role: :admin})
{:ok, %Invite{}}
iex> delete_invite(invite, %User{id: 123, role: :admin})
{:error, %Changeset{}}
"""
@spec delete_invite(Invite.t(), User.t()) ::
{:ok, Invite.t()} | {:error, Invite.changeset()}
def delete_invite(invite, %User{role: :admin}) do
invite |> Repo.delete()
end
@doc """
Deletes a invite.
## Examples
iex> delete_invite(invite, %User{id: 123, role: :admin})
%Invite{}
"""
@spec delete_invite!(Invite.t(), User.t()) :: Invite.t()
def delete_invite!(invite, %User{role: :admin}) do
invite |> Repo.delete!()
end
end

View File

@ -1,13 +1,13 @@
defmodule Cannery.Accounts.User do
@moduledoc """
A cannery user
A Cannery user
"""
use Ecto.Schema
import Ecto.Changeset
import CanneryWeb.Gettext
alias Ecto.{Changeset, UUID}
alias Cannery.{Accounts.User, Invites.Invite}
alias Ecto.{Association, Changeset, UUID}
alias Cannery.Accounts.{Invite, User}
@derive {Jason.Encoder,
only: [
@ -15,7 +15,9 @@ defmodule Cannery.Accounts.User do
:email,
:confirmed_at,
:role,
:locale
:locale,
:inserted_at,
:updated_at
]}
@derive {Inspect, except: [:password]}
@primary_key {:id, :binary_id, autogenerate: true}
@ -28,7 +30,9 @@ defmodule Cannery.Accounts.User do
field :role, Ecto.Enum, values: [:admin, :user], default: :user
field :locale, :string
has_many :invites, Invite, on_delete: :delete_all
has_many :created_invites, Invite, foreign_key: :created_by_id
belongs_to :invite, Invite
timestamps()
end
@ -41,7 +45,9 @@ defmodule Cannery.Accounts.User do
confirmed_at: NaiveDateTime.t(),
role: role(),
locale: String.t() | nil,
invites: [Invite.t()],
created_invites: [Invite.t()] | Association.NotLoaded.t(),
invite: Invite.t() | nil | Association.NotLoaded.t(),
invite_id: Invite.id() | nil,
inserted_at: NaiveDateTime.t(),
updated_at: NaiveDateTime.t()
}
@ -67,11 +73,12 @@ defmodule Cannery.Accounts.User do
validations on a LiveView form), this option can be set to `false`.
Defaults to `true`.
"""
@spec registration_changeset(attrs :: map()) :: changeset()
@spec registration_changeset(attrs :: map(), opts :: keyword()) :: changeset()
def registration_changeset(attrs, opts \\ []) do
@spec registration_changeset(attrs :: map(), Invite.t() | nil) :: changeset()
@spec registration_changeset(attrs :: map(), Invite.t() | nil, opts :: keyword()) :: changeset()
def registration_changeset(attrs, invite, opts \\ []) do
%User{}
|> cast(attrs, [:email, :password, :locale])
|> put_change(:invite_id, if(invite, do: invite.id))
|> validate_email()
|> validate_password(opts)
end

View File

@ -1,12 +1,12 @@
defmodule Cannery.Accounts.UserToken do
@moduledoc """
Schema for serialized user session and authentication tokens
Schema for a user's session token
"""
use Ecto.Schema
import Ecto.Query
alias Ecto.{Query, UUID}
alias Cannery.{Accounts.User, Accounts.UserToken}
alias Cannery.Accounts.User
alias Ecto.{Association, UUID}
@hash_algorithm :sha256
@rand_size 32
@ -30,27 +30,27 @@ defmodule Cannery.Accounts.UserToken do
timestamps(updated_at: false)
end
@type t :: %UserToken{
@type t :: %__MODULE__{
id: id(),
token: String.t(),
token: token(),
context: String.t(),
sent_to: String.t(),
user: User.t(),
user_id: User.id(),
user: User.t() | Association.NotLoaded.t(),
user_id: User.id() | nil,
inserted_at: NaiveDateTime.t()
}
@type new_token :: %UserToken{}
@type new_user_token :: %__MODULE__{}
@type id :: UUID.t()
@type token :: binary()
@doc """
Generates a token that will be stored in a signed place,
such as session or cookie. As they are signed, those
tokens do not need to be hashed.
"""
@spec build_session_token(User.t()) :: {token :: String.t(), new_token()}
def build_session_token(%{id: user_id}) do
def build_session_token(user) do
token = :crypto.strong_rand_bytes(@rand_size)
{token, %UserToken{token: token, context: "session", user_id: user_id}}
{token, %__MODULE__{token: token, context: "session", user_id: user.id}}
end
@doc """
@ -58,7 +58,6 @@ defmodule Cannery.Accounts.UserToken do
The query returns the user found by the token.
"""
@spec verify_session_token_query(token :: String.t()) :: {:ok, Query.t()}
def verify_session_token_query(token) do
query =
from token in token_and_context_query(token, "session"),
@ -77,19 +76,16 @@ defmodule Cannery.Accounts.UserToken do
The token is valid for a week as long as users don't change
their email.
"""
@spec build_email_token(User.t(), context :: String.t()) :: {token :: String.t(), new_token()}
def build_email_token(user, context) do
build_hashed_token(user, context, user.email)
end
@spec build_hashed_token(User.t(), String.t(), String.t()) ::
{String.t(), new_token()}
defp build_hashed_token(user, context, sent_to) do
token = :crypto.strong_rand_bytes(@rand_size)
hashed_token = :crypto.hash(@hash_algorithm, token)
{Base.url_encode64(token, padding: false),
%UserToken{
%__MODULE__{
token: hashed_token,
context: context,
sent_to: sent_to,
@ -102,8 +98,6 @@ defmodule Cannery.Accounts.UserToken do
The query returns the user found by the token.
"""
@spec verify_email_token_query(token :: String.t(), context :: String.t()) ::
{:ok, Query.t()} | :error
def verify_email_token_query(token, context) do
case Base.url_decode64(token, padding: false) do
{:ok, decoded_token} ->
@ -123,7 +117,6 @@ defmodule Cannery.Accounts.UserToken do
end
end
@spec days_for_context(context :: <<_::56>>) :: non_neg_integer()
defp days_for_context("confirm"), do: @confirm_validity_in_days
defp days_for_context("reset_password"), do: @reset_password_validity_in_days
@ -132,8 +125,6 @@ defmodule Cannery.Accounts.UserToken do
The query returns the user token record.
"""
@spec verify_change_email_token_query(token :: String.t(), context :: String.t()) ::
{:ok, Query.t()} | :error
def verify_change_email_token_query(token, context) do
case Base.url_decode64(token, padding: false) do
{:ok, decoded_token} ->
@ -153,21 +144,18 @@ defmodule Cannery.Accounts.UserToken do
@doc """
Returns the given token with the given context.
"""
@spec token_and_context_query(token :: String.t(), context :: String.t()) :: Query.t()
def token_and_context_query(token, context) do
from UserToken, where: [token: ^token, context: ^context]
from __MODULE__, where: [token: ^token, context: ^context]
end
@doc """
Gets all tokens for the given user for the given contexts.
"""
@spec user_and_contexts_query(User.t(), contexts :: :all | nonempty_maybe_improper_list()) ::
Query.t()
def user_and_contexts_query(%{id: user_id}, :all) do
from t in UserToken, where: t.user_id == ^user_id
def user_and_contexts_query(user, :all) do
from t in __MODULE__, where: t.user_id == ^user.id
end
def user_and_contexts_query(%{id: user_id}, [_ | _] = contexts) do
from t in UserToken, where: t.user_id == ^user_id and t.context in ^contexts
def user_and_contexts_query(user, [_ | _] = contexts) do
from t in __MODULE__, where: t.user_id == ^user.id and t.context in ^contexts
end
end

View File

@ -1,155 +0,0 @@
defmodule Cannery.Invites do
@moduledoc """
The Invites context.
"""
import Ecto.Query, warn: false
alias Cannery.{Accounts.User, Invites.Invite, Repo}
@invite_token_length 20
@doc """
Returns the list of invites.
## Examples
iex> list_invites(%User{id: 123, role: :admin})
[%Invite{}, ...]
"""
@spec list_invites(User.t()) :: [Invite.t()]
def list_invites(%User{role: :admin}) do
Repo.all(from i in Invite, order_by: i.name)
end
@doc """
Gets a single invite.
Raises `Ecto.NoResultsError` if the Invite does not exist.
## Examples
iex> get_invite!(123, %User{id: 123, role: :admin})
%Invite{}
iex> get_invite!(456, %User{id: 123, role: :admin})
** (Ecto.NoResultsError)
"""
@spec get_invite!(Invite.id(), User.t()) :: Invite.t()
def get_invite!(id, %User{role: :admin}) do
Repo.get!(Invite, id)
end
@doc """
Returns a valid invite or nil based on the attempted token
## Examples
iex> get_invite_by_token("valid_token")
%Invite{}
iex> get_invite_by_token("invalid_token")
nil
"""
@spec get_invite_by_token(token :: String.t() | nil) :: Invite.t() | nil
def get_invite_by_token(nil), do: nil
def get_invite_by_token(""), do: nil
def get_invite_by_token(token) do
Repo.one(
from(i in Invite,
where: i.token == ^token and i.disabled_at |> is_nil()
)
)
end
@doc """
Uses invite by decrementing uses_left, or marks invite invalid if it's been
completely used.
"""
@spec use_invite!(Invite.t()) :: Invite.t()
def use_invite!(%Invite{uses_left: nil} = invite), do: invite
def use_invite!(%Invite{uses_left: uses_left} = invite) do
new_uses_left = uses_left - 1
attrs =
if new_uses_left <= 0 do
now = NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second)
%{"uses_left" => 0, "disabled_at" => now}
else
%{"uses_left" => new_uses_left}
end
invite |> Invite.update_changeset(attrs) |> Repo.update!()
end
@doc """
Creates a invite.
## Examples
iex> create_invite(%User{id: 123, role: :admin}, %{field: value})
{:ok, %Invite{}}
iex> create_invite(%User{id: 123, role: :admin}, %{field: bad_value})
{:error, %Changeset{}}
"""
@spec create_invite(User.t(), attrs :: map()) ::
{:ok, Invite.t()} | {:error, Invite.changeset()}
def create_invite(%User{role: :admin} = user, attrs) do
token =
:crypto.strong_rand_bytes(@invite_token_length)
|> Base.url_encode64()
|> binary_part(0, @invite_token_length)
Invite.create_changeset(user, token, attrs) |> Repo.insert()
end
@doc """
Updates a invite.
## Examples
iex> update_invite(invite, %{field: new_value}, %User{id: 123, role: :admin})
{:ok, %Invite{}}
iex> update_invite(invite, %{field: bad_value}, %User{id: 123, role: :admin})
{:error, %Changeset{}}
"""
@spec update_invite(Invite.t(), attrs :: map(), User.t()) ::
{:ok, Invite.t()} | {:error, Invite.changeset()}
def update_invite(invite, attrs, %User{role: :admin}),
do: invite |> Invite.update_changeset(attrs) |> Repo.update()
@doc """
Deletes a invite.
## Examples
iex> delete_invite(invite, %User{id: 123, role: :admin})
{:ok, %Invite{}}
iex> delete_invite(invite, %User{id: 123, role: :admin})
{:error, %Changeset{}}
"""
@spec delete_invite(Invite.t(), User.t()) ::
{:ok, Invite.t()} | {:error, Invite.changeset()}
def delete_invite(invite, %User{role: :admin}), do: invite |> Repo.delete()
@doc """
Deletes a invite.
## Examples
iex> delete_invite(invite, %User{id: 123, role: :admin})
%Invite{}
"""
@spec delete_invite!(Invite.t(), User.t()) :: Invite.t()
def delete_invite!(invite, %User{role: :admin}), do: invite |> Repo.delete!()
end

View File

@ -72,16 +72,14 @@ defmodule CanneryWeb do
quote do
use Phoenix.Router
import Phoenix.{Controller, LiveView.Router}
# credo:disable-for-next-line Credo.Check.Consistency.MultiAliasImportRequireUse
import Plug.Conn
import Phoenix.Controller
import Phoenix.LiveView.Router
end
end
def channel do
quote do
# credo:disable-for-next-line Credo.Check.Consistency.MultiAliasImportRequireUse
use Phoenix.Channel
# credo:disable-for-next-line Credo.Check.Consistency.MultiAliasImportRequireUse
import CanneryWeb.Gettext
@ -95,15 +93,10 @@ defmodule CanneryWeb do
use Phoenix.HTML
# Import LiveView and .heex helpers (live_render, live_patch, <.form>, etc)
# credo:disable-for-next-line Credo.Check.Consistency.MultiAliasImportRequireUse
import Phoenix.Component
# Import basic rendering functionality (render, render_layout, etc)
# credo:disable-for-next-line Credo.Check.Consistency.MultiAliasImportRequireUse
import Phoenix.View
# credo:disable-for-next-line Credo.Check.Consistency.MultiAliasImportRequireUse
import CanneryWeb.{ErrorHelpers, Gettext, LiveHelpers, ViewHelpers}
import Phoenix.{Component, View}
alias CanneryWeb.Endpoint
alias CanneryWeb.Router.Helpers, as: Routes
end

View File

@ -4,23 +4,24 @@ defmodule CanneryWeb.Components.InviteCard do
"""
use CanneryWeb, :component
alias Cannery.Invites.Invite
alias Cannery.Accounts.{Invite, Invites, User}
alias CanneryWeb.Endpoint
attr :invite, Invite, required: true
attr :current_user, User, required: true
slot(:inner_block)
slot(:code_actions)
def invite_card(assigns) do
assigns = assigns |> assign_new(:code_actions, fn -> [] end)
def invite_card(%{invite: invite, current_user: current_user} = assigns) do
assigns =
assigns
|> assign(:use_count, Invites.get_use_count(invite, current_user))
|> assign_new(:code_actions, fn -> [] end)
~H"""
<div
id={"invite-#{@invite.id}"}
class="mx-4 my-2 px-8 py-4 flex flex-col justify-center items-center space-y-4
border border-gray-400 rounded-lg shadow-lg hover:shadow-md
transition-all duration-300 ease-in-out"
>
<div class="mx-4 my-2 px-8 py-4 flex flex-col justify-center items-center space-y-4
border border-gray-400 rounded-lg shadow-lg hover:shadow-md
transition-all duration-300 ease-in-out">
<h1 class="title text-xl">
<%= @invite.name %>
</h1>
@ -29,8 +30,8 @@ defmodule CanneryWeb.Components.InviteCard do
<h2 class="title text-md">
<%= if @invite.uses_left do %>
<%= gettext(
"Uses Left: %{uses_left}",
uses_left: @invite.uses_left
"Uses Left: %{uses_left_count}",
uses_left_count: @invite.uses_left
) %>
<% else %>
<%= gettext("Uses Left: Unlimited") %>
@ -47,6 +48,10 @@ defmodule CanneryWeb.Components.InviteCard do
filename={@invite.name}
/>
<h2 :if={@use_count != 0} class="title text-md">
<%= gettext("Uses: %{uses_count}", uses_count: @use_count) %>
</h2>
<div class="flex flex-row flex-wrap justify-center items-center">
<code
id={"code-#{@invite.id}"}

View File

@ -1,14 +1,12 @@
defmodule CanneryWeb.UserRegistrationController do
use CanneryWeb, :controller
import CanneryWeb.Gettext
alias Cannery.{Accounts, Invites}
alias Cannery.{Accounts, Accounts.Invites}
alias CanneryWeb.{Endpoint, HomeLive}
def new(conn, %{"invite" => invite_token}) do
invite = Invites.get_invite_by_token(invite_token)
if invite do
conn |> render_new(invite)
if Invites.valid_invite_token?(invite_token) do
conn |> render_new(invite_token)
else
conn
|> put_flash(:error, dgettext("errors", "Sorry, this invite was not found or expired"))
@ -27,19 +25,17 @@ defmodule CanneryWeb.UserRegistrationController do
end
# renders new user registration page
defp render_new(conn, invite \\ nil) do
defp render_new(conn, invite_token \\ nil) do
render(conn, "new.html",
changeset: Accounts.change_user_registration(),
invite: invite,
invite_token: invite_token,
page_title: gettext("Register")
)
end
def create(conn, %{"user" => %{"invite_token" => invite_token}} = attrs) do
invite = Invites.get_invite_by_token(invite_token)
if invite do
conn |> create_user(attrs, invite)
if Invites.valid_invite_token?(invite_token) do
conn |> create_user(attrs, invite_token)
else
conn
|> put_flash(:error, dgettext("errors", "Sorry, this invite was not found or expired"))
@ -57,13 +53,9 @@ defmodule CanneryWeb.UserRegistrationController do
end
end
defp create_user(conn, %{"user" => user_params}, invite \\ nil) do
case Accounts.register_user(user_params) do
defp create_user(conn, %{"user" => user_params}, invite_token \\ nil) do
case Accounts.register_user(user_params, invite_token) do
{:ok, user} ->
unless invite |> is_nil() do
invite |> Invites.use_invite!()
end
Accounts.deliver_user_confirmation_instructions(
user,
&Routes.user_confirmation_url(conn, :confirm, &1)
@ -73,8 +65,13 @@ defmodule CanneryWeb.UserRegistrationController do
|> put_flash(:info, dgettext("prompts", "Please check your email to verify your account"))
|> redirect(to: Routes.user_session_path(Endpoint, :new))
{:error, :invalid_token} ->
conn
|> put_flash(:error, dgettext("errors", "Sorry, this invite was not found or expired"))
|> redirect(to: Routes.live_path(Endpoint, HomeLive))
{:error, %Ecto.Changeset{} = changeset} ->
conn |> render("new.html", changeset: changeset, invite: invite)
conn |> render("new.html", changeset: changeset, invite_token: invite_token)
end
end
end

View File

@ -1,11 +1,11 @@
defmodule CanneryWeb.InviteLive.FormComponent do
@moduledoc """
Livecomponent that can update or create an Cannery.Invites.Invite
Livecomponent that can update or create an Cannery.Accounts.Invite
"""
use CanneryWeb, :live_component
alias Cannery.{Accounts.User, Invites, Invites.Invite}
alias Ecto.Changeset
alias Cannery.Accounts.{Invite, Invites, User}
alias Phoenix.LiveView.Socket
@impl true

View File

@ -1,11 +1,12 @@
defmodule CanneryWeb.InviteLive.Index do
@moduledoc """
Liveview to show a Cannery.Invites.Invite index
Liveview to show a Cannery.Accounts.Invite index
"""
use CanneryWeb, :live_view
import CanneryWeb.Components.{InviteCard, UserCard}
alias Cannery.{Accounts, Invites, Invites.Invite}
alias Cannery.Accounts
alias Cannery.Accounts.{Invite, Invites}
alias CanneryWeb.{Endpoint, HomeLive}
alias Phoenix.LiveView.JS
@ -17,7 +18,7 @@ defmodule CanneryWeb.InviteLive.Index do
else
prompt = dgettext("errors", "You are not authorized to view this page")
return_to = Routes.live_path(Endpoint, HomeLive)
socket |> put_flash(:error, prompt) |> push_navigate(to: return_to)
socket |> put_flash(:error, prompt) |> push_redirect(to: return_to)
end
{:ok, socket}
@ -50,7 +51,7 @@ defmodule CanneryWeb.InviteLive.Index do
%{name: invite_name} =
id |> Invites.get_invite!(current_user) |> Invites.delete_invite!(current_user)
prompt = dgettext("prompts", "%{name} deleted succesfully", name: invite_name)
prompt = dgettext("prompts", "%{invite_name} deleted succesfully", invite_name: invite_name)
{:noreply, socket |> put_flash(:info, prompt) |> display_invites()}
end
@ -61,10 +62,12 @@ defmodule CanneryWeb.InviteLive.Index do
) do
socket =
Invites.get_invite!(id, current_user)
|> Invites.update_invite(%{"uses_left" => nil}, current_user)
|> Invites.update_invite(%{uses_left: nil}, current_user)
|> case do
{:ok, %{name: invite_name}} ->
prompt = dgettext("prompts", "%{name} updated succesfully", name: invite_name)
prompt =
dgettext("prompts", "%{invite_name} updated succesfully", invite_name: invite_name)
socket |> put_flash(:info, prompt) |> display_invites()
{:error, changeset} ->
@ -81,10 +84,12 @@ defmodule CanneryWeb.InviteLive.Index do
) do
socket =
Invites.get_invite!(id, current_user)
|> Invites.update_invite(%{"uses_left" => nil, "disabled_at" => nil}, current_user)
|> Invites.update_invite(%{uses_left: nil, disabled_at: nil}, current_user)
|> case do
{:ok, %{name: invite_name}} ->
prompt = dgettext("prompts", "%{name} enabled succesfully", name: invite_name)
prompt =
dgettext("prompts", "%{invite_name} enabled succesfully", invite_name: invite_name)
socket |> put_flash(:info, prompt) |> display_invites()
{:error, changeset} ->
@ -103,10 +108,12 @@ defmodule CanneryWeb.InviteLive.Index do
socket =
Invites.get_invite!(id, current_user)
|> Invites.update_invite(%{"uses_left" => 0, "disabled_at" => now}, current_user)
|> Invites.update_invite(%{uses_left: 0, disabled_at: now}, current_user)
|> case do
{:ok, %{name: invite_name}} ->
prompt = dgettext("prompts", "%{name} disabled succesfully", name: invite_name)
prompt =
dgettext("prompts", "%{invite_name} disabled succesfully", invite_name: invite_name)
socket |> put_flash(:info, prompt) |> display_invites()
{:error, changeset} ->
@ -130,7 +137,7 @@ defmodule CanneryWeb.InviteLive.Index do
) do
%{email: user_email} = Accounts.get_user!(id) |> Accounts.delete_user!(current_user)
prompt = dgettext("prompts", "%{name} deleted succesfully", name: user_email)
prompt = dgettext("prompts", "%{user_email} deleted succesfully", user_email: user_email)
{:noreply, socket |> put_flash(:info, prompt) |> display_invites()}
end

View File

@ -19,7 +19,7 @@
<% end %>
<div class="w-full flex flex-row flex-wrap justify-center items-stretch">
<.invite_card :for={invite <- @invites} invite={invite}>
<.invite_card :for={invite <- @invites} invite={invite} current_user={@current_user}>
<:code_actions>
<form phx-submit="copy_to_clipboard">
<button
@ -45,8 +45,8 @@
phx-click="delete_invite"
phx-value-id={invite.id}
data-confirm={
dgettext("prompts", "Are you sure you want to delete the invite for %{name}?",
name: invite.name
dgettext("prompts", "Are you sure you want to delete the invite for %{invite_name}?",
invite_name: invite.name
)
}
data-qa={"delete-#{invite.id}"}
@ -70,8 +70,8 @@
phx-click="set_unlimited"
phx-value-id={invite.id}
data-confirm={
dgettext("prompts", "Are you sure you want to make %{name} unlimited?",
name: invite.name
dgettext("prompts", "Are you sure you want to make %{invite_name} unlimited?",
invite_name: invite.name
)
}
>

View File

@ -49,7 +49,7 @@ defmodule CanneryWeb.LiveHelpers do
id="modal-content"
class="fade-in-scale w-full max-w-3xl relative
pointer-events-auto overflow-hidden
px-8 py-4 sm:py-8 flex flex-col justify-center items-center
px-8 py-4 sm:py-8
flex flex-col justify-start items-center
bg-white border-2 rounded-lg"
>

View File

@ -9,14 +9,12 @@
action={Routes.user_registration_path(@conn, :create)}
class="flex flex-col space-y-4 sm:space-y-0 sm:grid sm:grid-cols-3 sm:gap-4 justify-center items-center"
>
<div :if={@changeset.action && not @changeset.valid?()} class="alert alert-danger col-span-3">
<p>
<%= dgettext("errors", "Oops, something went wrong! Please check the errors below.") %>
</p>
</div>
<p :if={@changeset.action && not @changeset.valid?()} class="alert alert-danger col-span-3">
<%= dgettext("errors", "Oops, something went wrong! Please check the errors below.") %>
</p>
<%= if @invite do %>
<%= hidden_input(f, :invite_token, value: @invite.token) %>
<%= if @invite_token do %>
<%= hidden_input(f, :invite_token, value: @invite_token) %>
<% end %>
<%= label(f, :email, class: "title text-lg text-primary-600") %>
@ -31,7 +29,7 @@
<%= select(
f,
:locale,
[{gettext("English"), "en_US"}, {gettext("German"), "de"}, {gettext("French"), "fr"}],
[{gettext("English"), "en_US"}],
class: "input input-primary col-span-2"
) %>
<%= error_tag(f, :locale) %>

View File

@ -54,7 +54,7 @@ msgstr ""
msgid "Delete User"
msgstr ""
#: lib/cannery_web/templates/user_registration/new.html.heex:49
#: lib/cannery_web/templates/user_registration/new.html.heex:47
#: lib/cannery_web/templates/user_reset_password/new.html.heex:3
#: lib/cannery_web/templates/user_session/new.html.heex:44
#, elixir-autogen, elixir-format
@ -68,7 +68,7 @@ msgstr ""
#: lib/cannery_web/components/topbar.ex:135
#: lib/cannery_web/templates/user_confirmation/new.html.heex:31
#: lib/cannery_web/templates/user_registration/new.html.heex:46
#: lib/cannery_web/templates/user_registration/new.html.heex:44
#: lib/cannery_web/templates/user_reset_password/edit.html.heex:47
#: lib/cannery_web/templates/user_reset_password/new.html.heex:31
#: lib/cannery_web/templates/user_session/new.html.heex:3
@ -100,7 +100,7 @@ msgstr ""
#: lib/cannery_web/components/topbar.ex:127
#: lib/cannery_web/templates/user_confirmation/new.html.heex:28
#: lib/cannery_web/templates/user_registration/new.html.heex:3
#: lib/cannery_web/templates/user_registration/new.html.heex:39
#: lib/cannery_web/templates/user_registration/new.html.heex:37
#: lib/cannery_web/templates/user_reset_password/edit.html.heex:44
#: lib/cannery_web/templates/user_reset_password/new.html.heex:28
#: lib/cannery_web/templates/user_session/new.html.heex:41

View File

@ -67,7 +67,7 @@ msgstr "Einladung erstellen"
msgid "Delete User"
msgstr "Benutzer löschen"
#: lib/cannery_web/templates/user_registration/new.html.heex:49
#: lib/cannery_web/templates/user_registration/new.html.heex:47
#: lib/cannery_web/templates/user_reset_password/new.html.heex:3
#: lib/cannery_web/templates/user_session/new.html.heex:44
#, elixir-autogen, elixir-format
@ -81,7 +81,7 @@ msgstr "Laden Sie jemanden ein!"
#: lib/cannery_web/components/topbar.ex:135
#: lib/cannery_web/templates/user_confirmation/new.html.heex:31
#: lib/cannery_web/templates/user_registration/new.html.heex:46
#: lib/cannery_web/templates/user_registration/new.html.heex:44
#: lib/cannery_web/templates/user_reset_password/edit.html.heex:47
#: lib/cannery_web/templates/user_reset_password/new.html.heex:31
#: lib/cannery_web/templates/user_session/new.html.heex:3
@ -113,7 +113,7 @@ msgstr "Neuer Tag"
#: lib/cannery_web/components/topbar.ex:127
#: lib/cannery_web/templates/user_confirmation/new.html.heex:28
#: lib/cannery_web/templates/user_registration/new.html.heex:3
#: lib/cannery_web/templates/user_registration/new.html.heex:39
#: lib/cannery_web/templates/user_registration/new.html.heex:37
#: lib/cannery_web/templates/user_reset_password/edit.html.heex:44
#: lib/cannery_web/templates/user_reset_password/new.html.heex:28
#: lib/cannery_web/templates/user_session/new.html.heex:41

View File

@ -141,7 +141,7 @@ msgstr "Beschreibung:"
msgid "Easy to Use:"
msgstr "Einfache Anwendung:"
#: lib/cannery_web/live/invite_live/index.ex:33
#: lib/cannery_web/live/invite_live/index.ex:34
#, elixir-autogen, elixir-format
msgid "Edit Invite"
msgstr "Einladung bearbeiten"
@ -178,7 +178,7 @@ msgstr "Brandmunition"
msgid "Instance Information"
msgstr "Instanzinformationen"
#: lib/cannery_web/components/invite_card.ex:41
#: lib/cannery_web/components/invite_card.ex:42
#, elixir-autogen, elixir-format
msgid "Invite Disabled"
msgstr "Einladung deaktiviert"
@ -189,7 +189,7 @@ msgid "Invite Only"
msgstr "Nur mit Einladung"
#: lib/cannery_web/components/topbar.ex:90
#: lib/cannery_web/live/invite_live/index.ex:41
#: lib/cannery_web/live/invite_live/index.ex:42
#: lib/cannery_web/live/invite_live/index.html.heex:3
#, elixir-autogen, elixir-format
msgid "Invites"
@ -256,7 +256,7 @@ msgstr "Neuer Munitionstyp"
msgid "New Container"
msgstr "Neuer Behälter"
#: lib/cannery_web/live/invite_live/index.ex:37
#: lib/cannery_web/live/invite_live/index.ex:38
#, elixir-autogen, elixir-format
msgid "New Invite"
msgstr "Neue Einladung"
@ -682,7 +682,7 @@ msgstr "Passwort vergessen?"
msgid "Log in"
msgstr "Einloggen"
#: lib/cannery_web/controllers/user_registration_controller.ex:34
#: lib/cannery_web/controllers/user_registration_controller.ex:32
#, elixir-autogen, elixir-format
msgid "Register"
msgstr "Registrieren"
@ -708,25 +708,23 @@ msgstr "Kopien"
msgid "Added on:"
msgstr "Hinzugefügt am:"
#: lib/cannery_web/templates/user_registration/new.html.heex:34
#: lib/cannery_web/templates/user_registration/new.html.heex:32
#: lib/cannery_web/templates/user_settings/edit.html.heex:133
#, elixir-autogen, elixir-format
msgid "English"
msgstr "Englisch"
#: lib/cannery_web/templates/user_registration/new.html.heex:34
#: lib/cannery_web/templates/user_settings/edit.html.heex:135
#, elixir-autogen, elixir-format
msgid "French"
msgstr "Französisch"
#: lib/cannery_web/templates/user_registration/new.html.heex:34
#: lib/cannery_web/templates/user_settings/edit.html.heex:134
#, elixir-autogen, elixir-format
msgid "German"
msgstr "Deutsch"
#: lib/cannery_web/templates/user_registration/new.html.heex:30
#: lib/cannery_web/templates/user_registration/new.html.heex:28
#, elixir-autogen, elixir-format
msgid "Language"
msgstr "Sprache"
@ -1139,12 +1137,7 @@ msgstr "Benutzer registriert am"
msgid "User was confirmed at%{confirmed_datetime}"
msgstr ""
#: lib/cannery_web/components/invite_card.ex:31
#, elixir-autogen, elixir-format, fuzzy
msgid "Uses Left: %{uses_left}"
msgstr "Verbleibende Nutzung:"
#: lib/cannery_web/components/invite_card.ex:36
#: lib/cannery_web/components/invite_card.ex:37
#, elixir-autogen, elixir-format, fuzzy
msgid "Uses Left: Unlimited"
msgstr "Verbleibende Nutzung:"
@ -1194,3 +1187,13 @@ msgstr ""
#, elixir-autogen, elixir-format
msgid "Enable"
msgstr ""
#: lib/cannery_web/components/invite_card.ex:32
#, elixir-autogen, elixir-format, fuzzy
msgid "Uses Left: %{uses_left_count}"
msgstr "Verbleibende Nutzung:"
#: lib/cannery_web/components/invite_card.ex:52
#, elixir-autogen, elixir-format
msgid "Uses: %{uses_count}"
msgstr ""

View File

@ -69,7 +69,7 @@ msgstr "Ungültige Mailadresse oder Passwort"
msgid "Not found"
msgstr "Nicht gefunden"
#: lib/cannery_web/templates/user_registration/new.html.heex:14
#: lib/cannery_web/templates/user_registration/new.html.heex:13
#: lib/cannery_web/templates/user_reset_password/edit.html.heex:14
#: lib/cannery_web/templates/user_settings/edit.html.heex:23
#: lib/cannery_web/templates/user_settings/edit.html.heex:67
@ -83,14 +83,15 @@ msgstr "Oops, etwas ist schiefgegangen. Bitte beachten Sie den Fehler unten."
msgid "Reset password link is invalid or it has expired."
msgstr "Link zum Passwort zurücksetzen ist ungültig oder abgelaufen."
#: lib/cannery_web/controllers/user_registration_controller.ex:24
#: lib/cannery_web/controllers/user_registration_controller.ex:55
#: lib/cannery_web/controllers/user_registration_controller.ex:22
#: lib/cannery_web/controllers/user_registration_controller.ex:51
#, elixir-autogen, elixir-format
msgid "Sorry, public registration is disabled"
msgstr "Entschuldigung, aber öffentliche Registrierung ist deaktiviert"
#: lib/cannery_web/controllers/user_registration_controller.ex:14
#: lib/cannery_web/controllers/user_registration_controller.ex:45
#: lib/cannery_web/controllers/user_registration_controller.ex:12
#: lib/cannery_web/controllers/user_registration_controller.ex:41
#: lib/cannery_web/controllers/user_registration_controller.ex:70
#, elixir-autogen, elixir-format
msgid "Sorry, this invite was not found or expired"
msgstr ""
@ -111,7 +112,7 @@ msgstr "Unbefugt"
msgid "User confirmation link is invalid or it has expired."
msgstr "Nutzerkonto Bestätigungslink ist ungültig oder abgelaufen."
#: lib/cannery_web/live/invite_live/index.ex:18
#: lib/cannery_web/live/invite_live/index.ex:19
#, elixir-autogen, elixir-format
msgid "You are not authorized to view this page"
msgstr "Sie sind nicht berechtigt, diese Seite aufzurufen"
@ -121,22 +122,22 @@ msgstr "Sie sind nicht berechtigt, diese Seite aufzurufen"
msgid "You are not authorized to view this page."
msgstr "Sie sind nicht berechtigt, diese Seite aufzurufen."
#: lib/cannery/accounts/user.ex:137
#: lib/cannery/accounts/user.ex:144
#, elixir-autogen, elixir-format
msgid "did not change"
msgstr "hat sich nicht geändert"
#: lib/cannery/accounts/user.ex:158
#: lib/cannery/accounts/user.ex:165
#, elixir-autogen, elixir-format
msgid "does not match password"
msgstr "Passwort stimmt nicht überein"
#: lib/cannery/accounts/user.ex:195
#: lib/cannery/accounts/user.ex:202
#, elixir-autogen, elixir-format
msgid "is not valid"
msgstr "ist nicht gültig"
#: lib/cannery/accounts/user.ex:92
#: lib/cannery/accounts/user.ex:99
#, elixir-autogen, elixir-format
msgid "must have the @ sign and no spaces"
msgstr "Muss ein @ Zeichen und keine Leerzeichen haben"

View File

@ -33,34 +33,17 @@ msgstr "%{name} erfolgreich erstellt"
#: lib/cannery_web/live/ammo_type_live/index.ex:73
#: lib/cannery_web/live/ammo_type_live/show.ex:55
#: lib/cannery_web/live/invite_live/index.ex:53
#: lib/cannery_web/live/invite_live/index.ex:133
#: lib/cannery_web/live/tag_live/index.ex:64
#, elixir-autogen, elixir-format
msgid "%{name} deleted succesfully"
msgstr "%{name} erfolgreich gelöscht"
#: lib/cannery_web/live/invite_live/index.ex:109
#, elixir-autogen, elixir-format
msgid "%{name} disabled succesfully"
msgstr "%{name} erfolgreich deaktiviert"
#: lib/cannery_web/live/invite_live/index.ex:87
#, elixir-autogen, elixir-format
msgid "%{name} enabled succesfully"
msgstr "%{name} erfolgreich aktiviert"
#: lib/cannery_web/live/container_live/index.ex:85
#: lib/cannery_web/live/container_live/show.ex:63
#, elixir-autogen, elixir-format
msgid "%{name} has been deleted"
msgstr "%{name} wurde gelöscht"
#: lib/cannery_web/live/invite_live/index.ex:67
#, elixir-autogen, elixir-format
msgid "%{name} updated succesfully"
msgstr "%{name} erfolgreich aktualisiert"
#: lib/cannery_web/live/ammo_type_live/form_component.ex:67
#: lib/cannery_web/live/container_live/form_component.ex:70
#: lib/cannery_web/live/invite_live/form_component.ex:62
@ -90,11 +73,6 @@ msgstr ""
msgid "Are you sure you want to delete %{name}?"
msgstr "Sind Sie sicher, dass sie %{name} löschen möchten?"
#: lib/cannery_web/live/invite_live/index.html.heex:48
#, elixir-autogen, elixir-format
msgid "Are you sure you want to delete the invite for %{name}?"
msgstr "Sind Sie sicher, dass sie die Einladung für %{name} löschen möchten?"
#: lib/cannery_web/live/ammo_group_live/index.html.heex:153
#: lib/cannery_web/live/ammo_group_live/show.html.heex:75
#, elixir-autogen, elixir-format
@ -111,11 +89,6 @@ msgstr "Sind Sie sicher, dass sie Ihren Account löschen möchten?"
msgid "Are you sure you want to log out?"
msgstr "Wirklich ausloggen?"
#: lib/cannery_web/live/invite_live/index.html.heex:73
#, elixir-autogen, elixir-format
msgid "Are you sure you want to make %{name} unlimited?"
msgstr "Sind Sie sicher, dass sie %{name} auf unbegrenzt setzen möchten?"
#: lib/cannery_web/controllers/user_settings_controller.ex:77
#, elixir-autogen, elixir-format
msgid "Email changed successfully."
@ -150,7 +123,7 @@ msgstr "Passwort erfolgreich zurückgesetzt."
msgid "Password updated successfully."
msgstr "Passwort erfolgreich geändert."
#: lib/cannery_web/controllers/user_registration_controller.ex:73
#: lib/cannery_web/controllers/user_registration_controller.ex:65
#, elixir-autogen, elixir-format
msgid "Please check your email to verify your account"
msgstr "Bitte überprüfen Sie ihre Mailbox und bestätigen Sie das Nutzerkonto"
@ -230,7 +203,7 @@ msgstr "%{email} erfolgreich bestätigt."
msgid "Ammo moved to %{name} successfully"
msgstr "Munition erfolgreich zu %{name} verschoben"
#: lib/cannery_web/live/invite_live/index.ex:121
#: lib/cannery_web/live/invite_live/index.ex:128
#, elixir-autogen, elixir-format
msgid "Copied to clipboard"
msgstr "Der Zwischenablage hinzugefügt"
@ -294,3 +267,38 @@ msgstr "Sind Sie sicher, dass sie %{name} löschen möchten?"
#, elixir-autogen, elixir-format, fuzzy
msgid "Register to setup Cannery"
msgstr "Registrieren Sie sich, um %{name} zu bearbeiten"
#: lib/cannery_web/live/invite_live/index.ex:54
#, elixir-autogen, elixir-format, fuzzy
msgid "%{invite_name} deleted succesfully"
msgstr "%{name} erfolgreich gelöscht"
#: lib/cannery_web/live/invite_live/index.ex:115
#, elixir-autogen, elixir-format, fuzzy
msgid "%{invite_name} disabled succesfully"
msgstr "%{name} erfolgreich deaktiviert"
#: lib/cannery_web/live/invite_live/index.ex:91
#, elixir-autogen, elixir-format, fuzzy
msgid "%{invite_name} enabled succesfully"
msgstr "%{name} erfolgreich aktiviert"
#: lib/cannery_web/live/invite_live/index.ex:69
#, elixir-autogen, elixir-format, fuzzy
msgid "%{invite_name} updated succesfully"
msgstr "%{name} erfolgreich aktualisiert"
#: lib/cannery_web/live/invite_live/index.ex:140
#, elixir-autogen, elixir-format, fuzzy
msgid "%{user_email} deleted succesfully"
msgstr "%{name} erfolgreich gelöscht"
#: lib/cannery_web/live/invite_live/index.html.heex:48
#, elixir-autogen, elixir-format, fuzzy
msgid "Are you sure you want to delete the invite for %{invite_name}?"
msgstr "Sind Sie sicher, dass sie die Einladung für %{name} löschen möchten?"
#: lib/cannery_web/live/invite_live/index.html.heex:73
#, elixir-autogen, elixir-format, fuzzy
msgid "Are you sure you want to make %{invite_name} unlimited?"
msgstr "Sind Sie sicher, dass sie %{name} auf unbegrenzt setzen möchten?"

View File

@ -137,7 +137,7 @@ msgstr ""
msgid "Easy to Use:"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:33
#: lib/cannery_web/live/invite_live/index.ex:34
#, elixir-autogen, elixir-format
msgid "Edit Invite"
msgstr ""
@ -174,7 +174,7 @@ msgstr ""
msgid "Instance Information"
msgstr ""
#: lib/cannery_web/components/invite_card.ex:41
#: lib/cannery_web/components/invite_card.ex:42
#, elixir-autogen, elixir-format
msgid "Invite Disabled"
msgstr ""
@ -185,7 +185,7 @@ msgid "Invite Only"
msgstr ""
#: lib/cannery_web/components/topbar.ex:90
#: lib/cannery_web/live/invite_live/index.ex:41
#: lib/cannery_web/live/invite_live/index.ex:42
#: lib/cannery_web/live/invite_live/index.html.heex:3
#, elixir-autogen, elixir-format
msgid "Invites"
@ -252,7 +252,7 @@ msgstr ""
msgid "New Container"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:37
#: lib/cannery_web/live/invite_live/index.ex:38
#, elixir-autogen, elixir-format
msgid "New Invite"
msgstr ""
@ -676,7 +676,7 @@ msgstr ""
msgid "Log in"
msgstr ""
#: lib/cannery_web/controllers/user_registration_controller.ex:34
#: lib/cannery_web/controllers/user_registration_controller.ex:32
#, elixir-autogen, elixir-format
msgid "Register"
msgstr ""
@ -702,25 +702,23 @@ msgstr ""
msgid "Added on:"
msgstr ""
#: lib/cannery_web/templates/user_registration/new.html.heex:34
#: lib/cannery_web/templates/user_registration/new.html.heex:32
#: lib/cannery_web/templates/user_settings/edit.html.heex:133
#, elixir-autogen, elixir-format
msgid "English"
msgstr ""
#: lib/cannery_web/templates/user_registration/new.html.heex:34
#: lib/cannery_web/templates/user_settings/edit.html.heex:135
#, elixir-autogen, elixir-format
msgid "French"
msgstr ""
#: lib/cannery_web/templates/user_registration/new.html.heex:34
#: lib/cannery_web/templates/user_settings/edit.html.heex:134
#, elixir-autogen, elixir-format
msgid "German"
msgstr ""
#: lib/cannery_web/templates/user_registration/new.html.heex:30
#: lib/cannery_web/templates/user_registration/new.html.heex:28
#, elixir-autogen, elixir-format
msgid "Language"
msgstr ""
@ -1133,12 +1131,7 @@ msgstr ""
msgid "User was confirmed at%{confirmed_datetime}"
msgstr ""
#: lib/cannery_web/components/invite_card.ex:31
#, elixir-autogen, elixir-format
msgid "Uses Left: %{uses_left}"
msgstr ""
#: lib/cannery_web/components/invite_card.ex:36
#: lib/cannery_web/components/invite_card.ex:37
#, elixir-autogen, elixir-format
msgid "Uses Left: Unlimited"
msgstr ""
@ -1177,3 +1170,13 @@ msgstr ""
#, elixir-autogen, elixir-format
msgid "Enable"
msgstr ""
#: lib/cannery_web/components/invite_card.ex:32
#, elixir-autogen, elixir-format
msgid "Uses Left: %{uses_left_count}"
msgstr ""
#: lib/cannery_web/components/invite_card.ex:52
#, elixir-autogen, elixir-format
msgid "Uses: %{uses_count}"
msgstr ""

View File

@ -54,7 +54,7 @@ msgstr ""
msgid "Delete User"
msgstr ""
#: lib/cannery_web/templates/user_registration/new.html.heex:49
#: lib/cannery_web/templates/user_registration/new.html.heex:47
#: lib/cannery_web/templates/user_reset_password/new.html.heex:3
#: lib/cannery_web/templates/user_session/new.html.heex:44
#, elixir-autogen, elixir-format
@ -68,7 +68,7 @@ msgstr ""
#: lib/cannery_web/components/topbar.ex:135
#: lib/cannery_web/templates/user_confirmation/new.html.heex:31
#: lib/cannery_web/templates/user_registration/new.html.heex:46
#: lib/cannery_web/templates/user_registration/new.html.heex:44
#: lib/cannery_web/templates/user_reset_password/edit.html.heex:47
#: lib/cannery_web/templates/user_reset_password/new.html.heex:31
#: lib/cannery_web/templates/user_session/new.html.heex:3
@ -100,7 +100,7 @@ msgstr ""
#: lib/cannery_web/components/topbar.ex:127
#: lib/cannery_web/templates/user_confirmation/new.html.heex:28
#: lib/cannery_web/templates/user_registration/new.html.heex:3
#: lib/cannery_web/templates/user_registration/new.html.heex:39
#: lib/cannery_web/templates/user_registration/new.html.heex:37
#: lib/cannery_web/templates/user_reset_password/edit.html.heex:44
#: lib/cannery_web/templates/user_reset_password/new.html.heex:28
#: lib/cannery_web/templates/user_session/new.html.heex:41

View File

@ -137,7 +137,7 @@ msgstr ""
msgid "Easy to Use:"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:33
#: lib/cannery_web/live/invite_live/index.ex:34
#, elixir-autogen, elixir-format
msgid "Edit Invite"
msgstr ""
@ -174,7 +174,7 @@ msgstr ""
msgid "Instance Information"
msgstr ""
#: lib/cannery_web/components/invite_card.ex:41
#: lib/cannery_web/components/invite_card.ex:42
#, elixir-autogen, elixir-format
msgid "Invite Disabled"
msgstr ""
@ -185,7 +185,7 @@ msgid "Invite Only"
msgstr ""
#: lib/cannery_web/components/topbar.ex:90
#: lib/cannery_web/live/invite_live/index.ex:41
#: lib/cannery_web/live/invite_live/index.ex:42
#: lib/cannery_web/live/invite_live/index.html.heex:3
#, elixir-autogen, elixir-format
msgid "Invites"
@ -252,7 +252,7 @@ msgstr ""
msgid "New Container"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:37
#: lib/cannery_web/live/invite_live/index.ex:38
#, elixir-autogen, elixir-format
msgid "New Invite"
msgstr ""
@ -676,7 +676,7 @@ msgstr ""
msgid "Log in"
msgstr ""
#: lib/cannery_web/controllers/user_registration_controller.ex:34
#: lib/cannery_web/controllers/user_registration_controller.ex:32
#, elixir-autogen, elixir-format
msgid "Register"
msgstr ""
@ -702,25 +702,23 @@ msgstr ""
msgid "Added on:"
msgstr ""
#: lib/cannery_web/templates/user_registration/new.html.heex:34
#: lib/cannery_web/templates/user_registration/new.html.heex:32
#: lib/cannery_web/templates/user_settings/edit.html.heex:133
#, elixir-autogen, elixir-format
msgid "English"
msgstr ""
#: lib/cannery_web/templates/user_registration/new.html.heex:34
#: lib/cannery_web/templates/user_settings/edit.html.heex:135
#, elixir-autogen, elixir-format
msgid "French"
msgstr ""
#: lib/cannery_web/templates/user_registration/new.html.heex:34
#: lib/cannery_web/templates/user_settings/edit.html.heex:134
#, elixir-autogen, elixir-format
msgid "German"
msgstr ""
#: lib/cannery_web/templates/user_registration/new.html.heex:30
#: lib/cannery_web/templates/user_registration/new.html.heex:28
#, elixir-autogen, elixir-format
msgid "Language"
msgstr ""
@ -1133,12 +1131,7 @@ msgstr ""
msgid "User was confirmed at%{confirmed_datetime}"
msgstr ""
#: lib/cannery_web/components/invite_card.ex:31
#, elixir-autogen, elixir-format, fuzzy
msgid "Uses Left: %{uses_left}"
msgstr ""
#: lib/cannery_web/components/invite_card.ex:36
#: lib/cannery_web/components/invite_card.ex:37
#, elixir-autogen, elixir-format, fuzzy
msgid "Uses Left: Unlimited"
msgstr ""
@ -1177,3 +1170,13 @@ msgstr ""
#, elixir-autogen, elixir-format
msgid "Enable"
msgstr ""
#: lib/cannery_web/components/invite_card.ex:32
#, elixir-autogen, elixir-format, fuzzy
msgid "Uses Left: %{uses_left_count}"
msgstr ""
#: lib/cannery_web/components/invite_card.ex:52
#, elixir-autogen, elixir-format
msgid "Uses: %{uses_count}"
msgstr ""

View File

@ -56,7 +56,7 @@ msgstr ""
msgid "Not found"
msgstr ""
#: lib/cannery_web/templates/user_registration/new.html.heex:14
#: lib/cannery_web/templates/user_registration/new.html.heex:13
#: lib/cannery_web/templates/user_reset_password/edit.html.heex:14
#: lib/cannery_web/templates/user_settings/edit.html.heex:23
#: lib/cannery_web/templates/user_settings/edit.html.heex:67
@ -70,14 +70,15 @@ msgstr ""
msgid "Reset password link is invalid or it has expired."
msgstr ""
#: lib/cannery_web/controllers/user_registration_controller.ex:24
#: lib/cannery_web/controllers/user_registration_controller.ex:55
#: lib/cannery_web/controllers/user_registration_controller.ex:22
#: lib/cannery_web/controllers/user_registration_controller.ex:51
#, elixir-autogen, elixir-format
msgid "Sorry, public registration is disabled"
msgstr ""
#: lib/cannery_web/controllers/user_registration_controller.ex:14
#: lib/cannery_web/controllers/user_registration_controller.ex:45
#: lib/cannery_web/controllers/user_registration_controller.ex:12
#: lib/cannery_web/controllers/user_registration_controller.ex:41
#: lib/cannery_web/controllers/user_registration_controller.ex:70
#, elixir-autogen, elixir-format
msgid "Sorry, this invite was not found or expired"
msgstr ""
@ -97,7 +98,7 @@ msgstr ""
msgid "User confirmation link is invalid or it has expired."
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:18
#: lib/cannery_web/live/invite_live/index.ex:19
#, elixir-autogen, elixir-format
msgid "You are not authorized to view this page"
msgstr ""
@ -107,23 +108,23 @@ msgstr ""
msgid "You are not authorized to view this page."
msgstr ""
#: lib/cannery/accounts/user.ex:137
#: lib/cannery/accounts/user.ex:144
#, elixir-autogen, elixir-format
msgid "did not change"
msgstr ""
#: lib/cannery/accounts/user.ex:158
#: lib/cannery/accounts/user.ex:165
#, elixir-autogen, elixir-format
msgid "does not match password"
msgstr ""
## From Ecto.Changeset.put_change/3
#: lib/cannery/accounts/user.ex:195
#: lib/cannery/accounts/user.ex:202
#, elixir-autogen, elixir-format, fuzzy
msgid "is not valid"
msgstr ""
#: lib/cannery/accounts/user.ex:92
#: lib/cannery/accounts/user.ex:99
#, elixir-autogen, elixir-format
msgid "must have the @ sign and no spaces"
msgstr ""

View File

@ -20,34 +20,17 @@ msgstr ""
#: lib/cannery_web/live/ammo_type_live/index.ex:73
#: lib/cannery_web/live/ammo_type_live/show.ex:55
#: lib/cannery_web/live/invite_live/index.ex:53
#: lib/cannery_web/live/invite_live/index.ex:133
#: lib/cannery_web/live/tag_live/index.ex:64
#, elixir-autogen, elixir-format
msgid "%{name} deleted succesfully"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:109
#, elixir-autogen, elixir-format
msgid "%{name} disabled succesfully"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:87
#, elixir-autogen, elixir-format
msgid "%{name} enabled succesfully"
msgstr ""
#: lib/cannery_web/live/container_live/index.ex:85
#: lib/cannery_web/live/container_live/show.ex:63
#, elixir-autogen, elixir-format
msgid "%{name} has been deleted"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:67
#, elixir-autogen, elixir-format
msgid "%{name} updated succesfully"
msgstr ""
#: lib/cannery_web/live/ammo_type_live/form_component.ex:67
#: lib/cannery_web/live/container_live/form_component.ex:70
#: lib/cannery_web/live/invite_live/form_component.ex:62
@ -75,11 +58,6 @@ msgstr ""
msgid "Are you sure you want to delete %{name}?"
msgstr ""
#: lib/cannery_web/live/invite_live/index.html.heex:48
#, elixir-autogen, elixir-format
msgid "Are you sure you want to delete the invite for %{name}?"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:153
#: lib/cannery_web/live/ammo_group_live/show.html.heex:75
#, elixir-autogen, elixir-format
@ -96,11 +74,6 @@ msgstr ""
msgid "Are you sure you want to log out?"
msgstr ""
#: lib/cannery_web/live/invite_live/index.html.heex:73
#, elixir-autogen, elixir-format
msgid "Are you sure you want to make %{name} unlimited?"
msgstr ""
#: lib/cannery_web/controllers/user_settings_controller.ex:77
#, elixir-autogen, elixir-format
msgid "Email changed successfully."
@ -131,7 +104,7 @@ msgstr ""
msgid "Password updated successfully."
msgstr ""
#: lib/cannery_web/controllers/user_registration_controller.ex:73
#: lib/cannery_web/controllers/user_registration_controller.ex:65
#, elixir-autogen, elixir-format
msgid "Please check your email to verify your account"
msgstr ""
@ -209,7 +182,7 @@ msgstr ""
msgid "Ammo moved to %{name} successfully"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:121
#: lib/cannery_web/live/invite_live/index.ex:128
#, elixir-autogen, elixir-format
msgid "Copied to clipboard"
msgstr ""
@ -273,3 +246,38 @@ msgstr ""
#, elixir-autogen, elixir-format, fuzzy
msgid "Register to setup Cannery"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:54
#, elixir-autogen, elixir-format, fuzzy
msgid "%{invite_name} deleted succesfully"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:115
#, elixir-autogen, elixir-format, fuzzy
msgid "%{invite_name} disabled succesfully"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:91
#, elixir-autogen, elixir-format, fuzzy
msgid "%{invite_name} enabled succesfully"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:69
#, elixir-autogen, elixir-format, fuzzy
msgid "%{invite_name} updated succesfully"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:140
#, elixir-autogen, elixir-format, fuzzy
msgid "%{user_email} deleted succesfully"
msgstr ""
#: lib/cannery_web/live/invite_live/index.html.heex:48
#, elixir-autogen, elixir-format, fuzzy
msgid "Are you sure you want to delete the invite for %{invite_name}?"
msgstr ""
#: lib/cannery_web/live/invite_live/index.html.heex:73
#, elixir-autogen, elixir-format, fuzzy
msgid "Are you sure you want to make %{invite_name} unlimited?"
msgstr ""

View File

@ -56,7 +56,7 @@ msgstr ""
msgid "Not found"
msgstr ""
#: lib/cannery_web/templates/user_registration/new.html.heex:14
#: lib/cannery_web/templates/user_registration/new.html.heex:13
#: lib/cannery_web/templates/user_reset_password/edit.html.heex:14
#: lib/cannery_web/templates/user_settings/edit.html.heex:23
#: lib/cannery_web/templates/user_settings/edit.html.heex:67
@ -70,14 +70,15 @@ msgstr ""
msgid "Reset password link is invalid or it has expired."
msgstr ""
#: lib/cannery_web/controllers/user_registration_controller.ex:24
#: lib/cannery_web/controllers/user_registration_controller.ex:55
#: lib/cannery_web/controllers/user_registration_controller.ex:22
#: lib/cannery_web/controllers/user_registration_controller.ex:51
#, elixir-autogen, elixir-format
msgid "Sorry, public registration is disabled"
msgstr ""
#: lib/cannery_web/controllers/user_registration_controller.ex:14
#: lib/cannery_web/controllers/user_registration_controller.ex:45
#: lib/cannery_web/controllers/user_registration_controller.ex:12
#: lib/cannery_web/controllers/user_registration_controller.ex:41
#: lib/cannery_web/controllers/user_registration_controller.ex:70
#, elixir-autogen, elixir-format
msgid "Sorry, this invite was not found or expired"
msgstr ""
@ -97,7 +98,7 @@ msgstr ""
msgid "User confirmation link is invalid or it has expired."
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:18
#: lib/cannery_web/live/invite_live/index.ex:19
#, elixir-autogen, elixir-format
msgid "You are not authorized to view this page"
msgstr ""
@ -107,22 +108,22 @@ msgstr ""
msgid "You are not authorized to view this page."
msgstr ""
#: lib/cannery/accounts/user.ex:137
#: lib/cannery/accounts/user.ex:144
#, elixir-autogen, elixir-format
msgid "did not change"
msgstr ""
#: lib/cannery/accounts/user.ex:158
#: lib/cannery/accounts/user.ex:165
#, elixir-autogen, elixir-format
msgid "does not match password"
msgstr ""
#: lib/cannery/accounts/user.ex:195
#: lib/cannery/accounts/user.ex:202
#, elixir-autogen, elixir-format
msgid "is not valid"
msgstr ""
#: lib/cannery/accounts/user.ex:92
#: lib/cannery/accounts/user.ex:99
#, elixir-autogen, elixir-format
msgid "must have the @ sign and no spaces"
msgstr ""

View File

@ -67,7 +67,7 @@ msgstr "Crear Invitación"
msgid "Delete User"
msgstr "Eliminar cuenta de Usuario"
#: lib/cannery_web/templates/user_registration/new.html.heex:49
#: lib/cannery_web/templates/user_registration/new.html.heex:47
#: lib/cannery_web/templates/user_reset_password/new.html.heex:3
#: lib/cannery_web/templates/user_session/new.html.heex:44
#, elixir-autogen, elixir-format
@ -81,7 +81,7 @@ msgstr "¡Invita a alguien nuevo!"
#: lib/cannery_web/components/topbar.ex:135
#: lib/cannery_web/templates/user_confirmation/new.html.heex:31
#: lib/cannery_web/templates/user_registration/new.html.heex:46
#: lib/cannery_web/templates/user_registration/new.html.heex:44
#: lib/cannery_web/templates/user_reset_password/edit.html.heex:47
#: lib/cannery_web/templates/user_reset_password/new.html.heex:31
#: lib/cannery_web/templates/user_session/new.html.heex:3
@ -113,7 +113,7 @@ msgstr "Nueva Etiqueta"
#: lib/cannery_web/components/topbar.ex:127
#: lib/cannery_web/templates/user_confirmation/new.html.heex:28
#: lib/cannery_web/templates/user_registration/new.html.heex:3
#: lib/cannery_web/templates/user_registration/new.html.heex:39
#: lib/cannery_web/templates/user_registration/new.html.heex:37
#: lib/cannery_web/templates/user_reset_password/edit.html.heex:44
#: lib/cannery_web/templates/user_reset_password/new.html.heex:28
#: lib/cannery_web/templates/user_session/new.html.heex:41

View File

@ -141,7 +141,7 @@ msgstr "Descripción:"
msgid "Easy to Use:"
msgstr "Facil de Usar:"
#: lib/cannery_web/live/invite_live/index.ex:33
#: lib/cannery_web/live/invite_live/index.ex:34
#, elixir-autogen, elixir-format
msgid "Edit Invite"
msgstr "Editar Invitación"
@ -178,7 +178,7 @@ msgstr "Incendiaria"
msgid "Instance Information"
msgstr "Información de Instancia"
#: lib/cannery_web/components/invite_card.ex:41
#: lib/cannery_web/components/invite_card.ex:42
#, elixir-autogen, elixir-format
msgid "Invite Disabled"
msgstr "Invitación Desactivada"
@ -189,7 +189,7 @@ msgid "Invite Only"
msgstr "Solo Invitación"
#: lib/cannery_web/components/topbar.ex:90
#: lib/cannery_web/live/invite_live/index.ex:41
#: lib/cannery_web/live/invite_live/index.ex:42
#: lib/cannery_web/live/invite_live/index.html.heex:3
#, elixir-autogen, elixir-format
msgid "Invites"
@ -256,7 +256,7 @@ msgstr "Nuevo tipo de Munición"
msgid "New Container"
msgstr "Nuevo Contenedor"
#: lib/cannery_web/live/invite_live/index.ex:37
#: lib/cannery_web/live/invite_live/index.ex:38
#, elixir-autogen, elixir-format
msgid "New Invite"
msgstr "Nueva Invitación"
@ -683,7 +683,7 @@ msgstr "¿Olvidó su contraseña?"
msgid "Log in"
msgstr "Entrar"
#: lib/cannery_web/controllers/user_registration_controller.ex:34
#: lib/cannery_web/controllers/user_registration_controller.ex:32
#, elixir-autogen, elixir-format
msgid "Register"
msgstr "Registrarse"
@ -709,25 +709,23 @@ msgstr "Copias"
msgid "Added on:"
msgstr "Añadido en:"
#: lib/cannery_web/templates/user_registration/new.html.heex:34
#: lib/cannery_web/templates/user_registration/new.html.heex:32
#: lib/cannery_web/templates/user_settings/edit.html.heex:133
#, elixir-autogen, elixir-format
msgid "English"
msgstr "Inglés"
#: lib/cannery_web/templates/user_registration/new.html.heex:34
#: lib/cannery_web/templates/user_settings/edit.html.heex:135
#, elixir-autogen, elixir-format
msgid "French"
msgstr "Francés"
#: lib/cannery_web/templates/user_registration/new.html.heex:34
#: lib/cannery_web/templates/user_settings/edit.html.heex:134
#, elixir-autogen, elixir-format
msgid "German"
msgstr "Alemán"
#: lib/cannery_web/templates/user_registration/new.html.heex:30
#: lib/cannery_web/templates/user_registration/new.html.heex:28
#, elixir-autogen, elixir-format
msgid "Language"
msgstr "Idioma"
@ -1141,12 +1139,7 @@ msgstr "Usuario registrado en"
msgid "User was confirmed at%{confirmed_datetime}"
msgstr ""
#: lib/cannery_web/components/invite_card.ex:31
#, elixir-autogen, elixir-format, fuzzy
msgid "Uses Left: %{uses_left}"
msgstr "Usos Restantes:"
#: lib/cannery_web/components/invite_card.ex:36
#: lib/cannery_web/components/invite_card.ex:37
#, elixir-autogen, elixir-format, fuzzy
msgid "Uses Left: Unlimited"
msgstr "Usos Restantes:"
@ -1196,3 +1189,13 @@ msgstr ""
#, elixir-autogen, elixir-format
msgid "Enable"
msgstr ""
#: lib/cannery_web/components/invite_card.ex:32
#, elixir-autogen, elixir-format, fuzzy
msgid "Uses Left: %{uses_left_count}"
msgstr "Usos Restantes:"
#: lib/cannery_web/components/invite_card.ex:52
#, elixir-autogen, elixir-format
msgid "Uses: %{uses_count}"
msgstr ""

View File

@ -69,7 +69,7 @@ msgstr "Correo o contraseña incorrecta"
msgid "Not found"
msgstr "No se encontró"
#: lib/cannery_web/templates/user_registration/new.html.heex:14
#: lib/cannery_web/templates/user_registration/new.html.heex:13
#: lib/cannery_web/templates/user_reset_password/edit.html.heex:14
#: lib/cannery_web/templates/user_settings/edit.html.heex:23
#: lib/cannery_web/templates/user_settings/edit.html.heex:67
@ -86,14 +86,15 @@ msgid "Reset password link is invalid or it has expired."
msgstr ""
"El enlace de reestablecimiento de la contraseña es inválido o ha caducado."
#: lib/cannery_web/controllers/user_registration_controller.ex:24
#: lib/cannery_web/controllers/user_registration_controller.ex:55
#: lib/cannery_web/controllers/user_registration_controller.ex:22
#: lib/cannery_web/controllers/user_registration_controller.ex:51
#, elixir-autogen, elixir-format
msgid "Sorry, public registration is disabled"
msgstr "Lo sentimos, el registro público no está habilitado"
#: lib/cannery_web/controllers/user_registration_controller.ex:14
#: lib/cannery_web/controllers/user_registration_controller.ex:45
#: lib/cannery_web/controllers/user_registration_controller.ex:12
#: lib/cannery_web/controllers/user_registration_controller.ex:41
#: lib/cannery_web/controllers/user_registration_controller.ex:70
#, elixir-autogen, elixir-format
msgid "Sorry, this invite was not found or expired"
msgstr "Lo sentimos, esta invitación no es válida o ha caducado"
@ -113,7 +114,7 @@ msgstr "No autorizado"
msgid "User confirmation link is invalid or it has expired."
msgstr "El enlace de confirmación de usuario no es válido o ha caducado."
#: lib/cannery_web/live/invite_live/index.ex:18
#: lib/cannery_web/live/invite_live/index.ex:19
#, elixir-autogen, elixir-format
msgid "You are not authorized to view this page"
msgstr "No está autorizado a ver esta página"
@ -123,22 +124,22 @@ msgstr "No está autorizado a ver esta página"
msgid "You are not authorized to view this page."
msgstr "No está autorizado a ver esta página."
#: lib/cannery/accounts/user.ex:137
#: lib/cannery/accounts/user.ex:144
#, elixir-autogen, elixir-format
msgid "did not change"
msgstr "no cambió"
#: lib/cannery/accounts/user.ex:158
#: lib/cannery/accounts/user.ex:165
#, elixir-autogen, elixir-format
msgid "does not match password"
msgstr "no coincide con la contraseña"
#: lib/cannery/accounts/user.ex:195
#: lib/cannery/accounts/user.ex:202
#, elixir-autogen, elixir-format
msgid "is not valid"
msgstr "no es válido"
#: lib/cannery/accounts/user.ex:92
#: lib/cannery/accounts/user.ex:99
#, elixir-autogen, elixir-format
msgid "must have the @ sign and no spaces"
msgstr "debe tener el signo @ y no contener espacios"

View File

@ -33,34 +33,17 @@ msgstr "%{name} creado exitosamente"
#: lib/cannery_web/live/ammo_type_live/index.ex:73
#: lib/cannery_web/live/ammo_type_live/show.ex:55
#: lib/cannery_web/live/invite_live/index.ex:53
#: lib/cannery_web/live/invite_live/index.ex:133
#: lib/cannery_web/live/tag_live/index.ex:64
#, elixir-autogen, elixir-format
msgid "%{name} deleted succesfully"
msgstr "%{name} borrado exitosamente"
#: lib/cannery_web/live/invite_live/index.ex:109
#, elixir-autogen, elixir-format
msgid "%{name} disabled succesfully"
msgstr "%{name} desactivado exitosamente"
#: lib/cannery_web/live/invite_live/index.ex:87
#, elixir-autogen, elixir-format
msgid "%{name} enabled succesfully"
msgstr "%{name} activado exitosamente"
#: lib/cannery_web/live/container_live/index.ex:85
#: lib/cannery_web/live/container_live/show.ex:63
#, elixir-autogen, elixir-format
msgid "%{name} has been deleted"
msgstr "%{name} ha sido borrado"
#: lib/cannery_web/live/invite_live/index.ex:67
#, elixir-autogen, elixir-format
msgid "%{name} updated succesfully"
msgstr "%{name} actualizado exitosamente"
#: lib/cannery_web/live/ammo_type_live/form_component.ex:67
#: lib/cannery_web/live/container_live/form_component.ex:70
#: lib/cannery_web/live/invite_live/form_component.ex:62
@ -90,11 +73,6 @@ msgstr "Está seguro que desea eliminar %{email}? Esta acción es permanente!"
msgid "Are you sure you want to delete %{name}?"
msgstr "Está seguro que desea eliminar %{name}?"
#: lib/cannery_web/live/invite_live/index.html.heex:48
#, elixir-autogen, elixir-format
msgid "Are you sure you want to delete the invite for %{name}?"
msgstr "Está seguro que quiere eliminar la invitación para %{name}?"
#: lib/cannery_web/live/ammo_group_live/index.html.heex:153
#: lib/cannery_web/live/ammo_group_live/show.html.heex:75
#, elixir-autogen, elixir-format
@ -111,11 +89,6 @@ msgstr "Está seguro que desea eliminar su cuenta?"
msgid "Are you sure you want to log out?"
msgstr "Está seguro que desea cerrar sesión?"
#: lib/cannery_web/live/invite_live/index.html.heex:73
#, elixir-autogen, elixir-format
msgid "Are you sure you want to make %{name} unlimited?"
msgstr "Está seguro que desea hacer %{name} ilimitado?"
#: lib/cannery_web/controllers/user_settings_controller.ex:77
#, elixir-autogen, elixir-format
msgid "Email changed successfully."
@ -150,7 +123,7 @@ msgstr "Contraseña reiniciada exitosamente."
msgid "Password updated successfully."
msgstr "Contraseña cambiada exitosamente."
#: lib/cannery_web/controllers/user_registration_controller.ex:73
#: lib/cannery_web/controllers/user_registration_controller.ex:65
#, elixir-autogen, elixir-format
msgid "Please check your email to verify your account"
msgstr "Por favor chequea el correo para verificar tu cuenta"
@ -229,7 +202,7 @@ msgstr "%{email} confirmado exitosamente."
msgid "Ammo moved to %{name} successfully"
msgstr "Munición movida a %{name} exitosamente"
#: lib/cannery_web/live/invite_live/index.ex:121
#: lib/cannery_web/live/invite_live/index.ex:128
#, elixir-autogen, elixir-format
msgid "Copied to clipboard"
msgstr "Copiado al portapapeles"
@ -295,3 +268,38 @@ msgstr ""
#, elixir-autogen, elixir-format, fuzzy
msgid "Register to setup Cannery"
msgstr "Regístrese para configurar %{name}"
#: lib/cannery_web/live/invite_live/index.ex:54
#, elixir-autogen, elixir-format, fuzzy
msgid "%{invite_name} deleted succesfully"
msgstr "%{name} borrado exitosamente"
#: lib/cannery_web/live/invite_live/index.ex:115
#, elixir-autogen, elixir-format, fuzzy
msgid "%{invite_name} disabled succesfully"
msgstr "%{name} desactivado exitosamente"
#: lib/cannery_web/live/invite_live/index.ex:91
#, elixir-autogen, elixir-format, fuzzy
msgid "%{invite_name} enabled succesfully"
msgstr "%{name} activado exitosamente"
#: lib/cannery_web/live/invite_live/index.ex:69
#, elixir-autogen, elixir-format, fuzzy
msgid "%{invite_name} updated succesfully"
msgstr "%{name} actualizado exitosamente"
#: lib/cannery_web/live/invite_live/index.ex:140
#, elixir-autogen, elixir-format, fuzzy
msgid "%{user_email} deleted succesfully"
msgstr "%{name} borrado exitosamente"
#: lib/cannery_web/live/invite_live/index.html.heex:48
#, elixir-autogen, elixir-format, fuzzy
msgid "Are you sure you want to delete the invite for %{invite_name}?"
msgstr "Está seguro que quiere eliminar la invitación para %{name}?"
#: lib/cannery_web/live/invite_live/index.html.heex:73
#, elixir-autogen, elixir-format, fuzzy
msgid "Are you sure you want to make %{invite_name} unlimited?"
msgstr "Está seguro que desea hacer %{name} ilimitado?"

View File

@ -67,7 +67,7 @@ msgstr "Créer une invitation"
msgid "Delete User"
msgstr "Supprimer utilisateur"
#: lib/cannery_web/templates/user_registration/new.html.heex:49
#: lib/cannery_web/templates/user_registration/new.html.heex:47
#: lib/cannery_web/templates/user_reset_password/new.html.heex:3
#: lib/cannery_web/templates/user_session/new.html.heex:44
#, elixir-autogen, elixir-format
@ -81,7 +81,7 @@ msgstr "Invitez une nouvelle personne!"
#: lib/cannery_web/components/topbar.ex:135
#: lib/cannery_web/templates/user_confirmation/new.html.heex:31
#: lib/cannery_web/templates/user_registration/new.html.heex:46
#: lib/cannery_web/templates/user_registration/new.html.heex:44
#: lib/cannery_web/templates/user_reset_password/edit.html.heex:47
#: lib/cannery_web/templates/user_reset_password/new.html.heex:31
#: lib/cannery_web/templates/user_session/new.html.heex:3
@ -113,7 +113,7 @@ msgstr "Nouveau tag"
#: lib/cannery_web/components/topbar.ex:127
#: lib/cannery_web/templates/user_confirmation/new.html.heex:28
#: lib/cannery_web/templates/user_registration/new.html.heex:3
#: lib/cannery_web/templates/user_registration/new.html.heex:39
#: lib/cannery_web/templates/user_registration/new.html.heex:37
#: lib/cannery_web/templates/user_reset_password/edit.html.heex:44
#: lib/cannery_web/templates/user_reset_password/new.html.heex:28
#: lib/cannery_web/templates/user_session/new.html.heex:41

View File

@ -141,7 +141,7 @@ msgstr "Description:"
msgid "Easy to Use:"
msgstr "Simple à utiliser:"
#: lib/cannery_web/live/invite_live/index.ex:33
#: lib/cannery_web/live/invite_live/index.ex:34
#, elixir-autogen, elixir-format
msgid "Edit Invite"
msgstr "Modifier linvitation"
@ -178,7 +178,7 @@ msgstr "Incendiaire"
msgid "Instance Information"
msgstr "Information de linstance"
#: lib/cannery_web/components/invite_card.ex:41
#: lib/cannery_web/components/invite_card.ex:42
#, elixir-autogen, elixir-format
msgid "Invite Disabled"
msgstr "Invitation désactivée"
@ -189,7 +189,7 @@ msgid "Invite Only"
msgstr "Uniquement sur invitation"
#: lib/cannery_web/components/topbar.ex:90
#: lib/cannery_web/live/invite_live/index.ex:41
#: lib/cannery_web/live/invite_live/index.ex:42
#: lib/cannery_web/live/invite_live/index.html.heex:3
#, elixir-autogen, elixir-format
msgid "Invites"
@ -256,7 +256,7 @@ msgstr "Nouveau type de munition"
msgid "New Container"
msgstr "Nouveau conteneur"
#: lib/cannery_web/live/invite_live/index.ex:37
#: lib/cannery_web/live/invite_live/index.ex:38
#, elixir-autogen, elixir-format
msgid "New Invite"
msgstr "Nouvelle invitation"
@ -684,7 +684,7 @@ msgstr "Mot de passe oublié?"
msgid "Log in"
msgstr "Se connecter"
#: lib/cannery_web/controllers/user_registration_controller.ex:34
#: lib/cannery_web/controllers/user_registration_controller.ex:32
#, elixir-autogen, elixir-format
msgid "Register"
msgstr "Senregistrer"
@ -710,25 +710,23 @@ msgstr "Exemplaires"
msgid "Added on:"
msgstr "Ajouté le:"
#: lib/cannery_web/templates/user_registration/new.html.heex:34
#: lib/cannery_web/templates/user_registration/new.html.heex:32
#: lib/cannery_web/templates/user_settings/edit.html.heex:133
#, elixir-autogen, elixir-format
msgid "English"
msgstr "Anglais"
#: lib/cannery_web/templates/user_registration/new.html.heex:34
#: lib/cannery_web/templates/user_settings/edit.html.heex:135
#, elixir-autogen, elixir-format
msgid "French"
msgstr "Français"
#: lib/cannery_web/templates/user_registration/new.html.heex:34
#: lib/cannery_web/templates/user_settings/edit.html.heex:134
#, elixir-autogen, elixir-format
msgid "German"
msgstr "Allemand"
#: lib/cannery_web/templates/user_registration/new.html.heex:30
#: lib/cannery_web/templates/user_registration/new.html.heex:28
#, elixir-autogen, elixir-format
msgid "Language"
msgstr "Langue"
@ -1142,12 +1140,7 @@ msgstr "Utilisateur·ice enregistré·e le"
msgid "User was confirmed at%{confirmed_datetime}"
msgstr ""
#: lib/cannery_web/components/invite_card.ex:31
#, elixir-autogen, elixir-format, fuzzy
msgid "Uses Left: %{uses_left}"
msgstr "Utilisations restantes:"
#: lib/cannery_web/components/invite_card.ex:36
#: lib/cannery_web/components/invite_card.ex:37
#, elixir-autogen, elixir-format, fuzzy
msgid "Uses Left: Unlimited"
msgstr "Utilisations restantes:"
@ -1197,3 +1190,13 @@ msgstr ""
#, elixir-autogen, elixir-format
msgid "Enable"
msgstr ""
#: lib/cannery_web/components/invite_card.ex:32
#, elixir-autogen, elixir-format, fuzzy
msgid "Uses Left: %{uses_left_count}"
msgstr "Utilisations restantes:"
#: lib/cannery_web/components/invite_card.ex:52
#, elixir-autogen, elixir-format
msgid "Uses: %{uses_count}"
msgstr ""

View File

@ -69,7 +69,7 @@ msgstr "Mél ou mot de passe invalide"
msgid "Not found"
msgstr "Pas trouvé"
#: lib/cannery_web/templates/user_registration/new.html.heex:14
#: lib/cannery_web/templates/user_registration/new.html.heex:13
#: lib/cannery_web/templates/user_reset_password/edit.html.heex:14
#: lib/cannery_web/templates/user_settings/edit.html.heex:23
#: lib/cannery_web/templates/user_settings/edit.html.heex:67
@ -85,14 +85,15 @@ msgstr ""
msgid "Reset password link is invalid or it has expired."
msgstr "Le lien de réinitialisation de mot de passe est invalide ou expiré."
#: lib/cannery_web/controllers/user_registration_controller.ex:24
#: lib/cannery_web/controllers/user_registration_controller.ex:55
#: lib/cannery_web/controllers/user_registration_controller.ex:22
#: lib/cannery_web/controllers/user_registration_controller.ex:51
#, elixir-autogen, elixir-format
msgid "Sorry, public registration is disabled"
msgstr "Désolé, lenregistrement public est désactivé"
#: lib/cannery_web/controllers/user_registration_controller.ex:14
#: lib/cannery_web/controllers/user_registration_controller.ex:45
#: lib/cannery_web/controllers/user_registration_controller.ex:12
#: lib/cannery_web/controllers/user_registration_controller.ex:41
#: lib/cannery_web/controllers/user_registration_controller.ex:70
#, elixir-autogen, elixir-format
msgid "Sorry, this invite was not found or expired"
msgstr "Désolé, cette invitation nest pas trouvée ou est expirée"
@ -112,7 +113,7 @@ msgstr "Non autorisé·e"
msgid "User confirmation link is invalid or it has expired."
msgstr "Le lien de confirmation dutilisateur·ice est invalide ou a expiré."
#: lib/cannery_web/live/invite_live/index.ex:18
#: lib/cannery_web/live/invite_live/index.ex:19
#, elixir-autogen, elixir-format
msgid "You are not authorized to view this page"
msgstr "Vous nêtes pas autorisé·e à voir cette page"
@ -122,22 +123,22 @@ msgstr "Vous nêtes pas autorisé·e à voir cette page"
msgid "You are not authorized to view this page."
msgstr "Vous nêtes pas autorisé·e à voir cette page."
#: lib/cannery/accounts/user.ex:137
#: lib/cannery/accounts/user.ex:144
#, elixir-autogen, elixir-format
msgid "did not change"
msgstr "est inchangé"
#: lib/cannery/accounts/user.ex:158
#: lib/cannery/accounts/user.ex:165
#, elixir-autogen, elixir-format
msgid "does not match password"
msgstr "le mot de passe ne correspond pas"
#: lib/cannery/accounts/user.ex:195
#: lib/cannery/accounts/user.ex:202
#, elixir-autogen, elixir-format
msgid "is not valid"
msgstr "nest pas valide"
#: lib/cannery/accounts/user.ex:92
#: lib/cannery/accounts/user.ex:99
#, elixir-autogen, elixir-format
msgid "must have the @ sign and no spaces"
msgstr "doit contenir le symbole @ et aucune espace"

View File

@ -33,34 +33,17 @@ msgstr "%{name} créé· avec succès"
#: lib/cannery_web/live/ammo_type_live/index.ex:73
#: lib/cannery_web/live/ammo_type_live/show.ex:55
#: lib/cannery_web/live/invite_live/index.ex:53
#: lib/cannery_web/live/invite_live/index.ex:133
#: lib/cannery_web/live/tag_live/index.ex:64
#, elixir-autogen, elixir-format
msgid "%{name} deleted succesfully"
msgstr "%{name} supprimé· avec succès"
#: lib/cannery_web/live/invite_live/index.ex:109
#, elixir-autogen, elixir-format
msgid "%{name} disabled succesfully"
msgstr "%{name} supprimé·e avec succès"
#: lib/cannery_web/live/invite_live/index.ex:87
#, elixir-autogen, elixir-format
msgid "%{name} enabled succesfully"
msgstr "%{name} activé·e avec succès"
#: lib/cannery_web/live/container_live/index.ex:85
#: lib/cannery_web/live/container_live/show.ex:63
#, elixir-autogen, elixir-format
msgid "%{name} has been deleted"
msgstr "%{name} a été supprimé·e"
#: lib/cannery_web/live/invite_live/index.ex:67
#, elixir-autogen, elixir-format
msgid "%{name} updated succesfully"
msgstr "%{name} mis à jour avec succès"
#: lib/cannery_web/live/ammo_type_live/form_component.ex:67
#: lib/cannery_web/live/container_live/form_component.ex:70
#: lib/cannery_web/live/invite_live/form_component.ex:62
@ -91,11 +74,6 @@ msgstr ""
msgid "Are you sure you want to delete %{name}?"
msgstr "Êtes-vous certain·e de supprimer %{name}?"
#: lib/cannery_web/live/invite_live/index.html.heex:48
#, elixir-autogen, elixir-format
msgid "Are you sure you want to delete the invite for %{name}?"
msgstr "Êtes-vous certain·e de supprimer linvitation pour %{name}?"
#: lib/cannery_web/live/ammo_group_live/index.html.heex:153
#: lib/cannery_web/live/ammo_group_live/show.html.heex:75
#, elixir-autogen, elixir-format
@ -112,11 +90,6 @@ msgstr "Êtes-vous certain·e de supprimer votre compte?"
msgid "Are you sure you want to log out?"
msgstr "Êtes-vous certain·e de vouloir vous déconnecter?"
#: lib/cannery_web/live/invite_live/index.html.heex:73
#, elixir-autogen, elixir-format
msgid "Are you sure you want to make %{name} unlimited?"
msgstr "Êtes-vous certain·e de vouloir rendre %{name} illimité?"
#: lib/cannery_web/controllers/user_settings_controller.ex:77
#, elixir-autogen, elixir-format
msgid "Email changed successfully."
@ -151,7 +124,7 @@ msgstr "Mot de passe réinitialiser avec succès."
msgid "Password updated successfully."
msgstr "Mot de passe mis à jour avec succès."
#: lib/cannery_web/controllers/user_registration_controller.ex:73
#: lib/cannery_web/controllers/user_registration_controller.ex:65
#, elixir-autogen, elixir-format
msgid "Please check your email to verify your account"
msgstr "Veuillez vérifier votre mél pour confirmer votre compte"
@ -231,7 +204,7 @@ msgstr "%{email} confirmé avec succès."
msgid "Ammo moved to %{name} successfully"
msgstr "Munition déplacée à %{name} avec succès"
#: lib/cannery_web/live/invite_live/index.ex:121
#: lib/cannery_web/live/invite_live/index.ex:128
#, elixir-autogen, elixir-format
msgid "Copied to clipboard"
msgstr "Copié dans le presse-papier"
@ -295,3 +268,38 @@ msgstr "Êtes-vous certain·e de supprimer %{name}?"
#, elixir-autogen, elixir-format, fuzzy
msgid "Register to setup Cannery"
msgstr "Senregistrer pour mettre en place %{name}"
#: lib/cannery_web/live/invite_live/index.ex:54
#, elixir-autogen, elixir-format, fuzzy
msgid "%{invite_name} deleted succesfully"
msgstr "%{name} supprimé· avec succès"
#: lib/cannery_web/live/invite_live/index.ex:115
#, elixir-autogen, elixir-format, fuzzy
msgid "%{invite_name} disabled succesfully"
msgstr "%{name} supprimé·e avec succès"
#: lib/cannery_web/live/invite_live/index.ex:91
#, elixir-autogen, elixir-format, fuzzy
msgid "%{invite_name} enabled succesfully"
msgstr "%{name} activé·e avec succès"
#: lib/cannery_web/live/invite_live/index.ex:69
#, elixir-autogen, elixir-format, fuzzy
msgid "%{invite_name} updated succesfully"
msgstr "%{name} mis à jour avec succès"
#: lib/cannery_web/live/invite_live/index.ex:140
#, elixir-autogen, elixir-format, fuzzy
msgid "%{user_email} deleted succesfully"
msgstr "%{name} supprimé· avec succès"
#: lib/cannery_web/live/invite_live/index.html.heex:48
#, elixir-autogen, elixir-format, fuzzy
msgid "Are you sure you want to delete the invite for %{invite_name}?"
msgstr "Êtes-vous certain·e de supprimer linvitation pour %{name}?"
#: lib/cannery_web/live/invite_live/index.html.heex:73
#, elixir-autogen, elixir-format, fuzzy
msgid "Are you sure you want to make %{invite_name} unlimited?"
msgstr "Êtes-vous certain·e de vouloir rendre %{name} illimité?"

View File

@ -65,7 +65,7 @@ msgstr ""
msgid "Delete User"
msgstr ""
#: lib/cannery_web/templates/user_registration/new.html.heex:49
#: lib/cannery_web/templates/user_registration/new.html.heex:47
#: lib/cannery_web/templates/user_reset_password/new.html.heex:3
#: lib/cannery_web/templates/user_session/new.html.heex:44
#, elixir-autogen, elixir-format
@ -79,7 +79,7 @@ msgstr ""
#: lib/cannery_web/components/topbar.ex:135
#: lib/cannery_web/templates/user_confirmation/new.html.heex:31
#: lib/cannery_web/templates/user_registration/new.html.heex:46
#: lib/cannery_web/templates/user_registration/new.html.heex:44
#: lib/cannery_web/templates/user_reset_password/edit.html.heex:47
#: lib/cannery_web/templates/user_reset_password/new.html.heex:31
#: lib/cannery_web/templates/user_session/new.html.heex:3
@ -111,7 +111,7 @@ msgstr ""
#: lib/cannery_web/components/topbar.ex:127
#: lib/cannery_web/templates/user_confirmation/new.html.heex:28
#: lib/cannery_web/templates/user_registration/new.html.heex:3
#: lib/cannery_web/templates/user_registration/new.html.heex:39
#: lib/cannery_web/templates/user_registration/new.html.heex:37
#: lib/cannery_web/templates/user_reset_password/edit.html.heex:44
#: lib/cannery_web/templates/user_reset_password/new.html.heex:28
#: lib/cannery_web/templates/user_session/new.html.heex:41

View File

@ -139,7 +139,7 @@ msgstr ""
msgid "Easy to Use:"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:33
#: lib/cannery_web/live/invite_live/index.ex:34
#, elixir-autogen, elixir-format
msgid "Edit Invite"
msgstr ""
@ -176,7 +176,7 @@ msgstr ""
msgid "Instance Information"
msgstr ""
#: lib/cannery_web/components/invite_card.ex:41
#: lib/cannery_web/components/invite_card.ex:42
#, elixir-autogen, elixir-format
msgid "Invite Disabled"
msgstr ""
@ -187,7 +187,7 @@ msgid "Invite Only"
msgstr ""
#: lib/cannery_web/components/topbar.ex:90
#: lib/cannery_web/live/invite_live/index.ex:41
#: lib/cannery_web/live/invite_live/index.ex:42
#: lib/cannery_web/live/invite_live/index.html.heex:3
#, elixir-autogen, elixir-format
msgid "Invites"
@ -254,7 +254,7 @@ msgstr ""
msgid "New Container"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:37
#: lib/cannery_web/live/invite_live/index.ex:38
#, elixir-autogen, elixir-format
msgid "New Invite"
msgstr ""
@ -678,7 +678,7 @@ msgstr ""
msgid "Log in"
msgstr ""
#: lib/cannery_web/controllers/user_registration_controller.ex:34
#: lib/cannery_web/controllers/user_registration_controller.ex:32
#, elixir-autogen, elixir-format
msgid "Register"
msgstr ""
@ -704,25 +704,23 @@ msgstr ""
msgid "Added on:"
msgstr ""
#: lib/cannery_web/templates/user_registration/new.html.heex:34
#: lib/cannery_web/templates/user_registration/new.html.heex:32
#: lib/cannery_web/templates/user_settings/edit.html.heex:133
#, elixir-autogen, elixir-format
msgid "English"
msgstr ""
#: lib/cannery_web/templates/user_registration/new.html.heex:34
#: lib/cannery_web/templates/user_settings/edit.html.heex:135
#, elixir-autogen, elixir-format
msgid "French"
msgstr ""
#: lib/cannery_web/templates/user_registration/new.html.heex:34
#: lib/cannery_web/templates/user_settings/edit.html.heex:134
#, elixir-autogen, elixir-format
msgid "German"
msgstr ""
#: lib/cannery_web/templates/user_registration/new.html.heex:30
#: lib/cannery_web/templates/user_registration/new.html.heex:28
#, elixir-autogen, elixir-format
msgid "Language"
msgstr ""
@ -1135,12 +1133,7 @@ msgstr ""
msgid "User was confirmed at%{confirmed_datetime}"
msgstr ""
#: lib/cannery_web/components/invite_card.ex:31
#, elixir-autogen, elixir-format, fuzzy
msgid "Uses Left: %{uses_left}"
msgstr ""
#: lib/cannery_web/components/invite_card.ex:36
#: lib/cannery_web/components/invite_card.ex:37
#, elixir-autogen, elixir-format, fuzzy
msgid "Uses Left: Unlimited"
msgstr ""
@ -1188,3 +1181,13 @@ msgstr ""
#, elixir-autogen, elixir-format
msgid "Enable"
msgstr ""
#: lib/cannery_web/components/invite_card.ex:32
#, elixir-autogen, elixir-format, fuzzy
msgid "Uses Left: %{uses_left_count}"
msgstr ""
#: lib/cannery_web/components/invite_card.ex:52
#, elixir-autogen, elixir-format
msgid "Uses: %{uses_count}"
msgstr ""

View File

@ -70,7 +70,7 @@ msgstr "Seoladh email nó pasfhocal neamhbhailí"
msgid "Not found"
msgstr "Ní feidir é a fáil"
#: lib/cannery_web/templates/user_registration/new.html.heex:14
#: lib/cannery_web/templates/user_registration/new.html.heex:13
#: lib/cannery_web/templates/user_reset_password/edit.html.heex:14
#: lib/cannery_web/templates/user_settings/edit.html.heex:23
#: lib/cannery_web/templates/user_settings/edit.html.heex:67
@ -86,14 +86,15 @@ msgstr ""
msgid "Reset password link is invalid or it has expired."
msgstr "Tá nasc an pasfhocail a athrú neamhbailí nó as dáta."
#: lib/cannery_web/controllers/user_registration_controller.ex:24
#: lib/cannery_web/controllers/user_registration_controller.ex:55
#: lib/cannery_web/controllers/user_registration_controller.ex:22
#: lib/cannery_web/controllers/user_registration_controller.ex:51
#, elixir-autogen, elixir-format
msgid "Sorry, public registration is disabled"
msgstr "Tá brón orainn, tá clarú póiblí bactha"
#: lib/cannery_web/controllers/user_registration_controller.ex:14
#: lib/cannery_web/controllers/user_registration_controller.ex:45
#: lib/cannery_web/controllers/user_registration_controller.ex:12
#: lib/cannery_web/controllers/user_registration_controller.ex:41
#: lib/cannery_web/controllers/user_registration_controller.ex:70
#, elixir-autogen, elixir-format
msgid "Sorry, this invite was not found or expired"
msgstr "Tá brón orainn, ní feidir an cuireadh seo a fáil nó tá sé as dáta"
@ -113,7 +114,7 @@ msgstr "Níl cead agaibh"
msgid "User confirmation link is invalid or it has expired."
msgstr "Tá nasc an úsáideoir a deimhnigh neamhbailí nó as dáta."
#: lib/cannery_web/live/invite_live/index.ex:18
#: lib/cannery_web/live/invite_live/index.ex:19
#, elixir-autogen, elixir-format
msgid "You are not authorized to view this page"
msgstr "Níl cead agaibh féachaint ar an leathanach seo"
@ -123,22 +124,22 @@ msgstr "Níl cead agaibh féachaint ar an leathanach seo"
msgid "You are not authorized to view this page."
msgstr "Níl cead agaibh féachaint ar an leathanach seo."
#: lib/cannery/accounts/user.ex:137
#: lib/cannery/accounts/user.ex:144
#, elixir-autogen, elixir-format
msgid "did not change"
msgstr "Níor athraigh sé"
#: lib/cannery/accounts/user.ex:158
#: lib/cannery/accounts/user.ex:165
#, elixir-autogen, elixir-format
msgid "does not match password"
msgstr ""
#: lib/cannery/accounts/user.ex:195
#: lib/cannery/accounts/user.ex:202
#, elixir-autogen, elixir-format
msgid "is not valid"
msgstr ""
#: lib/cannery/accounts/user.ex:92
#: lib/cannery/accounts/user.ex:99
#, elixir-autogen, elixir-format
msgid "must have the @ sign and no spaces"
msgstr ""

View File

@ -31,34 +31,17 @@ msgstr ""
#: lib/cannery_web/live/ammo_type_live/index.ex:73
#: lib/cannery_web/live/ammo_type_live/show.ex:55
#: lib/cannery_web/live/invite_live/index.ex:53
#: lib/cannery_web/live/invite_live/index.ex:133
#: lib/cannery_web/live/tag_live/index.ex:64
#, elixir-autogen, elixir-format
msgid "%{name} deleted succesfully"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:109
#, elixir-autogen, elixir-format
msgid "%{name} disabled succesfully"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:87
#, elixir-autogen, elixir-format
msgid "%{name} enabled succesfully"
msgstr ""
#: lib/cannery_web/live/container_live/index.ex:85
#: lib/cannery_web/live/container_live/show.ex:63
#, elixir-autogen, elixir-format
msgid "%{name} has been deleted"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:67
#, elixir-autogen, elixir-format
msgid "%{name} updated succesfully"
msgstr ""
#: lib/cannery_web/live/ammo_type_live/form_component.ex:67
#: lib/cannery_web/live/container_live/form_component.ex:70
#: lib/cannery_web/live/invite_live/form_component.ex:62
@ -86,11 +69,6 @@ msgstr ""
msgid "Are you sure you want to delete %{name}?"
msgstr ""
#: lib/cannery_web/live/invite_live/index.html.heex:48
#, elixir-autogen, elixir-format
msgid "Are you sure you want to delete the invite for %{name}?"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:153
#: lib/cannery_web/live/ammo_group_live/show.html.heex:75
#, elixir-autogen, elixir-format
@ -107,11 +85,6 @@ msgstr ""
msgid "Are you sure you want to log out?"
msgstr ""
#: lib/cannery_web/live/invite_live/index.html.heex:73
#, elixir-autogen, elixir-format
msgid "Are you sure you want to make %{name} unlimited?"
msgstr ""
#: lib/cannery_web/controllers/user_settings_controller.ex:77
#, elixir-autogen, elixir-format
msgid "Email changed successfully."
@ -142,7 +115,7 @@ msgstr ""
msgid "Password updated successfully."
msgstr ""
#: lib/cannery_web/controllers/user_registration_controller.ex:73
#: lib/cannery_web/controllers/user_registration_controller.ex:65
#, elixir-autogen, elixir-format
msgid "Please check your email to verify your account"
msgstr ""
@ -220,7 +193,7 @@ msgstr ""
msgid "Ammo moved to %{name} successfully"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:121
#: lib/cannery_web/live/invite_live/index.ex:128
#, elixir-autogen, elixir-format
msgid "Copied to clipboard"
msgstr ""
@ -284,3 +257,38 @@ msgstr ""
#, elixir-autogen, elixir-format, fuzzy
msgid "Register to setup Cannery"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:54
#, elixir-autogen, elixir-format, fuzzy
msgid "%{invite_name} deleted succesfully"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:115
#, elixir-autogen, elixir-format, fuzzy
msgid "%{invite_name} disabled succesfully"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:91
#, elixir-autogen, elixir-format, fuzzy
msgid "%{invite_name} enabled succesfully"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:69
#, elixir-autogen, elixir-format, fuzzy
msgid "%{invite_name} updated succesfully"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:140
#, elixir-autogen, elixir-format, fuzzy
msgid "%{user_email} deleted succesfully"
msgstr ""
#: lib/cannery_web/live/invite_live/index.html.heex:48
#, elixir-autogen, elixir-format, fuzzy
msgid "Are you sure you want to delete the invite for %{invite_name}?"
msgstr ""
#: lib/cannery_web/live/invite_live/index.html.heex:73
#, elixir-autogen, elixir-format, fuzzy
msgid "Are you sure you want to make %{invite_name} unlimited?"
msgstr ""

View File

@ -20,34 +20,17 @@ msgstr ""
#: lib/cannery_web/live/ammo_type_live/index.ex:73
#: lib/cannery_web/live/ammo_type_live/show.ex:55
#: lib/cannery_web/live/invite_live/index.ex:53
#: lib/cannery_web/live/invite_live/index.ex:133
#: lib/cannery_web/live/tag_live/index.ex:64
#, elixir-autogen, elixir-format
msgid "%{name} deleted succesfully"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:109
#, elixir-autogen, elixir-format
msgid "%{name} disabled succesfully"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:87
#, elixir-autogen, elixir-format
msgid "%{name} enabled succesfully"
msgstr ""
#: lib/cannery_web/live/container_live/index.ex:85
#: lib/cannery_web/live/container_live/show.ex:63
#, elixir-autogen, elixir-format
msgid "%{name} has been deleted"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:67
#, elixir-autogen, elixir-format
msgid "%{name} updated succesfully"
msgstr ""
#: lib/cannery_web/live/ammo_type_live/form_component.ex:67
#: lib/cannery_web/live/container_live/form_component.ex:70
#: lib/cannery_web/live/invite_live/form_component.ex:62
@ -75,11 +58,6 @@ msgstr ""
msgid "Are you sure you want to delete %{name}?"
msgstr ""
#: lib/cannery_web/live/invite_live/index.html.heex:48
#, elixir-autogen, elixir-format
msgid "Are you sure you want to delete the invite for %{name}?"
msgstr ""
#: lib/cannery_web/live/ammo_group_live/index.html.heex:153
#: lib/cannery_web/live/ammo_group_live/show.html.heex:75
#, elixir-autogen, elixir-format
@ -96,11 +74,6 @@ msgstr ""
msgid "Are you sure you want to log out?"
msgstr ""
#: lib/cannery_web/live/invite_live/index.html.heex:73
#, elixir-autogen, elixir-format
msgid "Are you sure you want to make %{name} unlimited?"
msgstr ""
#: lib/cannery_web/controllers/user_settings_controller.ex:77
#, elixir-autogen, elixir-format
msgid "Email changed successfully."
@ -131,7 +104,7 @@ msgstr ""
msgid "Password updated successfully."
msgstr ""
#: lib/cannery_web/controllers/user_registration_controller.ex:73
#: lib/cannery_web/controllers/user_registration_controller.ex:65
#, elixir-autogen, elixir-format
msgid "Please check your email to verify your account"
msgstr ""
@ -209,7 +182,7 @@ msgstr ""
msgid "Ammo moved to %{name} successfully"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:121
#: lib/cannery_web/live/invite_live/index.ex:128
#, elixir-autogen, elixir-format
msgid "Copied to clipboard"
msgstr ""
@ -273,3 +246,38 @@ msgstr ""
#, elixir-autogen, elixir-format
msgid "Register to setup Cannery"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:54
#, elixir-autogen, elixir-format
msgid "%{invite_name} deleted succesfully"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:115
#, elixir-autogen, elixir-format
msgid "%{invite_name} disabled succesfully"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:91
#, elixir-autogen, elixir-format
msgid "%{invite_name} enabled succesfully"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:69
#, elixir-autogen, elixir-format
msgid "%{invite_name} updated succesfully"
msgstr ""
#: lib/cannery_web/live/invite_live/index.ex:140
#, elixir-autogen, elixir-format
msgid "%{user_email} deleted succesfully"
msgstr ""
#: lib/cannery_web/live/invite_live/index.html.heex:48
#, elixir-autogen, elixir-format
msgid "Are you sure you want to delete the invite for %{invite_name}?"
msgstr ""
#: lib/cannery_web/live/invite_live/index.html.heex:73
#, elixir-autogen, elixir-format
msgid "Are you sure you want to make %{invite_name} unlimited?"
msgstr ""

View File

@ -0,0 +1,11 @@
defmodule Cannery.Repo.Migrations.RecordInvites do
use Ecto.Migration
def change do
alter table(:users) do
add :invite_id, references(:invites, type: :binary_id)
end
rename table(:invites), :user_id, to: :created_by_id
end
end

View File

@ -0,0 +1,176 @@
defmodule Cannery.InvitesTest do
@moduledoc """
This module tests the Cannery.Accounts.Invites context
"""
use Cannery.DataCase
alias Cannery.Accounts
alias Cannery.Accounts.{Invite, Invites}
alias Ecto.Changeset
@moduletag :invites_test
@valid_attrs %{
"name" => "some name"
}
@invalid_attrs %{
"name" => nil,
"token" => nil
}
describe "invites" do
setup do
current_user = admin_fixture()
{:ok, invite} = Invites.create_invite(current_user, @valid_attrs)
[invite: invite, current_user: current_user]
end
test "list_invites/0 returns all invites", %{invite: invite, current_user: current_user} do
assert Invites.list_invites(current_user) == [invite]
end
test "get_invite!/1 returns the invite with given id",
%{invite: invite, current_user: current_user} do
assert Invites.get_invite!(invite.id, current_user) == invite
end
test "valid_invite_token? returns for valid and invalid invite tokens",
%{invite: %{token: token}} do
refute Invites.valid_invite_token?(nil)
refute Invites.valid_invite_token?("")
assert Invites.valid_invite_token?(token)
end
test "valid_invite_token? does not return true for a disabled invite by token",
%{invite: %{token: token} = invite, current_user: current_user} do
assert Invites.valid_invite_token?(token)
{:ok, _invite} = Invites.update_invite(invite, %{uses_left: 1}, current_user)
{:ok, _invite} = Invites.use_invite(token)
refute Invites.valid_invite_token?(token)
end
test "get_use_count/2 returns the correct invite usage",
%{invite: %{token: token} = invite, current_user: current_user} do
assert 0 == Invites.get_use_count(invite, current_user)
assert {:ok, _user} =
Accounts.register_user(
%{"email" => unique_user_email(), "password" => valid_user_password()},
token
)
assert 1 == Invites.get_use_count(invite, current_user)
assert {:ok, _user} =
Accounts.register_user(
%{"email" => unique_user_email(), "password" => valid_user_password()},
token
)
assert 2 == Invites.get_use_count(invite, current_user)
end
test "use_invite/1 successfully uses an unlimited invite",
%{invite: %{token: token} = invite, current_user: current_user} do
{:ok, invite} = Invites.update_invite(invite, %{uses_left: nil}, current_user)
assert {:ok, ^invite} = Invites.use_invite(token)
assert {:ok, ^invite} = Invites.use_invite(token)
assert {:ok, ^invite} = Invites.use_invite(token)
end
test "use_invite/1 successfully decrements an invite",
%{invite: %{token: token} = invite, current_user: current_user} do
{:ok, _invite} = Invites.update_invite(invite, %{uses_left: 10}, current_user)
assert {:ok, %{uses_left: 9}} = Invites.use_invite(token)
assert {:ok, %{uses_left: 8}} = Invites.use_invite(token)
assert {:ok, %{uses_left: 7}} = Invites.use_invite(token)
end
test "use_invite/1 successfully disactivates an invite",
%{invite: %{token: token} = invite, current_user: current_user} do
{:ok, _invite} = Invites.update_invite(invite, %{uses_left: 1}, current_user)
assert {:ok, %{uses_left: 0, disabled_at: disabled_at}} = Invites.use_invite(token)
assert not is_nil(disabled_at)
end
test "use_invite/1 does not work on disactivated invite",
%{invite: %{token: token} = invite, current_user: current_user} do
{:ok, _invite} = Invites.update_invite(invite, %{uses_left: 1}, current_user)
{:ok, _invite} = Invites.use_invite(token)
assert {:error, :invalid_token} = Invites.use_invite(token)
end
test "create_invite/1 with valid data creates an unlimited invite",
%{current_user: current_user} do
assert {:ok, %Invite{} = invite} =
Invites.create_invite(current_user, %{
"name" => "some name"
})
assert invite.name == "some name"
end
test "create_invite/1 with valid data creates a limited invite",
%{current_user: current_user} do
assert {:ok, %Invite{} = invite} =
Invites.create_invite(current_user, %{
"name" => "some name",
"uses_left" => 10
})
assert invite.name == "some name"
assert invite.uses_left == 10
end
test "create_invite/1 with invalid data returns error changeset",
%{current_user: current_user} do
assert {:error, %Changeset{}} = Invites.create_invite(current_user, @invalid_attrs)
end
test "update_invite/2 can set an invite to be limited",
%{invite: invite, current_user: current_user} do
assert {:ok, %Invite{} = new_invite} =
Invites.update_invite(
invite,
%{"name" => "some updated name", "uses_left" => 5},
current_user
)
assert new_invite.name == "some updated name"
assert new_invite.uses_left == 5
end
test "update_invite/2 can set an invite to be unlimited",
%{invite: invite, current_user: current_user} do
{:ok, invite} = Invites.update_invite(invite, %{"uses_left" => 5}, current_user)
assert {:ok, %Invite{} = new_invite} =
Invites.update_invite(
invite,
%{"name" => "some updated name", "uses_left" => nil},
current_user
)
assert new_invite.name == "some updated name"
assert new_invite.uses_left |> is_nil()
end
test "update_invite/2 with invalid data returns error changeset",
%{invite: invite, current_user: current_user} do
assert {:error, %Changeset{}} = Invites.update_invite(invite, @invalid_attrs, current_user)
assert invite == Invites.get_invite!(invite.id, current_user)
end
test "delete_invite/1 deletes the invite", %{invite: invite, current_user: current_user} do
assert {:ok, %Invite{}} = Invites.delete_invite(invite, current_user)
assert_raise Ecto.NoResultsError, fn -> Invites.get_invite!(invite.id, current_user) end
end
test "delete_invite!/1 deletes the invite", %{invite: invite, current_user: current_user} do
assert %Invite{} = Invites.delete_invite!(invite, current_user)
assert_raise Ecto.NoResultsError, fn -> Invites.get_invite!(invite.id, current_user) end
end
end
end

View File

@ -5,7 +5,7 @@ defmodule Cannery.AccountsTest do
use Cannery.DataCase
alias Cannery.Accounts
alias Cannery.Accounts.{User, UserToken}
alias Cannery.Accounts.{Invites, User, UserToken}
alias Ecto.Changeset
@moduletag :accounts_test
@ -102,6 +102,17 @@ defmodule Cannery.AccountsTest do
assert is_nil(user.confirmed_at)
assert is_nil(user.password)
end
test "records used invite during registration" do
{:ok, %{id: invite_id, token: token}} =
admin_fixture() |> Invites.create_invite(%{"name" => "my invite"})
assert {:ok, %{invite_id: ^invite_id}} =
Accounts.register_user(
%{"email" => unique_user_email(), "password" => valid_user_password()},
token
)
end
end
describe "change_user_registration/2" do
@ -305,9 +316,9 @@ defmodule Cannery.AccountsTest do
end
test "deletes all tokens for the given user", %{user: user} do
_token = Accounts.generate_user_session_token(user)
_session_token = Accounts.generate_user_session_token(user)
{:ok, _user} =
{:ok, _} =
Accounts.update_user_password(user, valid_user_password(), %{
"password" => "new valid password"
})
@ -502,7 +513,7 @@ defmodule Cannery.AccountsTest do
end
test "deletes all tokens for the given user", %{user: user} do
_token = Accounts.generate_user_session_token(user)
_session_token = Accounts.generate_user_session_token(user)
{:ok, _user} = Accounts.reset_user_password(user, %{"password" => "new valid password"})
refute Repo.get_by(UserToken, user_id: user.id)
end

View File

@ -1,72 +0,0 @@
defmodule Cannery.InvitesTest do
@moduledoc """
This module tests the Invites context
"""
use Cannery.DataCase
alias Cannery.{Invites, Invites.Invite}
alias Ecto.Changeset
@moduletag :invites_test
@valid_attrs %{
"name" => "some name",
"token" => "some token"
}
@update_attrs %{
"name" => "some updated name",
"token" => "some updated token"
}
@invalid_attrs %{
"name" => nil,
"token" => nil
}
describe "invites" do
setup do
current_user = admin_fixture()
{:ok, invite} = Invites.create_invite(current_user, @valid_attrs)
[invite: invite, current_user: current_user]
end
test "list_invites/0 returns all invites", %{invite: invite, current_user: current_user} do
assert Invites.list_invites(current_user) == [invite]
end
test "get_invite!/1 returns the invite with given id",
%{invite: invite, current_user: current_user} do
assert Invites.get_invite!(invite.id, current_user) == invite
end
test "create_invite/1 with valid data creates a invite",
%{current_user: current_user} do
assert {:ok, %Invite{} = invite} = Invites.create_invite(current_user, @valid_attrs)
assert invite.name == "some name"
end
test "create_invite/1 with invalid data returns error changeset",
%{current_user: current_user} do
assert {:error, %Changeset{}} = Invites.create_invite(current_user, @invalid_attrs)
end
test "update_invite/2 with valid data updates the invite",
%{invite: invite, current_user: current_user} do
assert {:ok, %Invite{} = new_invite} =
Invites.update_invite(invite, @update_attrs, current_user)
assert new_invite.name == "some updated name"
assert new_invite.token == new_invite.token
end
test "update_invite/2 with invalid data returns error changeset",
%{invite: invite, current_user: current_user} do
assert {:error, %Changeset{}} = Invites.update_invite(invite, @invalid_attrs, current_user)
assert invite == Invites.get_invite!(invite.id, current_user)
end
test "delete_invite/1 deletes the invite", %{invite: invite, current_user: current_user} do
assert {:ok, %Invite{}} = Invites.delete_invite(invite, current_user)
assert_raise Ecto.NoResultsError, fn -> Invites.get_invite!(invite.id, current_user) end
end
end
end

View File

@ -8,14 +8,7 @@ defmodule CanneryWeb.ExportControllerTest do
@moduletag :export_controller_test
setup %{conn: conn} do
current_user = user_fixture() |> confirm_user()
[
current_user: current_user,
conn: conn |> log_in_user(current_user)
]
end
setup [:register_and_log_in_user]
defp add_data(%{current_user: current_user}) do
ammo_type = ammo_type_fixture(current_user)
@ -124,7 +117,9 @@ defmodule CanneryWeb.ExportControllerTest do
"email" => current_user.email,
"id" => current_user.id,
"locale" => current_user.locale,
"role" => to_string(current_user.role)
"role" => to_string(current_user.role),
"inserted_at" => current_user.inserted_at |> NaiveDateTime.to_iso8601(),
"updated_at" => current_user.updated_at |> NaiveDateTime.to_iso8601()
}
json_resp = conn |> json_response(200)

View File

@ -6,7 +6,7 @@ defmodule CanneryWeb.InviteLiveTest do
use CanneryWeb.ConnCase
import Phoenix.LiveViewTest
import CanneryWeb.Gettext
alias Cannery.Invites
alias Cannery.Accounts.Invites
@moduletag :invite_live_test
@create_attrs %{"name" => "some name"}
@ -40,13 +40,14 @@ defmodule CanneryWeb.InviteLiveTest do
# |> form("#invite-form", invite: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "can't be blank")
{:ok, _view, html} =
{:ok, _live, html} =
index_live
|> form("#invite-form", invite: @create_attrs)
|> render_submit()
|> follow_redirect(conn, Routes.invite_index_path(conn, :index))
assert html =~ dgettext("prompts", "%{name} created successfully", name: "some name")
assert html =~
dgettext("prompts", "%{invite_name} created successfully", invite_name: "some name")
assert html =~ "some name"
end
@ -63,14 +64,16 @@ defmodule CanneryWeb.InviteLiveTest do
# |> form("#invite-form", invite: @invalid_attrs)
# |> render_change() =~ dgettext("errors", "can't be blank")
{:ok, _view, html} =
{:ok, _live, html} =
index_live
|> form("#invite-form", invite: @update_attrs)
|> render_submit()
|> follow_redirect(conn, Routes.invite_index_path(conn, :index))
assert html =~
dgettext("prompts", "%{name} updated successfully", name: "some updated name")
dgettext("prompts", "%{invite_name} updated successfully",
invite_name: "some updated name"
)
assert html =~ "some updated name"
end

View File

@ -43,7 +43,7 @@ defmodule Cannery.DataCase do
"""
def errors_on(changeset) do
Ecto.Changeset.traverse_errors(changeset, fn {message, opts} ->
Regex.replace(~r"%{(\w+)}", message, fn _content, key ->
Regex.replace(~r"%{(\w+)}", message, fn _capture, key ->
opts |> Keyword.get(String.to_existing_atom(key), key) |> to_string()
end)
end)