Files
Htmx/Htmx.ApiDemo/Templates/MainLayout.htmx.cs
T

90 lines
4.0 KiB
C#

using Htmx.ApiDemo;
using Htmx.ApiDemo.Templates.Components;
using Immediate.Apis.Shared;
using Immediate.Handlers.Shared;
using Microsoft.AspNetCore.Http;
namespace Htmx.ApiDemo.Templates;
public sealed class MainLayout : MainLayoutBase
{
private byte[] _titleData = [];
private byte[] _appNameData = [];
private byte[] _pageTitleData = [];
private byte[] _userSectionData = [];
public IHtmxComponent Body { get; }
public MainLayout(IHtmxComponent body, string title = "App", string appName = "MyApp",
string pageTitle = "Dashboard", string? userName = null, string? afToken = null)
{
Body = body;
_titleData = title.ToUtf8Bytes();
_appNameData = appName.ToUtf8Bytes();
_pageTitleData = pageTitle.ToUtf8Bytes();
var afInput = string.IsNullOrEmpty(afToken)
? ""
: $"""<input type="hidden" name="__RequestVerificationToken" value="{System.Web.HttpUtility.HtmlAttributeEncode(afToken)}" />""";
_userSectionData = userName is not null
? $"""
<div class="flex items-center gap-2">
<div class="flex h-9 w-9 items-center justify-center rounded-full bg-primary text-primary-foreground text-sm font-semibold select-none" title="{System.Web.HttpUtility.HtmlAttributeEncode(userName)}">
{System.Web.HttpUtility.HtmlEncode(GetInitials(userName))}
</div>
<form method="post" action="/logout">
{afInput}
<button type="submit"
class="inline-flex h-8 items-center rounded-md border border-input bg-transparent px-3 text-xs
font-medium transition-colors hover:bg-accent hover:text-accent-foreground
focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring">
Sign out
</button>
</form>
</div>
""".ToUtf8Bytes()
: """
<a href="/login"
class="inline-flex h-8 items-center rounded-md border border-input bg-transparent px-3 text-xs
font-medium transition-colors hover:bg-accent hover:text-accent-foreground
focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring">
Sign in
</a>
""".ToUtf8Bytes();
}
private static string GetInitials(string name)
{
var parts = name.Trim().Split(' ', System.StringSplitOptions.RemoveEmptyEntries);
return parts.Length >= 2
? $"{parts[0][0]}{parts[^1][0]}".ToUpperInvariant()
: name.Length > 0 ? name[0].ToString().ToUpperInvariant() : "?";
}
protected override void RenderBody(HtmxRenderContext context) => Body.Render(context);
protected override void RenderTitle(HtmxRenderContext context) => context.Writer.WriteUtf8(_titleData);
protected override void RenderAppName(HtmxRenderContext context) => context.Writer.WriteUtf8(_appNameData);
protected override void RenderPageTitle(HtmxRenderContext context) => context.Writer.WriteUtf8(_pageTitleData);
protected override void RenderUserSection(HtmxRenderContext context) => context.Writer.WriteUtf8(_userSectionData);
}
[Handler]
[MapGet("/")]
public static partial class GetIndexHandler
{
public class Command;
private static ValueTask<IResult> HandleAsync(
Command command,
IHttpContextAccessor httpContextAccessor,
CancellationToken token)
{
var context = httpContextAccessor.HttpContext
?? throw new InvalidOperationException("HttpContext is not available.");
var greet = new Greeting { Username = "Enciphered", Count = 0, GreetingId = Guid.NewGuid() };
return ValueTask.FromResult<IResult>(context.WriteHtmxPage(greet, title: "Home", appName: "HtmxApp", pageTitle: "Home"));
}
}