diff --git a/src/MyWebLog.Data/Extensions/CategoryExtensions.cs b/src/MyWebLog.Data/Extensions/CategoryExtensions.cs
new file mode 100644
index 0000000..37d4dd8
--- /dev/null
+++ b/src/MyWebLog.Data/Extensions/CategoryExtensions.cs
@@ -0,0 +1,13 @@
+using Microsoft.EntityFrameworkCore;
+
+namespace MyWebLog.Data;
+
+public static class CategoryEtensions
+{
+ ///
+ /// Count all categories
+ ///
+ /// A count of all categories
+ public static async Task CountAll(this DbSet db) =>
+ await db.CountAsync().ConfigureAwait(false);
+}
diff --git a/src/MyWebLog.Data/Extensions/PageExtensions.cs b/src/MyWebLog.Data/Extensions/PageExtensions.cs
index c105815..2f90f65 100644
--- a/src/MyWebLog.Data/Extensions/PageExtensions.cs
+++ b/src/MyWebLog.Data/Extensions/PageExtensions.cs
@@ -4,11 +4,26 @@ namespace MyWebLog.Data;
public static class PageExtensions
{
+ ///
+ /// Count the number of pages
+ ///
+ /// The number of pages
+ public static async Task CountAll(this DbSet db) =>
+ await db.CountAsync().ConfigureAwait(false);
+
///
/// Retrieve a page by its ID (non-tracked)
///
/// The ID of the page to retrieve
/// The requested page (or null if it is not found)
public static async Task FindById(this DbSet db, string id) =>
- await db.FirstOrDefaultAsync(p => p.Id == id).ConfigureAwait(false);
+ await db.SingleOrDefaultAsync(p => p.Id == id).ConfigureAwait(false);
+
+ ///
+ /// Retrieve a page by its permalink (non-tracked)
+ ///
+ /// The permalink
+ /// The requested page (or null if it is not found)
+ public static async Task FindByPermalink(this DbSet db, string permalink) =>
+ await db.SingleOrDefaultAsync(p => p.Permalink == permalink).ConfigureAwait(false);
}
diff --git a/src/MyWebLog.Data/Extensions/PostExtensions.cs b/src/MyWebLog.Data/Extensions/PostExtensions.cs
index 818d3ca..dd28fe1 100644
--- a/src/MyWebLog.Data/Extensions/PostExtensions.cs
+++ b/src/MyWebLog.Data/Extensions/PostExtensions.cs
@@ -4,6 +4,22 @@ namespace MyWebLog.Data;
public static class PostExtensions
{
+ ///
+ /// Count the posts in the given status
+ ///
+ /// The status for which posts should be counted
+ /// A count of the posts in the given status
+ public static async Task CountByStatus(this DbSet db, PostStatus status) =>
+ await db.CountAsync(p => p.Status == status).ConfigureAwait(false);
+
+ ///
+ /// Retrieve a post by its permalink (non-tracked)
+ ///
+ /// The possible post permalink
+ /// The post matching the permalink, or null if none is found
+ public static async Task FindByPermalink(this DbSet db, string permalink) =>
+ await db.SingleOrDefaultAsync(p => p.Id == permalink).ConfigureAwait(false);
+
///
/// Retrieve a page of published posts (non-tracked)
///
diff --git a/src/MyWebLog/Features/Admin/AdminController.cs b/src/MyWebLog/Features/Admin/AdminController.cs
index 088ee6e..efd99e0 100644
--- a/src/MyWebLog/Features/Admin/AdminController.cs
+++ b/src/MyWebLog/Features/Admin/AdminController.cs
@@ -12,8 +12,12 @@ public class AdminController : MyWebLogController
public AdminController(WebLogDbContext db) : base(db) { }
[HttpGet("")]
- public IActionResult Index()
- {
- return View();
- }
+ public async Task Index() =>
+ View(new DashboardModel(WebLog)
+ {
+ Posts = await Db.Posts.CountByStatus(PostStatus.Published),
+ Drafts = await Db.Posts.CountByStatus(PostStatus.Draft),
+ Pages = await Db.Pages.CountAll(),
+ Categories = await Db.Categories.CountAll()
+ });
}
diff --git a/src/MyWebLog/Features/Admin/DashboardModel.cs b/src/MyWebLog/Features/Admin/DashboardModel.cs
new file mode 100644
index 0000000..2342334
--- /dev/null
+++ b/src/MyWebLog/Features/Admin/DashboardModel.cs
@@ -0,0 +1,30 @@
+namespace MyWebLog.Features.Admin;
+
+///
+/// The model used to display the dashboard
+///
+public class DashboardModel : MyWebLogModel
+{
+ ///
+ /// The number of published posts
+ ///
+ public int Posts { get; set; } = 0;
+
+ ///
+ /// The number of post drafts
+ ///
+ public int Drafts { get; set; } = 0;
+
+ ///
+ /// The number of pages
+ ///
+ public int Pages { get; set; } = 0;
+
+ ///
+ /// The number of categories
+ ///
+ public int Categories { get; set; } = 0;
+
+ ///
+ public DashboardModel(WebLogDetails webLog) : base(webLog) { }
+}
diff --git a/src/MyWebLog/Features/Admin/Index.cshtml b/src/MyWebLog/Features/Admin/Index.cshtml
index 52fecf9..b9f7ff7 100644
--- a/src/MyWebLog/Features/Admin/Index.cshtml
+++ b/src/MyWebLog/Features/Admin/Index.cshtml
@@ -1,5 +1,35 @@
-@{
+@model DashboardModel
+@{
Layout = "_AdminLayout";
ViewBag.Title = Resources.Dashboard;
}
-