mirror of
https://github.com/fly-apps/live_beats.git
synced 2024-11-25 09:20:59 +00:00
settings
This commit is contained in:
parent
4f474b6462
commit
ff7b064660
13 changed files with 201 additions and 68 deletions
|
@ -74,6 +74,16 @@ defmodule LiveBeats.Accounts do
|
||||||
Repo.one(query)
|
Repo.one(query)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def change_settings(%User{} = user, attrs) do
|
||||||
|
User.settings_changeset(user, attrs)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_settings(%User{} = user, attrs) do
|
||||||
|
user
|
||||||
|
|> change_settings(attrs)
|
||||||
|
|> Repo.update()
|
||||||
|
end
|
||||||
|
|
||||||
defp update_github_token(%User{} = user, new_token) do
|
defp update_github_token(%User{} = user, new_token) do
|
||||||
identity =
|
identity =
|
||||||
Repo.one!(from(i in Identity, where: i.user_id == ^user.id and i.provider == "github"))
|
Repo.one!(from(i in Identity, where: i.user_id == ^user.id and i.provider == "github"))
|
||||||
|
|
|
@ -10,6 +10,7 @@ defmodule LiveBeats.Accounts.User do
|
||||||
field :username, :string
|
field :username, :string
|
||||||
field :confirmed_at, :naive_datetime
|
field :confirmed_at, :naive_datetime
|
||||||
field :role, :string, default: "subscriber"
|
field :role, :string, default: "subscriber"
|
||||||
|
field :profile_tagline, :string
|
||||||
|
|
||||||
has_many :identities, Identity
|
has_many :identities, Identity
|
||||||
|
|
||||||
|
@ -21,16 +22,21 @@ defmodule LiveBeats.Accounts.User do
|
||||||
"""
|
"""
|
||||||
def github_registration_changeset(info, primary_email, emails, token) do
|
def github_registration_changeset(info, primary_email, emails, token) do
|
||||||
%{"login" => username} = info
|
%{"login" => username} = info
|
||||||
identity_changeset = Identity.github_registration_changeset(info, primary_email, emails, token)
|
|
||||||
|
identity_changeset =
|
||||||
|
Identity.github_registration_changeset(info, primary_email, emails, token)
|
||||||
|
|
||||||
if identity_changeset.valid? do
|
if identity_changeset.valid? do
|
||||||
params = %{
|
params = %{
|
||||||
"username" => username,
|
"username" => username,
|
||||||
"email" => primary_email,
|
"email" => primary_email,
|
||||||
"name" => get_change(identity_changeset, :provider_name),
|
"name" => get_change(identity_changeset, :provider_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
%User{}
|
%User{}
|
||||||
|> cast(params, [:email, :name, :username])
|
|> cast(params, [:email, :name, :username])
|
||||||
|> validate_required([:email, :name, :username])
|
|> validate_required([:email, :name, :username])
|
||||||
|
|> validate_username()
|
||||||
|> validate_email()
|
|> validate_email()
|
||||||
|> put_assoc(:identities, [identity_changeset])
|
|> put_assoc(:identities, [identity_changeset])
|
||||||
else
|
else
|
||||||
|
@ -41,6 +47,13 @@ defmodule LiveBeats.Accounts.User do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def settings_changeset(%User{} = user, params) do
|
||||||
|
user
|
||||||
|
|> cast(params, [:username])
|
||||||
|
|> validate_required([:username])
|
||||||
|
|> validate_username()
|
||||||
|
end
|
||||||
|
|
||||||
defp validate_email(changeset) do
|
defp validate_email(changeset) do
|
||||||
changeset
|
changeset
|
||||||
|> validate_required([:email])
|
|> validate_required([:email])
|
||||||
|
@ -49,4 +62,21 @@ defmodule LiveBeats.Accounts.User do
|
||||||
|> unsafe_validate_unique(:email, LiveBeats.Repo)
|
|> unsafe_validate_unique(:email, LiveBeats.Repo)
|
||||||
|> unique_constraint(:email)
|
|> unique_constraint(:email)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp validate_username(changeset) do
|
||||||
|
changeset
|
||||||
|
|> validate_format(:username, ~r/^[a-z0-9_-]{2,32}$/)
|
||||||
|
|> unsafe_validate_unique(:username, LiveBeats.Repo)
|
||||||
|
|> unique_constraint(:username)
|
||||||
|
|> prepare_changes(fn changeset ->
|
||||||
|
case fetch_change(changeset, :profile_tagline) do
|
||||||
|
{:ok, _} ->
|
||||||
|
changeset
|
||||||
|
|
||||||
|
:error ->
|
||||||
|
username = get_field(changeset, :username)
|
||||||
|
put_change(changeset, :profile_tagline, "#{username}'s beats")
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
11
lib/live_beats_web/controllers/redirect_controller.ex
Normal file
11
lib/live_beats_web/controllers/redirect_controller.ex
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
defmodule LiveBeatsWeb.RedirectController do
|
||||||
|
use LiveBeatsWeb, :controller
|
||||||
|
|
||||||
|
def redirect_authenticated(conn, _) do
|
||||||
|
if conn.assigns.current_user do
|
||||||
|
LiveBeatsWeb.UserAuth.redirect_if_user_is_authenticated(conn, [])
|
||||||
|
else
|
||||||
|
redirect(conn, to: Routes.sign_in_path(conn, :index))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -43,6 +43,7 @@ defmodule LiveBeatsWeb.UserAuth do
|
||||||
"""
|
"""
|
||||||
def log_in_user(conn, user) do
|
def log_in_user(conn, user) do
|
||||||
user_return_to = get_session(conn, :user_return_to)
|
user_return_to = get_session(conn, :user_return_to)
|
||||||
|
conn = assign(conn, :current_user, user)
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|> renew_session()
|
|> renew_session()
|
||||||
|
@ -107,7 +108,7 @@ defmodule LiveBeatsWeb.UserAuth do
|
||||||
conn
|
conn
|
||||||
|> put_flash(:error, "You must log in to access this page.")
|
|> put_flash(:error, "You must log in to access this page.")
|
||||||
|> maybe_store_return_to()
|
|> maybe_store_return_to()
|
||||||
|> redirect(to: Routes.home_path(conn, :index))
|
|> redirect(to: Routes.sign_in_path(conn, :index))
|
||||||
|> halt()
|
|> halt()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -134,5 +135,5 @@ defmodule LiveBeatsWeb.UserAuth do
|
||||||
|
|
||||||
defp maybe_store_return_to(conn), do: conn
|
defp maybe_store_return_to(conn), do: conn
|
||||||
|
|
||||||
defp signed_in_path(_conn), do: "/"
|
def signed_in_path(conn), do: Routes.song_index_path(conn, :index, conn.assigns.current_user.username)
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,8 +2,13 @@ defmodule LiveBeatsWeb.LiveHelpers do
|
||||||
import Phoenix.LiveView
|
import Phoenix.LiveView
|
||||||
import Phoenix.LiveView.Helpers
|
import Phoenix.LiveView.Helpers
|
||||||
|
|
||||||
|
alias LiveBeatsWeb.Router.Helpers, as: Routes
|
||||||
alias Phoenix.LiveView.JS
|
alias Phoenix.LiveView.JS
|
||||||
|
|
||||||
|
def home_path(socket) do
|
||||||
|
Routes.song_index_path(socket, :index, socket.assigns.current_user.username)
|
||||||
|
end
|
||||||
|
|
||||||
def spinner(assigns) do
|
def spinner(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<svg class="inline-block animate-spin h-2.5 w-2.5 text-gray-400" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
<svg class="inline-block animate-spin h-2.5 w-2.5 text-gray-400" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||||||
|
|
93
lib/live_beats_web/live/settings_live.ex
Normal file
93
lib/live_beats_web/live/settings_live.ex
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
defmodule LiveBeatsWeb.SettingsLive do
|
||||||
|
use LiveBeatsWeb, :live_view
|
||||||
|
|
||||||
|
alias LiveBeats.Accounts
|
||||||
|
|
||||||
|
def render(assigns) do
|
||||||
|
~H"""
|
||||||
|
<.title_bar>
|
||||||
|
Profile Settings
|
||||||
|
</.title_bar>
|
||||||
|
|
||||||
|
<div class="max-w-3xl mx-auto mt-6">
|
||||||
|
<.form let={f} for={@changeset} phx-change="validate" phx-submit="save" class="space-y-8 divide-y divide-gray-200">
|
||||||
|
<div class="space-y-8 divide-y divide-gray-200">
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<p class="mt-1 text-sm text-gray-500">
|
||||||
|
This information will be displayed publicly so be careful what you share.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-6 grid grid-cols-1 gap-y-6 gap-x-4 sm:grid-cols-6">
|
||||||
|
<div class="sm:col-span-4">
|
||||||
|
<label for="username" class="block text-sm font-medium text-gray-700">
|
||||||
|
Username
|
||||||
|
</label>
|
||||||
|
<div class="mt-1 flex rounded-md shadow-sm">
|
||||||
|
<span class="inline-flex items-center px-3 rounded-l-md border border-r-0 border-gray-300 bg-gray-50 text-gray-500 sm:text-sm">
|
||||||
|
<%= URI.parse(LiveBeatsWeb.Endpoint.url()).host %>/
|
||||||
|
</span>
|
||||||
|
<%= text_input f, :username, class: "flex-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full min-w-0 rounded-none rounded-r-md sm:text-sm border-gray-300" %>
|
||||||
|
<.error field={:username} input_name="user[username]" errors={@changeset.errors} class="pt-2 pl-4 pr-4 ml-2 text-center" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sm:col-span-4">
|
||||||
|
<label for="username" class="block text-sm font-medium text-gray-700">
|
||||||
|
Email (from GitHub)
|
||||||
|
</label>
|
||||||
|
<div class="mt-1 flex rounded-md shadow-sm">
|
||||||
|
<%= text_input f, :email, disabled: true, class: "flex-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full min-w-0 rounded-md sm:text-sm border-gray-300 bg-gray-50" %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sm:col-span-4">
|
||||||
|
<label for="about" class="block text-sm font-medium text-gray-700">
|
||||||
|
Profile Tagline
|
||||||
|
</label>
|
||||||
|
<div class="mt-1">
|
||||||
|
<%= text_input f, :profile_tagline, class: "flex-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full min-w-0 rounded-md sm:text-sm border-gray-300" %>
|
||||||
|
<.error field={:profile_tagline} input_name="user[profile_tagline]" errors={@changeset.errors} class="pt-2 pl-4 pr-4 ml-2 text-center" />
|
||||||
|
</div>
|
||||||
|
<p class="text-sm text-gray-500">Write a short tagline for your beats page.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pt-5">
|
||||||
|
<div class="flex justify-end">
|
||||||
|
<button type="submit" class="ml-3 inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
|
||||||
|
Save
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</.form>
|
||||||
|
</div>
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
|
def mount(_parmas, _session, socket) do
|
||||||
|
changeset = Accounts.change_settings(socket.assigns.current_user, %{})
|
||||||
|
{:ok, assign(socket, changeset: changeset)}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_event("validate", %{"user" => params}, socket) do
|
||||||
|
changeset = Accounts.change_settings(socket.assigns.current_user, params)
|
||||||
|
{:noreply, assign(socket, changeset: changeset)}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_event("save", %{"user" => params}, socket) do
|
||||||
|
case Accounts.update_settings(socket.assigns.current_user, params) do
|
||||||
|
{:ok, user} ->
|
||||||
|
{:noreply,
|
||||||
|
socket
|
||||||
|
|> assign(current_user: user)
|
||||||
|
|> put_flash(:info, "settings updated!")}
|
||||||
|
|
||||||
|
{:error, changeset} ->
|
||||||
|
{:noreply, assign(socket, changeset: changeset)}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -130,7 +130,7 @@ defmodule LiveBeatsWeb.SongLive.Index do
|
||||||
LayoutComponent.show_modal(UploadFormComponent, %{
|
LayoutComponent.show_modal(UploadFormComponent, %{
|
||||||
id: :new,
|
id: :new,
|
||||||
confirm: {"Save", type: "submit", form: "song-form"},
|
confirm: {"Save", type: "submit", form: "song-form"},
|
||||||
patch_to: Routes.song_index_path(socket, :index),
|
patch_to: home_path(socket),
|
||||||
song: socket.assigns.song,
|
song: socket.assigns.song,
|
||||||
title: socket.assigns.page_title,
|
title: socket.assigns.page_title,
|
||||||
current_user: socket.assigns.current_user
|
current_user: socket.assigns.current_user
|
||||||
|
|
|
@ -30,8 +30,8 @@ defmodule LiveBeatsWeb.SongLive.SongEntryComponent do
|
||||||
class="block w-full border-0 p-0 text-gray-900 placeholder-gray-500 focus:ring-0 sm:text-sm"/>
|
class="block w-full border-0 p-0 text-gray-900 placeholder-gray-500 focus:ring-0 sm:text-sm"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-span-full sm:grid sm:grid-cols-2 sm:gap-2 sm:items-start">
|
<div class="col-span-full sm:grid sm:grid-cols-2 sm:gap-2 sm:items-start">
|
||||||
<.error input_name={"songs[#{@ref}][title]"} field={:title} errors={@errors}/>
|
<.error input_name={"songs[#{@ref}][title]"} field={:title} errors={@errors} class="-mt-1"/>
|
||||||
<.error input_name={"songs[#{@ref}][artist]"} field={:artist} errors={@errors}/>
|
<.error input_name={"songs[#{@ref}][artist]"} field={:artist} errors={@errors} class="-mt-1"/>
|
||||||
</div>
|
</div>
|
||||||
<div style={"width: #{@progress}%;"} class="col-span-full bg-purple-500 dark:bg-purple-400 h-1.5 w-0 p-0">
|
<div style={"width: #{@progress}%;"} class="col-span-full bg-purple-500 dark:bg-purple-400 h-1.5 w-0 p-0">
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
defmodule LiveBeatsWeb.Router do
|
defmodule LiveBeatsWeb.Router do
|
||||||
use LiveBeatsWeb, :router
|
use LiveBeatsWeb, :router
|
||||||
|
|
||||||
import LiveBeatsWeb.UserAuth, only: [redirect_if_user_is_authenticated: 2]
|
import LiveBeatsWeb.UserAuth,
|
||||||
|
only: [fetch_current_user: 2, redirect_if_user_is_authenticated: 2]
|
||||||
|
|
||||||
pipeline :browser do
|
pipeline :browser do
|
||||||
plug :accepts, ["html"]
|
plug :accepts, ["html"]
|
||||||
|
@ -10,48 +11,19 @@ defmodule LiveBeatsWeb.Router do
|
||||||
plug :put_root_layout, {LiveBeatsWeb.LayoutView, :root}
|
plug :put_root_layout, {LiveBeatsWeb.LayoutView, :root}
|
||||||
plug :protect_from_forgery
|
plug :protect_from_forgery
|
||||||
plug :put_secure_browser_headers
|
plug :put_secure_browser_headers
|
||||||
|
plug :fetch_current_user
|
||||||
end
|
end
|
||||||
|
|
||||||
pipeline :api do
|
pipeline :api do
|
||||||
plug :accepts, ["json"]
|
plug :accepts, ["json"]
|
||||||
end
|
end
|
||||||
|
|
||||||
scope "/", LiveBeatsWeb do
|
|
||||||
pipe_through :browser
|
|
||||||
|
|
||||||
get "/files/:id", FileController, :show
|
|
||||||
|
|
||||||
delete "/signout", OAuthCallbackController, :sign_out
|
|
||||||
|
|
||||||
live_session :default, on_mount: [{LiveBeatsWeb.UserAuth, :current_user}, LiveBeatsWeb.Nav] do
|
|
||||||
live "/signin", SignInLive, :index
|
|
||||||
end
|
|
||||||
|
|
||||||
live_session :authenticated, on_mount: [{LiveBeatsWeb.UserAuth, :ensure_authenticated}, LiveBeatsWeb.Nav] do
|
|
||||||
live "/", HomeLive, :index
|
|
||||||
live "/songs", SongLive.Index, :index
|
|
||||||
live "/songs/new", SongLive.Index, :new
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
scope "/", LiveBeatsWeb do
|
scope "/", LiveBeatsWeb do
|
||||||
pipe_through [:browser, :redirect_if_user_is_authenticated]
|
pipe_through [:browser, :redirect_if_user_is_authenticated]
|
||||||
|
|
||||||
get "/oauth/callbacks/:provider", OAuthCallbackController, :new
|
get "/oauth/callbacks/:provider", OAuthCallbackController, :new
|
||||||
end
|
end
|
||||||
|
|
||||||
# Other scopes may use custom stacks.
|
|
||||||
# scope "/api", LiveBeatsWeb do
|
|
||||||
# pipe_through :api
|
|
||||||
# end
|
|
||||||
|
|
||||||
# Enables LiveDashboard only for development
|
|
||||||
#
|
|
||||||
# If you want to use the LiveDashboard in production, you should put
|
|
||||||
# it behind authentication and allow only admins to access it.
|
|
||||||
# If your application does not have an admins-only section yet,
|
|
||||||
# you can use Plug.BasicAuth to set up some basic authentication
|
|
||||||
# as long as you are also using SSL (which you should anyway).
|
|
||||||
if Mix.env() in [:dev, :test] do
|
if Mix.env() in [:dev, :test] do
|
||||||
import Phoenix.LiveDashboard.Router
|
import Phoenix.LiveDashboard.Router
|
||||||
|
|
||||||
|
@ -61,10 +33,6 @@ defmodule LiveBeatsWeb.Router do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Enables the Swoosh mailbox preview in development.
|
|
||||||
#
|
|
||||||
# Note that preview only shows emails that were sent by the same
|
|
||||||
# node running the Phoenix server.
|
|
||||||
if Mix.env() == :dev do
|
if Mix.env() == :dev do
|
||||||
scope "/dev" do
|
scope "/dev" do
|
||||||
pipe_through :browser
|
pipe_through :browser
|
||||||
|
@ -72,4 +40,24 @@ defmodule LiveBeatsWeb.Router do
|
||||||
forward "/mailbox", Plug.Swoosh.MailboxPreview
|
forward "/mailbox", Plug.Swoosh.MailboxPreview
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
scope "/", LiveBeatsWeb do
|
||||||
|
pipe_through :browser
|
||||||
|
|
||||||
|
get "/", RedirectController, :redirect_authenticated
|
||||||
|
get "/files/:id", FileController, :show
|
||||||
|
|
||||||
|
delete "/signout", OAuthCallbackController, :sign_out
|
||||||
|
|
||||||
|
live_session :default, on_mount: [{LiveBeatsWeb.UserAuth, :current_user}, LiveBeatsWeb.Nav] do
|
||||||
|
live "/signin", SignInLive, :index
|
||||||
|
end
|
||||||
|
|
||||||
|
live_session :authenticated,
|
||||||
|
on_mount: [{LiveBeatsWeb.UserAuth, :ensure_authenticated}, LiveBeatsWeb.Nav] do
|
||||||
|
live "/songs/new", SongLive.Index, :new
|
||||||
|
live "/:user_id", SongLive.Index, :index
|
||||||
|
live "/profile/settings", SettingsLive, :edit
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -38,18 +38,6 @@
|
||||||
<nav class="px-2">
|
<nav class="px-2">
|
||||||
<div class="space-y-1">
|
<div class="space-y-1">
|
||||||
|
|
||||||
<%= live_redirect to: Routes.home_path(@conn, :index),
|
|
||||||
class: "bg-gray-100 text-gray-900 group flex items-center px-2 py-2 text-base leading-5 font-medium rounded-md" do %>
|
|
||||||
<.icon name={:home} outlined class="text-gray-500 mr-3 flex-shrink-0 h-6 w-6"/>
|
|
||||||
Home
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<a href="#"
|
|
||||||
class="text-gray-600 hover:text-gray-900 hover:bg-gray-50 group flex items-center px-2 py-2 text-base leading-5 font-medium rounded-md">
|
|
||||||
<.icon name={:music_note} outlined class="text-gray-400 group-hover:text-gray-500 mr-3 flex-shrink-0 h-6 w-6"/>
|
|
||||||
My tasks
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<%= if @current_user do %>
|
<%= if @current_user do %>
|
||||||
<!-- User account dropdown -->
|
<!-- User account dropdown -->
|
||||||
<div class="px-3 mt-6 relative inline-block text-left w-full">
|
<div class="px-3 mt-6 relative inline-block text-left w-full">
|
||||||
|
@ -207,16 +195,22 @@
|
||||||
<nav class="px-3 mt-6">
|
<nav class="px-3 mt-6">
|
||||||
<div class="space-y-1">
|
<div class="space-y-1">
|
||||||
|
|
||||||
<%= live_redirect to: Routes.home_path(@conn, :index),
|
<%= if @current_user do %>
|
||||||
class: "bg-gray-200 text-gray-900 group flex items-center px-2 py-2 text-sm font-medium rounded-md" do %>
|
<.link
|
||||||
<.icon name={:home} outlined class="text-gray-500 mr-3 flex-shrink-0 h-6 w-6"/>
|
redirect_to={Routes.song_index_path(@conn, :index, @current_user.username)}
|
||||||
Home
|
class="text-gray-700 hover:text-gray-900 hover:bg-gray-50 group flex items-center px-2 py-2 text-sm font-medium rounded-md"
|
||||||
<% end %>
|
>
|
||||||
|
|
||||||
<%= live_redirect to: Routes.song_index_path(@conn, :index),
|
|
||||||
class: "text-gray-700 hover:text-gray-900 hover:bg-gray-50 group flex items-center px-2 py-2 text-sm font-medium rounded-md" do %>
|
|
||||||
<.icon name={:music_note} outlined class="text-gray-400 group-hover:text-gray-500 mr-3 flex-shrink-0 h-6 w-6"/>
|
<.icon name={:music_note} outlined class="text-gray-400 group-hover:text-gray-500 mr-3 flex-shrink-0 h-6 w-6"/>
|
||||||
My Songs
|
My Songs
|
||||||
|
</.link>
|
||||||
|
|
||||||
|
<.link
|
||||||
|
redirect_to={Routes.settings_path(@conn, :edit)}
|
||||||
|
class="text-gray-700 hover:text-gray-900 hover:bg-gray-50 group flex items-center px-2 py-2 text-sm font-medium rounded-md"
|
||||||
|
>
|
||||||
|
<.icon name={:adjustments} outlined class="text-gray-400 group-hover:text-gray-500 mr-3 flex-shrink-0 h-6 w-6"/>
|
||||||
|
Settings
|
||||||
|
</.link>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= unless @current_user do %>
|
<%= unless @current_user do %>
|
||||||
|
|
|
@ -22,16 +22,16 @@ defmodule LiveBeatsWeb.ErrorHelpers do
|
||||||
|
|
||||||
~H"""
|
~H"""
|
||||||
<%= for error <- @error_values do %>
|
<%= for error <- @error_values do %>
|
||||||
<div
|
<span
|
||||||
phx-feedback-for={@input_name}
|
phx-feedback-for={@input_name}
|
||||||
class={"invalid-feedback -mt-1 pl-2 text-sm text-white bg-red-600 rounded-md #{@class}"}
|
class={"invalid-feedback inline-block pl-2 pr-2 text-sm text-white bg-red-600 rounded-md #{@class}"}
|
||||||
>
|
>
|
||||||
<%= translate_error(error) %>
|
<%= translate_error(error) %>
|
||||||
</div>
|
</span>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= if Enum.empty?(@error_values) do %>
|
<%= if Enum.empty?(@error_values) do %>
|
||||||
<div class={"invalid-feedback h-0 #{@class}"}></div>
|
<span class={"invalid-feedback inline-block h-0 #{@class}"}></span>
|
||||||
<% end %>
|
<% end %>
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,6 +10,7 @@ defmodule LiveBeats.Repo.Migrations.CreateUserAuth do
|
||||||
add :name, :string
|
add :name, :string
|
||||||
add :role, :string, null: false
|
add :role, :string, null: false
|
||||||
add :confirmed_at, :naive_datetime
|
add :confirmed_at, :naive_datetime
|
||||||
|
add :profile_tagline, :string
|
||||||
|
|
||||||
timestamps()
|
timestamps()
|
||||||
end
|
end
|
||||||
|
|
|
@ -86,7 +86,7 @@ defmodule LiveBeatsWeb.UserAuthTest do
|
||||||
test "redirects if user is not authenticated", %{conn: conn} do
|
test "redirects if user is not authenticated", %{conn: conn} do
|
||||||
conn = conn |> fetch_flash() |> UserAuth.require_authenticated_user([])
|
conn = conn |> fetch_flash() |> UserAuth.require_authenticated_user([])
|
||||||
assert conn.halted
|
assert conn.halted
|
||||||
assert redirected_to(conn) == Routes.home_path(conn, :index)
|
assert redirected_to(conn) == Routes.song_index_path(conn, :index)
|
||||||
assert get_flash(conn, :error) == "You must log in to access this page."
|
assert get_flash(conn, :error) == "You must log in to access this page."
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue