diff --git a/app/controllers/staffs/accounts/contacts_controller.rb b/app/controllers/staffs/accounts/contacts_controller.rb
new file mode 100644
index 0000000..d8cf3f1
--- /dev/null
+++ b/app/controllers/staffs/accounts/contacts_controller.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class Staffs::Accounts::ContactsController < ApplicationController
+ include PaginalController
+
+ before_action :set_account
+
+ # GET /staff/accounts/:account_nickname/contacts
+ def index
+ authorize [:staff, Account, Contact]
+
+ @contacts = policy_scope(
+ @account.contact_list.contacts,
+ policy_scope_class: Staff::Account::ContactPolicy::Scope,
+ ).page(active_page)
+ end
+
+private
+
+ def set_account
+ @account = Account.find_by! nickname: params[:account_nickname]
+ end
+end
diff --git a/app/policies/staff/account/contact_policy.rb b/app/policies/staff/account/contact_policy.rb
new file mode 100644
index 0000000..dad6b84
--- /dev/null
+++ b/app/policies/staff/account/contact_policy.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class Staff::Account::ContactPolicy < ApplicationPolicy
+ def index?
+ return false if restricted?
+
+ account&.superuser?
+ end
+
+ class Scope < Scope
+ def resolve
+ return scope.none if restricted?
+
+ return scope.all if account&.superuser?
+
+ scope.none
+ end
+ end
+end
diff --git a/app/views/staffs/accounts/_nav_tabs.html.erb b/app/views/staffs/accounts/_nav_tabs.html.erb
new file mode 100644
index 0000000..5494eed
--- /dev/null
+++ b/app/views/staffs/accounts/_nav_tabs.html.erb
@@ -0,0 +1,14 @@
+
+ <%= nav_tabs(
+ :account,
+ tab,
+ overview: [
+ policy([:staff, account]).show?,
+ [:staff, account],
+ ],
+ contacts: [
+ policy([:staff, Account, Contact]).index?,
+ staff_account_contacts_path(account),
+ ],
+ ) %>
+
diff --git a/app/views/staffs/accounts/contacts/_table.html.erb b/app/views/staffs/accounts/contacts/_table.html.erb
new file mode 100644
index 0000000..dddcb64
--- /dev/null
+++ b/app/views/staffs/accounts/contacts/_table.html.erb
@@ -0,0 +1,28 @@
+
+
+
+
+ <%= Contact.human_attribute_name :contact_network %>
+ |
+
+ <%= Contact.human_attribute_name :value %>
+ |
+
+
+
+
+ <% contacts.each do |contact| %>
+
+ <%= contact.contact_network.name %> |
+
+ <% if contact.link.nil? %>
+ <%= truncate contact.value %>
+ <% else %>
+ <%= link_to truncate(contact.value), contact.link, target: :_blank %>
+
+ <% end %>
+ |
+
+ <% end %>
+
+
diff --git a/app/views/staffs/accounts/contacts/index.html.erb b/app/views/staffs/accounts/contacts/index.html.erb
new file mode 100644
index 0000000..317b1ee
--- /dev/null
+++ b/app/views/staffs/accounts/contacts/index.html.erb
@@ -0,0 +1,14 @@
+
+ <%= nav_breadcrumb(
+ [translate(:staff_services), staff_root_path],
+ [Account.model_name.human(count: 0), staff_accounts_path],
+ [@account.nickname, [:staff, @account]],
+ Contact.model_name.human(count: 0),
+ ) %>
+
+ <%= render partial: 'staffs/accounts/nav_tabs',
+ locals: { account: @account, tab: :contacts } %>
+
+ <%= render partial: 'table', locals: { contacts: @contacts } %>
+ <%= pagination @contacts %>
+
diff --git a/app/views/staffs/accounts/show.html.erb b/app/views/staffs/accounts/show.html.erb
index d0ec827..ebc46fb 100644
--- a/app/views/staffs/accounts/show.html.erb
+++ b/app/views/staffs/accounts/show.html.erb
@@ -5,6 +5,9 @@
@account.nickname,
) %>
+ <%= render partial: 'nav_tabs',
+ locals: { account: @account, tab: :overview } %>
+
<% if @account.superuser? %>
diff --git a/config/locales/nav_tabs/en.yml b/config/locales/nav_tabs/en.yml
index 9556546..d64904d 100644
--- a/config/locales/nav_tabs/en.yml
+++ b/config/locales/nav_tabs/en.yml
@@ -1,5 +1,8 @@
en:
nav_tabs:
+ account:
+ overview: Overview
+ contacts: Contacts
person:
overview: Overview
person_comments: Comments
diff --git a/config/locales/nav_tabs/ru.yml b/config/locales/nav_tabs/ru.yml
index fa58b02..4092958 100644
--- a/config/locales/nav_tabs/ru.yml
+++ b/config/locales/nav_tabs/ru.yml
@@ -1,5 +1,8 @@
ru:
nav_tabs:
+ account:
+ overview: Обзор
+ contacts: Контакты
person:
overview: Обзор
person_comments: Комментарии
diff --git a/config/routes.rb b/config/routes.rb
index 12065fa..723d1f9 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -57,7 +57,11 @@ Rails.application.routes.draw do
get '/sidekiq', to: redirect('/', status: 307), as: :forbidden_sidekiq
- resources :accounts, param: :nickname, only: %i[index show]
+ resources :accounts, param: :nickname, only: %i[index show] do
+ resources :contacts,
+ controller: 'accounts/contacts',
+ only: :index
+ end
resources :contact_networks, only: :index
diff --git a/spec/requests/staff/accounts/contacts/index_spec.rb b/spec/requests/staff/accounts/contacts/index_spec.rb
new file mode 100644
index 0000000..af13727
--- /dev/null
+++ b/spec/requests/staff/accounts/contacts/index_spec.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe 'GET /staff/accounts/:account_nickname/contacts' do
+ let(:current_account) { create :superuser_account }
+
+ let(:some_account) { create :initial_account }
+
+ let :contacts_count do
+ [0, 1, rand(2..4), rand(5..10), rand(20..40)].sample
+ end
+
+ before do
+ sign_in current_account.user if current_account&.user
+
+ create_list :some_contact, contacts_count,
+ contact_list: some_account.contact_list
+
+ get "/staff/accounts/#{some_account.nickname}/contacts"
+ end
+
+ it_behaves_like 'paginal controller', :contacts_count
+
+ for_account_types nil, :usual do
+ specify do
+ expect(response).to have_http_status :forbidden
+ end
+ end
+
+ for_account_types :superuser do
+ specify do
+ expect(response).to have_http_status :ok
+ end
+ end
+end