+
Blog Posts
+
diff --git a/src/src/content/blog/generics-with-typescript.mdx b/src/src/content/blog/generics-with-typescript.mdx
index aea8485..21d76e4 100644
--- a/src/src/content/blog/generics-with-typescript.mdx
+++ b/src/src/content/blog/generics-with-typescript.mdx
@@ -4,6 +4,7 @@ description: A quick introduction to generics with TypeScript
author: Timothy Pidashev
tags: [typescript]
date: December 25, 2021
+image: "/path/to/your/image.jpg"
---
In this quick post we'll cover what are generics and how to use them with TypeScript. It answers a question I got from a friend, and I thought it could also be useful for others. We'll go through the following points:
diff --git a/src/src/content/config.ts b/src/src/content/config.ts
index 8eed5f2..0cef474 100644
--- a/src/src/content/config.ts
+++ b/src/src/content/config.ts
@@ -8,6 +8,7 @@ export const collections = {
author: z.string(),
tags: z.array(z.string()),
date: z.string(),
+ image: z.string().optional(),
}),
}),
projects: defineCollection({
diff --git a/src/src/content/darkbox.mdx b/src/src/content/darkbox.mdx
new file mode 100644
index 0000000..3e113bd
--- /dev/null
+++ b/src/src/content/darkbox.mdx
@@ -0,0 +1 @@
+My gruvbox theme, with a pure black background
diff --git a/src/src/content/fhccenter.mdx b/src/src/content/fhccenter.mdx
new file mode 100644
index 0000000..e69de29
diff --git a/src/src/content/iridescent.mdx b/src/src/content/iridescent.mdx
new file mode 100644
index 0000000..e69de29
diff --git a/src/src/content/projects/ai-code-reviewer.mdx b/src/src/content/projects/ai-code-reviewer.mdx
deleted file mode 100644
index 929f379..0000000
--- a/src/src/content/projects/ai-code-reviewer.mdx
+++ /dev/null
@@ -1,9 +0,0 @@
----
-title: "AI Code Review Assistant"
-description: "An AI-powered code review tool that integrates with GitHub to provide automated code analysis and suggestions"
-githubUrl: "https://github.com/username/ai-code-reviewer"
-techStack: ["Python", "OpenAI API", "GitHub API", "FastAPI"]
-date: "2024-02-28"
-image: "/projects/ai-reviewer-preview.png"
----
-
diff --git a/src/src/content/projects/embedded-rust.mdx b/src/src/content/projects/embedded-rust.mdx
deleted file mode 100644
index b26b2dc..0000000
--- a/src/src/content/projects/embedded-rust.mdx
+++ /dev/null
@@ -1,8 +0,0 @@
----
-title: "Embedded Rust Framework"
-description: "A framework for writing embedded systems applications in Rust with a focus on safety and performance"
-githubUrl: "https://github.com/username/embedded-rust"
-techStack: ["Rust", "Embedded Systems", "RTOS", "HAL"]
-date: "2024-01-15"
-image: "/projects/embedded-preview.png"
----
diff --git a/src/src/content/projects/llm-finetuning.mdx b/src/src/content/projects/llm-finetuning.mdx
deleted file mode 100644
index f96f959..0000000
--- a/src/src/content/projects/llm-finetuning.mdx
+++ /dev/null
@@ -1,9 +0,0 @@
----
-title: "LLM Fine-tuning Pipeline"
-description: "A toolkit for fine-tuning large language models on custom datasets with optimized training procedures"
-githubUrl: "https://github.com/username/llm-fine-tuning"
-demoUrl: "https://llm-tuning.demo.dev"
-techStack: ["Python", "PyTorch", "CUDA", "MLFlow"]
-date: "2024-01-01"
-image: "/projects/llm-preview.png"
----
diff --git a/src/src/content/projects/realtime-editor.mdx b/src/src/content/projects/realtime-editor.mdx
deleted file mode 100644
index 961573a..0000000
--- a/src/src/content/projects/realtime-editor.mdx
+++ /dev/null
@@ -1,9 +0,0 @@
----
-title: "Real-time Collaboration Editor"
-description: "A collaborative text editor with real-time synchronization using WebTransport protocol for minimal latency"
-githubUrl: "https://github.com/username/real-time-collab"
-demoUrl: "https://collab.demo.dev"
-techStack: ["TypeScript", "React", "WebTransport", "CRDT"]
-date: "2024-02-10"
-image: "/projects/collab-preview.png"
----
diff --git a/src/src/content/projects/reviveauto.mdx b/src/src/content/projects/reviveauto.mdx
new file mode 100644
index 0000000..ebc4be7
--- /dev/null
+++ b/src/src/content/projects/reviveauto.mdx
@@ -0,0 +1,179 @@
+---
+title: "Revive Auto Parts"
+description: "A car parts listing site built for a client."
+demoUrl: "https://reviveauto.parts"
+techStack: ["Typescript", "Tanstack Router", "React Query"]
+date: "2024-12-15"
+image: "/projects/reviveauto/thumbnail.jpeg"
+---
+
+## Overview
+A car parts listing website built to provide an intuitive and efficient experience
+for users searching for automotive parts. This project was commissioned by a client
+and showcases some pretty cool modern web technologies, enabling excellent
+performance and a clean user interface.
+
+## Key Features
+* **Dynamic & Simple Routing**: Powered by TanStack Router, enabling seamless navigation
+and deep-linking for product categories and details.
+
+* **Real-Time Data Fetching**: Utilized React Query to handle server state and caching,
+ensuring users have up-to-date information.
+
+* **Infinite Scroll**: Implemented React Query's infinite scrolling and memoization
+optimization techniques to ensure fast and seamless scrolling through listings.
+
+* **Dynamic Filters**: Created dynamic filters which are editable on the admin panel,
+allowing for a high level of customization.
+
+* **Responsive Design**: Built with Tailwind and Shadcn for a fully responsive layout,
+providing a consistent experience across desktop and mobile devices.
+
+* **Optimized Performance**: Leveraged Vite for fast builds and optimized code-splitting,
+improving page load times drastically.
+
+## Development Highlights
+I had numerous highlights and *aha* moments when developing this site. One of these has to
+be the site layout, built with [shadcn/ui](https://ui.shadcn.com) components. I had used
+this component library in a previous site, but I had yet to grasp just how powerful this
+collection of components is. We truly do stand on the shoulders of giants, and using this
+library not only allowed me to very quickly prototype a design, but to then flesh it out
+without having to dive into the weeds of UI development.
+
+Another great highlight has to be [Tanstack Router](https://tanstack.com/router/latest).
+As a seasoned developer, I have had many opportunities to try a lot of different routers
+across several frameworks. As many have before me, we stumble onto the nextjs router, and
+tend not to look back. However, tanstack did something I did not expect, and it takes routing
+to the next level. With TanStack, the routes folder is solely focused on defining routes and
+layouts, providing a cleaner, more modular structure. This is a stark contrast to Next.js's
+approach, where the app directory can quickly become convoluted by mixing route definitions
+with server-side logic, API calls, and other concerns. Anybody who has built a Nextjs project
+bigger than a To-Do app can likely relate to the mental pain that is trying to find a route or
+endpoint in your app router when its nested and hidden away four or five directories deep.
+
+Another memorable highlight was writing my backend in Python using [Fastapi](https://fastapi.tiangolo.com/).
+Sometimes, a project doesn't need a complex nodejs runtime, or an ORM built for a massive service.
+As a python enthusiast, I found the combination of fastapi & sqlmodel to be just perfect for this project,
+and defining api endpoints and schemas were quite enjoyable. As I do, I decided to roll my own authentication,
+and found Python to be a great environment in which to do so.
+
+Lastly, I have to touch on React Query. The combo that is React Query and Fastapi can truly be magical.
+To truly showcase what I mean, here's an example of a query and endpoint working together:
+
+```typescript
+// features/auth/services/login/queries.ts
+export function useLogin() {
+ const { setCredentials } = useUserStore();
+
+ return useMutation
, LoginRequestSchemaType>({
+ mutationFn: user => login(user),
+ onSuccess: data => {
+ setCredentials({
+ accessToken: data.access_token,
+ });
+ },
+ });
+}
+
+const login = backend, z.infer>({
+ method: "POST",
+ path: `${BACKEND_URL}${AUTH}/login`,
+ requestSchema: LoginRequestSchema,
+ responseSchema: LoginResponseSchema,
+ type: "public",
+});
+```
+```typescript
+// features/auth/services/login/schemas
+import { z } from "zod";
+
+export const LoginRequestSchema = z.object({
+ email: z
+ .string()
+ .min(1, "Email is required!")
+ .trim()
+ .email({ message: "Invalid email!" })
+ .toLowerCase(),
+ password: z.string().trim().min(8, { message: "Password must be at least 8 characters long!" }),
+});
+export type LoginRequestSchemaType = z.infer;
+
+export const LoginResponseSchema = z.object({
+ access_token: z.string(),
+});
+export type LoginResponseSchemaType = z.infer;
+```
+
+```python
+# routes/auth.py
+class LoginResponse(BaseModel):
+ access_token: str
+
+@router.post(
+ "/login",
+ description=
+ """
+ The login endpoint.
+
+ Used to create access and refresh tokens for a user.
+ The refresh token is set as an HTTP-only cookie.
+ """,
+ summary="Create access token and set refresh token as HTTP-only cookie."
+)
+async def login(
+ response: Response,
+ form_data: LoginSchema = Body(...),
+ session: Session = Depends(get_session)
+) -> Any:
+
+ # Fetch user using the form_data sent by the client
+ user = await service.authenticate(
+ email=form_data.email,
+ password=form_data.password,
+ session=session
+ )
+
+ # If service returns None, raise exception
+ if not user:
+ raise HTTPException(
+ status_code=status.HTTP_401_UNAUTHORIZED,
+ detail="Incorrect email or password",
+ )
+
+ # Set refresh token as HTTP-only cookie
+ response.set_cookie(
+ key="refresh_token",
+ value=create_token(user, type="refresh"),
+ httponly=True,
+ path="/auth/refresh",
+ domain=Config.JWT_COOKIE_DOMAIN,
+ expires=datetime.now(timezone.utc) + Config.JWT_REFRESH_EXPIRES
+ )
+
+ return LoginResponse(
+ access_token=create_token(user, type="access")
+ )
+```
+Using Zod, the frontend is validating what a user is attempting to submit
+before calling the endpoint. If Zod does not throw an error, our frontend will
+call our backend endpoint, which also expects the right types to be present.
+Afterwards, the backend will respond back with a response that our frontend
+will also validate. This allows for a complete multi-directional
+request -> response type validation!
+
+## Challenges and Roadblocks
+For the most part, there were really no challenges, say for some hiccups here and there.
+Probably the most painful parts were creating unit tests for the frontend, and scraping
+Facebook for a total of 1,384 posts for my client, who wanted the posts imported over.
+As one can imagine, that process is not simple to do manually by hand, so I wrote multiple
+python scriptsusing the seleneum library to fetch the posts from the sellers account, a process
+which took multiple attempts, several overnight scrapes, and lots of data sanitation afterwards.
+Other than that, everything else was an absolute joy to work on, and I finished the project in under
+15K LOC.
+
+## Summary
+Sometimes, building a CRUD app can be lots of fun, no matter how many times you've done it before.
+All it takes is adding something new to the stack, and striving to improve the code you write. This
+project was exactly that, a mix of new technologies working together to power a fairly neat site,
+which can be viewed [here](https://reviveauto.parts). Maybe there is a car part there which the reader
+might need. As always, thanks for the read :)
diff --git a/src/src/content/projects/test.mdx b/src/src/content/projects/test.mdx
deleted file mode 100644
index 0cef92a..0000000
--- a/src/src/content/projects/test.mdx
+++ /dev/null
@@ -1,26 +0,0 @@
----
-title: "Project Name"
-description: "Project description here"
-demoUrl: "https://demo.project.com" # optional
-techStack: ["React", "TypeScript", "Tailwind"]
-date: "2024-03-15"
-image: "/projects/preview.png" # optional
----
-
-# Project Overview
-
-This is a detailed description of the project...
-
-## Features
-
-- Feature 1
-- Feature 2
-- Feature 3
-
-## Technical Details
-
-Here's how it works...
-
-## Challenges & Solutions
-
-During development...
diff --git a/src/src/content/projects/test2.mdx b/src/src/content/projects/test2.mdx
deleted file mode 100644
index a4c4608..0000000
--- a/src/src/content/projects/test2.mdx
+++ /dev/null
@@ -1,27 +0,0 @@
----
-title: "Rust WASM Game Engine"
-description: "A lightweight 2D game engine built with Rust and compiled to WebAssembly for high-performance browser games"
-githubUrl: "https://github.com/username/rust-wasm-game"
-demoUrl: "https://rust-wasm-game.demo.dev"
-techStack: ["Rust", "WebAssembly", "Canvas API", "Web Workers"]
-date: "2024-03-15"
-image: "/projects/rust-wasm-preview.png"
----
-
-# Project Overview
-
-This is a detailed description of the project...
-
-## Features
-
-- Feature 1
-- Feature 2
-- Feature 3
-
-## Technical Details
-
-Here's how it works...
-
-## Challenges & Solutions
-
-During development...
diff --git a/src/src/pages/projects/[...slug].astro b/src/src/pages/projects/[...slug].astro
index f85b6cd..7366122 100644
--- a/src/src/pages/projects/[...slug].astro
+++ b/src/src/pages/projects/[...slug].astro
@@ -50,7 +50,7 @@ const { Content } = await project.render();
{project.data.demoUrl && (
- Live Demo
+ Live Link
)}