upgrade to phoenix 1.7

This commit is contained in:
2023-04-14 23:34:11 -04:00
parent 1796fb822f
commit 1037f37be2
138 changed files with 2304 additions and 2252 deletions

View File

@ -109,14 +109,12 @@ defmodule CanneryWeb.Components.ContainerTableComponent do
end
@spec get_value_for_key(atom(), Container.t(), extra_data :: map) :: any()
defp get_value_for_key(:name, %{id: id, name: container_name}, _extra_data) do
assigns = %{id: id, container_name: container_name}
defp get_value_for_key(:name, %{name: container_name} = assigns, _extra_data) do
{container_name,
~H"""
<div class="flex flex-wrap justify-center items-center">
<.link navigate={Routes.container_show_path(Endpoint, :show, @id)} class="link">
<%= @container_name %>
<.link navigate={~p"/container/#{@id}"} class="link">
<%= @name %>
</.link>
</div>
"""}

View File

@ -3,11 +3,11 @@ defmodule CanneryWeb.CoreComponents do
Provides core UI components.
"""
use Phoenix.Component
import CanneryWeb.{Gettext, ViewHelpers}
use CanneryWeb, :verified_routes
import CanneryWeb.{Gettext, HTMLHelpers}
alias Cannery.{Accounts, Accounts.Invite, Accounts.User}
alias Cannery.{Ammo, Ammo.Pack}
alias Cannery.{Containers.Container, Containers.Tag}
alias CanneryWeb.{Endpoint, HomeLive}
alias CanneryWeb.Router.Helpers, as: Routes
alias Phoenix.LiveView.{JS, Rendered}
@ -29,13 +29,13 @@ defmodule CanneryWeb.CoreComponents do
## Examples
<.modal return_to={Routes.<%= schema.singular %>_index_path(Endpoint, :index)}>
<.modal return_to={~p"/\#{<%= schema.plural %>}"}>
<.live_component
module={<%= inspect context.web_module %>.<%= inspect Module.concat(schema.web_namespace, schema.alias) %>Live.FormComponent}
id={@<%= schema.singular %>.id || :new}
title={@page_title}
action={@live_action}
return_to={Routes.<%= schema.singular %>_index_path(Endpoint, :index)}
return_to={~p"/\#{<%= schema.singular %>}"}
<%= schema.singular %>: @<%= schema.singular %>
/>
</.modal>

View File

@ -5,7 +5,7 @@
border border-gray-400 rounded-lg shadow-lg hover:shadow-md
transition-all duration-300 ease-in-out"
>
<.link navigate={Routes.container_show_path(Endpoint, :show, @container)} class="link">
<.link navigate={~p"/container/#{@container}"} class="link">
<h1 class="px-4 py-2 rounded-lg title text-xl">
<%= @container.name %>
</h1>

View File

@ -23,7 +23,7 @@
<% end %>
<.qr_code
content={Routes.user_registration_url(Endpoint, :new, invite: @invite.token)}
content={url(CanneryWeb.Endpoint, ~p"/users/register?invite=#{@invite.token}")}
filename={@invite.name}
/>
@ -36,7 +36,7 @@
id={"code-#{@invite.id}"}
class="mx-2 my-1 text-xs px-4 py-2 rounded-lg text-center break-all text-gray-100 bg-primary-800"
phx-no-format
><%= Routes.user_registration_url(Endpoint, :new, invite: @invite.token) %></code>
><%= url(CanneryWeb.Endpoint, ~p"/users/register?invite=#{@invite.token}") %></code>
<%= if @code_actions, do: render_slot(@code_actions) %>
</div>

View File

@ -5,7 +5,7 @@
border border-gray-400 rounded-lg shadow-lg hover:shadow-md
transition-all duration-300 ease-in-out"
>
<.link navigate={Routes.pack_show_path(Endpoint, :show, @pack)} class="mb-2 link">
<.link navigate={~p"/ammo/show/#{@pack}"} class="mb-2 link">
<h1 class="title text-xl title-primary-500">
<%= @pack.type.name %>
</h1>
@ -55,7 +55,7 @@
<span :if={@container} class="rounded-lg title text-lg">
<%= gettext("Container:") %>
<.link navigate={Routes.container_show_path(Endpoint, :show, @container)} class="link">
<.link navigate={~p"/container/#{@container}"} class="link">
<%= @container.name %>
</.link>
</span>

View File

@ -1,12 +1,9 @@
<nav role="navigation" class="mb-8 px-8 py-4 w-full bg-primary-500">
<div class="flex flex-col sm:flex-row justify-between items-center">
<div class="mb-4 sm:mb-0 sm:mr-8 flex flex-row justify-start items-center space-x-2">
<.link
navigate={Routes.live_path(Endpoint, HomeLive)}
class="inline mx-2 my-1 leading-5 text-xl text-white"
>
<.link navigate={~p"/"} class="inline mx-2 my-1 leading-5 text-xl text-white">
<img
src={Routes.static_path(Endpoint, "/images/cannery.svg")}
src={~p"/images/cannery.svg"}
alt={gettext("Cannery logo")}
class="inline-block h-8 mx-1"
/>
@ -27,64 +24,43 @@
text-lg text-white text-ellipsis">
<%= if @current_user do %>
<li class="mx-2 my-1">
<.link
navigate={Routes.tag_index_path(Endpoint, :index)}
class="text-white hover:underline"
>
<.link navigate={~p"/tags"} class="text-white hover:underline">
<%= gettext("Tags") %>
</.link>
</li>
<li class="mx-2 my-1">
<.link
navigate={Routes.container_index_path(Endpoint, :index)}
class="text-white hover:underline"
>
<.link navigate={~p"/containers"} class="text-white hover:underline">
<%= gettext("Containers") %>
</.link>
</li>
<li class="mx-2 my-1">
<.link
navigate={Routes.type_index_path(Endpoint, :index)}
class="text-white hover:underline"
>
<.link navigate={~p"/catalog"} class="text-white hover:underline">
<%= gettext("Catalog") %>
</.link>
</li>
<li class="mx-2 my-1">
<.link
navigate={Routes.pack_index_path(Endpoint, :index)}
class="text-white hover:underline"
>
<.link navigate={~p"/ammo"} class="text-white hover:underline">
<%= gettext("Ammo") %>
</.link>
</li>
<li class="mx-2 my-1">
<.link
navigate={Routes.range_index_path(Endpoint, :index)}
class="text-white hover:underline"
>
<.link navigate={~p"/range"} class="text-white hover:underline">
<%= gettext("Range") %>
</.link>
</li>
<li :if={@current_user |> Accounts.is_already_admin?()} class="mx-2 my-1">
<.link
navigate={Routes.invite_index_path(Endpoint, :index)}
class="text-white hover:underline"
>
<.link navigate={~p"/invites"} class="text-white hover:underline">
<%= gettext("Invites") %>
</.link>
</li>
<li class="mx-2 my-1">
<.link
href={Routes.user_settings_path(Endpoint, :edit)}
class="text-white hover:underline truncate"
>
<.link href={~p"/users/settings"} class="text-white hover:underline truncate">
<%= @current_user.email %>
</.link>
</li>
<li class="mx-2 my-1">
<.link
href={Routes.user_session_path(Endpoint, :delete)}
href={~p"/users/log_out"}
method="delete"
data-confirm={dgettext("prompts", "Are you sure you want to log out?")}
aria-label={gettext("Log out")}
@ -100,7 +76,7 @@
class="mx-2 my-1"
>
<.link
navigate={Routes.live_dashboard_path(Endpoint, :home)}
navigate={~p"/dashboard"}
class="text-white hover:underline"
aria-label={gettext("Live Dashboard")}
>
@ -109,18 +85,12 @@
</li>
<% else %>
<li :if={Accounts.allow_registration?()} class="mx-2 my-1">
<.link
href={Routes.user_registration_path(Endpoint, :new)}
class="text-white hover:underline truncate"
>
<.link href={~p"/users/register"} class="text-white hover:underline truncate">
<%= dgettext("actions", "Register") %>
</.link>
</li>
<li class="mx-2 my-1">
<.link
href={Routes.user_session_path(Endpoint, :new)}
class="text-white hover:underline truncate"
>
<.link href={~p"/users/log_in"} class="text-white hover:underline truncate">
<%= dgettext("actions", "Log in") %>
</.link>
</li>

View File

@ -0,0 +1,10 @@
defmodule CanneryWeb.EmailHTML do
@moduledoc """
Renders email templates
"""
use CanneryWeb, :html
embed_templates "email_html/*.html", suffix: "_html"
embed_templates "email_html/*.txt", suffix: "_text"
end

View File

@ -0,0 +1,23 @@
<div style="display: flex; flex-direction: column; justify-content: center; align-items: center;">
<span style="margin-bottom: 0.75em; font-size: 1.5em;">
<%= dgettext("emails", "Hi %{email},", email: @user.email) %>
</span>
<br />
<span style="margin-bottom: 1em; font-size: 1.25em;">
<%= dgettext("emails", "Welcome to Cannery") %>
</span>
<br />
<%= dgettext("emails", "You can confirm your account by visiting the URL below:") %>
<br />
<a style="margin: 1em; color: rgb(31, 31, 31);" href={@url}><%= @url %></a>
<br />
<%= dgettext("emails", "If you didn't create an account at Cannery, please ignore this.") %>
</div>

View File

@ -0,0 +1,12 @@
<%= dgettext("emails", "Hi %{email},", email: @user.email) %>
<%= dgettext("emails", "Welcome to Cannery") %>
<%= dgettext("emails", "You can confirm your account by visiting the URL below:") %>
<%= @url %>
<%= dgettext("emails",
"If you didn't create an account at %{url}, please ignore this.",
url: ~p"/") %>

View File

@ -0,0 +1,17 @@
<div style="display: flex; flex-direction: column; justify-content: center; align-items: center;">
<span style="margin-bottom: 0.5em; font-size: 1.5em;">
<%= dgettext("emails", "Hi %{email},", email: @user.email) %>
</span>
<br />
<%= dgettext("emails", "You can reset your password by visiting the URL below:") %>
<br />
<a style="margin: 1em; color: rgb(31, 31, 31);" href={@url}><%= @url %></a>
<br />
<%= dgettext("emails", "If you didn't request this change from Cannery, please ignore this.") %>
</div>

View File

@ -0,0 +1,10 @@
<%= dgettext("emails", "Hi %{email},", email: @user.email) %>
<%= dgettext("emails", "You can reset your password by visiting the URL below:") %>
<%= @url %>
<%= dgettext("emails",
"If you didn't request this change from %{url}, please ignore this.",
url: ~p"/") %>

View File

@ -0,0 +1,20 @@
<div style="display: flex; flex-direction: column; justify-content: center; align-items: center;">
<span style="margin-bottom: 0.5em; font-size: 1.5em;">
<%= dgettext("emails", "Hi %{email},", email: @user.email) %>
</span>
<br />
<%= dgettext("emails", "You can change your email by visiting the URL below:") %>
<br />
<a style="margin: 1em; color: rgb(31, 31, 31);" href={@url}><%= @url %></a>
<br />
<%= dgettext(
"emails",
"If you didn't request this change from Cannery, please ignore this."
) %>
</div>

View File

@ -0,0 +1,10 @@
<%= dgettext("emails", "Hi %{email},", email: @user.email) %>
<%= dgettext("emails", "You can change your email by visiting the URL below:") %>
<%= @url %>
<%= dgettext("emails",
"If you didn't request this change from %{url}, please ignore this.",
url: ~p"/") %>

View File

@ -0,0 +1,17 @@
defmodule CanneryWeb.Layouts do
@moduledoc """
The root layouts for the entire application
"""
use CanneryWeb, :html
embed_templates "layouts/*"
def get_title(%{assigns: %{title: title}}) when title not in [nil, ""] do
gettext("Cannery | %{title}", title: title)
end
def get_title(_conn) do
gettext("Cannery")
end
end

View File

@ -0,0 +1,18 @@
<main role="main" class="min-h-full min-w-full">
<header>
<.topbar current_user={assigns[:current_user]} />
<div class="mx-8 my-2 flex flex-col space-y-4 text-center">
<p :if={@flash["info"]} class="alert alert-info" role="alert">
<%= @flash["info"] %>
</p>
<p :if={@flash["error"]} class="alert alert-danger" role="alert">
<%= @flash["error"] %>
</p>
</div>
</header>
<div class="mx-4 sm:mx-8 md:mx-16">
<%= @inner_content %>
</div>
</main>

View File

@ -0,0 +1,19 @@
<html>
<head>
<title>
<%= @email.subject %>
</title>
</head>
<body style="padding: 2em; color: rgb(31, 31, 31); background-color: rgb(220, 220, 228); font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif; text-align: center;">
<%= @inner_content %>
<hr style="margin: 2em auto; border-width: 1px; border-color: rgb(212, 212, 216); width: 100%; max-width: 42rem;" />
<a style="color: rgb(31, 31, 31);" href={~p"/"}>
<%= dgettext(
"emails",
"This email was sent from Cannery, the self-hosted firearm tracker website."
) %>
</a>
</body>
</html>

View File

@ -0,0 +1,11 @@
<%= @email.subject %>
====================
<%= @inner_content %>
=====================
<%= dgettext("emails",
"This email was sent from Cannery at %{url}, the self-hosted firearm tracker website.",
url: ~p"/") %>

View File

@ -0,0 +1,45 @@
<main class="pb-8 min-w-full">
<header>
<.topbar current_user={assigns[:current_user]} />
<div class="mx-8 my-2 flex flex-col space-y-4 text-center">
<p
:if={@flash && @flash |> Map.has_key?("info")}
class="alert alert-info"
role="alert"
phx-click="lv:clear-flash"
phx-value-key="info"
>
<%= live_flash(@flash, "info") %>
</p>
<p
:if={@flash && @flash |> Map.has_key?("error")}
class="alert alert-danger"
role="alert"
phx-click="lv:clear-flash"
phx-value-key="error"
>
<%= live_flash(@flash, "error") %>
</p>
</div>
</header>
<div class="mx-4 sm:mx-8 md:mx-16 flex flex-col justify-center items-stretch">
<%= @inner_content %>
</div>
</main>
<div
id="disconnect"
class="z-50 fixed opacity-0 bottom-12 right-12 px-8 py-4 w-max h-max
border border-primary-200 shadow-lg rounded-lg bg-white
flex justify-center items-center space-x-4
transition-opacity ease-in-out duration-500 delay-[2000ms]"
>
<i class="fas fa-fade text-md fa-satellite-dish"></i>
<h1 class="title text-md title-primary-500">
<%= gettext("Reconnecting...") %>
</h1>
</div>

View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en" class="m-0 p-0 w-full h-full bg-white">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<%= csrf_meta_tag() %>
<link rel="shortcut icon" type="image/jpg" href={~p"/images/cannery.svg"} />
<.live_title suffix={" | #{gettext("Cannery")}"}>
<%= assigns[:page_title] || gettext("Cannery") %>
</.live_title>
<link phx-track-static rel="stylesheet" href={~p"/css/app.css"} />
<script defer phx-track-static type="text/javascript" src={~p"/js/app.js"}>
</script>
</head>
<body class="m-0 p-0 w-full h-full subpixel-antialiased">
<%= @inner_content %>
</body>
</html>

View File

@ -5,7 +5,6 @@ defmodule CanneryWeb.Components.MovePackComponent do
use CanneryWeb, :live_component
alias Cannery.{Accounts.User, Ammo, Ammo.Pack, Containers, Containers.Container}
alias CanneryWeb.Endpoint
alias Ecto.Changeset
alias Phoenix.LiveView.Socket
@ -84,7 +83,7 @@ defmodule CanneryWeb.Components.MovePackComponent do
<%= display_emoji("😔") %>
</h2>
<.link navigate={Routes.container_index_path(Endpoint, :new)} class="btn btn-primary">
<.link navigate={~p"/containers/new"} class="btn btn-primary">
<%= dgettext("actions", "Add another container!") %>
</.link>
<% else %>

View File

@ -98,7 +98,7 @@ defmodule CanneryWeb.Components.ShotRecordTableComponent do
{pack.type.name,
~H"""
<.link navigate={Routes.pack_show_path(Endpoint, :show, @pack)} class="link">
<.link navigate={~p"/ammo/show/#{@pack}"} class="link">
<%= @pack.type.name %>
</.link>
"""}

View File

@ -261,13 +261,11 @@ defmodule CanneryWeb.Components.TypeTableComponent do
end
end
defp get_type_value(:name, _key, %{name: type_name} = type, _other_data) do
assigns = %{type: type}
defp get_type_value(:name, _key, %{name: type_name} = assigns, _other_data) do
{type_name,
~H"""
<.link navigate={Routes.type_show_path(Endpoint, :show, @type)} class="link">
<%= @type.name %>
<.link navigate={~p"/type/#{@id}"} class="link">
<%= @name %>
</.link>
"""}
end