diff --git a/app/Database/Migrations/2020-06-05-170000_add_episodes.php b/app/Database/Migrations/2020-06-05-170000_add_episodes.php
index 522400a867ec81f29ca221925dab7035e92b3c39..5804c4603468b94a074c8c7f6e875682af964958 100644
--- a/app/Database/Migrations/2020-06-05-170000_add_episodes.php
+++ b/app/Database/Migrations/2020-06-05-170000_add_episodes.php
@@ -147,10 +147,6 @@ class AddEpisodes extends Migration
             'updated_at' => [
                 'type' => 'DATETIME',
             ],
-            'deleted_at' => [
-                'type' => 'DATETIME',
-                'null' => true,
-            ],
         ]);
         $this->forge->addPrimaryKey('id');
         $this->forge->addUniqueKey(['podcast_id', 'slug']);
diff --git a/app/Database/Seeds/AuthSeeder.php b/app/Database/Seeds/AuthSeeder.php
index dff5c8eb87821b4c3c2dad133d8b9edf726bb5db..889ab902e8843b8908b4c31224a0865d32e3581e 100644
--- a/app/Database/Seeds/AuthSeeder.php
+++ b/app/Database/Seeds/AuthSeeder.php
@@ -207,12 +207,6 @@ class AuthSeeder extends Seeder
             ],
             [
                 'name' => 'delete',
-                'description' =>
-                    'Delete an episode of a podcast without removing it from the database',
-                'has_permission' => ['podcast_admin'],
-            ],
-            [
-                'name' => 'delete_permanently',
                 'description' =>
                     'Delete all occurrences of an episode of a podcast from the database',
                 'has_permission' => ['podcast_admin'],
diff --git a/app/Entities/Episode.php b/app/Entities/Episode.php
index c706585c0b625a45edc9775c317b48b552f82b26..32223685175dba4c16bdfd167ebebd7495508659 100644
--- a/app/Entities/Episode.php
+++ b/app/Entities/Episode.php
@@ -78,7 +78,6 @@ use RuntimeException;
  * @property Time|null $published_at;
  * @property Time $created_at;
  * @property Time $updated_at;
- * @property Time|null $deleted_at;
  *
  * @property Person[] $persons;
  * @property Soundbite[] $soundbites;
diff --git a/app/Entities/Media/BaseMedia.php b/app/Entities/Media/BaseMedia.php
index a45ede67af978e73c62a211013086556729bc084..2acf221d9fb9dc8ee14e770e8bf78138f046bd42 100644
--- a/app/Entities/Media/BaseMedia.php
+++ b/app/Entities/Media/BaseMedia.php
@@ -10,6 +10,8 @@ declare(strict_types=1);
 
 namespace App\Entities\Media;
 
+use App\Models\MediaModel;
+use CodeIgniter\Database\BaseResult;
 use CodeIgniter\Entity\Entity;
 use CodeIgniter\Files\File;
 
@@ -101,9 +103,15 @@ class BaseMedia extends Entity
         return $this;
     }
 
-    public function deleteFile(): void
+    public function deleteFile(): bool
     {
         helper('media');
-        unlink(media_path($this->file_path));
+        return unlink(media_path($this->file_path));
+    }
+
+    public function delete(): bool|BaseResult
+    {
+        $mediaModel = new MediaModel();
+        return $mediaModel->delete($this->id, true);
     }
 }
diff --git a/app/Entities/Media/Image.php b/app/Entities/Media/Image.php
index e57426c091d531fdfcceee06c15631c99cc9d81d..c1524806113e9942c12e3228cb0d2202006f2b34 100644
--- a/app/Entities/Media/Image.php
+++ b/app/Entities/Media/Image.php
@@ -69,11 +69,13 @@ class Image extends BaseMedia
         return $this;
     }
 
-    public function deleteFile(): void
+    public function deleteFile(): bool
     {
-        parent::deleteFile();
+        if (parent::deleteFile()) {
+            return $this->deleteSizes();
+        }
 
-        $this->deleteSizes();
+        return false;
     }
 
     public function saveSizes(): void
@@ -89,12 +91,16 @@ class Image extends BaseMedia
         }
     }
 
-    private function deleteSizes(): void
+    private function deleteSizes(): bool
     {
         // delete all derived sizes
         foreach (array_keys($this->sizes) as $name) {
             $pathProperty = $name . '_path';
-            unlink(media_path($this->{$pathProperty}));
+            if (! unlink(media_path($this->{$pathProperty}))) {
+                return false;
+            }
         }
+
+        return true;
     }
 }
diff --git a/app/Entities/Media/Transcript.php b/app/Entities/Media/Transcript.php
index a0dbebdf303fb69118e1f541368e75626fb0ec1d..988e24889710f4a2e765e82034ec492ed2a43c88 100644
--- a/app/Entities/Media/Transcript.php
+++ b/app/Entities/Media/Transcript.php
@@ -63,12 +63,16 @@ class Transcript extends BaseMedia
         return $this;
     }
 
-    public function deleteFile(): void
+    public function deleteFile(): bool
     {
-        parent::deleteFile();
+        if (! parent::deleteFile()) {
+            return false;
+        }
 
         if ($this->json_path) {
-            unlink($this->json_path);
+            return unlink($this->json_path);
         }
+
+        return true;
     }
 }
diff --git a/app/Entities/Podcast.php b/app/Entities/Podcast.php
index a54b7f62927f0f78abca4d0d42eaaa078444a825..b943ce8b4a2dd7e5ae1add7ba71b03764a328853 100644
--- a/app/Entities/Podcast.php
+++ b/app/Entities/Podcast.php
@@ -327,6 +327,18 @@ class Podcast extends Entity
         return $this->episodes;
     }
 
+    /**
+     * Returns the podcast's episodes count
+     */
+    public function getEpisodesCount(): int|string
+    {
+        if ($this->id === null) {
+            throw new RuntimeException('Podcast must be created before getting number of episodes.');
+        }
+
+        return (new EpisodeModel())->getPodcastEpisodesCount($this->id);
+    }
+
     /**
      * Returns the podcast's persons
      *
diff --git a/app/Models/EpisodeModel.php b/app/Models/EpisodeModel.php
index 573b6e7694e9056587a6de00e2463a2ae580e77c..3b20c07ba9baffa5e2e3eb412c007fc0851905ba 100644
--- a/app/Models/EpisodeModel.php
+++ b/app/Models/EpisodeModel.php
@@ -94,11 +94,6 @@ class EpisodeModel extends Model
      */
     protected $returnType = Episode::class;
 
-    /**
-     * @var bool
-     */
-    protected $useSoftDeletes = true;
-
     /**
      * @var bool
      */
@@ -249,6 +244,18 @@ class EpisodeModel extends Model
         return $found;
     }
 
+    /**
+     * Returns number of episodes of a podcast
+     */
+    public function getPodcastEpisodesCount(int $podcastId): int|string
+    {
+        return $this
+            ->where([
+                'podcast_id' => $podcastId,
+            ])
+            ->countAllResults();
+    }
+
     /**
      * Returns the timestamp difference in seconds between the next episode to publish and the current timestamp Returns
      * false if there's no episode to publish
diff --git a/app/Views/Components/Button.php b/app/Views/Components/Button.php
index 79c96ac5fdc7931b4f1bf08d7ad409f21dcc9a2b..2c2429b3f0bdb49772fe7c455214ca11718e1276 100644
--- a/app/Views/Components/Button.php
+++ b/app/Views/Components/Button.php
@@ -38,6 +38,7 @@ class Button extends Component
             'danger' => 'text-white bg-red-600 hover:bg-red-700',
             'warning' => 'text-black bg-yellow-500 hover:bg-yellow-600',
             'info' => 'text-white bg-blue-500 hover:bg-blue-600',
+            'disabled' => 'text-black bg-gray-300 cursor-not-allowed',
         ];
 
         $sizeClass = [
diff --git a/modules/Admin/Controllers/EpisodeController.php b/modules/Admin/Controllers/EpisodeController.php
index 6b1373cf17b3cf7b0fdef304fa944a5e05ad06f9..9521c8381d1da42cd41b61ff79ae5e2123a88b82 100644
--- a/modules/Admin/Controllers/EpisodeController.php
+++ b/modules/Admin/Controllers/EpisodeController.php
@@ -131,6 +131,18 @@ class EpisodeController extends BaseController
                 ->with('errors', $this->validator->getErrors());
         }
 
+        if ((new EpisodeModel())
+            ->where([
+                'slug' => $this->request->getPost('slug'),
+                'podcast_id' => $this->podcast->id,
+            ])
+            ->first()) {
+            return redirect()
+                ->back()
+                ->withInput()
+                ->with('error', lang('Episode.messages.sameSlugError'));
+        }
+
         $db = db_connect();
         $db->transStart();
 
@@ -681,6 +693,11 @@ class EpisodeController extends BaseController
                 ->with('errors', $episodeModel->errors());
         }
 
+        // set podcast is_published_on_hubs to false to trigger websub push
+        (new PodcastModel())->update($this->episode->podcast->id, [
+            'is_published_on_hubs' => false,
+        ]);
+
         $db->transComplete();
 
         return redirect()->route('episode-view', [$this->podcast->id, $this->episode->id]);
@@ -715,43 +732,74 @@ class EpisodeController extends BaseController
                 ->with('errors', $this->validator->getErrors());
         }
 
+        if ($this->episode->published_at !== null) {
+            return redirect()
+                ->back()
+                ->withInput()
+                ->with('error', lang('Episode.messages.deletePublishedEpisodeError'));
+        }
+
+        $audio = $this->episode->audio;
+
         $db = db_connect();
 
         $db->transStart();
 
-        $allPostsLinkedToEpisode = (new PostModel())
-            ->where([
-                'episode_id' => $this->episode->id,
-            ])
-            ->findAll();
-        foreach ($allPostsLinkedToEpisode as $post) {
-            (new PostModel())->removePost($post);
+        $episodeModel = new EpisodeModel();
+
+        if (! $episodeModel->delete($this->episode->id)) {
+            $db->transRollback();
+            return redirect()
+                ->back()
+                ->withInput()
+                ->with('errors', $episodeModel->errors());
         }
 
-        // set podcast is_published_on_hubs to false to trigger websub push
-        (new PodcastModel())->update($this->episode->podcast->id, [
-            'is_published_on_hubs' => false,
-        ]);
+        $episodeMediaList = [$this->episode->transcript, $this->episode->chapters, $audio];
 
-        $episodeModel = new EpisodeModel();
-        if ($this->episode->published_at !== null) {
-            // if episode is published, set episode published_at to null to unpublish before deletion
-            $this->episode->published_at = null;
+        //only delete episode cover if different from podcast's
+        if ($this->episode->cover_id !== null) {
+            $episodeMediaList[] = $this->episode->cover;
+        }
 
-            if (! $episodeModel->update($this->episode->id, $this->episode)) {
+        //delete episode media records from database
+        foreach ($episodeMediaList as $episodeMedia) {
+            if ($episodeMedia !== null && ! $episodeMedia->delete()) {
                 $db->transRollback();
                 return redirect()
                     ->back()
                     ->withInput()
-                    ->with('errors', $episodeModel->errors());
+                    ->with('error', lang('Episode.messages.deleteError', [
+                        'type' => $episodeMedia->type,
+                    ]));
             }
         }
 
-        $episodeModel->delete($this->episode->id);
+        $warnings = [];
+
+        //remove episode media files from disk
+        foreach ($episodeMediaList as $episodeMedia) {
+            if ($episodeMedia !== null && ! $episodeMedia->deleteFile()) {
+                $warnings[] = lang('Episode.messages.deleteFileError', [
+                    'type' => $episodeMedia->type,
+                    'file_path' => $episodeMedia->file_path,
+                ]);
+            }
+        }
 
         $db->transComplete();
 
-        return redirect()->route('episode-list', [$this->podcast->id]);
+        if ($warnings !== []) {
+            return redirect()
+                ->route('episode-list', [$this->podcast->id])
+                ->with('message', lang('Episode.messages.deleteSuccess'))
+                ->with('warnings', $warnings);
+        }
+
+        return redirect()->route('episode-list', [$this->podcast->id])->with(
+            'message',
+            lang('Episode.messages.deleteSuccess')
+        );
     }
 
     public function embed(): string
diff --git a/modules/Admin/Language/en/Episode.php b/modules/Admin/Language/en/Episode.php
index 82ed40dc7546dc79a09da219c1c3ed6c2fb37125..718bca1f933b651f4e5c467cc5e7952f639be5a1 100644
--- a/modules/Admin/Language/en/Episode.php
+++ b/modules/Admin/Language/en/Episode.php
@@ -47,6 +47,24 @@ return [
         'createSuccess' => 'Episode has been successfully created!',
         'editSuccess' => 'Episode has been successfully updated!',
         'publishCancelSuccess' => 'Episode publication successfully cancelled!',
+        'unpublishBeforeDeleteTip' => 'You must unpublish the episode before deleting it.',
+        'deletePublishedEpisodeError' => 'Please unpublish the episode before deleting it.',
+        'deleteSuccess' => 'Episode successfully deleted!',
+        'deleteError' => 'Failed to delete episode {type, select,
+            transcript {transcript}
+            chapters {chapters}
+            image {cover}
+            audio {audio}
+            other {media}
+        }.',
+        'deleteFileError' => 'Failed to delete {type, select,
+            transcript {transcript}
+            chapters {chapters}
+            image {cover}
+            audio {audio}
+            other {media}
+        } file {file_path}. You must manually remove it from your disk.',
+        'sameSlugError' => 'An episode with the chosen slug already exists.',
     ],
     'form' => [
         'file_size_error' =>
@@ -147,7 +165,7 @@ return [
     ],
     'delete_form' => [
         'disclaimer' =>
-            "Deleting the episode will delete all the posts associated with it and remove it from the podcast's RSS feed.",
+            "Deleting the episode will delete all media files, comments, video clips and soundbites associated with it.",
         'understand' => 'I understand, I want to delete the episode',
         'submit' => 'Delete',
     ],
diff --git a/modules/Admin/Language/fr/Episode.php b/modules/Admin/Language/fr/Episode.php
index ee1ba07ad8137c4606f67b8dd57868593660537a..4b8d039fd91a263f35f77042cef234ae0e47d33a 100644
--- a/modules/Admin/Language/fr/Episode.php
+++ b/modules/Admin/Language/fr/Episode.php
@@ -147,7 +147,7 @@ return [
     ],
     'delete_form' => [
         'disclaimer' =>
-            "Supprimer l’épisode supprimera toutes les publications qui lui sont associées et le retirera du flux RSS du podcast.",
+            "Supprimer l’épisode supprimera tous les fichiers multimédia, commentaires, extraits vidéos et extraits sonores qui lui sont associés.",
         'understand' => 'Je comprends, je veux supprimer l’épisode',
         'submit' => 'Supprimer',
     ],
diff --git a/modules/Auth/Database/Seeds/AuthSeeder.php b/modules/Auth/Database/Seeds/AuthSeeder.php
index 87e2bfcdae702c4ea3a73093b667cd790ea80a61..cb4c819aa15b19c56b9cd66e9357d43f64af0ccf 100644
--- a/modules/Auth/Database/Seeds/AuthSeeder.php
+++ b/modules/Auth/Database/Seeds/AuthSeeder.php
@@ -195,12 +195,6 @@ class AuthSeeder extends Seeder
             ],
             [
                 'name' => 'delete',
-                'description' =>
-                    'Delete an episode of a podcast without removing it from the database',
-                'has_permission' => ['podcast_admin'],
-            ],
-            [
-                'name' => 'delete_permanently',
                 'description' =>
                     'Delete all occurrences of an episode of a podcast from the database',
                 'has_permission' => ['podcast_admin'],
diff --git a/modules/WebSub/Database/Migrations/2022-03-07-180000_add_is_published_on_hubs_to_podcasts.php b/modules/WebSub/Database/Migrations/2022-03-07-180000_add_is_published_on_hubs_to_podcasts.php
index 523ffdfdfd445852d7724f9949eee41688240d03..fb3d68ca7fa7efd9ab871c0b742276f43b9be4ee 100644
--- a/modules/WebSub/Database/Migrations/2022-03-07-180000_add_is_published_on_hubs_to_podcasts.php
+++ b/modules/WebSub/Database/Migrations/2022-03-07-180000_add_is_published_on_hubs_to_podcasts.php
@@ -28,8 +28,6 @@ class AddIsPublishedOnHubsToPodcasts extends Migration
 
     public function down(): void
     {
-        $prefix = $this->db->getPrefix();
-
-        $this->forge->dropColumn($prefix . 'podcasts', 'is_published_on_hubs');
+        $this->forge->dropColumn('podcasts', 'is_published_on_hubs');
     }
 }
diff --git a/modules/WebSub/Database/Migrations/2022-03-07-181500_add_is_published_on_hubs_to_episodes.php b/modules/WebSub/Database/Migrations/2022-03-07-181500_add_is_published_on_hubs_to_episodes.php
index 3bb719661ddfd77ac6858f7ae36d35b85f0f3818..dfe92a08bedd20958582dc75291a5d3c02d21906 100644
--- a/modules/WebSub/Database/Migrations/2022-03-07-181500_add_is_published_on_hubs_to_episodes.php
+++ b/modules/WebSub/Database/Migrations/2022-03-07-181500_add_is_published_on_hubs_to_episodes.php
@@ -28,8 +28,6 @@ class AddIsPublishedOnHubsToEpisodes extends Migration
 
     public function down(): void
     {
-        $prefix = $this->db->getPrefix();
-
-        $this->forge->dropColumn($prefix . 'episodes', 'is_published_on_hubs');
+        $this->forge->dropColumn('episodes', 'is_published_on_hubs');
     }
 }
diff --git a/themes/cp_admin/_message_block.php b/themes/cp_admin/_message_block.php
index 1504aa372c71b16280bc6967d34588142527f3e4..8e3ee6df5c3c6316b3e7ae86044c620b94f60bf7 100644
--- a/themes/cp_admin/_message_block.php
+++ b/themes/cp_admin/_message_block.php
@@ -17,3 +17,13 @@ if (session()->has('message')): ?>
         </ul>
     </Alert>
 <?php endif; ?>
+
+<?php if (session()->has('warnings')): ?>
+    <Alert variant="warning" class="mb-4">
+        <ul>
+            <?php foreach (session('warnings') as $warning): ?>
+                <li><?= esc($warning) ?></li>
+            <?php endforeach; ?>
+        </ul>
+    </Alert>
+<?php endif; ?>
diff --git a/themes/cp_admin/episode/_card.php b/themes/cp_admin/episode/_card.php
index 543d45e0f28568252df419c8e5f41ac79f84c030..0d675fe901902a54f2333d70a1f4b09194d28389 100644
--- a/themes/cp_admin/episode/_card.php
+++ b/themes/cp_admin/episode/_card.php
@@ -11,7 +11,7 @@
         </div>
     </a>
     <button class="absolute top-0 right-0 z-10 p-2 mt-2 mr-2 text-white transition -translate-y-12 rounded-full opacity-0 focus:ring-accent focus:opacity-100 focus:-translate-y-0 group-hover:translate-y-0 bg-black/50 group-hover:opacity-100" id="more-dropdown-<?= $episode->id ?>" data-dropdown="button" data-dropdown-target="more-dropdown-<?= $episode->id ?>-menu" aria-haspopup="true" aria-expanded="false" title="<?= lang('Common.more') ?>"><?= icon('more') ?></button>
-    <DropdownMenu id="more-dropdown-<?= $episode->id ?>-menu" labelledby="more-dropdown-<?= $episode->id ?>" offsetY="-32" items="<?= esc(json_encode([
+    <?php $items = [
         [
             'type' => 'link',
             'title' => lang('Episode.go_to_page'),
@@ -45,11 +45,24 @@
         [
             'type' => 'separator',
         ],
-        [
+    ];
+    if ($episode->published_at === null) {
+        $items[] = [
             'type' => 'link',
             'title' => lang('Episode.delete'),
             'uri' => route_to('episode-delete', $episode->podcast->id, $episode->id),
             'class' => 'font-semibold text-red-600',
-        ],
-    ])) ?>" />
+        ];
+    } else {
+        $label = lang('Episode.delete');
+        $icon = icon('forbid', 'mr-2');
+        $title = lang('Episode.messages.unpublishBeforeDeleteTip');
+        $items[] = [
+            'type' => 'html',
+            'content' => esc(<<<CODE_SAMPLE
+                    <span class="inline-flex items-center px-4 py-1 font-semibold text-gray-400 cursor-not-allowed" data-tooltip="bottom" title="{$title}">{$icon}{$label}</span>
+                CODE_SAMPLE),
+        ];
+    } ?>
+    <DropdownMenu id="more-dropdown-<?= $episode->id ?>-menu" labelledby="more-dropdown-<?= $episode->id ?>" offsetY="-32" items="<?= esc(json_encode($items)) ?>" />
 </article>
\ No newline at end of file
diff --git a/themes/cp_admin/episode/edit.php b/themes/cp_admin/episode/edit.php
index 5611b60b0a3e4466406177556110c4c0fc7116c3..9191635d31632e6d149b941b90a8e7fd0366120e 100644
--- a/themes/cp_admin/episode/edit.php
+++ b/themes/cp_admin/episode/edit.php
@@ -278,7 +278,11 @@
 
 </form>
 
-<Button class="mt-8" variant="danger" uri="<?= route_to('episode-delete', $podcast->id, $episode->id) ?>" iconLeft="delete-bin"><?= lang('Episode.delete') ?></Button>
+<?php if ($episode->published_at === null): ?>
+    <Button class="mt-8" variant="danger" uri="<?= route_to('episode-delete', $podcast->id, $episode->id) ?>" iconLeft="delete-bin"><?= lang('Episode.delete') ?></Button>    
+<?php else: ?>
+    <Button class="mt-8" variant="disabled" iconLeft="forbid" data-tooltip="right" title="<?= lang('Episode.messages.unpublishBeforeDeleteTip') ?>"><?= lang('Episode.delete') ?></Button>
+<?php endif ?>
 
 
 <?= $this->endSection() ?>
diff --git a/themes/cp_admin/episode/list.php b/themes/cp_admin/episode/list.php
index b491ea9613df525a8eb5f5157d96b92d99e4e364..a7d2762bccfc047f0caae38f944ec710a0d87631 100644
--- a/themes/cp_admin/episode/list.php
+++ b/themes/cp_admin/episode/list.php
@@ -73,50 +73,63 @@
             [
                 'header' => lang('Episode.list.actions'),
                 'cell' => function ($episode, $podcast) {
+                    $items = [
+                        [
+                            'type' => 'link',
+                            'title' => lang('Episode.go_to_page'),
+                            'uri' => route_to('episode', esc($podcast->handle), esc($episode->slug)),
+                        ],
+                        [
+                            'type' => 'link',
+                            'title' => lang('Episode.edit'),
+                            'uri' => route_to('episode-edit', $podcast->id, $episode->id),
+                        ],
+                        [
+                            'type' => 'link',
+                            'title' => lang('Episode.embed.title'),
+                            'uri' => route_to('embed-add', $podcast->id, $episode->id),
+                        ],
+                        [
+                            'type' => 'link',
+                            'title' => lang('Person.persons'),
+                            'uri' => route_to('episode-persons-manage', $podcast->id, $episode->id),
+                        ],
+                        [
+                            'type' => 'link',
+                            'title' => lang('VideoClip.list.title'),
+                            'uri' => route_to('video-clips-list', $episode->podcast->id, $episode->id),
+                        ],
+                        [
+                            'type' => 'link',
+                            'title' => lang('Soundbite.list.title'),
+                            'uri' => route_to('soundbites-list', $podcast->id, $episode->id),
+                        ],
+                        [
+                            'type' => 'separator',
+                        ],
+                    ];
+                    if ($episode->published_at === null) {
+                        $items[] = [
+                            'type' => 'link',
+                            'title' => lang('Episode.delete'),
+                            'uri' => route_to('episode-delete', $podcast->id, $episode->id),
+                            'class' => 'font-semibold text-red-600',
+                        ];
+                    } else {
+                        $label = lang('Episode.delete');
+                        $icon = icon('forbid');
+                        $title = lang('Episode.messages.unpublishBeforeDeleteTip');
+                        $items[] = [
+                            'type' => 'html',
+                            'content' => esc(<<<CODE_SAMPLE
+                                    <span class="inline-flex items-center px-4 py-1 font-semibold text-gray-400 cursor-not-allowed" data-tooltip="bottom" title="{$title}">{$icon}<span class="ml-2">{$label}</span></span>
+                                CODE_SAMPLE),
+                        ];
+                    }
                     return '<button id="more-dropdown-' . $episode->id . '" type="button" class="inline-flex items-center p-1 rounded-full focus:ring-accent" data-dropdown="button" data-dropdown-target="more-dropdown-' . $episode->id . '-menu" aria-haspopup="true" aria-expanded="false">' .
                         icon('more') .
                         '</button>' .
-                        '<DropdownMenu id="more-dropdown-' . $episode->id . '-menu" labelledby="more-dropdown-' . $episode->id . '" offsetY="-24" items="' . esc(json_encode([
-                            [
-                                'type' => 'link',
-                                'title' => lang('Episode.go_to_page'),
-                                'uri' => route_to('episode', esc($podcast->handle), esc($episode->slug)),
-                            ],
-                            [
-                                'type' => 'link',
-                                'title' => lang('Episode.edit'),
-                                'uri' => route_to('episode-edit', $podcast->id, $episode->id),
-                            ],
-                            [
-                                'type' => 'link',
-                                'title' => lang('Episode.embed.title'),
-                                'uri' => route_to('embed-add', $podcast->id, $episode->id),
-                            ],
-                            [
-                                'type' => 'link',
-                                'title' => lang('Person.persons'),
-                                'uri' => route_to('episode-persons-manage', $podcast->id, $episode->id),
-                            ],
-                            [
-                                'type' => 'link',
-                                'title' => lang('VideoClip.list.title'),
-                                'uri' => route_to('video-clips-list', $episode->podcast->id, $episode->id),
-                            ],
-                            [
-                                'type' => 'link',
-                                'title' => lang('Soundbite.list.title'),
-                                'uri' => route_to('soundbites-list', $podcast->id, $episode->id),
-                            ],
-                            [
-                                'type' => 'separator',
-                            ],
-                            [
-                                'type' => 'link',
-                                'title' => lang('Episode.delete'),
-                                'uri' => route_to('episode-delete', $podcast->id, $episode->id),
-                                'class' => 'font-semibold text-red-600',
-                            ],
-                        ])) . '" />';
+                        '<DropdownMenu id="more-dropdown-' . $episode->id . '-menu" labelledby="more-dropdown-' . $episode->id . '" offsetY="-24" items="' . esc(json_encode($items)) . '" />';
                 },
             ],
         ],
diff --git a/themes/cp_admin/podcast/_sidebar.php b/themes/cp_admin/podcast/_sidebar.php
index dadafde8749b4b04e7343e43f802e3b140b49f1c..619e1f4cf7036b06f203c88a59f94d2ad725b217 100644
--- a/themes/cp_admin/podcast/_sidebar.php
+++ b/themes/cp_admin/podcast/_sidebar.php
@@ -33,7 +33,13 @@ $podcastNavigation = [
             'platforms-funding',
         ],
     ],
-]; ?>
+];
+
+$counts = [
+    'episode-list' => $podcast->getEpisodesCount(),
+];
+
+?>
 
 <div class="flex items-center px-4 py-2 border-b border-navigation">
     <img
@@ -65,13 +71,19 @@ $podcastNavigation = [
         <ul class="flex flex-col">
             <?php foreach ($data['items'] as $item): ?>
                 <?php $isActive = url_is(route_to($item, $podcast->id)); ?>
+                <?php
+                    $itemLabel = lang('PodcastNavigation.' . $item);
+                    if (array_key_exists($item, $counts)) {
+                        $itemLabel .= ' (' . $counts[$item] . ')';
+                    }
+                ?>
             <li class="inline-flex">
                 <a class="w-full py-1 pl-14 pr-2 text-sm hover:opacity-100 focus:ring-inset focus:ring-accent <?= $isActive
                     ? 'font-semibold opacity-100 inline-flex items-center'
                     : 'opacity-75' ?>" href="<?= route_to(
                         $item,
                         $podcast->id,
-                    ) ?>"><?= ($isActive ? icon('chevron-right', 'mr-2') : '') . lang('PodcastNavigation.' . $item) ?></a>
+                    ) ?>"><?= ($isActive ? icon('chevron-right', 'mr-2') : '') . $itemLabel ?></a>
             </li>
             <?php endforeach; ?>
         </ul>