forked from treehouse/mastodon
Customizing devise views and controllers
parent
7e93da3f8d
commit
6045b6cb18
Binary file not shown.
After Width: | Height: | Size: 1.3 MiB |
|
@ -7,15 +7,73 @@ $darker-background-color: #e3dede;
|
|||
$text-color: #333030;
|
||||
$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";
|
||||
|
||||
/* 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 {
|
||||
font-family: 'Noto Sans', sans-serif;
|
||||
background: $background-color image-url('background-pattern.png');
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
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;
|
||||
line-height: 18px;
|
||||
font-weight: 400;
|
||||
color: $text-color;
|
||||
}
|
||||
|
||||
|
@ -25,19 +83,143 @@ body {
|
|||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
.logo-container {
|
||||
width: 400px;
|
||||
margin: 100px auto;
|
||||
cursor: default;
|
||||
|
||||
h1 {
|
||||
display: block;
|
||||
text-align: center;
|
||||
padding: 100px 0;
|
||||
color: #fff;
|
||||
font-size: 48px;
|
||||
line-height: 48px;
|
||||
font-weight: 500;
|
||||
|
||||
small {
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
color: $text-color;
|
||||
font-weight: 400;
|
||||
font-family: 'Roboto Mono', monospace;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mastodon-link {
|
||||
color: $quaternary-color;
|
||||
.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;
|
||||
font-weight: bold;
|
||||
|
||||
&: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 'accounts';
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -1,6 +1,7 @@
|
|||
class Account < ActiveRecord::Base
|
||||
# Local users
|
||||
has_one :user, inverse_of: :account
|
||||
validates :username, uniqueness: { scope: :domain }
|
||||
|
||||
# Avatar upload
|
||||
attr_reader :avatar_remote_url
|
||||
|
|
|
@ -2,6 +2,7 @@ class User < ActiveRecord::Base
|
|||
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable
|
||||
|
||||
belongs_to :account, inverse_of: :user
|
||||
accepts_nested_attributes_for :account
|
||||
|
||||
validates :account, presence: true
|
||||
end
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
<p>Hello <%= @resource.email %>!</p>
|
||||
|
||||
<p>We're contacting you to notify you that your password has been changed.</p>
|
|
@ -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>
|
|
@ -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" %>
|
|
@ -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"
|
|
@ -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'
|
|
@ -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"
|
|
@ -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"
|
|
@ -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)
|
|
@ -1 +1,3 @@
|
|||
Mastodon
|
||||
|
||||
= link_to 'Logout', destroy_user_session_path, method: :delete
|
||||
|
|
|
@ -9,7 +9,4 @@
|
|||
= yield :header_tags
|
||||
%body
|
||||
.container
|
||||
= yield
|
||||
.footer
|
||||
Powered by
|
||||
= link_to 'Mastodon', 'https://github.com/Gargron/mastodon', class: 'mastodon-link'
|
||||
= content_for?(:content) ? yield(:content) : yield
|
||||
|
|
|
@ -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"
|
|
@ -2,7 +2,11 @@ Rails.application.routes.draw do
|
|||
get '.well-known/host-meta', to: 'xrd#host_meta', as: :host_meta
|
||||
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 :stream_entries, path: 'updates', only: [:show]
|
||||
|
|
Loading…
Reference in New Issue