Commit 6c571aa7 by Mai Hoang Thai Ha

create sign up, login, profile, edit, forgot password

parent a92c2bab
......@@ -64,3 +64,5 @@ gem 'kaminari', :git => 'https://github.com/kaminari/kaminari'
gem 'nokogiri', '~> 1.11', '>= 1.11.7'
gem 'httparty', '~> 0.18.1'
gem 'active_storage_validations', '~> 0.9.5'
gem 'devise', '~> 4.8'
gem 'jquery-rails', '~> 4.4'
\ No newline at end of file
......@@ -82,6 +82,7 @@ GEM
addressable (2.8.0)
public_suffix (>= 2.0.2, < 5.0)
ast (2.4.2)
bcrypt (3.1.16)
bindex (0.8.1)
bootsnap (1.7.5)
msgpack (~> 1.0)
......@@ -102,6 +103,12 @@ GEM
coderay (1.1.3)
concurrent-ruby (1.1.9)
crass (1.0.6)
devise (4.8.0)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 4.1.0)
responders
warden (~> 1.2.3)
erubi (1.10.0)
ffi (1.15.3)
globalid (0.4.2)
......@@ -113,6 +120,10 @@ GEM
concurrent-ruby (~> 1.0)
jbuilder (2.11.2)
activesupport (>= 5.0.0)
jquery-rails (4.4.0)
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
listen (3.5.1)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
......@@ -134,6 +145,7 @@ GEM
nio4r (2.5.7)
nokogiri (1.11.7-x86_64-linux)
racc (~> 1.4)
orm_adapter (0.5.0)
parallel (1.20.1)
parser (3.0.2.0)
ast (~> 2.4.1)
......@@ -185,6 +197,9 @@ GEM
rb-inotify (0.10.1)
ffi (~> 1.0)
regexp_parser (2.1.1)
responders (3.0.1)
actionpack (>= 5.0)
railties (>= 5.0)
rexml (3.2.5)
rubocop (1.18.3)
parallel (~> 1.10)
......@@ -242,6 +257,8 @@ GEM
concurrent-ruby (~> 1.0)
unicode-display_width (2.0.0)
uniform_notifier (1.14.2)
warden (1.2.9)
rack (>= 2.0.9)
web-console (4.1.0)
actionview (>= 6.0.0)
activemodel (>= 6.0.0)
......@@ -272,8 +289,10 @@ DEPENDENCIES
bullet (~> 6.1, >= 6.1.4)
byebug
capybara (>= 3.26)
devise (~> 4.8)
httparty (~> 0.18.1)
jbuilder (~> 2.7)
jquery-rails (~> 4.4)
kaminari!
listen (~> 3.3)
mysql2 (~> 0.5)
......
// Place all the styles related to the Users controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: https://sass-lang.com/
.main-body {
padding: 15px;
margin-top:20px;
color: #1a202c;
text-align: left;
background-color: #e2e8f0;
}
.card {
box-shadow: 0 1px 3px 0 rgba(0,0,0,.1), 0 1px 2px 0 rgba(0,0,0,.06);
}
.card {
position: relative;
display: flex;
flex-direction: column;
min-width: 0;
word-wrap: break-word;
background-color: #fff;
background-clip: border-box;
border: 0 solid rgba(0,0,0,.125);
border-radius: .25rem;
}
.card-body {
flex: 1 1 auto;
min-height: 1px;
padding: 1rem;
}
.gutters-sm {
margin-right: -8px;
margin-left: -8px;
}
.gutters-sm>.col, .gutters-sm>[class*=col-] {
padding-right: 8px;
padding-left: 8px;
}
.mb-3, .my-3 {
margin-bottom: 1rem!important;
}
.bg-gray-300 {
background-color: #e2e8f0;
}
.h-100 {
height: 100%!important;
}
.shadow-none {
box-shadow: none!important;
}
\ No newline at end of file
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit :sign_up, keys: %i[name address phone email password]
devise_parameter_sanitizer.permit :account_update, keys: %i[name email address phone password current_password]
end
private
def logged_in_user
unless user_signed_in?
flash[:danger] = 'Please log in.'
redirect_to new_user_session_path
end
end
end
class AppliesController < ApplicationController
before_action :load_job, only: %i[new confirm create]
before_action :logged_in_user
def index
end
def create
@user = User.find_by(id: 1)
@user = current_user
@apply = @job.apply_jobs.build(apply_params)
@apply.user_id = @user.id
@apply.cv.attach(params[:apply_job][:cv])
if @apply.save
UserMailer.apply_job(@user, @job, @apply).deliver_now
flash.now[:info] = 'Job application information has been sent to your email'
......@@ -25,7 +25,7 @@ class AppliesController < ApplicationController
end
def confirm
@user = User.find_by(id: 1)
@user = current_user
@apply = @job.apply_jobs.build(apply_params)
@apply.user_id = @user.id
if @apply.valid?
......
class UsersController < ApplicationController
before_action :logged_in_user
def show
@user = User.find(params[:id])
end
end
module UsersHelper
def gravatar_for(user, options = { size: 150 })
size = options[:size]
gravatar_id = Digest::MD5::hexdigest(user.email.downcase)
gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}?s=#{size}"
image_tag(gravatar_url, alt: user.name, class: "rounded-circle")
end
end
......@@ -15,3 +15,8 @@ ActiveStorage.start()
import "bootstrap"
window.bootstrap = require("bootstrap");
import "../stylesheets/application.scss";
//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require turbolinks
//= require_tree .
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :apply_jobs, dependent: :destroy
has_many :favorite_jobs, dependent: :destroy
has_many :history_jobs, dependent: :destroy
......
......@@ -3,8 +3,15 @@ header.navbar.navbar-fixed-top.navbar-inverse
= link_to image_tag("logo.png", alt: "Zigexn logo", width: "150"),
- root_path
nav
ul.nav.navbar-nav.navbar-right
ul.nav.navbar-nav.navbar-right.text-light
- if user_signed_in?
li
= link_to "Log in", '#'
= link_to "Profile", current_user
li
= link_to "Sign up", '#'
\ No newline at end of file
= link_to "Log out", destroy_user_session_path, method: :delete
- else
li
= link_to "Log in", new_user_session_path
li
= link_to "Sign up", new_user_registration_path
......@@ -9,9 +9,15 @@ html
= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload'
= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload'
= render 'layouts/shim'
= yield(:head)
body
= render 'layouts/header'
.container-fluid style ="min-height:80vh;"
/ .container-fluid class=("text-center alert alert-#{notice}")
/ p.notice
/ = notice
/ p.alert
/ = alert
- flash.each do |message_type, message|
div class=("text-center alert alert-#{message_type}") = message
= yield
......
<h2>Resend confirmation instructions</h2>
<%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>
<%= render "users/shared/error_messages", resource: resource %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email", value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email) %>
</div>
<div class="actions">
<%= f.submit "Resend confirmation instructions" %>
</div>
<% end %>
<%= render "users/shared/links" %>
<p>Welcome <%= @email %>!</p>
<p>You can confirm your account email through the link below:</p>
<p><%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %></p>
<p>Hello <%= @email %>!</p>
<% if @resource.try(:unconfirmed_email?) %>
<p>We're contacting you to notify you that your email is being changed to <%= @resource.unconfirmed_email %>.</p>
<% else %>
<p>We're contacting you to notify you that your email has been changed to <%= @resource.email %>.</p>
<% end %>
<p>Hello <%= @resource.email %>!</p>
<p>We're contacting you to notify you that your password has been changed.</p>
<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>
<p>Hello <%= @resource.email %>!</p>
<p>Your account has been locked due to an excessive number of unsuccessful sign in attempts.</p>
<p>Click the link below to unlock your account:</p>
<p><%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %></p>
- provide(:title, "Change password")
.container
.row.justify-content-center
.col-6
h2.text-center.my-5
| Change your password
= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f|
= render "users/shared/error_messages", resource: resource
= f.hidden_field :reset_password_token
.field
= f.label :password, "New password", class: 'form-label'
br/
- if @minimum_password_length
em
| (#{@minimum_password_length} characters minimum)
br/
= f.password_field :password, autofocus: true, autocomplete: "new-password", class: 'form-control mb-2'
.field
= f.label :password_confirmation, "Confirm new password", class: 'form-label'
br/
= f.password_field :password_confirmation, autocomplete: "new-password", class: 'form-control mb-2'
.actions
= f.submit "Change my password", class: 'btn btn-primary w-100 my-4'
= render "users/shared/links"
- provide(:title, "Forgot password")
.container
.row.justify-content-center
.col-6
h2.text-center.my-5
| Forgot your password?
= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f|
= render "users/shared/error_messages", resource: resource
.field
= f.label :email, class: 'form-label'
br/
= f.email_field :email, autofocus: true, autocomplete: "email", class: 'form-control mb-2'
.actions
= f.submit "Send me reset password instructions", class: 'btn btn-primary w-100 my-4'
= render "users/shared/links"
- provide(:title, "Edit profile")
.container
.row.justify-content-center
.col-6
h2.text-center.my-5
| Edit
= resource_name.to_s.humanize
= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f|
= render "users/shared/error_messages", resource: resource
.field
= f.label :email, class: 'form-label'
br
= f.email_field :email, autofocus: true, autocomplete: "email", class: 'form-control mb-2'
.field
- if devise_mapping.confirmable? && resource.pending_reconfirmation?
div
| Currently waiting confirmation for:
= resource.unconfirmed_email
.field
= f.label :name, class: 'form-label'
br
= f.text_field :name, autofocus: true, autocomplete: "name", class: 'form-control mb-2'
.field
= f.label :address, class: 'form-label'
br
= f.text_field :address, autofocus: true, autocomplete: "address", class: 'form-control mb-2'
.field
= f.label :phone, class: 'form-label'
br
= f.text_field :phone, autofocus: true, autocomplete: "phone", class: 'form-control mb-2'
.field
= f.label :password, class: 'form-label'
i
| (leave blank if you don't want to change it)
br
= f.password_field :password, autocomplete: "new-password", class: 'form-control mb-2'
- if @minimum_password_length
em
= @minimum_password_length
| characters minimum
.field
= f.label :password_confirmation, class: 'form-label'
br
= f.password_field :password_confirmation, autocomplete: "new-password", class: 'form-control mb-2'
.field
= f.label :current_password, class: 'form-label'
i
| (we need your current password to confirm your changes)
br
= f.password_field :current_password, autocomplete: "current-password", class: 'form-control mb-2'
.actions
= f.submit "Done", class: "btn btn-primary w-100 my-4"
hr
h3
| Delete my account
p
| Click the button below to delete account
= button_to "Delete", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete, class: "btn btn-primary w-100 my-4"
= link_to "Home", :back
\ No newline at end of file
- provide(:title, "Sign Up")
.container
.row.justify-content-center
.col-6
h2.text-center.my-5
| Sign up
= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f|
= render "users/shared/error_messages", resource: resource
.field
= f.label :email, class: 'form-label'
br
= f.email_field :email, autofocus: true, autocomplete: "email", class: 'form-control mb-2'
.field
= f.label :name, class: 'form-label'
br
= f.text_field :name, autofocus: true, autocomplete: "name", class: 'form-control mb-2'
.field
= f.label :address, class: 'form-label'
br
= f.text_field :address, autofocus: true, autocomplete: "address", class: 'form-control mb-2'
.field
= f.label :phone, class: 'form-label'
br
= f.text_field :phone, autofocus: true, autocomplete: "phone", class: 'form-control mb-2'
.field
= f.label :password, class: 'form-label'
- if @minimum_password_length
em
| (
= @minimum_password_length
| characters minimum)
br
= f.password_field :password, autocomplete: "new-password", class: 'form-control mb-2'
.field
= f.label :password_confirmation, class: 'form-label'
br
= f.password_field :password_confirmation, autocomplete: "new-password", class: 'form-control mb-2'
.actions
= f.submit "Sign up", class: "btn btn-primary w-100 my-5"
= render "users/shared/links"
\ No newline at end of file
.container
.row.justify-content-center
.col-6
h2.text-center.my-5
| Log in
= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
.field
= f.label :email, class: 'form-label'
br
= f.email_field :email, autofocus: true, autocomplete: "email", class: 'form-control mb-2'
.field
= f.label :password, class: 'form-label'
br
= f.password_field :password, autocomplete: "current-password", class: 'form-control mb-2'
- if devise_mapping.rememberable?
.field
= f.check_box :remember_me
= f.label :remember_me, class: 'form-label'
.actions
= f.submit "Log in", class: "btn btn-primary w-100 my-5"
= render "users/shared/links"
\ No newline at end of file
- if resource.errors.any?
#error_explanation.bg_danger
.alert.alert-danger
= I18n.t("errors.messages.not_saved", count: resource.errors.count, resource: resource.class.model_name.human.downcase)
ul.mb-3
- resource.errors.full_messages.each do |message|
li.text-danger
= message
\ No newline at end of file
- if controller_name != 'sessions'
= link_to "Log in", new_session_path(resource_name), class: 'text-decoration-none'
br/
- if devise_mapping.registerable? && controller_name != 'registrations'
= link_to "Sign up", new_registration_path(resource_name), class: 'text-decoration-none'
br/
- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations'
= link_to "Forgot your password?", new_password_path(resource_name), class: 'text-decoration-none'
br/
- if devise_mapping.confirmable? && controller_name != 'confirmations'
= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name), class: 'text-decoration-none'
br/
- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks'
= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name), class: 'text-decoration-none'
br/
- if devise_mapping.omniauthable?
- resource_class.omniauth_providers.each do |provider|
= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), method: :post, class: 'text-decoration-none'
br/
- content_for :head do
= stylesheet_link_tag 'users'
.container
.main-body
/! Breadcrumb
nav.main-breadcrumb aria-label="breadcrumb"
ol.breadcrumb
li.breadcrumb-item
= link_to 'Home', root_path
li.breadcrumb-item
= link_to 'User', '#'
li.breadcrumb-item.active aria-current="page" User Profile
/! /Breadcrumb
.row.gutters-sm
.col-md-4.mb-3
.card
.card-body
.d-flex.flex-column.align-items-center.text-center
= gravatar_for @user
/ img.rounded-circle alt="Admin" src="https://bootdey.com/img/Content/avatar/avatar7.png" width="150" /
.mt-3
h4
= @user.name
p.text-secondary.mb-1 Full Stack Developer
p.text-muted.font-size-sm
= @user.address
button.btn.btn-primary Follow
button.btn.btn-outline-primary Message
.card.mt-3
ul.list-group.list-group-flush
li.list-group-item.d-flex.justify-content-between.align-items-center.flex-wrap
h6.mb-0
svg.feather.feather-globe.mr-2.icon-inline fill="none" height="24" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewbox=("0 0 24 24") width="24" xmlns="http://www.w3.org/2000/svg"
circle cx="12" cy="12" r="10"
line x1="2" x2="22" y1="12" y2="12"
path d=("M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z")
| Website
span.text-secondary none
li.list-group-item.d-flex.justify-content-between.align-items-center.flex-wrap
h6.mb-0
svg.feather.feather-github.mr-2.icon-inline fill="none" height="24" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewbox=("0 0 24 24") width="24" xmlns="http://www.w3.org/2000/svg"
path d=("M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22")
| Github
span.text-secondary none
li.list-group-item.d-flex.justify-content-between.align-items-center.flex-wrap
h6.mb-0
svg.feather.feather-twitter.mr-2.icon-inline.text-info fill="none" height="24" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewbox=("0 0 24 24") width="24" xmlns="http://www.w3.org/2000/svg"
path d=("M23 3a10.9 10.9 0 0 1-3.14 1.53 4.48 4.48 0 0 0-7.86 3v1A10.66 10.66 0 0 1 3 4s-4 9 5 13a11.64 11.64 0 0 1-7 2c9 5 20 0 20-11.5a4.5 4.5 0 0 0-.08-.83A7.72 7.72 0 0 0 23 3z")
| Twitter
span.text-secondary none
li.list-group-item.d-flex.justify-content-between.align-items-center.flex-wrap
h6.mb-0
svg.feather.feather-instagram.mr-2.icon-inline.text-danger fill="none" height="24" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewbox=("0 0 24 24") width="24" xmlns="http://www.w3.org/2000/svg"
rect height="20" rx="5" ry="5" width="20" x="2" y="2"
path d=("M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z")
line x1="17.5" x2="17.51" y1="6.5" y2="6.5"
| Instagram
span.text-secondary none
li.list-group-item.d-flex.justify-content-between.align-items-center.flex-wrap
h6.mb-0
svg.feather.feather-facebook.mr-2.icon-inline.text-primary fill="none" height="24" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewbox=("0 0 24 24") width="24" xmlns="http://www.w3.org/2000/svg"
path d=("M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z")
| Facebook
span.text-secondary none
.col-md-8
.card.mb-3
.card-body
.row
.col-sm-3
h6.mb-0 Full Name
.col-sm-9.text-secondary
= @user.name
hr/
.row
.col-sm-3
h6.mb-0 Email
.col-sm-9.text-secondary
= @user.email
hr/
.row
.col-sm-3
h6.mb-0 Phone
.col-sm-9.text-secondary
= @user.phone
hr/
.row
.col-sm-3
h6.mb-0 Address
.col-sm-9.text-secondary
= @user.address
hr/
.row
.col-sm-12
= link_to 'Edit profile', edit_user_registration_path, class:'btn btn-info'
.row.gutters-sm
.col-sm-6.mb-3
.card.h-100
.card-body
h6.d-flex.align-items-center.mb-3
i.material-icons.text-info.mr-2> assignment
span.d-block.m-auto
| Project Status
small Skill
.progress.mb-3 style=("height: 5px")
.progress-bar.bg-primary aria-valuemax="100" aria-valuemin="0" aria-valuenow="80" role="progressbar" style=("width: 80%")
small Skill
.progress.mb-3 style=("height: 5px")
.progress-bar.bg-primary aria-valuemax="100" aria-valuemin="0" aria-valuenow="72" role="progressbar" style=("width: 72%")
small Skill
.progress.mb-3 style=("height: 5px")
.progress-bar.bg-primary aria-valuemax="100" aria-valuemin="0" aria-valuenow="89" role="progressbar" style=("width: 89%")
small Skill
.progress.mb-3 style=("height: 5px")
.progress-bar.bg-primary aria-valuemax="100" aria-valuemin="0" aria-valuenow="55" role="progressbar" style=("width: 55%")
small Skill
.progress.mb-3 style=("height: 5px")
.progress-bar.bg-primary aria-valuemax="100" aria-valuemin="0" aria-valuenow="66" role="progressbar" style=("width: 66%")
.col-sm-6.mb-3
.card.h-100
.card-body
h6.d-flex.align-items-center.mb-3
i.material-icons.text-info.mr-2> assignment
span.d-block.m-auto
| Project Status
small Skill
.progress.mb-3 style=("height: 5px")
.progress-bar.bg-primary aria-valuemax="100" aria-valuemin="0" aria-valuenow="80" role="progressbar" style=("width: 80%")
small Skill
.progress.mb-3 style=("height: 5px")
.progress-bar.bg-primary aria-valuemax="100" aria-valuemin="0" aria-valuenow="72" role="progressbar" style=("width: 72%")
small Skill
.progress.mb-3 style=("height: 5px")
.progress-bar.bg-primary aria-valuemax="100" aria-valuemin="0" aria-valuenow="89" role="progressbar" style=("width: 89%")
small Skill
.progress.mb-3 style=("height: 5px")
.progress-bar.bg-primary aria-valuemax="100" aria-valuemin="0" aria-valuenow="55" role="progressbar" style=("width: 55%")
small Skill
.progress.mb-3 style=("height: 5px")
.progress-bar.bg-primary aria-valuemax="100" aria-valuemin="0" aria-valuenow="66" role="progressbar" style=("width: 66%")
<h2>Resend unlock instructions</h2>
<%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %>
<%= render "users/shared/error_messages", resource: resource %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
</div>
<div class="actions">
<%= f.submit "Resend unlock instructions" %>
</div>
<% end %>
<%= render "users/shared/links" %>
# Additional translations at https://github.com/heartcombo/devise/wiki/I18n
en:
devise:
confirmations:
confirmed: "Your email address has been successfully confirmed."
send_instructions: "You will receive an email with instructions for how to confirm your email address in a few minutes."
send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions for how to confirm your email address in a few minutes."
failure:
already_authenticated: "You are already signed in."
inactive: "Your account is not activated yet."
invalid: "Invalid %{authentication_keys} or password."
locked: "Your account is locked."
last_attempt: "You have one more attempt before your account is locked."
not_found_in_database: "Invalid %{authentication_keys} or password."
timeout: "Your session expired. Please sign in again to continue."
unauthenticated: "You need to sign in or sign up before continuing."
unconfirmed: "You have to confirm your email address before continuing."
mailer:
confirmation_instructions:
subject: "Confirmation instructions"
reset_password_instructions:
subject: "Reset password instructions"
unlock_instructions:
subject: "Unlock instructions"
email_changed:
subject: "Email Changed"
password_change:
subject: "Password Changed"
omniauth_callbacks:
failure: "Could not authenticate you from %{kind} because \"%{reason}\"."
success: "Successfully authenticated from %{kind} account."
passwords:
no_token: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided."
send_instructions: "You will receive an email with instructions on how to reset your password in a few minutes."
send_paranoid_instructions: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes."
updated: "Your password has been changed successfully. You are now signed in."
updated_not_active: "Your password has been changed successfully."
registrations:
destroyed: "Bye! Your account has been successfully cancelled. We hope to see you again soon."
signed_up: "Welcome! You have signed up successfully."
signed_up_but_inactive: "You have signed up successfully. However, we could not sign you in because your account is not yet activated."
signed_up_but_locked: "You have signed up successfully. However, we could not sign you in because your account is locked."
signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please follow the link to activate your account."
update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and follow the confirmation link to confirm your new email address."
updated: "Your account has been updated successfully."
updated_but_not_signed_in: "Your account has been updated successfully, but since your password was changed, you need to sign in again."
sessions:
signed_in: "Signed in successfully."
signed_out: "Signed out successfully."
already_signed_out: "Signed out successfully."
unlocks:
send_instructions: "You will receive an email with instructions for how to unlock your account in a few minutes."
send_paranoid_instructions: "If your account exists, you will receive an email with instructions for how to unlock it in a few minutes."
unlocked: "Your account has been unlocked successfully. Please sign in to continue."
errors:
messages:
already_confirmed: "was already confirmed, please try signing in"
confirmation_period_expired: "needs to be confirmed within %{period}, please request a new one"
expired: "has expired, please request a new one"
not_found: "not found"
not_locked: "was not locked"
not_saved:
one: "1 error prohibited this %{resource} from being saved:"
other: "%{count} errors prohibited this %{resource} from being saved:"
Rails.application.routes.draw do
devise_for :users
root 'top#index'
resources :cities, param: :slug, only: %i[index show] do
......@@ -9,6 +10,8 @@ Rails.application.routes.draw do
end
resources :jobs, only: %i[index show]
resources :users, only: %i[index show]
get '/apply', to: 'applies#new'
post '/confirm', to: 'applies#confirm'
......
......@@ -15,6 +15,5 @@ class CreateUsers < ActiveRecord::Migration[6.1]
t.timestamps
end
add_index :users, :email, unique: true
add_index :users, :password_reset_digest, unique: true
end
end
class RemoveFieldFromUsers < ActiveRecord::Migration[6.1]
def change
remove_column :users, :password_digest, :string
remove_column :users, :remember_digest, :string
remove_column :users, :admin, :boolean
remove_column :users, :activation_digest, :string
remove_column :users, :activated, :boolean
remove_column :users, :activated_at, :datetime
remove_column :users, :password_reset_digest, :string
remove_column :users, :password_reset_sent_at, :datetime
end
end
# frozen_string_literal: true
class AddDeviseToUsers < ActiveRecord::Migration[6.1]
def self.up
change_table :users do |t|
## Database authenticatable
# t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
# t.integer :sign_in_count, default: 0, null: false
# t.datetime :current_sign_in_at
# t.datetime :last_sign_in_at
# t.string :current_sign_in_ip
# t.string :last_sign_in_ip
## Confirmable
# t.string :confirmation_token
# t.datetime :confirmed_at
# t.datetime :confirmation_sent_at
# t.string :unconfirmed_email # Only if using reconfirmable
## Lockable
# t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
# t.string :unlock_token # Only if unlock strategy is :email or :both
# t.datetime :locked_at
# Uncomment below if timestamps were not included in your original model.
# t.timestamps null: false
end
# add_index :users, :email, unique: true
add_index :users, :reset_password_token, unique: true
# add_index :users, :confirmation_token, unique: true
# add_index :users, :unlock_token, unique: true
end
def self.down
# By default, we don't want to make any assumption about how to roll back a migration when your
# model already existed. Please edit below which fields you would like to remove in this migration.
raise ActiveRecord::IrreversibleMigration
end
end
class AddInfoToUser < ActiveRecord::Migration[6.1]
def change
add_column :users, :phone, :string
add_column :users, :address, :string
end
end
......@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2021_07_29_140527) do
ActiveRecord::Schema.define(version: 2021_08_05_105601) do
create_table "active_storage_attachments", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.string "name", null: false
......@@ -130,18 +130,16 @@ ActiveRecord::Schema.define(version: 2021_07_29_140527) do
create_table "users", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.string "name"
t.string "email", null: false
t.string "password_digest"
t.string "remember_digest"
t.boolean "admin", default: false
t.string "activation_digest"
t.boolean "activated", default: false
t.datetime "activated_at"
t.string "password_reset_digest"
t.datetime "password_reset_sent_at"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.string "phone"
t.string "address"
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["password_reset_digest"], name: "index_users_on_password_reset_digest", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
......
require "test_helper"
class UsersControllerTest < ActionDispatch::IntegrationTest
# test "the truth" do
# assert true
# end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment