Skip to content

Commit

Permalink
Merge pull request #22 from jameswilliamiii/sign-in-card
Browse files Browse the repository at this point in the history
Update sign in and password reset to use cards
  • Loading branch information
jameswilliamiii authored Oct 16, 2024
2 parents 4c252c5 + 2653048 commit 8b05fa0
Show file tree
Hide file tree
Showing 20 changed files with 225 additions and 67 deletions.
3 changes: 3 additions & 0 deletions app/assets/images/check-circle.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions app/assets/images/exclamation-circle.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions app/assets/images/information-circle.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
51 changes: 51 additions & 0 deletions app/components/flash_alerts.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# frozen_string_literal: true

class Components::FlashAlerts < Components::Base
attr_reader :flash

def initialize(flash)
@flash = flash
end
def view_template
flash.keys.each do |key|
variant = find_variant(key)

RBUI::Alert(variant: variant, class: find_alert_class(variant), data: { controller: "flash-alerts" }) do
div(class: "w-5 inline-block me-2") { render find_icon(variant) }
render RBUI::AlertDescription.new { flash[key] }
end
end
end

def find_variant(key)
case key
when "notice"
:success
when "alert"
:destructive
end
end

def find_icon(variant)
case variant
when :success
InlineSvg.new("check-circle.svg")
when :destructive
InlineSvg.new("exclamation-circle.svg")
else
InlineSvg.new("information-circle.svg")
end
end

def find_alert_class(variant)
base_class = "flex items-center mb-3"
case variant
when :success
[ base_class, "text-primary ring-primary/20" ].join(" ")
when :destructive
[ base_class, "text-red-500 ring-red-500/20" ].join(" ")
else
[ base_class, "text-gray-500 ring-gray-500/20" ].join(" ")
end
end
end
14 changes: 14 additions & 0 deletions app/components/form_card.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

class Components::FormCard < Components::Base
def view_template(&block)
div(class: base_class) { yield }
end

def base_class
"
w-full max-w-sm p-4 bg-white border border-gray-200 rounded-lg shadowsm:p-6 md:p-8
dark:bg-gray-800 dark:border-gray-700
"
end
end
34 changes: 34 additions & 0 deletions app/components/forms/inputable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
module Components::Forms::Inputable
def label_class
"block mb-2 text-sm font-medium text-gray-900 dark:text-white"
end

def input_class
"
bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500
block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white
"
end

def floating_label_input_class
"block py-2.5 px-0 w-full text-sm bg-transparent border-0 border-b-2 appearance-none focus:outline-none focus:ring-0 peer"
end

def floating_label_class
"
peer-focus:font-medium text-gray-500 peer-focus:text-primary absolute text-sm duration-300 transform -translate-y-6 scale-75 top-3 -z-10 origin-[0]
peer-focus:start-0 rtl:peer-focus:translate-x-1/4 rtl:peer-focus:left-auto peer-placeholder-shown:scale-100
peer-placeholder-shown:translate-y-0 peer-focus:scale-75 peer-focus:-translate-y-6
"
end

def floating_label_input(form, attr, field_type = :text_field, options = {})
base_class = "relative z-0 w-full mb-5 group"
combined_class = [ base_class, options.delete(:class) ].join(" ")

div(class: combined_class) {
form.send(field_type, attr, class: floating_label_input_class, placeholder: " ", **options)
form.label attr, class: floating_label_class
}
end
end
11 changes: 11 additions & 0 deletions app/components/forms/submit.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

class Components::Forms::Submit < Components::Base
def initialize(**options)
@options = options
end

def view_template(&block)
render RBUI::Button.new(type: :submit, class: "w-full py-5", **@options) { yield }
end
end
2 changes: 1 addition & 1 deletion app/components/navigation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class Components::Navigation < Components::Base

def view_template
nav(class: nav_classes) {
div(class: "max-w-screen-xl flex flex-wrap items-center justify-between mx-auto px-4 py-2") {
div(class: "flex flex-wrap items-center justify-between mx-auto px-4 py-2") {
link_to(root_path, class: logo_classes) {
"PostIt"
}
Expand Down
31 changes: 31 additions & 0 deletions app/components/passwords/new.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# frozen_string_literal: true

class Components::Passwords::New < Components::Base
include Phlex::Rails::Helpers::FormWith
include Components::Forms::Inputable

def view_template
render Components::FormCard do
form_with url: passwords_path, class: "space-y-6" do |form|
h1(class: "font-bold text-2xl") { "Forgot your password?" }
div {
render RBUI::TypographySmall.new { "Enter your email address and we'll send you a link to reset your password." }
}
div {
floating_label_input(
form, :email_address, :email_field,
required: true, autocomplete: "username",
autofocus: true, value: helpers.params[:email_address]
)
}
div {
render Components::Forms::Submit.new(class: "mt-3") { "Email reset instructions" }
}

div {
RBUI::Link(href: new_session_path, class: "px-0") { "Sign in" }
}
end
end
end
end
30 changes: 30 additions & 0 deletions app/components/sessions/new.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# frozen_string_literal: true

class Components::Sessions::New < Components::Base
include Phlex::Rails::Helpers::FormWith
include Components::Forms::Inputable

def view_template
render Components::FormCard do
form_with url: session_url, class: "space-y-6" do |form|
h1(class: "font-bold text-2xl") { "Sign in" }
div {
floating_label_input(form, :email_address, :email_field, required: true)
}
div {
floating_label_input(form, :password, :password_field, required: true)
}
div {
RBUI::Link(href: new_password_path, class: "px-0") { "Forgot password?" }
}
div {
render Components::Forms::Submit.new { "Sign into your account" }
}
div(class: "mt-4 flex items-center") {
RBUI::TypographyMuted() { "Not signed up yet?" }
RBUI::Link(href: "#") { "Create account" }
}
end
end
end
end
2 changes: 1 addition & 1 deletion app/controllers/sessions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def new
def create
if user = User.authenticate_by(params.permit(:email_address, :password))
start_new_session_for user
redirect_to after_authentication_url
redirect_to after_authentication_url, notice: "Welcome back #{user.name}!"
else
redirect_to new_session_url, alert: "Try another email address or password."
end
Expand Down
1 change: 1 addition & 0 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
module ApplicationHelper
include Components::Forms::Inputable
end
3 changes: 3 additions & 0 deletions app/javascript/controllers/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ application.debug = false
window.Stimulus = application

export { application }

import RBUI from "rbui-js";
RBUI.initialize(application);
14 changes: 14 additions & 0 deletions app/javascript/controllers/flash_alerts_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Controller } from "@hotwired/stimulus"

// Connects to data-controller="flash-alerts"
export default class extends Controller {
connect() {
this.closeAlert()
}

closeAlert() {
setTimeout(() => {
this.element.classList.add('hidden')
}, 5000)
}
}
7 changes: 3 additions & 4 deletions app/javascript/controllers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@

import { application } from "./application"

import FlashAlertsController from "./flash_alerts_controller"
application.register("flash-alerts", FlashAlertsController)

import HelloController from "./hello_controller"
application.register("hello", HelloController)


import RBUI from "rbui-js";
RBUI.initialize(application);
17 changes: 10 additions & 7 deletions app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,15 @@
<%= javascript_include_tag "application", "data-turbo-track": "reload", type: "module", defer: true %>
</head>

<body>
<%= render Components::Navigation.new %>


<main class="container">
<%= yield %>
</main>
<body class="min-h-screen flex flex-col">
<div class="flex flex-col flex-grow">
<%= render Components::Navigation.new %>
<div class="container">
<%= render Components::FlashAlerts.new(flash) %>
</div>
<main class="container flex flex-grow">
<%= yield %>
</main>
</div>
</body>
</html>
20 changes: 4 additions & 16 deletions app/views/passwords/new.html.erb
Original file line number Diff line number Diff line change
@@ -1,17 +1,5 @@
<div class="mx-auto md:w-2/3 w-full">
<% if alert = flash[:alert] %>
<p class="py-2 px-3 bg-red-50 mb-5 text-red-500 font-medium rounded-lg inline-block" id="alert"><%= alert %></p>
<% end %>

<h1 class="font-bold text-4xl">Forgot your password?</h1>

<%= form_with url: passwords_path, class: "contents" do |form| %>
<div class="my-5">
<%= form.email_field :email_address, required: true, autofocus: true, autocomplete: "username", placeholder: "Enter your email address", value: params[:email_address], class: "block shadow rounded-md border border-gray-400 outline-none px-3 py-2 mt-2 w-full" %>
</div>

<div class="inline">
<%= form.submit "Email reset instructions", class: "rounded-lg py-3 px-5 bg-blue-600 text-white inline-block font-medium cursor-pointer" %>
</div>
<% end %>
<div class=" flex flex-grow items-center justify-center">
<div class="flex items-center justify-center w-full max-w-sm">
<%= render Components::Passwords::New.new %>
</div>
</div>
6 changes: 3 additions & 3 deletions app/views/posts/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
</div>
<% end %>

<div class="my-5">
<%= form.label :title %>
<%= form.text_field :title, class: "block shadow rounded-md border border-gray-400 outline-none px-3 py-2 mt-2 w-full" %>
<div class="relative z-0 w-full group my-5">
<%= form.text_field :title, class: floating_label_input_class, placeholder: " " %>
<%= form.label :title, class: floating_label_class %>
</div>

<div class="my-5">
Expand Down
4 changes: 0 additions & 4 deletions app/views/posts/index.html.erb
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
<div class="w-full">
<% if notice.present? %>
<p class="py-2 px-3 bg-green-50 mb-5 text-green-500 font-medium rounded-lg inline-block" id="notice"><%= notice %></p>
<% end %>

<% content_for :title, "Posts" %>

<div class="flex justify-between items-center">
Expand Down
36 changes: 5 additions & 31 deletions app/views/sessions/new.html.erb
Original file line number Diff line number Diff line change
@@ -1,31 +1,5 @@
<div class="mx-auto md:w-2/3 w-full">
<% if alert = flash[:alert] %>
<p class="py-2 px-3 bg-red-50 mb-5 text-red-500 font-medium rounded-lg inline-block" id="alert"><%= alert %></p>
<% end %>

<% if notice = flash[:notice] %>
<p class="py-2 px-3 bg-green-50 mb-5 text-green-500 font-medium rounded-lg inline-block" id="notice"><%= notice %></p>
<% end %>

<h1 class="font-bold text-4xl">Sign in</h1>

<%= form_with url: session_url, class: "contents" do |form| %>
<div class="my-5">
<%= form.email_field :email_address, required: true, autofocus: true, autocomplete: "username", placeholder: "Enter your email address", value: params[:email_address], class: "block shadow rounded-md border border-gray-400 outline-none px-3 py-2 mt-2 w-full" %>
</div>

<div class="my-5">
<%= form.password_field :password, required: true, autocomplete: "current-password", placeholder: "Enter your password", maxlength: 72, class: "block shadow rounded-md border border-gray-400 outline-none px-3 py-2 mt-2 w-full" %>
</div>

<div class="col-span-6 sm:flex sm:items-center sm:gap-4">
<div class="inline">
<%= form.submit "Sign in", class: "rounded-lg py-3 px-5 bg-blue-600 text-white inline-block font-medium cursor-pointer" %>
</div>

<div class="mt-4 text-sm text-gray-500 sm:mt-0">
<%= link_to "Forgot password?", new_password_path, class: "text-gray-700 underline" %>
</div>
</div>
<% end %>
</div>
<div class=" flex flex-grow items-center justify-center">
<div class="w-full max-w-sm">
<%= render Components::Sessions::New.new %>
</div>
</div>

0 comments on commit 8b05fa0

Please sign in to comment.