Portfolio Neeta

Full-stack portfolio site for Neeta Bhusal — built with Next.js 16, MongoDB, and a custom admin CMS.

Documentation

DocumentDescription
ArchitectureHigh-level design, system layers, data flow, tech stack rationale
Low-Level DesignModule breakdown: routes, controllers, services, repos, models, hooks
API ReferenceAll endpoints, request/response shapes, validation schemas
Database SchemaModels, fields, indexes, enums, entity relationships
Component TreeFull component hierarchy, server/client split, UI primitives
User JourneysFlows for visitors, clients, and admin
Deployment GuideEnvironment setup, Vercel deployment, troubleshooting
SecurityAuth flow, middleware, XSS/CSRF prevention, input validation
ScreenshotsPage-by-page walkthrough with desktop and mobile viewport screenshots

Tech Stack

LayerTechnology
FrameworkNext.js 16.2.4 (App Router)
UIReact 19.2.4, shadcn/ui (Radix), Tailwind CSS v4
DatabaseMongoDB + Mongoose 8
AuthJWT (jose + jsonwebtoken), bcryptjs
ImagesCloudinary (upload, transform, delivery)
Data FetchingTanStack React Query 5
AnimationsGSAP 3.15 + ScrollTrigger
ValidationZod 3
Iconsreact-icons, @radix-ui/react-icons
Themenext-themes (dark/light)
EmailNodemailer (SMTP)
AnalyticsVercel Analytics
Package Managernpm

Features

  • Portfolio — Projects listing with search, filter by category, pagination, and detail pages
  • Logo Request — Multi-step form with auto-save, email notifications, and public status tracking
  • Admin CMS — Login/signup, create/edit projects with image upload, manage requests
  • Authentication — JWT-based auth with httpOnly cookies and middleware-protected routes
  • Cloudinary Integration — Image upload with signed signatures, responsive delivery via hydrateProject()
  • SEO — Dynamic metadata, sitemap, robots.txt, Open Graph / Twitter cards
  • Animations — GSAP scroll reveals and hover effects
  • Dark Mode — Default dark with next-themes toggle
  • Responsive — Mobile-first, Tailwind responsive utilities

Getting Started

Prerequisites

  • Node.js 20+
  • MongoDB (local or Atlas)
  • Cloudinary account

Setup

# Install dependencies
npm install

# Copy environment variables
cp .env.example .env
# Edit .env with your MongoDB URI, JWT secret, and Cloudinary credentials

# Run development server
npm run dev

Open http://localhost:3000 in your browser.

Scripts

ScriptCommandPurpose
devnext dev --webpackStart dev server
buildnext build --webpackBuild for production
startnext startStart production server
linteslintLint all files

Architecture

The backend follows a layered pattern:

Route (API) → Controller → Service → Repository → Mongoose Model
  • Controllers — Parse request, call service, format response
  • Services — Business logic, validation, cross-cutting concerns
  • Repositories — Database queries (Mongoose)
  • Models — Schema definitions

Server components fetch public/site.json directly. Client components use TanStack Query to call API routes.

Data Flow

  1. Public pages — Server component reads public/site.json, passes data as props to client components
  2. Projects — Server component queries MongoDB via controller/service/repository, returns hydrated data
  3. Admin — Authenticated users CRUD projects via /api/projects (POST/PATCH), images via Cloudinary signed uploads

Environment Variables

VariableRequiredDefaultDescription
MONGODB_URIYesMongoDB connection string
JWT_SECRETYesSecret for signing JWTs
CLOUDINARY_CLOUD_NAMEYesCloudinary cloud name
CLOUDINARY_API_KEYYesCloudinary API key
CLOUDINARY_API_SECRETYesCloudinary API secret
CLOUDINARY_FOLDER_NAMENoUpload folder
AUTH_COOKIE_NAMENonb_authAuth cookie name
JWT_MAX_AGENo2592000Token lifetime (seconds)
DISABLE_ONBOARDINGNotrueDisable signup route

Deployment

See Deployment Guide for full setup instructions.

Key Conventions

  • Server components are the default; add "use client" only when needed (hooks, browser APIs, state)
  • Data fetching from site.json uses fetchJson() with Next.js cache; from MongoDB uses repository pattern
  • Project images live on Cloudinary; hydrateProject() enriches project objects with imageUrl and downloadUrl
  • Animations use [data-reveal] and [data-hover-lift] attributes consumed by useGSAP hook
  • API responses follow a standard { success, data/error } format via successResponse() / errorResponse()
  • Icons are centralized in lib/iconMapper.ts mapping string names to react-icons components

Screenshots

Main Page

Main Page

Full page-by-page walkthrough with desktop and mobile views: docs/screenshots.md.

Project Details

Stars0
Forks0
LanguageTypeScript
LicenseMIT
UpdatedJul 11, 2026