{"id":49655677,"url":"https://github.com/shadowdevcode/vijay-portfolio","last_synced_at":"2026-05-06T09:05:41.142Z","repository":{"id":346529452,"uuid":"1116072571","full_name":"shadowdevcode/vijay-portfolio","owner":"shadowdevcode","description":"My vibe coded portfolio website","archived":false,"fork":false,"pushed_at":"2026-04-29T00:26:27.000Z","size":3331,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-29T00:28:32.373Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://vijay-portfolio-pink.vercel.app","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shadowdevcode.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-12-14T06:13:23.000Z","updated_at":"2026-04-29T00:26:31.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/shadowdevcode/vijay-portfolio","commit_stats":null,"previous_names":["shadowdevcode/vijay-portfolio"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/shadowdevcode/vijay-portfolio","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shadowdevcode%2Fvijay-portfolio","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shadowdevcode%2Fvijay-portfolio/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shadowdevcode%2Fvijay-portfolio/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shadowdevcode%2Fvijay-portfolio/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shadowdevcode","download_url":"https://codeload.github.com/shadowdevcode/vijay-portfolio/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shadowdevcode%2Fvijay-portfolio/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32686273,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-06T08:33:17.875Z","status":"ssl_error","status_checked_at":"2026-05-06T08:33:17.221Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-05-06T09:05:40.429Z","updated_at":"2026-05-06T09:05:41.136Z","avatar_url":"https://github.com/shadowdevcode.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Vijay Sehgal — AI Product Manager Portfolio\n\nA modern, recruiter-optimized portfolio built with **React 19 + Vite + Tailwind CSS**. Features an AI chat assistant (powered by Google Gemini), structured proof-of-impact metrics, filterable case studies, and a clear conversion funnel.\n\n**Live site:** _deploy via Vercel + custom domain_\n\n---\n\n## Quick Start\n\n```bash\n# 1. Install dependencies\nbun install\n\n# 2. Set up environment variables\ncp .env.example .env\n# Edit .env → add your GEMINI_API_KEY (get one at https://aistudio.google.com)\n\n# 3. Start the dev server (chatbot works locally via dev middleware)\nbun run dev\n```\n\nOpen [http://localhost:5173](http://localhost:5173) in your browser.\n\n---\n\n## Tech Stack\n\n| Layer         | Technology                                  |\n| ------------- | ------------------------------------------- |\n| **Framework** | React 19 + TypeScript                       |\n| **Build**     | Vite 5                                      |\n| **Styling**   | Tailwind CSS 3 (local pipeline, not CDN)    |\n| **AI Chat**   | Google Gemini 2.5 Flash (server-side proxy) |\n| **Icons**     | Lucide React                                |\n| **Hosting**   | Vercel (serverless functions for API)       |\n\n---\n\n## Project Structure\n\n```\nvijay-portfolio/\n├── api/                        # Vercel serverless functions (server-side only)\n│   └── chat.ts                 #   POST /api/chat — Gemini proxy with rate limiting\n├── components/                 # React UI components\n│   ├── Hero.tsx                #   Landing: name, title, roles, availability, CTAs\n│   ├── ProofOfImpact.tsx       #   Compact metric cards (before → after)\n│   ├── Projects.tsx            #   Case studies with segment filter chips\n│   ├── Experience.tsx          #   Work timeline with impact bullets\n│   ├── Skills.tsx              #   Filterable skill tags by category\n│   ├── Education.tsx           #   Degrees (cards) + certifications (inline badges)\n│   ├── Blog.tsx                #   Writing \u0026 insights feed\n│   ├── ContactCTA.tsx          #   Conversion: call booking, email, resume download\n│   ├── ChatWidget.tsx          #   Floating AI chat assistant\n│   ├── Navbar.tsx              #   Floating bottom nav with scroll-spy\n│   ├── Footer.tsx              #   Footer with social links\n│   └── ErrorBoundary.tsx       #   React error boundary\n├── data/\n│   └── system-prompt.ts        #   Shared chatbot prompt (dev + prod use same)\n├── services/\n│   └── geminiService.ts        #   Client-side chat service (calls /api/chat)\n├── constants.tsx               #   All portfolio data — EDIT THIS TO UPDATE CONTENT\n├── types.ts                    #   TypeScript interfaces for all data models\n├── App.tsx                     #   Root component (section ordering + scroll spy)\n├── index.tsx                   #   React DOM entry point\n├── index.html                  #   HTML shell with SEO meta + structured data\n├── index.css                   #   Tailwind directives + custom animations\n├── tailwind.config.js          #   Tailwind theme config\n├── postcss.config.js           #   PostCSS pipeline\n├── vite.config.ts              #   Vite build + dev chat middleware\n├── vercel.json                 #   Vercel SPA routing config\n├── public/\n│   ├── Gemini-headshot.png     #   Profile photo (optimize to \u003c 100 KB)\n│   ├── resume.pdf              #   (You add this) Downloadable resume\n│   ├── sitemap.xml             #   SEO sitemap\n│   └── robots.txt              #   Crawler directives\n├── .env.example                #   Env variable template\n├── .env                        #   (Gitignored) Your actual API key\n├── CONTRIBUTING.md             #   Content refresh cadence + checklists\n└── package.json\n```\n\n### Section Order (in `App.tsx`)\n\nThe page is structured for a **recruiter scan flow** — proof of work comes first:\n\n```\nHero → Proof of Impact → Case Studies → Work Experience → Skills → Education → Writing → Contact CTA\n```\n\nNav order matches: **Home → About → Projects → Work → Skills → Writing**\n\n---\n\n## How to Update Content\n\n**All portfolio data lives in one file:** [`constants.tsx`](constants.tsx)\n\n### Adding a new case study\n\nAdd an entry to the `PROJECTS` array:\n\n```tsx\n{\n  title: \"Project Name\",\n  subtitle: \"Type\",\n  description: \"One-line description...\",\n  tags: [\"#Tag1\", \"#Tag2\"],\n  metrics: [\"Metric 1\", \"Metric 2\"],\n  highlights: [\"Bullet 1\", \"Bullet 2\"],\n  segment: \"AI\",               // Used for filter chips\n  caseStudyAvailable: true,\n  link: \"https://notion.so/...\"\n}\n```\n\n### Adding a new impact metric\n\nAdd to the `IMPACT_METRICS` array:\n\n```tsx\n{\n  label: \"Metric Name\",\n  baseline: \"Before state\",\n  action: \"What you did\",\n  result: \"After state\",\n  confidence: \"Measured\",        // \"Measured\" | \"Estimated\" | \"Projected\"\n  source: \"Company Name\",\n}\n```\n\n### Adding a blog post\n\nAdd to `BLOG_POSTS` with `title`, `excerpt`, `date`, `readTime`, `tags`, `link`, and `source`.\n\n### Adding your resume PDF\n\nPlace your resume at **`public/resume.pdf`**. The \"Download Resume\" button in Hero and ContactCTA is already wired to `/resume.pdf`.\n\n---\n\n## Environment Variables\n\n| Variable         | Required | Description                                                                                                                                   |\n| ---------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------- |\n| `GEMINI_API_KEY` | Yes      | Google Gemini API key. **Server-side only** — never exposed to the browser. In dev, read from `.env`. In production, set in Vercel dashboard. |\n\n---\n\n## Architecture: How the AI Chat Works\n\n```\n┌─ Development (bun run dev) ─────────────────────┐\n│                                                  │\n│  Browser → geminiService.ts → fetch('/api/chat') │\n│                    ↓                             │\n│  Vite dev middleware (vite.config.ts)             │\n│     ├── Reads GEMINI_API_KEY from .env            │\n│     ├── Calls Gemini SDK directly                 │\n│     └── Returns { reply }                         │\n└──────────────────────────────────────────────────┘\n\n┌─ Production (Vercel) ───────────────────────────┐\n│                                                  │\n│  Browser → geminiService.ts → fetch('/api/chat') │\n│                    ↓                             │\n│  api/chat.ts (Vercel Serverless Function)        │\n│     ├── Validates input (non-empty, \u003c1000 chars) │\n│     ├── Rate limits per IP (10 req/min)           │\n│     ├── Reads GEMINI_API_KEY from env vars        │\n│     ├── Calls Gemini 2.5 Flash                    │\n│     └── Returns { reply }                         │\n└──────────────────────────────────────────────────┘\n\nBoth use the same system prompt from data/system-prompt.ts\n```\n\nThe API key **never** reaches the browser in either environment.\n\n---\n\n## Deployment (Vercel)\n\n1. Push to GitHub.\n2. Connect repo to [Vercel](https://vercel.com).\n3. In Vercel dashboard → **Settings → Environment Variables**:\n   - Add `GEMINI_API_KEY` = your Gemini API key.\n4. Deploy. Vercel auto-detects the Vite build and `/api` serverless functions.\n\nFor a custom domain:\n\n- Go to **Vercel → Settings → Domains** → Add your domain and follow DNS instructions.\n\n---\n\n## Scripts\n\n| Command           | Description                                             |\n| ----------------- | ------------------------------------------------------- |\n| `bun run dev`     | Start local dev server (port 5173) with chat middleware |\n| `bun run build`   | Production build to `dist/`                             |\n| `bun run preview` | Preview the production build locally                    |\n\n---\n\n## License\n\n© 2026 Vijay Sehgal. All rights reserved.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshadowdevcode%2Fvijay-portfolio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshadowdevcode%2Fvijay-portfolio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshadowdevcode%2Fvijay-portfolio/lists"}