Merge pull request #9 from bdfin/about-page-coming-soon
Add coming soon to about page
This commit is contained in:
@@ -1,25 +0,0 @@
|
||||
using System.Net;
|
||||
using Microsoft.Azure.Functions.Worker;
|
||||
using Microsoft.Azure.Functions.Worker.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace BeauFindlay.Api
|
||||
{
|
||||
public class Function1(ILoggerFactory loggerFactory)
|
||||
{
|
||||
private readonly ILogger _logger = loggerFactory.CreateLogger<Function1>();
|
||||
|
||||
[Function("Function1")]
|
||||
public HttpResponseData Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req)
|
||||
{
|
||||
_logger.LogInformation("C# HTTP trigger function processed a request.");
|
||||
|
||||
var response = req.CreateResponse(HttpStatusCode.OK);
|
||||
response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
|
||||
|
||||
response.WriteString("Welcome to Azure Functions!");
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<a href="@Href"
|
||||
target="@Target"
|
||||
class="underline underline-offset-2">
|
||||
@ChildContent
|
||||
</a>
|
||||
|
||||
@code {
|
||||
|
||||
[Parameter]
|
||||
public string Href { get; set; } = string.Empty;
|
||||
|
||||
[Parameter]
|
||||
public string Target { get; set; } = "_blank";
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment? ChildContent { get; set; }
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
<footer class="mt-auto fade-in">
|
||||
<footer class="mt-auto">
|
||||
<div class="mx-auto py-8 px-4 md:px-12">
|
||||
<div class="md:flex md:items-center md:justify-between">
|
||||
<div class="flex space-x-6 md:order-2">
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
@inherits LayoutComponentBase
|
||||
|
||||
<div class="flex flex-col min-h-screen">
|
||||
<div class="flex flex-col min-h-screen fade-in">
|
||||
<NavBar/>
|
||||
|
||||
<div class="px-4 md:px-12 py-4">
|
||||
<div class="flex-1 px-4 md:px-12 py-4">
|
||||
@Body
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<nav class="flex items-center justify-center py-12 space-x-8 fade-in">
|
||||
<nav class="flex items-center justify-center py-12 space-x-8">
|
||||
<NavLink href="/" Match="NavLinkMatch.All" ActiveClass="border-l-2 border-r-2 px-2 rounded">
|
||||
Home
|
||||
</NavLink>
|
||||
|
||||
@@ -2,49 +2,60 @@
|
||||
|
||||
@inject IJSRuntime JSRuntime
|
||||
|
||||
@if (!hasPreviouslyRendered)
|
||||
@if (comingSoon)
|
||||
{
|
||||
<h1 class="text-4xl">
|
||||
<Typewriter Text="This app"/>
|
||||
</h1>
|
||||
<div class="text-center">
|
||||
<h1 class="text-4xl">Coming soon...</h1>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<h1 class="text-4xl">This app<span class="blinking-cursor">|</span></h1>
|
||||
@if (!hasPreviouslyRendered)
|
||||
{
|
||||
<h1 class="text-4xl">
|
||||
<Typewriter Text="This app"/>
|
||||
</h1>
|
||||
}
|
||||
else
|
||||
{
|
||||
<h1 class="text-4xl">This app<span class="blinking-cursor">|</span></h1>
|
||||
}
|
||||
|
||||
<p class="py-4 text-xl">Below is a brief outline of how this app is made and what technologies are used. If you'd like to dive straight in then full project is available on my <Anchor Href="https://github.com/bdfin/my-portfolio">GitHub</Anchor>.</p>
|
||||
|
||||
<section class="py-6" id="@FrontEndSection">
|
||||
<h2 class="text-2xl">Front-end</h2>
|
||||
|
||||
<p class="py-4">I wanted to create a decent, modern client-side experience for this app and given my <em class="text-xs">(very...)</em> limited front-end expertise I decided to choose <Anchor Href="https://dotnet.microsoft.com/en-us/apps/aspnet/web-apps/blazor">.NET Blazor Webassembly</Anchor>. Blazor is Microsoft's take on component-based SPAs (single page applications) and offers us back-end focussed devs a way of producing decent client experiences without needing to dive into another front-end specific technology.</p>
|
||||
|
||||
<p class="py-4">Blazor traditionally came in two flavours, server and webassembly with an additional third option (Blazor Web App) recently released with .NET 8 which is an amalgamation of both. <Anchor Href="https://learn.microsoft.com/en-us/aspnet/core/blazor/hosting-models?view=aspnetcore-8.0#blazor-server">Blazor Server</Anchor> initially generates content on the server and utilises web-sockets to communicate dynamic UI updates with the client without requiring a page load, whereas <Anchor Href="https://learn.microsoft.com/en-us/aspnet/core/blazor/hosting-models?view=aspnetcore-8.0#blazor-webassembly">Blazor Webassembly</Anchor> downloads the entire app to the client browser on first load alongside a light-weight .NET run-time to execute code directly on the browsers UI thread.</p>
|
||||
|
||||
<p class="py-4">As Blazor server requires a dedicated server to host the application, I chose Blazor webassembly to enable me to host this app for free using an <Anchor Href="https://azure.microsoft.com/en-gb/products/app-service/static">Azure Static Web App</Anchor>. You can read more about this in the <a @onclick="() => ScrollToElementAsync(HostingSection)" class="underline underline-offset-2 cursor-pointer">hosting</a> section.</p>
|
||||
</section>
|
||||
|
||||
<section class="py-6" id="@BackEndSection">
|
||||
<h2 class="text-2xl pb-4">Back-end</h2>
|
||||
<p class="my-4">As the </p>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="py-6" id="@HostingSection">
|
||||
<h2 class="text-2xl pb-4">Hosting</h2>
|
||||
<p></p>
|
||||
</section>
|
||||
}
|
||||
|
||||
<p class="py-4 text-xl">Below is a brief outline of how this app is made and what technologies are used. If you'd like to dive straight in then full project is available on my <a href="https://github.com/bdfin/my-portfolio" target="_blank" class="underline underline-offset-2">GitHub</a>.</p>
|
||||
|
||||
<section class="py-6" id="@FrontEndSection">
|
||||
<h2 class="text-2xl">Front-end</h2>
|
||||
|
||||
<p class="py-4">I wanted to create a decent, modern client-side experience for this app and given my <em class="text-xs">(very...)</em> limited front-end expertise I decided to choose <a href="https://dotnet.microsoft.com/en-us/apps/aspnet/web-apps/blazor" target="_blank" class="underline underline-offset-2">.NET Blazor Webassembly</a>. Blazor is Microsoft's take on component-based SPAs (single page applications) and offers us back-end focussed devs a way of producing decent client experiences without needing to dive into another front-end specific technology.</p>
|
||||
|
||||
<p class="py-4">Blazor traditionally came in two flavours, server and webassembly with an additional third option (Blazor Web App) recently released with .NET 8 which is an amalgamation of both. <a href="https://learn.microsoft.com/en-us/aspnet/core/blazor/hosting-models?view=aspnetcore-8.0#blazor-server" target="_blank" class="underline underline-offset-2">Blazor Server</a> initially generates content on the server and utilises web-sockets to communicate dynamic UI updates with the client without requiring a page load, whereas <a href="https://learn.microsoft.com/en-us/aspnet/core/blazor/hosting-models?view=aspnetcore-8.0#blazor-webassembly" target="_blank" class="underline underline-offset-2">Blazor Webassembly</a> downloads the entire app to the client browser on first load alongside a light-weight .NET run-time to execute code directly on the browsers UI thread.</p>
|
||||
|
||||
<p class="py-4">As Blazor server requires a dedicated server to host the application, I chose Blazor webassembly to enable me to host this app for free using an <a href="https://azure.microsoft.com/en-gb/products/app-service/static" target="_blank" class="underline underline-offset-2">Azure Static Web App</a>. You can read more about this in the <a @onclick="() => ScrollToElementAsync(HostingSection)" class="underline underline-offset-2 cursor-pointer">hosting</a> section.</p>
|
||||
</section>
|
||||
|
||||
<section class="py-6" id="@BackEndSection">
|
||||
<h2 class="text-2xl pb-4">Back-end</h2>
|
||||
<p class="my-4">As the </p>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="py-6" id="@HostingSection">
|
||||
<h2 class="text-2xl pb-4">Hosting</h2>
|
||||
<p></p>
|
||||
</section>
|
||||
|
||||
<AnchorNavigation />
|
||||
<AnchorNavigation/>
|
||||
|
||||
@code {
|
||||
private const string ComponentKey = "ComponentRendered_About";
|
||||
private const string ComponentKey = "ComponentRendered_About";
|
||||
private const string FrontEndSection = "front-end";
|
||||
private const string BackEndSection = "back-end";
|
||||
private const string HostingSection = "hosting";
|
||||
|
||||
private bool hasPreviouslyRendered;
|
||||
private bool comingSoon = true;
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
@@ -71,4 +82,5 @@ else
|
||||
{
|
||||
await JSRuntime.InvokeVoidAsync("scrollToElement", elementId);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,8 +1,7 @@
|
||||
@page "/contact"
|
||||
@using BeauFindlay.Shared.Contracts
|
||||
|
||||
@inject HttpClient HttpClient
|
||||
@inject IJSRuntime JsRuntime
|
||||
@inject IJSRuntime JSRuntime
|
||||
|
||||
<div class="text-center">
|
||||
<h1 class="text-4xl">Contact</h1>
|
||||
@@ -12,7 +11,7 @@
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="mx-auto max-w-xl pt-10 pb-4">
|
||||
<div class="mx-auto max-w-xl pt-8 pb-4">
|
||||
<EditForm Model="contactInput" OnValidSubmit="HandleValidSubmit">
|
||||
<DataAnnotationsValidator/>
|
||||
|
||||
@@ -20,14 +19,14 @@
|
||||
<div class="sm:col-span-2">
|
||||
<label for="name" class="block font-semibold leading-6">Name</label>
|
||||
<div class="mt-2.5">
|
||||
<InputText id="name" @bind-Value="contactInput.Name" class="block w-full text-lg border-0 px-3.5 py-2 bg-black shadow ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-gray-600"/>
|
||||
<InputText id="name" @bind-Value="contactInput.Name" class="block w-full text-lg border-0 px-3.5 py-2 bg-black shadow ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-gray-600" autocomplete="given-name"/>
|
||||
<ValidationMessage For="() => contactInput.Name" class="text-red-600"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sm:col-span-2">
|
||||
<label for="email" class="block font-semibold leading-6">Email</label>
|
||||
<div class="mt-2.5">
|
||||
<InputText id="email" @bind-Value="contactInput.Email" class="block w-full text-lg border-0 px-3.5 py-2 bg-black shadow ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-gray-600"/>
|
||||
<InputText id="email" @bind-Value="contactInput.Email" class="block w-full text-lg border-0 px-3.5 py-2 bg-black shadow ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-gray-600" autocomplete="email"/>
|
||||
<ValidationMessage For="() => contactInput.Email" class="text-red-600"/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -39,7 +38,10 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-8 flex items-center justify-center">
|
||||
<div class="mt-4">
|
||||
<small>This site is protected by reCAPTCHA and the Google <Anchor Href="https://policies.google.com/privacy" Target="_blank">Privacy Policy</Anchor> and <Anchor Href="https://policies.google.com/terms" Target="_blank">Terms of Service</Anchor> apply.</small>
|
||||
</div>
|
||||
<div class="mt-4 flex items-center justify-center">
|
||||
<Button Type="submit" IsLoading="@isSubmitting">
|
||||
<i class="fa-solid fa-paper-plane"></i> Send
|
||||
</Button>
|
||||
@@ -66,10 +68,6 @@
|
||||
</div>
|
||||
}
|
||||
|
||||
<script src="https://www.google.com/recaptcha/api.js?render=6LcvxZIpAAAAAOIP5L6kGngwDZRpwkTdMezPn06x" async
|
||||
defer></script>
|
||||
<script src="js/recaptcha.js"></script>
|
||||
|
||||
@code {
|
||||
private readonly ContactInputModel contactInput = new();
|
||||
|
||||
@@ -96,7 +94,7 @@
|
||||
{
|
||||
isSubmitting = true;
|
||||
|
||||
var recaptchaResponse = await JsRuntime.InvokeAsync<string>("executeRecaptcha");
|
||||
var recaptchaResponse = await JSRuntime.InvokeAsync<string>("executeRecaptcha");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(recaptchaResponse))
|
||||
{
|
||||
|
||||
@@ -25,12 +25,12 @@
|
||||
</p>
|
||||
|
||||
<p class="text-xl mt-4">
|
||||
<Typewriter Text="I'm currently heading up the tech as CTO at a cool startup called un:hurd."/>
|
||||
<Typewriter Text="I've worked with businesses at all sizes and stages and I'm currently heading up the tech as CTO at a cool startup called un:hurd."/>
|
||||
</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<h1 class="text-4xl">Hi, I'm Beau.<span class="blinking-cursor">|</span></h1>
|
||||
<h1 class="text-4xl">Hi, I'm Beau.</h1>
|
||||
|
||||
<p class="text-xl mt-4">I'm a UK-based software engineer and I love building cool stuff.</p>
|
||||
|
||||
@@ -38,7 +38,7 @@ else
|
||||
|
||||
<p class="text-xl mt-4">I mostly specialise in back-end C#/.NET development and I've built systems that scale for hundreds-of-thousands of global users.</p>
|
||||
|
||||
<p class="text-xl mt-4">I'm currently heading up the tech as CTO at a cool startup called <a href="https://unhurd.co.uk" target="_blank" class="underline">un:hurd</a>.</p>
|
||||
<p class="text-xl mt-4">I've worked with businesses at all sizes and stages and I'm currently heading up the tech as CTO at a cool startup called <Anchor Href="https://unhurd.co.uk">un:hurd</Anchor>.</p>
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
@using BeauFindlay.Client
|
||||
@using BeauFindlay.Client.Layout
|
||||
@using BeauFindlay.Client.Components.Alert
|
||||
@using BeauFindlay.Client.Components.Anchor
|
||||
@using BeauFindlay.Client.Components.Typewriter
|
||||
@using BeauFindlay.Client.Components.Button
|
||||
@using BeauFindlay.Client.Components.LoadingSpinner
|
||||
@using BeauFindlay.Shared.Contracts
|
||||
@@ -12,7 +12,7 @@
|
||||
}
|
||||
|
||||
.fade-in {
|
||||
animation: fadeInAnimation ease 6s;
|
||||
animation: fadeInAnimation ease 3s;
|
||||
animation-iteration-count: 1;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
@@ -21,3 +21,20 @@
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
.grecaptcha-badge {
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
body::-webkit-scrollbar {
|
||||
width: 14px;
|
||||
}
|
||||
|
||||
body::-webkit-scrollbar-track {
|
||||
background: white;
|
||||
}
|
||||
|
||||
body::-webkit-scrollbar-thumb {
|
||||
background-color: black;
|
||||
border: 1px solid white;
|
||||
}
|
||||
@@ -666,6 +666,10 @@ video {
|
||||
max-width: 36rem;
|
||||
}
|
||||
|
||||
.flex-1 {
|
||||
flex: 1 1 0%;
|
||||
}
|
||||
|
||||
.flex-shrink-0 {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
@@ -809,8 +813,8 @@ video {
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.pt-10 {
|
||||
padding-top: 2.5rem;
|
||||
.pt-8 {
|
||||
padding-top: 2rem;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
@@ -965,7 +969,7 @@ video {
|
||||
}
|
||||
|
||||
.fade-in {
|
||||
animation: fadeInAnimation ease 6s;
|
||||
animation: fadeInAnimation ease 3s;
|
||||
animation-iteration-count: 1;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
@@ -980,6 +984,23 @@ video {
|
||||
}
|
||||
}
|
||||
|
||||
.grecaptcha-badge {
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
body::-webkit-scrollbar {
|
||||
width: 14px;
|
||||
}
|
||||
|
||||
body::-webkit-scrollbar-track {
|
||||
background: white;
|
||||
}
|
||||
|
||||
body::-webkit-scrollbar-thumb {
|
||||
background-color: black;
|
||||
border: 1px solid white;
|
||||
}
|
||||
|
||||
.placeholder\:text-gray-400::-moz-placeholder {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(156 163 175 / var(--tw-text-opacity));
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
</div>
|
||||
<script src="js/smoothScroll.js"></script>
|
||||
<script src="_framework/blazor.webassembly.js"></script>
|
||||
<script src="https://www.google.com/recaptcha/api.js?render=6LcvxZIpAAAAAOIP5L6kGngwDZRpwkTdMezPn06x" async
|
||||
defer></script>
|
||||
<script src="js/recaptcha.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user