My Projects
A static multi-page wiki site for a custom tabletop RPG world, built with vanilla HTML, CSS and JavaScript — no frameworks. Features include a Leaflet.js image map with custom markers, IntersectionObserver scroll animations, modular JS data systems for locations, characters, lore, bestiary, gods, stars and a timeline, URL parameter-based deep linking, responsive mobile layout, and a Google Forms submission pipeline for community contributions. This is a passion project, created for my own game and world, and as a gift to everyone who plays or has ever played, a place where we can preserve the stories told in this hobby we love. With that in mind, I have created a template for sale on Gumroad, so that others may have a place to house their own worlds.
Vizion is a full-stack Kanban-style project management app. My first end-to-end project connecting a real backend to a real frontend. On the backend, I built a REST API with Node.js and Express, organized into resource routers (boards, columns, cards, auth) and connected to a MySQL database using a connection pool. I implemented JWT-based authentication with bcrypt password hashing, rate limiting on auth routes, input sanitization, and CORS restrictions, thinking through security from the start. I also learned how to structure routes, handle async/await with proper error handling, and think about data relationships, like how cards belong to columns, which belong to boards, and how position ordering needs to stay in sync when you drag things around. On the frontend, I used vanilla JavaScript, no frameworks, which forced me to really understand the DOM, state management, and the Fetch API. I implemented drag-and-drop natively using the HTML5 Drag and Drop API for both cards and columns, built a reusable modal system, and added a light/dark theme toggle that persists via localStorage. Deployed on Railway (API) and Vercel (frontend).
What's next:
v1.1 - small but meaningful:
Due dates on cards, a card counter badge on the board list, and keyboard shortcut Esc to close modals.
v2 - collaboration:
Multiple users per board, shared workspaces, and board invitations.
v3 - real-time & rich content:
Live sync with WebSockets, file attachments on cards, and an activity log.
A task manager built with React that connects to live weather data and uses it to make your to-do list context-aware. React project, built step by step to learn the fundamentals properly rather than cargo-culting a tutorial. On the React side, I built out the full component tree from scratch: AddTaskForm, TaskList, TaskItem, WeatherWidget, ForecastBar, learning how to lift state up, pass callbacks as props, and keep a single source of truth in the parent. Tasks persist across sessions using localStorage synced via useEffect, and I used a lazy initialiser in useState to load saved data efficiently on mount. For the weather layer, I wrote a custom useWeather hook that fetches from the OpenWeatherMap API using either a city name or browser geolocation coordinates, running both the current conditions and 5-day forecast requests in parallel with Promise.all. The hybrid logic lives in a pure utility file that flags outdoor tasks with warnings and surfaces a banner when bad weather coincides with pending outdoor work. Styled with Tailwind CSS v4 and Font Awesome icons. Working with a third-party API, environment variables, and thinking through how UI should respond to async state, loading skeletons, error messages, and conditional rendering throughout.