Resolve "Navigation" #19

Merged
leon.hoppe merged 3 commits from feature/navigation into dev 2025-01-21 16:36:00 +01:00
7 changed files with 87 additions and 2 deletions
Showing only changes of commit 5b16cda8ea - Show all commits

View File

@@ -75,7 +75,6 @@ await using (var scope = app.Services.CreateAsyncScope()) {
await db.Database.EnsureCreatedAsync();
}
app.UseHttpsRedirection();
app.MapDefaultEndpoints();
app.MapControllers();

View File

@@ -0,0 +1,11 @@
using Microsoft.AspNetCore.Components;
namespace Portfolio.Web.Components;
public class CancellableComponent : ComponentBase, IDisposable {
protected CancellationTokenSource TokenSource { get; } = new();
public void Dispose() {
TokenSource.Dispose();
}
}

View File

@@ -1,4 +1,6 @@
using Portfolio.Shared.Services;
using Portfolio.Web.Components;
using Portfolio.Web.Services;
var builder = WebApplication.CreateBuilder(args);
@@ -8,6 +10,15 @@ builder.Services.AddRazorComponents()
builder.AddServiceDefaults();
builder.Services.AddScoped<IProjectRepository, ProjectRepository>();
builder.Services.AddScoped<ITechnologyRepository, TechnologyRepository>();
builder.Services.AddScoped<ITimelineRepository, TimelineRepository>();
builder.Services.AddScoped<IAboutRepository, AboutRepository>();
builder.Services.AddHttpClient("api", client => {
client.BaseAddress = new Uri("http://api");
});
var app = builder.Build();
// Configure the HTTP request pipeline.
@@ -17,7 +28,6 @@ if (!app.Environment.IsDevelopment()) {
app.UseHsts();
}
app.UseHttpsRedirection();
app.MapDefaultEndpoints();
app.UseAntiforgery();

View File

@@ -0,0 +1,20 @@
using Portfolio.Shared.Models;
using Portfolio.Shared.Services;
namespace Portfolio.Web.Services;
internal sealed class AboutRepository(IHttpClientFactory factory) : IAboutRepository {
private About DefaultValue => new() {
AboutMe = string.Empty,
Future = string.Empty
};
public async Task<About> GetAbout(CancellationToken ct) {
var client = factory.CreateClient("api");
var response = await client.GetAsync("api/about", ct);
if (!response.IsSuccessStatusCode) return DefaultValue;
var data = await response.Content.ReadFromJsonAsync<About>(ct);
return data ?? DefaultValue;
}
}

View File

@@ -0,0 +1,15 @@
using Portfolio.Shared.Models;
using Portfolio.Shared.Services;
namespace Portfolio.Web.Services;
internal sealed class ProjectRepository(IHttpClientFactory factory) : IProjectRepository {
public async Task<IEnumerable<Project>> GetProjects(CancellationToken ct) {
var client = factory.CreateClient("api");
var response = await client.GetAsync("api/projects", ct);
if (!response.IsSuccessStatusCode) return [];
var data = await response.Content.ReadFromJsonAsync<IEnumerable<Project>>(ct);
return data ?? [];
}
}

View File

@@ -0,0 +1,15 @@
using Portfolio.Shared.Models;
using Portfolio.Shared.Services;
namespace Portfolio.Web.Services;
internal sealed class TechnologyRepository(IHttpClientFactory factory) : ITechnologyRepository {
public async Task<IEnumerable<Technology>> GetTechnologies(CancellationToken ct) {
var client = factory.CreateClient("api");
var response = await client.GetAsync("api/technologies", ct);
if (!response.IsSuccessStatusCode) return [];
var data = await response.Content.ReadFromJsonAsync<IEnumerable<Technology>>(ct);
return data ?? [];
}
}

View File

@@ -0,0 +1,15 @@
using Portfolio.Shared.Models;
using Portfolio.Shared.Services;
namespace Portfolio.Web.Services;
internal sealed class TimelineRepository(IHttpClientFactory factory) : ITimelineRepository {
public async Task<IEnumerable<TimelineEntry>> GetTimeline(TimelineEntryType type, CancellationToken ct) {
var client = factory.CreateClient("api");
var result = await client.GetAsync($"api/timeline/{type}", ct);
if (!result.IsSuccessStatusCode) return [];
var data = await result.Content.ReadFromJsonAsync<IEnumerable<TimelineEntry>>(ct);
return data ?? [];
}
}