Skip to content

yourlcfr/daffa-portfolio

Repository files navigation

Daffa Ananda Rizki — Portfolio

Bilingual (ID/EN) developer portfolio where the full-tier experience is an explorable 3D world built with React Three Fiber. A semantic DOM fallback is always served underneath.

What this is

My personal site, rebuilt as a small navigable space instead of a scroll page. Nine destinations float in a dark field — 4 infrastructure nodes, 4 project case studies, 1 operator beacon. You fly between them: drag to orbit, scroll or W/S to dolly, click a node to dock, Esc to leave. Case studies render on in-world billboards rather than DOM overlays. If your device can't or shouldn't run it, you get a plain crawlable page instead — that fallback is a hard requirement in the spec, not a degradation path bolted on later.

Engineering notes

The parts I'd actually point at in a review:

  • Three-tier capability gate (src/components/webgl/capability.tsx): off (prefers-reduced-motion or no WebGL2 → semantic DOM + poster), lite (coarse pointer or <1024px → lightweight scene), full (desktop, post-processed). Decided once at mount, not sniffed per-frame.
  • Hash deep-links (src/components/webgl/hashSync.ts): #destination docks the camera on load and on hashchange. Lookups go through Object.hasOwn so a hash like #constructor can't walk the prototype chain and crash the dock. Docking rewrites the hash without pushing history entries; unknown hashes fall through to native anchor behavior.
  • Pure camera math (src/components/webgl/orbitMath.ts): orbit/dolly/fly-to as a dependency-free module with pitch and distance clamps and a documented calibration knob. 9 unit tests, zero three.js imports.
  • React 19 + postprocessing fix (commit c4e36b1): React 19 passes ref as a regular prop, which breaks @react-three/postprocessing's JSON.stringify-based memoization. Switched to callback refs on effect components.
  • Typed bilingual content: next-intl locale routing (id/en), 71 message keys per locale in exact parity, plus a Localized<T> model so no in-world copy is hard-coded. Parity is checked by a content-integrity test, not by hand.
  • Case studies as data (src/content/work.ts, W-01..W-04): each entry follows a fixed schema — problem, decision, tradeoff, metric, outcome, what I'd change, point of view. No MDX, no CMS, no database.
  • Command palette (src/components/agent/CommandPalette.tsx): scripted keyword Q&A whose answers can fly the camera to the node they reference. The resolver contract ({answer, focus?, scrollTo?}) is deliberately narrow so an LLM backend could replace the script without touching the UI.
  • Build isolation: next.config.ts honors NEXT_BUILD_DIR, so CI builds never clobber .next under a running dev server.
  • Test surface: 41 cases in 14 files — 13 Vitest suites (orbit math, map physics, hash sync, contact schema, i18n routing, sitemap, content integrity) plus a Playwright e2e covering home load, language toggle, and contact submit.

The world supersedes an earlier pin-scroll journey (GSAP ScrollTrigger + Lenis) — +2,898/−211 across 32 files on top of it; the src/components/webgl module alone is 2,193 LOC across 25 files.

Stack

  • Next.js 15 (App Router), React 19, TypeScript 6
  • three 0.184 / @react-three/fiber 9 / drei 10 / postprocessing 3
  • Tailwind CSS 4, next-intl 3, GSAP 3 + Lenis
  • Zod 4 + Resend for the contact API
  • Vitest 4 + Testing Library, Playwright

Screenshots

The world — nine destinations in a dark field

Docked on a destination — case study on an in-world billboard

Getting started

pnpm install
pnpm dev           # http://localhost:3100
pnpm test          # Vitest unit/component suites
pnpm e2e           # Playwright (needs a built or running app)
pnpm typecheck
pnpm build

Contact form needs RESEND_API_KEY — copy .env.example to .env and fill it in. Everything else runs without configuration; content is static typed TS, no database.

License

MIT

About

Bilingual portfolio as an explorable React Three Fiber 3D world — free-fly camera, dockable nodes, in-world billboards

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages