diff --git a/src/Portfolio.Api/Program.cs b/src/Portfolio.Api/Program.cs index e093629..cdef3e7 100644 --- a/src/Portfolio.Api/Program.cs +++ b/src/Portfolio.Api/Program.cs @@ -75,7 +75,6 @@ await using (var scope = app.Services.CreateAsyncScope()) { await db.Database.EnsureCreatedAsync(); } -app.UseHttpsRedirection(); app.MapDefaultEndpoints(); app.MapControllers(); diff --git a/src/Portfolio.Web/Components/CancellableComponent.cs b/src/Portfolio.Web/Components/CancellableComponent.cs new file mode 100644 index 0000000..a2aab92 --- /dev/null +++ b/src/Portfolio.Web/Components/CancellableComponent.cs @@ -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(); + } +} \ No newline at end of file diff --git a/src/Portfolio.Web/Program.cs b/src/Portfolio.Web/Program.cs index d82cbbf..6ab644c 100644 --- a/src/Portfolio.Web/Program.cs +++ b/src/Portfolio.Web/Program.cs @@ -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(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); + +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(); diff --git a/src/Portfolio.Web/Services/AboutRepository.cs b/src/Portfolio.Web/Services/AboutRepository.cs new file mode 100644 index 0000000..e666782 --- /dev/null +++ b/src/Portfolio.Web/Services/AboutRepository.cs @@ -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 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(ct); + return data ?? DefaultValue; + } +} \ No newline at end of file diff --git a/src/Portfolio.Web/Services/ProjectRepository.cs b/src/Portfolio.Web/Services/ProjectRepository.cs new file mode 100644 index 0000000..eccefc4 --- /dev/null +++ b/src/Portfolio.Web/Services/ProjectRepository.cs @@ -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> 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>(ct); + return data ?? []; + } +} \ No newline at end of file diff --git a/src/Portfolio.Web/Services/TechnologyRepository.cs b/src/Portfolio.Web/Services/TechnologyRepository.cs new file mode 100644 index 0000000..d723a6d --- /dev/null +++ b/src/Portfolio.Web/Services/TechnologyRepository.cs @@ -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> 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>(ct); + return data ?? []; + } +} \ No newline at end of file diff --git a/src/Portfolio.Web/Services/TimelineRepository.cs b/src/Portfolio.Web/Services/TimelineRepository.cs new file mode 100644 index 0000000..0057e61 --- /dev/null +++ b/src/Portfolio.Web/Services/TimelineRepository.cs @@ -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> 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>(ct); + return data ?? []; + } +} \ No newline at end of file