summaryrefslogtreecommitdiff
path: root/CoreWiki/Pages
diff options
context:
space:
mode:
Diffstat (limited to 'CoreWiki/Pages')
-rw-r--r--CoreWiki/Pages/All.cshtml48
-rw-r--r--CoreWiki/Pages/All.cshtml.cs39
-rw-r--r--CoreWiki/Pages/Create.cshtml4
-rw-r--r--CoreWiki/Pages/Create.cshtml.cs14
-rw-r--r--CoreWiki/Pages/Delete.cshtml6
-rw-r--r--CoreWiki/Pages/Delete.cshtml.cs33
-rw-r--r--CoreWiki/Pages/Details.cshtml8
-rw-r--r--CoreWiki/Pages/Details.cshtml.cs23
-rw-r--r--CoreWiki/Pages/Edit.cshtml12
-rw-r--r--CoreWiki/Pages/Edit.cshtml.cs17
-rw-r--r--CoreWiki/Pages/LatestChanges.cshtml6
-rw-r--r--CoreWiki/Pages/Shared/_Layout.cshtml15
12 files changed, 152 insertions, 73 deletions
diff --git a/CoreWiki/Pages/All.cshtml b/CoreWiki/Pages/All.cshtml
new file mode 100644
index 0000000..ca06cb5
--- /dev/null
+++ b/CoreWiki/Pages/All.cshtml
@@ -0,0 +1,48 @@
+@page
+@model CoreWiki.Pages.All
+
+@{
+ ViewData["Title"] = "All articles";
+}
+
+<h2>All articles</h2>
+
+@foreach (var item in Model.Articles)
+{
+ <div class="card border-primary my-2 mx-1">
+ <div class="card-body">
+ <h3 class="card-title">
+ <a href="~/@item.Slug">@item.Topic</a>
+ </h3>
+ <h6 class="card-subtitle mb-2 text-muted">
+ <span data-value="@item.Published" class="timeStampValue">@item.Published</span>
+ </h6>
+
+ <a class="card-link" asp-page="./Edit" asp-route-slug="@item.Slug">Edit</a>
+ <a class="card-link" asp-page="./Delete" asp-route-slug="@item.Slug">Delete</a>
+ </div>
+ </div>
+}
+
+<div class="col-md-12 d-flex">
+ <nav class="flex-grow-1">
+ <ul class="pagination">
+ @for (var i = 1; i <= Model.TotalPages; i++)
+ {
+ var i1 = i;
+ <li class="page-item @(i1 == Model.PageNumber ? "active" : "")">
+ <a class="page-link" asp-page="All" asp-route-PageNumber="@i1" asp-route-PageSize="@Model.PageSize">@i1</a>
+ </li>
+ }
+ </ul>
+ </nav>
+ <form class="ms-auto" method="get" asp-page="All">
+ <input hidden name="@nameof(Model.PageNumber)" value="@Model.PageNumber"/>
+ <select class="form-select" asp-for="@Model.PageSize" onchange="this.form.submit()">
+ <option value="2">2</option>
+ <option value="10">10</option>
+ <option value="25">25</option>
+ <option value="50">50</option>
+ </select>
+ </form>
+</div> \ No newline at end of file
diff --git a/CoreWiki/Pages/All.cshtml.cs b/CoreWiki/Pages/All.cshtml.cs
new file mode 100644
index 0000000..c41e216
--- /dev/null
+++ b/CoreWiki/Pages/All.cshtml.cs
@@ -0,0 +1,39 @@
+using CoreWiki.Models;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.RazorPages;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Internal;
+
+namespace CoreWiki.Pages;
+
+public class All : PageModel
+{
+ private readonly ApplicationDbContext _context;
+
+ [BindProperty(SupportsGet = true)]
+ public int PageNumber { get; set; } = 1;
+ [BindProperty(SupportsGet = true)]
+ public int PageSize { get; set; } = 25;
+ public IEnumerable<Article>? Articles { get; set; }
+ public int TotalPages { get; set; }
+
+ public All(ApplicationDbContext context)
+ {
+ _context = context;
+ }
+
+ public async Task<IActionResult> OnGetAsync()
+ {
+ TotalPages = (int)Math.Ceiling(await _context.Articles.CountAsync() / (float)PageSize);
+ if (PageNumber > TotalPages) PageNumber = 1;
+
+ Articles = await _context.Articles
+ .AsNoTracking()
+ .OrderBy(a => a.PublishedDateTime)
+ .Skip(PageSize * (PageNumber - 1))
+ .Take(PageSize)
+ .ToArrayAsync();
+
+ return Page();
+ }
+} \ No newline at end of file
diff --git a/CoreWiki/Pages/Create.cshtml b/CoreWiki/Pages/Create.cshtml
index fc74317..4abbf11 100644
--- a/CoreWiki/Pages/Create.cshtml
+++ b/CoreWiki/Pages/Create.cshtml
@@ -9,8 +9,8 @@
<h4>Article</h4>
<hr />
-<div class="row">
- <div class="col-md-4">
+<div class="row d-flex justify-content-center">
+ <div class="col-md-8">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
diff --git a/CoreWiki/Pages/Create.cshtml.cs b/CoreWiki/Pages/Create.cshtml.cs
index d89b97b..0bf9327 100644
--- a/CoreWiki/Pages/Create.cshtml.cs
+++ b/CoreWiki/Pages/Create.cshtml.cs
@@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using CoreWiki.Models;
+using CoreWiki.Utils;
using NodaTime;
namespace CoreWiki.Pages
@@ -30,19 +31,26 @@ namespace CoreWiki.Pages
public Article Article { get; set; } = default!;
- // To protect from overposting attacks, see https://aka.ms/RazorPagesCRUD
public async Task<IActionResult> OnPostAsync()
{
- if (!ModelState.IsValid || _context.Articles == null || Article == null)
+ ModelState.Remove("Article.Slug");
+ if (!ModelState.IsValid)
{
return Page();
}
+ Article.Slug = SafeUrl.Create(true, Article.Topic);
Article.Published = _clock.GetCurrentInstant();
+ if (_context.Articles.Any(a => a.Slug == Article.Slug))
+ {
+ ModelState.AddModelError("Article.Topic", "Article already exists");
+ return Page();
+ }
+
_context.Articles.Add(Article);
await _context.SaveChangesAsync();
- return Redirect($"/{Article.Topic}");
+ return Redirect($"/{Article.Slug}");
}
}
}
diff --git a/CoreWiki/Pages/Delete.cshtml b/CoreWiki/Pages/Delete.cshtml
index ec40822..0b680b8 100644
--- a/CoreWiki/Pages/Delete.cshtml
+++ b/CoreWiki/Pages/Delete.cshtml
@@ -1,4 +1,4 @@
-@page
+@page "/Delete/{slug}"
@model CoreWiki.Pages.DeleteModel
@{
@@ -27,8 +27,8 @@
</dl>
<form method="post">
- <input type="hidden" asp-for="Article.Topic" />
+ <input type="hidden" asp-for="Article.Slug" />
<input type="submit" value="Delete" class="btn btn-danger" /> |
- <a asp-page="./Index">Back to List</a>
+ <a href="/">Back to Home Page</a>
</form>
</div>
diff --git a/CoreWiki/Pages/Delete.cshtml.cs b/CoreWiki/Pages/Delete.cshtml.cs
index 9de563e..584dc48 100644
--- a/CoreWiki/Pages/Delete.cshtml.cs
+++ b/CoreWiki/Pages/Delete.cshtml.cs
@@ -19,42 +19,39 @@ namespace CoreWiki.Pages
}
[BindProperty]
- public Article Article { get; set; } = default!;
+ public Article Article { get; set; } = default!;
- public async Task<IActionResult> OnGetAsync(string id)
+ public async Task<IActionResult> OnGetAsync(string slug)
{
- if (id == null || _context.Articles == null)
+ if (slug == "home-page")
{
return NotFound();
}
-
- var article = await _context.Articles.FirstOrDefaultAsync(m => m.Topic == id);
+
+ var article = await _context.Articles.FirstOrDefaultAsync(a => a.Slug == slug);
if (article == null)
{
return NotFound();
}
- else
- {
- Article = article;
- }
+
+ Article = article;
return Page();
}
- public async Task<IActionResult> OnPostAsync(string id)
+ public async Task<IActionResult> OnPostAsync(string slug)
{
- if (id == null || _context.Articles == null)
+ if (slug == "home-page")
{
return NotFound();
}
- var article = await _context.Articles.FindAsync(id);
+
+ var article = await _context.Articles.FirstOrDefaultAsync(a => a.Slug == slug);
- if (article != null)
- {
- Article = article;
- _context.Articles.Remove(Article);
- await _context.SaveChangesAsync();
- }
+ if (article == null) return NotFound();
+ Article = article;
+ _context.Articles.Remove(Article);
+ await _context.SaveChangesAsync();
return Redirect("/");
}
diff --git a/CoreWiki/Pages/Details.cshtml b/CoreWiki/Pages/Details.cshtml
index bf1a616..9f48f9f 100644
--- a/CoreWiki/Pages/Details.cshtml
+++ b/CoreWiki/Pages/Details.cshtml
@@ -1,8 +1,8 @@
-@page "{topicName?}"
+@page "/{slug?}"
@model CoreWiki.Pages.DetailsModel
@{
- ViewData["Title"] = "Details";
+ ViewData["Title"] = Model.Article.Topic;
}
<h1>@Model.Article.Topic</h1>
@@ -11,8 +11,8 @@
<markdown markdown="Article.Content"/>
<div>
- <a asp-page="./Edit" asp-route-id="@Model.Article?.Topic">Edit</a>
- @if (Model.Article.Topic != "HomePage")
+ <a asp-page="./Edit" asp-route-slug="@Model.Article.Slug">Edit</a>
+ @if (Model.Article.Slug != "home-page")
{
<text>| </text> <a href="~/">Back to Home</a>
}
diff --git a/CoreWiki/Pages/Details.cshtml.cs b/CoreWiki/Pages/Details.cshtml.cs
index 25ff6c0..e4100ac 100644
--- a/CoreWiki/Pages/Details.cshtml.cs
+++ b/CoreWiki/Pages/Details.cshtml.cs
@@ -11,33 +11,26 @@ namespace CoreWiki.Pages
{
public class DetailsModel : PageModel
{
- private readonly CoreWiki.Models.ApplicationDbContext _context;
+ private readonly ApplicationDbContext _context;
- public DetailsModel(CoreWiki.Models.ApplicationDbContext context)
+ public DetailsModel(ApplicationDbContext context)
{
_context = context;
}
- public Article Article { get; set; } = default!;
+ public Article Article { get; set; } = default!;
- public async Task<IActionResult> OnGetAsync(string? topicName)
+ public async Task<IActionResult> OnGetAsync(string? slug)
{
- topicName ??= "HomePage";
-
- if (_context.Articles == null)
- {
- return NotFound();
- }
+ slug ??= "home-page";
- var article = await _context.Articles.FirstOrDefaultAsync(m => m.Topic == topicName);
+ var article = await _context.Articles.FirstOrDefaultAsync(a => a.Slug == slug);
if (article == null)
{
return NotFound();
}
- else
- {
- Article = article;
- }
+
+ Article = article;
return Page();
}
}
diff --git a/CoreWiki/Pages/Edit.cshtml b/CoreWiki/Pages/Edit.cshtml
index 7609348..8793034 100644
--- a/CoreWiki/Pages/Edit.cshtml
+++ b/CoreWiki/Pages/Edit.cshtml
@@ -1,4 +1,4 @@
-@page
+@page "/Edit/{slug}"
@using CoreWiki.Models
@model CoreWiki.Pages.EditModel
@@ -8,17 +8,15 @@
<h1>Edit</h1>
-<h3>@Model.Article.Topic</h3>
-<hr />
+<br />
<div class="row">
- <div class="col-md-4">
+ <div class="col-md-12">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
+ <input type="hidden" asp-for="Article.Slug" />
<input type="hidden" asp-for="Article.Topic" />
<div class="form-group">
- <label asp-for="Article.Published" class="control-label"></label>
- <input disabled asp-for="Article.Published" class="form-control" />
- <span asp-validation-for="Article.Published" class="text-danger"></span>
+ <h3>@Model.Article.Topic</h3>
</div>
<div class="form-group">
<label asp-for="Article.Content" class="control-label"></label>
diff --git a/CoreWiki/Pages/Edit.cshtml.cs b/CoreWiki/Pages/Edit.cshtml.cs
index e3b11c2..46920cb 100644
--- a/CoreWiki/Pages/Edit.cshtml.cs
+++ b/CoreWiki/Pages/Edit.cshtml.cs
@@ -25,14 +25,9 @@ namespace CoreWiki.Pages
[BindProperty]
public Article Article { get; set; } = default!;
- public async Task<IActionResult> OnGetAsync(string id)
+ public async Task<IActionResult> OnGetAsync(string slug)
{
- if (id == null || _context.Articles == null)
- {
- return NotFound();
- }
-
- var article = await _context.Articles.FirstOrDefaultAsync(m => m.Topic == id);
+ var article = await _context.Articles.FirstOrDefaultAsync(m => m.Slug == slug);
if (article == null)
{
return NotFound();
@@ -40,9 +35,7 @@ namespace CoreWiki.Pages
Article = article;
return Page();
}
-
- // To protect from overposting attacks, enable the specific properties you want to bind to.
- // For more details, see https://aka.ms/RazorPagesCRUD.
+
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
@@ -69,12 +62,12 @@ namespace CoreWiki.Pages
}
}
- return Redirect($"./{(Article.Topic == "HomePage" ? "" : Article.Topic)}");
+ return Redirect($"/{(Article.Slug == "home-page" ? "" : Article.Slug)}");
}
private bool ArticleExists(string id)
{
- return (_context.Articles?.Any(e => e.Topic == id)).GetValueOrDefault();
+ return (_context.Articles?.Any(e => e.Slug == id)).GetValueOrDefault();
}
}
}
diff --git a/CoreWiki/Pages/LatestChanges.cshtml b/CoreWiki/Pages/LatestChanges.cshtml
index 390c8ab..677887b 100644
--- a/CoreWiki/Pages/LatestChanges.cshtml
+++ b/CoreWiki/Pages/LatestChanges.cshtml
@@ -15,11 +15,11 @@
{
<div class="card border-primary m-1">
<div class="card-body">
- <h3 class="card-title"><a href="~/@item.Topic">@item.Topic</a></h3>
+ <h3 class="card-title"><a href="~/@item.Slug">@item.Topic</a></h3>
<h6 class="card-subtitle mb-2 text-muted"><span data-value="@item.Published" class="timeStampValue">@item.Published</span></h6>
- <a class="card-link" asp-page="./Edit" asp-route-id="@item.Topic">Edit</a>
- <a class="card-link" asp-page="./Delete" asp-route-id="@item.Topic">Delete</a>
+ <a class="card-link" asp-page="./Edit" asp-route-slug="@item.Slug">Edit</a>
+ <a class="card-link" asp-page="./Delete" asp-route-slug="@item.Slug">Delete</a>
</div>
</div>
} \ No newline at end of file
diff --git a/CoreWiki/Pages/Shared/_Layout.cshtml b/CoreWiki/Pages/Shared/_Layout.cshtml
index dbe5e47..ac74eba 100644
--- a/CoreWiki/Pages/Shared/_Layout.cshtml
+++ b/CoreWiki/Pages/Shared/_Layout.cshtml
@@ -7,14 +7,14 @@
<link rel="stylesheet" href="~/lib/bootstrap/css/bootstrap.min.css"/>
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true"/>
<link rel="stylesheet" href="~/CoreWiki.styles.css" asp-append-version="true"/>
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.3.0/css/all.min.css" integrity="sha512-SzlrxWUlpfuzQ+pcUCosxcglQRNAq/DZjVsC0lE40xsADsfeQoEypE+enwcOiGjk/bSuGGKHEyjSoQ1zVisanQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.3.0/css/all.min.css" integrity="sha512-SzlrxWUlpfuzQ+pcUCosxcglQRNAq/DZjVsC0lE40xsADsfeQoEypE+enwcOiGjk/bSuGGKHEyjSoQ1zVisanQ==" crossorigin="anonymous" referrerpolicy="no-referrer"/>
@await RenderSectionAsync("Styles", required: false)
</head>
<body>
<header>
- <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-dark bg-dark border-bottom box-shadow mb-3">
+ <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-light border-bottom box-shadow mb-3">
<div class="container">
- <a class="navbar-brand" asp-area="" asp-page="/Index">CoreWiki</a>
+ <a class="navbar-brand" asp-page="Details">CoreWiki</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
@@ -22,13 +22,16 @@
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
- <a class="nav-link text-light" href="~/Index">Home</a>
+ <a class="nav-link" asp-page="Details">Home</a>
</li>
<li class="nav-item">
- <a class="nav-link text-light" asp-area="" asp-page="/Create">Create</a>
+ <a class="nav-link" asp-area="" asp-page="Create">Create</a>
</li>
<li class="nav-item">
- <a class="nav-link text-light" href="~/LatestChanges">Latest Changes</a>
+ <a class="nav-link" asp-page="All">All Articles</a>
+ </li>
+ <li class="nav-item">
+ <a class="nav-link" asp-page="LatestChanges">Latest Changes</a>
</li>
</ul>
</div>