A modern portfolio website built with Next.js 14, TypeScript, and Tailwind CSS.
- ⚡ Built with Next.js 14 App Router
- 🎨 Styled with Tailwind CSS
- 📱 Fully responsive design
- 🌙 Modern hero section with GitHub contributions graph
- 💼 Experience, Skills, Projects, and Education sections
- 🔗 Social media links with interactive hover effects
- Node.js 18.17 or later
- npm or yarn
-
Navigate to the project directory:
cd nextjs-portfolio -
Install dependencies:
npm install
-
Copy your assets from the parent
Assestsfolder topublic/:cp -r ../Assests/* public/ -
Run the development server:
npm run dev
-
Open http://localhost:3000 in your browser.
nextjs-portfolio/
├── public/ # Static assets (images, favicon, resume)
├── src/
│ ├── app/
│ │ ├── globals.css # Global styles
│ │ ├── layout.tsx # Root layout
│ │ └── page.tsx # Home page
│ └── components/
│ ├── Header.tsx
│ ├── Hero.tsx
│ ├── GitHubContributions.tsx
│ ├── Experience.tsx
│ ├── Skills.tsx
│ ├── Work.tsx
│ ├── Education.tsx
│ └── Footer.tsx
├── package.json
├── tailwind.config.ts
├── tsconfig.json
└── next.config.js
npm run build
npm startThis project can be easily deployed on Vercel, Netlify, or any other hosting platform that supports Next.js.
MIT
The site stores contact messages, resume uploads and anonymous page views in Supabase. Everything runs server-side with the secret key; nothing Supabase-related is shipped to the browser.
- Create a Supabase project, open SQL → New query, paste
supabase/schema.sqland run it. It creates the tables (with row level security on), the publicresumestorage bucket and the analytics functions. - Copy
.env.exampleto.env.localand fill inSUPABASE_URL,SUPABASE_SECRET_KEY,ADMIN_PASSWORDandADMIN_SESSION_SECRET(openssl rand -base64 48). Optionally addGITHUB_TOKEN(a read-only token) for the GitHub widget. - Add the same variables in Vercel → Project → Settings → Environment Variables and redeploy.
Routes:
/contact: public contact form (honeypot, timing check and 5 messages per hour per visitor)./admin: password-protected dashboard (analytics),/admin/messages(inbox),/admin/resume(upload a new PDF;/resumeupdates immediately)./api/track: records an anonymous page view (no cookies, no stored IPs; bots and the signed-in admin are skipped)./api/views: public total visit count shown in the footer.
Without the environment variables the site still builds and runs: the contact form shows an email fallback,
the visit counter is hidden and /resume serves public/Kevish_Resume.pdf.