feat: 使用Bootstrap重写前端页面 #2
|
@ -40,6 +40,7 @@ public class EssayContentService
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<KeyValuePair<string, int>> Tags => from item in _tags
|
public IEnumerable<KeyValuePair<string, int>> Tags => from item in _tags
|
||||||
|
orderby item.Value.Count descending
|
||||||
select KeyValuePair.Create(item.Key, item.Value.Count);
|
select KeyValuePair.Create(item.Key, item.Value.Count);
|
||||||
|
|
||||||
public int TagCount => _tags.Count;
|
public int TagCount => _tags.Count;
|
||||||
|
|
|
@ -1,4 +1,42 @@
|
||||||
<div>
|
@using YaeBlog.Core.Services
|
||||||
<h3>“奇奇怪怪东西的聚合地”</h3>
|
|
||||||
|
@inject EssayContentService EssayContentInstance
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-auto p-4">
|
||||||
|
<Image Src="images/avatar.png" Alt="Ricardo's avatar"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row justify-content-center p-3">
|
||||||
|
<div class="col-auto fs-4">
|
||||||
|
“奇奇怪怪东西的聚合地”
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row justify-content-between px-2 py-1 fs-5">
|
||||||
|
<div class="col-auto">
|
||||||
|
文章
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-auto">
|
||||||
|
<a href="/blog/archives">
|
||||||
|
@(EssayContentInstance.Essays.Count)
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row justify-content-between px-2 py-1 fs-5">
|
||||||
|
<div class="col-auto">
|
||||||
|
标签
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-auto">
|
||||||
|
<a href="/blog/tags">
|
||||||
|
@(EssayContentInstance.TagCount)
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
39
YaeBlog/Components/EssayCard.razor
Normal file
39
YaeBlog/Components/EssayCard.razor
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
@using YaeBlog.Core.Models
|
||||||
|
|
||||||
|
<div class="container p-3">
|
||||||
|
<div class="row fs-2 fw-bold py-2 essay-title">
|
||||||
|
<a href="/blog/essays/@(Essay.FileName)" target="_blank">@(Essay.Title)</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row p-2 justify-content-start">
|
||||||
|
<div class="col-auto fw-light">
|
||||||
|
@(Essay.PublishTime.ToString("yyyy-MM-dd"))
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@foreach (string key in Essay.Tags)
|
||||||
|
{
|
||||||
|
<div class="col-auto">
|
||||||
|
<a href="/blog/tags/?tagName=@key">
|
||||||
|
# @key
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row p-2">
|
||||||
|
<div class="col">
|
||||||
|
@(Essay.Description)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col border-bottom">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
[Parameter]
|
||||||
|
public required BlogEssay Essay { get; set; }
|
||||||
|
}
|
3
YaeBlog/Components/EssayCard.razor.css
Normal file
3
YaeBlog/Components/EssayCard.razor.css
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
.essay-title a {
|
||||||
|
color: var(--bs-body-color);
|
||||||
|
}
|
|
@ -11,28 +11,28 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-4 d-flex justify-content-around align-items-center">
|
<div class="col-4 d-flex justify-content-around align-items-center">
|
||||||
<a href="/blog/" class="p-2" target="_blank">
|
<a href="/blog/" class="p-2">
|
||||||
<div class="d-inline-flex" style="text-align: center">
|
<div class="d-inline-flex" style="text-align: center">
|
||||||
<Icon Name="@IconName.House" Color="@IconColor.Primary" class="px-2 d-none d-xl-block" Size="@IconSize.x5"/>
|
<Icon Name="@IconName.House" Color="@IconColor.Primary" class="px-2 d-none d-xl-block" Size="@IconSize.x5"/>
|
||||||
<h5>首页</h5>
|
<h5>首页</h5>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="/blog/archives/" class="p-2" target="_blank">
|
<a href="/blog/archives/" class="p-2">
|
||||||
<div class="d-inline-flex">
|
<div class="d-inline-flex">
|
||||||
<Icon Name="@IconName.Archive" Color="@IconColor.Primary" class="px-2 d-none d-xl-block" Size="IconSize.x5"/>
|
<Icon Name="@IconName.Archive" Color="@IconColor.Primary" class="px-2 d-none d-xl-block" Size="IconSize.x5"/>
|
||||||
<h5>归档</h5>
|
<h5>归档</h5>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="/blog/tags/" class="p-2" target="_blank">
|
<a href="/blog/tags/" class="p-2">
|
||||||
<div class="d-inline-flex">
|
<div class="d-inline-flex">
|
||||||
<Icon Name="@IconName.Tags" Color="@IconColor.Primary" class="px-2 d-none d-xl-block" Size="@IconSize.x5"/>
|
<Icon Name="@IconName.Tags" Color="@IconColor.Primary" class="px-2 d-none d-xl-block" Size="@IconSize.x5"/>
|
||||||
<h5>标签</h5>
|
<h5>标签</h5>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="/blog/about/" class="p-2" target="_blank">
|
<a href="/blog/about/" class="p-2">
|
||||||
<div class="d-inline-flex">
|
<div class="d-inline-flex">
|
||||||
<Icon Name="@IconName.Person" Color="@IconColor.Primary" class="px-2 d-none d-xl-block" Size="@IconSize.x5"/>
|
<Icon Name="@IconName.Person" Color="@IconColor.Primary" class="px-2 d-none d-xl-block" Size="@IconSize.x5"/>
|
||||||
<h5>关于</h5>
|
<h5>关于</h5>
|
||||||
|
|
9
YaeBlog/Pages/About.razor
Normal file
9
YaeBlog/Pages/About.razor
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
@page "/blog/about"
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
|
||||||
|
}
|
0
YaeBlog/Pages/About.razor.css
Normal file
0
YaeBlog/Pages/About.razor.css
Normal file
72
YaeBlog/Pages/Archives.razor
Normal file
72
YaeBlog/Pages/Archives.razor
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
@page "/blog/archives"
|
||||||
|
@using YaeBlog.Core.Models
|
||||||
|
@using YaeBlog.Core.Services
|
||||||
|
|
||||||
|
@inject EssayContentService EssayContentInstance
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<h1>归档</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col fst-italic py-4">
|
||||||
|
时光图书馆,黑历史集散地。
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@foreach (IGrouping<DateTime, KeyValuePair<string, BlogEssay>> group in _essays)
|
||||||
|
{
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<h3>@(group.Key.Year)</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container px-3 py-2">
|
||||||
|
@foreach (KeyValuePair<string, BlogEssay> essay in group)
|
||||||
|
{
|
||||||
|
<div class="row py-1">
|
||||||
|
<div class="col-auto">
|
||||||
|
@(essay.Value.PublishTime.ToString("MM-dd"))
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-auto">
|
||||||
|
<a href="/blog/@(essay.Key)">
|
||||||
|
@(essay.Value.Title)
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
private readonly List<IGrouping<DateTime, KeyValuePair<string, BlogEssay>>> _essays = [];
|
||||||
|
|
||||||
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
base.OnInitialized();
|
||||||
|
|
||||||
|
_essays.AddRange(from essay in EssayContentInstance.Essays
|
||||||
|
orderby essay.Value.PublishTime descending
|
||||||
|
group essay by new DateTime(essay.Value.PublishTime.Year, 1, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
0
YaeBlog/Pages/Archives.razor.css
Normal file
0
YaeBlog/Pages/Archives.razor.css
Normal file
|
@ -4,45 +4,13 @@
|
||||||
|
|
||||||
@inject EssayContentService EssayContentInstance
|
@inject EssayContentService EssayContentInstance
|
||||||
@inject NavigationManager NavigationInstance
|
@inject NavigationManager NavigationInstance
|
||||||
@inject ILogger<BlogIndex> Logger
|
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-12 col-md-9">
|
<div class="col-sm-12 col-md-9">
|
||||||
@foreach (KeyValuePair<string, BlogEssay> pair in _essays)
|
@foreach (KeyValuePair<string, BlogEssay> pair in _essays)
|
||||||
{
|
{
|
||||||
<div class="container p-3">
|
<EssayCard Essay="@(pair.Value)"/>
|
||||||
<div class="row fs-2 fw-bold py-2 essay-title">
|
|
||||||
<a href="/blog/essays/@(pair.Key)">@(pair.Value.Title)</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row p-2 justify-content-start">
|
|
||||||
<div class="col-auto fw-light">
|
|
||||||
@(pair.Value.PublishTime.ToString("yyyy-MM-dd"))
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@foreach (string key in pair.Value.Tags)
|
|
||||||
{
|
|
||||||
<div class="col-auto">
|
|
||||||
<a href="/blog/tags?tagName=@key">
|
|
||||||
# @key
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row p-2">
|
|
||||||
<div class="col">
|
|
||||||
@(pair.Value.Description)
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col border-bottom">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<div class="row align-items-center justify-content-center p-3">
|
<div class="row align-items-center justify-content-center p-3">
|
||||||
|
@ -60,7 +28,7 @@
|
||||||
@if (_page == 1)
|
@if (_page == 1)
|
||||||
{
|
{
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
<a href="/blog/?page=1">1</a>
|
1
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
<a href="/blog/?page=2">2</a>
|
<a href="/blog/?page=2">2</a>
|
||||||
|
@ -78,7 +46,7 @@
|
||||||
<a href="/blog/?page=@(_pageCount - 1)">@(_pageCount - 1)</a>
|
<a href="/blog/?page=@(_pageCount - 1)">@(_pageCount - 1)</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
<a href="/blog/?page=@(_pageCount)">@(_pageCount)</a>
|
@(_pageCount)
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -87,7 +55,7 @@
|
||||||
<a href="/blog/?page=@(_page - 1)">@(_page - 1)</a>
|
<a href="/blog/?page=@(_page - 1)">@(_page - 1)</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
<a href="/blog/?page=@(_page)">@(_page)</a>
|
@(_page)
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
<a href="/blog/?page=@(_page + 1)">@(_page + 1)</a>
|
<a href="/blog/?page=@(_page + 1)">@(_page + 1)</a>
|
||||||
|
|
|
@ -5,8 +5,35 @@
|
||||||
@inject NavigationManager NavigationInstance
|
@inject NavigationManager NavigationInstance
|
||||||
@inject EssayContentService EssayContentInstance
|
@inject EssayContentService EssayContentInstance
|
||||||
|
|
||||||
<div class="container">
|
<PageTitle>
|
||||||
|
@(_essay!.Title)
|
||||||
|
</PageTitle>
|
||||||
|
|
||||||
|
<div class="container py-4">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-auto">
|
||||||
|
<h1>@(_essay!.Title)</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row p-4">
|
||||||
|
<div class="col-auto fw-light">
|
||||||
|
@(_essay!.PublishTime.ToString("yyyy-MM-dd"))
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@foreach (string tag in _essay!.Tags)
|
||||||
|
{
|
||||||
|
<div class="col-auto">
|
||||||
|
<a href="/tags/?tagName=@(tag)"># @(tag)</a>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-8 col-md-12">
|
||||||
|
@((MarkupString)_essay!.HtmlContent)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
|
67
YaeBlog/Pages/Tags.razor
Normal file
67
YaeBlog/Pages/Tags.razor
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
@page "/blog/tags/"
|
||||||
|
@using YaeBlog.Core.Models
|
||||||
|
@using YaeBlog.Core.Services
|
||||||
|
|
||||||
|
@inject EssayContentService EssayContentInstance
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
@if (TagName is null)
|
||||||
|
{
|
||||||
|
<h1>标签</h1>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<h2>@(TagName)</h2>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col fst-italic py-4">
|
||||||
|
在野外游荡的指针,走向未知的方向。
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@if (TagName is null)
|
||||||
|
{
|
||||||
|
<div>
|
||||||
|
<ul>
|
||||||
|
@foreach (KeyValuePair<string, int> pair in EssayContentInstance.Tags)
|
||||||
|
{
|
||||||
|
<li class="p-2">
|
||||||
|
<a href="/blog/tags/?tagName=@(pair.Key)">
|
||||||
|
<div class="container fs-5">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-auto">
|
||||||
|
# @(pair.Key)
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-auto tag-count">
|
||||||
|
@(pair.Value)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<div class="container">
|
||||||
|
@foreach (BlogEssay essay in EssayContentInstance.GetTag(TagName).OrderByDescending(e => e.PublishTime))
|
||||||
|
{
|
||||||
|
<EssayCard Essay="@essay"/>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
[SupplyParameterFromQuery] public string? TagName { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
6
YaeBlog/Pages/Tags.razor.css
Normal file
6
YaeBlog/Pages/Tags.razor.css
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
.tag-count {
|
||||||
|
background: var(--bs-secondary-bg);
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 0 6px;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user