diff --git a/src/core/features/course/components/components.module.ts b/src/core/features/course/components/components.module.ts
index a8bbc04f1..f663770b5 100644
--- a/src/core/features/course/components/components.module.ts
+++ b/src/core/features/course/components/components.module.ts
@@ -29,6 +29,7 @@ import { CoreCourseModuleManualCompletionComponent } from './module-manual-compl
 import { CoreCourseModuleNavigationComponent } from './module-navigation/module-navigation';
 import { CoreCourseModuleSummaryComponent } from './module-summary/module-summary';
 import { CoreCourseCourseIndexTourComponent } from './course-index-tour/course-index-tour';
+import { CoreRemindersComponentsModule } from '@features/reminders/components/components.module';
 
 @NgModule({
     declarations: [
@@ -48,6 +49,7 @@ import { CoreCourseCourseIndexTourComponent } from './course-index-tour/course-i
     ],
     imports: [
         CoreBlockComponentsModule,
+        CoreRemindersComponentsModule,
         CoreSharedModule,
     ],
     exports: [
diff --git a/src/core/features/course/components/module-info/core-course-module-info.html b/src/core/features/course/components/module-info/core-course-module-info.html
index b338fc7d1..1e00b23b0 100644
--- a/src/core/features/course/components/module-info/core-course-module-info.html
+++ b/src/core/features/course/components/module-info/core-course-module-info.html
@@ -26,10 +26,9 @@
 
     <!-- Activity dates. -->
     <div *ngIf="module.dates && module.dates.length" class="core-module-dates core-module-info-box-section">
-        <p *ngFor="let date of module.dates">
-            <ion-icon name="fas-calendar" aria-hidden="true"></ion-icon><strong>{{ date.label }}</strong>
-            {{ date.readableTime }}
-        </p>
+        <core-reminders-date *ngFor="let date of module.dates" [component]="component" [instanceId]="module.id" [type]="date.dataid"
+            [label]="date.label" [time]="date.timestamp" [relativeTo]="date.relativeto" [title]="module.name" [url]="module.url">
+        </core-reminders-date>
     </div>
 
     <!-- Availability info space. -->
diff --git a/src/core/features/course/components/module-info/course-module-info.scss b/src/core/features/course/components/module-info/course-module-info.scss
index bf6e0d5ce..533696aae 100644
--- a/src/core/features/course/components/module-info/course-module-info.scss
+++ b/src/core/features/course/components/module-info/course-module-info.scss
@@ -48,12 +48,6 @@
             padding-top: 8px;
         }
 
-        .core-module-dates ion-icon {
-            margin-left: 4px;
-            margin-right: 4px;
-        }
-
-        .core-module-dates,
         .core-module-availabilityinfo {
             font-size: 90%;
             ion-icon {
@@ -94,8 +88,6 @@
             white-space: normal !important;
         }
     }
-
-
 }
 
 :host-context(.core-iframe-fullscreen) {
diff --git a/src/core/features/course/components/module/core-course-module.html b/src/core/features/course/components/module/core-course-module.html
index 8a099383d..5206b6397 100644
--- a/src/core/features/course/components/module/core-course-module.html
+++ b/src/core/features/course/components/module/core-course-module.html
@@ -81,10 +81,9 @@
                     *ngIf="(showActivityDates && module.dates && module.dates.length) || module.availabilityinfo">
                     <!-- Activity dates. -->
                     <div *ngIf="showActivityDates && module.dates && module.dates.length" class="core-module-dates">
-                        <p *ngFor="let date of module.dates">
-                            <ion-icon name="fas-calendar" aria-hidden="true"></ion-icon><strong>{{ date.label }}</strong>
-                            {{ date.readableTime }}
-                        </p>
+                        <core-reminders-date *ngFor="let date of module.dates" [type]="date.id" [label]="date.label" [time]="date.timestamp"
+                            [relativeTo]="date.relativeto">
+                        </core-reminders-date>
                     </div>
 
                     <!-- Availability info -->
diff --git a/src/core/features/course/pages/course-summary/course-summary.html b/src/core/features/course/pages/course-summary/course-summary.html
index 0336344b6..56e89e0fa 100644
--- a/src/core/features/course/pages/course-summary/course-summary.html
+++ b/src/core/features/course/pages/course-summary/course-summary.html
@@ -57,16 +57,14 @@
                             </core-progress-bar>
                         </div>
                         <div *ngIf="course.startdate || course.enddate" class="core-course-dates">
-                            <p *ngIf="course.startdate">
-                                <ion-icon name="fas-calendar" aria-hidden="true"></ion-icon>
-                                <strong>{{ 'core.course.startdate' | translate }}</strong><br>
-                                {{ course.startdate * 1000 | coreFormatDate:'strftimedaydatetime' }}
-                            </p>
-                            <p *ngIf="course.enddate">
-                                <ion-icon name="fas-calendar" aria-hidden="true"></ion-icon>
-                                <strong>{{ 'core.course.enddate' | translate }}</strong><br>
-                                {{ course.enddate * 1000 | coreFormatDate:'strftimedaydatetime' }}
-                            </p>
+                            <core-reminders-date *ngIf="course.startdate" component="course" [instanceId]="course.id" type="coursestart"
+                                [label]="'core.course.startdate' | translate" [time]="course.startdate" [title]="course.fullname"
+                                [url]="courseUrl">
+                            </core-reminders-date>
+                            <core-reminders-date *ngIf="course.enddate" component="course" [instanceId]="course.id" type="courseend"
+                                [label]="'core.course.enddate' | translate" [time]="course.enddate" [title]="course.fullname"
+                                [url]="courseUrl">
+                            </core-reminders-date>
                         </div>
                     </ion-label>
                 </ion-item>
diff --git a/src/core/features/course/pages/course-summary/course-summary.module.ts b/src/core/features/course/pages/course-summary/course-summary.module.ts
index daeb7f70c..c925524f7 100644
--- a/src/core/features/course/pages/course-summary/course-summary.module.ts
+++ b/src/core/features/course/pages/course-summary/course-summary.module.ts
@@ -17,6 +17,7 @@ import { RouterModule, Routes } from '@angular/router';
 
 import { CoreSharedModule } from '@/core/shared.module';
 import { CoreCourseSummaryPage } from './course-summary';
+import { CoreRemindersComponentsModule } from '@features/reminders/components/components.module';
 
 const routes: Routes = [
     {
@@ -27,6 +28,7 @@ const routes: Routes = [
 @NgModule({
     imports: [
         CoreSharedModule,
+        CoreRemindersComponentsModule,
     ],
     declarations: [
         CoreCourseSummaryPage,
@@ -39,6 +41,7 @@ export class CoreCoursePreviewPageComponentModule { }
         RouterModule.forChild(routes),
         CoreSharedModule,
         CoreCoursePreviewPageComponentModule,
+        CoreRemindersComponentsModule,
     ],
     exports: [RouterModule],
 })
diff --git a/src/core/features/course/services/course-helper.ts b/src/core/features/course/services/course-helper.ts
index 58ae2f26d..65d242603 100644
--- a/src/core/features/course/services/course-helper.ts
+++ b/src/core/features/course/services/course-helper.ts
@@ -27,7 +27,6 @@ import {
     CoreCourseModuleCompletionTracking,
     CoreCourseModuleCompletionStatus,
     CoreCourseGetContentsWSModule,
-    CoreCourseGetContentsWSModuleDate,
 } from './course';
 import { CoreConstants } from '@/core/constants';
 import { CoreLogger } from '@singletons/logger';
@@ -1189,7 +1188,7 @@ export class CoreCourseHelperProvider {
      * This should be used in 3.6 sites or higher, where the course contents already include the completion.
      *
      * @param courseId The course to get the completion.
-     * @param mmodule The module.
+     * @param module The module.
      * @param siteId Site ID. If not defined, current site.
      * @return Promise resolved when done.
      */
@@ -2086,20 +2085,12 @@ export type CoreCourseSectionWithStatus = CoreCourseSection & {
 /**
  * Module with calculated data.
  */
-export type CoreCourseModuleData = Omit<CoreCourseGetContentsWSModule, 'completiondata'|'dates'> & {
+export type CoreCourseModuleData = Omit<CoreCourseGetContentsWSModule, 'completiondata'> & {
     course: number; // The course id.
     isStealth?: boolean;
     handlerData?: CoreCourseModuleHandlerData;
     completiondata?: CoreCourseModuleCompletionData;
     section: number;
-    dates?: CoreCourseModuleDate[];
-};
-
-/**
- * Module date with calculated data.
- */
-export type CoreCourseModuleDate = CoreCourseGetContentsWSModuleDate & {
-    readableTime: string;
 };
 
 /**
diff --git a/src/core/features/course/services/course.ts b/src/core/features/course/services/course.ts
index 16a680440..70b2ca22b 100644
--- a/src/core/features/course/services/course.ts
+++ b/src/core/features/course/services/course.ts
@@ -38,7 +38,7 @@ import {
 import { CoreDomUtils } from '@services/utils/dom';
 import { CoreWSError } from '@classes/errors/wserror';
 import { CorePushNotifications } from '@features/pushnotifications/services/pushnotifications';
-import { CoreCourseHelper, CoreCourseModuleData, CoreCourseModuleCompletionData, CoreCourseModuleDate } from './course-helper';
+import { CoreCourseHelper, CoreCourseModuleData, CoreCourseModuleCompletionData } from './course-helper';
 import { CoreCourseFormatDelegate } from './format-delegate';
 import { CoreCronDelegate } from '@services/cron';
 import { CoreCourseLogCronHandler } from './handlers/log-cron';
@@ -53,7 +53,6 @@ import { CoreDatabaseTable } from '@classes/database/database-table';
 import { CoreDatabaseCachingStrategy } from '@classes/database/database-table-proxy';
 import { SQLiteDB } from '@classes/sqlitedb';
 import { CorePlatform } from '@services/platform';
-import { CoreTime } from '@singletons/time';
 import { asyncObservable, firstValueFrom } from '@/core/utils/rxjs';
 import { map } from 'rxjs/operators';
 
@@ -678,39 +677,11 @@ export class CoreCourseProvider {
             };
         }
 
-        let formattedDates: CoreCourseModuleDate[] | undefined;
-
-        if (module.dates) {
-            formattedDates = module.dates.map(date => {
-                let readableTime = '';
-                if (!date.relativeto) {
-                    readableTime = CoreTimeUtils.userDate(date.timestamp * 1000, 'core.strftimedatetime', true);
-                } else {
-                    readableTime = Translate.instant(
-                        'core.course.relativedatessubmissionduedate' + (date.timestamp > date.relativeto ? 'after' : 'before'),
-                        {
-                            $a: {
-                                datediffstr: date.relativeto === date.timestamp ?
-                                    '0 ' + Translate.instant('core.secs') :
-                                    CoreTime.formatTime(date.relativeto - date.timestamp, 3),
-                            },
-                        },
-                    );
-                }
-
-                return {
-                    ...date,
-                    readableTime,
-                };
-            });
-        }
-
         return  {
             ...module,
             course: courseId,
             section: sectionId,
             completiondata: completionData,
-            dates: formattedDates,
         };
     }
 
@@ -1775,7 +1746,10 @@ export type CoreCourseGetContentsWSModule = {
     completiondata?: CoreCourseModuleWSCompletionData; // Module completion data.
     contents?: CoreCourseModuleContentFile[];
     downloadcontent?: number; // @since 4.0 The download content value.
-    dates?: CoreCourseGetContentsWSModuleDate[]; // @since 3.11. Activity dates.
+    dates?: {
+        label: string;
+        timestamp: number;
+    }[]; // @since 3.11. Activity dates.
     contentsinfo?: { // @since v3.7.6 Contents summary information.
         filescount: number; // Total number of files.
         filessize: number; // Total files size.
@@ -1785,16 +1759,6 @@ export type CoreCourseGetContentsWSModule = {
     };
 };
 
-/**
- * Activity date.
- */
-export type CoreCourseGetContentsWSModuleDate = {
-    label: string;
-    timestamp: number;
-    relativeto?: number; // @since 4.1. Relative date timestamp.
-    dataid?: string; // @since 4.1. ID to identify the text.
-};
-
 /**
  * Data returned by core_course_get_contents WS.
  */
diff --git a/src/core/features/reminders/components/components.module.ts b/src/core/features/reminders/components/components.module.ts
index a16051728..c99c2b06a 100644
--- a/src/core/features/reminders/components/components.module.ts
+++ b/src/core/features/reminders/components/components.module.ts
@@ -14,20 +14,26 @@
 
 import { CoreSharedModule } from '@/core/shared.module';
 import { NgModule } from '@angular/core';
+import { CoreRemindersDateComponent } from './date/date';
+import { CoreRemindersSetButtonComponent } from './set-button/set-button';
 import { CoreRemindersSetReminderCustomComponent } from './set-reminder-custom/set-reminder-custom';
 import { CoreRemindersSetReminderMenuComponent } from './set-reminder-menu/set-reminder-menu';
 
 @NgModule({
     declarations: [
-        CoreRemindersSetReminderMenuComponent,
+        CoreRemindersDateComponent,
+        CoreRemindersSetButtonComponent,
         CoreRemindersSetReminderCustomComponent,
+        CoreRemindersSetReminderMenuComponent,
     ],
     imports: [
         CoreSharedModule,
     ],
     exports: [
-        CoreRemindersSetReminderMenuComponent,
+        CoreRemindersDateComponent,
+        CoreRemindersSetButtonComponent,
         CoreRemindersSetReminderCustomComponent,
+        CoreRemindersSetReminderMenuComponent,
     ],
 })
 export class CoreRemindersComponentsModule {}
diff --git a/src/core/features/reminders/components/date/date.html b/src/core/features/reminders/components/date/date.html
new file mode 100644
index 000000000..4f75b5422
--- /dev/null
+++ b/src/core/features/reminders/components/date/date.html
@@ -0,0 +1,8 @@
+<div>
+    <ion-icon name="fas-calendar" aria-hidden="true"></ion-icon>
+    <strong>{{ label }}</strong> {{ readableTime }}
+</div>
+
+<core-reminders-set-button *ngIf="showReminderButton" slot="end" [component]="component" [instanceId]="instanceId" [type]="type"
+    [label]="label" [timebefore]="timebefore" [time]="time" [title]="title" [url]="url">
+</core-reminders-set-button>
diff --git a/src/core/features/reminders/components/date/date.scss b/src/core/features/reminders/components/date/date.scss
new file mode 100644
index 000000000..e898db6da
--- /dev/null
+++ b/src/core/features/reminders/components/date/date.scss
@@ -0,0 +1,21 @@
+@import "~theme/globals";
+
+:host {
+    display: flex;
+    flex-direction: row;
+}
+
+div {
+    flex-grow: 1;
+    font-size: 14px;
+    margin: 0;
+    align-self: center;
+
+    ion-icon {
+        @include margin-horizontal(0px, 4px);
+    }
+}
+
+core-reminders-date + :host  {
+    margin-top: 12px;
+}
diff --git a/src/core/features/reminders/components/date/date.ts b/src/core/features/reminders/components/date/date.ts
new file mode 100644
index 000000000..137d88d4b
--- /dev/null
+++ b/src/core/features/reminders/components/date/date.ts
@@ -0,0 +1,95 @@
+// (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 { CoreReminders } from '@features/reminders/services/reminders';
+import { Component, Input, OnInit } from '@angular/core';
+import { CoreTimeUtils } from '@services/utils/time';
+import { Translate } from '@singletons';
+import { CoreTime } from '@singletons/time';
+
+/**
+ * Component that displays a date to remind.
+ */
+@Component({
+    selector: 'core-reminders-date',
+    templateUrl: 'date.html',
+    styleUrls: ['date.scss'],
+})
+export class CoreRemindersDateComponent implements OnInit {
+
+    @Input() component?: string;
+    @Input() instanceId?: number;
+    @Input() type?: string;
+    @Input() label = '';
+    @Input() time = 0;
+    @Input() relativeTo = 0;
+    @Input() title = '';
+    @Input() url = '';
+
+    showReminderButton = false;
+    timebefore?: number; // Undefined means no reminder has been set.
+    readableTime = '';
+
+    /**
+     * @inheritdoc
+     */
+    async ngOnInit(): Promise<void> {
+        this.readableTime = this.getReadableTime(this.time, this.relativeTo);
+
+        // If not set, button won't be shown.
+        if (this.component === undefined || this.instanceId === undefined || this.type === undefined) {
+            return;
+        }
+
+        const remindersEnabled = CoreReminders.isEnabled();
+        this.showReminderButton = remindersEnabled && this.time > CoreTimeUtils.timestamp();
+
+        if (!this.showReminderButton) {
+            return;
+        }
+
+        const reminders = await CoreReminders.getReminders({
+            instanceId: this.instanceId,
+            component: this.component,
+            type: this.type,
+        });
+
+        this.timebefore = reminders[0]?.timebefore;
+    }
+
+    /**
+     * Returns the readable time.
+     *
+     * @param timestamp Timestamp.
+     * @param relativeTo Base timestamp if timestamp is relative to this one.
+     * @return Readable time string.
+     */
+    protected getReadableTime(timestamp: number, relativeTo = 0): string {
+        if (!relativeTo) {
+            return CoreTimeUtils.userDate(timestamp * 1000, 'core.strftimedatetime', true);
+        }
+
+        return Translate.instant(
+            'core.course.relativedatessubmissionduedate' + (timestamp > relativeTo ? 'after' : 'before'),
+            {
+                $a: {
+                    datediffstr: relativeTo === timestamp ?
+                        '0 ' + Translate.instant('core.secs') :
+                        CoreTime.formatTime(relativeTo - timestamp, 3),
+                },
+            },
+        );
+    }
+
+}
diff --git a/src/core/features/reminders/components/set-button/set-button.html b/src/core/features/reminders/components/set-button/set-button.html
new file mode 100644
index 000000000..fcc693d20
--- /dev/null
+++ b/src/core/features/reminders/components/set-button/set-button.html
@@ -0,0 +1,4 @@
+<ion-button fill="clear" size="small" (click)="setReminder($event)">
+    <ion-icon name="fas-bell" slot="icon-only" *ngIf="timebefore !== undefined"></ion-icon>
+    <ion-icon name="far-bell-slash" slot="icon-only" *ngIf="timebefore === undefined"></ion-icon>
+</ion-button>
diff --git a/src/core/features/reminders/components/set-button/set-button.ts b/src/core/features/reminders/components/set-button/set-button.ts
new file mode 100644
index 000000000..d9fa8f439
--- /dev/null
+++ b/src/core/features/reminders/components/set-button/set-button.ts
@@ -0,0 +1,116 @@
+// (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 { CoreReminderData, CoreReminders, CoreRemindersService } from '@features/reminders/services/reminders';
+import { Component, Input } from '@angular/core';
+import { CoreDomUtils } from '@services/utils/dom';
+import { CoreRemindersSetReminderMenuComponent } from '../set-reminder-menu/set-reminder-menu';
+
+/**
+ * Component that displays a button to set a reminder.
+ */
+@Component({
+    selector: 'core-reminders-set-button',
+    templateUrl: 'set-button.html',
+})
+export class CoreRemindersSetButtonComponent {
+
+    @Input() component?: string;
+    @Input() instanceId?: number;
+    @Input() type?: string;
+    @Input() label = '';
+    @Input() timebefore?: number;
+    @Input() time = -1;
+    @Input() title = '';
+    @Input() url = '';
+
+    /**
+     * Set reminder.
+     *
+     * @param ev Click event.
+     */
+    async setReminder(ev: Event): Promise<void> {
+        if (this.component === undefined || this.instanceId === undefined || this.type === undefined) {
+            return;
+        }
+
+        ev.preventDefault();
+        ev.stopPropagation();
+
+        if (this.timebefore === undefined) {
+            // Set it to the time of the event.
+            this.saveReminder(0);
+
+            return;
+        }
+
+        // Open popover.
+        const reminderTime = await CoreDomUtils.openPopover<{timeBefore: number}>({
+            component: CoreRemindersSetReminderMenuComponent,
+            componentProps: {
+                initialValue: this.timebefore,
+                noReminderLabel: 'core.reminders.delete',
+            },
+            event: ev,
+        });
+
+        if (reminderTime === undefined) {
+            // User canceled.
+            return;
+        }
+
+        // Save before.
+        this.saveReminder(reminderTime.timeBefore);
+    }
+
+    /**
+     * Save reminder.
+     *
+     * @param timebefore Time before the event to fire the notification.
+     * @return Promise resolved when done.
+     */
+    protected async saveReminder(timebefore: number): Promise<void> {
+        if (this.component === undefined || this.instanceId === undefined || this.type === undefined) {
+            return;
+        }
+
+        if (timebefore === CoreRemindersService.DISABLED) {
+            // Remove the reminder.
+            await CoreReminders.removeReminders({
+                instanceId: this.instanceId,
+                component: this.component,
+                type: this.type,
+            });
+            this.timebefore = undefined;
+
+            return;
+        }
+
+        this.timebefore = timebefore;
+
+        const reminder: CoreReminderData = {
+            component: this.component,
+            instanceId: this.instanceId,
+            timebefore: this.timebefore,
+            type: this.type,
+            title: this.label + ' ' + this.title,
+            url: this.url,
+            time: this.time,
+        };
+
+        // Save before.
+        await CoreReminders.addReminder(reminder);
+    }
+
+}