Projects

Sports Shuffle Logo

SportsShuffle

View Details
BookKeeper Logo

BookKeeper

View Details
Spot Rouletee Logo

SpotRoulette

View Details
BookKeeper
A full-stack web app to manage and track your personal library. Users can sign up/Login, add books (with cover images fetched via ISBN/ASIN lookup), mark reading status, search by title/author/genre, and filter their collection. Built as a learning project to master modern full-stack development.

Tech Stack

  • Frontend: React, React Router, Auth0 for Authentication, Axios for HTTP, Bootstrap 5 for styling
  • Backend: Node.js with Express, MongoDB driver, JSON Web Tokens (JWT) for securing endpoints
  • DevOps & Testing: Docker & Docker-Compose for containerized local development, Jest & Supertest for API testing, Swagger (swagger-jsdoc + swagger-ui-express) for API docs

Screenshots

Coming Soon...

Live Demo Link: Coming Soon

Case Study

  • Challenge 1: Integrating Auth0 for secure user authentication without compromising UX.
    Solution: Followed Auth0's React SDK docs to implement login/signup flows and protected routes.
    What I Learned: OAuth fundamentals, handling auth state in React.
  • Challenge 2: Managing complex state for filtering/searching large lists in React.
    Solution: Lifted state into parent, used controlled components for filters, optimized re-renders with useMemo.
    What I Learned: Effective state management patterns and performance tuning in React.
SpotRoulette
A multi-platform "place picker" that randomly suggests venues (e.g., restaurants, cafes, parks) from a curated collection based on user-selected categories and tags-built to explore end-to-end TypeScript/Express APIs, a React web client, and native mobile prototypes.

Tech Stack

  • Frontend: React, TypeScript, React Router, Axios for HTTP requests, CSS
  • Backend: Node.js, Express.js, TypeScript, CORS, serves static JSON datasets for places & tags via custom /api/places and /api/tags routes
  • DevOps & Testing: Git & GitHub for version control, npm & ts-node-dev for local development scripts

Screenshots

Coming Soon...

Github Repo: github.com/jnycolej/SpotRoulette

Live Demo Link: Coming Soon

Case Study

  • Challenge 1: Designing a flexible, tag-based filter with "any" vs. "all" match modes.
    Solution: Solution: Built a reusable filterPlaces utility to combine type and tag filters dynamically. <br />
    What I Learned: Functional programming patterns in TypeScript and robust API design.
  • Challenge 2: Serving location data without a full database.
    Solution: Used static JSON files (places.json, tags.json) and simple Express routes to mock production-style endpoints
    What I Learned: Trade-offs of prototyping with static vs. dynamic data sources.
  • Challenge 3: Rapidly prototyping cross-platform mobile experiences.
    Solution: Created early Android (Kotlin) and iOS (Objective-C++) demos to validate UX flows
    What I Learned: Foundations of mobile development workflows and platform differences.
SportsShuffle
A real-time, multiplayer sports-themed game platform featuring card-based gameplay, trivia, and live score tracking. Players can join shared rooms, trigger game events, and compete during live sessions. Built as a learning project to explore real-time communication, game state management, and scalable backend architecture.

Tech Stack

  • Frontend: React, JavaScript, HTML, CSS
  • Backend: Node.js with Express, Socket.IO for real-time communication
  • DevOps & Testing: Heroku for deployment, GitHub for version control

Screenshots

Coming Soon...

Github Repo: https://github.com/jnycolej/GamesApp

Live Demo Link: Coming Soon

Case Study

  • Challenge 1: Building a multiplayer experience that keeps all players in sync during live gameplay.
    Solution: Used Socket.IO rooms and server-controlled game logic to broadcast events and updates consistently across all connected clients.
    What I Learned: Real-time event handling, client-server synchronization, and managing shared application state.
  • Challenge 2: Managing complex game logic while keeping the UI responsive and easy to extend.
    Solution: Separated game rules from UI components and centralized state updates on the backend to reduce client-side complexity.
    What I Learned: Architectural separation of concerns and designing systems that scale as features grow.