Last updated: March 1, 2026
Single-Page Application for displaying an image gallery with infinite scroll and keyword filtering.
Live: https://image-gallery-thanakrit-thanyawatsa.vercel.app/
- Logo – Header and footer use
public/image-gallery-icon.webp. - Premium UI & UX – Glassmorphism, Framer Motion animations, and design tokens (Tailwind v4). Nav hides on scroll down, shows on scroll up.
- Theme toggle – Light / Dark / System in header; preference stored in
localStorage; no flash on load (inline script in layout). - Loading skeleton – Grid of 12 pulse placeholders while initial gallery loads (replaces dots + text).
- Advanced Masonry Layout – Stable JavaScript-based distribution algorithm that eliminates layout shift (Zero Layout Shift) during infinite scroll.
- Interactive Lightbox – Full-screen modal with Next/Prev navigation, keyboard support (Arrow keys/ESC), and zoom transitions.
- Performance Optimized – LCP priority loading, skeleton states, and hardware-accelerated transitions.
- Infinite Scroll – Intelligent loading with smooth sentinel detection and animated feedback.
- Keyword Filtering – Dynamic active filtering; on desktop in header, on mobile a floating pill (section) bottom-left when a filter is active.
- Micro-interactions – Ripple effects on hashtag clicks and subtle card entrance animations for elite feedback.
- Frontend: Next.js 16, React 19, TypeScript, Tailwind CSS, Framer Motion
- Quality: ESLint, Prettier, Vitest, SonarQube, Husky, Commitlint
- CI/CD: GitHub Actions
All checks must pass before submit. Current bar:
- ESLint –
npm run lint(no errors/warnings) - Prettier –
npm run format:check - TypeScript –
npm run type-check - Unit tests –
npm run test:coverage(100% coverage) - E2E –
npm run test:e2e(Playwright) - SonarQube –
npm run sonar(Quality Gate pass: 0 open issues, 100% coverage, no duplications). Optional; see SETUP.md for Docker.
See docs/CODING_STANDARDS.md for full standards.
Accessibility & theme: Theme toggle (Light/Dark/System) in header; contrast and focus states target WCAG AA via design tokens in globals.css. Motion respects prefers-reduced-motion.
- Node.js 20+
- npm
npm install
npm run devOpen http://localhost:3000 in your browser.
| Command | Description |
|---|---|
npm run dev |
Run development server |
npm run build |
Build for production |
npm run start |
Run production server |
npm run lint |
Run ESLint |
npm run format |
Format code with Prettier |
npm run test |
Run unit tests (Vitest) |
npm run test:coverage |
Run tests with coverage report |
npm run test:e2e |
Run E2E tests (Playwright) |
npm run test:e2e:ui |
Run E2E tests with UI mode |
npm run test:e2e:report |
Open Playwright HTML report |
npm run sonar |
Run SonarQube scan (optional) |
src/
├── app/ # App Router pages
├── components/ # Shared components
└── lib/ # Utils, hooks, data
__tests__/ # Unit tests (Vitest)
e2e/ # E2E tests (Playwright)
docs/ # Documentation
With MySQL, the app uses the API. Without it, mock data is used.
# Set DATABASE_URL in .env (see .env.example)
npm run db:generate
npm run db:push
npm run db:seed
npm run db:studio # Optional: Prisma Studio UIYou can run and test the app in three ways:
| Option | Description |
|---|---|
| Vercel | Deployed. Live URL. No setup required. Uses mock data when no database is connected. |
| Docker | From the project folder: docker compose up -d, then docker compose exec app npm run db:push && npm run db:seed. App at http://localhost:3000 with MySQL. |
| Zip / Clone | Unzip or clone the repo → npm install → npm run dev → open http://localhost:3000. Uses mock data when no database is configured. |
See docs/DEPLOY.md and SETUP.md for details.
- PRD.md – Product Requirements Document
- docs/PROJECT_STATUS.md – Project status (what’s done)
- docs/CODING_STANDARDS.md – Coding standards
- docs/ARCHITECTURE.md – Architecture diagram
- docs/DEPLOY.md – Deployment guide
- SETUP.md – Setup guide
- CONTRIBUTING.md – How to contribute
- Vercel: App is deployed on Vercel. See docs/DEPLOY.md for details.
- Docker:
docker compose up -d– App + MySQL (see docs/DEPLOY.md) - Ubuntu + PM2: See docs/DEPLOY.md
Build for production:
npm run build
npm run start