Skip to content

Repository files navigation

πŸš€ Portfolio of Hakkan

A modern, interactive portfolio website built with Next.js 15, featuring stunning animations, interactive mini games.

🌐 Live Preview β†’

Next.js React TypeScript Tailwind CSS Framer Motion

✨ Features

🎨 Visual Excellence

  • Stunning Animations - Smooth, professional animations powered by Framer Motion
  • Interactive Background - Dynamic floating elements with parallax effects
  • Dark/Light Theme - Seamless theme switching with system preference detection
  • Responsive Design - Fully optimized for desktop, tablet, and mobile devices

πŸ“± Sections

  • Hero - Eye-catching introduction with animated terminal
  • About - Professional background and expertise
  • Skills - Comprehensive technical skill showcase with interactive effects
  • Experience - Detailed work history with unique perspectives
  • Projects - Portfolio of featured projects with live demos
  • Education - Academic background
  • Certifications - Professional certifications
  • Contact - Get in touch via integrated form

🐣 Easter Eggs: This portfolio contains several delightful easter eggs and interactive surprises. Explore and discover them yourself!

πŸ› οΈ Tech Stack

Core Technologies

Additional Libraries

πŸš€ Getting Started

Prerequisites

  • Node.js 18.x or higher
  • npm or yarn package manager

Installation

  1. Clone the repository

    git clone https://github.com/HakkanShah/Portfolio.git
    cd Portfolio
  2. Install dependencies

    npm install
  3. Set up environment variables

    Create a .env.local file in the root directory:

    # πŸ“§ Email Service (Resend)
    RESEND_API_KEY=your_resend_api_key
    # πŸ‘Ύ Discord Webhook (Visitor Notifications)
    DISCORD_WEBHOOK_URL=your_discord_webhook_url
    # πŸ”₯ Firebase Configuration (Visitor Counter)
    NEXT_PUBLIC_FIREBASE_API_KEY=your_api_key
    NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your_project_id.firebaseapp.com
    NEXT_PUBLIC_FIREBASE_PROJECT_ID=your_project_id
    NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=your_project_id.firebasestorage.app
    NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=your_sender_id
    NEXT_PUBLIC_FIREBASE_APP_ID=your_app_id
    NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID=your_measurement_id
  4. Run the development server

    npm run dev
  5. Open your browser

    Navigate to http://localhost:9002

πŸ› οΈ Setup Guide

πŸ€– Hakkan Bot (AI Assistant)

The chat assistant is powered by an LLM through Groq, grounded on your own content β€” it does not make facts up from general knowledge.

  1. Get an API key at console.groq.com/keys.
  2. Set a spend limit while you're there. The endpoint is public.
  3. Add it to .env.local:
    GROQ_API_KEY=gsk_...
    GROQ_MODEL=llama-3.3-70b-versatile   # optional override
    NEXT_PUBLIC_SITE_URL=https://your-domain.com   # optional; locks the API to your origin
  4. Check the model id is still current at console.groq.com/docs/models β€” Groq retires models fairly often, and GROQ_MODEL lets you swap one without a redeploy.

Without a key the site works normally; the bot just explains that it isn't configured.

Two files control what the bot knows β€” nothing else:

File What goes in it
src/lib/data.ts Structured facts: projects, jobs, skills, education, certifications. These already power the visible site, so editing here updates the page and the bot together.
src/content/profile.ts Everything the site doesn't show: how the bot should sound, what you're available for, opinions, FAQs, off-limits topics. Plain prose.

Built-in guardrails: the phone number in CONTACT_INFO is filtered out of the bot's context, answers are capped in length so the voice mode stays listenable, and /api/chat rate-limits per IP with a global daily ceiling.

πŸ‘Ύ Discord Notifications

  1. Create a server (or use an existing one) on Discord.
  2. Go to Server Settings > Integrations > Webhooks.
  3. Click New Webhook, give it a name (e.g., "Portfolio Bot"), and copy the Webhook URL.
  4. Paste it into your .env.local as DISCORD_WEBHOOK_URL.

πŸ”₯ Firebase Visitor Counter

  1. Go to Firebase Console and create a new project.
  2. Navigate to Firestore Database and create a database (Start in production mode).
  3. Go to Project Settings > General > Your apps > Web app (</> icon).
  4. Register the app and copy the firebaseConfig object values to your .env.local.
  5. Important: Set Firestore Rules to allow read/write for the counter:
    rules_version = '2';
    service cloud.firestore {
      match /databases/{database}/documents {
        match /site_stats/visitors {
          allow read, write: if true;
        }
      }
    }

πŸ’‘ Features & Usage

πŸ”— Source Tracking

Track where your visitors are coming from by adding a ?ref= parameter to your URL.

  • LinkedIn: your-site.com/?ref=linkedin
  • Twitter: your-site.com/?ref=twitter
  • Instagram: your-site.com/?ref=instagram

The Discord notification will show "πŸ”— Source: linkedin".

Available Scripts

# Development server (with Turbopack)
npm run dev

# Build for production
npm run build

# Start production server
npm start

# Lint code
npm run lint

# Type checking
npm run typecheck

πŸ“¦ Project Structure

portfolio/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ app/              # Next.js app directory
β”‚   β”‚   β”œβ”€β”€ api/chat/     # Groq-backed assistant endpoint
β”‚   β”‚   β”œβ”€β”€ globals.css   # Global styles and animations
β”‚   β”‚   β”œβ”€β”€ layout.tsx    # Root layout with theme provider
β”‚   β”‚   β”œβ”€β”€ page.tsx      # Home page
β”‚   β”‚   └── sitemap.ts    # Dynamic sitemap generation
β”‚   β”œβ”€β”€ components/       # React components
β”‚   β”‚   β”œβ”€β”€ assistant/    # Hakkan Bot chat UI + 3D bot
β”‚   β”‚   β”œβ”€β”€ games/        # Interactive mini-games
β”‚   β”‚   β”œβ”€β”€ ui/           # shadcn/ui components
β”‚   β”‚   β”œβ”€β”€ hero-section.tsx
β”‚   β”‚   β”œβ”€β”€ about-section.tsx
β”‚   β”‚   β”œβ”€β”€ skills-section.tsx
β”‚   β”‚   └── ...
β”‚   β”œβ”€β”€ content/          # Prose the site doesn't render
β”‚   β”‚   └── profile.ts    # What the bot knows beyond data.ts  ← edit me
β”‚   β”œβ”€β”€ hooks/            # Custom React hooks
β”‚   └── lib/              # Utilities and data
β”‚       β”œβ”€β”€ assistant/    # Bot: prompt building, API client, voice
β”‚       β”œβ”€β”€ data.ts       # Portfolio content data              ← edit me
β”‚       β”œβ”€β”€ sound.ts      # Audio utilities
β”‚       └── utils.ts      # Helper functions
β”œβ”€β”€ public/               # Static assets
β”œβ”€β”€ .gitignore
β”œβ”€β”€ next.config.ts        # Next.js configuration
β”œβ”€β”€ tailwind.config.ts    # Tailwind configuration
β”œβ”€β”€ tsconfig.json         # TypeScript configuration
└── package.json

🎨 Customization

Update Portfolio Content

Edit src/lib/data.ts to customize:

  • Personal information
  • Skills and expertise
  • Work experience
  • Projects
  • Education
  • Certifications

This is also what the AI assistant reads, so the site and the bot can never drift apart. For the bot's tone and anything the site doesn't display, edit src/content/profile.ts.

Modify Theme Colors

Update tailwind.config.ts to change color scheme:

theme: {
  extend: {
    colors: {
      // Customize your colors here
    }
  }
}

Configure Animations

Adjust animation settings in src/app/globals.css:

@keyframes your-animation {
  /* Custom animation keyframes */
}

πŸš€ Deployment

Environment variables

Set these in Vercel β†’ Project β†’ Settings β†’ Environment Variables (Production, Preview and Development), and mirror them in a local .env.local. See .env.example.

Variable Required Notes
GROQ_API_KEY Yes, for the bot Without it the site works fine and the bot says it isn't configured. Server-only β€” never prefix with NEXT_PUBLIC_.
GROQ_MODEL No Overrides the default model. Change here instead of redeploying code when Groq retires a model.
NEXT_PUBLIC_SITE_URL Recommended Locks /api/chat to your own origin. www., *.vercel.app previews and localhost are allowed automatically. Leave unset and the check is skipped. Inlined at build time, so changing it needs a redeploy.
RESEND_API_KEY For the contact form
DISCORD_WEBHOOK_URL For visitor pings
NEXT_PUBLIC_FIREBASE_* For the visitor counter

Pre-flight checklist

npm run typecheck   # must be clean β€” type errors now fail the build
npm run build
  • GROQ_API_KEY set in Vercel, and a spend limit set in the Groq console β€” /api/chat is a public endpoint that costs money per call
  • Model id in GROQ_MODEL still listed at console.groq.com/docs/models
  • src/content/profile.ts has no TODO left that you care about
  • Ask the deployed bot "where do you work now" β€” it must say Persist

Deploy to Vercel (Recommended)

  1. Push your code to GitHub
  2. Import your repository on Vercel
  3. Add the environment variables above
  4. Deploy!

Note: /api/chat runs on the Node runtime with maxDuration = 15s and aborts the upstream call at 8s. On the Vercel Hobby plan that sits inside the function limit.

Deploy with Vercel

Deploy to Netlify

  1. Push your code to GitHub
  2. Connect your repository on Netlify
  3. Build command: npm run build
  4. Publish directory: .next
  5. Deploy!

Deploy to Firebase Hosting

# Build the project
npm run build

# Deploy to Firebase
firebase deploy

πŸ“„ License

This project is open source and available under the MIT License.

🀝 Connect

πŸ™ Acknowledgments


Built with ❀️ by Hakkan Shah

⭐ Star this repo if you find it helpful!

Releases

Packages

Contributors

Languages