Customizing devise views and controllers

main
Eugen Rochko 2016-03-05 22:43:05 +01:00
parent 7e93da3f8d
commit 6045b6cb18
19 changed files with 398 additions and 17 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

@ -7,15 +7,73 @@ $darker-background-color: #e3dede;
$text-color: #333030; $text-color: #333030;
$lighter-text-color: #8b8687; $lighter-text-color: #8b8687;
@import url("https://fonts.googleapis.com/css?family=Noto+Sans:400,700,400italic"); @import url(https://fonts.googleapis.com/css?family=Roboto:400,500,400italic);
@import url(https://fonts.googleapis.com/css?family=Roboto+Mono);
@import "font-awesome-sprockets"; @import "font-awesome-sprockets";
@import "font-awesome"; @import "font-awesome";
/* http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body { body {
font-family: 'Noto Sans', sans-serif; line-height: 1;
background: $background-color image-url('background-pattern.png'); }
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
body {
font-family: 'Roboto', sans-serif;
background: $background-color image-url('background-photo.jpeg');
background-size: cover;
font-size: 13px; font-size: 13px;
line-height: 18px; line-height: 18px;
font-weight: 400;
color: $text-color; color: $text-color;
} }
@ -25,19 +83,143 @@ body {
margin-top: 40px; margin-top: 40px;
} }
.footer { .logo-container {
text-align: center; width: 400px;
padding: 100px 0; margin: 100px auto;
font-size: 12px; cursor: default;
color: $text-color;
.mastodon-link { h1 {
color: $quaternary-color; display: block;
text-decoration: none; text-align: center;
font-weight: bold; color: #fff;
font-size: 48px;
line-height: 48px;
font-weight: 500;
small {
display: block;
font-size: 12px;
font-weight: 400;
font-family: 'Roboto Mono', monospace;
}
} }
} }
.form-container {
width: 400px;
margin: 0 auto;
.field {
margin-bottom: 15px;
}
input[type=text], input[type=email], input[type=password] {
background: transparent;
border: 0;
border-bottom: 2px solid #9baec8;
padding: 7px 0;
font-size: 16px;
color: #fff;
display: block;
width: 100%;
outline: 0;
&:invalid {
box-shadow: none;
}
&:focus:invalid {
border-bottom-color: #df405a;
}
&:required:valid {
border-bottom-color: #79bd9a;
}
&:active, &:focus {
border-bottom-color: #2b90d9;
}
}
.field_with_error {
input[type=text], input[type=email], input[type=password] {
border-bottom-color: #df405a;
}
}
.actions {
margin-top: 30px;
button {
display: block;
width: 100%;
border: 0;
border-radius: 4px;
background: #2b90d9;
color: #fff;
font-size: 18px;
padding: 10px;
text-transform: uppercase;
cursor: pointer;
font-weight: 500;
outline: 0;
&:hover {
background-color: lighten(#2b90d9, 5%);
}
&:active, &:focus {
position: relative;
top: 1px;
background-color: darken(#2b90d9, 5%);
}
}
}
.form-footer {
margin-top: 30px;
text-align: center;
a {
color: #9baec8;
text-decoration: none;
&:hover {
color: #d9e1e8;
text-decoration: underline;
}
}
}
#error_explanation {
background: #282c37;
color: #9baec8;
border-radius: 4px;
padding: 15px 10px;
margin-bottom: 30px;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
h2 {
font-weight: 500;
margin-bottom: 5px;
}
li {
margin-left: 15px;
list-style: circle;
}
}
}
.no-list {
list-style: none;
li {
display: inline-block;
margin: 0 5px;
}
}
@import 'home'; @import 'home';
@import 'accounts'; @import 'accounts';

View File

@ -0,0 +1,34 @@
class Auth::PasswordsController < Devise::PasswordsController
layout 'auth'
# GET /resource/password/new
# def new
# super
# end
# POST /resource/password
# def create
# super
# end
# GET /resource/password/edit?reset_password_token=abcdef
# def edit
# super
# end
# PUT /resource/password
# def update
# super
# end
# protected
# def after_resetting_password_path_for(resource)
# super(resource)
# end
# The path used after sending reset password instructions
# def after_sending_reset_password_instructions_path_for(resource_name)
# super(resource_name)
# end
end

View File

@ -0,0 +1,22 @@
class Auth::RegistrationsController < Devise::RegistrationsController
layout 'auth'
before_filter :configure_sign_up_params, only: [:create]
protected
def build_resource(hash = nil)
super(hash)
self.resource.build_account if self.resource.account.nil?
end
def configure_sign_up_params
devise_parameter_sanitizer.for(:sign_up) do |u|
u.permit(:email, :password, :password_confirmation, account_attributes: [:username])
end
end
def after_sign_up_path_for(resource)
account_path(resource.account)
end
end

View File

@ -0,0 +1,27 @@
class Auth::SessionsController < Devise::SessionsController
layout 'auth'
# before_filter :configure_sign_in_params, only: [:create]
# GET /resource/sign_in
# def new
# super
# end
# POST /resource/sign_in
# def create
# super
# end
# DELETE /resource/sign_out
# def destroy
# super
# end
# protected
# If you have extra params to permit, append them to the sanitizer.
# def configure_sign_in_params
# devise_parameter_sanitizer.for(:sign_in) << :attribute
# end
end

View File

@ -1,6 +1,7 @@
class Account < ActiveRecord::Base class Account < ActiveRecord::Base
# Local users # Local users
has_one :user, inverse_of: :account has_one :user, inverse_of: :account
validates :username, uniqueness: { scope: :domain }
# Avatar upload # Avatar upload
attr_reader :avatar_remote_url attr_reader :avatar_remote_url

View File

@ -2,6 +2,7 @@ class User < ActiveRecord::Base
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable
belongs_to :account, inverse_of: :user belongs_to :account, inverse_of: :user
accepts_nested_attributes_for :account
validates :account, presence: true validates :account, presence: true
end end

View File

@ -0,0 +1,3 @@
<p>Hello <%= @resource.email %>!</p>
<p>We're contacting you to notify you that your password has been changed.</p>

View File

@ -0,0 +1,8 @@
<p>Hello <%= @resource.email %>!</p>
<p>Someone has requested a link to change your password. You can do this through the link below.</p>
<p><%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %></p>
<p>If you didn't request this, please ignore this email.</p>
<p>Your password won't change until you access the link above and create a new one.</p>

View File

@ -0,0 +1,25 @@
<h2>Change your password</h2>
<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %>
<%= devise_error_messages! %>
<%= f.hidden_field :reset_password_token %>
<div class="field">
<%= f.label :password, "New password" %><br />
<% if @minimum_password_length %>
<em>(<%= @minimum_password_length %> characters minimum)</em><br />
<% end %>
<%= f.password_field :password, autofocus: true, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation, "Confirm new password" %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<div class="actions">
<%= f.submit "Change my password" %>
</div>
<% end %>
<%= render "devise/shared/links" %>

View File

@ -0,0 +1,9 @@
= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f|
= devise_error_messages!
.field
= f.email_field :email, autofocus: true, required: true, placeholder: 'E-mail address'
.actions
= f.button "Reset password", type: 'submit'
.form-footer= render "auth/shared/links"

View File

@ -0,0 +1,11 @@
= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f|
= devise_error_messages!
.field
= f.password_field :password, autocomplete: "off", placeholder: 'New password'
.field
= f.password_field :password_confirmation, autocomplete: "off", placeholder: 'Confirm new password'
.field
= f.password_field :current_password, autocomplete: "off", placeholder: 'Current password'
.actions
= f.button "Save changes", type: 'submit'

View File

@ -0,0 +1,17 @@
= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f|
= devise_error_messages!
= f.fields_for :account do |ff|
.field
= ff.text_field :username, autofocus: true, placeholder: 'Username', required: true
.field
= f.email_field :email, placeholder: 'E-mail address', required: true
.field
= f.password_field :password, autocomplete: "off", placeholder: 'Password', required: true
.field
= f.password_field :password_confirmation, autocomplete: "off", placeholder: 'Confirm password', required: true
.actions
= f.button "Sign up", type: 'submit'
.form-footer= render "auth/shared/links"

View File

@ -0,0 +1,9 @@
= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
.field
= f.email_field :email, autofocus: true, placeholder: 'E-mail address', required: true
.field
= f.password_field :password, autocomplete: "off", placeholder: 'Password', required: true
.actions
= f.button "Log in", type: 'submit'
.form-footer= render "auth/shared/links"

View File

@ -0,0 +1,19 @@
%ul.no-list
- if controller_name != 'sessions'
%li= link_to "Log in", new_session_path(resource_name)
- if devise_mapping.registerable? && controller_name != 'registrations'
%li= link_to "Sign up", new_registration_path(resource_name)
- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations'
%li= link_to "Forgot your password?", new_password_path(resource_name)
- if devise_mapping.confirmable? && controller_name != 'confirmations'
%li= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name)
- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks'
%li= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name)
- if devise_mapping.omniauthable?
- resource_class.omniauth_providers.each do |provider|
%li= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider)

View File

@ -1 +1,3 @@
Mastodon Mastodon
= link_to 'Logout', destroy_user_session_path, method: :delete

View File

@ -9,7 +9,4 @@
= yield :header_tags = yield :header_tags
%body %body
.container .container
= yield = content_for?(:content) ? yield(:content) : yield
.footer
Powered by
= link_to 'Mastodon', 'https://github.com/Gargron/mastodon', class: 'mastodon-link'

View File

@ -0,0 +1,10 @@
- content_for :content do
.logo-container
%h1
Mastodon
%small= Rails.configuration.x.local_domain
.form-container
= yield
= render template: "layouts/application"

View File

@ -2,7 +2,11 @@ Rails.application.routes.draw do
get '.well-known/host-meta', to: 'xrd#host_meta', as: :host_meta get '.well-known/host-meta', to: 'xrd#host_meta', as: :host_meta
get '.well-known/webfinger', to: 'xrd#webfinger', as: :webfinger get '.well-known/webfinger', to: 'xrd#webfinger', as: :webfinger
devise_for :users, path: 'auth' devise_for :users, path: 'auth', controllers: {
sessions: 'auth/sessions',
registrations: 'auth/registrations',
passwords: 'auth/passwords'
}
resources :accounts, path: 'users', only: [:show], param: :username do resources :accounts, path: 'users', only: [:show], param: :username do
resources :stream_entries, path: 'updates', only: [:show] resources :stream_entries, path: 'updates', only: [:show]