diff --git a/src/Client/src/components/AboutTabs.tsx b/src/Client/src/components/AboutTabs.tsx
index 0ae4fbd..8bf1a75 100644
--- a/src/Client/src/components/AboutTabs.tsx
+++ b/src/Client/src/components/AboutTabs.tsx
@@ -1,7 +1,158 @@
import { Tab } from "@headlessui/react";
-import { Fragment } from "react";
-import Subtitle from "./Subtitle";
+import { Fragment, ReactNode } from "react";
+import { SiAzurefunctions, SiMicrosoftazure, SiReact } from "react-icons/si";
+import { Link } from "react-router-dom";
import buildClassNames from "../helpers/cssClassFormatter";
+import AnchorLink from "./AnchorLink";
+import List from "./List";
+import ListItem from "./ListItem";
+import Subtitle from "./Subtitle";
+import Text from "./Text";
+
+interface AboutTab {
+ tabName: string;
+ title: ReactNode;
+ subtitle: string;
+ content: ReactNode[];
+}
+
+const tabs: AboutTab[] = [
+ {
+ tabName: "Front-end",
+ title: (
+
+ Front-end
+
+ ),
+ subtitle: "React + TypeScript",
+ content: [
+
+ This app was originally made using{" "}
+
+ .NET Blazor WASM
+ {" "}
+ however I recently decided to start learning{" "}
+ React and saw this as
+ a good oppurtunity to solidify some knowledge by re-writing this app
+ from the ground up using React with{" "}
+
+ TypeScript
+
+ .
+ ,
+
+ Overall I've found building front-end apps far more enjoyable using
+ React & TypeScript dispite the steep learning-curve coming from a purely
+ .NET & C# background. Both the developer experience and performance of
+ the app have improved dramatically after switching front-end
+ technologies.
+ ,
+
+ This app is styled using a cool CSS framework called{" "}
+ TailwindCSS.{" "}
+ PostCSS is used
+ alongside Tailwind to generate a lightweight stylesheet based only on
+ the parts of the framework that are used, as oppose to including a
+ everything the framework offers.
+ ,
+ ],
+ },
+ {
+ tabName: "Back-end",
+ title: (
+
+ Back-end
+
+ ),
+ subtitle: ".NET Azure Functions API",
+ content: [
+
+ There is a very minimal API used as the back-end of this app to allow
+ users to contact me directly via the{" "}
+
+ contact
+ {" "}
+ page. This will be expanded to serve the technical blog I'm building as
+ a new feature that will be available soon.
+ ,
+ The contact API endpoint currently:,
+
+
+ Validates a{" "}
+
+ Google reCAPTCHA
+ {" "}
+ token to protect against fraudulent submissions.
+
+
+ Builds a HTML email from the information provided in the form.
+
+
+ Sends an email directly to my inbox using the{" "}
+ SendGrid{" "}
+ API.
+
+ ,
+
+ The API is written in .NET 8 using{" "}
+
+ Azure Serverless Functions
+ {" "}
+ with a HTTP trigger to act as an API endpoint. For larger scale projects
+ I would almost always opt for a fully-featured{" "}
+
+ Web API
+
+ , however Azure Functions provide automatic elastic scaling with
+ consumption-based billing and a generous free-tier, making them perfect
+ for smaller projects like this.
+ ,
+ ],
+ },
+ {
+ tabName: "Hosting",
+ title: (
+
+ Hosting
+
+ ),
+ subtitle: "Microsoft Azure Static Web App",
+ content: [
+
+ The goal of this project was to learn some new technologies and host the
+ app as cheaply as possible. With this in mind I decided to go with a{" "}
+
+ Static Web App
+ {" "}
+ hosted on Microsoft Azure. Static Web Apps offer global distribution of
+ static assets (the Blazor Webassembly app in this case) and offer
+ integrated hosting for Azure Function App APIs.
+ ,
+
+ Another cool feature of Static Web Apps is Azure's integration with
+ GitHub actions to deploy both the client and server simultaneously and
+ provide automatically deployed staging environments for pull-requests
+ opened to the main branch. This made testing deployed changes much
+ easier and cheaper than deploying an isolated testing/GA environment
+ before releasing to the live version of the app.
+ ,
+
+ Using Static Web Apps on Azure has meant that I have been able to build,
+ deploy and serve this site and API completely free (with the exception
+ of the domain name). The next thing on the roadmap is building a simple
+ blog using an{" "}
+
+ Azure SQL database
+ {" "}
+ where I'll document the full process of writing and deploying this app
+ so check back again soon.
+ ,
+ ],
+ },
+];
export default function AboutTabs() {
return (
@@ -9,56 +160,35 @@ export default function AboutTabs() {
;
diff --git a/src/Client/src/pages/AboutPage.tsx b/src/Client/src/pages/AboutPage.tsx
index e293c9b..2cd3277 100644
--- a/src/Client/src/pages/AboutPage.tsx
+++ b/src/Client/src/pages/AboutPage.tsx
@@ -1,5 +1,5 @@
import AboutTabs from "../components/AboutTabs";
-import Link from "../components/Link";
+import AnchorLink from "../components/AnchorLink";
import Text from "../components/Text";
import Title from "../components/Title";
@@ -11,7 +11,10 @@ export default function AboutPage() {
Below is an overview of how this simple app is made and what
technologies are used. If you'd like to dive straight in, the full
project is available on my{" "}
- GitHub.
+
+ GitHub
+
+ .
I'm planning to integrate a simple blog as part of this app that will
diff --git a/src/Client/src/pages/HomePage.tsx b/src/Client/src/pages/HomePage.tsx
index 9be6c7f..dc9b4db 100644
--- a/src/Client/src/pages/HomePage.tsx
+++ b/src/Client/src/pages/HomePage.tsx
@@ -1,4 +1,4 @@
-import Link from "../components/Link";
+import AnchorLink from "../components/AnchorLink";
import Subtitle from "../components/Subtitle";
import Text from "../components/Text";
import Title from "../components/Title";
@@ -19,7 +19,7 @@ export default function HomePage() {
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 music.
+ un:hurd music.
>
);