diff --git a/app/assets/javascripts/discourse/app/helpers/category-badge.js b/app/assets/javascripts/discourse/app/helpers/category-badge.js
index b9e51674c91..ec697eecc63 100644
--- a/app/assets/javascripts/discourse/app/helpers/category-badge.js
+++ b/app/assets/javascripts/discourse/app/helpers/category-badge.js
@@ -1,12 +1,14 @@
 import { categoryLinkHTML } from "discourse/helpers/category-link";
-import { registerUnbound } from "discourse-common/lib/helpers";
 import { isPresent } from "@ember/utils";
+import { registerRawHelper } from "discourse-common/lib/helpers";
 
-registerUnbound("category-badge", function (cat, options) {
+registerRawHelper("category-badge", categoryBadge);
+
+export default function categoryBadge(cat, options = {}) {
   return categoryLinkHTML(cat, {
     hideParent: options.hideParent,
     allowUncategorized: options.allowUncategorized,
     categoryStyle: options.categoryStyle,
     link: isPresent(options.link) ? options.link : false,
   });
-});
+}
diff --git a/app/assets/javascripts/discourse/app/helpers/replace-emoji.js b/app/assets/javascripts/discourse/app/helpers/replace-emoji.js
index 81d78a3a1f4..13c1f7ea193 100644
--- a/app/assets/javascripts/discourse/app/helpers/replace-emoji.js
+++ b/app/assets/javascripts/discourse/app/helpers/replace-emoji.js
@@ -1,9 +1,11 @@
 import { emojiUnescape } from "discourse/lib/text";
 import { htmlSafe, isHTMLSafe } from "@ember/template";
-import { registerUnbound } from "discourse-common/lib/helpers";
 import { escapeExpression } from "discourse/lib/utilities";
+import { registerRawHelper } from "discourse-common/lib/helpers";
 
-registerUnbound("replace-emoji", (text, options) => {
+registerRawHelper("replace-emoji", replaceEmoji);
+
+export default function replaceEmoji(text, options) {
   text = isHTMLSafe(text) ? text.toString() : escapeExpression(text);
   return htmlSafe(emojiUnescape(text, options));
-});
+}
diff --git a/app/assets/javascripts/float-kit/addon/lib/constants.js b/app/assets/javascripts/float-kit/addon/lib/constants.js
index 64a1a39c25e..6590e1820d8 100644
--- a/app/assets/javascripts/float-kit/addon/lib/constants.js
+++ b/app/assets/javascripts/float-kit/addon/lib/constants.js
@@ -70,7 +70,7 @@ import DDefaultToast from "float-kit/components/d-default-toast";
 export const TOAST = {
   options: {
     autoClose: true,
-    duration: 10000,
+    duration: 3000,
     component: DDefaultToast,
   },
 };
diff --git a/plugins/chat/assets/javascripts/discourse/chat-route-map.js b/plugins/chat/assets/javascripts/discourse/chat-route-map.js
index 7237e535014..2131b6b82cd 100644
--- a/plugins/chat/assets/javascripts/discourse/chat-route-map.js
+++ b/plugins/chat/assets/javascripts/discourse/chat-route-map.js
@@ -12,7 +12,6 @@ export default function () {
       "channel.info",
       { path: "/c/:channelTitle/:channelId/info" },
       function () {
-        this.route("about", { path: "/about" });
         this.route("members", { path: "/members" });
         this.route("settings", { path: "/settings" });
       }
diff --git a/plugins/chat/assets/javascripts/discourse/components/chat-channel-about-view.hbs b/plugins/chat/assets/javascripts/discourse/components/chat-channel-about-view.hbs
deleted file mode 100644
index 23046d405b3..00000000000
--- a/plugins/chat/assets/javascripts/discourse/components/chat-channel-about-view.hbs
+++ /dev/null
@@ -1,93 +0,0 @@
-{{#if this.channel.isCategoryChannel}}
-  <div class="chat-form__section">
-    <div class="chat-form__field">
-      <label class="chat-form__label">
-        {{i18n "chat.about_view.associated_category"}}
-      </label>
-      <div class="chat-form__control">
-        {{category-badge
-          this.channel.chatable
-          link=true
-          allowUncategorized=true
-        }}
-      </div>
-    </div>
-  </div>
-{{/if}}
-
-<div class="chat-form__section">
-  <div class="chat-form__field">
-    <label class="chat-form__label">
-      <span>{{i18n "chat.about_view.name"}}</span>
-      {{#if (chat-guardian "can-edit-chat-channel")}}
-        <div class="chat-form__label-actions">
-          <DButton
-            @label="chat.channel_settings.edit"
-            @action={{if this.onEditChatChannelName this.onEditChatChannelName}}
-            class="edit-name-slug-btn btn-flat"
-          />
-        </div>
-      {{/if}}
-    </label>
-    <div class="chat-form__control">
-      <div class="channel-info-about-view__name">
-        {{replace-emoji this.channel.title}}
-      </div>
-      <div class="channel-info-about-view__slug">
-        {{this.channel.slug}}
-      </div>
-    </div>
-  </div>
-</div>
-
-{{#if
-  (or (chat-guardian "can-edit-chat-channel") this.channel.description.length)
-}}
-  <div class="chat-form__section">
-    <div class="chat-form__field">
-      <label class="chat-form__label">
-        <span>{{i18n "chat.about_view.description"}}</span>
-        {{#if (chat-guardian "can-edit-chat-channel")}}
-          <div class="chat-form__label-actions">
-            <DButton
-              @label={{if
-                this.channel.description.length
-                "chat.channel_settings.edit"
-                "chat.channel_settings.add"
-              }}
-              @action={{if
-                this.onEditChatChannelDescription
-                this.onEditChatChannelDescription
-              }}
-              class="edit-description-btn btn-flat"
-            />
-          </div>
-        {{/if}}
-      </label>
-
-      <div class="chat-form__control">
-        <div class="channel-info-about-view__description">
-          {{#if this.channel.description.length}}
-            {{this.channel.description}}
-          {{else}}
-            <div class="channel-info-about-view__description__helper-text">
-              {{i18n "chat.channel_edit_description_modal.description"}}
-            </div>
-          {{/if}}
-        </div>
-      </div>
-    </div>
-  </div>
-{{/if}}
-
-<div class="chat-form__section">
-  <ToggleChannelMembershipButton
-    @channel={{this.channel}}
-    @options={{hash
-      joinClass="btn-primary"
-      leaveClass="btn-flat"
-      joinIcon="sign-in-alt"
-      leaveIcon="sign-out-alt"
-    }}
-  />
-</div>
\ No newline at end of file
diff --git a/plugins/chat/assets/javascripts/discourse/components/chat-channel-about-view.js b/plugins/chat/assets/javascripts/discourse/components/chat-channel-about-view.js
deleted file mode 100644
index c7e1aa5b65a..00000000000
--- a/plugins/chat/assets/javascripts/discourse/components/chat-channel-about-view.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import Component from "@ember/component";
-import { inject as service } from "@ember/service";
-
-export default class ChatChannelAboutView extends Component {
-  @service chat;
-  tagName = "";
-  channel = null;
-  onEditChatChannelName = null;
-  onEditChatChannelDescription = null;
-  isLoading = false;
-}
diff --git a/plugins/chat/assets/javascripts/discourse/components/chat-channel-info.gjs b/plugins/chat/assets/javascripts/discourse/components/chat-channel-info.gjs
new file mode 100644
index 00000000000..3face999589
--- /dev/null
+++ b/plugins/chat/assets/javascripts/discourse/components/chat-channel-info.gjs
@@ -0,0 +1,85 @@
+import Component from "@glimmer/component";
+import { inject as service } from "@ember/service";
+import icon from "discourse-common/helpers/d-icon";
+import { LinkTo } from "@ember/routing";
+import ChatChannelTitle from "discourse/plugins/chat/discourse/components/chat-channel-title";
+import ChatChannelStatus from "discourse/plugins/chat/discourse/components/chat-channel-status";
+import I18n from "I18n";
+
+export default class ChatChannelMessageEmojiPicker extends Component {
+  <template>
+    <div class="chat-full-page-header">
+      <div class="chat-channel-header-details">
+        <div class="chat-full-page-header__left-actions">
+          {{#if this.chatChannelInfoRouteOriginManager.isBrowse}}
+            <LinkTo
+              @route="chat.browse"
+              class="chat-full-page-header__back-btn no-text btn-flat btn"
+              title={{this.backToAllChannelsLabel}}
+            >
+              {{icon "chevron-left"}}
+            </LinkTo>
+          {{else}}
+            <LinkTo
+              @route="chat.channel"
+              @models={{@channel.routeModels}}
+              class="chat-full-page-header__back-btn no-text btn-flat btn"
+              title={{this.backToChannelLabel}}
+            >
+              {{icon "chevron-left"}}
+            </LinkTo>
+          {{/if}}
+        </div>
+
+        <ChatChannelTitle @channel={{@channel}} />
+      </div>
+    </div>
+
+    <ChatChannelStatus @channel={{@channel}} />
+
+    <div class="chat-channel-info">
+      {{#if this.showTabs}}
+        <nav class="chat-channel-info__nav">
+          <ul class="nav nav-pills">
+            <li>
+              <LinkTo
+                @route="chat.channel.info.settings"
+                @model={{@channel}}
+                @replace={{true}}
+              >
+                {{this.settingsLabel}}
+              </LinkTo>
+            </li>
+            <li>
+              <LinkTo
+                @route="chat.channel.info.members"
+                @model={{@channel}}
+                @replace={{true}}
+              >
+                {{this.membersLabel}}
+              </LinkTo>
+            </li>
+          </ul>
+        </nav>
+      {{/if}}
+
+      {{outlet}}
+    </div>
+  </template>
+
+  @service chatChannelInfoRouteOriginManager;
+  @service site;
+
+  membersLabel = I18n.t("chat.channel_info.tabs.members");
+  settingsLabel = I18n.t("chat.channel_info.tabs.settings");
+  backToChannelLabel = I18n.t("chat.channel_info.back_to_all_channel");
+  backToAllChannelsLabel = I18n.t("chat.channel_info.back_to_channel");
+
+  get showTabs() {
+    return (
+      this.site.desktopView &&
+      this.args.channel.membershipsCount > 1 &&
+      this.args.channel.isOpen
+    );
+  }
+}
diff --git a/plugins/chat/assets/javascripts/discourse/components/chat-channel-members-view.hbs b/plugins/chat/assets/javascripts/discourse/components/chat-channel-members-view.hbs
deleted file mode 100644
index 54f52fe97b1..00000000000
--- a/plugins/chat/assets/javascripts/discourse/components/chat-channel-members-view.hbs
+++ /dev/null
@@ -1,42 +0,0 @@
-{{#if (gt this.channel.membershipsCount 0)}}
-  <LoadMore @selector=".channel-members-view__list-item" @action={{this.load}}>
-    <div class="channel-members-view-wrapper">
-      <div
-        class={{concat
-          "channel-members-view__search-input-container"
-          (if this.isSearchFocused " is-focused")
-        }}
-      >
-        <Input
-          class={{this.inputSelector}}
-          placeholder={{i18n "chat.members_view.filter_placeholder"}}
-          {{on "input" (action "onFilterMembers" value="target.value")}}
-          {{on "focusin" (action (mut this.isSearchFocused) true)}}
-          {{on "focusout" (action (mut this.isSearchFocused) false)}}
-        />
-        {{d-icon "search"}}
-      </div>
-
-      <div class="channel-members-view__list-container">
-        <div role="list" class="channel-members-view__list">
-          {{#each this.members as |membership|}}
-            <div class="channel-members-view__list-item">
-              <ChatUserInfo @user={{membership.user}} />
-            </div>
-          {{else}}
-            {{#if this.members.fetchedOnce}}
-              <div class="chat-thread-list__no-threads">
-                {{i18n "chat.channel.no_memberships_found"}}
-              </div>
-            {{/if}}
-          {{/each}}
-        </div>
-      </div>
-    </div>
-    <ConditionalLoadingSpinner @condition={{this.members.loading}} />
-  </LoadMore>
-{{else}}
-  <div class="channel-members-view-wrapper">
-    {{i18n "chat.channel.no_memberships"}}
-  </div>
-{{/if}}
\ No newline at end of file
diff --git a/plugins/chat/assets/javascripts/discourse/components/chat-channel-members-view.js b/plugins/chat/assets/javascripts/discourse/components/chat-channel-members-view.js
deleted file mode 100644
index 0912bd77b07..00000000000
--- a/plugins/chat/assets/javascripts/discourse/components/chat-channel-members-view.js
+++ /dev/null
@@ -1,66 +0,0 @@
-import { INPUT_DELAY } from "discourse-common/config/environment";
-import Component from "@ember/component";
-import { action } from "@ember/object";
-import { schedule } from "@ember/runloop";
-import discourseDebounce from "discourse-common/lib/debounce";
-import { inject as service } from "@ember/service";
-
-export default class ChatChannelMembersView extends Component {
-  @service chatApi;
-
-  tagName = "";
-  channel = null;
-  isSearchFocused = false;
-  onlineUsers = null;
-  filter = null;
-  inputSelector = "channel-members-view__search-input";
-  members = null;
-
-  didInsertElement() {
-    this._super(...arguments);
-
-    if (!this.channel) {
-      return;
-    }
-
-    this._focusSearch();
-    this.set("members", this.chatApi.listChannelMemberships(this.channel.id));
-    this.members.load();
-
-    this.appEvents.on("chat:refresh-channel-members", this, "onFilterMembers");
-  }
-
-  willDestroyElement() {
-    this._super(...arguments);
-
-    this.appEvents.off("chat:refresh-channel-members", this, "onFilterMembers");
-  }
-
-  @action
-  onFilterMembers(username) {
-    this.set("filter", username);
-    this.set("members", this.chatApi.listChannelMemberships(this.channel.id));
-
-    discourseDebounce(
-      this,
-      this.members.load,
-      { username: this.filter },
-      INPUT_DELAY
-    );
-  }
-
-  @action
-  load() {
-    discourseDebounce(this, this.members.load, INPUT_DELAY);
-  }
-
-  _focusSearch() {
-    if (this.capabilities.isIpadOS || this.site.mobileView) {
-      return;
-    }
-
-    schedule("afterRender", () => {
-      document.getElementsByClassName(this.inputSelector)[0]?.focus();
-    });
-  }
-}
diff --git a/plugins/chat/assets/javascripts/discourse/components/chat-channel-members.gjs b/plugins/chat/assets/javascripts/discourse/components/chat-channel-members.gjs
new file mode 100644
index 00000000000..bc102c97d83
--- /dev/null
+++ b/plugins/chat/assets/javascripts/discourse/components/chat-channel-members.gjs
@@ -0,0 +1,125 @@
+import Component from "@glimmer/component";
+import { action } from "@ember/object";
+import { inject as service } from "@ember/service";
+import ChatUserInfo from "discourse/plugins/chat/discourse/components/chat-user-info";
+import gt from "truth-helpers/helpers/gt";
+import { cached, tracked } from "@glimmer/tracking";
+import { INPUT_DELAY } from "discourse-common/config/environment";
+import discourseDebounce from "discourse-common/lib/debounce";
+import { modifier } from "ember-modifier";
+import isElementInViewport from "discourse/lib/is-element-in-viewport";
+import DcFilterInput from "discourse/plugins/chat/discourse/components/dc-filter-input";
+import I18n from "I18n";
+import { hash } from "@ember/helper";
+import { schedule } from "@ember/runloop";
+
+export default class ChatChannelMembers extends Component {
+  <template>
+    {{! template-lint-disable modifier-name-case }}
+    <div class="chat-channel-members">
+      <DcFilterInput
+        @class="chat-channel-members__filter"
+        @filterAction={{this.mutFilter}}
+        @icons={{hash right="search"}}
+        placeholder={{this.filterPlaceholder}}
+        {{this.focusInput}}
+      />
+
+      {{#if (gt @channel.membershipsCount 0)}}
+        <ul class="chat-channel-members__list" {{this.fill}}>
+          {{#each this.members as |membership|}}
+            <li class="chat-channel-members__list-item">
+              <ChatUserInfo @user={{membership.user}} @avatarSize="tiny" />
+            </li>
+          {{else}}
+            {{#if this.noResults}}
+              <li
+                class="chat-channel-members__list-item -no-results alert alert-info"
+              >
+                {{this.noMembershipsFoundLabel}}
+              </li>
+            {{/if}}
+          {{/each}}
+        </ul>
+
+        <div {{this.loadMore}}>
+          <br />
+        </div>
+      {{else}}
+        <p class="alert alert-info">
+          {{this.noMembershipsLabel}}
+        </p>
+      {{/if}}
+    </div>
+  </template>
+
+  @service chatApi;
+  @service modal;
+  @service loadingSlider;
+
+  @tracked filter = "";
+
+  filterPlaceholder = I18n.t("chat.members_view.filter_placeholder");
+  noMembershipsFoundLabel = I18n.t("chat.channel.no_memberships_found");
+  noMembershipsLabel = I18n.t("chat.channel.no_memberships");
+
+  focusInput = modifier((element) => {
+    schedule("afterRender", () => {
+      element.focus();
+    });
+  });
+
+  fill = modifier((element) => {
+    this.resizeObserver = new ResizeObserver(() => {
+      if (isElementInViewport(element)) {
+        this.load();
+      }
+    });
+
+    this.resizeObserver.observe(element);
+
+    return () => {
+      this.resizeObserver.disconnect();
+    };
+  });
+
+  loadMore = modifier((element) => {
+    this.intersectionObserver = new IntersectionObserver(this.load);
+    this.intersectionObserver.observe(element);
+
+    return () => {
+      this.intersectionObserver.disconnect();
+    };
+  });
+
+  get noResults() {
+    return this.members.fetchedOnce && !this.members.loading;
+  }
+
+  @cached
+  get members() {
+    const params = {};
+    if (this.filter?.length) {
+      params.username = this.filter;
+    }
+
+    return this.chatApi.listChannelMemberships(this.args.channel.id, params);
+  }
+
+  @action
+  load() {
+    discourseDebounce(this, this.debouncedLoad, INPUT_DELAY);
+  }
+
+  @action
+  mutFilter(event) {
+    this.filter = event.target.value;
+    this.load();
+  }
+
+  async debouncedLoad() {
+    this.loadingSlider.transitionStarted();
+    await this.members.load({ limit: 20 });
+    this.loadingSlider.transitionEnded();
+  }
+}
diff --git a/plugins/chat/assets/javascripts/discourse/components/chat-channel-settings-saved-indicator.hbs b/plugins/chat/assets/javascripts/discourse/components/chat-channel-settings-saved-indicator.hbs
deleted file mode 100644
index 43cb508c047..00000000000
--- a/plugins/chat/assets/javascripts/discourse/components/chat-channel-settings-saved-indicator.hbs
+++ /dev/null
@@ -1,14 +0,0 @@
-<span
-  {{did-update this.activate @property}}
-  {{will-destroy this.teardown}}
-  class={{concat-class
-    "chat-channel-settings-saved-indicator"
-    (if this.isActive "is-active")
-  }}
-  role="status"
->
-  {{#if this.isActive}}
-    {{d-icon "check"}}
-    <span>{{i18n "saved"}}</span>
-  {{/if}}
-</span>
\ No newline at end of file
diff --git a/plugins/chat/assets/javascripts/discourse/components/chat-channel-settings-saved-indicator.js b/plugins/chat/assets/javascripts/discourse/components/chat-channel-settings-saved-indicator.js
deleted file mode 100644
index 292e3af2308..00000000000
--- a/plugins/chat/assets/javascripts/discourse/components/chat-channel-settings-saved-indicator.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import discourseLater from "discourse-common/lib/later";
-import Component from "@glimmer/component";
-import { action } from "@ember/object";
-import { tracked } from "@glimmer/tracking";
-import { cancel } from "@ember/runloop";
-
-const ACTIVE_DURATION = 2000;
-
-export default class ChatChannelSettingsSavedIndicator extends Component {
-  @tracked isActive = false;
-  property = null;
-
-  @action
-  activate() {
-    cancel(this._deactivateHandler);
-
-    this.isActive = true;
-
-    this._deactivateHandler = discourseLater(() => {
-      this.isActive = false;
-    }, ACTIVE_DURATION);
-  }
-
-  @action
-  teardown() {
-    cancel(this._deactivateHandler);
-  }
-}
diff --git a/plugins/chat/assets/javascripts/discourse/components/chat-channel-settings-view.hbs b/plugins/chat/assets/javascripts/discourse/components/chat-channel-settings-view.hbs
deleted file mode 100644
index 9ef7414e025..00000000000
--- a/plugins/chat/assets/javascripts/discourse/components/chat-channel-settings-view.hbs
+++ /dev/null
@@ -1,199 +0,0 @@
-<div class="chat-form__section">
-  <div class="chat-form__field -mute">
-    <label class="chat-form__label">
-      <span>{{i18n "chat.settings.mute"}}</span>
-      <ChatChannelSettingsSavedIndicator
-        @property={{@channel.currentUserMembership.muted}}
-      />
-    </label>
-    <div class="chat-form__control">
-      <ComboBox
-        @content={{this.mutedOptions}}
-        @value={{@channel.currentUserMembership.muted}}
-        @valueProperty="value"
-        @class="channel-settings-view__selector"
-        @onChange={{fn this.saveNotificationSettings "muted" "muted"}}
-      />
-    </div>
-  </div>
-
-  {{#unless @channel.currentUserMembership.muted}}
-    <div class="chat-form__field -desktop-notification-level">
-      <label class="chat-form__label">
-        <span>{{i18n "chat.settings.desktop_notification_level"}}</span>
-        <ChatChannelSettingsSavedIndicator
-          @property={{@channel.currentUserMembership.desktopNotificationLevel}}
-        />
-      </label>
-      <div class="chat-form__control">
-        <ComboBox
-          @content={{this.notificationLevels}}
-          @value={{@channel.currentUserMembership.desktopNotificationLevel}}
-          @valueProperty="value"
-          @class="channel-settings-view__selector"
-          @onChange={{fn
-            this.saveNotificationSettings
-            "desktopNotificationLevel"
-            "desktop_notification_level"
-          }}
-        />
-      </div>
-    </div>
-
-    <div class="chat-form__field -mobile-notification-level">
-      <label class="chat-form__label">
-        <span>{{i18n "chat.settings.mobile_notification_level"}}</span>
-        <ChatChannelSettingsSavedIndicator
-          @property={{@channel.currentUserMembership.mobileNotificationLevel}}
-        />
-      </label>
-      <div class="chat-form__control">
-        <ComboBox
-          @content={{this.notificationLevels}}
-          @value={{@channel.currentUserMembership.mobileNotificationLevel}}
-          @valueProperty="value"
-          @class="channel-settings-view__selector"
-          @onChange={{fn
-            this.saveNotificationSettings
-            "mobileNotificationLevel"
-            "mobile_notification_level"
-          }}
-        />
-      </div>
-    </div>
-  {{/unless}}
-  <div class="chat-retention-info">
-    {{d-icon "info-circle"}}
-    <ChatRetentionReminderText @channel={{@channel}} />
-  </div>
-</div>
-
-{{#if this.adminSectionAvailable}}
-  <h3 class="chat-form__section-admin-title">
-    {{i18n "chat.settings.admin_title"}}
-  </h3>
-
-  {{#if this.autoJoinAvailable}}
-    <div class="chat-form__section -autojoin">
-      <div class="chat-form__field">
-        <label class="chat-form__label">
-          <span>{{i18n "chat.settings.auto_join_users_label"}}</span>
-          <ChatChannelSettingsSavedIndicator
-            @property={{@channel.autoJoinUsers}}
-          />
-        </label>
-        <ComboBox
-          @content={{this.autoAddUsersOptions}}
-          @value={{@channel.autoJoinUsers}}
-          @valueProperty="value"
-          @class="channel-settings-view__selector"
-          @onChange={{action
-            (fn this.onToggleAutoJoinUsers @channel.autoJoinUsers)
-          }}
-        />
-        <p class="chat-form__description">
-          {{i18n
-            "chat.settings.auto_join_users_info"
-            category=@channel.chatable.name
-          }}
-        </p>
-      </div>
-    </div>
-  {{/if}}
-
-  {{#if this.togglingChannelWideMentionsAvailable}}
-    <div class="chat-form__section -channel-wide-mentions">
-      <div class="chat-form__field">
-        <label class="chat-form__label">
-          <span>{{i18n "chat.settings.channel_wide_mentions_label"}}</span>
-          <ChatChannelSettingsSavedIndicator
-            @property={{@channel.allowChannelWideMentions}}
-          />
-        </label>
-        <ComboBox
-          @content={{this.channelWideMentionsOptions}}
-          @value={{@channel.allowChannelWideMentions}}
-          @valueProperty="value"
-          @class="channel-settings-view__selector"
-          @onChange={{this.onToggleChannelWideMentions}}
-        />
-        <p class="chat-form__description">
-          {{i18n
-            "chat.settings.channel_wide_mentions_description"
-            channel=@channel.title
-          }}
-        </p>
-      </div>
-    </div>
-  {{/if}}
-
-  <div class="chat-form__section -threading">
-    <div class="chat-form__field">
-      <label class="chat-form__label">
-        <span>{{i18n "chat.settings.channel_threading_label"}}</span>
-        <span class="channel-settings-view__channel-threading-tooltip">
-          {{d-icon "info-circle"}}
-          <DTooltip>
-            {{i18n "chat.settings.channel_threading_description"}}
-          </DTooltip>
-        </span>
-        <ChatChannelSettingsSavedIndicator
-          @property={{@channel.threadingEnabled}}
-        />
-      </label>
-      <ComboBox
-        @content={{this.threadingEnabledOptions}}
-        @value={{@channel.threadingEnabled}}
-        @valueProperty="value"
-        @class="channel-settings-view__selector"
-        @onChange={{this.onToggleThreadingEnabled}}
-      />
-    </div>
-  </div>
-{{/if}}
-
-{{#unless @channel.isDirectMessageChannel}}
-  <div class="chat-form__section">
-    {{#if (chat-guardian "can-edit-chat-channel")}}
-      {{#if (chat-guardian "can-archive-channel" @channel)}}
-        <div class="chat-form__field">
-          <DButton
-            @action={{this.onArchiveChannel}}
-            @label="chat.channel_settings.archive_channel"
-            @icon="archive"
-            class="archive-btn chat-form__btn btn-flat"
-          />
-        </div>
-      {{/if}}
-
-      {{#if @channel.isClosed}}
-        <div class="chat-form__field">
-          <DButton
-            @action={{this.onToggleChannelState}}
-            @label="chat.channel_settings.open_channel"
-            @icon="unlock"
-            class="open-btn chat-form__btn btn-flat"
-          />
-        </div>
-      {{else}}
-        <div class="chat-form__field">
-          <DButton
-            @action={{this.onToggleChannelState}}
-            @label="chat.channel_settings.close_channel"
-            @icon="lock"
-            class="close-btn chat-form__btn btn-flat"
-          />
-        </div>
-      {{/if}}
-
-      <div class="chat-form__field">
-        <DButton
-          @action={{this.onDeleteChannel}}
-          @label="chat.channel_settings.delete_channel"
-          @icon="trash-alt"
-          class="delete-btn chat-form__btn btn-flat"
-        />
-      </div>
-    {{/if}}
-  </div>
-{{/unless}}
\ No newline at end of file
diff --git a/plugins/chat/assets/javascripts/discourse/components/chat-channel-settings-view.js b/plugins/chat/assets/javascripts/discourse/components/chat-channel-settings-view.js
deleted file mode 100644
index a5c980d5ed1..00000000000
--- a/plugins/chat/assets/javascripts/discourse/components/chat-channel-settings-view.js
+++ /dev/null
@@ -1,203 +0,0 @@
-import Component from "@glimmer/component";
-import { action } from "@ember/object";
-import { inject as service } from "@ember/service";
-import I18n from "I18n";
-import ChatModalArchiveChannel from "discourse/plugins/chat/discourse/components/chat/modal/archive-channel";
-import ChatModalDeleteChannel from "discourse/plugins/chat/discourse/components/chat/modal/delete-channel";
-import ChatModalToggleChannelStatus from "discourse/plugins/chat/discourse/components/chat/modal/toggle-channel-status";
-
-const NOTIFICATION_LEVELS = [
-  { name: I18n.t("chat.notification_levels.never"), value: "never" },
-  { name: I18n.t("chat.notification_levels.mention"), value: "mention" },
-  { name: I18n.t("chat.notification_levels.always"), value: "always" },
-];
-
-const MUTED_OPTIONS = [
-  { name: I18n.t("chat.settings.muted_on"), value: true },
-  { name: I18n.t("chat.settings.muted_off"), value: false },
-];
-
-const AUTO_ADD_USERS_OPTIONS = [
-  { name: I18n.t("yes_value"), value: true },
-  { name: I18n.t("no_value"), value: false },
-];
-
-const THREADING_ENABLED_OPTIONS = [
-  { name: I18n.t("chat.settings.threading_enabled"), value: true },
-  { name: I18n.t("chat.settings.threading_disabled"), value: false },
-];
-
-const CHANNEL_WIDE_MENTIONS_OPTIONS = [
-  { name: I18n.t("yes_value"), value: true },
-  {
-    name: I18n.t("no_value"),
-    value: false,
-  },
-];
-
-export default class ChatChannelSettingsView extends Component {
-  @service chat;
-  @service chatApi;
-  @service chatGuardian;
-  @service currentUser;
-  @service siteSettings;
-  @service router;
-  @service dialog;
-  @service modal;
-
-  notificationLevels = NOTIFICATION_LEVELS;
-  mutedOptions = MUTED_OPTIONS;
-  threadingEnabledOptions = THREADING_ENABLED_OPTIONS;
-  autoAddUsersOptions = AUTO_ADD_USERS_OPTIONS;
-  channelWideMentionsOptions = CHANNEL_WIDE_MENTIONS_OPTIONS;
-  isSavingNotificationSetting = false;
-  savedDesktopNotificationLevel = false;
-  savedMobileNotificationLevel = false;
-  savedMuted = false;
-
-  get togglingChannelWideMentionsAvailable() {
-    return this.args.channel.isCategoryChannel;
-  }
-
-  get autoJoinAvailable() {
-    return (
-      this.siteSettings.max_chat_auto_joined_users > 0 &&
-      this.args.channel.isCategoryChannel
-    );
-  }
-
-  get adminSectionAvailable() {
-    return (
-      this.chatGuardian.canEditChatChannel() &&
-      (this.autoJoinAvailable || this.togglingChannelWideMentionsAvailable)
-    );
-  }
-
-  get canArchiveChannel() {
-    return (
-      this.siteSettings.chat_allow_archiving_channels &&
-      !this.args.channel.isArchived &&
-      !this.args.channel.isReadOnly
-    );
-  }
-
-  @action
-  saveNotificationSettings(frontendKey, backendKey, newValue) {
-    if (this.args.channel.currentUserMembership[frontendKey] === newValue) {
-      return;
-    }
-
-    const settings = {};
-    settings[backendKey] = newValue;
-    return this.chatApi
-      .updateCurrentUserChannelNotificationsSettings(
-        this.args.channel.id,
-        settings
-      )
-      .then((result) => {
-        this.args.channel.currentUserMembership[frontendKey] =
-          result.membership[backendKey];
-      });
-  }
-
-  @action
-  onArchiveChannel() {
-    return this.modal.show(ChatModalArchiveChannel, {
-      model: { channel: this.args.channel },
-    });
-  }
-
-  @action
-  onDeleteChannel() {
-    return this.modal.show(ChatModalDeleteChannel, {
-      model: { channel: this.args.channel },
-    });
-  }
-
-  @action
-  onToggleChannelState() {
-    this.modal.show(ChatModalToggleChannelStatus, { model: this.args.channel });
-  }
-
-  @action
-  onToggleAutoJoinUsers() {
-    if (!this.args.channel.autoJoinUsers) {
-      this.onEnableAutoJoinUsers();
-    } else {
-      this.onDisableAutoJoinUsers();
-    }
-  }
-
-  @action
-  onToggleThreadingEnabled(value) {
-    return this._updateChannelProperty(
-      this.args.channel,
-      "threading_enabled",
-      value
-    ).then((result) => {
-      this.args.channel.threadingEnabled = result.channel.threading_enabled;
-    });
-  }
-
-  @action
-  onToggleChannelWideMentions() {
-    const newValue = !this.args.channel.allowChannelWideMentions;
-    if (this.args.channel.allowChannelWideMentions === newValue) {
-      return;
-    }
-
-    return this._updateChannelProperty(
-      this.args.channel,
-      "allow_channel_wide_mentions",
-      newValue
-    ).then((result) => {
-      this.args.channel.allowChannelWideMentions =
-        result.channel.allow_channel_wide_mentions;
-    });
-  }
-
-  onDisableAutoJoinUsers() {
-    if (this.args.channel.autoJoinUsers === false) {
-      return;
-    }
-
-    return this._updateChannelProperty(
-      this.args.channel,
-      "auto_join_users",
-      false
-    ).then((result) => {
-      this.args.channel.autoJoinUsers = result.channel.auto_join_users;
-    });
-  }
-
-  onEnableAutoJoinUsers() {
-    if (this.args.channel.autoJoinUsers === true) {
-      return;
-    }
-
-    this.dialog.confirm({
-      message: I18n.t("chat.settings.auto_join_users_warning", {
-        category: this.args.channel.chatable.name,
-      }),
-      didConfirm: () =>
-        this._updateChannelProperty(
-          this.args.channel,
-          "auto_join_users",
-          true
-        ).then((result) => {
-          this.args.channel.autoJoinUsers = result.channel.auto_join_users;
-        }),
-    });
-  }
-
-  _updateChannelProperty(channel, property, value) {
-    const payload = {};
-    payload[property] = value;
-
-    return this.chatApi.updateChannel(channel.id, payload).catch((event) => {
-      if (event.jqXHR?.responseJSON?.errors) {
-        this.flash(event.jqXHR.responseJSON.errors.join("\n"), "error");
-      }
-    });
-  }
-}
diff --git a/plugins/chat/assets/javascripts/discourse/components/chat-channel-settings.gjs b/plugins/chat/assets/javascripts/discourse/components/chat-channel-settings.gjs
new file mode 100644
index 00000000000..b2b562c0046
--- /dev/null
+++ b/plugins/chat/assets/javascripts/discourse/components/chat-channel-settings.gjs
@@ -0,0 +1,581 @@
+import Component from "@glimmer/component";
+import ChatForm from "discourse/plugins/chat/discourse/components/chat/form";
+import DToggleSwitch from "discourse/components/d-toggle-switch";
+import { action } from "@ember/object";
+import { inject as service } from "@ember/service";
+import ChatModalArchiveChannel from "discourse/plugins/chat/discourse/components/chat/modal/archive-channel";
+import ChatModalDeleteChannel from "discourse/plugins/chat/discourse/components/chat/modal/delete-channel";
+import ChatModalToggleChannelStatus from "discourse/plugins/chat/discourse/components/chat/modal/toggle-channel-status";
+import { on } from "@ember/modifier";
+import I18n from "I18n";
+import { fn, hash } from "@ember/helper";
+import { popupAjaxError } from "discourse/lib/ajax-error";
+import ComboBox from "select-kit/components/combo-box";
+import ChatRetentionReminderText from "discourse/plugins/chat/discourse/components/chat-retention-reminder-text";
+import DButton from "discourse/components/d-button";
+import ToggleChannelMembershipButton from "discourse/plugins/chat/discourse/components/toggle-channel-membership-button";
+import replaceEmoji from "discourse/helpers/replace-emoji";
+import ChatModalEditChannelName from "discourse/plugins/chat/discourse/components/chat/modal/edit-channel-name";
+import categoryBadge from "discourse/helpers/category-badge";
+import ChatModalEditChannelDescription from "discourse/plugins/chat/discourse/components/chat/modal/edit-channel-description";
+import { LinkTo } from "@ember/routing";
+
+const NOTIFICATION_LEVELS = [
+  { name: I18n.t("chat.notification_levels.never"), value: "never" },
+  { name: I18n.t("chat.notification_levels.mention"), value: "mention" },
+  { name: I18n.t("chat.notification_levels.always"), value: "always" },
+];
+
+export default class ChatAboutScreen extends Component {
+  <template>
+    <div class="chat-channel-settings">
+      <ChatForm as |form|>
+        {{#if this.shouldRenderTitleSection}}
+          <form.section @title={{this.titleSectionTitle}} as |section|>
+            <section.row>
+              <:default>
+                <div class="chat-channel-settings__name">
+                  {{replaceEmoji @channel.title}}
+                </div>
+
+                {{#if @channel.isCategoryChannel}}
+                  <div class="chat-channel-settings__slug">
+                    <LinkTo
+                      @route="chat.channel"
+                      @models={{@channel.routeModels}}
+                    >
+                      /chat/c/{{@channel.slug}}/{{@channel.id}}
+                    </LinkTo>
+                  </div>
+                {{/if}}
+              </:default>
+
+              <:action>
+                {{#if this.canEditChannel}}
+                  <DButton
+                    @label="chat.channel_settings.edit"
+                    @action={{this.onEditChannelName}}
+                    class="edit-name-slug-btn btn-flat"
+                  />
+                {{/if}}
+              </:action>
+
+            </section.row>
+          </form.section>
+        {{/if}}
+
+        {{#if this.shouldRenderDescriptionSection}}
+          <form.section @title={{this.descriptionSectionTitle}} as |section|>
+            <section.row>
+              <:default>
+                {{#if @channel.description.length}}
+                  {{@channel.description}}
+                {{else}}
+                  {{this.descriptionPlaceholder}}
+                {{/if}}
+              </:default>
+
+              <:action>
+                {{#if this.canEditChannel}}
+                  <DButton
+                    @label={{if
+                      @channel.description.length
+                      "chat.channel_settings.edit"
+                      "chat.channel_settings.add"
+                    }}
+                    @action={{this.onEditChannelDescription}}
+                    class="edit-description-btn btn-flat"
+                  />
+                {{/if}}
+              </:action>
+            </section.row>
+          </form.section>
+        {{/if}}
+
+        {{#if this.site.mobileView}}
+          <form.section as |section|>
+            <section.row
+              @label={{this.membersLabel}}
+              @route="chat.channel.info.members"
+              @routeModels={{@channel.routeModels}}
+            />
+          </form.section>
+        {{/if}}
+
+        {{#if @channel.isOpen}}
+          <form.section @title={{this.settingsSectionTitle}} as |section|>
+            <section.row @label={{this.muteSectionLabel}}>
+              <:action>
+                <DToggleSwitch
+                  @state={{@channel.currentUserMembership.muted}}
+                  class="chat-channel-settings__mute-switch"
+                  {{on "click" this.onToggleMuted}}
+                />
+              </:action>
+            </section.row>
+
+            {{#if this.shouldRenderDesktopNotificationsLevelSection}}
+              <section.row @label={{this.desktopNotificationsLevelLabel}}>
+                <:action>
+                  <ComboBox
+                    @content={{this.notificationLevels}}
+                    @value={{@channel.currentUserMembership.desktopNotificationLevel}}
+                    @valueProperty="value"
+                    @class="chat-channel-settings__selector chat-channel-settings__desktop-notifications-selector"
+                    @onChange={{fn
+                      this.saveNotificationSettings
+                      "desktopNotificationLevel"
+                      "desktop_notification_level"
+                    }}
+                  />
+                </:action>
+              </section.row>
+            {{/if}}
+
+            {{#if this.shouldRenderMobileNotificationsLevelSection}}
+              <section.row @label={{this.mobileNotificationsLevelLabel}}>
+                <:action>
+                  <ComboBox
+                    @content={{this.notificationLevels}}
+                    @value={{@channel.currentUserMembership.mobileNotificationLevel}}
+                    @valueProperty="value"
+                    @class="chat-channel-settings__selector chat-channel-settings__mobile-notifications-selector"
+                    @onChange={{fn
+                      this.saveNotificationSettings
+                      "mobileNotificationLevel"
+                      "mobile_notification_level"
+                    }}
+                  />
+                </:action>
+              </section.row>
+            {{/if}}
+          </form.section>
+        {{/if}}
+
+        <form.section @title={{this.channelInfoSectionTitle}} as |section|>
+          {{#if @channel.isCategoryChannel}}
+            <section.row @label={{this.categoryLabel}}>
+              {{categoryBadge
+                @channel.chatable
+                link=true
+                allowUncategorized=true
+              }}
+            </section.row>
+          {{/if}}
+
+          <section.row @label={{this.historyLabel}}>
+            <ChatRetentionReminderText @channel={{@channel}} />
+          </section.row>
+        </form.section>
+
+        {{#if this.shouldRenderAdminSection}}
+          <form.section
+            @title={{this.adminSectionTitle}}
+            data-section="admin"
+            as |section|
+          >
+            {{#if this.autoJoinAvailable}}
+              <section.row @label={{this.autoJoinLabel}}>
+                <:action>
+                  <DToggleSwitch
+                    @state={{@channel.autoJoinUsers}}
+                    class="chat-channel-settings__auto-join-switch"
+                    {{on
+                      "click"
+                      (fn this.onToggleAutoJoinUsers @channel.autoJoinUsers)
+                    }}
+                  />
+                </:action>
+              </section.row>
+            {{/if}}
+
+            {{#if this.toggleChannelWideMentionsAvailable}}
+              <section.row @label={{this.channelWideMentionsLabel}}>
+                <:action>
+                  <DToggleSwitch
+                    class="chat-channel-settings__channel-wide-mentions"
+                    @state={{@channel.allowChannelWideMentions}}
+                    {{on
+                      "click"
+                      (fn
+                        this.onToggleChannelWideMentions
+                        @channel.allowChannelWideMentions
+                      )
+                    }}
+                  />
+                </:action>
+
+                <:description>
+                  {{this.channelWideMentionsDescription}}
+                </:description>
+              </section.row>
+            {{/if}}
+
+            {{#if this.toggleThreadingAvailable}}
+              <section.row @label={{this.toggleThreadingLabel}}>
+                <:action>
+                  <DToggleSwitch
+                    @state={{@channel.threadingEnabled}}
+                    class="chat-channel-settings__threading-switch"
+                    {{on
+                      "click"
+                      (fn
+                        this.onToggleThreadingEnabled @channel.threadingEnabled
+                      )
+                    }}
+                  />
+                </:action>
+
+                <:description>
+                  {{this.toggleThreadingDescription}}
+                </:description>
+              </section.row>
+            {{/if}}
+
+            {{#if this.shouldRenderStatusSection}}
+              {{#if this.shouldRenderArchiveRow}}
+                <section.row>
+                  <:action>
+                    <DButton
+                      @action={{this.onArchiveChannel}}
+                      @label="chat.channel_settings.archive_channel"
+                      @icon="archive"
+                      class="archive-btn chat-form__btn btn-flat"
+                    />
+                  </:action>
+                </section.row>
+              {{/if}}
+
+              <section.row>
+                <:action>
+                  {{#if @channel.isOpen}}
+                    <DButton
+                      @action={{this.onToggleChannelState}}
+                      @label="chat.channel_settings.close_channel"
+                      @icon="lock"
+                      class="close-btn chat-form__btn btn-flat"
+                    />
+                  {{else}}
+                    <DButton
+                      @action={{this.onToggleChannelState}}
+                      @label="chat.channel_settings.open_channel"
+                      @icon="unlock"
+                      class="open-btn chat-form__btn btn-flat"
+                    />
+                  {{/if}}
+                </:action>
+              </section.row>
+
+              <section.row>
+                <:action>
+                  <DButton
+                    @action={{this.onDeleteChannel}}
+                    @label="chat.channel_settings.delete_channel"
+                    @icon="trash-alt"
+                    class="delete-btn chat-form__btn btn-flat"
+                  />
+                </:action>
+              </section.row>
+            {{/if}}
+
+          </form.section>
+        {{/if}}
+
+        <form.section as |section|>
+          <section.row>
+            <:action>
+              <ToggleChannelMembershipButton
+                @channel={{@channel}}
+                @options={{hash
+                  joinClass="btn-primary"
+                  leaveClass="btn-flat"
+                  joinIcon="sign-in-alt"
+                  leaveIcon="sign-out-alt"
+                }}
+              />
+            </:action>
+          </section.row>
+        </form.section>
+      </ChatForm>
+    </div>
+  </template>
+
+  @service chatApi;
+  @service chatGuardian;
+  @service currentUser;
+  @service siteSettings;
+  @service dialog;
+  @service modal;
+  @service site;
+  @service toasts;
+
+  notificationLevels = NOTIFICATION_LEVELS;
+
+  settingsSectionTitle = I18n.t("chat.settings.settings_title");
+  channelInfoSectionTitle = I18n.t("chat.settings.info_title");
+  categoryLabel = I18n.t("chat.settings.category_label");
+  historyLabel = I18n.t("chat.settings.history_label");
+  adminSectionTitle = I18n.t("chat.settings.admin_title");
+  membersLabel = I18n.t("chat.settings.tabs.members_label");
+  descriptionSectionTitle = I18n.t("chat.about_view.description");
+  titleSectionTitle = I18n.t("chat.about_view.title");
+  descriptionPlaceholder = I18n.t(
+    "chat.channel_edit_description_modal.description"
+  );
+  toggleThreadingLabel = I18n.t("chat.settings.channel_threading_label");
+  toggleThreadingDescription = I18n.t(
+    "chat.settings.channel_threading_description"
+  );
+  muteSectionLabel = I18n.t("chat.settings.mute");
+  channelWideMentionsLabel = I18n.t(
+    "chat.settings.channel_wide_mentions_label"
+  );
+  autoJoinLabel = I18n.t("chat.settings.auto_join_users_label");
+  desktopNotificationsLevelLabel = I18n.t(
+    "chat.settings.desktop_notification_level"
+  );
+  mobileNotificationsLevelLabel = I18n.t(
+    "chat.settings.mobile_notification_level"
+  );
+
+  get canEditChannel() {
+    return this.chatGuardian.canEditChatChannel();
+  }
+
+  get shouldRenderTitleSection() {
+    return this.args.channel.isCategoryChannel;
+  }
+
+  get shouldRenderDescriptionSection() {
+    return this.args.channel.isCategoryChannel;
+  }
+
+  get shouldRenderStatusSection() {
+    return this.args.channel.isCategoryChannel;
+  }
+
+  get shouldRenderArchiveRow() {
+    return this.chatGuardian.canArchiveChannel(this.args.channel);
+  }
+
+  get toggleChannelWideMentionsAvailable() {
+    return this.args.channel.isCategoryChannel && this.args.channel.isOpen;
+  }
+
+  get toggleThreadingAvailable() {
+    return this.args.channel.isCategoryChannel && this.args.channel.isOpen;
+  }
+
+  get channelWideMentionsDescription() {
+    return I18n.t("chat.settings.channel_wide_mentions_description", {
+      channel: this.args.channel.title,
+    });
+  }
+
+  get isChannelMuted() {
+    return this.args.channel.currentUserMembership.muted;
+  }
+
+  get shouldRenderChannelWideMentionsAvailable() {
+    return this.args.channel.isCategoryChannel;
+  }
+
+  get shouldRenderDesktopNotificationsLevelSection() {
+    return !this.isChannelMuted;
+  }
+
+  get shouldRenderMobileNotificationsLevelSection() {
+    return !this.isChannelMuted;
+  }
+
+  get autoJoinAvailable() {
+    return (
+      this.siteSettings.max_chat_auto_joined_users > 0 &&
+      this.args.channel.isCategoryChannel &&
+      this.args.channel.isOpen
+    );
+  }
+
+  get shouldRenderAdminSection() {
+    return (
+      this.canEditChannel &&
+      (this.toggleChannelWideMentionsAvailable ||
+        this.args.channel.isCategoryChannel)
+    );
+  }
+
+  @action
+  async onToggleChannelWideMentions() {
+    const newValue = !this.args.channel.allowChannelWideMentions;
+
+    if (this.args.channel.allowChannelWideMentions === newValue) {
+      return;
+    }
+
+    try {
+      this.args.channel.allowChannelWideMentions = newValue;
+
+      const result = await this._updateChannelProperty(
+        this.args.channel,
+        "allow_channel_wide_mentions",
+        newValue
+      );
+
+      this.args.channel.allowChannelWideMentions =
+        result.channel.allow_channel_wide_mentions;
+    } catch (error) {
+      popupAjaxError(error);
+    }
+  }
+
+  @action
+  async onToggleAutoJoinUsers() {
+    if (this.args.channel.autoJoinUsers) {
+      return await this.onDisableAutoJoinUsers();
+    }
+
+    return await this.onEnableAutoJoinUsers();
+  }
+
+  @action
+  async onDisableAutoJoinUsers() {
+    if (this.args.channel.autoJoinUsers === false) {
+      return;
+    }
+
+    try {
+      this.args.channel.autoJoinUsers = false;
+
+      const result = await this._updateChannelProperty(
+        this.args.channel,
+        "auto_join_users",
+        false
+      );
+
+      this.args.channel.autoJoinUsers = result.channel.auto_join_users;
+    } catch (error) {
+      popupAjaxError(error);
+    }
+  }
+
+  @action
+  onEnableAutoJoinUsers() {
+    if (this.args.channel.autoJoinUsers === true) {
+      return;
+    }
+
+    return this.dialog.confirm({
+      message: I18n.t("chat.settings.auto_join_users_warning", {
+        category: this.args.channel.chatable.name,
+      }),
+      didConfirm: async () => {
+        try {
+          const result = await this._updateChannelProperty(
+            this.args.channel,
+            "auto_join_users",
+            true
+          );
+
+          this.args.channel.autoJoinUsers = result.channel.auto_join_users;
+        } catch (error) {
+          popupAjaxError(error);
+        }
+      },
+    });
+  }
+
+  @action
+  onToggleMuted() {
+    const newValue = !this.args.channel.currentUserMembership.muted;
+    this.saveNotificationSettings("muted", "muted", newValue);
+  }
+
+  @action
+  async saveNotificationSettings(frontendKey, backendKey, newValue) {
+    if (this.args.channel.currentUserMembership[frontendKey] === newValue) {
+      return;
+    }
+
+    this.args.channel.currentUserMembership[frontendKey] = newValue;
+
+    const settings = {};
+    settings[backendKey] = newValue;
+
+    try {
+      const result =
+        await this.chatApi.updateCurrentUserChannelNotificationsSettings(
+          this.args.channel.id,
+          settings
+        );
+
+      this.args.channel.currentUserMembership[frontendKey] =
+        result.membership[backendKey];
+      this.toasts.success({ data: { message: I18n.t("saved") } });
+    } catch (error) {
+      popupAjaxError(error);
+    }
+  }
+
+  @action
+  async _updateChannelProperty(channel, property, value) {
+    try {
+      const result = await this.chatApi.updateChannel(channel.id, {
+        [property]: value,
+      });
+      this.toasts.success({ data: { message: I18n.t("saved") } });
+      return result;
+    } catch (error) {
+      popupAjaxError(error);
+    }
+  }
+
+  @action
+  async onToggleThreadingEnabled(value) {
+    try {
+      this.args.channel.threadingEnabled = !value;
+      const result = await this._updateChannelProperty(
+        this.args.channel,
+        "threading_enabled",
+        !value
+      );
+      this.args.channel.threadingEnabled = result.channel.threading_enabled;
+    } catch (error) {
+      popupAjaxError(error);
+    }
+  }
+
+  @action
+  onToggleChannelState() {
+    return this.modal.show(ChatModalToggleChannelStatus, {
+      model: this.args.channel,
+    });
+  }
+
+  @action
+  onArchiveChannel() {
+    return this.modal.show(ChatModalArchiveChannel, {
+      model: { channel: this.args.channel },
+    });
+  }
+
+  @action
+  onDeleteChannel() {
+    return this.modal.show(ChatModalDeleteChannel, {
+      model: { channel: this.args.channel },
+    });
+  }
+
+  @action
+  onEditChannelName() {
+    return this.modal.show(ChatModalEditChannelName, {
+      model: this.args.channel,
+    });
+  }
+
+  @action
+  onEditChannelDescription() {
+    return this.modal.show(ChatModalEditChannelDescription, {
+      model: this.args.channel,
+    });
+  }
+}
diff --git a/plugins/chat/assets/javascripts/discourse/components/chat-retention-reminder-text.js b/plugins/chat/assets/javascripts/discourse/components/chat-retention-reminder-text.gjs
similarity index 90%
rename from plugins/chat/assets/javascripts/discourse/components/chat-retention-reminder-text.js
rename to plugins/chat/assets/javascripts/discourse/components/chat-retention-reminder-text.gjs
index 5ad70302b9f..71fc34beca8 100644
--- a/plugins/chat/assets/javascripts/discourse/components/chat-retention-reminder-text.js
+++ b/plugins/chat/assets/javascripts/discourse/components/chat-retention-reminder-text.gjs
@@ -3,6 +3,12 @@ import I18n from "I18n";
 import { inject as service } from "@ember/service";
 
 export default class ChatRetentionReminderText extends Component {
+  <template>
+    <span class="chat-retention-reminder-text">
+      {{this.text}}
+    </span>
+  </template>
+
   @service siteSettings;
 
   get text() {
diff --git a/plugins/chat/assets/javascripts/discourse/components/chat-retention-reminder-text.hbs b/plugins/chat/assets/javascripts/discourse/components/chat-retention-reminder-text.hbs
deleted file mode 100644
index 309d7f6c5fe..00000000000
--- a/plugins/chat/assets/javascripts/discourse/components/chat-retention-reminder-text.hbs
+++ /dev/null
@@ -1,3 +0,0 @@
-<span class="chat-retention-reminder-text">
-  {{this.text}}
-</span>
\ No newline at end of file
diff --git a/plugins/chat/assets/javascripts/discourse/components/chat-user-info.gjs b/plugins/chat/assets/javascripts/discourse/components/chat-user-info.gjs
new file mode 100644
index 00000000000..d4ae7ebc428
--- /dev/null
+++ b/plugins/chat/assets/javascripts/discourse/components/chat-user-info.gjs
@@ -0,0 +1,25 @@
+import Component from "@glimmer/component";
+import { userPath } from "discourse/lib/url";
+import ChatUserAvatar from "discourse/plugins/chat/discourse/components/chat/user-avatar";
+import ChatUserDisplayName from "discourse/plugins/chat/discourse/components/chat-user-display-name";
+
+export default class ChatUserInfo extends Component {
+  <template>
+    {{#if @user}}
+      <a href={{this.userPath}} data-user-card={{@user.username}}>
+        <ChatUserAvatar @user={{@user}} @avatarSize={{this.avatarSize}} />
+      </a>
+      <a href={{this.userPath}} data-user-card={{@user.username}}>
+        <ChatUserDisplayName @user={{@user}} />
+      </a>
+    {{/if}}
+  </template>
+
+  get avatarSize() {
+    return this.args.avatarSize ?? "medium";
+  }
+
+  get userPath() {
+    return userPath(this.args.user.username);
+  }
+}
diff --git a/plugins/chat/assets/javascripts/discourse/components/chat-user-info.hbs b/plugins/chat/assets/javascripts/discourse/components/chat-user-info.hbs
deleted file mode 100644
index 1dd5843bf8e..00000000000
--- a/plugins/chat/assets/javascripts/discourse/components/chat-user-info.hbs
+++ /dev/null
@@ -1,8 +0,0 @@
-{{#if @user}}
-  <a href={{this.userPath}} data-user-card={{@user.username}}>
-    <Chat::UserAvatar @user={{@user}} @avatarSize="medium" />
-  </a>
-  <a href={{this.userPath}} data-user-card={{@user.username}}>
-    <ChatUserDisplayName @user={{@user}} />
-  </a>
-{{/if}}
\ No newline at end of file
diff --git a/plugins/chat/assets/javascripts/discourse/components/chat-user-info.js b/plugins/chat/assets/javascripts/discourse/components/chat-user-info.js
deleted file mode 100644
index ccc7d150af6..00000000000
--- a/plugins/chat/assets/javascripts/discourse/components/chat-user-info.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import Component from "@glimmer/component";
-import { userPath } from "discourse/lib/url";
-
-export default class ChatUserInfo extends Component {
-  get userPath() {
-    return userPath(this.args.user.username);
-  }
-}
diff --git a/plugins/chat/assets/javascripts/discourse/components/chat/form.gjs b/plugins/chat/assets/javascripts/discourse/components/chat/form.gjs
new file mode 100644
index 00000000000..d665004c2f2
--- /dev/null
+++ b/plugins/chat/assets/javascripts/discourse/components/chat/form.gjs
@@ -0,0 +1,14 @@
+import Component from "@glimmer/component";
+import ChatFormSection from "discourse/plugins/chat/discourse/components/chat/form/section";
+
+export default class ChatForm extends Component {
+  <template>
+    <div class="chat-form">
+      {{yield this.yieldableArgs}}
+    </div>
+  </template>
+
+  get yieldableArgs() {
+    return { section: ChatFormSection };
+  }
+}
diff --git a/plugins/chat/assets/javascripts/discourse/components/chat/form/row.gjs b/plugins/chat/assets/javascripts/discourse/components/chat/form/row.gjs
new file mode 100644
index 00000000000..faef5e17944
--- /dev/null
+++ b/plugins/chat/assets/javascripts/discourse/components/chat/form/row.gjs
@@ -0,0 +1,48 @@
+import Component from "@glimmer/component";
+import { LinkTo } from "@ember/routing";
+import icon from "discourse-common/helpers/d-icon";
+import concatClass from "discourse/helpers/concat-class";
+
+export default class ChatFormRow extends Component {
+  <template>
+    {{#if @route}}
+      <LinkTo
+        @route={{@route}}
+        @models={{@routeModels}}
+        class={{concatClass
+          "chat-form__row -link"
+          (if @separator "-separator")
+        }}
+      >
+        <div class="chat-form__row-content">
+          {{@label}}
+          {{icon "chevron-right" class="chat-form__row-icon"}}
+        </div>
+      </LinkTo>
+    {{else}}
+      <div class={{concatClass "chat-form__row" (if @separator "-separator")}}>
+        <div class="chat-form__row-content">
+          {{#if @label}}
+            <span class="chat-form__row-label">{{@label}}</span>
+          {{/if}}
+
+          {{#if (has-block)}}
+            <span class="chat-form__row-label">
+              {{yield}}
+            </span>
+          {{/if}}
+
+          {{#if (has-block "action")}}
+            <div class="chat-form__row-action">{{yield to="action"}}</div>
+          {{/if}}
+        </div>
+
+        {{#if (has-block "description")}}
+          <div class="chat-form__row-description">
+            {{yield to="description"}}
+          </div>
+        {{/if}}
+      </div>
+    {{/if}}
+  </template>
+}
diff --git a/plugins/chat/assets/javascripts/discourse/components/chat/form/section.gjs b/plugins/chat/assets/javascripts/discourse/components/chat/form/section.gjs
new file mode 100644
index 00000000000..47dcf2e8530
--- /dev/null
+++ b/plugins/chat/assets/javascripts/discourse/components/chat/form/section.gjs
@@ -0,0 +1,22 @@
+import Component from "@glimmer/component";
+import ChatFormRow from "discourse/plugins/chat/discourse/components/chat/form/row";
+
+export default class ChatFormSection extends Component {
+  <template>
+    <div class="chat-form__section" ...attributes>
+      {{#if @title}}
+        <div class="chat-form__section-title">
+          {{@title}}
+        </div>
+      {{/if}}
+
+      <div class="chat-form__section-content">
+        {{yield this.yieldableArgs}}
+      </div>
+    </div>
+  </template>
+
+  get yieldableArgs() {
+    return { row: ChatFormRow };
+  }
+}
diff --git a/plugins/chat/assets/javascripts/discourse/components/chat/modal/edit-channel-name.hbs b/plugins/chat/assets/javascripts/discourse/components/chat/modal/edit-channel-name.hbs
index 0256880fac7..2838b84ed5a 100644
--- a/plugins/chat/assets/javascripts/discourse/components/chat/modal/edit-channel-name.hbs
+++ b/plugins/chat/assets/javascripts/discourse/components/chat/modal/edit-channel-name.hbs
@@ -25,12 +25,10 @@
     <div class="edit-channel-control">
       <label for="channel-slug" class="edit-channel-label">
         {{i18n "chat.channel_edit_name_slug_modal.slug"}}&nbsp;
-        <span>
-          {{d-icon "info-circle"}}
-          <DTooltip>{{i18n
-              "chat.channel_edit_name_slug_modal.slug_description"
-            }}</DTooltip>
-        </span>
+        <DTooltip
+          @icon="info-circle"
+          @content={{i18n "chat.channel_edit_name_slug_modal.slug_description"}}
+        />
       </label>
       <Input
         name="channel-slug"
diff --git a/plugins/chat/assets/javascripts/discourse/components/dc-filter-input.gjs b/plugins/chat/assets/javascripts/discourse/components/dc-filter-input.gjs
new file mode 100644
index 00000000000..5d924d93822
--- /dev/null
+++ b/plugins/chat/assets/javascripts/discourse/components/dc-filter-input.gjs
@@ -0,0 +1,58 @@
+import Component from "@glimmer/component";
+import { Input } from "@ember/component";
+import { on } from "@ember/modifier";
+import noop from "discourse/helpers/noop";
+import concatClass from "discourse/helpers/concat-class";
+import icon from "discourse-common/helpers/d-icon";
+import { modifier } from "ember-modifier";
+import { tracked } from "@glimmer/tracking";
+
+export default class DcFilterInput extends Component {
+  <template>
+    {{! template-lint-disable modifier-name-case }}
+    <div
+      class={{concatClass
+        @class
+        "dc-filter-input-container"
+        (if this.isFocused " is-focused")
+      }}
+    >
+      {{#if @icons.left}}
+        {{icon @icons.left class="-left"}}
+      {{/if}}
+
+      <Input
+        class="dc-filter-input"
+        @value={{@value}}
+        {{on "input" (if @filterAction @filterAction (noop))}}
+        {{this.focusState}}
+        ...attributes
+      />
+
+      {{yield}}
+
+      {{#if @icons.right}}
+        {{icon @icons.right class="-right"}}
+      {{/if}}
+    </div>
+  </template>
+
+  @tracked isFocused = false;
+
+  focusState = modifier((element) => {
+    const focusInHandler = () => {
+      this.isFocused = true;
+    };
+    const focusOutHandler = () => {
+      this.isFocused = false;
+    };
+
+    element.addEventListener("focusin", focusInHandler);
+    element.addEventListener("focusout", focusOutHandler);
+
+    return () => {
+      element.removeEventListener("focusin", focusInHandler);
+      element.removeEventListener("focusout", focusOutHandler);
+    };
+  });
+}
diff --git a/plugins/chat/assets/javascripts/discourse/components/dc-filter-input.hbs b/plugins/chat/assets/javascripts/discourse/components/dc-filter-input.hbs
deleted file mode 100644
index a3d465fe24e..00000000000
--- a/plugins/chat/assets/javascripts/discourse/components/dc-filter-input.hbs
+++ /dev/null
@@ -1,26 +0,0 @@
-<div
-  class={{concat
-    @class
-    " dc-filter-input-container"
-    (if this.isFocused " is-focused")
-  }}
->
-  {{#if @icons.left}}
-    {{d-icon @icons.left class="-left"}}
-  {{/if}}
-
-  <Input
-    class="dc-filter-input"
-    @value={{@value}}
-    {{on "input" (if @filterAction @filterAction (noop))}}
-    {{on "focusin" (action (mut this.isFocused) true)}}
-    {{on "focusout" (action (mut this.isFocused) false)}}
-    ...attributes
-  />
-
-  {{yield}}
-
-  {{#if @icons.right}}
-    {{d-icon @icons.right class="-right"}}
-  {{/if}}
-</div>
\ No newline at end of file
diff --git a/plugins/chat/assets/javascripts/discourse/components/dc-filter-input.js b/plugins/chat/assets/javascripts/discourse/components/dc-filter-input.js
deleted file mode 100644
index 60b7b82ea4f..00000000000
--- a/plugins/chat/assets/javascripts/discourse/components/dc-filter-input.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import Component from "@glimmer/component";
-
-export default class DcFilterInput extends Component {}
diff --git a/plugins/chat/assets/javascripts/discourse/controllers/chat-channel-info-about.js b/plugins/chat/assets/javascripts/discourse/controllers/chat-channel-info-about.js
deleted file mode 100644
index 8748478788f..00000000000
--- a/plugins/chat/assets/javascripts/discourse/controllers/chat-channel-info-about.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import Controller from "@ember/controller";
-import { action } from "@ember/object";
-import ModalFunctionality from "discourse/mixins/modal-functionality";
-import { inject as service } from "@ember/service";
-import ChatModalEditChannelDescription from "discourse/plugins/chat/discourse/components/chat/modal/edit-channel-description";
-import ChatModalEditChannelName from "discourse/plugins/chat/discourse/components/chat/modal/edit-channel-name";
-
-export default class ChatChannelInfoAboutController extends Controller.extend(
-  ModalFunctionality
-) {
-  @service modal;
-
-  @action
-  onEditChatChannelName() {
-    return this.modal.show(ChatModalEditChannelName, {
-      model: this.model,
-    });
-  }
-
-  @action
-  onEditChatChannelDescription() {
-    return this.modal.show(ChatModalEditChannelDescription, {
-      model: this.model,
-    });
-  }
-}
diff --git a/plugins/chat/assets/javascripts/discourse/controllers/chat-channel-info-members.js b/plugins/chat/assets/javascripts/discourse/controllers/chat-channel-info-members.js
deleted file mode 100644
index 48e3c615581..00000000000
--- a/plugins/chat/assets/javascripts/discourse/controllers/chat-channel-info-members.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import Controller from "@ember/controller";
-
-export default class ChatChannelInfoMembersController extends Controller {}
diff --git a/plugins/chat/assets/javascripts/discourse/controllers/chat-channel-info-settings.js b/plugins/chat/assets/javascripts/discourse/controllers/chat-channel-info-settings.js
deleted file mode 100644
index a70d62d1ea9..00000000000
--- a/plugins/chat/assets/javascripts/discourse/controllers/chat-channel-info-settings.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import Controller from "@ember/controller";
-
-export default class ChatChannelInfoSettingsController extends Controller {}
diff --git a/plugins/chat/assets/javascripts/discourse/controllers/chat-channel-info.js b/plugins/chat/assets/javascripts/discourse/controllers/chat-channel-info.js
deleted file mode 100644
index 65c132080d9..00000000000
--- a/plugins/chat/assets/javascripts/discourse/controllers/chat-channel-info.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import Controller from "@ember/controller";
-import { inject as service } from "@ember/service";
-import { reads } from "@ember/object/computed";
-import { computed } from "@ember/object";
-
-export default class ChatChannelInfoIndexController extends Controller {
-  @service router;
-  @service chat;
-  @service chatChannelInfoRouteOriginManager;
-
-  @reads("router.currentRoute.localName") tab;
-
-  @computed("model.{membershipsCount,status,currentUserMembership.following}")
-  get tabs() {
-    const tabs = [];
-
-    if (!this.model.isDirectMessageChannel) {
-      tabs.push("about");
-    }
-
-    if (this.model.isOpen && this.model.membershipsCount >= 1) {
-      tabs.push("members");
-    }
-
-    if (
-      this.currentUser?.staff ||
-      this.model.currentUserMembership?.following
-    ) {
-      tabs.push("settings");
-    }
-
-    return tabs;
-  }
-}
diff --git a/plugins/chat/assets/javascripts/discourse/lib/collection.js b/plugins/chat/assets/javascripts/discourse/lib/collection.js
index e472d45bffe..08014429e6b 100644
--- a/plugins/chat/assets/javascripts/discourse/lib/collection.js
+++ b/plugins/chat/assets/javascripts/discourse/lib/collection.js
@@ -12,9 +12,10 @@ export default class Collection {
   @tracked loading = false;
   @tracked fetchedOnce = false;
 
-  constructor(resourceURL, handler) {
+  constructor(resourceURL, handler, params = {}) {
     this._resourceURL = resourceURL;
     this._handler = handler;
+    this._params = params;
     this._fetchedAll = false;
   }
 
@@ -94,6 +95,6 @@ export default class Collection {
   }
 
   #fetch(url) {
-    return ajax(url, { type: "GET" });
+    return ajax(url, { type: "GET", data: this._params });
   }
 }
diff --git a/plugins/chat/assets/javascripts/discourse/routes/chat-channel-info-about.js b/plugins/chat/assets/javascripts/discourse/routes/chat-channel-info-about.js
deleted file mode 100644
index 9bb3d7b81b0..00000000000
--- a/plugins/chat/assets/javascripts/discourse/routes/chat-channel-info-about.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import DiscourseRoute from "discourse/routes/discourse";
-import { inject as service } from "@ember/service";
-
-export default class ChatChannelInfoAboutRoute extends DiscourseRoute {
-  @service router;
-
-  afterModel(model) {
-    if (model.isDirectMessageChannel) {
-      this.router.replaceWith("chat.channel.info.index");
-    }
-  }
-}
diff --git a/plugins/chat/assets/javascripts/discourse/routes/chat-channel-info-index.js b/plugins/chat/assets/javascripts/discourse/routes/chat-channel-info-index.js
index 03258bae148..34ffcf2343e 100644
--- a/plugins/chat/assets/javascripts/discourse/routes/chat-channel-info-index.js
+++ b/plugins/chat/assets/javascripts/discourse/routes/chat-channel-info-index.js
@@ -4,15 +4,7 @@ import { inject as service } from "@ember/service";
 export default class ChatChannelInfoIndexRoute extends DiscourseRoute {
   @service router;
 
-  afterModel(model) {
-    if (model.isDirectMessageChannel) {
-      if (model.isOpen && model.membershipsCount >= 1) {
-        this.router.replaceWith("chat.channel.info.members");
-      } else {
-        this.router.replaceWith("chat.channel.info.settings");
-      }
-    } else {
-      this.router.replaceWith("chat.channel.info.about");
-    }
+  afterModel() {
+    this.router.replaceWith("chat.channel.info.settings");
   }
 }
diff --git a/plugins/chat/assets/javascripts/discourse/routes/chat-channel-info-members.js b/plugins/chat/assets/javascripts/discourse/routes/chat-channel-info-members.js
index 6260e3f1a65..e6912480514 100644
--- a/plugins/chat/assets/javascripts/discourse/routes/chat-channel-info-members.js
+++ b/plugins/chat/assets/javascripts/discourse/routes/chat-channel-info-members.js
@@ -5,12 +5,8 @@ export default class ChatChannelInfoMembersRoute extends DiscourseRoute {
   @service router;
 
   afterModel(model) {
-    if (!model.isOpen) {
+    if (!model.isOpen || model.membershipsCount < 1) {
       return this.router.replaceWith("chat.channel.info.settings");
     }
-
-    if (model.membershipsCount < 1) {
-      return this.router.replaceWith("chat.channel.info");
-    }
   }
 }
diff --git a/plugins/chat/assets/javascripts/discourse/routes/chat-channel-info-settings.js b/plugins/chat/assets/javascripts/discourse/routes/chat-channel-info-settings.js
deleted file mode 100644
index 8468b04492d..00000000000
--- a/plugins/chat/assets/javascripts/discourse/routes/chat-channel-info-settings.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import DiscourseRoute from "discourse/routes/discourse";
-import { inject as service } from "@ember/service";
-
-export default class ChatChannelInfoSettingsRoute extends DiscourseRoute {
-  @service router;
-  @service currentUser;
-
-  afterModel(model) {
-    if (!this.currentUser?.staff && !model.currentUserMembership?.following) {
-      this.router.replaceWith("chat.channel.info");
-    }
-  }
-}
diff --git a/plugins/chat/assets/javascripts/discourse/services/chat-api.js b/plugins/chat/assets/javascripts/discourse/services/chat-api.js
index daae4cc8b19..f4ab3c79068 100644
--- a/plugins/chat/assets/javascripts/discourse/services/chat-api.js
+++ b/plugins/chat/assets/javascripts/discourse/services/chat-api.js
@@ -233,14 +233,15 @@ export default class ChatApi extends Service {
    * @param {number} channelId - The ID of the channel.
    * @returns {Collection}
    */
-  listChannelMemberships(channelId) {
+  listChannelMemberships(channelId, params = {}) {
     return new Collection(
       `${this.#basePath}/channels/${channelId}/memberships`,
       (response) => {
         return response.memberships.map((membership) =>
           UserChatChannelMembership.create(membership)
         );
-      }
+      },
+      params
     );
   }
 
diff --git a/plugins/chat/assets/javascripts/discourse/services/chat-channels-manager.js b/plugins/chat/assets/javascripts/discourse/services/chat-channels-manager.js
index 882353e6d45..7a6f9d8df80 100644
--- a/plugins/chat/assets/javascripts/discourse/services/chat-channels-manager.js
+++ b/plugins/chat/assets/javascripts/discourse/services/chat-channels-manager.js
@@ -18,6 +18,7 @@ export default class ChatChannelsManager extends Service {
   @service chatSubscriptionsManager;
   @service chatApi;
   @service currentUser;
+  @service router;
   @tracked _cached = new TrackedObject();
 
   async find(id, options = { fetchIfNotFound: true }) {
@@ -131,12 +132,12 @@ export default class ChatChannelsManager extends Service {
   }
 
   async #find(id) {
-    return this.chatApi
-      .channel(id)
-      .catch(popupAjaxError)
-      .then((result) => {
-        return this.store(result.channel);
-      });
+    try {
+      const result = await this.chatApi.channel(id);
+      return this.store(result.channel);
+    } catch (error) {
+      popupAjaxError(error);
+    }
   }
 
   #cache(channel) {
diff --git a/plugins/chat/assets/javascripts/discourse/services/chat-guardian.js b/plugins/chat/assets/javascripts/discourse/services/chat-guardian.js
index 791b06938e6..7411643bdaf 100644
--- a/plugins/chat/assets/javascripts/discourse/services/chat-guardian.js
+++ b/plugins/chat/assets/javascripts/discourse/services/chat-guardian.js
@@ -1,6 +1,9 @@
-import Service from "@ember/service";
+import Service, { inject as service } from "@ember/service";
 
 export default class ChatGuardian extends Service {
+  @service currentUser;
+  @service siteSettings;
+
   canEditChatChannel() {
     return this.canUseChat() && this.currentUser.staff;
   }
diff --git a/plugins/chat/assets/javascripts/discourse/templates/chat-channel-info-about.hbs b/plugins/chat/assets/javascripts/discourse/templates/chat-channel-info-about.hbs
deleted file mode 100644
index 83de81608a8..00000000000
--- a/plugins/chat/assets/javascripts/discourse/templates/chat-channel-info-about.hbs
+++ /dev/null
@@ -1,5 +0,0 @@
-<ChatChannelAboutView
-  @channel={{this.model}}
-  @onEditChatChannelName={{action "onEditChatChannelName"}}
-  @onEditChatChannelDescription={{action "onEditChatChannelDescription"}}
-/>
\ No newline at end of file
diff --git a/plugins/chat/assets/javascripts/discourse/templates/chat-channel-info-members.hbs b/plugins/chat/assets/javascripts/discourse/templates/chat-channel-info-members.hbs
index 50f2aa56629..3294012102c 100644
--- a/plugins/chat/assets/javascripts/discourse/templates/chat-channel-info-members.hbs
+++ b/plugins/chat/assets/javascripts/discourse/templates/chat-channel-info-members.hbs
@@ -1 +1 @@
-<ChatChannelMembersView @channel={{this.model}} />
\ No newline at end of file
+<ChatChannelMembers @channel={{this.model}} />
\ No newline at end of file
diff --git a/plugins/chat/assets/javascripts/discourse/templates/chat-channel-info-settings.hbs b/plugins/chat/assets/javascripts/discourse/templates/chat-channel-info-settings.hbs
index 633f0350277..2aac01fe3da 100644
--- a/plugins/chat/assets/javascripts/discourse/templates/chat-channel-info-settings.hbs
+++ b/plugins/chat/assets/javascripts/discourse/templates/chat-channel-info-settings.hbs
@@ -1 +1 @@
-<ChatChannelSettingsView @channel={{this.model}} />
\ No newline at end of file
+<ChatChannelSettings @channel={{this.model}} />
\ No newline at end of file
diff --git a/plugins/chat/assets/javascripts/discourse/templates/chat-channel-info.hbs b/plugins/chat/assets/javascripts/discourse/templates/chat-channel-info.hbs
index e390f0a194c..660315b5925 100644
--- a/plugins/chat/assets/javascripts/discourse/templates/chat-channel-info.hbs
+++ b/plugins/chat/assets/javascripts/discourse/templates/chat-channel-info.hbs
@@ -1,65 +1 @@
-<div class="channel-info">
-  <div class="chat-full-page-header">
-    <div class="chat-channel-header-details">
-      <div class="chat-full-page-header__left-actions">
-        {{#if this.chatChannelInfoRouteOriginManager.isBrowse}}
-          <LinkTo
-            @route="chat.browse"
-            class="chat-full-page-header__back-btn no-text btn-flat btn"
-            title={{i18n "chat.channel_info.back_to_all_channel"}}
-          >
-            {{d-icon "chevron-left"}}
-          </LinkTo>
-        {{else}}
-          <LinkTo
-            @route="chat.channel"
-            @models={{this.model.routeModels}}
-            class="chat-full-page-header__back-btn no-text btn-flat btn"
-            title={{i18n "chat.channel_info.back_to_channel"}}
-          >
-            {{d-icon "chevron-left"}}
-          </LinkTo>
-        {{/if}}
-      </div>
-
-      <ChatChannelTitle @channel={{this.model}} />
-    </div>
-  </div>
-
-  <ChatChannelStatus @channel={{this.model}} />
-
-  <div class="chat-tabs chat-info-tabs">
-    <ul class="chat-tabs-list nav-pills" role="tablist">
-      {{#each this.tabs as |tab|}}
-        <li
-          class="chat-tabs-list__item"
-          role="tab"
-          aria-controls={{concat tab "-tab"}}
-        >
-          <LinkTo
-            @route={{concat "chat.channel.info." tab}}
-            @models={{this.model.routeModels}}
-            class="chat-tabs-list__link"
-          >
-            <span>{{i18n (concat "chat.channel_info.tabs." tab)}}</span>
-            {{#if (eq tab "members")}}
-              <span class="chat-tabs__memberships-count">
-                ({{this.model.membershipsCount}})
-              </span>
-            {{/if}}
-          </LinkTo>
-        </li>
-      {{/each}}
-    </ul>
-
-    <div
-      id={{this.tab}}
-      class="chat-tabs__tabpanel"
-      aria-hidden={{notEq this.tab this.activeTab}}
-      role="tabpanel"
-      aria-labelledby={{concat this.tab "-tab"}}
-    >
-      {{outlet}}
-    </div>
-  </div>
-</div>
\ No newline at end of file
+<ChatChannelInfo @channel={{this.model}} />
\ No newline at end of file
diff --git a/plugins/chat/assets/stylesheets/common/chat-channel-info.scss b/plugins/chat/assets/stylesheets/common/chat-channel-info.scss
index be5dee75b81..3993019c0d6 100644
--- a/plugins/chat/assets/stylesheets/common/chat-channel-info.scss
+++ b/plugins/chat/assets/stylesheets/common/chat-channel-info.scss
@@ -1,11 +1,19 @@
-.channel-info {
+.chat-channel-info {
   display: flex;
   flex-direction: column;
   height: 100%;
+  padding: 1rem;
+
+  &__nav {
+    .nav-pills {
+      margin: 0;
+      padding-bottom: 1rem;
+    }
+  }
 }
 
 // Info header
-.channel-info-header {
+.chat-channel-info-header {
   display: flex;
   justify-content: space-between;
   align-items: flex-start;
@@ -13,129 +21,7 @@
   box-sizing: border-box;
 }
 
-.channel-info-header__title {
+.chat-channel-info-header__title {
   font-size: var(--font-up-2);
   margin: 0;
 }
-
-// About view
-.channel-info-about-view__title-input {
-  width: 100%;
-}
-
-.channel-info-about-view__description-input {
-  height: 150px;
-  width: 100%;
-}
-
-.channel-info-about-view__description__helper-text {
-  color: var(--primary-medium);
-}
-
-.channel-info-about-view__slug {
-  color: var(--primary-medium);
-  font-size: var(--font-down-2);
-}
-
-.channel-settings-view__selector {
-  width: 220px;
-}
-
-.channel-settings-view__channel-threading-tooltip {
-  padding-left: 0.25rem;
-  color: var(--tertiary);
-  cursor: pointer;
-}
-
-.channel-settings-view__muted-selector,
-.chat-form__btn.delete-btn {
-  .d-icon {
-    color: var(--danger);
-  }
-}
-
-// Members list
-.chat-tabs__memberships-count {
-  margin-left: 0.25em;
-}
-
-.channel-members-view-wrapper {
-  display: flex;
-  flex-direction: column;
-  height: 100%;
-  box-sizing: border-box;
-  padding: 0 1rem;
-}
-
-.channel-members-view__search-input-container {
-  display: flex;
-  align-items: center;
-  border: 1px solid var(--primary-medium);
-
-  &.is-focused {
-    border: 1px solid var(--tertiary);
-  }
-
-  .d-icon {
-    padding: 0.5rem;
-    color: var(--primary-medium);
-  }
-}
-
-input.channel-members-view__search-input {
-  border: 0;
-  margin: 0;
-  outline: 0;
-  width: 100%;
-
-  &:focus {
-    border: 0;
-    outline: 0;
-  }
-}
-
-.channel-members-view__status {
-  display: flex;
-  align-items: center;
-}
-
-.channel-members-view__list-container {
-  display: flex;
-  flex-direction: column;
-  margin-top: 1em;
-  box-sizing: border-box;
-}
-
-.channel-members-view__list-item {
-  display: flex;
-  align-items: center;
-  padding: 0.5rem 0 0.5rem 1px;
-
-  &:not(:last-child) {
-    border-bottom: 1px solid var(--primary-low);
-  }
-
-  .chat-user-avatar {
-    margin-right: 0.5rem;
-  }
-}
-
-// Channel info edit name and slug modal
-.chat-channel-edit-name-slug-modal {
-  .modal-inner-container {
-    width: 300px;
-  }
-
-  &__name-input,
-  &__slug-input {
-    display: flex;
-    margin: 0;
-    width: 100%;
-  }
-}
-
-.chat-channel-edit-name-slug-modal__description {
-  display: flex;
-  padding: 0.5rem 0;
-  color: var(--primary-medium);
-}
diff --git a/plugins/chat/assets/stylesheets/common/chat-channel-members.scss b/plugins/chat/assets/stylesheets/common/chat-channel-members.scss
new file mode 100644
index 00000000000..40a07573bce
--- /dev/null
+++ b/plugins/chat/assets/stylesheets/common/chat-channel-members.scss
@@ -0,0 +1,32 @@
+.chat-channel-members {
+  width: 50%;
+  min-width: 320px;
+
+  &__filter {
+    margin-bottom: 1rem;
+  }
+
+  &__list {
+    display: flex;
+    margin: 0;
+    flex-direction: column;
+    gap: 0.5rem;
+
+    &-item {
+      display: flex;
+      gap: 0.5rem;
+      list-style: none;
+      border-bottom: 1px solid var(--primary-low);
+      height: 42px;
+      align-items: center;
+
+      &.-no-results {
+        box-sizing: border-box;
+      }
+
+      &:last-child {
+        border-bottom: none;
+      }
+    }
+  }
+}
diff --git a/plugins/chat/assets/stylesheets/common/chat-channel-settings-saved-indicator.scss b/plugins/chat/assets/stylesheets/common/chat-channel-settings-saved-indicator.scss
deleted file mode 100644
index e28129f3e17..00000000000
--- a/plugins/chat/assets/stylesheets/common/chat-channel-settings-saved-indicator.scss
+++ /dev/null
@@ -1,9 +0,0 @@
-.chat-channel-settings-saved-indicator {
-  padding-left: 0.5rem;
-  color: var(--success);
-  font-weight: normal;
-
-  .d-icon-check {
-    margin-right: 0.25rem;
-  }
-}
diff --git a/plugins/chat/assets/stylesheets/common/chat-channel-settings.scss b/plugins/chat/assets/stylesheets/common/chat-channel-settings.scss
new file mode 100644
index 00000000000..86023946e05
--- /dev/null
+++ b/plugins/chat/assets/stylesheets/common/chat-channel-settings.scss
@@ -0,0 +1,18 @@
+.chat-channel-settings {
+  width: 50%;
+  min-width: 320px;
+
+  .chat-channel-settings__slug {
+    max-width: 250px;
+    @include ellipsis;
+  }
+
+  // category badge margin reset
+  .badge-wrapper.bullet {
+    margin-right: 0;
+  }
+
+  .chat-retention-reminder-text {
+    color: var(--primary-medium);
+  }
+}
diff --git a/plugins/chat/assets/stylesheets/common/chat-form.scss b/plugins/chat/assets/stylesheets/common/chat-form.scss
index 24e44dc5d84..4071798448a 100644
--- a/plugins/chat/assets/stylesheets/common/chat-form.scss
+++ b/plugins/chat/assets/stylesheets/common/chat-form.scss
@@ -1,62 +1,86 @@
-.chat-form__section {
-  margin: 1.5rem 1rem;
-
-  &:first-child {
-    margin-top: 0;
-  }
-
-  &:last-child {
-    margin-bottom: 0;
-    border-bottom: none;
-  }
-}
-.chat-form__section-admin-title {
-  margin-inline: 1rem;
-  padding-top: 1rem;
-  border-top: 1px solid var(--primary-low);
-}
-
-.chat-form__field {
-  margin-bottom: 1rem;
-
-  &:last-child {
-    margin-bottom: 0;
-  }
-}
-
-.chat-form__description {
-  margin-top: 3px;
-  color: var(--primary-medium);
-  font-size: var(--font-down-1);
-}
-
-.chat-form__btn {
-  border: 0;
-  background: none;
-  padding: 0.25rem 0;
-  margin: 0;
-}
-
-.chat-form__label {
-  font-weight: 700;
+.chat-form {
   display: flex;
-  align-items: center;
+  flex-direction: column;
 }
 
-.chat-form__label-actions {
-  margin-left: auto;
+.chat-form__row {
+  &.-separator {
+    border-bottom: 1px solid var(--primary-low);
+  }
+}
 
-  .btn-text {
-    color: var(--tertiary);
+.chat-form__section {
+  display: flex;
+  flex-direction: column;
+  width: 100%;
+
+  & + .chat-form__section {
+    margin-top: 1rem;
+  }
+
+  &-title {
+    font-weight: 700;
+    font-size: var(--font-down-1);
+    color: var(--primary-medium);
+  }
+
+  &-title + &-content {
+    margin-top: 0.25rem;
+  }
+
+  &-content {
+    background: var(--primary-very-low);
+    gap: 1rem;
+    display: flex;
+    padding: 1rem;
+    flex-direction: column;
+  }
+}
+
+.chat-form__row {
+  display: flex;
+  width: 100%;
+
+  // background: green;
+  flex-direction: column;
+  justify-content: center;
+
+  label,
+  .d-toggle-switch__checkbox-slider {
+    margin: 0;
+  }
+
+  &-action {
+    .chat-form__btn:first-child {
+      padding-left: 0;
+    }
+  }
+
+  &-label + &-action {
+    margin-left: auto;
+  }
+
+  &.-link {
+    color: var(--primary);
+
+    .d-icon {
+      color: var(--primary-medium);
+    }
+  }
+
+  &-content {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+    min-height: 40px;
+    gap: 0.25rem;
+  }
+
+  &-description {
+    display: flex;
+    padding-top: 3px;
+    color: var(--primary-medium);
     font-size: var(--font-down-1);
   }
 }
-
-.chat-retention-info {
-  margin-top: 2rem;
-  color: var(--primary-high);
-
-  .d-icon {
-    margin-right: 0.5em;
-  }
-}
diff --git a/plugins/chat/assets/stylesheets/common/index.scss b/plugins/chat/assets/stylesheets/common/index.scss
index d9ab114867a..220f88a4cbf 100644
--- a/plugins/chat/assets/stylesheets/common/index.scss
+++ b/plugins/chat/assets/stylesheets/common/index.scss
@@ -8,7 +8,6 @@
 @import "chat-channel-card";
 @import "chat-channel-info";
 @import "chat-channel-preview-card";
-@import "chat-channel-settings-saved-indicator";
 @import "chat-channel-title";
 @import "chat-composer-dropdown";
 @import "chat-composer-upload";
@@ -64,3 +63,5 @@
 @import "chat-modal-move-message-to-channel";
 @import "chat-scroll-to-bottom";
 @import "chat-channel-row";
+@import "chat-channel-members";
+@import "chat-channel-settings";
diff --git a/plugins/chat/assets/stylesheets/mobile/chat-channel-info.scss b/plugins/chat/assets/stylesheets/mobile/chat-channel-info.scss
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/plugins/chat/assets/stylesheets/mobile/chat-channel-members.scss b/plugins/chat/assets/stylesheets/mobile/chat-channel-members.scss
new file mode 100644
index 00000000000..2e9eaadc263
--- /dev/null
+++ b/plugins/chat/assets/stylesheets/mobile/chat-channel-members.scss
@@ -0,0 +1,3 @@
+.chat-channel-members {
+  width: 100%;
+}
diff --git a/plugins/chat/assets/stylesheets/mobile/chat-channel-settings.scss b/plugins/chat/assets/stylesheets/mobile/chat-channel-settings.scss
new file mode 100644
index 00000000000..871658cf968
--- /dev/null
+++ b/plugins/chat/assets/stylesheets/mobile/chat-channel-settings.scss
@@ -0,0 +1,3 @@
+.chat-channel-settings {
+  width: 100%;
+}
diff --git a/plugins/chat/assets/stylesheets/mobile/index.scss b/plugins/chat/assets/stylesheets/mobile/index.scss
index 833388c5a50..7e3065003e4 100644
--- a/plugins/chat/assets/stylesheets/mobile/index.scss
+++ b/plugins/chat/assets/stylesheets/mobile/index.scss
@@ -1,5 +1,4 @@
 @import "base-mobile";
-@import "chat-channel-info";
 @import "chat-channel";
 @import "chat-composer";
 @import "chat-index";
@@ -15,3 +14,5 @@
 @import "chat-message-thread-indicator";
 @import "chat-message-creator";
 @import "chat-channel-row";
+@import "chat-channel-members";
+@import "chat-channel-settings";
diff --git a/plugins/chat/config/locales/client.en.yml b/plugins/chat/config/locales/client.en.yml
index 7b3e6828692..72358feed53 100644
--- a/plugins/chat/config/locales/client.en.yml
+++ b/plugins/chat/config/locales/client.en.yml
@@ -320,7 +320,6 @@ en:
         back_to_all_channels: "All channels"
         back_to_channel: "Back"
         tabs:
-          about: About
           members: Members
           settings: Settings
 
@@ -462,6 +461,11 @@ en:
         saved: "Saved"
         unfollow: "Leave"
         admin_title: "Admin"
+        settings_title: "Settings"
+        info_title: "Channel info"
+        category_label: "Category"
+        history_label: "History"
+        members_label: "Members"
 
       admin:
         title: "Chat"
@@ -538,14 +542,14 @@ en:
           other: "%{commaSeparatedUsernames} and %{count} others are typing"
 
       retention_reminders:
-        public_none: "Channel history is retained indefinitely."
+        public_none: "indefinitely"
         public:
-          one: "Channel history is retained for %{count} day."
-          other: "Channel history is retained for %{count} days."
-        dm_none: "Personal chat history is retained indefinitely."
+          one: "%{count} day"
+          other: "%{count} days"
+        dm_none: "indefinitely"
         dm:
-          one: "Personal chat history is retained for %{count} day."
-          other: "Personal chat history is retained for %{count} days."
+          one: "%{count} day"
+          other: "%{count} days"
 
       flags:
         off_topic: "This message is not relevant to the current discussion as defined by the channel title, and should probably be moved elsewhere."
diff --git a/plugins/chat/spec/system/channel_about_page_spec.rb b/plugins/chat/spec/system/channel_about_page_spec.rb
deleted file mode 100644
index 550fa4c3ee4..00000000000
--- a/plugins/chat/spec/system/channel_about_page_spec.rb
+++ /dev/null
@@ -1,138 +0,0 @@
-# frozen_string_literal: true
-
-RSpec.describe "Channel - Info - About page", type: :system do
-  fab!(:channel_1) { Fabricate(:category_channel) }
-
-  let(:chat_page) { PageObjects::Pages::Chat.new }
-  let(:chat_channel_about_page) { PageObjects::Pages::ChatChannelAbout.new }
-
-  before { chat_system_bootstrap }
-
-  context "as regular user" do
-    fab!(:current_user) { Fabricate(:user) }
-
-    before { sign_in(current_user) }
-
-    it "shows channel info" do
-      chat_page.visit_channel_about(channel_1)
-
-      expect(page.find(".category-name")).to have_content(channel_1.chatable.name)
-      expect(page.find(".channel-info-about-view__name")).to have_content(channel_1.title)
-      expect(page.find(".channel-info-about-view__slug")).to have_content(channel_1.slug)
-    end
-
-    it "escapes channel title" do
-      channel_1.update!(name: "<script>alert('hello')</script>")
-      chat_page.visit_channel_about(channel_1)
-
-      expect(page.find(".channel-info-about-view__name")["innerHTML"].strip).to eq(
-        "&lt;script&gt;alert('hello')&lt;/script&gt;",
-      )
-      expect(page.find(".chat-channel-title__name")["innerHTML"].strip).to eq(
-        "&lt;script&gt;alert('hello')&lt;/script&gt;",
-      )
-    end
-
-    it "can’t edit name or slug" do
-      chat_page.visit_channel_about(channel_1)
-
-      expect(page).to have_no_selector(".edit-name-slug-btn")
-    end
-
-    it "can’t edit description" do
-      chat_page.visit_channel_about(channel_1)
-
-      expect(page).to have_no_selector(".edit-description-btn")
-    end
-
-    context "as a member" do
-      before { channel_1.add(current_user) }
-
-      it "can leave channel" do
-        chat_page.visit_channel_about(channel_1)
-        membership = channel_1.membership_for(current_user)
-
-        expect {
-          click_button(I18n.t("js.chat.channel_settings.leave_channel"))
-          expect(page).to have_content(I18n.t("js.chat.channel_settings.join_channel"))
-        }.to change { membership.reload.following }.from(true).to(false)
-      end
-    end
-
-    context "as not a member" do
-      it "can join channel" do
-        chat_page.visit_channel_about(channel_1)
-
-        expect {
-          click_button(I18n.t("js.chat.channel_settings.join_channel"))
-          expect(page).to have_content(I18n.t("js.chat.channel_settings.leave_channel"))
-        }.to change {
-          Chat::UserChatChannelMembership.where(user_id: current_user.id, following: true).count
-        }.by(1)
-      end
-    end
-  end
-
-  context "as admin" do
-    fab!(:current_user) { Fabricate(:admin) }
-
-    before { sign_in(current_user) }
-
-    it "can edit name" do
-      chat_page.visit_channel_about(channel_1)
-
-      edit_modal = chat_channel_about_page.open_edit_modal
-
-      expect(edit_modal).to have_name_input(channel_1.title)
-
-      name = "A new name"
-
-      edit_modal.fill_and_save_name(name)
-
-      expect(chat_channel_about_page).to have_name(name)
-    end
-
-    it "can edit description" do
-      chat_page.visit_channel_about(channel_1)
-      find(".edit-description-btn").click
-
-      expect(page).to have_selector(
-        ".chat-modal-edit-channel-description__description-input",
-        text: channel_1.description,
-      )
-
-      description = "A new description"
-      find(".chat-modal-edit-channel-description__description-input").fill_in(with: description)
-      find(".create").click
-
-      expect(page).to have_content(description)
-    end
-
-    it "can edit slug" do
-      chat_page.visit_channel_about(channel_1)
-      edit_modal = chat_channel_about_page.open_edit_modal
-
-      slug = "gonzo-slug"
-
-      expect(edit_modal).to have_slug_input(channel_1.slug)
-
-      edit_modal.fill_and_save_slug(slug)
-
-      expect(chat_channel_about_page).to have_slug(slug)
-    end
-
-    it "can clear the slug to use the autogenerated version based on the name" do
-      channel_1.update!(name: "test channel")
-      chat_page.visit_channel_about(channel_1)
-      edit_modal = chat_channel_about_page.open_edit_modal
-
-      expect(edit_modal).to have_slug_input(channel_1.slug)
-
-      edit_modal.fill_in_slug_input("")
-      edit_modal.wait_for_auto_generated_slug
-      edit_modal.save_changes
-
-      expect(chat_channel_about_page).to have_slug("test-channel")
-    end
-  end
-end
diff --git a/plugins/chat/spec/system/channel_info_pages_spec.rb b/plugins/chat/spec/system/channel_info_pages_spec.rb
deleted file mode 100644
index 0b53d1e0f05..00000000000
--- a/plugins/chat/spec/system/channel_info_pages_spec.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-# frozen_string_literal: true
-
-RSpec.describe "Info pages", type: :system do
-  let(:chat_page) { PageObjects::Pages::Chat.new }
-  let(:channel) { PageObjects::Pages::ChatChannel.new }
-  fab!(:current_user) { Fabricate(:user) }
-  fab!(:channel_1) { Fabricate(:chat_channel) }
-
-  before do
-    chat_system_bootstrap
-    channel_1.add(current_user)
-    sign_in(current_user)
-  end
-
-  context "when visiting from browse page" do
-    context "when clicking back button" do
-      it "redirects to browse page" do
-        chat_page.visit_browse
-        find(".chat-channel-card__setting").click
-        find(".chat-full-page-header__back-btn").click
-
-        expect(page).to have_current_path("/chat/browse/open")
-      end
-    end
-  end
-
-  context "when visiting from channel page" do
-    context "when clicking back button" do
-      it "redirects to channel page" do
-        chat_page.visit_channel(channel_1)
-        find(".chat-channel-title-wrapper").click
-        find(".chat-full-page-header__back-btn").click
-
-        expect(page).to have_current_path(chat.channel_path(channel_1.slug, channel_1.id))
-      end
-    end
-  end
-end
diff --git a/plugins/chat/spec/system/channel_members_page_spec.rb b/plugins/chat/spec/system/channel_members_page_spec.rb
index becfd2812f7..8c7b3c9eae0 100644
--- a/plugins/chat/spec/system/channel_members_page_spec.rb
+++ b/plugins/chat/spec/system/channel_members_page_spec.rb
@@ -14,7 +14,7 @@ RSpec.describe "Channel - Info - Members page", type: :system do
   context "as unauthorized user" do
     before { SiteSetting.chat_allowed_groups = Fabricate(:group).id }
 
-    it "can’t see channel members" do
+    it "can't see channel members" do
       chat_page.visit_channel_members(channel_1)
 
       expect(page).to have_current_path("/latest")
@@ -23,10 +23,10 @@ RSpec.describe "Channel - Info - Members page", type: :system do
 
   context "as authorized user" do
     context "with no members" do
-      it "redirects to about page" do
+      it "redirects to settings page" do
         chat_page.visit_channel_members(channel_1)
 
-        expect(page).to have_current_path("/chat/c/#{channel_1.slug}/#{channel_1.id}/info/about")
+        expect(page).to have_current_path("/chat/c/#{channel_1.slug}/#{channel_1.id}/info/settings")
       end
     end
 
@@ -44,15 +44,15 @@ RSpec.describe "Channel - Info - Members page", type: :system do
 
         chat_page.visit_channel_members(channel_1)
 
-        expect(page).to have_selector(".channel-members-view__list-item", count: 50, wait: 15)
+        expect(page).to have_selector(".chat-channel-members__list-item", count: 60)
 
-        scroll_to(find(".channel-members-view__list-item:nth-child(50)"))
+        scroll_to(find(".chat-channel-members__list-item:nth-child(50)"))
 
-        expect(page).to have_selector(".channel-members-view__list-item", count: 100, wait: 15)
+        expect(page).to have_selector(".chat-channel-members__list-item", count: 100)
 
-        scroll_to(find(".channel-members-view__list-item:nth-child(100)"))
+        scroll_to(find(".chat-channel-members__list-item:nth-child(100)"))
 
-        expect(page).to have_selector(".channel-members-view__list-item", count: 100, wait: 15)
+        expect(page).to have_selector(".chat-channel-members__list-item", count: 100)
       end
 
       context "with filter" do
@@ -62,9 +62,9 @@ RSpec.describe "Channel - Info - Members page", type: :system do
           Jobs::Chat::UpdateChannelUserCount.new.execute(chat_channel_id: channel_1.id)
 
           chat_page.visit_channel_members(channel_1)
-          find(".channel-members-view__search-input").fill_in(with: "cat")
+          find(".chat-channel-members__filter").fill_in(with: "cat")
 
-          expect(page).to have_selector(".channel-members-view__list-item", count: 1, text: "cat")
+          expect(page).to have_selector(".chat-channel-members__list-item", count: 1, text: "cat")
         end
       end
     end
diff --git a/plugins/chat/spec/system/channel_settings_page_spec.rb b/plugins/chat/spec/system/channel_settings_page_spec.rb
index 5196a3e8856..1e6631d69b9 100644
--- a/plugins/chat/spec/system/channel_settings_page_spec.rb
+++ b/plugins/chat/spec/system/channel_settings_page_spec.rb
@@ -1,15 +1,42 @@
 # frozen_string_literal: true
 
 RSpec.describe "Channel - Info - Settings page", type: :system do
-  let(:chat_page) { PageObjects::Pages::Chat.new }
   fab!(:current_user) { Fabricate(:user) }
   fab!(:channel_1) { Fabricate(:category_channel) }
 
+  let(:chat_page) { PageObjects::Pages::Chat.new }
+  let(:toasts) { PageObjects::Components::Toasts.new }
+  let(:channel_settings_page) { PageObjects::Pages::ChatChannelSettings.new }
+
   before do
     chat_system_bootstrap
     sign_in(current_user)
   end
 
+  context "when visiting from browse page" do
+    context "when clicking back button" do
+      it "redirects to browse page" do
+        chat_page.visit_browse
+        find(".chat-channel-card__setting").click
+        find(".chat-full-page-header__back-btn").click
+
+        expect(page).to have_current_path("/chat/browse/open")
+      end
+    end
+  end
+
+  context "when visiting from channel page" do
+    context "when clicking back button" do
+      it "redirects to channel page" do
+        chat_page.visit_channel(channel_1)
+        find(".chat-channel-title-wrapper").click
+        find(".chat-full-page-header__back-btn").click
+
+        expect(page).to have_current_path(chat.channel_path(channel_1.slug, channel_1.id))
+      end
+    end
+  end
+
   context "as unauthorized user" do
     before { SiteSetting.chat_allowed_groups = Fabricate(:group).id }
 
@@ -20,194 +47,244 @@ RSpec.describe "Channel - Info - Settings page", type: :system do
     end
   end
 
-  context "as authorized user" do
-    context "as not member" do
-      it "redirects to about tab" do
-        chat_page.visit_channel_settings(channel_1)
+  context "as not allowed to see the channel" do
+    fab!(:channel_1) { Fabricate(:private_category_channel) }
 
-        expect(page).to have_current_path("/chat/c/#{channel_1.slug}/#{channel_1.id}/info/about")
-      end
+    it "redirects to browse page" do
+      chat_page.visit_channel_settings(channel_1)
 
-      it "doesn’t have settings tab" do
-        chat_page.visit_channel_settings(channel_1)
+      expect(page).to have_current_path("/chat/browse/open")
+    end
+  end
 
-        expect(page).to have_no_selector(".chat-tabs-list__item[aria-controls='settings-tab']")
-      end
+  context "as not member of channel" do
+    it "shows settings page" do
+      chat_page.visit_channel_settings(channel_1)
 
-      context "as an admin" do
-        before { sign_in(Fabricate(:admin)) }
+      expect(page).to have_current_path("/chat/c/#{channel_1.slug}/#{channel_1.id}/info/settings")
+    end
+  end
 
-        it "shows settings tab" do
-          chat_page.visit_channel_settings(channel_1)
+  context "as regular user of channel" do
+    before { channel_1.add(current_user) }
 
-          expect(page).to have_selector(".chat-tabs-list__item[aria-controls='settings-tab']")
-        end
+    it "shows settings page" do
+      chat_page.visit_channel_settings(channel_1)
 
-        it "can navigate to settings tab" do
-          chat_page.visit_channel_settings(channel_1)
-
-          expect(page).to have_current_path(
-            "/chat/c/#{channel_1.slug}/#{channel_1.id}/info/settings",
-          )
-        end
-      end
+      expect(page).to have_current_path("/chat/c/#{channel_1.slug}/#{channel_1.id}/info/settings")
     end
 
-    context "as a member" do
-      before { channel_1.add(current_user) }
+    it "shows channel info" do
+      chat_page.visit_channel_settings(channel_1)
 
-      context "when visiting the settings of a recently joined channel" do
-        fab!(:channel_2) { Fabricate(:category_channel) }
+      expect(page.find(".category-name")).to have_content(channel_1.chatable.name)
+      expect(page.find(".chat-channel-settings__name")).to have_content(channel_1.title)
+      expect(page.find(".chat-channel-settings__slug")).to have_content(channel_1.slug)
+    end
 
-        it "is correctly populated" do
-          chat_page.visit_browse
-          find(
-            ".chat-channel-card[data-channel-id='#{channel_2.id}'] .toggle-channel-membership-button",
-          ).click
+    it "can’t edit name or slug" do
+      chat_page.visit_channel_settings(channel_1)
 
-          expect(
-            page.find(".chat-channel-card[data-channel-id='#{channel_2.id}']"),
-          ).to have_content(I18n.t("js.chat.joined").upcase)
+      expect(page).to have_no_selector(".edit-name-slug-btn")
+    end
 
-          find(
-            ".chat-channel-card[data-channel-id='#{channel_2.id}'] .chat-channel-card__setting",
-          ).click
+    it "can’t edit description" do
+      chat_page.visit_channel_settings(channel_1)
 
-          expect(page).to have_content(I18n.t("js.chat.notification_levels.mention"))
-        end
-      end
+      expect(page).to have_no_selector(".edit-description-btn")
+    end
 
-      it "can mute channel" do
-        chat_page.visit_channel_settings(channel_1)
-        membership = channel_1.membership_for(current_user)
+    it "escapes channel title" do
+      channel_1.update!(name: "<script>alert('hello')</script>")
+      chat_page.visit_channel_settings(channel_1)
 
-        expect {
-          select_kit =
-            PageObjects::Components::SelectKit.new(".-mute .channel-settings-view__selector")
-          select_kit.expand
-          select_kit.select_row_by_name("On")
+      expect(page.find(".chat-channel-settings__name")["innerHTML"].strip).to eq(
+        "&lt;script&gt;alert('hello')&lt;/script&gt;",
+      )
+      expect(page.find(".chat-channel-title__name")["innerHTML"].strip).to eq(
+        "&lt;script&gt;alert('hello')&lt;/script&gt;",
+      )
+    end
 
-          expect(page).to have_content(I18n.t("js.chat.settings.saved"))
-        }.to change { membership.reload.muted }.from(false).to(true)
-      end
+    it "is not showing admin section" do
+      chat_page.visit_channel_settings(channel_1)
 
-      it "can change desktop notification level" do
-        chat_page.visit_channel_settings(channel_1)
-        membership = channel_1.membership_for(current_user)
+      expect(page).to have_no_css("[data-section='admin']")
+    end
 
-        expect {
-          select_kit =
-            PageObjects::Components::SelectKit.new(
-              ".-desktop-notification-level .channel-settings-view__selector",
-            )
-          select_kit.expand
-          select_kit.select_row_by_name("Never")
+    it "can mute channel" do
+      chat_page.visit_channel_settings(channel_1)
+      membership = channel_1.membership_for(current_user)
 
-          expect(page).to have_content(I18n.t("js.chat.settings.saved"))
-        }.to change { membership.reload.desktop_notification_level }.from("mention").to("never")
-      end
+      expect {
+        PageObjects::Components::DToggleSwitch.new(".chat-channel-settings__mute-switch").toggle
 
-      it "can change mobile notification level" do
-        chat_page.visit_channel_settings(channel_1)
-        membership = channel_1.membership_for(current_user)
+        expect(toasts).to have_success(I18n.t("js.saved"))
+      }.to change { membership.reload.muted }.from(false).to(true)
+    end
 
-        expect {
-          select_kit =
-            PageObjects::Components::SelectKit.new(
-              ".-mobile-notification-level .channel-settings-view__selector",
-            )
-          select_kit.expand
-          select_kit.select_row_by_name("Never")
+    it "can change desktop notification level" do
+      chat_page.visit_channel_settings(channel_1)
+      membership = channel_1.membership_for(current_user)
 
-          expect(page).to have_content(I18n.t("js.chat.settings.saved"))
-        }.to change { membership.reload.mobile_notification_level }.from("mention").to("never")
-      end
+      expect {
+        select_kit =
+          PageObjects::Components::SelectKit.new(
+            ".chat-channel-settings__desktop-notifications-selector",
+          )
+        select_kit.expand
+        select_kit.select_row_by_name("Never")
 
-      it "doesn’t show admin section" do
-        chat_page.visit_channel_settings(channel_1)
+        expect(toasts).to have_success(I18n.t("js.saved"))
+      }.to change { membership.reload.desktop_notification_level }.from("mention").to("never")
+    end
 
-        expect(page).to have_no_content(I18n.t("js.chat.settings.admin_title"))
-      end
+    it "can change mobile notification level" do
+      chat_page.visit_channel_settings(channel_1)
+      membership = channel_1.membership_for(current_user)
 
-      context "as an admin" do
-        before { sign_in(Fabricate(:admin)) }
+      expect {
+        select_kit =
+          PageObjects::Components::SelectKit.new(
+            ".chat-channel-settings__mobile-notifications-selector",
+          )
+        select_kit.expand
+        select_kit.select_row_by_name("Never")
 
-        it "shows admin section" do
-          chat_page.visit_channel_settings(channel_1)
+        expect(toasts).to have_success(I18n.t("js.saved"))
+      }.to change { membership.reload.mobile_notification_level }.from("mention").to("never")
+    end
+  end
 
-          expect(page).to have_content(I18n.t("js.chat.settings.admin_title"))
-        end
+  context "as staff" do
+    fab!(:current_user) { Fabricate(:admin) }
 
-        it "can change auto join setting" do
-          chat_page.visit_channel_settings(channel_1)
+    it "can edit name" do
+      chat_page.visit_channel_settings(channel_1)
 
-          expect {
-            select_kit =
-              PageObjects::Components::SelectKit.new(".-autojoin .channel-settings-view__selector")
-            select_kit.expand
-            select_kit.select_row_by_name("Yes")
-            find("#dialog-holder .btn-primary").click
+      edit_modal = channel_settings_page.open_edit_modal
 
-            expect(page).to have_content(I18n.t("js.chat.settings.saved"))
-          }.to change { channel_1.reload.auto_join_users }.from(false).to(true)
-        end
+      expect(edit_modal).to have_name_input(channel_1.title)
 
-        it "can change allow channel wide mentions" do
-          chat_page.visit_channel_settings(channel_1)
+      name = "A new name"
 
-          expect {
-            select_kit =
-              PageObjects::Components::SelectKit.new(
-                ".-channel-wide-mentions .channel-settings-view__selector",
-              )
-            select_kit.expand
-            select_kit.select_row_by_name("No")
+      edit_modal.fill_and_save_name(name)
 
-            expect(page).to have_content(I18n.t("js.chat.settings.saved"))
-          }.to change { channel_1.reload.allow_channel_wide_mentions }.from(true).to(false)
-        end
+      expect(channel_settings_page).to have_name(name)
+    end
 
-        it "can close channel" do
-          chat_page.visit_channel_settings(channel_1)
+    it "can edit description" do
+      chat_page.visit_channel_settings(channel_1)
+      find(".edit-description-btn").click
 
-          expect {
-            click_button(I18n.t("js.chat.channel_settings.close_channel"))
-            find("#chat-channel-toggle-btn").click
-            expect(page).to have_content(I18n.t("js.chat.channel_status.closed_header"))
-          }.to change { channel_1.reload.status }.from("open").to("closed")
-        end
+      expect(page).to have_selector(
+        ".chat-modal-edit-channel-description__description-input",
+        text: channel_1.description,
+      )
 
-        it "can enable threading" do
-          chat_page.visit_channel_settings(channel_1)
+      description = "A new description"
+      find(".chat-modal-edit-channel-description__description-input").fill_in(with: description)
+      find(".create").click
 
-          expect {
-            select_kit =
-              PageObjects::Components::SelectKit.new(".-threading .channel-settings-view__selector")
-            select_kit.expand
-            select_kit.select_row_by_name("Enabled")
-            expect(page).to have_content(I18n.t("js.chat.settings.saved"))
-          }.to change { channel_1.reload.threading_enabled }.from(false).to(true)
-        end
+      expect(page).to have_content(description)
+    end
 
-        it "can delete channel" do
-          chat_page.visit_channel_settings(channel_1)
+    it "can edit slug" do
+      chat_page.visit_channel_settings(channel_1)
+      edit_modal = channel_settings_page.open_edit_modal
 
-          click_button(I18n.t("js.chat.channel_settings.delete_channel"))
-          fill_in("channel-delete-confirm-name", with: channel_1.title)
-          find_button("chat-confirm-delete-channel", disabled: false).click
-          expect(page).to have_content(I18n.t("js.chat.channel_delete.process_started"))
-        end
+      slug = "gonzo-slug"
 
-        context "when confirmation name is wrong" do
-          it "doesn’t delete submission" do
-            chat_page.visit_channel_settings(channel_1)
-            find(".delete-btn").click
-            fill_in("channel-delete-confirm-name", with: channel_1.title + "wrong")
+      expect(edit_modal).to have_slug_input(channel_1.slug)
 
-            expect(page).to have_button("chat-confirm-delete-channel", disabled: true)
-          end
-        end
-      end
+      edit_modal.fill_and_save_slug(slug)
+
+      expect(channel_settings_page).to have_slug(slug)
+    end
+
+    it "can clear the slug to use the autogenerated version based on the name" do
+      channel_1.update!(name: "test channel")
+      chat_page.visit_channel_settings(channel_1)
+      edit_modal = channel_settings_page.open_edit_modal
+
+      expect(edit_modal).to have_slug_input(channel_1.slug)
+
+      edit_modal.fill_in_slug_input("")
+      edit_modal.wait_for_auto_generated_slug
+      edit_modal.save_changes
+
+      expect(channel_settings_page).to have_slug("test-channel")
+    end
+
+    it "shows settings page" do
+      chat_page.visit_channel_settings(channel_1)
+
+      expect(page).to have_current_path("/chat/c/#{channel_1.slug}/#{channel_1.id}/info/settings")
+    end
+
+    it "can change auto join setting" do
+      chat_page.visit_channel_settings(channel_1)
+
+      expect {
+        PageObjects::Components::DToggleSwitch.new(
+          ".chat-channel-settings__auto-join-switch",
+        ).toggle
+        find("#dialog-holder .btn-primary").click
+
+        expect(toasts).to have_success(I18n.t("js.saved"))
+      }.to change { channel_1.reload.auto_join_users }.from(false).to(true)
+    end
+
+    it "can change allow channel wide mentions" do
+      chat_page.visit_channel_settings(channel_1)
+
+      expect {
+        PageObjects::Components::DToggleSwitch.new(
+          ".chat-channel-settings__channel-wide-mentions",
+        ).toggle
+
+        expect(toasts).to have_success(I18n.t("js.saved"))
+      }.to change { channel_1.reload.allow_channel_wide_mentions }.from(true).to(false)
+    end
+
+    it "can close channel" do
+      chat_page.visit_channel_settings(channel_1)
+
+      expect {
+        click_button(I18n.t("js.chat.channel_settings.close_channel"))
+        find("#chat-channel-toggle-btn").click
+
+        expect(page).to have_content(I18n.t("js.chat.channel_status.closed_header"))
+      }.to change { channel_1.reload.status }.from("open").to("closed")
+    end
+
+    it "can enable threading" do
+      chat_page.visit_channel_settings(channel_1)
+
+      expect {
+        PageObjects::Components::DToggleSwitch.new(
+          ".chat-channel-settings__threading-switch",
+        ).toggle
+
+        expect(toasts).to have_success(I18n.t("js.saved"))
+      }.to change { channel_1.reload.threading_enabled }.from(false).to(true)
+    end
+
+    it "can delete channel" do
+      chat_page.visit_channel_settings(channel_1)
+
+      click_button(I18n.t("js.chat.channel_settings.delete_channel"))
+      fill_in("channel-delete-confirm-name", with: channel_1.title)
+      find_button("chat-confirm-delete-channel", disabled: false).click
+      expect(page).to have_content(I18n.t("js.chat.channel_delete.process_started"))
+    end
+
+    it "doesn’t delete when confirmation is wrong" do
+      chat_page.visit_channel_settings(channel_1)
+      find(".delete-btn").click
+      fill_in("channel-delete-confirm-name", with: channel_1.title + "wrong")
+
+      expect(page).to have_button("chat-confirm-delete-channel", disabled: true)
     end
   end
 end
diff --git a/plugins/chat/spec/system/drawer_spec.rb b/plugins/chat/spec/system/drawer_spec.rb
index 4def6cbd4e3..6e6c072094a 100644
--- a/plugins/chat/spec/system/drawer_spec.rb
+++ b/plugins/chat/spec/system/drawer_spec.rb
@@ -24,7 +24,7 @@ RSpec.describe "Drawer", type: :system do
         drawer_page.open_channel(channel)
         page.find(".chat-channel-title").click
 
-        expect(page).to have_current_path("/chat/c/#{channel.slug}/#{channel.id}/info/about")
+        expect(page).to have_current_path("/chat/c/#{channel.slug}/#{channel.id}/info/settings")
       end
     end
   end
diff --git a/plugins/chat/spec/system/page_objects/chat/chat.rb b/plugins/chat/spec/system/page_objects/chat/chat.rb
index d2fa99777c8..2b9a3117fc5 100644
--- a/plugins/chat/spec/system/page_objects/chat/chat.rb
+++ b/plugins/chat/spec/system/page_objects/chat/chat.rb
@@ -63,10 +63,6 @@ module PageObjects
         visit(channel.url + "/info/settings")
       end
 
-      def visit_channel_about(channel)
-        visit(channel.url + "/info/about")
-      end
-
       def visit_channel_members(channel)
         visit(channel.url + "/info/members")
       end
diff --git a/plugins/chat/spec/system/page_objects/chat/chat_channel_about.rb b/plugins/chat/spec/system/page_objects/chat/chat_channel_settings.rb
similarity index 68%
rename from plugins/chat/spec/system/page_objects/chat/chat_channel_about.rb
rename to plugins/chat/spec/system/page_objects/chat/chat_channel_settings.rb
index a28836bb59f..34d9ee1b8b1 100644
--- a/plugins/chat/spec/system/page_objects/chat/chat_channel_about.rb
+++ b/plugins/chat/spec/system/page_objects/chat/chat_channel_settings.rb
@@ -2,7 +2,7 @@
 
 module PageObjects
   module Pages
-    class ChatChannelAbout < PageObjects::Pages::Base
+    class ChatChannelSettings < PageObjects::Pages::Base
       EDIT_MODAL_SELECTOR = ".chat-modal-edit-channel-name"
 
       def open_edit_modal
@@ -12,11 +12,11 @@ module PageObjects
       end
 
       def has_slug?(slug)
-        page.has_css?(".channel-info-about-view__slug", text: slug)
+        page.has_css?(".chat-channel-settings__slug", text: slug)
       end
 
       def has_name?(name)
-        page.has_css?(".channel-info-about-view__name", text: name)
+        page.has_css?(".chat-channel-settings__name", text: name)
       end
     end
   end
diff --git a/plugins/chat/spec/system/page_objects/modals/chat_edit_modal.rb b/plugins/chat/spec/system/page_objects/modals/chat_edit_modal.rb
index d678db64485..0930ccb0970 100644
--- a/plugins/chat/spec/system/page_objects/modals/chat_edit_modal.rb
+++ b/plugins/chat/spec/system/page_objects/modals/chat_edit_modal.rb
@@ -5,7 +5,7 @@ module PageObjects
     class ChatChannelEdit < PageObjects::Modals::Base
       include SystemHelpers
 
-      EDIT_MODAL_SELECTOR = PageObjects::Pages::ChatChannelAbout::EDIT_MODAL_SELECTOR
+      EDIT_MODAL_SELECTOR = PageObjects::Pages::ChatChannelSettings::EDIT_MODAL_SELECTOR
       SLUG_INPUT_SELECTOR = ".chat-channel-edit-name-slug-modal__slug-input"
       NAME_INPUT_SELECTOR = ".chat-channel-edit-name-slug-modal__name-input"
 
diff --git a/plugins/chat/test/javascripts/components/chat-channel-settings-saved-indicator-test.js b/plugins/chat/test/javascripts/components/chat-channel-settings-saved-indicator-test.js
deleted file mode 100644
index 6f03050cb05..00000000000
--- a/plugins/chat/test/javascripts/components/chat-channel-settings-saved-indicator-test.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import { module, test } from "qunit";
-import { setupRenderingTest } from "discourse/tests/helpers/component-test";
-import { render, settled } from "@ember/test-helpers";
-import { hbs } from "ember-cli-htmlbars";
-
-module(
-  "Discourse Chat | Component | chat-channel-settings-saved-indicator",
-  function (hooks) {
-    setupRenderingTest(hooks);
-
-    test("when property changes", async function (assert) {
-      await render(
-        hbs`<ChatChannelSettingsSavedIndicator @property={{this.property}} />`
-      );
-
-      assert
-        .dom(".chat-channel-settings-saved-indicator.is-active")
-        .doesNotExist();
-
-      this.set("property", 1);
-
-      assert.dom(".chat-channel-settings-saved-indicator.is-active").exists();
-
-      await settled();
-
-      assert
-        .dom(".chat-channel-settings-saved-indicator.is-active")
-        .doesNotExist();
-    });
-  }
-);
diff --git a/plugins/chat/test/javascripts/components/chat-channel-settings-view-test.js b/plugins/chat/test/javascripts/components/chat-channel-settings-view-test.js
deleted file mode 100644
index 3bc294b528f..00000000000
--- a/plugins/chat/test/javascripts/components/chat-channel-settings-view-test.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import ChatChannel from "discourse/plugins/chat/discourse/models/chat-channel";
-import { setupRenderingTest } from "discourse/tests/helpers/component-test";
-import hbs from "htmlbars-inline-precompile";
-import I18n from "I18n";
-import { module, test } from "qunit";
-import { render } from "@ember/test-helpers";
-
-module(
-  "Discourse Chat | Component | chat-channel-settings-view",
-  function (hooks) {
-    setupRenderingTest(hooks);
-
-    test("display retention info", async function (assert) {
-      this.set("channel", ChatChannel.create({ chatable_type: "Category" }));
-
-      await render(hbs`<ChatChannelSettingsView @channel={{this.channel}} />`);
-
-      assert.dom(".chat-retention-info").hasText(
-        I18n.t("chat.retention_reminders.public", {
-          count: this.siteSettings.chat_channel_retention_days,
-        })
-      );
-    });
-  }
-);
diff --git a/spec/system/page_objects/components/d_toggle_switch.rb b/spec/system/page_objects/components/d_toggle_switch.rb
new file mode 100644
index 00000000000..5569a83a678
--- /dev/null
+++ b/spec/system/page_objects/components/d_toggle_switch.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+module PageObjects
+  module Components
+    class DToggleSwitch < PageObjects::Components::Base
+      attr_reader :context
+
+      def initialize(context)
+        @context = context
+      end
+
+      def component
+        find(@context, visible: :all).native
+      end
+
+      def toggle
+        actionbuilder = page.driver.browser.action # workaround zero height button
+        actionbuilder.click(component).perform
+      end
+    end
+  end
+end