feat: add blog feed (#3)

* chore: begin working on post service

* chore: add debug assets

* chore: add whitelist words

* feat: add prism for syntax highlighting

* feat: updated favicon

* feat: add blog feed

* fix: add link to written by image

* feat: add custom error pages

* fix: focus on h2 since h1 is always the journal site title

* feat: use status code pages with redirects

* fix: add discernible text to link

* feat: add support for light and dark theme

* fix: wrap body with main tag

* fix: style main element in pages to take up full width of container

* fix: add heading to home page

* feat: add not-found-corgi image

* chore: add robots.txt file

* chore: clean up place holder posts

* fix: namespace header in layouts

* fix: use logger instead of console

* fix: use new text context in each test when registering services

* chore: update workflow to debug failing tests

* chore: install playwright deps

* fix: extend expect timeout

* fix: extend expect timeout

* fix: capture traces

* fix: capture traces

* fix: index file name
This commit is contained in:
Stevan Freeborn
2024-04-10 01:28:38 -05:00
committed by GitHub
parent d25e5d4944
commit c4795dfdae
42 changed files with 16676 additions and 63 deletions
+5 -2
View File
@@ -1,4 +1,4 @@
@namespace Blog.Components
@namespace Blog.Components.Layout
<header class="container">
<div class="title-container">
@@ -8,6 +8,9 @@
</div>
<div class="author-container">
<span>by</span>
<img src="https://github.com/StevanFreeborn.png" alt="Stevan Freeborn" />
<a href="https://stevanfreeborn.com" target="_blank">
<img src="https://github.com/StevanFreeborn.png" alt="Stevan Freeborn" />
<span class="sr-only">Stevan Freeborn</span>
</a>
</div>
</header>
+3 -1
View File
@@ -3,7 +3,9 @@
<div class="container">
<Header />
@Body
<main>
@Body
</main>
</div>
<div id="blazor-error-ui">
@@ -6,10 +6,17 @@
max-width: 42rem;
padding: 1.25rem;
width: 100%;
gap: 4rem;
}
main {
display: flex;
flex-direction: column;
width: 100%;
}
#blazor-error-ui {
background: lightyellow;
background: var(--color-background-soft);
bottom: 0;
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
display: none;
+14 -23
View File
@@ -3,34 +3,25 @@
<PageTitle>Error</PageTitle>
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
<div class="container">
<h2>Error</h2>
<p>Sorry it's me, not you. It looks like an unhandled error occurred while processing your request.</p>
@if (ShowRequestId)
{
@if (ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@RequestId</code>
<strong>Request ID:</strong> <code>@RequestId</code>
</p>
}
<h3>Development Mode</h3>
<p>
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>
}
</div>
@code{
[CascadingParameter]
private HttpContext? HttpContext { get; set; }
[CascadingParameter]
private HttpContext? HttpContext { get; set; }
private string? RequestId { get; set; }
private bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
private string? RequestId { get; set; }
private bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
protected override void OnInitialized() =>
RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier;
protected override void OnInitialized() =>
RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier;
}
@@ -0,0 +1,5 @@
.container {
display: flex;
flex-direction: column;
gap: 1rem;
}
+3 -4
View File
@@ -3,9 +3,8 @@
<PageTitle>journal - A blog by Stevan Freeborn</PageTitle>
<HeadContent>
<meta name="description" content="A blog by Stevan Freeborn" />
<meta name="description" content="A blog by Stevan Freeborn" />
</HeadContent>
<h1>Hello, world!</h1>
Welcome to your new app.
<h2 class="sr-only">Posts</h2>
<Feed />
@@ -0,0 +1,8 @@
@page "/Error/404"
<div class="container">
<h2>Not Found</h2>
<p>Hmm...it doesn't look like the page you were looking for exists, but we did find this adorable corgi.</p>
<img src="not-found-corgi.jpg" alt="A cute corgi" />
</div>
@@ -0,0 +1,9 @@
.container {
display: flex;
flex-direction: column;
gap: 1rem;
& img {
border-radius: 0.5rem;
}
}
+34
View File
@@ -0,0 +1,34 @@
@namespace Blog.Components
@inject IPostService postService
@inject IJSRuntime JS
@if (posts.Count == 0)
{
<div class="container">
<p>Looks like writers block. Check back later.</p>
</div>
}
else
{
<section role="feed" class="container">
@foreach (var post in posts)
{
<a href="/@post.Slug">
<article>
<h3 title="@post.Title" >@post.Title</h3>
<p class="date">@post.PublishedAt.ToString("MMMM d, yyyy")</p>
<p class="lead">@post.Lead</p>
</article>
</a>
}
</section>
}
@code {
private List<Post> posts = [];
protected override async Task OnInitializedAsync()
{
posts = await postService.GetPostsAsync();
}
}
+46
View File
@@ -0,0 +1,46 @@
.container {
display: flex;
flex-direction: column;
width: 100%;
gap: 2rem;
& a {
padding: 1rem;
border-radius: 1rem;
background-color: var(--color-background-soft);
transition-property: transform;
transition-duration: 100ms;
transition-timing-function: ease-in-out
}
& a:active {
transform: scale(0.95)
}
& article {
display: flex;
flex-direction: column;
gap: 0.25rem;
& h3 {
background: linear-gradient(to right top, #db3e3e, #df3741, #e32e44, #e72347, #eb124b);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
font-size: 2rem;
font-weight: 900;
}
& .date {
font-size: 0.85rem;
}
& h3,
& .date,
& .lead {
text-wrap: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
<Router AppAssembly="typeof(Program).Assembly">
<Found Context="routeData">
<RouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)" />
<FocusOnNavigate RouteData="routeData" Selector="h1" />
<FocusOnNavigate RouteData="routeData" Selector="h2" />
</Found>
</Router>