This commit is contained in:
2026-05-17 20:54:09 -04:00
parent 6da2183583
commit 74c21ee5cc
3000 changed files with 11794 additions and 15301 deletions

View File

@@ -42,27 +42,9 @@
<div>
<button type="submit" class="w-100 btn btn-lg btn-primary">Log in</button>
</div>
<div>
<p>
<a href="Account/ForgotPassword">Forgot your password?</a>
</p>
<p>
<a href="@(NavigationManager.GetUriWithQueryParameters("Account/Register", new Dictionary<string, object?> { ["ReturnUrl"] = ReturnUrl }))">Register as a new user</a>
</p>
<p>
<a href="Account/ResendEmailConfirmation">Resend email confirmation</a>
</p>
</div>
</EditForm>
</section>
</div>
<div class="col-lg-4 col-lg-offset-2">
<section>
<h3>Use another service to log in.</h3>
<hr />
<ExternalLoginPicker />
</section>
</div>
</div>
@code {

View File

@@ -8,8 +8,12 @@
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" rel="stylesheet" />
<link href="_content/CodeBeam.MudBlazor.Extensions/MudExtensions.min.css" rel="stylesheet" />
<link href=@Assets["_content/MudBlazor/MudBlazor.min.css"] rel="stylesheet" />
@*Allows the css calsses used by the rich text editor this project uses to be displayed properly*@
<link href="https://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">
<ImportMap />
<link rel="icon" type="image/ico" href="favicon.ico" />
<link href="css/app.css" rel="stylesheet"/>
<HeadOutlet @rendermode="PageRenderMode" />
</head>
@@ -18,8 +22,8 @@
<script src="_framework/blazor.web.js"></script>
<script src=@Assets["_content/MudBlazor/MudBlazor.min.js"]></script>
<script src="_content/CodeBeam.MudBlazor.Extensions/MudExtensions.min.js"></script>
<script src="js/downloadHelper.js"></script>
<script src="js/imageSizeGetter.js"></script>
<script src=@Assets["js/downloadHelper.js"]></script>
<script src=@Assets["js/imageSizeGetter.js"]></script>
</body>
</html>

View File

@@ -0,0 +1,17 @@
<MudGrid Justify="Justify.Center">
<MudItem xs="12" md="3" lg="2">
<MudButton Href="/search" Variant="Variant.Filled" Color="Color.Primary" FullWidth="true" StartIcon="@Icons.Material.Filled.Home">Artifacts</MudButton>
</MudItem>
<MudItem xs="12" md="3" lg="2">
<MudButton Href="/featured" Variant="Variant.Filled" Color="Color.Primary" FullWidth="true" StartIcon="@Icons.Material.Filled.Star">Featured Artifacts</MudButton>
</MudItem>
<MudItem xs="12" md="3" lg="2">
<MudButton Variant="Variant.Filled" Color="Color.Primary" FullWidth="true" StartIcon="@Icons.Material.Filled.Book">Blog Posts</MudButton>
</MudItem>
</MudGrid>
@code {
}

View File

@@ -1,55 +1,55 @@
@using Microsoft.Extensions.Options
@using OpenArchival.Blazor.Config
@using OpenArchival.Blazor.Theme
@inherits LayoutComponentBase
@*
For the login/logout
<AuthorizeView>
<Authorized>
<MudNavLink Href="Account/Manage" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.Person">@context.User.Identity?.Name</MudNavLink>
<form action="Account/Logout" method="post">
<AntiforgeryToken />
<input type="hidden" name="ReturnUrl" value="@currentUrl" />
<button type="submit" class="mud-nav-link mud-ripple">
<MudIcon Icon="@Icons.Material.Filled.Logout" Color="Color.Info" Class="mr-3"></MudIcon> Logout
</button>
</form>
</Authorized>
<NotAuthorized>
<MudNavLink Href="Account/Register" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.Person">Register</MudNavLink>
<MudNavLink Href="Account/Login" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.Password">Login</MudNavLink>
</NotAuthorized>
</AuthorizeView>
*@
@inject IOptions<ApplicationOptions> Options;
@inject NavigationManager NavigationManager;
<MudThemeProvider />
<MudThemeProvider Theme="AppThemeFactory.GetTheme()"/>
<MudPopoverProvider />
<MudDialogProvider />
<MudSnackbarProvider />
<MudLayout>
<MudLayout Style="min-height: 100vh; display: flex; flex-direction: column;">
<MudAppBar Elevation="1" >
@if (!string.IsNullOrEmpty(Options.Value.NavBarTitle)) {
<MudNavLink Href="/" Style="max-width:200px;">
<MudNavLink Href="/" Style="max-width:400px;">
<MudText Typo="Typo.h6" Class="ml-3">@Options.Value.NavBarTitle</MudText>
</MudNavLink>
}
<div class="d-flex justify-center align-center">
<MudSpacer/>
<div class="d-flex d-md-none">
<MudMenu Icon="@Icons.Material.Filled.Menu" Color="Color.Inherit" AnchorOrigin="Origin.BottomRight" TransformOrigin="Origin.TopRight">
<MudMenuItem Icon="@Icons.Material.Filled.Home" IconColor=Color.Secondary Href="/">Home</MudMenuItem>
<MudMenuItem Icon="@Icons.Material.Filled.Star" IconColor=Color.Secondary Href="/featured">Featured</MudMenuItem>
<MudMenuItem Icon="@Icons.Material.Filled.Search" IconColor=Color.Secondary Href="/search">Artifacts</MudMenuItem>
<MudMenuItem Icon=@Icons.Material.Filled.Book Href="/articles/search" IconColor=Color.Secondary>Articles</MudMenuItem>
<MudMenuItem Href="/about" Icon=@Icons.Material.Filled.QuestionMark IconColor="Color.Secondary">About</MudMenuItem>
</MudMenu>
</div>
<div class="justify-center align-center d-none d-md-flex gap-4">
<MudNavLink
Icon="@Icons.Material.Filled.Home"
Icon="@Icons.Material.Filled.Star"
IconColor=Color.Secondary
Ripple=true
Style="max-width:200px;"
Href="/featured">
Featured
</MudNavLink>
<MudNavLink
Icon="@Icons.Material.Filled.Search"
IconColor=Color.Secondary
Ripple=true
Style="max-width:200px;"
Href="/search">
Artifacts
</MudNavLink>
<MudNavLink Href="/articles/search" Icon=@Icons.Material.Filled.Book IconColor=Color.Secondary Ripple=true Style="max-width: 200px">
Articles
</MudNavLink>
@@ -57,34 +57,44 @@ For the login/logout
<MudNavLink Href="/about" Icon=@Icons.Material.Filled.QuestionMark IconColor="Color.Secondary" Ripple=true Style="max-width:200px;">
About
</MudNavLink>
<MudSpacer></MudSpacer>
<div style="background-color: white; border-radius:10px;" class="pa-2">
<MudAutocomplete
Placeholder="Search Archive"
T="string"
Variant="Variant.Filled | Variant.Outlined"
AdornmentIcon="@Icons.Material.Filled.Search"
Dense=true
Underline=false
Style="width:200px; --mud-input-text: white; --mud-input-label-text: white;"
OnKeyDown="OnSearchBarKeyDown"
SearchFunc="Search"
@bind-Text=_searchBarText/>
</div>
</div>
<MudSpacer></MudSpacer>
<div style="background-color: white; border-radius:10px;" class="pa-2">
<MudAutocomplete
Placeholder="Search Archive"
T="string"
Variant="Variant.Filled | Variant.Outlined"
AdornmentIcon="@Icons.Material.Filled.Search"
Dense=true
Underline=false
Style="width:200px; --mud-input-text: white; --mud-input-label-text: white;"
OnKeyDown="OnSearchBarKeyDown"
@bind-Text=_searchBarText/>
</div>
@*
<MudTextField
Placeholder="Search"
Variant="Variant.Filled"
Adornment="Adornment.Start"
AdornmentIcon="@Icons.Material.Filled.Search"
IconSize="Size.Medium"
T="string">
</MudTextField>*@
</MudAppBar>
</MudAppBar>
<MudMainContent Class="pt-16 pa-4">
@Body
</MudMainContent>
<MudPaper Elevation="0" Class="pa-8 mt-auto" Style="background-color: var(--mud-palette-appbar-background); color: var(--mud-palette-appbar-text); border-radius: 0;">
<MudContainer MaxWidth="MaxWidth.Large">
<MudGrid Justify="Justify.Center">
<MudItem xs="12" sm="8" Class="d-flex flex-wrap gap-4 justify-center justify-sm-start align-center">
<MudLink Href="/" Color="Color.Inherit">Home</MudLink>
<MudLink Href="/featured" Color="Color.Inherit">Featured</MudLink>
<MudLink Href="/search" Color="Color.Inherit">Artifacts</MudLink>
<MudLink Href="/articles/search" Color="Color.Inherit">Articles</MudLink>
<MudLink Href="/about" Color="Color.Inherit">About</MudLink>
</MudItem>
<MudItem xs="12" sm="4" Class="d-flex justify-center justify-sm-end align-center">
<a href="https://www.linkedin.com/in/vincenttallen/">Development by Vincent Allen</a>
</MudItem>
</MudGrid>
</MudContainer>
</MudPaper>
</MudLayout>
@@ -106,6 +116,11 @@ For the login/logout
_searchBarText = "";
}
}
private Task<IEnumerable<string>> Search(string value, CancellationToken token)
{
return Task.FromResult<IEnumerable<string>>([]);
}
}

View File

@@ -1,18 +0,0 @@
@page "/counter"
<PageTitle>Counter</PageTitle>
<MudText Typo="Typo.h3" GutterBottom="true">Counter</MudText>
<MudText Typo="Typo.body1" Class="mb-4">Current count: @currentCount</MudText>
<MudButton Color="Color.Primary" Variant="Variant.Filled" @onclick="IncrementCount">Click me</MudButton>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}

View File

@@ -1,35 +1,120 @@
@using Microsoft.Extensions.Options
@using Microsoft.EntityFrameworkCore
@using Microsoft.Extensions.Caching.Memory
@using Microsoft.Extensions.Options
@using OpenArchival.Blazor.Components.CustomComponents
@using OpenArchival.Blazor.Config;
@using OpenArchival.Blazor.Blog
@using OpenArchival.Blazor.ArchiveDisplay
@page "/"
<PageTitle>Home</PageTitle>
@if (string.IsNullOrEmpty(_htmlContent))
<style>
.banner-container {
position: relative;
width: calc(100% + 32px);
margin-left: -16px;
margin-right: -16px;
margin-top: -16px;
overflow: hidden;
}
.banner-container img {
width: 100% !important;
height: auto !important;
display: block;
}
.floating-buttons {
position: absolute;
bottom: 24px;
left: 0;
right: 0;
z-index: 10;
}
@@media (max-width: 600px) {
.floating-buttons {
position: static;
padding-top: 16px;
padding-bottom: 16px;
}
}
</style>
@if (_homePageConfig is null)
{
<p>Loading content...</p>
}
else
{
@((MarkupString)_htmlContent)
@if (_homePageConfig.HomePageBanner is not null)
{
<div class="banner-container">
<MudImage
ObjectPosition=ObjectPosition.Center
Src=@($"/api/files/{_homePageConfig.HomePageBanner.Id}/large")></MudImage>
<div class="floating-buttons">
<HomePageButtons></HomePageButtons>
</div>
</div>
<MudDivider></MudDivider>
}
else
{
<HomePageButtons></HomePageButtons>
}
@if (!string.IsNullOrEmpty(_homePageConfig.Content)) {
// Uses a custom CSS class to force the content to the width of the page regardless of what is in it
// ql-editor class tells the quill css that it should apply its classes in this div. Quill is used by the rich text editor this
// project uses
<div class="dynamic-content-container ql-editor">
@((MarkupString)_homePageConfig.Content)
</div>
}
<LatestBlogPostsSlider />
@if (_homePageConfig.SliderEntries != null)
{
@foreach (var sliderEntry in _homePageConfig.SliderEntries)
{
<SearchPageSlider SliderEntry="sliderEntry" />
}
}
}
@inject IOptions<ApplicationOptions> AppOptions;
@inject IMemoryCache MemoryCache;
@inject IDbContextFactory<ApplicationDbContext> ContextFactory;
@code {
private string _htmlContent = $"<h1>HTML file not found for homepage. Create one at /admin/homepageeditor</h1>";
private HomePageConfiguration? _homePageConfig = null;
protected override async void OnInitialized()
protected override async Task OnInitializedAsync()
{
try
_homePageConfig = await MemoryCache.GetOrCreateAsync(OpenArchivalConstants.HomePageConfigurationCacheKey, async entry =>
{
using var reader = new StreamReader(AppOptions.Value.HomepageContentLocation);
_htmlContent = await reader.ReadToEndAsync();
}
catch (Exception ex)
{
_htmlContent = $"<h1>HTML file not found for homepage. Create one at /admin/homepageeditor</h1>";
}
await using var context = await ContextFactory.CreateDbContextAsync();
HomePageConfiguration? config = await context.HomePageConfiguration
.Include(conf=>conf.HomePageBanner)
.Include(conf=>conf.SliderEntries)
.ThenInclude(se => se.FilterTags)
.FirstOrDefaultAsync();
if (config is null)
{
return new HomePageConfiguration() { Content = "Failed to load HomePageConfiguration from the database!" };
}
return config;
});
StateHasChanged();
}
}

View File

@@ -1,60 +0,0 @@
@page "/weather"
<PageTitle>Weather</PageTitle>
<MudText Typo="Typo.h3" GutterBottom="true">Weather forecast</MudText>
<MudText Typo="Typo.body1" Class="mb-8">This component demonstrates fetching data from the server.</MudText>
@if (forecasts == null)
{
<MudProgressCircular Color="Color.Default" Indeterminate="true" />
}
else
{
<MudTable Items="forecasts" Hover="true" SortLabel="Sort By" Elevation="0" AllowUnsorted="false">
<HeaderContent>
<MudTh><MudTableSortLabel InitialDirection="SortDirection.Ascending" SortBy="new Func<WeatherForecast, object>(x=>x.Date)">Date</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<WeatherForecast, object>(x=>x.TemperatureC)">Temp. (C)</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<WeatherForecast, object>(x=>x.TemperatureF)">Temp. (F)</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<WeatherForecast, object>(x=>x.Summary!)">Summary</MudTableSortLabel></MudTh>
</HeaderContent>
<RowTemplate>
<MudTd DataLabel="Date">@context.Date</MudTd>
<MudTd DataLabel="Temp. (C)">@context.TemperatureC</MudTd>
<MudTd DataLabel="Temp. (F)">@context.TemperatureF</MudTd>
<MudTd DataLabel="Summary">@context.Summary</MudTd>
</RowTemplate>
<PagerContent>
<MudTablePager PageSizeOptions="new int[]{50, 100}" />
</PagerContent>
</MudTable>
}
@code {
private WeatherForecast[]? forecasts;
protected override async Task OnInitializedAsync()
{
// Simulate asynchronous loading to demonstrate a loading indicator
await Task.Delay(500);
var startDate = DateOnly.FromDateTime(DateTime.Now);
var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" };
forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = startDate.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = summaries[Random.Shared.Next(summaries.Length)]
}).ToArray();
}
private class WeatherForecast
{
public DateOnly Date { get; set; }
public int TemperatureC { get; set; }
public string? Summary { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
}