diff --git a/.env.example b/.env.example index addf9b685..80fec6985 100644 --- a/.env.example +++ b/.env.example @@ -73,10 +73,6 @@ RAILS_LOG_TO_STDOUT=true LOG_LEVEL=info LOG_SIZE=500 -# Credentials to access sidekiq dashboard in production -SIDEKIQ_AUTH_USERNAME= -SIDEKIQ_AUTH_PASSWORD= - ### This environment variables are only required if you are setting up social media channels #facebook FB_VERIFY_TOKEN= diff --git a/Gemfile b/Gemfile index 61b3f4bcd..b9e9c4f4c 100644 --- a/Gemfile +++ b/Gemfile @@ -49,6 +49,8 @@ gem 'devise_token_auth' # authorization gem 'jwt' gem 'pundit' +# super admin +gem 'administrate' ##--- gems for pubsub service ---## # https://karolgalanciak.com/blog/2019/11/30/from-activerecord-callbacks-to-publish-slash-subscribe-pattern-and-event-driven-design/ diff --git a/Gemfile.lock b/Gemfile.lock index 1932d7e72..1659d8cdf 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -84,11 +84,24 @@ GEM activerecord (>= 5.0, < 6.1) addressable (2.7.0) public_suffix (>= 2.0.2, < 5.0) + administrate (0.13.0) + actionpack (>= 4.2) + actionview (>= 4.2) + activerecord (>= 4.2) + autoprefixer-rails (>= 6.0) + datetime_picker_rails (~> 0.0.7) + jquery-rails (>= 4.0) + kaminari (>= 1.0) + momentjs-rails (~> 2.8) + sassc-rails (~> 2.1) + selectize-rails (~> 0.6) annotate (3.1.1) activerecord (>= 3.2, < 7.0) rake (>= 10.4, < 14.0) ast (2.4.0) attr_extras (6.2.3) + autoprefixer-rails (9.7.6) + execjs aws-eventstream (1.1.0) aws-partitions (1.310.0) aws-sdk-core (3.94.1) @@ -141,6 +154,8 @@ GEM concurrent-ruby (1.1.6) connection_pool (2.2.2) crass (1.0.6) + datetime_picker_rails (0.0.7) + momentjs-rails (>= 2.8.1) declarative (0.0.10) declarative-option (0.1.0) descendants_tracker (0.0.4) @@ -235,6 +250,10 @@ GEM jbuilder (2.10.0) activesupport (>= 5.0.0) jmespath (1.4.0) + jquery-rails (4.3.5) + rails-dom-testing (>= 1, < 3) + railties (>= 4.2.0) + thor (>= 0.14, < 2.0) json (2.3.0) json_pure (2.3.0) jwt (2.2.1) @@ -278,6 +297,8 @@ GEM mini_mime (1.0.2) mini_portile2 (2.4.0) minitest (5.14.0) + momentjs-rails (2.20.1) + railties (>= 3.1) msgpack (1.3.3) multi_json (1.14.1) multi_xml (0.6.0) @@ -406,6 +427,14 @@ GEM sass-listen (4.0.0) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) + sassc (2.3.0) + ffi (~> 1.9) + sassc-rails (2.1.2) + railties (>= 4.0.0) + sassc (>= 2.0) + sprockets (> 3.0) + sprockets-rails + tilt scout_apm (2.6.7) parser scss_lint (0.59.0) @@ -413,6 +442,7 @@ GEM seed_dump (3.3.1) activerecord (>= 4) activesupport (>= 4) + selectize-rails (0.12.6) semantic_range (2.3.0) sentry-raven (3.0.0) faraday (>= 1.0) @@ -451,6 +481,7 @@ GEM telephone_number (1.4.6) thor (0.20.3) thread_safe (0.3.6) + tilt (2.0.10) time_diff (0.3.0) activesupport i18n @@ -505,6 +536,7 @@ PLATFORMS DEPENDENCIES action-cable-testing acts-as-taggable-on + administrate annotate attr_extras aws-sdk-s3 diff --git a/app/assets/config/manifest.js b/app/assets/config/manifest.js index ac907b367..9b826819b 100644 --- a/app/assets/config/manifest.js +++ b/app/assets/config/manifest.js @@ -1 +1,3 @@ //= link_tree ../images +//= link administrate/application.css +//= link administrate/application.js diff --git a/app/builders/account_builder.rb b/app/builders/account_builder.rb index 126eedce0..9c724bd43 100644 --- a/app/builders/account_builder.rb +++ b/app/builders/account_builder.rb @@ -2,7 +2,7 @@ class AccountBuilder include CustomExceptions::Account - pattr_initialize [:account_name!, :email!] + pattr_initialize [:account_name!, :email!, :confirmed!] def perform validate_email @@ -46,6 +46,7 @@ class AccountBuilder password: password, password_confirmation: password, name: email_to_name(@email)) + @user.confirm if @confirmed if @user.save! link_user_to_account(@user, @account) @user diff --git a/app/controllers/api/v1/accounts/accounts_controller.rb b/app/controllers/api/v1/accounts/accounts_controller.rb index 0fd5dc7cf..29e26929b 100644 --- a/app/controllers/api/v1/accounts/accounts_controller.rb +++ b/app/controllers/api/v1/accounts/accounts_controller.rb @@ -16,7 +16,8 @@ class Api::V1::Accounts::AccountsController < Api::BaseController def create @user = AccountBuilder.new( account_name: account_params[:account_name], - email: account_params[:email] + email: account_params[:email], + confirmed: confirmed? ).perform if @user send_auth_headers(@user) @@ -40,6 +41,10 @@ class Api::V1::Accounts::AccountsController < Api::BaseController authorize(Account) end + def confirmed? + super_admin? && params[:confirmed] + end + def fetch_account @account = current_user.accounts.find(params[:id]) end diff --git a/app/controllers/concerns/access_token_auth_helper.rb b/app/controllers/concerns/access_token_auth_helper.rb index e7af9e116..3d6f55674 100644 --- a/app/controllers/concerns/access_token_auth_helper.rb +++ b/app/controllers/concerns/access_token_auth_helper.rb @@ -4,17 +4,25 @@ module AccessTokenAuthHelper 'api/v1/accounts/conversations/messages' => ['create'] }.freeze - def authenticate_access_token! + def ensure_access_token token = request.headers[:api_access_token] || request.headers[:HTTP_API_ACCESS_TOKEN] - access_token = AccessToken.find_by(token: token) - render_unauthorized('Invalid Access Token') && return unless access_token + @access_token = AccessToken.find_by(token: token) if token.present? + end - token_owner = access_token.owner - @resource = token_owner + def authenticate_access_token! + ensure_access_token + render_unauthorized('Invalid Access Token') && return if @access_token.blank? + + @resource = @access_token.owner + end + + def super_admin? + @resource.present? && @resource.is_a?(SuperAdmin) end def validate_bot_access_token! return if current_user.is_a?(User) + return if super_admin? return if agent_bot_accessible? render_unauthorized('Access to this endpoint is not authorized for bots') diff --git a/app/controllers/super_admin/access_tokens_controller.rb b/app/controllers/super_admin/access_tokens_controller.rb new file mode 100644 index 000000000..a8a2669c4 --- /dev/null +++ b/app/controllers/super_admin/access_tokens_controller.rb @@ -0,0 +1,44 @@ +class SuperAdmin::AccessTokensController < SuperAdmin::ApplicationController + # Overwrite any of the RESTful controller actions to implement custom behavior + # For example, you may want to send an email after a foo is updated. + # + # def update + # super + # send_foo_updated_email(requested_resource) + # end + + # Override this method to specify custom lookup behavior. + # This will be used to set the resource for the `show`, `edit`, and `update` + # actions. + # + # def find_resource(param) + # Foo.find_by!(slug: param) + # end + + # The result of this lookup will be available as `requested_resource` + + # Override this if you have certain roles that require a subset + # this will be used to set the records shown on the `index` action. + # + # def scoped_resource + # if current_user.super_admin? + # resource_class + # else + # resource_class.with_less_stuff + # end + # end + + # Override `resource_params` if you want to transform the submitted + # data before it's persisted. For example, the following would turn all + # empty values into nil values. It uses other APIs such as `resource_class` + # and `dashboard`: + # + # def resource_params + # params.require(resource_class.model_name.param_key). + # permit(dashboard.permitted_attributes). + # transform_values { |value| value == "" ? nil : value } + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information +end diff --git a/app/controllers/super_admin/accounts_controller.rb b/app/controllers/super_admin/accounts_controller.rb new file mode 100644 index 000000000..4d35fa1d8 --- /dev/null +++ b/app/controllers/super_admin/accounts_controller.rb @@ -0,0 +1,44 @@ +class SuperAdmin::AccountsController < SuperAdmin::ApplicationController + # Overwrite any of the RESTful controller actions to implement custom behavior + # For example, you may want to send an email after a foo is updated. + # + # def update + # super + # send_foo_updated_email(requested_resource) + # end + + # Override this method to specify custom lookup behavior. + # This will be used to set the resource for the `show`, `edit`, and `update` + # actions. + # + # def find_resource(param) + # Foo.find_by!(slug: param) + # end + + # The result of this lookup will be available as `requested_resource` + + # Override this if you have certain roles that require a subset + # this will be used to set the records shown on the `index` action. + # + # def scoped_resource + # if current_user.super_admin? + # resource_class + # else + # resource_class.with_less_stuff + # end + # end + + # Override `resource_params` if you want to transform the submitted + # data before it's persisted. For example, the following would turn all + # empty values into nil values. It uses other APIs such as `resource_class` + # and `dashboard`: + # + # def resource_params + # params.require(resource_class.model_name.param_key). + # permit(dashboard.permitted_attributes). + # transform_values { |value| value == "" ? nil : value } + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information +end diff --git a/app/controllers/super_admin/application_controller.rb b/app/controllers/super_admin/application_controller.rb new file mode 100644 index 000000000..463ad30e6 --- /dev/null +++ b/app/controllers/super_admin/application_controller.rb @@ -0,0 +1,16 @@ +# All Administrate controllers inherit from this +# `Administrate::ApplicationController`, making it the ideal place to put +# authentication logic or other before_actions. +# +# If you want to add pagination or other controller-level concerns, +# you're free to overwrite the RESTful controller actions. +class SuperAdmin::ApplicationController < Administrate::ApplicationController + # authenticiation done via devise : SuperAdmin Model + before_action :authenticate_super_admin! + + # Override this value to specify the number of elements to display at a time + # on index pages. Defaults to 20. + # def records_per_page + # params[:per_page] || 20 + # end +end diff --git a/app/controllers/super_admin/devise/sessions_controller.rb b/app/controllers/super_admin/devise/sessions_controller.rb new file mode 100644 index 000000000..fe046a522 --- /dev/null +++ b/app/controllers/super_admin/devise/sessions_controller.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +class SuperAdmin::Devise::SessionsController < Devise::SessionsController + def new + self.resource = resource_class.new(sign_in_params) + end + + def create + return unless valid_credentials? + + sign_in(@super_admin, scope: :super_admin) + flash.discard + redirect_to super_admin_users_path + end + + def destroy + sign_out + flash.discard + redirect_to '/' + end + + private + + def valid_credentials? + @super_admin = SuperAdmin.find_by!(email: params[:super_admin][:email]) + @super_admin.valid_password?(params[:super_admin][:password]) + end +end diff --git a/app/controllers/super_admin/super_admins_controller.rb b/app/controllers/super_admin/super_admins_controller.rb new file mode 100644 index 000000000..16d91a151 --- /dev/null +++ b/app/controllers/super_admin/super_admins_controller.rb @@ -0,0 +1,44 @@ +class SuperAdmin::SuperAdminsController < SuperAdmin::ApplicationController + # Overwrite any of the RESTful controller actions to implement custom behavior + # For example, you may want to send an email after a foo is updated. + # + # def update + # super + # send_foo_updated_email(requested_resource) + # end + + # Override this method to specify custom lookup behavior. + # This will be used to set the resource for the `show`, `edit`, and `update` + # actions. + # + # def find_resource(param) + # Foo.find_by!(slug: param) + # end + + # The result of this lookup will be available as `requested_resource` + + # Override this if you have certain roles that require a subset + # this will be used to set the records shown on the `index` action. + # + # def scoped_resource + # if current_user.super_admin? + # resource_class + # else + # resource_class.with_less_stuff + # end + # end + + # Override `resource_params` if you want to transform the submitted + # data before it's persisted. For example, the following would turn all + # empty values into nil values. It uses other APIs such as `resource_class` + # and `dashboard`: + # + # def resource_params + # params.require(resource_class.model_name.param_key). + # permit(dashboard.permitted_attributes). + # transform_values { |value| value == "" ? nil : value } + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information +end diff --git a/app/controllers/super_admin/users_controller.rb b/app/controllers/super_admin/users_controller.rb new file mode 100644 index 000000000..613670849 --- /dev/null +++ b/app/controllers/super_admin/users_controller.rb @@ -0,0 +1,44 @@ +class SuperAdmin::UsersController < SuperAdmin::ApplicationController + # Overwrite any of the RESTful controller actions to implement custom behavior + # For example, you may want to send an email after a foo is updated. + # + # def update + # super + # send_foo_updated_email(requested_resource) + # end + + # Override this method to specify custom lookup behavior. + # This will be used to set the resource for the `show`, `edit`, and `update` + # actions. + # + # def find_resource(param) + # Foo.find_by!(slug: param) + # end + + # The result of this lookup will be available as `requested_resource` + + # Override this if you have certain roles that require a subset + # this will be used to set the records shown on the `index` action. + # + # def scoped_resource + # if current_user.super_admin? + # resource_class + # else + # resource_class.with_less_stuff + # end + # end + + # Override `resource_params` if you want to transform the submitted + # data before it's persisted. For example, the following would turn all + # empty values into nil values. It uses other APIs such as `resource_class` + # and `dashboard`: + # + # def resource_params + # params.require(resource_class.model_name.param_key). + # permit(dashboard.permitted_attributes). + # transform_values { |value| value == "" ? nil : value } + # end + + # See https://administrate-prototype.herokuapp.com/customizing_controller_actions + # for more information +end diff --git a/app/dashboards/access_token_dashboard.rb b/app/dashboards/access_token_dashboard.rb new file mode 100644 index 000000000..bdc50a7db --- /dev/null +++ b/app/dashboards/access_token_dashboard.rb @@ -0,0 +1,66 @@ +require 'administrate/base_dashboard' + +class AccessTokenDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + owner: Field::Polymorphic, + id: Field::Number, + token: Field::String, + created_at: Field::DateTime, + updated_at: Field::DateTime + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = %i[ + owner + id + token + created_at + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = %i[ + owner + id + token + created_at + updated_at + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = %i[ + owner + token + ].freeze + + # COLLECTION_FILTERS + # a hash that defines filters that can be used while searching via the search + # field of the dashboard. + # + # For example to add an option to search for open resources by typing "open:" + # in the search field: + # + # COLLECTION_FILTERS = { + # open: ->(resources) { resources.where(open: true) } + # }.freeze + COLLECTION_FILTERS = {}.freeze + + # Overwrite this method to customize how access tokens are displayed + # across all pages of the admin dashboard. + # + # def display_resource(access_token) + # "AccessToken ##{access_token.id}" + # end +end diff --git a/app/dashboards/account_dashboard.rb b/app/dashboards/account_dashboard.rb new file mode 100644 index 000000000..d80abc199 --- /dev/null +++ b/app/dashboards/account_dashboard.rb @@ -0,0 +1,64 @@ +require 'administrate/base_dashboard' + +class AccountDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + id: Field::Number, + name: Field::String, + created_at: Field::DateTime, + updated_at: Field::DateTime, + locale: Field::String.with_options(searchable: false) + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = %i[ + name + locale + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = %i[ + id + name + created_at + updated_at + locale + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = %i[ + name + locale + ].freeze + + # COLLECTION_FILTERS + # a hash that defines filters that can be used while searching via the search + # field of the dashboard. + # + # For example to add an option to search for open resources by typing "open:" + # in the search field: + # + # COLLECTION_FILTERS = { + # open: ->(resources) { resources.where(open: true) } + # }.freeze + COLLECTION_FILTERS = {}.freeze + + # Overwrite this method to customize how accounts are displayed + # across all pages of the admin dashboard. + # + # def display_resource(account) + # "Account ##{account.id}" + # end +end diff --git a/app/dashboards/super_admin_dashboard.rb b/app/dashboards/super_admin_dashboard.rb new file mode 100644 index 000000000..4ceab3a17 --- /dev/null +++ b/app/dashboards/super_admin_dashboard.rb @@ -0,0 +1,81 @@ +require 'administrate/base_dashboard' + +class SuperAdminDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + id: Field::Number, + email: Field::String, + access_token: Field::HasOne, + remember_created_at: Field::DateTime, + sign_in_count: Field::Number, + current_sign_in_at: Field::DateTime, + last_sign_in_at: Field::DateTime, + current_sign_in_ip: Field::String.with_options(searchable: false), + last_sign_in_ip: Field::String.with_options(searchable: false), + created_at: Field::DateTime, + updated_at: Field::DateTime + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = %i[ + id + email + access_token + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = %i[ + id + email + remember_created_at + sign_in_count + current_sign_in_at + last_sign_in_at + current_sign_in_ip + last_sign_in_ip + created_at + updated_at + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = %i[ + email + remember_created_at + sign_in_count + current_sign_in_at + last_sign_in_at + current_sign_in_ip + last_sign_in_ip + ].freeze + + # COLLECTION_FILTERS + # a hash that defines filters that can be used while searching via the search + # field of the dashboard. + # + # For example to add an option to search for open resources by typing "open:" + # in the search field: + # + # COLLECTION_FILTERS = { + # open: ->(resources) { resources.where(open: true) } + # }.freeze + COLLECTION_FILTERS = {}.freeze + + # Overwrite this method to customize how super admins are displayed + # across all pages of the admin dashboard. + # + # def display_resource(super_admin) + # "SuperAdmin ##{super_admin.id}" + # end +end diff --git a/app/dashboards/user_dashboard.rb b/app/dashboards/user_dashboard.rb new file mode 100644 index 000000000..e8d24eae2 --- /dev/null +++ b/app/dashboards/user_dashboard.rb @@ -0,0 +1,88 @@ +require 'administrate/base_dashboard' + +class UserDashboard < Administrate::BaseDashboard + # ATTRIBUTE_TYPES + # a hash that describes the type of each of the model's fields. + # + # Each different type represents an Administrate::Field object, + # which determines how the attribute is displayed + # on pages throughout the dashboard. + ATTRIBUTE_TYPES = { + account_users: Field::HasMany, + accounts: Field::HasMany, + invitees: Field::HasMany.with_options(class_name: 'User'), + id: Field::Number, + provider: Field::String, + uid: Field::String, + reset_password_token: Field::String, + reset_password_sent_at: Field::DateTime, + remember_created_at: Field::DateTime, + sign_in_count: Field::Number, + current_sign_in_at: Field::DateTime, + last_sign_in_at: Field::DateTime, + current_sign_in_ip: Field::String, + last_sign_in_ip: Field::String, + confirmation_token: Field::String, + confirmed_at: Field::DateTime, + confirmation_sent_at: Field::DateTime, + unconfirmed_email: Field::String, + name: Field::String, + nickname: Field::String, + email: Field::String, + tokens: Field::String.with_options(searchable: false), + created_at: Field::DateTime, + updated_at: Field::DateTime, + pubsub_token: Field::String + }.freeze + + # COLLECTION_ATTRIBUTES + # an array of attributes that will be displayed on the model's index page. + # + # By default, it's limited to four items to reduce clutter on index pages. + # Feel free to add, remove, or rearrange items. + COLLECTION_ATTRIBUTES = %i[ + name + email + ].freeze + + # SHOW_PAGE_ATTRIBUTES + # an array of attributes that will be displayed on the model's show page. + SHOW_PAGE_ATTRIBUTES = %i[ + accounts + id + unconfirmed_email + name + nickname + email + created_at + updated_at + ].freeze + + # FORM_ATTRIBUTES + # an array of attributes that will be displayed + # on the model's form (`new` and `edit`) pages. + FORM_ATTRIBUTES = %i[ + name + nickname + email + ].freeze + + # COLLECTION_FILTERS + # a hash that defines filters that can be used while searching via the search + # field of the dashboard. + # + # For example to add an option to search for open resources by typing "open:" + # in the search field: + # + # COLLECTION_FILTERS = { + # open: ->(resources) { resources.where(open: true) } + # }.freeze + COLLECTION_FILTERS = {}.freeze + + # Overwrite this method to customize how users are displayed + # across all pages of the admin dashboard. + # + # def display_resource(user) + # "User ##{user.id}" + # end +end diff --git a/app/javascript/dashboard/assets/scss/super_admin/index.scss b/app/javascript/dashboard/assets/scss/super_admin/index.scss new file mode 100644 index 000000000..c45cf2e22 --- /dev/null +++ b/app/javascript/dashboard/assets/scss/super_admin/index.scss @@ -0,0 +1,5 @@ +@import '../variables'; + +.superadmin-body { + background: $color-background; +} diff --git a/app/javascript/dashboard/assets/scss/super_admin/pages.scss b/app/javascript/dashboard/assets/scss/super_admin/pages.scss new file mode 100644 index 000000000..91b62d671 --- /dev/null +++ b/app/javascript/dashboard/assets/scss/super_admin/pages.scss @@ -0,0 +1,13 @@ +@import 'shared/assets/fonts/inter'; +@import '../variables'; + +body { + background-color: $color-background; + font-family: Inter; +} + +.button { + background-color: $color-woot; + border-radius: 1px solid $color-woot; + color: $color-white; +} diff --git a/app/javascript/packs/superadmin.js b/app/javascript/packs/superadmin.js new file mode 100644 index 000000000..90e58bd5e --- /dev/null +++ b/app/javascript/packs/superadmin.js @@ -0,0 +1,2 @@ +import '../dashboard/assets/scss/app.scss'; +import '../dashboard/assets/scss/super_admin/index.scss'; diff --git a/app/javascript/packs/superadmin_pages.js b/app/javascript/packs/superadmin_pages.js new file mode 100644 index 000000000..4870b6f0f --- /dev/null +++ b/app/javascript/packs/superadmin_pages.js @@ -0,0 +1 @@ +import '../dashboard/assets/scss/super_admin/pages.scss'; diff --git a/app/models/super_admin.rb b/app/models/super_admin.rb new file mode 100644 index 000000000..72b1ceb8a --- /dev/null +++ b/app/models/super_admin.rb @@ -0,0 +1,27 @@ +# == Schema Information +# +# Table name: super_admins +# +# id :bigint not null, primary key +# current_sign_in_at :datetime +# current_sign_in_ip :inet +# email :string default(""), not null +# encrypted_password :string default(""), not null +# last_sign_in_at :datetime +# last_sign_in_ip :inet +# remember_created_at :datetime +# sign_in_count :integer default(0), not null +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_super_admins_on_email (email) UNIQUE +# +class SuperAdmin < ApplicationRecord + # Include default devise modules. Others available are: + # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable + devise :database_authenticatable, :trackable, :rememberable, :validatable + + include AccessTokenable +end diff --git a/app/views/super_admin/application/_navigation.html.erb b/app/views/super_admin/application/_navigation.html.erb new file mode 100644 index 000000000..348309e7b --- /dev/null +++ b/app/views/super_admin/application/_navigation.html.erb @@ -0,0 +1,27 @@ +<%# +# Navigation + +This partial is used to display the navigation in Administrate. +By default, the navigation contains navigation links +for all resources in the admin dashboard, +as defined by the routes in the `admin/` namespace +%> + +<%= javascript_pack_tag 'superadmin_pages' %> +<%= stylesheet_pack_tag 'superadmin_pages' %> + + + diff --git a/app/views/super_admin/devise/sessions/new.html.erb b/app/views/super_admin/devise/sessions/new.html.erb new file mode 100644 index 000000000..294ee66ee --- /dev/null +++ b/app/views/super_admin/devise/sessions/new.html.erb @@ -0,0 +1,43 @@ + + +
++ <%= f.check_box :remember_me %> Remember me +
+ +