progress on migrating to heex templates and font-icons
This commit is contained in:
parent
d43daafdb7
commit
3eff955672
21793 changed files with 2161968 additions and 16895 deletions
lib/shift73k_web
endpoint.ex
live
templates
layout
user_confirmation
user_reset_password
user_session
user_shifts_csv
user_shifts_ics
views
|
@ -10,12 +10,11 @@ defmodule Shift73kWeb.Endpoint do
|
|||
signing_salt: "9CKxo0VJ"
|
||||
]
|
||||
|
||||
socket("/socket", Shift73kWeb.UserSocket,
|
||||
socket "/socket", Shift73kWeb.UserSocket,
|
||||
websocket: true,
|
||||
longpoll: false
|
||||
)
|
||||
|
||||
socket("/live", Phoenix.LiveView.Socket, websocket: [connect_info: [session: @session_options]])
|
||||
socket "/live", Phoenix.LiveView.Socket, websocket: [connect_info: [session: @session_options]]
|
||||
|
||||
# Serve at "/" the static files from "priv/static" directory.
|
||||
#
|
||||
|
@ -23,33 +22,54 @@ defmodule Shift73kWeb.Endpoint do
|
|||
# when deploying your static files in production.
|
||||
#
|
||||
# file list generated by simple ls -1 assets/static/ - then copy/paste here
|
||||
plug(Plug.Static,
|
||||
plug Plug.Static,
|
||||
at: "/",
|
||||
from: :shift73k,
|
||||
gzip: (Mix.env() not in [:dev, :test]),
|
||||
only: "priv/static" |> Path.expand() |> File.ls!()
|
||||
)
|
||||
only: ~w(assets
|
||||
android-chrome-192x192.png
|
||||
android-chrome-512x512.png
|
||||
apple-touch-icon.png
|
||||
browserconfig.xml
|
||||
favicon-16x16.png
|
||||
favicon-32x32.png
|
||||
favicon.ico
|
||||
mstile-144x144.png
|
||||
mstile-150x150.png
|
||||
mstile-310x150.png
|
||||
mstile-310x310.png
|
||||
mstile-70x70.png
|
||||
robots.txt
|
||||
safari-pinned-tab.svg
|
||||
site.webmanifest)
|
||||
|
||||
# For using vite.js in dev, we need to instruct Phoenix to serve files at assets/src over the usual endpoint. This is only necessary in development.
|
||||
if Mix.env() == :dev do
|
||||
plug Plug.Static,
|
||||
at: "/",
|
||||
from: "assets",
|
||||
gzip: false
|
||||
end
|
||||
|
||||
# Code reloading can be explicitly enabled under the
|
||||
# :code_reloader configuration of your endpoint.
|
||||
if code_reloading? do
|
||||
socket("/phoenix/live_reload/socket", Phoenix.LiveReloader.Socket)
|
||||
plug(Phoenix.LiveReloader)
|
||||
plug(Phoenix.CodeReloader)
|
||||
plug(Phoenix.Ecto.CheckRepoStatus, otp_app: :shift73k)
|
||||
socket "/phoenix/live_reload/socket", Phoenix.LiveReloader.Socket
|
||||
plug Phoenix.LiveReloader
|
||||
plug Phoenix.CodeReloader
|
||||
plug Phoenix.Ecto.CheckRepoStatus, otp_app: :shift73k
|
||||
end
|
||||
|
||||
plug(Plug.RequestId)
|
||||
plug(Plug.Telemetry, event_prefix: [:phoenix, :endpoint])
|
||||
plug Plug.RequestId
|
||||
plug Plug.Telemetry, event_prefix: [:phoenix, :endpoint]
|
||||
|
||||
plug(Plug.Parsers,
|
||||
plug Plug.Parsers,
|
||||
parsers: [:urlencoded, :multipart, :json],
|
||||
pass: ["*/*"],
|
||||
json_decoder: Phoenix.json_library()
|
||||
)
|
||||
|
||||
plug(Plug.MethodOverride)
|
||||
plug(Plug.Head)
|
||||
plug(Plug.Session, @session_options)
|
||||
plug(Shift73kWeb.Router)
|
||||
plug Plug.MethodOverride
|
||||
plug Plug.Head
|
||||
plug Plug.Session, @session_options
|
||||
plug Shift73kWeb.Router
|
||||
end
|
||||
|
|
|
@ -9,8 +9,7 @@
|
|||
|
||||
|
||||
<h2 class="mb-3 mb-sm-0">
|
||||
<%= icon_div @socket, "bi-calendar2-plus", [class: "icon baseline"] %>
|
||||
Schedule Shifts
|
||||
<i class="bi bi-calendar2-plus me-1"></i> Schedule Shifts
|
||||
</h2>
|
||||
|
||||
<div class="row justify-content-center mt-4">
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
<div class="row justify-content-center">
|
||||
<div class="col-11 col-sm-8 col-md-6 col-lg-5 col-xl-4 col-xxl-3">
|
||||
|
||||
<h2><%= icon_div @socket, "bi-person-plus", [class: "icon baseline"] %>
|
||||
Register</h2>
|
||||
<h2>
|
||||
<i class="bi bi-journal-plus"></i> Register
|
||||
</h2>
|
||||
<p class="lead">Create an account to manage your work shifts with us.</p>
|
||||
|
||||
<%= form_for @changeset, "#", [phx_change: :validate, phx_submit: :save, novalidate: true, id: "reg_form"], fn f -> %>
|
||||
|
||||
<%= label f, :email, class: "form-label" %>
|
||||
<div class="inner-addon left-addon mb-3" phx-feedback-for="<%= input_id(f, :email) %>">
|
||||
<%= icon_div @socket, "bi-at", [class: "icon is-left text-muted fs-5"] %>
|
||||
<div class="inner-addon left-addon mb-3" phx-feedback-for={input_id(f, :email)}>
|
||||
<i class="bi bi-at icon is-left text-muted fs-5"></i>
|
||||
<%= email_input f, :email,
|
||||
value: input_value(f, :email),
|
||||
class: input_class(f, :email, "form-control"),
|
||||
|
@ -23,8 +24,8 @@
|
|||
</div>
|
||||
|
||||
<%= label f, :password, class: "form-label" %>
|
||||
<div class="inner-addon left-addon mb-3" phx-feedback-for="<%= input_id(f, :password) %>">
|
||||
<%= icon_div @socket, "bi-key", [class: "icon is-left text-muted fs-5"] %>
|
||||
<div class="inner-addon left-addon mb-3" phx-feedback-for={input_id(f, :password)}>
|
||||
<i class="bi bi-key icon is-left text-muted fs-5"></i>
|
||||
<%= password_input f, :password,
|
||||
value: input_value(f, :password),
|
||||
class: input_class(f, :password, "form-control"),
|
|
@ -17,8 +17,7 @@
|
|||
|
||||
|
||||
<h2 class="mb-3">
|
||||
<%= icon_div @socket, "bi-people", [class: "icon baseline"] %>
|
||||
Listing Users
|
||||
<i class="bi bi-people"></i> Listing Users
|
||||
</h2>
|
||||
|
||||
<%# filtering and new item creation %>
|
||||
|
@ -27,8 +26,7 @@
|
|||
<div class="col-12 col-md-6 col-lg-4 col-xl-3">
|
||||
<%= live_patch to: Routes.user_management_index_path(@socket, :new, Enum.into(@query, [])),
|
||||
class: "btn btn-primary mb-3 mb-md-0" do %>
|
||||
<%= icon_div @socket, "bi-person-plus", [class: "icon baseline me-1"] %>
|
||||
New User
|
||||
<i class="bi bi-person-plus"></i> New User
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
|
@ -49,7 +47,7 @@
|
|||
<%= form_for :filter, "#", [phx_change: "filter-change"], fn flt -> %>
|
||||
<%= label flt, :filter, class: "visually-hidden" %>
|
||||
<div class="inner-addon left-addon right-addon">
|
||||
<%= icon_div @socket, "bi-funnel", [class: "icon is-left text-muted fs-5"] %>
|
||||
<i class="bi bi-funnel is-left text-muted fs-5"></i>
|
||||
<%= if @query.filter != "" do %>
|
||||
<%= icon_div @socket, "bi-x-circle-fill", [class: "icon is-right text-primary fs-5"], [role: "img", aria_hidden: false, aria_label: "Clear filter", class: "cursor-pointer pe-auto", phx_click: "filter-clear"] %>
|
||||
<% end %>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
<h1 class="fs-4 my-0 py-0 lh-base">
|
||||
<%= link to: "/", class: "navbar-brand fs-4" do %>
|
||||
<%= icon_div @conn, "bi-calendar2-week", [class: "icon baseline me-1"] %>
|
||||
<i class="bi bi-calendar2-week me-1"></i>
|
||||
<span class="fw-light">Shift73k</span>
|
||||
<% end %>
|
||||
</h1>
|
||||
|
@ -16,8 +16,7 @@
|
|||
</button>
|
||||
<% else %>
|
||||
<%= link nav_link_opts(@conn, to: Routes.user_session_path(@conn, :new), class: "btn btn-outline-light d-block d-lg-none") do %>
|
||||
<%= icon_div @conn, "bi-door-open", [class: "icon baseline"] %>
|
||||
Log in
|
||||
<i class="bi bi-door-open me-1"></i> Log in
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
|
@ -75,8 +74,7 @@
|
|||
<% else %>
|
||||
|
||||
<%= link nav_link_opts(@conn, to: Routes.user_session_path(@conn, :new), class: "btn btn-outline-light d-none d-lg-block") do %>
|
||||
<%= icon_div @conn, "bi-door-open", [class: "icon baseline"] %>
|
||||
Log in
|
||||
<i class="bi bi-door-open me-1"></i> Log in
|
||||
<% end %>
|
||||
|
||||
<% end %>
|
10
lib/shift73k_web/templates/layout/_preamble.html.heex
Normal file
10
lib/shift73k_web/templates/layout/_preamble.html.heex
Normal file
|
@ -0,0 +1,10 @@
|
|||
<%= if dev_env?() do %>
|
||||
<script type="module" src="http://localhost:3000/@vite/client"></script>
|
||||
<script type="module" src="http://localhost:3000/js/app.js"></script>
|
||||
<% else %>
|
||||
<link rel="preload" href={Routes.static_path(@conn, "/assets/lato-latin-300-normal.woff2")} as="font" type="font/woff2" crossorigin="anonymous">
|
||||
<link rel="preload" href={Routes.static_path(@conn, "/assets/lato-latin-400-normal.woff2")} as="font" type="font/woff2" crossorigin="anonymous">
|
||||
<link rel="preload" href={Routes.static_path(@conn, "/assets/lato-latin-700-normal.woff2")} as="font" type="font/woff2" crossorigin="anonymous">
|
||||
<link phx-track-static rel="stylesheet" href={Routes.static_path(@conn, "/assets/app.css")}/>
|
||||
<script defer phx-track-static type="text/javascript" src={Routes.static_path(@conn, "/assets/app.js")}></script>
|
||||
<% end %>
|
|
@ -5,7 +5,7 @@
|
|||
<div class="col-md-12 col-lg-10 col-xxl-8 ">
|
||||
<%= for {kind, class} <- alert_kinds() do %>
|
||||
<%= if flash_content = get_flash(@conn, kind) do %>
|
||||
<div class="alert <%= class %> alert-dismissible fade show" role="alert">
|
||||
<div class={"alert #{class} alert-dismissible fade show"} role="alert">
|
||||
<%= flash_content %>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
|
@ -5,7 +5,7 @@
|
|||
<div class="col-md-12 col-lg-10 col-xxl-8 ">
|
||||
<%= for {kind, class} <- alert_kinds() do %>
|
||||
<%= if flash_content = live_flash(@flash, kind) do %>
|
||||
<div class="alert <%= class %> alert-dismissible fade show" role="alert" id="lv-alert-<%= kind %>" phx-hook="AlertRemover" data-key="<%= kind %>">
|
||||
<div class={"alert #{class} alert-dismissible fade show"} role="alert" id={"lv-alert-#{kind}"} phx-hook="AlertRemover" data-key={"#{kind}"}>
|
||||
<%= flash_content %>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
|
@ -1,28 +1,24 @@
|
|||
<li class="nav-item dropdown">
|
||||
|
||||
<a href="#" class="nav-link dropdown-toggle" id="navbarDropdownUserMenu" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<%= icon_div @conn, "bi-calendar2", [class: "icon baseline me-1"] %>
|
||||
Shifts
|
||||
<i class="bi bi-calendar2 me-1"></i> Shifts
|
||||
</a>
|
||||
|
||||
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdownUserMenu">
|
||||
|
||||
<li>
|
||||
<%= link nav_link_opts(@conn, to: Routes.shift_assign_index_path(@conn, :index), class: "dropdown-item") do %>
|
||||
<%= icon_div @conn, "bi-calendar2-plus", [class: "icon baseline me-1"] %>
|
||||
Schedule Shifts
|
||||
<i class="bi bi-calendar2-plus me-1"></i> Schedule Shifts
|
||||
<% end %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link nav_link_opts(@conn, to: Routes.shift_index_path(@conn, :index), class: "dropdown-item") do %>
|
||||
<%= icon_div @conn, "bi-card-list", [class: "icon baseline me-1"] %>
|
||||
My Scheduled Shifts
|
||||
<i class="bi bi-card-list me-1"></i> My Scheduled Shifts
|
||||
<% end %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link nav_link_opts(@conn, to: Routes.shift_template_index_path(@conn, :index), class: "dropdown-item") do %>
|
||||
<%= icon_div @conn, "bi-clock-history", [class: "icon baseline me-1"] %>
|
||||
My Shift Templates
|
||||
<i class="bi bi-clock-history me-1"></i> My Shift Templates
|
||||
<% end %>
|
||||
</li>
|
||||
|
||||
|
@ -30,14 +26,12 @@
|
|||
<%# user_shifts_csv_path %>
|
||||
<li>
|
||||
<%= link nav_link_opts(@conn, to: Routes.user_shifts_csv_path(@conn, :new), class: "dropdown-item") do %>
|
||||
<%= icon_div @conn, "bi-file-earmark-spreadsheet", [class: "icon baseline me-1"] %>
|
||||
CSV Export
|
||||
<i class="bi bi-file-earmark-spreadsheet me-1"></i> CSV Export
|
||||
<% end %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link nav_link_opts(@conn, to: Routes.shift_import_index_path(@conn, :index), class: "dropdown-item") do %>
|
||||
<%= icon_div @conn, "bi-box-arrow-in-left", [class: "icon baseline me-1"] %>
|
||||
iCal Import
|
||||
<i class="bi bi-box-arrow-in-left me-1"></i> iCal Import
|
||||
<% end %>
|
||||
</li>
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
<li class="nav-item dropdown">
|
||||
|
||||
<a href="#" class="nav-link dropdown-toggle" id="navbarDropdownUserMenu" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<%= icon_div @conn, "bi-person-circle", [class: "icon baseline me-1"] %>
|
||||
<%= @current_user && "Hello!" || "Hello?" %>
|
||||
<i class="bi bi-person-circle me-1"></i> <%= @current_user && "Hello!" || "Hello?" %>
|
||||
</a>
|
||||
|
||||
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdownUserMenu">
|
||||
|
@ -12,22 +11,19 @@
|
|||
<%= if Roles.can?(@current_user, %User{}, :index) do %>
|
||||
<li>
|
||||
<%= link nav_link_opts(@conn, to: Routes.user_management_index_path(@conn, :index), class: "dropdown-item") do %>
|
||||
<%= icon_div @conn, "bi-people", [class: "icon baseline me-1"] %>
|
||||
Users
|
||||
<i class="bi bi-people me-1"></i> Users
|
||||
<% end %>
|
||||
</li>
|
||||
<li><hr class="dropdown-divider"></li>
|
||||
<% end %>
|
||||
<li>
|
||||
<%= link nav_link_opts(@conn, to: Routes.user_settings_path(@conn, :edit), class: "dropdown-item") do %>
|
||||
<%= icon_div @conn, "bi-sliders", [class: "icon baseline me-1"] %>
|
||||
Settings
|
||||
<i class="bi bi-sliders me-1"></i> Settings
|
||||
<% end %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link nav_link_opts(@conn, to: Routes.user_session_path(@conn, :delete), method: :delete, class: "dropdown-item") do %>
|
||||
<%= icon_div @conn, "bi-door-closed", [class: "icon baseline me-1"] %>
|
||||
Log out
|
||||
<i class="bi bi-door-closed me-1"></i> Log out
|
||||
<% end %>
|
||||
</li>
|
||||
|
28
lib/shift73k_web/templates/layout/root.html.heex
Normal file
28
lib/shift73k_web/templates/layout/root.html.heex
Normal file
|
@ -0,0 +1,28 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<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() %>
|
||||
<%= live_title_tag assigns[:page_title] || "", suffix: assigns[:page_title] && " · Shift73k" || "Shift73k" %>
|
||||
<%= render "_preamble.html", assigns %>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href={Routes.static_path(@conn, "/apple-touch-icon.png")}>
|
||||
<link rel="icon" type="image/png" sizes="32x32" href={Routes.static_path(@conn, "/favicon-32x32.png")}>
|
||||
<link rel="icon" type="image/png" sizes="16x16" href={Routes.static_path(@conn, "/favicon-16x16.png")}>
|
||||
<link rel="manifest" href={Routes.static_path(@conn, "/site.webmanifest")}>
|
||||
<link rel="mask-icon" href={Routes.static_path(@conn, "/safari-pinned-tab.svg")} color="#78868a">
|
||||
<meta name="apple-mobile-web-app-title" content="Shift73k">
|
||||
<meta name="application-name" content="Shift73k">
|
||||
<meta name="msapplication-TileColor" content="#ee6c4d">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
<link rel="icon" href="favicon.ico">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<%= render "_navbar.html", assigns %>
|
||||
|
||||
<%= @inner_content %>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,32 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<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() %>
|
||||
<%= live_title_tag assigns[:page_title] || "", suffix: assigns[:page_title] && " · Shift73k" || "Shift73k" %>
|
||||
<link rel="preload" href="<%= Routes.static_path(@conn, "/fonts/lato-latin-300-normal.woff2") %>" as="font" type="font/woff2" crossorigin="anonymous">
|
||||
<link rel="preload" href="<%= Routes.static_path(@conn, "/fonts/lato-latin-400-normal.woff2") %>" as="font" type="font/woff2" crossorigin="anonymous">
|
||||
<link rel="preload" href="<%= Routes.static_path(@conn, "/fonts/lato-latin-700-normal.woff2") %>" as="font" type="font/woff2" crossorigin="anonymous">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="<%= Routes.static_path(@conn, "/apple-touch-icon.png") %>">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="<%= Routes.static_path(@conn, "/favicon-32x32.png") %>">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="<%= Routes.static_path(@conn, "/favicon-16x16.png") %>">
|
||||
<link rel="manifest" href="<%= Routes.static_path(@conn, "/site.webmanifest") %>">
|
||||
<link rel="mask-icon" href="<%= Routes.static_path(@conn, "/safari-pinned-tab.svg") %>" color="#78868a">
|
||||
<meta name="apple-mobile-web-app-title" content="Shift73k">
|
||||
<meta name="application-name" content="Shift73k">
|
||||
<meta name="msapplication-TileColor" content="#ee6c4d">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
<link rel="icon" href="favicon.ico">
|
||||
<link phx-track-static rel="stylesheet" href="<%= Routes.static_path(@conn, "/css/app.css") %>"/>
|
||||
<script defer phx-track-static type="text/javascript" src="<%= Routes.static_path(@conn, "/js/app.js") %>"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<%= render "_navbar.html", assigns %>
|
||||
|
||||
<%= @inner_content %>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -2,8 +2,7 @@
|
|||
<div class="col-11 col-sm-10 col-md-8 col-lg-7 col-xl-6 col-xxl-5">
|
||||
|
||||
<h2>
|
||||
<%= icon_div @conn, "bi-arrow-repeat", [class: "icon baseline"] %>
|
||||
Resend confirmation instructions
|
||||
<i class="bi bi-arrow-repeat"></i> Resend confirmation instructions
|
||||
</h2>
|
||||
<p class="lead">We'll send you another email with instructions to confirm your email address.</p>
|
||||
|
||||
|
@ -11,7 +10,7 @@
|
|||
|
||||
<%= label f, :email, class: "form-label" %>
|
||||
<div class="inner-addon left-addon mb-3">
|
||||
<%= icon_div @conn, "bi-at", [class: "icon is-left text-muted fs-5"] %>
|
||||
<i class="bi bi-at icon is-left text-muted fs-5"></i>
|
||||
<%= email_input f, :email,
|
||||
value: @current_user && @current_user.email || "",
|
||||
placeholder: "e.g., babka@73k.us",
|
|
@ -2,8 +2,7 @@
|
|||
<div class="col-11 col-sm-10 col-md-8 col-lg-7 col-xl-6 col-xxl-5">
|
||||
|
||||
<h2>
|
||||
<%= icon_div @conn, "mdi-head-question-outline", [class: "icon baseline"] %>
|
||||
Forgot your password?
|
||||
<i class="bi bi-patch-question"></i> Forgot your password?
|
||||
</h2>
|
||||
<p class="lead">We'll send you an email with instructions to reset your password.</p>
|
||||
|
||||
|
@ -11,7 +10,7 @@
|
|||
|
||||
<%= label f, :email, class: "form-label" %>
|
||||
<div class="inner-addon left-addon mb-3">
|
||||
<%= icon_div @conn, "bi-at", [class: "icon is-left text-muted fs-5"] %>
|
||||
<i class="bi bi-at icon is-left text-muted fs-5"></i>
|
||||
<%= email_input f, :email,
|
||||
placeholder: "e.g., babka@73k.us",
|
||||
class: "form-control",
|
|
@ -1,13 +1,14 @@
|
|||
<div class="row justify-content-center">
|
||||
<div class="col-11 col-sm-8 col-md-6 col-lg-5 col-xl-4 col-xxl-3">
|
||||
|
||||
<h2><%= icon_div @conn, "bi-door-open", [class: "icon baseline"] %>
|
||||
Log in</h2>
|
||||
<h2>
|
||||
<i class="bi bi-door-open me-1"></i> Log in
|
||||
</h2>
|
||||
<p class="lead">Who goes there?</p>
|
||||
|
||||
<%= form_for @conn, Routes.user_session_path(@conn, :create), [as: :user, class: "needs-validation", novalidate: true], fn f -> %>
|
||||
<%= if @error_message do %>
|
||||
<div class="alert alert-danger alert-dismissible fade show" role="alert">
|
||||
<div class="alert alert-danger alert-dismissible fade show mt-4" role="alert">
|
||||
<%= @error_message %>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
|
@ -15,11 +16,12 @@
|
|||
|
||||
<%= label f, :email, class: "form-label" %>
|
||||
<div class="inner-addon left-addon mb-3">
|
||||
<%= icon_div @conn, "bi-at", [class: "icon is-left text-muted fs-5"] %>
|
||||
<i class="bi bi-at icon is-left text-muted fs-5"></i>
|
||||
<%= email_input f, :email,
|
||||
class: "form-control",
|
||||
placeholder: "e.g., babka@73k.us",
|
||||
maxlength: User.max_email,
|
||||
autofocus: true,
|
||||
required: true
|
||||
%>
|
||||
<span class="invalid-feedback">must be a valid email address</span>
|
||||
|
@ -27,7 +29,7 @@
|
|||
|
||||
<%= label f, :password, class: "form-label" %>
|
||||
<div class="inner-addon left-addon mb-3">
|
||||
<%= icon_div @conn, "bi-lock", [class: "icon is-left text-muted fs-5"] %>
|
||||
<i class="bi bi-lock icon is-left text-muted fs-5"></i>
|
||||
<%= password_input f, :password,
|
||||
class: "form-control",
|
||||
required: true
|
|
@ -2,8 +2,7 @@
|
|||
<div class="col-12 col-md-10 col-xl-8">
|
||||
|
||||
<h2>
|
||||
<%= icon_div @conn, "bi-file-earmark-spreadsheet", [class: "icon baseline"] %>
|
||||
CSV Export
|
||||
<i class="bi bi-file-earmark-spreadsheet"></i> CSV Export
|
||||
</h2>
|
||||
<p class="lead">Select a date range for which to export a CSV of your scheduled shifts, or click "Export All" to export everything.</p>
|
||||
|
|
@ -2,8 +2,7 @@
|
|||
<div class="col-12 col-md-10 col-xl-8">
|
||||
|
||||
<h2>
|
||||
<%= icon_div @conn, "bi-calendar2", [class: "icon baseline"] %>
|
||||
User Shifts ICS
|
||||
<i class="bi bi-calendar2"></i> User Shifts ICS
|
||||
</h2>
|
||||
<p class="lead">Shifts for user: <%= @user.email %></p>
|
||||
<p>Calendar slug: <%= @slug %></p>
|
|
@ -4,6 +4,13 @@ defmodule Shift73kWeb.LayoutView do
|
|||
alias Shift73k.Accounts.User
|
||||
alias Shift73kWeb.Roles
|
||||
|
||||
# With a Vite.js-based workflow, we will import different asset files in development
|
||||
# and in production builds. Therefore, we will need a way to conditionally render
|
||||
# <script> tags based on Mix environment. However, since Mix is not available in
|
||||
# releases, we need to cache the Mix environment at compile time. To this end:
|
||||
@env Mix.env() # remember value at compile time
|
||||
def dev_env?, do: @env == :dev
|
||||
|
||||
def nav_link_opts(conn, opts) do
|
||||
case Keyword.get(opts, :to) == Phoenix.Controller.current_path(conn) do
|
||||
false -> opts
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue