diff --git a/src/addons/mod/chat/chat-lazy.module.ts b/src/addons/mod/chat/chat-lazy.module.ts
new file mode 100644
index 000000000..e190a1860
--- /dev/null
+++ b/src/addons/mod/chat/chat-lazy.module.ts
@@ -0,0 +1,38 @@
+// (C) Copyright 2015 Moodle Pty Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import { NgModule } from '@angular/core';
+import { RouterModule, Routes } from '@angular/router';
+import { CoreSharedModule } from '@/core/shared.module';
+import { AddonModChatComponentsModule } from './components/components.module';
+import { AddonModChatIndexPage } from './pages/index/index';
+
+const routes: Routes = [
+ {
+ path: ':courseId/:cmId',
+ component: AddonModChatIndexPage,
+ },
+];
+
+@NgModule({
+ imports: [
+ RouterModule.forChild(routes),
+ CoreSharedModule,
+ AddonModChatComponentsModule,
+ ],
+ declarations: [
+ AddonModChatIndexPage,
+ ],
+})
+export class AddonModChatLazyModule {}
diff --git a/src/addons/mod/chat/components/components.module.ts b/src/addons/mod/chat/components/components.module.ts
new file mode 100644
index 000000000..5c340aab9
--- /dev/null
+++ b/src/addons/mod/chat/components/components.module.ts
@@ -0,0 +1,34 @@
+// (C) Copyright 2015 Moodle Pty Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import { NgModule } from '@angular/core';
+import { AddonModChatIndexComponent } from './index/index';
+import { CoreSharedModule } from '@/core/shared.module';
+import { CoreCourseComponentsModule } from '@features/course/components/components.module';
+
+@NgModule({
+ declarations: [
+ AddonModChatIndexComponent,
+ ],
+ imports: [
+ CoreSharedModule,
+ CoreCourseComponentsModule,
+ ],
+ providers: [
+ ],
+ exports: [
+ AddonModChatIndexComponent,
+ ],
+})
+export class AddonModChatComponentsModule {}
diff --git a/src/addons/mod/chat/components/index/addon-mod-chat-index.html b/src/addons/mod/chat/components/index/addon-mod-chat-index.html
new file mode 100644
index 000000000..b4aa0ca7d
--- /dev/null
+++ b/src/addons/mod/chat/components/index/addon-mod-chat-index.html
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ 'addon.mod_chat.sessionstart' | translate:{$a: chatInfo} }}
+
+
+
+
+
+ {{ 'addon.mod_chat.enterchat' | translate }}
+
+
+ {{ 'addon.mod_chat.viewreport' | translate }}
+
+
+
diff --git a/src/addons/mod/chat/components/index/index.ts b/src/addons/mod/chat/components/index/index.ts
new file mode 100644
index 000000000..bd70985d2
--- /dev/null
+++ b/src/addons/mod/chat/components/index/index.ts
@@ -0,0 +1,129 @@
+// (C) Copyright 2015 Moodle Pty Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import { Component, OnInit, Optional } from '@angular/core';
+import { CoreCourseModuleMainActivityComponent } from '@features/course/classes/main-activity-component';
+import { CoreCourseContentsPage } from '@features/course/pages/contents/contents';
+import { CoreCourse } from '@features/course/services/course';
+import { IonContent } from '@ionic/angular';
+import { CoreNavigator } from '@services/navigator';
+import { CoreTimeUtils } from '@services/utils/time';
+import { AddonModChat, AddonModChatChat, AddonModChatProvider } from '../../services/chat';
+import { AddonModChatModuleHandlerService } from '../../services/handlers/module';
+
+/**
+ * Component that displays a chat.
+ */
+@Component({
+ selector: 'addon-mod-chat-index',
+ templateUrl: 'addon-mod-chat-index.html',
+})
+export class AddonModChatIndexComponent extends CoreCourseModuleMainActivityComponent implements OnInit {
+
+ component = AddonModChatProvider.COMPONENT;
+ moduleName = 'chat';
+ chat?: AddonModChatChat;
+ sessionsAvailable = false;
+ chatInfo?: {
+ date: string;
+ fromnow: string;
+ };
+
+ constructor(
+ protected content?: IonContent,
+ @Optional() courseContentsPage?: CoreCourseContentsPage,
+ ) {
+ super('AddonModChatIndexComponent', content, courseContentsPage);
+ }
+
+ /**
+ * @inheritdoc
+ */
+ async ngOnInit(): Promise {
+ super.ngOnInit();
+
+ await this.loadContent();
+
+ if (!this.chat) {
+ return;
+ }
+
+ try {
+ await AddonModChat.logView(this.chat.id, this.chat.name);
+
+ CoreCourse.checkModuleCompletion(this.courseId, this.module.completiondata);
+ } catch {
+ // Ignore errors.
+ }
+ }
+
+ /**
+ * @inheritdoc
+ */
+ protected async fetchContent(refresh: boolean = false): Promise {
+ try {
+ this.chat = await AddonModChat.getChat(this.courseId, this.module.id);
+
+ this.description = this.chat.intro;
+ const now = CoreTimeUtils.timestamp();
+ const span = (this.chat.chattime || 0) - now;
+
+ if (this.chat.chattime && this.chat.schedule && span > 0) {
+ this.chatInfo = {
+ date: CoreTimeUtils.userDate(this.chat.chattime * 1000),
+ fromnow: CoreTimeUtils.formatTime(span),
+ };
+ } else {
+ this.chatInfo = undefined;
+ }
+
+ this.dataRetrieved.emit(this.chat);
+
+ this.sessionsAvailable = await AddonModChat.areSessionsAvailable();
+ } finally {
+ this.fillContextMenu(refresh);
+ }
+ }
+
+ /**
+ * Enter the chat.
+ */
+ enterChat(): void {
+ const title = this.chat?.name || this.moduleName;
+
+ CoreNavigator.navigateToSitePath(
+ AddonModChatModuleHandlerService.PAGE_NAME + `/${this.courseId}/${this.module.id}/chat`,
+ {
+ params: {
+ title,
+ },
+ },
+ );
+ }
+
+ /**
+ * View past sessions.
+ */
+ viewSessions(): void {
+ CoreNavigator.navigateToSitePath(
+ AddonModChatModuleHandlerService.PAGE_NAME + `/${this.courseId}/${this.module.id}/sessions`,
+ {
+ params: {
+ chatId: this.chat!.id,
+ },
+ },
+ );
+ }
+
+}
diff --git a/src/addons/mod/chat/pages/index/index.html b/src/addons/mod/chat/pages/index/index.html
new file mode 100644
index 000000000..8f60e3997
--- /dev/null
+++ b/src/addons/mod/chat/pages/index/index.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/addons/mod/chat/pages/index/index.ts b/src/addons/mod/chat/pages/index/index.ts
new file mode 100644
index 000000000..9b87c5afa
--- /dev/null
+++ b/src/addons/mod/chat/pages/index/index.ts
@@ -0,0 +1,30 @@
+// (C) Copyright 2015 Moodle Pty Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import { Component, ViewChild } from '@angular/core';
+import { CoreCourseModuleMainActivityPage } from '@features/course/classes/main-activity-page';
+import { AddonModChatIndexComponent } from '../../components/index/index';
+
+/**
+ * Page that displays a chat.
+ */
+@Component({
+ selector: 'page-addon-mod-chat-index',
+ templateUrl: 'index.html',
+})
+export class AddonModChatIndexPage extends CoreCourseModuleMainActivityPage {
+
+ @ViewChild(AddonModChatIndexComponent) activityComponent?: AddonModChatIndexComponent;
+
+}