forked from shibao/cannery
improve invites, record usage
This commit is contained in:
parent
47dab6490d
commit
2c0a4dd7ca
@ -1,6 +1,7 @@
|
||||
# v0.8.2
|
||||
- Fix bug with public registration
|
||||
- Improve templates
|
||||
- Improve invites, record usage
|
||||
|
||||
# v0.8.1
|
||||
- Update dependencies
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
196
lib/cannery/accounts/invites.ex
Normal file
196
lib/cannery/accounts/invites.ex
Normal 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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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}"}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
)
|
||||
}
|
||||
>
|
||||
|
@ -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"
|
||||
>
|
||||
|
@ -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) %>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 ""
|
||||
|
@ -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"
|
||||
|
@ -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?"
|
||||
|
@ -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 ""
|
||||
|
@ -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
|
||||
|
@ -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 ""
|
||||
|
@ -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 ""
|
||||
|
@ -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 ""
|
||||
|
@ -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 ""
|
||||
|
@ -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
|
||||
|
@ -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 ""
|
||||
|
@ -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"
|
||||
|
@ -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?"
|
||||
|
@ -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
|
||||
|
@ -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 l’invitation"
|
||||
@ -178,7 +178,7 @@ msgstr "Incendiaire"
|
||||
msgid "Instance Information"
|
||||
msgstr "Information de l’instance"
|
||||
|
||||
#: 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 "S’enregistrer"
|
||||
@ -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 ""
|
||||
|
@ -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é, l’enregistrement 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 n’est 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 d’utilisateur·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 "n’est 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"
|
||||
|
@ -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 l’invitation 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 "S’enregistrer 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 l’invitation 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é ?"
|
||||
|
@ -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
|
||||
|
@ -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 ""
|
||||
|
@ -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 ""
|
||||
|
@ -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 ""
|
||||
|
@ -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 ""
|
||||
|
11
priv/repo/migrations/20230204191547_record_invites.exs
Normal file
11
priv/repo/migrations/20230204191547_record_invites.exs
Normal 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
|
176
test/cannery/accounts/invites_test.exs
Normal file
176
test/cannery/accounts/invites_test.exs
Normal 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
|
@ -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
|
||||
|
@ -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
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user