export type Screenshot = {
  src: string;
  /** Accessibility / SEO text — always required. */
  alt: string;
  /** Human-facing label shown in the carousel + viewer. Falls back to `alt`. */
  caption?: string;
};

export type Project = {
  /** Route segment — the page lives at /projects/<slug> */
  slug: string;
  title: string;
  year: string;
  stack: string[];
  /** Short summary shown on cards */
  description: string;
  /** Live demo URL */
  liveUrl: string;
  /** Longer write-up for the detail page (one entry per paragraph) */
  overview: string[];
  screenshots: Screenshot[];
  /** What I learned building it */
  learned: string[];
  /** What I'd do differently next time */
  improvements: string[];
};

export const projects: Project[] = [
  {
    slug: "orbit",
    title: "Orbit",
    year: "2026",
    stack: ["React", "TypeScript", "Bun", "Hono", "SQLite", "MCP"],
    description:
      "A self-hosted project and ticket management workspace with spaces, pages, and notes. MCP server",
    liveUrl: "https://demo.angelmankel.com/orbit",
    overview: [
      "Orbit is a custom project management tool I built for myself to organize my personal projects and easily integrate Claude Code to manage projects with natural language. I can create kanban boards with tickets, create markdown formatted documentation, upload files, and create excalidraw diagrams — all in one place. And since I built it with AI agents in mind, the MCP server provides an API for programmatic access to all my data.",
      "Orbit solves the friction of context-switching between separate tools for project management, documentation, and file storage — it's one workspace for all of it. A key feature is being able to upload screenshots or files to a ticket, then hand them to Claude Code or other agents without pasting anything into the terminal — which matters a lot over SSH, where pasting files is a real pain point. And the MCP server lets all my local AI infrastructure pull project context, find relevant information, and create or update tickets directly, without ever touching the web interface."
    ],
    screenshots: [
      { src: "/projects/orbit/1.png", alt: "Kanban board view" },
      { src: "/projects/orbit/2.png", alt: "Ticket detail view" },
      { src: "/projects/orbit/3.png", alt: "Documentation view" },
      { src: "/projects/orbit/4.png", alt: "Settings view" },
    ],
    learned: ["I learned a lot about the MCP protocol and some of the roadblocks you can run into when allowing AI agents to create and modify data in a tool like this. One example is ensuring agents have a way to patch slices of data without needing to resubmit the entire content. It's MUCH more efficient for an agent and I learned first hand - wondering why a simple markdown adjustment I asked for was taking 5+ minutes! Another lesson learned was gating off destructive functions and making sure to have a backup/restore strategy. Claude once deleted all my projects during development (I had a backup) and it got me thinking more about what specific tools to expose to agents to empower them while minimizing risk."],
    improvements: ["The app works great for what I wanted it for, but there are still some issues. One being the markdown editor and parsing is a bit buggy sometimes, and if I were to do this all over again, I'd probably use a more robust solution. The layout is a bit clunky in my opinion, and I would have liked a more Jira style layout with a tabbed top nav instead of the sidebar. Lastly, I created a web chat feature which would allow Claude to interact with you with a small set of web components like checkboxes, buttons, text inputs, etc. But it needed a much more robust communication channel to work seamlessly."],
  },
  {
    slug: "imagelab",
    title: "ImageLab",
    year: "2026",
    stack: ["React", "TypeScript", "Pixi.js", "Tailwind CSS"],
    description:
      "A browser-based AI image processing playground. Built as a frontend for the popular open source project: ComfyUI",
    liveUrl: "https://demo.angelmankel.com/imagelab",
    overview: [
      "ImageLab is something I've built many different iterations of over the years — and it's grown over time just as AI image generation has evolved. This latest version replaces heavy infrastructure with a simple client-side web interface that anyone can utilize with their own local ComfyUI instance. All you really need is the frontend running in your browser and a ComfyUI server running my custom node plugin. You can even add multiple servers to control multiple instances at once. The app provides a parameters focused view for experiementing, a model browser with metadata pulled from Civit.ai (models are hashed in my custom node), and an inpainting mode with an infinite canvas driven by Pixi.js for super smooth performance.",
      "I've used many different types of image generation interfaces, and I always felt like there was so much room for improvement. I liked the flexibility of ComfyUI's node-based system, but wanted a way to interact with a custom workflow while abstracting away the complexity after it's been set up. ImageLab allows me to utilize a pretty complex workflow in the background, but easily interface with it and experiment without having to mess with a node graph at all. Not to mention the model browser allows me to actually see metadata about the model which provides important context when experimenting. And the infinite canvas adds features not available in ComfyUI itself. Spinning up a Runpod instance using a H200 and connecting it to ImageLab in just a few clicks is awesome as well.",
    ],
    screenshots: [
      { src: "/projects/imagelab/1.png", alt: "Main editor" },
      { src: "/projects/imagelab/2.png", alt: "Prompt snippets library feature" },
      { src: "/projects/imagelab/3.png", alt: "Model metadata modal view with data from Civit.ai" },
      { src: "/projects/imagelab/4.png", alt: "Model selector with metadata from Civit.ai" },
      { src: "/projects/imagelab/5.png", alt: "Fullscreen image modal with image metadata" },
      { src: "/projects/imagelab/6.png", alt: "Saved images collection view" },
      { src: "/projects/imagelab/7.png", alt: "Inpainting workflow 1" },
      { src: "/projects/imagelab/8.png", alt: "Inpainting workflow 2" },
      { src: "/projects/imagelab/9.png", alt: "Inpainting workflow 3" },
    ],
    learned: ["ImageLab was the first big web project I stepped into back when AI image generation started getting popular around 2021. Back then, I was familar with React but I was still not sure how web servers worked, or what full stack development really entailed. This project really pushed me to learn about relational databases, web servers, REST APIs, authentication, and many other core web development concepts. This project will always be a special one to me because it really represents my journey into web development and how much I've grown since then."],
    improvements: ["This project has gone through so many iterations over the years - client-only, complex multi-server configurations, Tauri/Electron apps, and more. If I were to do it all over again, I would keep the client-side approach to keep things simple, but I would add an optional web server that can be used alongside the client to persist data across sessions. And a lot of the UI/UX could be improved with a lot more time and testing. The inpainting workflow is overly complex and could be simplified a lot as well."],
  },
  {
    slug: "league",
    title: "League of Legends Companion",
    year: "2026",
    stack: ["React", "TypeScript", "Hono", "MySQL", "Riot API"],
    description:
      "An app I built for a friend who was trying to climb the ranks in League of Legends. It pulls in match data and account stats from the Riot API, and allows users to keep notes on matchups, builds, and more.",
    liveUrl: "https://demo.angelmankel.com/league",
    overview: [
      "This project is essentially a note taking and builds app for League of Legends, the popular competitive MOBA game. It utilizes a MySQL database to store user data, match history, and user created builds, item sets, and more. It utilizes the public and private Riot API to pull in match history, account rank and other data, and game assets like item icons and champion art.",
      "My best friend is a long time PC gamer. He's climbed the ranks in multiple competitive games over the years, and has even played and won in real tournaments. One game he had not quite mastered was League of Legends, and he set out to challenge himself to push to a higher rank in the game. He previously used spreadsheets of matchup data acquired from high level players on Patreon and other sources, but we all know spreadsheets are mostly nothing but headaches. I built this app for him to easily keep track of matchup data, with a clean data model on the backend to allow for importing from multiple data sources easily.",
    ],
    screenshots: [
      { src: "/projects/league-helper/1.png", alt: "League of Legends Companion screenshot 1" },
      { src: "/projects/league-helper/2.png", alt: "League of Legends Companion screenshot 2" },
      { src: "/projects/league-helper/3.png", alt: "League of Legends Companion screenshot 3" },
      { src: "/projects/league-helper/4.png", alt: "League of Legends Companion screenshot 4" },
      { src: "/projects/league-helper/5.png", alt: "League of Legends Companion screenshot 5" },
      { src: "/projects/league-helper/6.png", alt: "League of Legends Companion screenshot 6" },
      { src: "/projects/league-helper/7.png", alt: "League of Legends Companion screenshot 7" },
    ],
    learned: ["This is actually the second iteration of this app. This iteration added many more features, utilized more of the available window space, and the data model was build from the ground up to allow for maximum flexibility and extensibility. The main thing I learned from this experience was that building on external APIs needs to be handled with care and planning. Since I don't control the API, I had to make sure to account for breaking changes. Luckily, a big update came out halfway through development, exposing parts I missed and ultimately forced me to learn the hard way."],
    improvements: ["I originally planned on adding a companion app that a user would install on their PC, which would talk to my server and pull in live match data. This data would be shown in the UI in a 'live game' mode. This would have been a really cool feature, but it was deceptively complex and required a lot of back and forth between my dev machine and a gaming machine to test. If I were to do this all over again, I would do more planning and research before attempting to build the feature."],
  },
  {
    slug: "study",
    title: "Study Time",
    year: "2026",
    stack: ["React", "TypeScript", "Vite", "Mantine"],
    description:
      "A study app I built for those late night study sessions - essentially a free Quizlet.",
    liveUrl: "https://demo.angelmankel.com/study",
    overview: [
      "Study Time is a very simple web app I built for myself to help with studying for my computer architecture class. This class required A LOT of memorization and a broad understanding of many different topics. I wanted a simple way to keep track of my progress and quiz myself on specific topics. It also was a great place to drop in all of my course content and have Claude Code parse the data, and upload it to the app since I built is as a fully JSON data driven system.",
      "This app really helped keep me on track with studying for the initial class but also carried over to many afterwards as well. The fact that it's a web app on my local network means I could start a quiz on my desktop, and then pull it up on my phone if I needed to step away and pick up where I left off. And a huge plus was that it is completely free and saved me from having to pay for Quizlet.",
    ],
    screenshots: [
      { src: "/projects/study-time/1.png", alt: "Study Time screenshot 1" },
      { src: "/projects/study-time/2.png", alt: "Study Time screenshot 2" },
      { src: "/projects/study-time/3.png", alt: "Study Time screenshot 3" },
      { src: "/projects/study-time/4.png", alt: "Study Time screenshot 4" },
      { src: "/projects/study-time/5.png", alt: "Study Time screenshot 5" },
      { src: "/projects/study-time/6.png", alt: "Study Time screenshot 6" },
      { src: "/projects/study-time/7.png", alt: "Study Time screenshot 7" },
    ],
    learned: ["This app was a fun and quick project, built mainly with Claude Code. This was actually partially an experiment to see how well Claude Code could handle a project with a lot of different components and features. I was pleasantly surprised with how well it handled the project, and it ended up being a great way to quickly build a useful tool for myself. The main thing I learned from this project was that having a clear data model and structure from the beginning is crucial when building with AI assistance. It allows the AI to generate code that fits within the structure and reduces the chances of running into issues down the line."],
    improvements: ["If I were to do this again, I would expand on the study games/modes which I partially added but are currently a bit buggy. I hardly used anything other than the quiz feature and flash cards, but if those other modes were more fleshed out, they might have made studying a bit less monotonous."],
  },

  {
    slug: "d2r",
    title: "Diablo II: Resurrected Tracker",
    year: "2026",
    stack: ["Bun", "JavaScript", "HTML/CSS"],
    description:
      "An event tracker and companion app for the game Diablo II: Resurrected.",
    liveUrl: "https://demo.angelmankel.com/d2r",
    overview: [
      "This project is a simple companion app for the game Diablo II: Resurrected. It has a few different features, but the main one is a live event tracker that pulls data from an unofficial API to show when in-game events are happening. It also has some guides and tools that are useful when creating new builds in the game.",
      "My friends and I are big Diablo fans. Recently, when the Warlock expansion was released for D2R, we started playing regularly again. We had a lot of runes and other high value items we were trading back and forth to other players to get gear we wanted for new builds. And there are now live service events in the game that we wanted to easily keep track of. So I built this app to solve those problems. It has a live event tracker that pulls data from an unofficial API, pricing data for high value runes and items to ensure we know how much things are worth when trading, and a few quality of life features that help when creating new builds and theorycrafting.",
    ],
    screenshots: [
      { src: "/projects/d2r/1.png", alt: "Diablo II: Resurrected Tracker screenshot 1" },
      { src: "/projects/d2r/2.png", alt: "Diablo II: Resurrected Tracker screenshot 2" },
      { src: "/projects/d2r/3.png", alt: "Diablo II: Resurrected Tracker screenshot 3" },
      { src: "/projects/d2r/4.png", alt: "Diablo II: Resurrected Tracker screenshot 4" },
      { src: "/projects/d2r/5.png", alt: "Diablo II: Resurrected Tracker screenshot 5" },
      { src: "/projects/d2r/6.png", alt: "Diablo II: Resurrected Tracker screenshot 6" },
    ],
    learned: ["This app was a great experience because it required me to utilize my existing web dev skills to get everything designed and working quickly - I didn't want to spend months on a simple companion app. I created a web scraper to pull data from the unofficial API which was something I normally stay away from. In this case, there were no other options so I had to dive in and learn quickly. The other thing was getting game data such as item images - by using some open source software, I was able to extract game assets directly from the game files and utilize them in my app. It was interesting to work with an AI agent to sort through the data and organize it for me, which would have been a nightmare to do manually."],
    improvements: ["Next time, I would take more time to plan out the features, adding much more robust build creation tools. It's a pretty simple guide right now, but it could be expanded to pull real build data from a character automatically, storing it in a database, and allowing users to share builds with each other. Similar to the popular website Maxroll.gg, but with more of a focus on QOL features."],
  },
];
