Skip to content

thenulldev/portfolio

Repository files navigation

πŸš€ Stephen Freerking - Portfolio

A modern, responsive portfolio website built with Next.js and deployed on Cloudflare Workers using OpenNext. Features real-time data integration with Credly, Microsoft Learn, and TryHackMe APIs.

✨ Features

  • 🎨 Modern Design: Clean, professional portfolio with dark mode support
  • πŸ“Š Live Data: Real-time certifications and skills from Credly API
  • πŸ“š Microsoft Learn Integration: Live progress tracking from Microsoft Learn
  • πŸ”“ TryHackMe Integration: Real-time cybersecurity learning stats and achievements
  • πŸ“ Blog System: Complete blog functionality with markdown support and dynamic content generation
  • πŸ“± Responsive: Optimized for all devices and screen sizes (mobile-first design)
  • β™Ώ Accessible: Built with accessibility in mind using Radix UI components
  • ⚑ Fast: Deployed on Cloudflare Workers for global performance
  • πŸŒ™ Dark Mode: Automatic dark/light mode detection with smooth transitions
  • πŸ”„ Automated Content: Blog posts automatically generated from markdown files

πŸ› οΈ Tech Stack

  • βš›οΈ Framework: Next.js 15 with App Router
  • 🎨 Styling: Tailwind CSS with custom dark mode support
  • 🧩 UI Components: Radix UI for accessible, unstyled components
  • ☁️ Deployment: Cloudflare Workers via OpenNext
  • πŸ”— APIs:
    • Credly API for certifications and skills
    • Microsoft Learn API for progress tracking
    • TryHackMe API for cybersecurity achievements
  • πŸ“ Content Management:
    • Markdown-based blog posts with frontmatter
    • Gray-matter for metadata parsing
    • Custom markdown-to-HTML conversion
  • 🎯 Icons: FontAwesome for social media and UI icons
  • πŸ“¦ Package Manager: pnpm for faster, more efficient dependency management

πŸš€ Getting Started

πŸ“‹ Prerequisites

  • Node.js 18+
  • pnpm (recommended) or npm
  • Cloudflare account (for deployment)

πŸ’» Development

  1. Clone the repository:
git clone <repository-url>
cd portfolio
  1. Install dependencies:
pnpm install
  1. Generate blog data (if you have blog posts):
pnpm generate-blog
  1. Run the development server:
pnpm dev

Open http://localhost:3000 with your browser to see the result.

πŸ”¨ Building for Production

The build process automatically generates blog data:

pnpm build

This command will:

  • Generate blog data from markdown files
  • Build the Next.js application
  • Prepare for deployment

🌐 Local Cloudflare Workers Preview

To test the Cloudflare Workers deployment locally:

pnpm preview

This will start the OpenNext build process and run the app using Wrangler dev server.

πŸš€ Deployment

☁️ Deploy to Cloudflare Workers

  1. Make sure you have Wrangler CLI installed and authenticated:
npm install -g wrangler
wrangler login
  1. Deploy the application:
pnpm deploy

This command will:

  • πŸ—οΈ Build the Next.js application using OpenNext
  • ☁️ Deploy it to Cloudflare Workers
  • 🌍 Make it available at your configured domain

πŸ”§ Environment Variables

The application uses the following external APIs:

  • πŸ† Credly API: For fetching certifications and skills
  • πŸ“š Microsoft Learn API: For fetching learning progress
  • πŸ”“ TryHackMe API: For fetching cybersecurity achievements and stats

No API keys are required as these are public endpoints.

πŸ“ Project Structure

src/
β”œβ”€β”€ app/                    # Next.js App Router
β”‚   β”œβ”€β”€ api/               # API routes
β”‚   β”‚   β”œβ”€β”€ certifications/ # Credly API proxy
β”‚   β”‚   β”œβ”€β”€ ms-learn/      # Microsoft Learn API proxy
β”‚   β”‚   └── tryhackme/     # TryHackMe API proxy
β”‚   β”œβ”€β”€ blog/              # Blog pages and routing
β”‚   β”‚   β”œβ”€β”€ [id]/          # Dynamic blog post pages
β”‚   β”‚   β”œβ”€β”€ [slug]/        # Alternative slug-based routing
β”‚   β”‚   └── page.tsx       # Blog listing page
β”‚   β”œβ”€β”€ globals.css        # Global styles
β”‚   β”œβ”€β”€ layout.tsx         # Root layout
β”‚   └── page.tsx           # Home page
β”œβ”€β”€ components/            # React components
β”‚   β”œβ”€β”€ ui/               # Radix UI components
β”‚   β”‚   β”œβ”€β”€ badge.tsx     # Badge component
β”‚   β”‚   β”œβ”€β”€ card.tsx      # Card component
β”‚   β”‚   β”œβ”€β”€ checkmark-badge.tsx # Checkmark badge
β”‚   β”‚   β”œβ”€β”€ empty-state.tsx # Empty state component
β”‚   β”‚   β”œβ”€β”€ error-state.tsx # Error state component
β”‚   β”‚   β”œβ”€β”€ hover-card.tsx # Hover card component
β”‚   β”‚   β”œβ”€β”€ loading-state.tsx # Loading state component
β”‚   β”‚   β”œβ”€β”€ section-container.tsx # Section container
β”‚   β”‚   └── section-header.tsx # Section header
β”‚   β”œβ”€β”€ creds.tsx         # Certifications component
β”‚   β”œβ”€β”€ skills.tsx        # Skills component
β”‚   β”œβ”€β”€ progress.tsx      # Microsoft Learn progress
β”‚   β”œβ”€β”€ tryhackme.tsx     # TryHackMe stats component
β”‚   β”œβ”€β”€ socials.tsx       # Social media links
β”‚   └── useCertifications.ts # Custom hook for data fetching
β”œβ”€β”€ content/              # Content management
β”‚   └── blog/             # Blog post markdown files
β”‚       β”œβ”€β”€ getting-started-with-cybersecurity.md
β”‚       β”œβ”€β”€ microsoft-learn-journey.md
β”‚       └── tryhackme-learning-path.md
β”œβ”€β”€ data/                 # Generated data files
β”‚   └── blog-posts.json   # Processed blog posts data
β”œβ”€β”€ hooks/                # Custom React hooks
β”‚   └── useApiData.ts     # Generic API data fetching hook
β”œβ”€β”€ lib/                  # Utility functions
β”‚   β”œβ”€β”€ api.ts           # API utility functions
β”‚   └── utils.ts         # Tailwind CSS utilities
β”œβ”€β”€ scripts/              # Build and deployment scripts
β”‚   β”œβ”€β”€ generate-blog-data.js # Blog data generation
β”‚   β”œβ”€β”€ deploy-cloudflare.js  # Cloudflare deployment
β”‚   └── preview-cloudflare.js # Local Cloudflare preview
β”œβ”€β”€ styles/              # Additional styles
β”‚   └── responsive.css   # Responsive design utilities
└── types/               # TypeScript type definitions
    └── index.ts         # Shared type definitions

πŸ”Œ API Endpoints

/api/certifications πŸ†

Proxies requests to the Credly API to fetch certifications and skills data.

/api/ms-learn πŸ“š

Proxies requests to the Microsoft Learn API to fetch learning progress and achievements.

/api/tryhackme πŸ”“

Proxies requests to the TryHackMe API to fetch cybersecurity achievements and statistics.

πŸ“ Blog System

The portfolio includes a complete blog system with the following features:

πŸ“„ Blog Posts

  • Markdown Support: Write posts in markdown with frontmatter metadata
  • Automatic Generation: Blog data is generated from markdown files during build
  • Dynamic Routing: Posts are accessible via /blog/[slug] URLs
  • Metadata Support: Title, description, date, tags, author, and read time

πŸ› οΈ Blog Management

Adding New Posts

  1. Create a new .md file in src/content/blog/
  2. Add frontmatter metadata:
---
title: "Your Post Title"
description: "Brief description"
date: "2024-12-01"
tags: ["tag1", "tag2"]
author: "Stephen Freerking"
readTime: "5 min read"
---

Your markdown content here...
  1. Run pnpm generate-blog to process the new post
  2. The post will be available at /blog/your-post-slug

Blog Data Generation

The generate-blog-data.js script:

  • Processes all markdown files in src/content/blog/
  • Converts markdown to HTML with syntax highlighting
  • Extracts frontmatter metadata
  • Generates src/data/blog-posts.json with all post data
  • Sorts posts by date (newest first)

🎨 Blog Styling

  • Responsive design with mobile-first approach
  • Syntax highlighting for code blocks
  • Consistent typography and spacing
  • Dark mode support
  • Accessible navigation and reading experience

🎨 Customization

βž• Adding New Certifications

Certifications are automatically fetched from your Credly profile. No manual updates required.

πŸ”§ Updating Skills

Skills are extracted from your certifications and automatically deduplicated.

🎨 Styling

The application uses Tailwind CSS with custom dark mode support. Modify src/app/globals.css and component styles as needed.

πŸ“± Responsive Design

The portfolio is built with a mobile-first approach and includes:

  • Responsive grid layouts for certifications (1-5 columns based on screen size)
  • Adaptive typography and spacing
  • Touch-friendly interactive elements

⚑ Performance

  • 🌍 Global CDN: Deployed on Cloudflare's global network
  • ⚑ Edge Computing: Server-side rendering at the edge
  • πŸ“¦ Optimized Assets: Images and fonts are optimized automatically
  • πŸ’Ύ Caching: Intelligent caching for API responses
  • πŸš€ Fast Loading: Optimized bundle sizes and lazy loading

πŸ”§ Recent Improvements

πŸ—οΈ Major Codebase Refactor

  • πŸ”„ Eliminated Code Duplication: Removed duplicate loading and error states across components
  • 🧩 Reusable UI Components: Created standardized UI components for consistent design
  • πŸ“¦ Centralized Type Definitions: Improved type safety with shared interfaces
  • 🎯 Standardized Data Fetching: Generic useApiData hook for consistent API handling
  • πŸ“ Better Organization: Cleaner file structure and import patterns

πŸ“ Blog System Implementation

  • πŸ“„ Complete Blog Functionality: Full markdown-based blog system
  • πŸ”„ Automated Content Generation: Scripts for processing blog posts
  • 🎨 Blog Styling: Responsive design with syntax highlighting
  • πŸ“Š Dynamic Routing: SEO-friendly blog post URLs

🎨 UI/UX Enhancements

  • πŸ“± Enhanced Responsiveness: Improved centering and layout on all screen sizes
  • 🎯 Better Grid Layout: Optimized certification grid with proper centering
  • ⚑ Performance Optimizations: Reduced bundle size and improved loading times
  • πŸŒ™ Dark Mode Polish: Enhanced visual design and user experience

🀝 Contributing

  1. 🍴 Fork the repository
  2. 🌿 Create a feature branch
  3. ✏️ Make your changes
  4. πŸ§ͺ Test thoroughly
  5. πŸ“€ Submit a pull request

πŸ“„ License

This project is private and proprietary.

πŸ’¬ Support

For questions or issues, please contact Stephen Freerking.


Built with ❀️ using Next.js and Cloudflare Workers πŸš€

About

Resources

Stars

Watchers

Forks