refactor: Modal layout and turbolinks optimization

Reload with turbolinks, error messages, confirm password validation

Login and Signup modals
This commit is contained in:
Juan Rodriguez
2021-06-14 15:10:56 -05:00
parent 9c7146820c
commit 3feaa5d88f
18 changed files with 204 additions and 176 deletions
+3
View File
@@ -58,4 +58,7 @@ group :test do
gem 'webdrivers'
# SimpleCov is a code coverage analysis tool for Ruby
gem 'simplecov'
# Simple console output formatter for SimpleCov
gem 'simplecov-console'
end
+9
View File
@@ -44,6 +44,7 @@ GEM
tzinfo (~> 1.1)
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0)
ansi (1.5.0)
arel (9.0.0)
bcrypt (3.1.16)
bcrypt (3.1.16-java)
@@ -157,6 +158,10 @@ GEM
docile (~> 1.1)
simplecov-html (~> 0.11)
simplecov_json_formatter (~> 0.1)
simplecov-console (0.9.1)
ansi
simplecov
terminal-table
simplecov-html (0.12.3)
simplecov_json_formatter (0.1.3)
spring (2.1.1)
@@ -170,6 +175,8 @@ GEM
actionpack (>= 4.0)
activesupport (>= 4.0)
sprockets (>= 3.0.0)
terminal-table (3.0.1)
unicode-display_width (>= 1.1.1, < 3)
thor (1.1.0)
thread_safe (0.3.6)
thread_safe (0.3.6-java)
@@ -180,6 +187,7 @@ GEM
thread_safe (~> 0.1)
uglifier (4.2.0)
execjs (>= 0.3.0, < 3)
unicode-display_width (2.0.0)
web-console (3.7.0)
actionview (>= 5.0)
activemodel (>= 5.0)
@@ -221,6 +229,7 @@ DEPENDENCIES
rails (~> 5.2.6)
selenium-webdriver
simplecov
simplecov-console
spring
spring-watcher-listen (~> 2.0.0)
turbolinks (~> 5)
+5 -6
View File
@@ -3,11 +3,10 @@
## How to run
### Development
- Setup
- Run migrations
```bash
docker-compose up -d
docker-compose up -d db
docker-compose run --rm app bundle exec rails db:migrate
docker-compose stop
```
- Run
```bash
@@ -15,7 +14,6 @@ docker-compose up
```
### Testing
- Run tests
```bash
docker-compose run --rm app bundle exec rails test
```
@@ -37,5 +35,6 @@ docker-compose run --rm app rubocop
- [x] Add userId key to link model
- [x] Login and logout (sessions)
- [x] User links view
- [ ] Modals layout
- [ ] Setup Redis for production cache_store
- [x] Modals layout
- [ ] Setup Redis for production cache_store
- [ ] Deployment CI
+3 -3
View File
@@ -7,15 +7,15 @@ class SessionsController < ApplicationController
@user = User.find_by(username: session_params[:username])
if @user&.authenticate(session_params[:password])
session[:user_id] = @user.id
redirect_to '/'
render json: nil, status: :ok
else
render json: nil, status: :unauthorized
render json: { username: ['Credentials not valid, try again or create an account'] }, status: :unauthorized
end
end
def destroy
reset_session
redirect_to '/'
render json: nil, status: :ok
end
private
+5 -1
View File
@@ -2,12 +2,16 @@
class UsersController < ApplicationController
def create
if user_params[:password] != params[:user][:confirm_password]
return render json: { password: ['Password not match with Confirm Password'] }, status: :bad_request
end
@user = User.create(user_params)
if @user.errors.any?
render json: @user.errors, status: :unprocessable_entity
else
session[:user_id] = @user.id
redirect_to '/'
render json: nil, status: :ok
end
end
+24 -3
View File
@@ -12,6 +12,7 @@ export default class extends Controller {
}
openSignupModal() {
this.closeLoginModal()
this.signupModalTarget.classList.remove("hidden")
}
@@ -21,18 +22,38 @@ export default class extends Controller {
onSignupSuccess() {
this.closeSignupModal();
Turbolinks.visit('/')
}
onLoginSuccess() {
this.closeLoginModal();
Turbolinks.visit('/')
}
onError(event) {
const [data, ,] = event.detail
const usernameError = `Username: ${data.username.join(' ')}`
const passwordError = `Password: ${data.username.join(' ')}`
const errors = []
alert(`${usernameError}, ${passwordError}`)
if (data.username) {
errors.push(`Username: ${data.username.join(' ')}`)
}
if (data.password) {
errors.push(`Password: ${data.password.join(' ')}`)
}
alert(errors.join(','))
}
confirmLogout(event) {
if (!window.confirm("Do you really want to leave?")) {
event.stopPropagation()
return
}
}
onSuccessLogout() {
Turbolinks.visit('/')
}
}
+1 -2
View File
@@ -1,4 +1,3 @@
a {
a, button, input[type=submit] {
cursor: pointer;
text-decoration: underline;
}
+30
View File
@@ -0,0 +1,30 @@
<div data-users-target="<%= target %>" class="fixed z-10 inset-0 overflow-y-auto hidden" aria-labelledby="modal-title" role="dialog" aria-modal="true">
<div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<!--
Background overlay, show/hide based on modal state.
Entering: "ease-out duration-300"
From: "opacity-0"
To: "opacity-100"
Leaving: "ease-in duration-200"
From: "opacity-100"
To: "opacity-0"
-->
<div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" aria-hidden="true"></div>
<!-- This element is to trick the browser into centering the modal contents. -->
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>
<!--
Modal panel, show/hide based on modal state.
Entering: "ease-out duration-300"
From: "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
To: "opacity-100 translate-y-0 sm:scale-100"
Leaving: "ease-in duration-200"
From: "opacity-100 translate-y-0 sm:scale-100"
To: "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
-->
<%= yield %>
</div>
</div>
+5 -5
View File
@@ -1,14 +1,14 @@
<%= form_with model: Link.new, url: links_path(@link), data: { action: 'ajax:success->links#onCreateLinkSuccess ajax:error->links#onCreateLinkError' } do |f| %>
<div class="col-span-3 sm:col-span-2">
<label for="company_website" class="block text-sm font-medium text-gray-700">
Website
<label for="company_website" class="text-lg leading-6 font-medium text-gray-900">
Shorten an url
</label>
<div class="mt-1 flex rounded-md shadow-sm">
<%= f.text_field :url, data: { target: "links.url" }, placeholder: true, class: "focus:ring-indigo-500 focus:border-indigo-500 flex-1 block w-full rounded-none rounded-md sm:text-sm border-gray-300"%>
<div class="mt-4 flex rounded-md shadow-sm mr-5">
<%= f.text_field :url, data: { target: "links.url" }, placeholder: "https://google.com", class: "focus:ring-indigo-500 focus:border-indigo-500 flex-1 block w-full rounded-none rounded-md sm:text-sm border-gray-300" %>
</div>
</div>
<div class="px-4 py-3 bg-gray-50 text-right sm:px-6">
<div class="px-4 py-3 text-right sm:px-6">
<%= f.submit "Generate", class: "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" %>
</div>
<% end %>
+4 -5
View File
@@ -1,7 +1,6 @@
<div data-links-target="userLinks">
<% if logged_in? %>
<% @current_user.links.each do |link| %>
<h2 class="text-2xl leading-7 text-gray-900 sm:text-3xl sm:truncate m-3 mt-6">My links</h2>
<% @current_user.links.each do |link| %>
<%= render partial: "links/show", locals: { link: link } %>
<% end %>
<% end %>
</div>
<% end %>
<% end %>
+3 -11
View File
@@ -1,12 +1,4 @@
<div class="flex flex-col">
<div class="py-2 align-middle inline-block sm:px-6 lg:px-8">
<div class="shadow sm:rounded-md sm:overflow-hidden">
<div class="px-4 py-5 bg-white space-y-6 sm:p-6">
<div class="grid grid-cols-3 gap-6">
<%= render partial: "links/form" %>
<div data-links-target="output"></div>
</div>
</div>
</div>
</div>
<div class="bg-white shadow overflow-hidden sm:rounded-lg m-3 p-6">
<%= render partial: "links/form" %>
<div data-links-target="output"></div>
</div>
+29 -12
View File
@@ -1,13 +1,30 @@
<div class="col-span-3 sm:col-span-2">
<label for="about" class="block text-sm font-medium text-gray-700">
Short url
</label>
<a href="<%= link.short %>" class="mt-1 text-sm text-gray-600" target="_blank" rel="noreferrer"><%= link.short %></a>
</div>
<div class="col-span-3 sm:col-span-2">
<label for="about" class="block text-sm font-medium text-gray-700">
Click counter
</label>
<p class="mt-2 text-sm text-gray-500"><%= link.click_counter %></p>
<div class="bg-white shadow overflow-hidden sm:rounded-lg m-3">
<div class="border-t border-gray-200">
<dl>
<div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm font-medium text-gray-500">
Website
</dt>
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
<a href="<%= link.url %>" class="mt-1 text-sm text-gray-600" target="_blank" rel="noreferrer"><%= link.url %></a>
</dd>
</div>
<div class="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm font-medium text-gray-500">
Shortened url
</dt>
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
<a href="<%= link.short %>" class="mt-1 text-sm text-gray-600" target="_blank" rel="noreferrer"><%= link.short %></a>
</dd>
</div>
<div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm font-medium text-gray-500">
Click counter
</dt>
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
<%= link.click_counter %>
</dd>
</div>
</dl>
</div>
</div>
+28 -55
View File
@@ -1,61 +1,34 @@
<div data-users-target="loginModal" class="fixed z-10 inset-0 overflow-y-auto hidden" aria-labelledby="modal-title" role="dialog" aria-modal="true">
<div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<!--
Background overlay, show/hide based on modal state.
Entering: "ease-out duration-300"
From: "opacity-0"
To: "opacity-100"
Leaving: "ease-in duration-200"
From: "opacity-100"
To: "opacity-0"
-->
<div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" aria-hidden="true"></div>
<!-- This element is to trick the browser into centering the modal contents. -->
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>
<!--
Modal panel, show/hide based on modal state.
Entering: "ease-out duration-300"
From: "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
To: "opacity-100 translate-y-0 sm:scale-100"
Leaving: "ease-in duration-200"
From: "opacity-100 translate-y-0 sm:scale-100"
To: "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
-->
<%= form_with url: '/login', data: { action: 'ajax:success->users#onLoginSuccess ajax:error->users#onError' }, class: "inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full" do |f| %>
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div class="sm:flex sm:items-start">
<div class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10">
<!-- Heroicon name: outline/exclamation -->
<svg class="h-6 w-6 text-red-600" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
</svg>
<%= form_with url: '/login', data: { action: 'ajax:success->users#onLoginSuccess ajax:error->users#onError' }, class: "inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full" do |f| %>
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div class="sm:flex sm:items-start">
<div class="flex-1 mt-3 text-center sm:mt-0 sm:mx-4 sm:text-left">
<h3 class="text-xl leading-6 font-medium text-gray-900" id="modal-title">
Login
</h3>
<div class="flex-col mt-4">
<div class="my-2">
<label for="username" class="block text-sm font-medium text-gray-700">
Username
</label>
<%= f.text_field :username, class: "focus:ring-indigo-500 focus:border-indigo-500 flex-1 block w-full rounded-none rounded-md sm:text-sm border-gray-300" %>
</div>
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
<h3 class="text-lg leading-6 font-medium text-gray-900" id="modal-title">
Login
</h3>
<div class="mt-2">
<p class="text-sm text-gray-500">
Are you sure you want to deactivate your account? All of your data will be permanently removed. This action cannot be undone.
</p>
<%= f.label :username%><br>
<%= f.text_field :username%><br>
<%= f.label :password%><br>
<%= f.password_field :password%><br>
<div class="my-2">
<label for="password" class="block text-sm font-medium text-gray-700">
Password
</label>
<div class="mt-1 flex rounded-md shadow-sm">
<%= f.password_field :password, class: "focus:ring-indigo-500 focus:border-indigo-500 flex-1 block w-full rounded-none rounded-md sm:text-sm border-gray-300" %>
</div>
</div>
</div>
</div>
<div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
<%= f.submit "Login", class: "mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm" %>
<button data-action="users#closeLoginModal" type="button" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">
Cancel
</button>
</div>
<%end%>
</div>
<button type="button" data-action="click->users#openSignupModal" class="block text-sm font-medium pl-4 pt-6 underline">Create an account</button>
</div>
</div>
<div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
<%= f.submit "Login", class: "mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm" %>
<button data-action="click->users#closeLoginModal" type="button" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">
Cancel
</button>
</div>
<%end%>
+17
View File
@@ -0,0 +1,17 @@
<div data-controller="users">
<div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
<% unless logged_in? %>
<button data-action="click->users#openLoginModal" class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">
Login
</button>
<% end %>
<%= render partial: "users/show" %>
</div>
<%= render partial: "users/new", layout: "layouts/modal", locals: { target: 'signupModal' } %>
<%= render partial: "sessions/new", layout: "layouts/modal", locals: { target: 'loginModal' } %>
</div>
<div data-controller="links">
<%= render partial: "links/new" %>
<%= render partial: "links/index" %>
</div>
-13
View File
@@ -1,13 +0,0 @@
<div data-controller="users">
<button data-action="users#openLoginModal">Login</button>
<button data-action="users#openSignupModal">Sign Up</button>
<%= render partial: "users/show" %>
<%= render partial: "users/new" %>
<%= render partial: "sessions/new" %>
</div>
<div data-controller="links">
<%= render partial: "links/new" %>
<%= render partial: "links/index" %>
</div>
+34 -56
View File
@@ -1,61 +1,39 @@
<div data-users-target="signupModal" class="fixed z-10 inset-0 overflow-y-auto hidden" aria-labelledby="modal-title" role="dialog" aria-modal="true">
<div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<!--
Background overlay, show/hide based on modal state.
Entering: "ease-out duration-300"
From: "opacity-0"
To: "opacity-100"
Leaving: "ease-in duration-200"
From: "opacity-100"
To: "opacity-0"
-->
<div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" aria-hidden="true"></div>
<!-- This element is to trick the browser into centering the modal contents. -->
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>
<!--
Modal panel, show/hide based on modal state.
Entering: "ease-out duration-300"
From: "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
To: "opacity-100 translate-y-0 sm:scale-100"
Leaving: "ease-in duration-200"
From: "opacity-100 translate-y-0 sm:scale-100"
To: "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
-->
<%= form_with model: User.new, url: users_path(@user), data: { action: 'ajax:success->users#onSignupSuccess ajax:error->users#onError' }, class: "inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full" do |f| %>
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div class="sm:flex sm:items-start">
<div class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10">
<!-- Heroicon name: outline/exclamation -->
<svg class="h-6 w-6 text-red-600" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
</svg>
<%= form_with model: User.new, url: users_path(@user), data: { action: 'ajax:success->users#onSignupSuccess ajax:error->users#onError' }, class: "inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full" do |f| %>
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div class="flex-1 mt-3 text-center sm:mt-0 sm:mx-4 sm:text-left">
<h3 class="text-xl leading-6 font-medium text-gray-900" id="modal-title">
Sign Up
</h3>
<div class="flex-col mt-4">
<div class="my-2">
<label for="username" class="block text-sm font-medium text-gray-700">
Username
</label>
<%= f.text_field :username, class: "focus:ring-indigo-500 focus:border-indigo-500 flex-1 block w-full rounded-none rounded-md sm:text-sm border-gray-300" %>
</div>
<div class="my-2">
<label for="password" class="block text-sm font-medium text-gray-700">
Password
</label>
<div class="mt-1 flex rounded-md shadow-sm">
<%= f.password_field :password, class: "focus:ring-indigo-500 focus:border-indigo-500 flex-1 block w-full rounded-none rounded-md sm:text-sm border-gray-300" %>
</div>
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
<h3 class="text-lg leading-6 font-medium text-gray-900" id="modal-title">
Deactivate account
</h3>
<div class="mt-2">
<p class="text-sm text-gray-500">
Are you sure you want to deactivate your account? All of your data will be permanently removed. This action cannot be undone.
</p>
<%= f.label :username%><br>
<%= f.text_field :username%><br>
<%= f.label :password%><br>
<%= f.password_field :password%><br>
</div>
</div>
<div class="my-2">
<label for="confirm_password" class="block text-sm font-medium text-gray-700">
Confirm password
</label>
<div class="mt-1 flex rounded-md shadow-sm">
<%= f.password_field :confirm_password, class: "focus:ring-indigo-500 focus:border-indigo-500 flex-1 block w-full rounded-none rounded-md sm:text-sm border-gray-300" %>
</div>
</div>
</div>
<div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
<%= f.submit "Submit", class: "mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm" %>
<button data-action="users#closeSignupModal" type="button" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">
Cancel
</button>
</div>
<%end%>
</div>
</div>
</div>
<div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
<%= f.submit "Sign Up", class: "mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm" %>
<button data-action="click->users#closeSignupModal" type="button" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">
Cancel
</button>
</div>
<%end%>
+2 -2
View File
@@ -1,4 +1,4 @@
<% if logged_in? %>
<h1>You are Logged In, <%= @current_user.username %></h1>
<%= button_to "Logout", '/logout', method: :post %>
<%= link_to "Logout", '/session/logout', data: { action: 'ajax:before->users#confirmLogout ajax:success->users#onSuccessLogout' }, remote: true, class: "mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm" %>
<h1 class="px-2 py-2 text-sm font-medium">You are Logged In, <%= @current_user.username %></h1>
<%end%>
+2 -2
View File
@@ -1,12 +1,12 @@
# frozen_string_literal: true
Rails.application.routes.draw do
root 'sessions#welcome'
root 'sessions#index'
get '/:slug', to: 'links#redirect', as: :short
get 'session/logout', to: 'sessions#destroy', as: :logout
post 'login', to: 'sessions#create', as: :login
post 'logout', to: 'sessions#destroy', as: :logout
resources :links, only: %i[create]
resources :users, only: %i[create]