From 1090ef9476cfba72bc68a372907f7ce0cbdd3a81 Mon Sep 17 00:00:00 2001
From: Arnaud Levy <contact@arnaudlevy.com>
Date: Fri, 10 Mar 2023 09:55:09 +0100
Subject: [PATCH] admin controllers

---
 .../documents/application_controller.rb       |  8 +++
 .../documents/categories_controller.rb        | 67 +++++++++++++++++++
 .../extranets/documents/kinds_controller.rb   | 66 ++++++++++++++++++
 .../extranets/documents_controller.rb         |  2 +
 app/models/communication/extranet.rb          |  2 +
 app/models/communication/extranet/document.rb |  2 +
 .../extranet/document/category.rb             | 26 ++++++-
 .../communication/extranet/document/kind.rb   | 26 ++++++-
 .../documents/categories/_form.html.erb       | 25 +++++++
 .../documents/categories/_list.html.erb       | 30 +++++++++
 .../documents/categories/edit.html.erb        |  5 ++
 .../documents/categories/index.html.erb       |  9 +++
 .../documents/categories/new.html.erb         |  5 ++
 .../documents/categories/preview.html.erb     |  3 +
 .../documents/categories/show.html.erb        | 14 ++++
 .../extranets/documents/index.html.erb        | 17 ++++-
 .../extranets/documents/kinds/_form.html.erb  | 25 +++++++
 .../extranets/documents/kinds/_list.html.erb  | 30 +++++++++
 .../extranets/documents/kinds/edit.html.erb   |  5 ++
 .../extranets/documents/kinds/index.html.erb  |  9 +++
 .../extranets/documents/kinds/new.html.erb    |  5 ++
 .../documents/kinds/preview.html.erb          |  3 +
 .../extranets/documents/kinds/show.html.erb   | 14 ++++
 .../extranets/posts/index.html.erb            |  3 +-
 config/routes/admin/communication.rb          |  9 ++-
 ..._slugs_to_document_categories_and_kinds.rb |  6 ++
 db/schema.rb                                  |  4 +-
 .../extranet/document/categories.yml          |  2 +-
 .../communication/extranet/document/kinds.yml |  2 +-
 .../extranet/document/category_test.rb        |  1 +
 .../extranet/document/kind_test.rb            |  1 +
 31 files changed, 412 insertions(+), 14 deletions(-)
 create mode 100644 app/controllers/admin/communication/extranets/documents/application_controller.rb
 create mode 100644 app/controllers/admin/communication/extranets/documents/categories_controller.rb
 create mode 100644 app/controllers/admin/communication/extranets/documents/kinds_controller.rb
 create mode 100644 app/views/admin/communication/extranets/documents/categories/_form.html.erb
 create mode 100644 app/views/admin/communication/extranets/documents/categories/_list.html.erb
 create mode 100644 app/views/admin/communication/extranets/documents/categories/edit.html.erb
 create mode 100644 app/views/admin/communication/extranets/documents/categories/index.html.erb
 create mode 100644 app/views/admin/communication/extranets/documents/categories/new.html.erb
 create mode 100644 app/views/admin/communication/extranets/documents/categories/preview.html.erb
 create mode 100644 app/views/admin/communication/extranets/documents/categories/show.html.erb
 create mode 100644 app/views/admin/communication/extranets/documents/kinds/_form.html.erb
 create mode 100644 app/views/admin/communication/extranets/documents/kinds/_list.html.erb
 create mode 100644 app/views/admin/communication/extranets/documents/kinds/edit.html.erb
 create mode 100644 app/views/admin/communication/extranets/documents/kinds/index.html.erb
 create mode 100644 app/views/admin/communication/extranets/documents/kinds/new.html.erb
 create mode 100644 app/views/admin/communication/extranets/documents/kinds/preview.html.erb
 create mode 100644 app/views/admin/communication/extranets/documents/kinds/show.html.erb
 create mode 100644 db/migrate/20230310083029_add_slugs_to_document_categories_and_kinds.rb

diff --git a/app/controllers/admin/communication/extranets/documents/application_controller.rb b/app/controllers/admin/communication/extranets/documents/application_controller.rb
new file mode 100644
index 000000000..7491d2183
--- /dev/null
+++ b/app/controllers/admin/communication/extranets/documents/application_controller.rb
@@ -0,0 +1,8 @@
+class Admin::Communication::Extranets::Documents::ApplicationController < Admin::Communication::Extranets::ApplicationController
+  protected
+
+  def breadcrumb
+    super
+    add_breadcrumb Communication::Extranet.human_attribute_name(:feature_library), admin_communication_extranet_documents_path
+  end
+end
\ No newline at end of file
diff --git a/app/controllers/admin/communication/extranets/documents/categories_controller.rb b/app/controllers/admin/communication/extranets/documents/categories_controller.rb
new file mode 100644
index 000000000..5e265cb29
--- /dev/null
+++ b/app/controllers/admin/communication/extranets/documents/categories_controller.rb
@@ -0,0 +1,67 @@
+class Admin::Communication::Extranets::Documents::CategoriesController < Admin::Communication::Extranets::ApplicationController
+  load_and_authorize_resource class: Communication::Extranet::Document::Category, through: :extranet, through_association: :document_categories
+
+  def index
+    @categories = @categories.ordered
+    breadcrumb
+  end
+
+  def show
+    @documents = @category.documents.ordered.page params[:page]
+    breadcrumb
+  end
+
+  def new
+    breadcrumb
+  end
+
+  def edit
+    breadcrumb
+    add_breadcrumb t('edit')
+  end
+
+  def create
+    if @category.save
+      redirect_to admin_communication_extranet_document_category_path(@category), notice: t('admin.successfully_created_html', model: @category.to_s)
+    else
+      breadcrumb
+      render :new, status: :unprocessable_entity
+    end
+  end
+
+  def update
+    if @category.update(category_params)
+      redirect_to admin_communication_extranet_document_category_path(@category), notice: t('admin.successfully_updated_html', model: @category.to_s)
+    else
+      breadcrumb
+      add_breadcrumb t('edit')
+      render :edit, status: :unprocessable_entity
+    end
+  end
+
+  def destroy
+    @category.destroy
+    redirect_to admin_communication_extranet_document_categories_url, notice: t('admin.successfully_destroyed_html', model: @category.to_s)
+  end
+
+  protected
+
+  def breadcrumb
+    super
+    add_breadcrumb Communication::Extranet.human_attribute_name(:feature_library), admin_communication_extranet_documents_path
+    add_breadcrumb Communication::Extranet::Document::Category.model_name.human(count: 2), admin_communication_extranet_document_categories_path
+    breadcrumb_for @category
+  end
+
+  def category_params
+    params.require(:communication_extranet_document_category)
+    .permit(
+      :name,
+      :slug,
+    )
+    .merge(
+      university_id: current_university.id
+    )
+  end
+
+end
\ No newline at end of file
diff --git a/app/controllers/admin/communication/extranets/documents/kinds_controller.rb b/app/controllers/admin/communication/extranets/documents/kinds_controller.rb
new file mode 100644
index 000000000..452459396
--- /dev/null
+++ b/app/controllers/admin/communication/extranets/documents/kinds_controller.rb
@@ -0,0 +1,66 @@
+class Admin::Communication::Extranets::Documents::KindsController < Admin::Communication::Extranets::Documents::ApplicationController
+  load_and_authorize_resource class: Communication::Extranet::Document::Kind, through: :extranet, through_association: :document_kinds
+
+  def index
+    @kinds = @kinds.ordered
+    breadcrumb
+  end
+
+  def show
+    @documents = @kind.documents.ordered.page params[:page]
+    breadcrumb
+  end
+
+  def new
+    breadcrumb
+  end
+
+  def edit
+    breadcrumb
+    add_breadcrumb t('edit')
+  end
+
+  def create
+    if @kind.save
+      redirect_to admin_communication_extranet_document_kind_path(@kind), notice: t('admin.successfully_created_html', model: @kind.to_s)
+    else
+      breadcrumb
+      render :new, status: :unprocessable_entity
+    end
+  end
+
+  def update
+    if @kind.update(kind_params)
+      redirect_to admin_communication_extranet_document_kind_path(@kind), notice: t('admin.successfully_updated_html', model: @kind.to_s)
+    else
+      breadcrumb
+      add_breadcrumb t('edit')
+      render :edit, status: :unprocessable_entity
+    end
+  end
+
+  def destroy
+    @kind.destroy
+    redirect_to admin_communication_extranet_document_kinds_url, notice: t('admin.successfully_destroyed_html', model: @kind.to_s)
+  end
+
+  protected
+
+  def breadcrumb
+    super
+    add_breadcrumb Communication::Extranet::Document::Kind.model_name.human(count: 2), admin_communication_extranet_document_kinds_path
+    breadcrumb_for @kind
+  end
+
+  def kind_params
+    params.require(:communication_extranet_document_kind)
+    .permit(
+      :name,
+      :slug,
+    )
+    .merge(
+      university_id: current_university.id
+    )
+  end
+
+end
\ No newline at end of file
diff --git a/app/controllers/admin/communication/extranets/documents_controller.rb b/app/controllers/admin/communication/extranets/documents_controller.rb
index 124981dd6..dd96762fc 100644
--- a/app/controllers/admin/communication/extranets/documents_controller.rb
+++ b/app/controllers/admin/communication/extranets/documents_controller.rb
@@ -3,6 +3,8 @@ class Admin::Communication::Extranets::DocumentsController < Admin::Communicatio
 
   def index
     @documents = @documents.ordered.page params[:page]
+    @categories = @extranet.document_categories.ordered
+    @kinds = @extranet.document_kinds.ordered
     breadcrumb
   end
 
diff --git a/app/models/communication/extranet.rb b/app/models/communication/extranet.rb
index faabfae42..c8ab92c46 100644
--- a/app/models/communication/extranet.rb
+++ b/app/models/communication/extranet.rb
@@ -60,6 +60,8 @@ class Communication::Extranet < ApplicationRecord
   has_many :posts
   has_many :post_categories, class_name: 'Communication::Extranet::Post::Category'
   has_many :documents
+  has_many :document_categories, class_name: 'Communication::Extranet::Document::Category'
+  has_many :document_kinds, class_name: 'Communication::Extranet::Document::Kind'
 
   validates_presence_of :name, :host
   validates :logo, size: { less_than: 1.megabytes }
diff --git a/app/models/communication/extranet/document.rb b/app/models/communication/extranet/document.rb
index 30a353f9f..9b332be81 100644
--- a/app/models/communication/extranet/document.rb
+++ b/app/models/communication/extranet/document.rb
@@ -33,6 +33,8 @@ class Communication::Extranet::Document < ApplicationRecord
   include WithUniversity
 
   belongs_to :extranet, class_name: 'Communication::Extranet'
+  belongs_to :category
+  belongs_to :kind
 
   has_one_attached_deletable :file
 
diff --git a/app/models/communication/extranet/document/category.rb b/app/models/communication/extranet/document/category.rb
index d153fb401..91f8d0214 100644
--- a/app/models/communication/extranet/document/category.rb
+++ b/app/models/communication/extranet/document/category.rb
@@ -4,6 +4,7 @@
 #
 #  id            :uuid             not null, primary key
 #  name          :string
+#  slug          :string
 #  created_at    :datetime         not null
 #  updated_at    :datetime         not null
 #  extranet_id   :uuid             not null, indexed
@@ -20,6 +21,27 @@
 #  fk_rails_76e327b90f  (extranet_id => communication_extranets.id)
 #
 class Communication::Extranet::Document::Category < ApplicationRecord
-  belongs_to :extranet
-  belongs_to :university
+  include WithSlug
+  include WithUniversity
+
+  belongs_to :extranet, class_name: 'Communication::Extranet'
+
+  has_many :documents
+
+  validates :name, presence: true
+
+  scope :ordered, -> { order(:name) }
+
+  def to_s
+    "#{name}"
+  end
+
+  protected
+
+  def slug_unavailable?(slug)
+    self.class.unscoped
+              .where(extranet_id: self.extranet_id, slug: slug)
+              .where.not(id: self.id)
+              .exists?
+  end
 end
diff --git a/app/models/communication/extranet/document/kind.rb b/app/models/communication/extranet/document/kind.rb
index d13f6fcbf..7f3afa355 100644
--- a/app/models/communication/extranet/document/kind.rb
+++ b/app/models/communication/extranet/document/kind.rb
@@ -4,6 +4,7 @@
 #
 #  id            :uuid             not null, primary key
 #  name          :string
+#  slug          :string
 #  created_at    :datetime         not null
 #  updated_at    :datetime         not null
 #  extranet_id   :uuid             not null, indexed
@@ -20,6 +21,27 @@
 #  fk_rails_2a55cf899a  (university_id => universities.id)
 #
 class Communication::Extranet::Document::Kind < ApplicationRecord
-  belongs_to :extranet
-  belongs_to :university
+  include WithSlug
+  include WithUniversity
+
+  belongs_to :extranet, class_name: 'Communication::Extranet'
+
+  has_many :documents
+
+  validates :name, presence: true
+
+  scope :ordered, -> { order(:name) }
+
+  def to_s
+    "#{name}"
+  end
+
+  protected
+
+  def slug_unavailable?(slug)
+    self.class.unscoped
+              .where(extranet_id: self.extranet_id, slug: slug)
+              .where.not(id: self.id)
+              .exists?
+  end
 end
diff --git a/app/views/admin/communication/extranets/documents/categories/_form.html.erb b/app/views/admin/communication/extranets/documents/categories/_form.html.erb
new file mode 100644
index 000000000..1dd744a49
--- /dev/null
+++ b/app/views/admin/communication/extranets/documents/categories/_form.html.erb
@@ -0,0 +1,25 @@
+<%= simple_form_for [:admin, category] do |f| %>
+  <%= f.error_notification %>
+  <%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>
+
+  <div class="row">
+    <div class="col-md-8">
+      <%= osuny_panel t('content') do %>
+        <%= f.input :name %>
+      <% end %>
+    </div>
+    <div class="col-md-4">
+      <%= osuny_panel t('metadata') do %>
+        <%= f.input :slug,
+                    as: :string,
+                    input_html: category.persisted? ? {} : {
+                      class: 'js-slug-input',
+                      data: { source: '#communication_extranet_document_category_name' }
+                    } %>
+      <% end %>
+    </div>
+  </div>
+  <% content_for :action_bar_right do %>
+    <%= submit f %>
+  <% end %>
+<% end %>
diff --git a/app/views/admin/communication/extranets/documents/categories/_list.html.erb b/app/views/admin/communication/extranets/documents/categories/_list.html.erb
new file mode 100644
index 000000000..3bf6eb7f2
--- /dev/null
+++ b/app/views/admin/communication/extranets/documents/categories/_list.html.erb
@@ -0,0 +1,30 @@
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
+      <tr>
+        <th class="ps-0" width="60%"><%= Communication::Extranet::Document::Category.human_attribute_name('name') %></th>
+        <th></th>
+      </tr>
+    </thead>
+    <tbody>
+      <% categories.each do |category| %>
+        <tr>
+          <td class="ps-0"><%= link_to category, admin_communication_extranet_document_category_path(extranet_id: category.extranet.id, id: category.id) %></td>
+
+          <td>
+            <div class="btn-group" role="group">
+              <%= link_to t('edit'),
+                          edit_admin_communication_extranet_document_category_path(extranet_id: category.extranet.id, id: category.id),
+                          class: button_classes if can?(:update, category) %>
+              <%= link_to t('delete'),
+                          admin_communication_extranet_document_category_path(extranet_id: category.extranet.id, id: category.id),
+                          method: :delete,
+                          data: { confirm: t('please_confirm') },
+                          class: button_classes_danger if can?(:destroy, category) %>
+            </div>
+          </td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
diff --git a/app/views/admin/communication/extranets/documents/categories/edit.html.erb b/app/views/admin/communication/extranets/documents/categories/edit.html.erb
new file mode 100644
index 000000000..213c0056b
--- /dev/null
+++ b/app/views/admin/communication/extranets/documents/categories/edit.html.erb
@@ -0,0 +1,5 @@
+<% content_for :title, @category %>
+
+<%= render 'admin/communication/extranets/sidebar' do %>
+  <%= render 'form', category: @category %>
+<% end %>
diff --git a/app/views/admin/communication/extranets/documents/categories/index.html.erb b/app/views/admin/communication/extranets/documents/categories/index.html.erb
new file mode 100644
index 000000000..c4e9bfba6
--- /dev/null
+++ b/app/views/admin/communication/extranets/documents/categories/index.html.erb
@@ -0,0 +1,9 @@
+<% content_for :title, Communication::Extranet::Post::Category.model_name.human(count: 2) %>
+
+<%= render 'admin/communication/extranets/sidebar' do %>
+  <%= render 'admin/communication/extranets/documents/categories/list', categories: @categories %>
+<% end %>
+
+<% content_for :action_bar_right do %>
+  <%= create_link Communication::Extranet::Post::Category %>
+<% end %>
\ No newline at end of file
diff --git a/app/views/admin/communication/extranets/documents/categories/new.html.erb b/app/views/admin/communication/extranets/documents/categories/new.html.erb
new file mode 100644
index 000000000..dffe93cc2
--- /dev/null
+++ b/app/views/admin/communication/extranets/documents/categories/new.html.erb
@@ -0,0 +1,5 @@
+<% content_for :title, Communication::Extranet::Post::Category.model_name.human %>
+
+<%= render 'admin/communication/extranets/sidebar' do %>
+  <%= render 'form', category: @category %>
+<% end %>
diff --git a/app/views/admin/communication/extranets/documents/categories/preview.html.erb b/app/views/admin/communication/extranets/documents/categories/preview.html.erb
new file mode 100644
index 000000000..14bd7cd48
--- /dev/null
+++ b/app/views/admin/communication/extranets/documents/categories/preview.html.erb
@@ -0,0 +1,3 @@
+<% content_for :title, @post.title %>
+<% content_for :image, kamifusen_tag(@post.featured_image) if @post.featured_image.attached? %>
+<%= render 'admin/communication/blocks/preview', about: @post %>
diff --git a/app/views/admin/communication/extranets/documents/categories/show.html.erb b/app/views/admin/communication/extranets/documents/categories/show.html.erb
new file mode 100644
index 000000000..96479dd7b
--- /dev/null
+++ b/app/views/admin/communication/extranets/documents/categories/show.html.erb
@@ -0,0 +1,14 @@
+<% content_for :title, @category %>
+
+<%= render 'admin/communication/extranets/sidebar' do %>
+  <%= render 'admin/communication/extranets/documents/list', documents: @documents %>
+  <%= paginate @documents, theme: 'bootstrap-5' %>
+<% end %>
+
+<% content_for :action_bar_left do %>
+  <%= destroy_link @category %>
+<% end %>
+
+<% content_for :action_bar_right do %>
+  <%= edit_link @category %>
+<% end %>
diff --git a/app/views/admin/communication/extranets/documents/index.html.erb b/app/views/admin/communication/extranets/documents/index.html.erb
index 40ec6ed9a..9f92cca16 100644
--- a/app/views/admin/communication/extranets/documents/index.html.erb
+++ b/app/views/admin/communication/extranets/documents/index.html.erb
@@ -1,8 +1,21 @@
 <% content_for :title, Communication::Extranet.human_attribute_name(:feature_library) %>
 
 <%= render 'admin/communication/extranets/sidebar' do %>
-  <%= render 'admin/communication/extranets/documents/list', documents: @documents %>
-  <%= paginate @documents, theme: 'bootstrap-5' %>
+  <section class="mb-5">
+    <%= render 'admin/communication/extranets/documents/list', documents: @documents %>
+    <%= paginate @documents, theme: 'bootstrap-5' %>
+  </section>
+
+  <% action = link_to t('create'), new_admin_communication_extranet_document_category_path, class: button_classes %>
+  <%= osuny_panel Communication::Extranet::Document::Category.model_name.human(count: 2), action: action do %>
+    <%= render 'admin/communication/extranets/documents/categories/list', categories: @categories %>
+  <% end %>
+
+  <% action = link_to t('create'), new_admin_communication_extranet_document_kind_path, class: button_classes %>
+  <%= osuny_panel Communication::Extranet::Document::Kind.model_name.human(count: 2), action: action do %>
+    <%= render 'admin/communication/extranets/documents/kinds/list', kinds: @kinds %>
+  <% end %>
+
 <% end %>
 
 <% content_for :action_bar_right do %>
diff --git a/app/views/admin/communication/extranets/documents/kinds/_form.html.erb b/app/views/admin/communication/extranets/documents/kinds/_form.html.erb
new file mode 100644
index 000000000..bfb75b8b5
--- /dev/null
+++ b/app/views/admin/communication/extranets/documents/kinds/_form.html.erb
@@ -0,0 +1,25 @@
+<%= simple_form_for [:admin, kind] do |f| %>
+  <%= f.error_notification %>
+  <%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>
+
+  <div class="row">
+    <div class="col-md-8">
+      <%= osuny_panel t('content') do %>
+        <%= f.input :name %>
+      <% end %>
+    </div>
+    <div class="col-md-4">
+      <%= osuny_panel t('metadata') do %>
+        <%= f.input :slug,
+                    as: :string,
+                    input_html: kind.persisted? ? {} : {
+                      class: 'js-slug-input',
+                      data: { source: '#communication_extranet_document_kind_name' }
+                    } %>
+      <% end %>
+    </div>
+  </div>
+  <% content_for :action_bar_right do %>
+    <%= submit f %>
+  <% end %>
+<% end %>
diff --git a/app/views/admin/communication/extranets/documents/kinds/_list.html.erb b/app/views/admin/communication/extranets/documents/kinds/_list.html.erb
new file mode 100644
index 000000000..602b8e38b
--- /dev/null
+++ b/app/views/admin/communication/extranets/documents/kinds/_list.html.erb
@@ -0,0 +1,30 @@
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
+      <tr>
+        <th class="ps-0" width="60%"><%= Communication::Extranet::Post::Category.human_attribute_name('name') %></th>
+        <th></th>
+      </tr>
+    </thead>
+    <tbody>
+      <% kinds.each do |kind| %>
+        <tr>
+          <td class="ps-0"><%= link_to kind, admin_communication_extranet_document_kind_path(extranet_id: kind.extranet.id, id: kind.id) %></td>
+
+          <td>
+            <div class="btn-group" role="group">
+              <%= link_to t('edit'),
+                          edit_admin_communication_extranet_document_kind_path(extranet_id: kind.extranet.id, id: kind.id),
+                          class: button_classes if can?(:update, kind) %>
+              <%= link_to t('delete'),
+                          admin_communication_extranet_document_kind_path(extranet_id: kind.extranet.id, id: kind.id),
+                          method: :delete,
+                          data: { confirm: t('please_confirm') },
+                          class: button_classes_danger if can?(:destroy, kind) %>
+            </div>
+          </td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
diff --git a/app/views/admin/communication/extranets/documents/kinds/edit.html.erb b/app/views/admin/communication/extranets/documents/kinds/edit.html.erb
new file mode 100644
index 000000000..6a33b3912
--- /dev/null
+++ b/app/views/admin/communication/extranets/documents/kinds/edit.html.erb
@@ -0,0 +1,5 @@
+<% content_for :title, @kind %>
+
+<%= render 'admin/communication/extranets/sidebar' do %>
+  <%= render 'form', kind: @kind %>
+<% end %>
diff --git a/app/views/admin/communication/extranets/documents/kinds/index.html.erb b/app/views/admin/communication/extranets/documents/kinds/index.html.erb
new file mode 100644
index 000000000..c10c021d7
--- /dev/null
+++ b/app/views/admin/communication/extranets/documents/kinds/index.html.erb
@@ -0,0 +1,9 @@
+<% content_for :title, Communication::Extranet::Document::Kind.model_name.human(count: 2) %>
+
+<%= render 'admin/communication/extranets/sidebar' do %>
+  <%= render 'admin/communication/extranets/documents/kinds/list', kinds: @kinds %>
+<% end %>
+
+<% content_for :action_bar_right do %>
+  <%= create_link Communication::Extranet::Document::Kind %>
+<% end %>
\ No newline at end of file
diff --git a/app/views/admin/communication/extranets/documents/kinds/new.html.erb b/app/views/admin/communication/extranets/documents/kinds/new.html.erb
new file mode 100644
index 000000000..c7b31afd7
--- /dev/null
+++ b/app/views/admin/communication/extranets/documents/kinds/new.html.erb
@@ -0,0 +1,5 @@
+<% content_for :title, Communication::Extranet::Document::Kind.model_name.human %>
+
+<%= render 'admin/communication/extranets/sidebar' do %>
+  <%= render 'form', kind: @kind %>
+<% end %>
diff --git a/app/views/admin/communication/extranets/documents/kinds/preview.html.erb b/app/views/admin/communication/extranets/documents/kinds/preview.html.erb
new file mode 100644
index 000000000..14bd7cd48
--- /dev/null
+++ b/app/views/admin/communication/extranets/documents/kinds/preview.html.erb
@@ -0,0 +1,3 @@
+<% content_for :title, @post.title %>
+<% content_for :image, kamifusen_tag(@post.featured_image) if @post.featured_image.attached? %>
+<%= render 'admin/communication/blocks/preview', about: @post %>
diff --git a/app/views/admin/communication/extranets/documents/kinds/show.html.erb b/app/views/admin/communication/extranets/documents/kinds/show.html.erb
new file mode 100644
index 000000000..2710035a8
--- /dev/null
+++ b/app/views/admin/communication/extranets/documents/kinds/show.html.erb
@@ -0,0 +1,14 @@
+<% content_for :title, @kind %>
+
+<%= render 'admin/communication/extranets/sidebar' do %>
+  <%= render 'admin/communication/extranets/documents/list', documents: @documents %>
+  <%= paginate @documents, theme: 'bootstrap-5' %>
+<% end %>
+
+<% content_for :action_bar_left do %>
+  <%= destroy_link @kind %>
+<% end %>
+
+<% content_for :action_bar_right do %>
+  <%= edit_link @kind %>
+<% end %>
diff --git a/app/views/admin/communication/extranets/posts/index.html.erb b/app/views/admin/communication/extranets/posts/index.html.erb
index cbf3d5fdf..831db566e 100644
--- a/app/views/admin/communication/extranets/posts/index.html.erb
+++ b/app/views/admin/communication/extranets/posts/index.html.erb
@@ -7,8 +7,7 @@
   </section>
 
   <% action = link_to t('create'), new_admin_communication_extranet_post_category_path, class: button_classes %>
-  <%# action = create_link Communication::Website::Category %>
-  <%= osuny_panel Communication::Website::Category.model_name.human(count: 2), action: action do %>
+  <%= osuny_panel Communication::Extranet::Post::Category.model_name.human(count: 2), action: action do %>
     <%= render 'admin/communication/extranets/posts/categories/list', categories: @categories %>
   <% end %>
 <% end %>
diff --git a/config/routes/admin/communication.rb b/config/routes/admin/communication.rb
index 5db6d8e7f..1be8ac580 100644
--- a/config/routes/admin/communication.rb
+++ b/config/routes/admin/communication.rb
@@ -73,8 +73,6 @@ namespace :communication do
         post :disconnect
       end
     end
-    namespace :posts do
-    end
     resources :posts, controller: 'extranets/posts' do
       collection do
         resources :categories, controller: 'extranets/posts/categories', as: 'post_categories'
@@ -85,7 +83,12 @@ namespace :communication do
     end
     # Automatic routes based on feature names
     get 'library' => 'extranets/documents#index', as: :library
-    resources :documents, controller: 'extranets/documents'
+    resources :documents, controller: 'extranets/documents' do
+      collection do
+        resources :categories, controller: 'extranets/documents/categories', as: 'document_categories'
+        resources :kinds, controller: 'extranets/documents/kinds', as: 'document_kinds'
+      end
+    end
     resources :jobs, controller: 'extranets/jobs'
   end
   resources :alumni do
diff --git a/db/migrate/20230310083029_add_slugs_to_document_categories_and_kinds.rb b/db/migrate/20230310083029_add_slugs_to_document_categories_and_kinds.rb
new file mode 100644
index 000000000..1e64b54ce
--- /dev/null
+++ b/db/migrate/20230310083029_add_slugs_to_document_categories_and_kinds.rb
@@ -0,0 +1,6 @@
+class AddSlugsToDocumentCategoriesAndKinds < ActiveRecord::Migration[7.0]
+  def change
+    add_column :communication_extranet_document_categories, :slug, :string
+    add_column :communication_extranet_document_kinds, :slug, :string
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 139e94000..e8777f0bc 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema[7.0].define(version: 2023_03_10_081530) do
+ActiveRecord::Schema[7.0].define(version: 2023_03_10_083029) do
   # These are extensions that must be enabled in order to support this database
   enable_extension "pgcrypto"
   enable_extension "plpgsql"
@@ -111,6 +111,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_03_10_081530) do
     t.string "name"
     t.datetime "created_at", null: false
     t.datetime "updated_at", null: false
+    t.string "slug"
     t.index ["extranet_id"], name: "index_communication_extranet_document_categories_on_extranet_id"
     t.index ["university_id"], name: "extranet_document_categories_universities"
   end
@@ -121,6 +122,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_03_10_081530) do
     t.string "name"
     t.datetime "created_at", null: false
     t.datetime "updated_at", null: false
+    t.string "slug"
     t.index ["extranet_id"], name: "index_communication_extranet_document_kinds_on_extranet_id"
     t.index ["university_id"], name: "extranet_document_kinds_universities"
   end
diff --git a/test/fixtures/communication/extranet/document/categories.yml b/test/fixtures/communication/extranet/document/categories.yml
index 5d73fea14..db2c02aa9 100644
--- a/test/fixtures/communication/extranet/document/categories.yml
+++ b/test/fixtures/communication/extranet/document/categories.yml
@@ -4,6 +4,7 @@
 #
 #  id            :uuid             not null, primary key
 #  name          :string
+#  slug          :string
 #  created_at    :datetime         not null
 #  updated_at    :datetime         not null
 #  extranet_id   :uuid             not null, indexed
@@ -19,7 +20,6 @@
 #  fk_rails_6f2232d9f8  (university_id => universities.id)
 #  fk_rails_76e327b90f  (extranet_id => communication_extranets.id)
 #
-# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
 
 one:
   extranet: one
diff --git a/test/fixtures/communication/extranet/document/kinds.yml b/test/fixtures/communication/extranet/document/kinds.yml
index bae066a93..480abfc3a 100644
--- a/test/fixtures/communication/extranet/document/kinds.yml
+++ b/test/fixtures/communication/extranet/document/kinds.yml
@@ -4,6 +4,7 @@
 #
 #  id            :uuid             not null, primary key
 #  name          :string
+#  slug          :string
 #  created_at    :datetime         not null
 #  updated_at    :datetime         not null
 #  extranet_id   :uuid             not null, indexed
@@ -19,7 +20,6 @@
 #  fk_rails_27a9b91ed8  (extranet_id => communication_extranets.id)
 #  fk_rails_2a55cf899a  (university_id => universities.id)
 #
-# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
 
 one:
   extranet: one
diff --git a/test/models/communication/extranet/document/category_test.rb b/test/models/communication/extranet/document/category_test.rb
index ef2a32707..6c922f246 100644
--- a/test/models/communication/extranet/document/category_test.rb
+++ b/test/models/communication/extranet/document/category_test.rb
@@ -4,6 +4,7 @@
 #
 #  id            :uuid             not null, primary key
 #  name          :string
+#  slug          :string
 #  created_at    :datetime         not null
 #  updated_at    :datetime         not null
 #  extranet_id   :uuid             not null, indexed
diff --git a/test/models/communication/extranet/document/kind_test.rb b/test/models/communication/extranet/document/kind_test.rb
index 7c37fe74c..acca11c4c 100644
--- a/test/models/communication/extranet/document/kind_test.rb
+++ b/test/models/communication/extranet/document/kind_test.rb
@@ -4,6 +4,7 @@
 #
 #  id            :uuid             not null, primary key
 #  name          :string
+#  slug          :string
 #  created_at    :datetime         not null
 #  updated_at    :datetime         not null
 #  extranet_id   :uuid             not null, indexed
-- 
GitLab