diff --git a/.rubocop.yml b/.rubocop.yml index f82c994..e5d612a 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -47,3 +47,7 @@ Naming/HeredocDelimiterNaming: Exclude: - 'spec/features/cli_help_spec.rb' - 'spec/features/git_and_git_flow_spec.rb' + +Style/ClassAndModuleChildren: + Exclude: + - 'templates/app_files/app/controllers/**/*.rb' \ No newline at end of file diff --git a/lib/cybele.rb b/lib/cybele.rb index acad501..1d1f45e 100644 --- a/lib/cybele.rb +++ b/lib/cybele.rb @@ -23,6 +23,7 @@ require 'cybele/helpers/app_files/assets_files' require 'cybele/helpers/app_files/controller_files' require 'cybele/helpers/app_files/model_files' +require 'cybele/helpers/app_files/vendor_files' require 'cybele/helpers/app_files/mailer_files' require 'cybele/helpers/app_files/helper_files' require 'cybele/helpers/app_files/view_files' diff --git a/lib/cybele/app_builder.rb b/lib/cybele/app_builder.rb index ca6c3a3..dd8bcbb 100644 --- a/lib/cybele/app_builder.rb +++ b/lib/cybele/app_builder.rb @@ -22,6 +22,7 @@ class AppBuilder < Rails::AppBuilder # rubocop:disable Metrics/ClassLength include Cybele::Helpers::AppFiles::AssetsFiles include Cybele::Helpers::AppFiles::ControllerFiles include Cybele::Helpers::AppFiles::ModelFiles + include Cybele::Helpers::AppFiles::VendorFiles include Cybele::Helpers::AppFiles::MailerFiles include Cybele::Helpers::AppFiles::HelperFiles include Cybele::Helpers::AppFiles::ViewFiles diff --git a/lib/cybele/helpers/app_files/assets_files.rb b/lib/cybele/helpers/app_files/assets_files.rb index d532996..aa9ca55 100644 --- a/lib/cybele/helpers/app_files/assets_files.rb +++ b/lib/cybele/helpers/app_files/assets_files.rb @@ -5,6 +5,11 @@ module Helpers module AppFiles module AssetsFiles def customize_assets_files + javascript_files + stylesheet_files + end + + def javascript_files # Javascript Assets files remove_file 'app/assets/javascripts/application.js', force: true @@ -15,7 +20,9 @@ def customize_assets_files template 'app_files/app/assets/javascripts/hq/application.js', 'app/assets/javascripts/hq/application.js', force: true + end + def stylesheet_files # Css Assets files remove_file 'app/assets/stylesheets/application.css', force: true @@ -26,6 +33,9 @@ def customize_assets_files template 'app_files/app/assets/stylesheets/hq/application.css.sass', 'app/assets/stylesheets/hq/application.css.sass', force: true + + copy_file 'app_files/app/assets/stylesheets/hq/_sidebar.css.sass', + 'app/assets/stylesheets/hq/_sidebar.css.sass' end end end diff --git a/lib/cybele/helpers/app_files/controller_files.rb b/lib/cybele/helpers/app_files/controller_files.rb index b65f970..b131e79 100644 --- a/lib/cybele/helpers/app_files/controller_files.rb +++ b/lib/cybele/helpers/app_files/controller_files.rb @@ -5,9 +5,12 @@ module Helpers module AppFiles module ControllerFiles def customize_controller_files - # HQ controller files + # Hq controller files directory 'app_files/app/controllers/hq', 'app/controllers/hq' + # User controller files + directory 'app_files/app/controllers/user', 'app/controllers/user' + # Welcome controller copy_file 'app_files/app/controllers/welcome_controller.rb', 'app/controllers/welcome_controller.rb' end diff --git a/lib/cybele/helpers/app_files/model_files.rb b/lib/cybele/helpers/app_files/model_files.rb index 4c5c63f..e392f4a 100644 --- a/lib/cybele/helpers/app_files/model_files.rb +++ b/lib/cybele/helpers/app_files/model_files.rb @@ -7,6 +7,7 @@ module ModelFiles def customize_model_files # Model files remove_file 'app/models/admin.rb', force: true + remove_file 'app/models/user.rb', force: true directory 'app_files/app/models', 'app/models' end end diff --git a/lib/cybele/helpers/app_files/vendor_files.rb b/lib/cybele/helpers/app_files/vendor_files.rb index a693696..d1205e2 100644 --- a/lib/cybele/helpers/app_files/vendor_files.rb +++ b/lib/cybele/helpers/app_files/vendor_files.rb @@ -5,8 +5,8 @@ module Helpers module AppFiles module VendorFiles def customize_vendor_files - # View files with option - directory 'app_files/app/vendor', 'app/vendor' + # javascript and stylesheet files in vendor + directory 'app_files/app/vendor/assets', 'vendor/assets' end end end diff --git a/lib/cybele/helpers/app_files/view_files.rb b/lib/cybele/helpers/app_files/view_files.rb index 4607609..d96b6bc 100644 --- a/lib/cybele/helpers/app_files/view_files.rb +++ b/lib/cybele/helpers/app_files/view_files.rb @@ -7,16 +7,39 @@ module ViewFiles def customize_view_files_with_option # View files with option directory 'app_files/app/views/hq', 'app/views/hq' + directory 'app_files/app/views/user', 'app/views/user' directory 'app_files/app/views/layouts/hq', 'app/views/layouts/hq' directory 'app_files/app/views/layouts/partials', 'app/views/layouts/partials' directory 'app_files/app/views/welcome', 'app/views/welcome' - template 'app_files/app/views/layouts/application.html.haml.erb', - 'app/views/layouts/application.html.haml', force: true + replace_erb_with_haml end def customize_default_view_files # Default view files directory 'app_files/app/views/admin_mailer', 'app/views/admin_mailer' + directory 'app_files/app/views/user_mailer', 'app/views/user_mailer' + end + + def replace_erb_with_haml + remove_file 'app/views/welcome/index.html.erb', force: true + template 'app_files/app/views/welcome/index.html.erb', + 'app/views/welcome/index.html.haml', force: true + + remove_file 'app/views/layouts/mailer.html.erb', force: true + template 'app_files/app/views/layouts/mailer.html.erb', + 'app/views/layouts/mailer.html.haml', force: true + + remove_file 'app/views/layouts/application.html.erb', force: true + template 'app_files/app/views/layouts/application.html.erb', + 'app/views/layouts/application.html.haml', force: true + + remove_file 'app/views/layouts/partials/_navbar.html.erb', force: true + template 'app_files/app/views/layouts/partials/_navbar.html.erb', + 'app/views/layouts/partials/_navbar.html.haml', force: true + + remove_file 'app/views/layouts/hq/application.html.erb', force: true + template 'app_files/app/views/layouts/hq/application.html.erb', + 'app/views/layouts/hq/application.html.haml', force: true end end end diff --git a/lib/cybele/helpers/devise.rb b/lib/cybele/helpers/devise.rb index 535b9d0..206a078 100644 --- a/lib/cybele/helpers/devise.rb +++ b/lib/cybele/helpers/devise.rb @@ -18,6 +18,8 @@ def generate_devise_models generate 'devise User name:string surname:string is_active:boolean time_zone:string' generate 'devise Admin name:string surname:string is_active:boolean time_zone:string' remove_file 'config/locales/devise.en.yml', force: true + copy_file 'config/locales/devise.en.yml', 'config/locales/devise.en.yml' + copy_file 'config/locales/devise.tr.yml', 'config/locales/devise.tr.yml' end def generate_devise_views diff --git a/lib/cybele/helpers/routes.rb b/lib/cybele/helpers/routes.rb index 47ab897..e7a49ca 100644 --- a/lib/cybele/helpers/routes.rb +++ b/lib/cybele/helpers/routes.rb @@ -9,9 +9,13 @@ def configure_routes 'devise_for :admins', '' + # User routes + replace_in_file 'config/routes.rb', + 'devise_for :users', + '' + inject_into_file 'config/routes.rb', template_content('config/routes.rb.erb'), before: 'if Rails.env.production? || Rails.env.staging?' - end end end diff --git a/lib/cybele/helpers/sidekiq.rb b/lib/cybele/helpers/sidekiq.rb index 63cd576..73ee8d7 100644 --- a/lib/cybele/helpers/sidekiq.rb +++ b/lib/cybele/helpers/sidekiq.rb @@ -38,6 +38,10 @@ def create_sidekiq_files template 'sidekiq/sidekiq_schedule.yml.erb', 'config/sidekiq_schedule.yml', force: true + # Proc file + template 'sidekiq/sidekiq_Procfile.erb', + 'Procfile', + force: true end end end diff --git a/spec/features/new_default_project_spec.rb b/spec/features/new_default_project_spec.rb index c42ce2a..699c267 100644 --- a/spec/features/new_default_project_spec.rb +++ b/spec/features/new_default_project_spec.rb @@ -241,34 +241,55 @@ expect(application_controller).to match('class ApplicationController') expect(application_controller).to match('configure_devise_permitted_parameters') + # Hq files hq_admins_controller = content('app/controllers/hq/admins_controller.rb') - expect(hq_admins_controller).to match('class AdminsController') + expect(hq_admins_controller).to match('class Hq::AdminsController') hq_application_controller = content('app/controllers/hq/application_controller.rb') - expect(hq_application_controller).to match('class ApplicationController') + expect(hq_application_controller).to match('class Hq::ApplicationController') expect(hq_application_controller).to match('before_action :authenticate_admin!') hq_audits_controller = content('app/controllers/hq/audits_controller.rb') - expect(hq_audits_controller).to match('class AuditsController') + expect(hq_audits_controller).to match('class Hq::AuditsController') hq_dashboard_controller = content('app/controllers/hq/dashboard_controller.rb') - expect(hq_dashboard_controller).to match('class DashboardController') + expect(hq_dashboard_controller).to match('class Hq::DashboardController') hq_passwords_controller = content('app/controllers/hq/passwords_controller.rb') - expect(hq_passwords_controller).to match('class PasswordsController') + expect(hq_passwords_controller).to match('class Hq::PasswordsController') hq_registrations_controller = content('app/controllers/hq/registrations_controller.rb') - expect(hq_registrations_controller).to match('class RegistrationsController') + expect(hq_registrations_controller).to match('class Hq::RegistrationsController') hq_sessions_controller = content('app/controllers/hq/sessions_controller.rb') - expect(hq_sessions_controller).to match('class SessionsController') + expect(hq_sessions_controller).to match('class Hq::SessionsController') hq_users_controller = content('app/controllers/hq/users_controller.rb') - expect(hq_users_controller).to match('class UsersController') + expect(hq_users_controller).to match('class Hq::UsersController') + + # User files + user_application_controller = content('app/controllers/user/application_controller.rb') + expect(user_application_controller).to match('class User::ApplicationController') + expect(user_application_controller).to match('before_action :authenticate_user!') + + user_dashboard_controller = content('app/controllers/user/dashboard_controller.rb') + expect(user_dashboard_controller).to match('class User::DashboardController') + + user_passwords_controller = content('app/controllers/user/passwords_controller.rb') + expect(user_passwords_controller).to match('class User::PasswordsController') + + user_profile_controller = content('app/controllers/user/profile_controller.rb') + expect(user_profile_controller).to match('class User::ProfileController') + + user_registrations_controller = content('app/controllers/user/registrations_controller.rb') + expect(user_registrations_controller).to match('class User::RegistrationsController') + + user_sessions_controller = content('app/controllers/user/sessions_controller.rb') + expect(user_sessions_controller).to match('class User::SessionsController') end it 'uses view files with option' do - # HQ files + # Hq files hq_admins_view = content('app/views/hq/admins/index.html.haml') expect(hq_admins_view).to match('@admins') @@ -290,6 +311,22 @@ hq_users_view = content('app/views/hq/users/index.html.haml') expect(hq_users_view).to match('@users') + # User files + user_dashboard_view = content('app/views/user/dashboard/index.html.haml') + expect(user_dashboard_view).to match('current_user.email') + + user_passwords_view = content('app/views/user/passwords/new.html.haml') + expect(user_passwords_view).to match('password_path') + + user_registrations_view = content('app/views/user/registrations/edit.html.haml') + expect(user_registrations_view).to match('user_registration_path') + + user_sessions_view = content('app/views/user/sessions/new.html.haml') + expect(user_sessions_view).to match('session_path') + + user_profile_view = content('app/views/user/profile/show.html.haml') + expect(user_profile_view).to match('@profile') + # Layouts expect(File).to exist(file_project_path('app/views/layouts/hq/partials/_dock.html.haml')) expect(File).to exist(file_project_path('app/views/layouts/hq/partials/_breadcrumb.html.haml')) diff --git a/spec/features/new_not_default_project_spec.rb b/spec/features/new_not_default_project_spec.rb index db2b262..3ced797 100644 --- a/spec/features/new_not_default_project_spec.rb +++ b/spec/features/new_not_default_project_spec.rb @@ -211,6 +211,8 @@ it 'do not use controller files' do expect(File).to exist(file_project_path('app/controllers/application_controller.rb')) + + # Hq files expect(File).not_to exist(file_project_path('app/controllers/hq/admins_controller.rb')) expect(File).not_to exist(file_project_path('app/controllers/hq/application_controller.rb')) expect(File).not_to exist(file_project_path('app/controllers/hq/audits_controller.rb')) @@ -219,10 +221,18 @@ expect(File).not_to exist(file_project_path('app/controllers/hq/registrations_controller.rb')) expect(File).not_to exist(file_project_path('app/controllers/hq/sessions_controller.rb')) expect(File).not_to exist(file_project_path('app/controllers/hq/users_controller.rb')) + + # User files + expect(File).not_to exist(file_project_path('app/controllers/user/application_controller.rb')) + expect(File).not_to exist(file_project_path('app/controllers/user/dashboard_controller.rb')) + expect(File).not_to exist(file_project_path('app/controllers/user/passwords_controller.rb')) + expect(File).not_to exist(file_project_path('app/controllers/user/registrations_controller.rb')) + expect(File).not_to exist(file_project_path('app/controllers/user/sessions_controller.rb')) + expect(File).not_to exist(file_project_path('app/controllers/user/profile_controller.rb')) end it 'do not use view files with option' do - # HQ files + # Hq files expect(File).not_to exist(file_project_path('app/views/hq/admins/index.html.haml')) expect(File).not_to exist(file_project_path('app/views/hq/audits/index.html.haml')) expect(File).not_to exist(file_project_path('app/views/hq/dashboard/index.html.haml')) @@ -231,6 +241,13 @@ expect(File).not_to exist(file_project_path('app/views/hq/sessions/new.html.haml')) expect(File).not_to exist(file_project_path('app/views/hq/users/index.html.haml')) + # User files + expect(File).not_to exist(file_project_path('app/views/user/dashboard/index.html.haml')) + expect(File).not_to exist(file_project_path('app/views/user/passwords/new.html.haml')) + expect(File).not_to exist(file_project_path('app/views/user/registrations/edit.html.haml')) + expect(File).not_to exist(file_project_path('app/views/user/sessions/new.html.haml')) + expect(File).not_to exist(file_project_path('app/views/user/profile/show.html.haml')) + # Layouts expect(File).not_to exist(file_project_path('app/views/layouts/hq/partials/_breadcrumb.html.haml')) expect(File).not_to exist(file_project_path('app/views/layouts/hq/partials/_dock.html.haml')) diff --git a/spec/support/devise_test_helper.rb b/spec/support/devise_test_helper.rb index f71ab99..98a5a72 100644 --- a/spec/support/devise_test_helper.rb +++ b/spec/support/devise_test_helper.rb @@ -39,6 +39,7 @@ def devise_model_file_test # rubocop:disable Metrics/AbcSize end def file_control_test - expect(File).not_to exist(file_project_path('config/locales/devise.en.yml')) + expect(File).to exist(file_project_path('config/locales/devise.en.yml')) + expect(File).to exist(file_project_path('config/locales/devise.tr.yml')) end end diff --git a/templates/app_files/app/assets/javascripts/application.js b/templates/app_files/app/assets/javascripts/application.js index a89a2f5..56a40cb 100644 --- a/templates/app_files/app/assets/javascripts/application.js +++ b/templates/app_files/app/assets/javascripts/application.js @@ -10,7 +10,67 @@ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details // about supported directives. // +//= require popper +//= require jquery //= require rails-ujs //= require turbolinks //= require bootstrap +//= require footable.min +//= require jquery.maskedinput.min +//= require trix +//= require jquery.datetimepicker +//= require nprogress //= require_tree . + +var ready = function(){ + $('.table').footable(); + + $('.datetimepicker').datetimepicker({ + format: $('.datetimepicker').data('format'), + step: 60, + lang: 'tr', + minDate: 0, + defaultTime: '12:00' + }); + + $(function () { + $('[data-toggle="tooltip"]').tooltip() + }); + + $("[data-mask]").each(function(index, element) { + var $element; + $element = $(element); + $element.mask($element.data('mask')); + }); + $('form[data-turboform]').on('submit', function(e) { + Turbolinks.visit(this.action + (this.action.indexOf('?') === -1 ? '?' : '&') + $(this).serialize()); + return false; + }); +}; + +$(document).on('page:load', ready); + +document.addEventListener("turbolinks:load", ready) + +$(window).on('page:load', ready); + +$(document).on('page:fetch', function() { + NProgress.start(); +}); + +$(document).on('page:change', function() { + NProgress.done(); +}); + +$(document).on('page:restore', function() { + NProgress.remove(); +}); + +$(document).ajaxStart(function() { + NProgress.start(); +}); + +$(document).ajaxComplete(function() { + NProgress.done(); +}); + diff --git a/templates/app_files/app/assets/javascripts/hq/application.js b/templates/app_files/app/assets/javascripts/hq/application.js index d3f303f..aa85c96 100644 --- a/templates/app_files/app/assets/javascripts/hq/application.js +++ b/templates/app_files/app/assets/javascripts/hq/application.js @@ -12,7 +12,7 @@ // //= require popper //= require jquery -//= require jquery_ujs +//= require rails-ujs //= require turbolinks //= require bootstrap //= require footable.min @@ -21,26 +21,6 @@ //= require jquery.datetimepicker //= require nprogress -this.App = (function() { - function App() {} - - App.ready = function() { - $('.changeable_select').on('change', function() { - var $hiden_area, values; - $hiden_area = $($('#hider-id').data('hiden-area')); - values = $('#hider-id').data('hiden-on').split(','); - if ($.inArray($(this).val(), values) !== -1) { - $hiden_area.addClass('hidden'); - } else { - $hiden_area.removeClass('hidden'); - } - }); - }; - - return App; - -})(); - var ready = function(){ App.ready(); diff --git a/templates/app_files/app/controllers/hq/admins_controller.rb b/templates/app_files/app/controllers/hq/admins_controller.rb index 378a828..cf78d55 100644 --- a/templates/app_files/app/controllers/hq/admins_controller.rb +++ b/templates/app_files/app/controllers/hq/admins_controller.rb @@ -1,66 +1,64 @@ # frozen_string_literal: true -module Hq - class AdminsController < ApplicationController - before_action :set_admin, only: %i[show edit update destroy toggle_is_active] - add_breadcrumb I18n.t('activerecord.models.admins'), :hq_admins_path +class Hq::AdminsController < Hq::ApplicationController + before_action :set_admin, only: %i[show edit update destroy toggle_is_active] + add_breadcrumb I18n.t('activerecord.models.admins'), :hq_admins_path - def index - @search = Admin.order(id: :desc).search(params[:q]) - @admins = @search.result(distinct: true).paginate(page: params[:page]) - respond_with(@admins) - end + def index + @search = Admin.order(id: :desc).search(params[:q]) + @admins = @search.result(distinct: true).paginate(page: params[:page]) + respond_with(@admins) + end - def show - add_breadcrumb @admin.name, hq_admin_path(@admin) - respond_with(@admin) - end + def show + add_breadcrumb @admin.name, hq_admin_path(@admin) + respond_with(@admin) + end - def new - add_breadcrumb t('view.tooltips.new'), new_hq_admin_path - @admin = Admin.new - respond_with(@admin) - end + def new + add_breadcrumb t('view.tooltips.new'), new_hq_admin_path + @admin = Admin.new + respond_with(@admin) + end - def edit - add_breadcrumb @admin.name, hq_admin_path(@admin) - add_breadcrumb t('view.tooltips.edit'), edit_hq_admin_path - end + def edit + add_breadcrumb @admin.name, hq_admin_path(@admin) + add_breadcrumb t('view.tooltips.edit'), edit_hq_admin_path + end - def create - @admin = Admin.new(admin_params) - @admin.save - respond_with(:hq, @admin) - end + def create + @admin = Admin.new(admin_params) + @admin.save + respond_with(:hq, @admin) + end - def update - @admin.update(admin_params) - respond_with(:hq, @admin) - end + def update + @admin.update(admin_params) + respond_with(:hq, @admin) + end - def destroy - @admin.destroy - respond_with(:hq, @admin, location: request.referer) - end + def destroy + @admin.destroy + respond_with(:hq, @admin, location: request.referer) + end - def toggle_is_active - if @admin.update(is_active: !@admin.is_active) - flash[:info] = t("flash.actions.toggle_is_active.#{@admin.is_active ? 'active' : 'passive'}", - resource_name: Admin.model_name.human) - else - flash[:danger] = t('flash.messages.error_occurred') - end - respond_with(:hq, @admin, location: request.referer) + def toggle_is_active + if @admin.update(is_active: !@admin.is_active) + flash[:info] = t("flash.actions.toggle_is_active.#{@admin.is_active ? 'active' : 'passive'}", + resource_name: Admin.model_name.human) + else + flash[:danger] = t('flash.messages.error_occurred') end + respond_with(:hq, @admin, location: request.referer) + end - private + private - def set_admin - @admin = Admin.find(params[:id]) - end + def set_admin + @admin = Admin.find(params[:id]) + end - def admin_params - params.require(:admin).permit(:email, :name, :surname) - end + def admin_params + params.require(:admin).permit(:email, :name, :surname) end end diff --git a/templates/app_files/app/controllers/hq/application_controller.rb b/templates/app_files/app/controllers/hq/application_controller.rb index 037a387..10f6df1 100644 --- a/templates/app_files/app/controllers/hq/application_controller.rb +++ b/templates/app_files/app/controllers/hq/application_controller.rb @@ -1,15 +1,13 @@ # frozen_string_literal: true -module Hq - class ApplicationController < ::ApplicationController - before_action :authenticate_admin! - before_action :set_audit_user - layout 'hq/application' +class Hq::ApplicationController < ApplicationController + before_action :authenticate_admin! + before_action :set_audit_user + layout 'hq/application' - private + private - def set_audit_user - Audited.current_user_method = :current_admin - end + def set_audit_user + Audited.current_user_method = :current_admin end end diff --git a/templates/app_files/app/controllers/hq/audits_controller.rb b/templates/app_files/app/controllers/hq/audits_controller.rb index 344fd31..0fe0e21 100644 --- a/templates/app_files/app/controllers/hq/audits_controller.rb +++ b/templates/app_files/app/controllers/hq/audits_controller.rb @@ -1,18 +1,16 @@ # frozen_string_literal: true -module Hq - class AuditsController < ApplicationController - add_breadcrumb I18n.t('activerecord.models.audits'), :hq_audits_path +class Hq::AuditsController < Hq::ApplicationController + add_breadcrumb I18n.t('activerecord.models.audits'), :hq_audits_path - def index - @search = Audit.includes(:user).reorder('id DESC').search(params[:q]) - @audits = @search.result(distinct: true).paginate(page: params[:page]) - @auditable_types = Audit.select('auditable_type').group('auditable_type').reorder('') - end + def index + @search = Audit.includes(:user).reorder('id DESC').search(params[:q]) + @audits = @search.result(distinct: true).paginate(page: params[:page]) + @auditable_types = Audit.select('auditable_type').group('auditable_type').reorder('') + end - def show - @audit = Audit.find(params[:id]) - add_breadcrumb @audit.id, hq_audit_path(id: @audit) - end + def show + @audit = Audit.find(params[:id]) + add_breadcrumb @audit.id, hq_audit_path(id: @audit) end end diff --git a/templates/app_files/app/controllers/hq/dashboard_controller.rb b/templates/app_files/app/controllers/hq/dashboard_controller.rb index ea60ab1..7f01cd5 100644 --- a/templates/app_files/app/controllers/hq/dashboard_controller.rb +++ b/templates/app_files/app/controllers/hq/dashboard_controller.rb @@ -1,9 +1,7 @@ # frozen_string_literal: true -module Hq - class DashboardController < ApplicationController - add_breadcrumb I18n.t('view.dock.dashboard'), :hq_dashboard_index_path +class Hq::DashboardController < Hq::ApplicationController + add_breadcrumb I18n.t('view.dock.dashboard'), :hq_dashboard_index_path - def index; end - end + def index; end end diff --git a/templates/app_files/app/controllers/hq/passwords_controller.rb b/templates/app_files/app/controllers/hq/passwords_controller.rb index 61366a1..868aa90 100644 --- a/templates/app_files/app/controllers/hq/passwords_controller.rb +++ b/templates/app_files/app/controllers/hq/passwords_controller.rb @@ -1,13 +1,11 @@ # frozen_string_literal: true -module Hq - class PasswordsController < Devise::PasswordsController - layout 'hq/login' +class Hq::PasswordsController < Devise::PasswordsController + layout 'hq/login' - private + private - def after_resetting_password_path_for - hq_root_path - end + def after_resetting_password_path_for + hq_root_path end end diff --git a/templates/app_files/app/controllers/hq/registrations_controller.rb b/templates/app_files/app/controllers/hq/registrations_controller.rb index 8a055de..27ed22c 100644 --- a/templates/app_files/app/controllers/hq/registrations_controller.rb +++ b/templates/app_files/app/controllers/hq/registrations_controller.rb @@ -1,24 +1,22 @@ # frozen_string_literal: true -module Hq - class RegistrationsController < Devise::RegistrationsController - layout 'hq/application' - before_action :authenticate_admin! - before_action :redirect_admin, only: %i[new create destroy] - add_breadcrumb I18n.t('view.dock.dashboard'), :hq_dashboard_index_path +class Hq::RegistrationsController < Devise::RegistrationsController + layout 'hq/application' + before_action :authenticate_admin! + before_action :redirect_admin, only: %i[new create destroy] + add_breadcrumb I18n.t('view.dock.dashboard'), :hq_dashboard_index_path - def edit - add_breadcrumb I18n.t('view.title.edit', resource_name: Admin.model_name.human) - end + def edit + add_breadcrumb I18n.t('view.title.edit', resource_name: Admin.model_name.human) + end - private + private - def redirect_admin - redirect_to hq_root_path - end + def redirect_admin + redirect_to hq_root_path + end - def after_update_path_for - hq_root_path - end + def after_update_path_for(_resource) + hq_root_path end end diff --git a/templates/app_files/app/controllers/hq/sessions_controller.rb b/templates/app_files/app/controllers/hq/sessions_controller.rb index 61777e4..f388baa 100644 --- a/templates/app_files/app/controllers/hq/sessions_controller.rb +++ b/templates/app_files/app/controllers/hq/sessions_controller.rb @@ -1,19 +1,17 @@ # frozen_string_literal: true -module Hq - class SessionsController < Devise::SessionsController - layout 'hq/login' +class Hq::SessionsController < Devise::SessionsController + layout 'hq/login' - private + private - # Overwriting the sign_out redirect path method - def after_sign_in_path_for(_resource_or_scope) - hq_root_path - end + # Overwriting the sign_out redirect path method + def after_sign_in_path_for(_resource_or_scope) + hq_root_path + end - # Overwriting the sign_out redirect path method - def after_sign_out_path_for(_resource_or_scope) - new_admin_session_path - end + # Overwriting the sign_out redirect path method + def after_sign_out_path_for(_resource_or_scope) + new_admin_session_path end end diff --git a/templates/app_files/app/controllers/hq/users_controller.rb b/templates/app_files/app/controllers/hq/users_controller.rb index b4eecb8..c0c5c17 100644 --- a/templates/app_files/app/controllers/hq/users_controller.rb +++ b/templates/app_files/app/controllers/hq/users_controller.rb @@ -1,66 +1,64 @@ # frozen_string_literal: true -module Hq - class UsersController < ApplicationController - before_action :set_user, only: %i[show edit update destroy toggle_is_active] - add_breadcrumb I18n.t('activerecord.models.users'), :hq_users_path +class Hq::UsersController < Hq::ApplicationController + before_action :set_user, only: %i[show edit update destroy toggle_is_active] + add_breadcrumb I18n.t('activerecord.models.users'), :hq_users_path - def index - @search = User.order(id: :desc).search(params[:q]) - @users = @search.result(distinct: true).paginate(page: params[:page]) - respond_with(@users) - end + def index + @search = User.order(id: :desc).search(params[:q]) + @users = @search.result(distinct: true).paginate(page: params[:page]) + respond_with(@users) + end - def show - add_breadcrumb @user.name, hq_user_path(@user) - respond_with(@user) - end + def show + add_breadcrumb @user.name, hq_user_path(@user) + respond_with(@user) + end - def new - add_breadcrumb t('view.tooltips.new'), new_hq_user_path - @user = User.new - respond_with(@user) - end + def new + add_breadcrumb t('view.tooltips.new'), new_hq_user_path + @user = User.new + respond_with(@user) + end - def edit - add_breadcrumb @user.name, hq_user_path(@user) - add_breadcrumb t('view.tooltips.edit'), edit_hq_user_path - end + def edit + add_breadcrumb @user.name, hq_user_path(@user) + add_breadcrumb t('view.tooltips.edit'), edit_hq_user_path + end - def create - @user = User.new(user_params) - @user.save - respond_with(:hq, @user) - end + def create + @user = User.new(user_params) + @user.save + respond_with(:hq, @user) + end - def update - @user.update(user_params) - respond_with(:hq, @user) - end + def update + @user.update(user_params) + respond_with(:hq, @user) + end - def destroy - @user.destroy - respond_with(:hq, @user, location: request.referer) - end + def destroy + @user.destroy + respond_with(:hq, @user, location: request.referer) + end - def toggle_is_active - if @user.update(is_active: !@user.is_active) - flash[:info] = t("flash.actions.toggle_is_active.#{@user.is_active ? 'active' : 'passive'}", - resource_name: User.model_name.human) - else - flash[:danger] = t('flash.messages.error_occurred') - end - respond_with(:hq, @user, location: request.referer) + def toggle_is_active + if @user.update(is_active: !@user.is_active) + flash[:info] = t("flash.actions.toggle_is_active.#{@user.is_active ? 'active' : 'passive'}", + resource_name: User.model_name.human) + else + flash[:danger] = t('flash.messages.error_occurred') end + respond_with(:hq, @user, location: request.referer) + end - private + private - def set_user - @user = User.find(params[:id]) - end + def set_user + @user = User.find(params[:id]) + end - def user_params - params.require(:user).permit(:email, :name, :surname, :time_zone) - end + def user_params + params.require(:user).permit(:email, :name, :surname, :time_zone) end end diff --git a/templates/app_files/app/controllers/user/application_controller.rb b/templates/app_files/app/controllers/user/application_controller.rb new file mode 100644 index 0000000..2f3731f --- /dev/null +++ b/templates/app_files/app/controllers/user/application_controller.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +class User::ApplicationController < ApplicationController + layout 'application' + before_filter :set_audit_user, :set_user_time_zone + before_action :authenticate_user! + + protected + + def set_user_time_zone + Time.zone = current_user.time_zone if current_user.time_zone.present? + end + + private + + def set_audit_user + # Set audit current user + Audited.current_user_method = :current_user + end +end diff --git a/templates/app_files/app/controllers/user/dashboard_controller.rb b/templates/app_files/app/controllers/user/dashboard_controller.rb new file mode 100644 index 0000000..c2b0f2b --- /dev/null +++ b/templates/app_files/app/controllers/user/dashboard_controller.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class User::DashboardController < User::ApplicationController + add_breadcrumb I18n.t('view.dock.dashboard'), :user_dashboard_index_path + + def index; end +end diff --git a/templates/app_files/app/controllers/user/passwords_controller.rb b/templates/app_files/app/controllers/user/passwords_controller.rb new file mode 100644 index 0000000..ce00f2d --- /dev/null +++ b/templates/app_files/app/controllers/user/passwords_controller.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class User::PasswordsController < Devise::PasswordsController + private + + def after_resetting_password_path_for + user_root_path + end +end diff --git a/templates/app_files/app/controllers/user/profile_controller.rb b/templates/app_files/app/controllers/user/profile_controller.rb new file mode 100644 index 0000000..68a06a8 --- /dev/null +++ b/templates/app_files/app/controllers/user/profile_controller.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +class User::ProfileController < User::ApplicationController + before_action :set_profile, only: %i[show edit update] + add_breadcrumb I18n.t('view.dock.profile'), :user_profile_path + + def show + add_breadcrumb @profile.full_name, user_profile_path + respond_with(:user, @profile) + end + + def edit + add_breadcrumb t('view.tooltips.edit'), edit_user_profile_path + end + + def update + @profile.update(profile_params) + respond_with(:user, @profile, location: user_profile_path) + end + + private + + def set_profile + @profile = current_user + end + + def profile_params + params.require(:user).permit(:name, :surname, :time_zone) + end +end diff --git a/templates/app_files/app/controllers/user/registrations_controller.rb b/templates/app_files/app/controllers/user/registrations_controller.rb new file mode 100644 index 0000000..566389f --- /dev/null +++ b/templates/app_files/app/controllers/user/registrations_controller.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +class User::RegistrationsController < Devise::RegistrationsController + before_action :authenticate_user!, except: %i[new create] + before_action :redirect_user, only: %i[destroy] + add_breadcrumb I18n.t('activerecord.models.user'), :user_root_path + + def edit; end + + private + + def redirect_user + redirect_to user_root_path + end + + def after_update_path_for(_resource) + user_root_path + end +end diff --git a/templates/app_files/app/controllers/user/sessions_controller.rb b/templates/app_files/app/controllers/user/sessions_controller.rb new file mode 100644 index 0000000..46bb9ad --- /dev/null +++ b/templates/app_files/app/controllers/user/sessions_controller.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class User::SessionsController < Devise::SessionsController + private + + # Overwriting the sign_out redirect path method + def after_sign_in_path_for(_resource_or_scope) + user_root_path + end + + # Overwriting the sign_out redirect path method + def after_sign_out_path_for(_resource_or_scope) + new_user_session_path + end +end diff --git a/templates/app_files/app/controllers/welcome_controller.rb b/templates/app_files/app/controllers/welcome_controller.rb index 23178ac..f3ec03d 100644 --- a/templates/app_files/app/controllers/welcome_controller.rb +++ b/templates/app_files/app/controllers/welcome_controller.rb @@ -1,10 +1,9 @@ +# frozen_string_literal: true + class WelcomeController < ApplicationController - def index - end + def index; end - def about - end + def about; end - def contact - end -end \ No newline at end of file + def contact; end +end diff --git a/templates/app_files/app/mailers/user_mailer.rb b/templates/app_files/app/mailers/user_mailer.rb new file mode 100644 index 0000000..178fa03 --- /dev/null +++ b/templates/app_files/app/mailers/user_mailer.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +class UserMailer < ApplicationMailer + def login_info(user_id, password) + @user = User.find(user_id) + @password = password + @subject = t('mailer.user.login_info.title') + mail(to: @user.email, subject: @subject) + end +end diff --git a/templates/app_files/app/models/admin.rb b/templates/app_files/app/models/admin.rb index acb06b9..e9b4292 100644 --- a/templates/app_files/app/models/admin.rb +++ b/templates/app_files/app/models/admin.rb @@ -12,6 +12,9 @@ class Admin < ApplicationRecord :trackable, :validatable + # Scopes + scope :active, -> { where(is_active: true) } + # Send devise emails with background job def send_devise_notification(notification, *args) devise_mailer.send(notification, self, *args).deliver_later diff --git a/templates/app_files/app/models/user.rb b/templates/app_files/app/models/user.rb new file mode 100644 index 0000000..dc02627 --- /dev/null +++ b/templates/app_files/app/models/user.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +class User < ApplicationRecord + # Virtual attributes + attr_accessor :is_generated_password + + # Scopes + scope :active, -> { where(is_active: true) } + + # Include default devise modules. Others available are: + # :confirmable, :lockable, :timeoutable and :omniauthable + devise :database_authenticatable, + :registerable, + :recoverable, + :rememberable, + :trackable, + :validatable + + # Send devise emails with background job + def send_devise_notification(notification, *args) + devise_mailer.send(notification, self, *args).deliver_later + end + + # Helpers + audited except: [:password] + + # Validations + validates_presence_of :name, :email, :surname + validates :email, uniqueness: true + + # Callbacks + after_commit :send_login_info, on: :create + before_validation :create_password, on: :create + after_initialize do |obj| + obj.is_generated_password = false + end + + def active_for_authentication? + super && is_active + end + + def full_name + "#{name} #{surname}" + end + + private + + def create_password + return unless password.nil? + password = Devise.friendly_token.first(8) + self.password = password + self.password_confirmation = password + self.is_generated_password = true + end + + def send_login_info + UserMailer.login_info(id, password).deliver_later! if is_generated_password + end +end diff --git a/templates/app_files/app/views/layouts/application.html.haml.erb b/templates/app_files/app/views/layouts/application.html.erb similarity index 59% rename from templates/app_files/app/views/layouts/application.html.haml.erb rename to templates/app_files/app/views/layouts/application.html.erb index 52e4e55..fca0b2f 100644 --- a/templates/app_files/app/views/layouts/application.html.haml.erb +++ b/templates/app_files/app/views/layouts/application.html.erb @@ -9,26 +9,16 @@ %link(rel="shortcut icon" href="/images/favicon.png") = stylesheet_link_tag 'application', '//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css', - media: 'all', 'data-turbolinks-track' => true - = javascript_include_tag 'application', 'data-turbolinks-track' => true + media: 'all', 'data-turbolinks-track': 'reload' + = javascript_include_tag 'application', 'data-turbolinks-track': 'reload' = csrf_meta_tags - = yield :headls + = yield :head %body = render 'layouts/partials/warnings' .container-narrow .header - %nav - / Brand and toggle get grouped for better mobile display - = link_to root_path, class: 'navbar-brand' do - %i.fa.fa-home - = "<%= app_name.capitalize %>" - %ul.nav.nav-pills.float-right - %li.nav-item - %a.nav-link{href: about_welcome_index_path} - = t('view.welcome.navbar.about') - %li.nav-item - %a.nav-link{href: contact_welcome_index_path} - = t('view.welcome.navbar.contact') + = render partial: 'layouts/partials/navbar' + = render partial: 'layouts/partials/messages' = yield .footer %p diff --git a/templates/app_files/app/views/layouts/hq/application.html.haml b/templates/app_files/app/views/layouts/hq/application.html.erb similarity index 100% rename from templates/app_files/app/views/layouts/hq/application.html.haml rename to templates/app_files/app/views/layouts/hq/application.html.erb diff --git a/templates/app_files/app/views/layouts/mailer.html.erb b/templates/app_files/app/views/layouts/mailer.html.erb new file mode 100644 index 0000000..8864453 --- /dev/null +++ b/templates/app_files/app/views/layouts/mailer.html.erb @@ -0,0 +1,321 @@ +!!! +%html{:xmlns => "http://www.w3.org/1999/xhtml", "xmlns:mc" => "http://www.w3.org/1999/xhtml"} + %head + %meta{:content => "text/html; charset=UTF-8", "http-equiv" => "Content-Type"}/ + %title= @subject + :css + #outlook a{padding:0;} + .ReadMsgBody{width:100%;} .ExternalClass{width:100%;} + .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {line-height: 100%;} + body, table, td, p, a, li, blockquote{-webkit-text-size-adjust:100%; -ms-text-size-adjust:100%;} + table, td{mso-table-lspace:0pt; mso-table-rspace:0pt;} + img{-ms-interpolation-mode:bicubic;} + body{margin:0; padding:0;} + img{border:0; height:auto; line-height:100%; outline:none; text-decoration:none;} + table{border-collapse:collapse !important;} + body, #bodyTable, #bodyCell{height:100% !important; margin:0; padding:0; width:100% !important;} + #bodyCell{padding:20px;} + #templateContainer{width:600px;} + body, #bodyTable{ + /*@editable*/ background-color:#DEE0E2; + } + #bodyCell{ + /*@editable*/ border-top:4px solid #BBBBBB; + } + #templateContainer{ + /*@editable*/ border:1px solid #BBBBBB; + } + h1{ + /*@editable*/ color:#202020 !important; + display:block; + /*@editable*/ font-family:Helvetica; + /*@editable*/ font-size:26px; + /*@editable*/ font-style:normal; + /*@editable*/ font-weight:bold; + /*@editable*/ line-height:100%; + /*@editable*/ letter-spacing:normal; + margin-top:0; + margin-right:0; + margin-bottom:10px; + margin-left:0; + /*@editable*/ text-align:left; + } + h2{ + /*@editable*/ color:#404040 !important; + display:block; + /*@editable*/ font-family:Helvetica; + /*@editable*/ font-size:20px; + /*@editable*/ font-style:normal; + /*@editable*/ font-weight:bold; + /*@editable*/ line-height:100%; + /*@editable*/ letter-spacing:normal; + margin-top:0; + margin-right:0; + margin-bottom:10px; + margin-left:0; + /*@editable*/ text-align:left; + } + h3{ + /*@editable*/ color:#606060 !important; + display:block; + /*@editable*/ font-family:Helvetica; + /*@editable*/ font-size:16px; + /*@editable*/ font-style:italic; + /*@editable*/ font-weight:normal; + /*@editable*/ line-height:100%; + /*@editable*/ letter-spacing:normal; + margin-top:0; + margin-right:0; + margin-bottom:10px; + margin-left:0; + /*@editable*/ text-align:left; + } + h4{ + /*@editable*/ color:#808080 !important; + display:block; + /*@editable*/ font-family:Helvetica; + /*@editable*/ font-size:14px; + /*@editable*/ font-style:italic; + /*@editable*/ font-weight:normal; + /*@editable*/ line-height:100%; + /*@editable*/ letter-spacing:normal; + margin-top:0; + margin-right:0; + margin-bottom:10px; + margin-left:0; + /*@editable*/ text-align:left; + } + #templatePreheader{ + /*@editable*/ background-color:#F4F4F4; + /*@editable*/ border-bottom:1px solid #CCCCCC; + } + .preheaderContent{ + /*@editable*/ color:#808080; + /*@editable*/ font-family:Helvetica; + /*@editable*/ font-size:10px; + /*@editable*/ line-height:125%; + /*@editable*/ text-align:left; + } + .preheaderContent a:link, .preheaderContent a:visited, /* Yahoo! Mail Override */ .preheaderContent a .yshortcuts /* Yahoo! Mail Override */{ + /*@editable*/ color:#606060; + /*@editable*/ font-weight:normal; + /*@editable*/ text-decoration:underline; + } + #templateHeader{ + /*@editable*/ background-color:#F4F4F4; + /*@editable*/ border-top:1px solid #FFFFFF; + /*@editable*/ border-bottom:1px solid #CCCCCC; + } + .headerContent{ + /*@editable*/ color:#505050; + /*@editable*/ font-family:Helvetica; + /*@editable*/ font-size:20px; + /*@editable*/ font-weight:bold; + /*@editable*/ line-height:100%; + /*@editable*/ padding-top:0; + /*@editable*/ padding-right:0; + /*@editable*/ padding-bottom:0; + /*@editable*/ padding-left:0; + /*@editable*/ text-align:left; + /*@editable*/ vertical-align:middle; + } + .headerContent a:link, .headerContent a:visited, /* Yahoo! Mail Override */ .headerContent a .yshortcuts /* Yahoo! Mail Override */{ + /*@editable*/ color:#EB4102; + /*@editable*/ font-weight:normal; + /*@editable*/ text-decoration:underline; + } + #headerImage{ + height:auto; + max-width:600px; + } + #templateBody{ + /*@editable*/ background-color:#F4F4F4; + /*@editable*/ border-top:1px solid #FFFFFF; + /*@editable*/ border-bottom:1px solid #CCCCCC; + } + .bodyContent{ + /*@editable*/ color:#505050; + /*@editable*/ font-family:Helvetica; + /*@editable*/ font-size:16px; + /*@editable*/ line-height:150%; + padding-top:20px; + padding-right:20px; + padding-bottom:20px; + padding-left:20px; + /*@editable*/ text-align:left; + } + .bodyContent a:link, .bodyContent a:visited, /* Yahoo! Mail Override */ .bodyContent a .yshortcuts /* Yahoo! Mail Override */{ + /*@editable*/ color:#EB4102; + /*@editable*/ font-weight:normal; + /*@editable*/ text-decoration:underline; + } + .bodyContent img{ + display:inline; + height:auto; + max-width:560px; + } + .templateColumnContainer{width:260px;} + #templateColumns{ + /*@editable*/ background-color:#F4F4F4; + /*@editable*/ border-top:1px solid #FFFFFF; + /*@editable*/ border-bottom:1px solid #CCCCCC; + } + .leftColumnContent{ + /*@editable*/ color:#505050; + /*@editable*/ font-family:Helvetica; + /*@editable*/ font-size:14px; + /*@editable*/ line-height:150%; + padding-top:0; + padding-right:20px; + padding-bottom:20px; + padding-left:20px; + /*@editable*/ text-align:left; + } + .leftColumnContent a:link, .leftColumnContent a:visited, /* Yahoo! Mail Override */ .leftColumnContent a .yshortcuts /* Yahoo! Mail Override */{ + /*@editable*/ color:#EB4102; + /*@editable*/ font-weight:normal; + /*@editable*/ text-decoration:underline; + } + .rightColumnContent{ + /*@editable*/ color:#505050; + /*@editable*/ font-family:Helvetica; + /*@editable*/ font-size:14px; + /*@editable*/ line-height:150%; + padding-top:0; + padding-right:20px; + padding-bottom:20px; + padding-left:20px; + /*@editable*/ text-align:left; + } + .rightColumnContent a:link, .rightColumnContent a:visited, /* Yahoo! Mail Override */ .rightColumnContent a .yshortcuts /* Yahoo! Mail Override */{ + /*@editable*/ color:#EB4102; + /*@editable*/ font-weight:normal; + /*@editable*/ text-decoration:underline; + } + .leftColumnContent img, .rightColumnContent img{ + display:inline; + height:auto; + max-width:260px; + } + #templateFooter{ + /*@editable*/ background-color:#F4F4F4; + /*@editable*/ border-top:1px solid #FFFFFF; + } + .footerContent{ + /*@editable*/ color:#808080; + /*@editable*/ font-family:Helvetica; + /*@editable*/ font-size:10px; + /*@editable*/ line-height:150%; + padding-top:20px; + padding-right:20px; + padding-bottom:20px; + padding-left:20px; + /*@editable*/ text-align:left; + } + .footerContent a:link, .footerContent a:visited, /* Yahoo! Mail Override */ .footerContent a .yshortcuts, .footerContent a span /* Yahoo! Mail Override */{ + /*@editable*/ color:#606060; + /*@editable*/ font-weight:normal; + /*@editable*/ text-decoration:underline; + } + @media only screen and (max-width: 480px){ + body, table, td, p, a, li, blockquote{-webkit-text-size-adjust:none !important;} /* Prevent Webkit platforms from changing default text sizes */ + body{width:100% !important; min-width:100% !important;} /* Prevent iOS Mail from adding padding to the body */ + #bodyCell{padding:10px !important;} + #templateContainer{ + max-width:600px !important; + /*@editable*/ width:100% !important; + } + h1{ + /*@editable*/ font-size:24px !important; + /*@editable*/ line-height:100% !important; + } + h2{ + /*@editable*/ font-size:20px !important; + /*@editable*/ line-height:100% !important; + } + h3{ + /*@editable*/ font-size:18px !important; + /*@editable*/ line-height:100% !important; + } + h4{ + /*@editable*/ font-size:16px !important; + /*@editable*/ line-height:100% !important; + } + #templatePreheader{display:none !important;} + #headerImage{ + height:auto !important; + /*@editable*/ max-width:600px !important; + /*@editable*/ width:100% !important; + } + .headerContent{ + /*@editable*/ font-size:20px !important; + /*@editable*/ line-height:125% !important; + } + .bodyContent{ + /*@editable*/ font-size:18px !important; + /*@editable*/ line-height:125% !important; + } + .templateColumnContainer{display:block !important; width:100% !important;} + .columnImage{ + height:auto !important; + /*@editable*/ max-width:480px !important; + /*@editable*/ width:100% !important; + } + .leftColumnContent{ + /*@editable*/ font-size:16px !important; + /*@editable*/ line-height:125% !important; + } + .rightColumnContent{ + /*@editable*/ font-size:16px !important; + /*@editable*/ line-height:125% !important; + } + .footerContent{ + /*@editable*/ font-size:14px !important; + /*@editable*/ line-height:115% !important; + } + .footerContent a{display:block !important;} + } + %body{:leftmargin => "0", :marginheight => "0", :marginwidth => "0", :offset => "0", :topmargin => "0"} + %center + %table#bodyTable{:align => "center", :border => "0", :cellpadding => "0", :cellspacing => "0", :height => "100%", :width => "100%"} + %tr + %td#bodyCell{:align => "center", :valign => "top"} + %table#templateContainer{:border => "0", :cellpadding => "0", :cellspacing => "0"} + %tr + %td{:align => "center", :valign => "top"} + %table#templateBody{:border => "0", :cellpadding => "0", :cellspacing => "0", :width => "100%"} + %tr + %td{:align => "left", :valign => "top"} + = image_tag "#{Settings.root_path}/images/mail-logo.png", width: 150, height: 150, style: 'padding: 10px 20px' + %tr + %td.bodyContent{"mc:edit" => "body_content", :valign => "top"} + = yield + %br/ + %br/ + %tr + %td{:align => "center", :valign => "top"} + %table#templateFooter{:border => "0", :cellpadding => "0", :cellspacing => "0", :width => "100%"} + %tr + %td.footerContent{"mc:edit" => "footer_content01", :style => "padding-top:0;", :valign => "top"} + %br/ + %strong + Web adresi + \: + www.<%= app_name %>.com + %br/ + %strong + E-posta + \: + info@<%= app_name %>.com + %br/ + %strong + Telefon + \: + +90 (850) XXX XX-XX + %br/ + %strong + İşlem Zamanı + \: + #{I18n.localize(Time.zone.now)} + %br/ + <%= app_name.capitalize %> Copyright © #{Time.zone.now.year} Tüm Hakları Saklıdır. diff --git a/templates/app_files/app/views/layouts/partials/_navbar.html.erb b/templates/app_files/app/views/layouts/partials/_navbar.html.erb new file mode 100644 index 0000000..076e02e --- /dev/null +++ b/templates/app_files/app/views/layouts/partials/_navbar.html.erb @@ -0,0 +1,32 @@ +%nav.navbar.navbar-expand-lg.navbar-light.bg-light + %a.navbar-brand{href: root_path} + %i.fa.fa-home + = "<%= app_name.capitalize %>" + %button.navbar-toggler{"aria-controls" => "navbarNavDropdown", "aria-expanded" => "false", "aria-label" => "Toggle navigation", "data-target" => "#navbarNavDropdown", "data-toggle" => "collapse", :type => "button"} + %span.navbar-toggler-icon + #navbarNavDropdown.collapse.navbar-collapse + %ul.navbar-nav.ml-auto + %li.nav-item + = link_to about_welcome_index_path, class: 'nav-link' do + = t('view.welcome.navbar.about') + %li.nav-item + = link_to contact_welcome_index_path, class: 'nav-link' do + = t('view.welcome.navbar.contact') + - if user_signed_in? + %li.nav-item + = link_to destroy_user_session_path, class: 'nav-link', method: :delete do + %i.fa.fa-sign-out + = t('navbar.sign_out') + %li.nav-item + = link_to user_profile_path(current_user), class: 'nav-link' do + %i.fa.fa-user + = t('navbar.profile') + - else + %li.nav-item + = link_to new_user_session_path, class: 'nav-link' do + %i.fa.fa-pencil-square-o{"aria-hidden" => "true"} + = t('navbar.signin') + %li.nav-item + = link_to new_user_registration_path, class: 'nav-link' do + %i.fa.fa-user{"aria-hidden" => "true"} + = t('navbar.signup') diff --git a/templates/app_files/app/views/user/dashboard/index.html.haml b/templates/app_files/app/views/user/dashboard/index.html.haml new file mode 100644 index 0000000..bddaaac --- /dev/null +++ b/templates/app_files/app/views/user/dashboard/index.html.haml @@ -0,0 +1,6 @@ +.card + .card-body + .alert.alert-info + = t('view.hello', user: current_user.email) + = link_to t('view.navbar.sign_out'), destroy_user_session_path, method: :delete, class: 'btn btn-danger' + = link_to t('view.navbar.edit_login_info'), edit_user_registration_path, class: 'btn btn-primary' diff --git a/templates/app_files/app/views/user/passwords/edit.html.haml b/templates/app_files/app/views/user/passwords/edit.html.haml new file mode 100644 index 0000000..17f05cc --- /dev/null +++ b/templates/app_files/app/views/user/passwords/edit.html.haml @@ -0,0 +1,15 @@ +.card + .card-header.text-center + %h2= t('devise.password.edit.title') + .card-body + = simple_form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| + = f.error_notification + = f.input :reset_password_token, as: :hidden + = f.full_error :reset_password_token + .form-inputs + = f.input :password, required: true, autofocus: true + = f.input :password_confirmation, required: true + .form-actions + = f.button :submit, t('devise.password.edit.button') , class: 'btn btn-primary btn-block' + .card-footer.text-center + = render 'devise/shared/links' diff --git a/templates/app_files/app/views/user/passwords/new.html.haml b/templates/app_files/app/views/user/passwords/new.html.haml new file mode 100644 index 0000000..b211af1 --- /dev/null +++ b/templates/app_files/app/views/user/passwords/new.html.haml @@ -0,0 +1,13 @@ +.card + .card-header.text-center + %h2= t('devise.password.new.title') + .card-body + = simple_form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| + = f.error_notification + .form-inputs + = f.input :email, required: true, autofocus: true + .form-actions + = f.button :submit, t('devise.password.reset.instructions'), class: 'btn btn-primary btn-block' + + .card-footer.text-center + = render 'devise/shared/links' \ No newline at end of file diff --git a/templates/app_files/app/views/user/profile/_form.html.haml b/templates/app_files/app/views/user/profile/_form.html.haml new file mode 100644 index 0000000..ae8ee21 --- /dev/null +++ b/templates/app_files/app/views/user/profile/_form.html.haml @@ -0,0 +1,15 @@ +.card + .card-header + %i.icon-edit.icon-large + = yield :form_title + .card-body + = simple_form_for([:user, @profile], url: user_profile_path, validate: true) do |f| + = f.error_notification + + .form-inputs + = f.input :name + = f.input :surname + + .form-actions + = f.button :submit, class: 'btn btn-primary' + = link_to t('view.cancel'), user_profile_path, class: 'btn' diff --git a/templates/app_files/app/views/user/profile/edit.html.haml b/templates/app_files/app/views/user/profile/edit.html.haml new file mode 100644 index 0000000..0d7bb22 --- /dev/null +++ b/templates/app_files/app/views/user/profile/edit.html.haml @@ -0,0 +1,3 @@ +- content_for :form_title do + = t('view.title.edit', resource_name: User.model_name.human) += render 'form' diff --git a/templates/app_files/app/views/user/profile/show.html.haml b/templates/app_files/app/views/user/profile/show.html.haml new file mode 100644 index 0000000..25dae32 --- /dev/null +++ b/templates/app_files/app/views/user/profile/show.html.haml @@ -0,0 +1,18 @@ +.card + .card-header + %i.fa.fa-edit + = t('view.title.show', resource_name: User.model_name.human) + .card-body + = show_for @profile do |s| + = s.attribute :name + = s.attribute :surname + = s.attribute :email + = s.attribute :created_at + = s.attribute :updated_at + .card-footer + = link_to root_path, class: 'btn' do + %i.fa.fa-arrow-left + = t('view.btn.back') + = link_to edit_user_profile_path(@profile), class: 'btn btn-primary' do + %i.fa.fa-pencil + = t('view.navbar.edit_profile_info') \ No newline at end of file diff --git a/templates/app_files/app/views/user/registrations/edit.html.haml b/templates/app_files/app/views/user/registrations/edit.html.haml new file mode 100644 index 0000000..117abda --- /dev/null +++ b/templates/app_files/app/views/user/registrations/edit.html.haml @@ -0,0 +1,23 @@ +.card + .card-header + %i.fa.fa-edit + = t('devise.registration.edit.title', model: resource.class.model_name.human) + .card-body + = simple_form_for(resource, as: resource_name, url: user_registration_path, html: { method: :put }) do |f| + = f.error_notification + .form-inputs + = f.input :email, required: true, autofocus: true + - if devise_mapping.confirmable? && resource.pending_reconfirmation? + %p + = t('devise.registration.waiting_confirmation', email: resource.unconfirmed_email ) + %hr + = f.input :password, label: t('activerecord.attributes.user.password'), + autocomplete: 'off', hint: t('devise.registration.hint_password'), + required: false + = f.input :password_confirmation, label: t('activerecord.attributes.user.password_confirmation'), + required: false + %hr + = f.input :current_password, label: t('activerecord.attributes.user.current_password'), + hint: t('devise.registration.hint_current_password'), required: true + .form-actions + = f.button :submit, t('view.btn.update'), class: 'btn btn-primary btn-block' diff --git a/templates/app_files/app/views/user/registrations/new.html.haml b/templates/app_files/app/views/user/registrations/new.html.haml new file mode 100644 index 0000000..e5b9fcb --- /dev/null +++ b/templates/app_files/app/views/user/registrations/new.html.haml @@ -0,0 +1,25 @@ +.card + .card-header + %h2.text-center + = t('devise.registration.new.title', model: resource.class.model_name.human) + - if devise_mapping.omniauthable? + - resource_class.omniauth_providers.each do |provider| + = link_to omniauth_authorize_path(resource_name, provider), class: 'btn btn-lg btn-primary btn-block' do + %i.fa.fa-facebook + = t('devise.shared.links.signup_with', name: provider.to_s.titleize) + %h3.text-center + = t('view.or') + .card-body + = simple_form_for(resource, as: resource_name, url: registration_path(resource_name), validate: true) do |f| + = f.error_notification + .form-inputs + = f.input :email + = f.input :password + = f.input :password_confirmation + = f.input :name + = f.input :surname + = f.input :time_zone, input_html: { class: 'chosen-select'}, include_blank: t('view.select') + .form-actions + = f.button :submit, t('devise.registration.new.button'), class: 'btn btn-primary btn-block' + .card-footer.text-center + = render 'devise/shared/links' diff --git a/templates/app_files/app/views/user/sessions/new.html.haml b/templates/app_files/app/views/user/sessions/new.html.haml new file mode 100644 index 0000000..8831830 --- /dev/null +++ b/templates/app_files/app/views/user/sessions/new.html.haml @@ -0,0 +1,14 @@ +.card + .card-header.text-center + %h2 + = t('devise.session.title', model: resource.class.model_name.human ) + .card-body + = simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| + .form-inputs + = f.input :email, required: false, autofocus: true + = f.input :password, required: false + = f.input :remember_me, as: :boolean,label: t('devise.session.remember_me') if devise_mapping.rememberable? + .form-actions + = f.button :submit, t('devise.session.button'), class: 'btn btn-primary btn-block' + .card-footer.text-center + = render 'devise/shared/links' \ No newline at end of file diff --git a/templates/app_files/app/views/user_mailer/login_info.html.haml b/templates/app_files/app/views/user_mailer/login_info.html.haml new file mode 100644 index 0000000..0df3d81 --- /dev/null +++ b/templates/app_files/app/views/user_mailer/login_info.html.haml @@ -0,0 +1,13 @@ +%h2= t('mailer.hello') + +%p= t('mailer.user.login_info.first_info') +%p= t('mailer.user.login_info.second_info') +%p + %strong= "#{t('activerecord.attributes.user.email')} :" + = @user.email +%p + %strong= "#{t('activerecord.attributes.user.password')} :" + = @password +%p= link_to t('mailer.user.login_info.btn_login'), new_user_session_url + +%p= t('mailer.user.login_info.last_info', link: new_user_session_url ).html_safe diff --git a/templates/app_files/app/views/welcome/index.html.erb b/templates/app_files/app/views/welcome/index.html.erb new file mode 100644 index 0000000..0d57af9 --- /dev/null +++ b/templates/app_files/app/views/welcome/index.html.erb @@ -0,0 +1,16 @@ +.jumbotron + %h1 Welcome to <%= app_name.capitalize %> + - if current_user + = link_to t('view.navbar.sign_out'), destroy_user_session_path, class: 'btn btn-link', method: :delete + .row-fluid.marketing + %p + %strong Name: + = current_user.name + %p + %strong Email: + = current_user.email + = link_to t('view.navbar.edit_login_info'), edit_user_registration_path, class: 'btn btn-link' + = link_to t('view.navbar.profile'), user_profile_path(current_user), class: 'btn btn-link' + - else + = link_to t('view.navbar.signup'), new_user_registration_path, class: 'btn btn-success' + = link_to t('view.navbar.signin'), new_user_session_path, class: 'btn btn-link' diff --git a/templates/app_files/app/views/welcome/index.html.haml b/templates/app_files/app/views/welcome/index.html.haml deleted file mode 100644 index 4d980e6..0000000 --- a/templates/app_files/app/views/welcome/index.html.haml +++ /dev/null @@ -1,16 +0,0 @@ -.jumbotron - %h1 Welcome to <%= app_name.capitalize %> - - if current_user - = link_to t('navbar.sign_out'), destroy_user_session_path, class: 'btn btn-large', method: :delete - .row-fluid.marketing - %p - %strong Name: - = current_user.name - %p - %strong Email: - = current_user.email - = link_to t('navbar.edit_login_info'), edit_user_registration_path, class: 'btn btn-large' - = link_to t('navbar.profile'), user_profile_path(current_user), class: 'btn btn-link' - - else - = link_to t('navbar.signup'), new_user_registration_path, class: 'btn btn-large btn-success' - = link_to t('navbar.signin'), new_user_session_path, class: 'btn btn-large' \ No newline at end of file diff --git a/templates/config/locales/devise.en.yml b/templates/config/locales/devise.en.yml new file mode 100644 index 0000000..2988c0f --- /dev/null +++ b/templates/config/locales/devise.en.yml @@ -0,0 +1,42 @@ +en: + devise: + session: + title: "%{model} Log in" + button: Log In + remember_me: Remember me + deactivated: "Sorry, this account has been disabled." + registration: + title: 'Update %{model} Login Info' + waiting_confirmation: "Currently waiting confirmation for: %{email}" + hint_password: "Leave it blank if you don't want to change it" + hint_current_password: "we need your current password to confirm your changes" + new: + title: '%{model} Sign Up' + character_hint: "%{length} characters minimum" + button: Sign Up + edit: + title: '%{model} Log in info' + shared: + links: + signup: Sign Up + signin: Log In + forgot_password: "Forgot your password?" + confirmation_instructions: "Did not you get the confirmation instructions?" + unlock_instructions: "Did not you get the unlock instructions?" + sign_in_with: "Sign in with %{name}" + sign_up_with: "Sign up with %{name}" + confirmation: + new: + title: "Resend confirmation instructions" + btn: + resend: Resend + password: + new: + title: "Forgot your password?" + reset: + instructions: Send password reset instructions + edit: + title: "Change your password" + new_password: "New password" + confirmation: "Confirm your new password" + button: "Change my password" \ No newline at end of file diff --git a/templates/config/locales/devise.tr.yml b/templates/config/locales/devise.tr.yml new file mode 100644 index 0000000..6beb44a --- /dev/null +++ b/templates/config/locales/devise.tr.yml @@ -0,0 +1,42 @@ +tr: + devise: + session: + title: '%{model} Girişi' + button: Giriş Yap + remember_me: Beni Hatırla + deactivated: Üzgünüz, bu hesap pasif hale getirilmiştir. + registration: + title: '%{model} Giriş Bilgilerini Güncelle' + waiting_confirmation: 'E-posta addresi onayı için bekleniyor: %{email}' + hint_password: Değiştirmek istemiyorsanız boş bırakınız + hint_current_password: Değişiklikleri onaylamak için şuan ki parolanız girmelisiniz + new: + title: '%{model} Kayıt İşlemi' + character_hint: 'Minimum %{length} karakter' + button: Kayıt Ol + edit: + title: '%{model} Giriş Bilgilerini Güncelle' + shared: + links: + signup: Kayıt Ol + signin: Giriş Yap + forgot_password: Parolanızı mı unuttunuz? + confirmation_instructions: Onaylama yönergesini mi almadınız? + unlock_instructions: Kapatma yönergesini mi almadınız? + signin_with: '%{name} ile Giriş Yap' + signup_with: '%{name} ile Kayıt Ol' + confirmation: + new: + title: Onaylama Talimatlarını Yeniden Gönder + btn: + resend: Gönder + password: + new: + title: Parolanızı mı unuttunuz? + reset: + instructions: Parola sıfırlama talimatlarını gönder + edit: + title: Parolanızı Değiştiriniz + new_password: Yeni parolanız + confirmation: Yeni parola doğrulması + button: Parolamı Değiştir \ No newline at end of file diff --git a/templates/config/locales/mailer.en.yml b/templates/config/locales/mailer.en.yml index 6dba1a0..28f9a63 100644 --- a/templates/config/locales/mailer.en.yml +++ b/templates/config/locales/mailer.en.yml @@ -17,4 +17,11 @@ en: first_info: Your admin account has been created. You can now log in to the admin portal. second_info: Your login information is btn_login: Click to login + last_info: "If you can not use 'Login' button, your login
Link : %{link}
Copy this link and paste it into your browser." + user: + login_info: + title: User Login Information + first_info: Your user account has been created. You can now log in to the user portal. + second_info: Your login information is + btn_login: Click to login last_info: "If you can not use 'Login' button, your login
Link : %{link}
Copy this link and paste it into your browser." \ No newline at end of file diff --git a/templates/config/locales/mailer.tr.yml b/templates/config/locales/mailer.tr.yml index 6ffa919..34e49b1 100644 --- a/templates/config/locales/mailer.tr.yml +++ b/templates/config/locales/mailer.tr.yml @@ -17,4 +17,11 @@ tr: first_info: Portal üzerinden yönetici hesabınız oluşturuldu. Artık yönetici portalına giriş yapabilirsiniz. second_info: Giriş bilgileriniz şu şekildedir btn_login: Giriş yapmak için tıklayınız + last_info: "Eğer 'Giriş Yap' butonunu kullanamıyorsanız giriş linkiniz şu şekildedir
Link : %{link}
Bu linki kopyalayıp tarayıcınıza yapıştırınız.." + user: + login_info: + title: Kullanıcı Giriş Bilgileriniz + first_info: Portal üzerinden kullanıcı hesabınız oluşturuldu. Artık kullanıcı portalına giriş yapabilirsiniz. + second_info: Giriş bilgileriniz şu şekildedir + btn_login: Giriş yapmak için tıklayınız last_info: "Eğer 'Giriş Yap' butonunu kullanamıyorsanız giriş linkiniz şu şekildedir
Link : %{link}
Bu linki kopyalayıp tarayıcınıza yapıştırınız.." \ No newline at end of file diff --git a/templates/config/locales/view.en.yml b/templates/config/locales/view.en.yml index e9c16f2..ad51abe 100644 --- a/templates/config/locales/view.en.yml +++ b/templates/config/locales/view.en.yml @@ -70,45 +70,4 @@ en: navbar: about: About contact: Contact - footer: "%{app_name} Copyright © %{year} All Rights Reserved." - devise: - session: - title: "%{model} Log in" - button: Log In - remember_me: Remember me - deactivated: "Sorry, this account has been disabled." - registration: - title: 'Update %{model} Login Info' - waiting_confirmation: "Currently waiting confirmation for: %{email}" - hint_password: "Leave it blank if you don't want to change it" - hint_current_password: "we need your current password to confirm your changes" - new: - title: '%{model} Sign Up' - character_hint: "%{length} characters minimum" - button: Sign Up - edit: - title: '%{model} Log in info' - shared: - links: - signup: Sign Up - signin: Log In - forgot_password: "Forgot your password?" - confirmation_instructions: "Did not you get the confirmation instructions?" - unlock_instructions: "Did not you get the unlock instructions?" - sign_in_with: "Sign in with %{name}" - sign_up_with: "Sign up with %{name}" - confirmation: - new: - title: "Resend confirmation instructions" - btn: - resend: Resend - password: - new: - title: "Forgot your password?" - reset: - instructions: Send password reset instructions - edit: - title: "Change your password" - new_password: "New password" - confirmation: "Confirm your new password" - button: "Change my password" \ No newline at end of file + footer: "%{app_name} Copyright © %{year} All Rights Reserved." \ No newline at end of file diff --git a/templates/config/locales/view.tr.yml b/templates/config/locales/view.tr.yml index d630e21..6623450 100644 --- a/templates/config/locales/view.tr.yml +++ b/templates/config/locales/view.tr.yml @@ -66,44 +66,3 @@ tr: about: Hakkında contact: İletişim footer: "%{app_name} Copyright © %{year} Tüm Hakları Saklıdır." - devise: - session: - title: '%{model} Girişi' - button: Giriş Yap - remember_me: Beni Hatırla - deactivated: Üzgünüz, bu hesap pasif hale getirilmiştir. - registration: - title: '%{model} Giriş Bilgilerini Güncelle' - waiting_confirmation: 'E-posta addresi onayı için bekleniyor: %{email}' - hint_password: Değiştirmek istemiyorsanız boş bırakınız - hint_current_password: Değişiklikleri onaylamak için şuan ki parolanız girmelisiniz - new: - title: '%{model} Kayıt İşlemi' - character_hint: 'Minimum %{length} karakter' - button: Kayıt Ol - edit: - title: '%{model} Giriş Bilgilerini Güncelle' - shared: - links: - signup: Kayıt Ol - signin: Giriş Yap - forgot_password: Parolanızı mı unuttunuz? - confirmation_instructions: Onaylama yönergesini mi almadınız? - unlock_instructions: Kapatma yönergesini mi almadınız? - signin_with: '%{name} ile Giriş Yap' - signup_with: '%{name} ile Kayıt Ol' - confirmation: - new: - title: Onaylama Talimatlarını Yeniden Gönder - btn: - resend: Gönder - password: - new: - title: Parolanızı mı unuttunuz? - reset: - instructions: Parola sıfırlama talimatlarını gönder - edit: - title: Parolanızı Değiştiriniz - new_password: Yeni parolanız - confirmation: Yeni parola doğrulması - button: Parolamı Değiştir diff --git a/templates/config/routes.rb.erb b/templates/config/routes.rb.erb index 0afdea9..0057d67 100644 --- a/templates/config/routes.rb.erb +++ b/templates/config/routes.rb.erb @@ -15,16 +15,32 @@ namespace :hq do root to: 'dashboard#index' - resources :dashboard, only: [:index] - resources :admins, concerns: [:activeable] - resources :users, concerns: [:activeable] - resources :audits, only: [:index, :show] + resources :dashboard, only: %i[index] + resources :admins, concerns: %i[activeable] + resources :users, concerns: %i[activeable] + resources :audits, only: %i[index show] + end + + # Users + devise_for :users, controllers: { sessions: 'user/sessions', registrations: 'user/registrations', passwords: 'user/passwords' }, + path: 'user', + path_names: { sign_in: 'login', sign_out: 'logout', password: 'secret', confirmation: 'verification' } + + as :user do + get 'user/edit' => 'user/registrations#edit', as: 'edit_user_profile_registration' + put 'user' => 'user/registrations#update', as: 'user_profile_registration' + end + + namespace :user do + root to: 'dashboard#index' + resources :dashboard, only: %i[index] + resources :profile, only: %i[show edit update] end # Common pages root to: 'welcome#index' - resources :welcome, path: '', only: :index do + resources :welcome, path: '', only: %i[index] do get :about, on: :collection get :contact, on: :collection end diff --git a/templates/sidekiq/sidekiq_Procfile.erb b/templates/sidekiq/sidekiq_Procfile.erb new file mode 100644 index 0000000..16a5cc0 --- /dev/null +++ b/templates/sidekiq/sidekiq_Procfile.erb @@ -0,0 +1,2 @@ +web: bin/rails server -p $PORT -e $RAILS_ENV +worker: bundle exec sidekiq -C config/sidekiq.yml \ No newline at end of file