Skip to content

Latest commit

 

History

History
280 lines (244 loc) · 10.5 KB

File metadata and controls

280 lines (244 loc) · 10.5 KB

Project Detail Page Implementation

Overview

This document describes the implementation of the project detail page feature using Next.js 16 Parallel Routes (Intercept Routes) and React 19 View Transition API for smooth animations.

Status: ✅ COMPLETED (2025-11-21) Implementation Time: ~6 hours

Features Implemented

1. Intercept Routes with Modal Display

  • Created a parallel route slot @modal for displaying project details in a modal overlay
  • Implemented intercept route at @modal/(.)project/[slug] to catch navigation from the project list page
  • Modal displays project details without full page navigation when accessed from the list
  • Direct navigation to /project/[slug] still works normally and shows the full page
  • Works seamlessly with i18n routing (/[locale]/project/[slug])

2. React 19 View Transition API Integration

  • Integrated React 19's native <ViewTransition> component for smooth animations
  • View transition names applied to key elements:
    • project-detail-image-{slug} - Animates the project thumbnail
    • project-detail-title-{slug} - Animates the project title
    • project-modal - Modal container transition
    • project-modal-content - Modal content transition
  • Graceful fallback for browsers that don't support View Transitions API
  • Configured multiple transition modes: default, enter, exit, share, update

3. Modal Component

  • Created a reusable Modal component using native HTML <dialog> element
  • Features:
    • Backdrop blur effect with dark overlay
    • Close button (top-right corner)
    • Click outside to close (via dialog.close())
    • Keyboard ESC key to close
    • Prevents body scroll when open
    • Smooth enter/exit animations with ViewTransition
    • Router.back() integration for natural navigation flow

4. Comprehensive Project Detail Page

  • Header Section: Title, summary, period, team, role, external links
  • Hero Image: Full-width responsive thumbnail with View Transition
  • Overview Section: Background, goal, features list
  • Tech Stack Section: Technology tags display
  • Challenges & Solutions: Paired problem-solution layout with visual distinction
  • Achievements Section:
    • Metrics cards (grid layout)
    • User feedback bullets
    • Improvement highlights
  • Gallery Section: Image gallery with lightbox functionality
  • Navigation: Back to projects link
  • Responsive Design: Mobile-first approach with breakpoints

5. Image Gallery Component

  • Thumbnail Grid: 1/2/3 column responsive layout
  • Lightbox Modal: Full-screen image viewer with dark overlay
  • Navigation: Previous/Next buttons and keyboard arrows
  • Features:
    • Click to open full-size image
    • Keyboard navigation (←/→ arrows, ESC to close)
    • Image counter display (e.g., "2 / 5")
    • Image captions support
    • Hover effects with scale animation
    • Body scroll lock when open
    • Click outside to close

File Structure

src/
├── app/
│   └── [locale]/
│       ├── @modal/                          # Parallel route slot for modals
│       │   ├── default.tsx                  # Default (empty) modal state
│       │   └── (.)project/                  # Intercept route
│       │       └── [slug]/
│       │           └── page.tsx             # Modal project detail page
│       ├── project/
│       │   ├── page.tsx                     # Project list page
│       │   └── [slug]/
│       │       └── page.tsx                 # Full project detail page
│       └── layout.tsx                       # Updated to support modal slot
├── pages-layer/
│   └── project/
│       ├── index.tsx                        # Project list component
│       ├── item/
│       │   └── index.tsx                    # Project item (updated with TransitionLink)
│       └── [slug]/
│           └── index.tsx                    # Project detail component (with view-transition-name)
├── shared/
│   ├── constant/
│   │   └── project-detail.tsx               # Project detail data
│   └── ui/
│       ├── modal.tsx                        # Modal component (NEW)
│       ├── transition-link.tsx              # TransitionLink wrapper (NEW)
│       └── image-gallery.tsx                # Image gallery component
└── globals.css                              # Added view transition styles

Key Implementation Details

Layout Update (src/app/[locale]/layout.tsx)

export default async function LocaleLayout({
  children,
  modal,  // Added modal slot
  params,
}: {
  children: React.ReactNode;
  modal: React.ReactNode;  // Parallel route slot
  params: Promise<{ locale: string }>;
}) {
  // ...
  return (
    // ...
    {children}
    {modal}  // Modal renders here when active
    // ...
  );
}

Intercept Route (@modal/(.)project/[slug]/page.tsx)

  • Uses (.) syntax to intercept same-level navigation
  • Wraps ProjectDetailPage in Modal component
  • Server component that fetches project data

React 19 ViewTransition Component

  • Uses React 19's built-in <ViewTransition> component
  • Declarative API for view transitions
  • Props: name, default, enter, exit, share, update
  • No manual document.startViewTransition() required
  • Automatic handling of transition lifecycle

View Transition Styles (globals.css)

/* Configured via React 19 ViewTransition component props */
/* No manual CSS required for basic transitions */
/* Browser handles animation automatically based on view-transition-name */

Browser Compatibility

View Transition API

  • ✅ Chrome 111+
  • ✅ Edge 111+
  • ✅ Opera 97+
  • ❌ Firefox (not yet supported)
  • ❌ Safari (not yet supported)

The implementation includes automatic fallback for unsupported browsers - they will see instant navigation without transitions.

Intercept Routes

  • Works on all browsers as it's a Next.js routing feature
  • No special browser requirements

Data Structure

ProjectDetail Type

Located in src/shared/constant/project-detail.tsx:

export type ProjectDetail = {
  slug: string;                    // URL parameter
  title: string;
  thumbnail: string | StaticImageData;
  summary: string;
  period: string;
  team: string;
  role: string;
  links: {
    github?: string;
    demo?: string;
    etc?: { label: string; url: string }[];
  };
  overview: {
    background: string;
    goal: string;
    features: string[];
  };
  tech: {
    stack: TechStackEnum[];
    challenges: { title: string; description: string }[];
    solutions: { title: string; description: string }[];
  };
  achievements: {
    metrics?: { label: string; value: string }[];
    feedback?: string[];
    improvements?: string[];
  };
  gallery: {
    src: string | StaticImageData;
    alt: string;
    caption?: string;
  }[];
  metadata: {
    publishedAt: string;
    updatedAt?: string;
    tags: string[];
  };
};

Sample Projects

4 projects fully documented:

  1. POCAZ - 아이돌 포토카드 거래 플랫폼
  2. 법률사무소 대도 - 법률사무소 웹사이트
  3. 메뉴 고르기 앱 - 카페 메뉴 추천 서비스
  4. 역대카 - 렌트카 가격 비교 서비스

Testing

Manual Testing Steps ✅ PASSED

  1. Start dev server: pnpm dev
  2. Navigate to projects page: /project or /en/project
  3. Click on a project card: Should open modal with smooth transition
  4. Test close modal:
    • ✅ Click close button
    • ✅ Press ESC key
    • ✅ Click backdrop
  5. Test direct navigation: Open /project/pocaz in new tab - shows full page
  6. Test browser back: Click project → modal opens → press browser back → modal closes
  7. Test transitions: Smooth animation of image and title (Chrome/Edge)
  8. Test i18n: Switch language, modal should work in both KO/EN
  9. Test image gallery: Click gallery images, navigate with arrows, ESC to close
  10. Test responsive: Check mobile, tablet, desktop layouts

Expected Behavior (All Verified ✅)

  • ✅ Modal opens smoothly when clicking project from list
  • ✅ View transitions animate (Chrome/Edge/Opera)
  • ✅ Direct URL access shows full page (not modal)
  • ✅ Browser back/forward works correctly
  • ✅ Modal closes on ESC, close button, or backdrop click
  • ✅ Body scroll locked when modal open
  • ✅ Accessibility: Focus management, keyboard navigation
  • ✅ Image gallery lightbox works with keyboard navigation
  • ✅ Responsive design works on all screen sizes
  • ✅ i18n integration works seamlessly

Performance Considerations

  1. Code Splitting: Modal and transition code only loads when needed
  2. Image Optimization: Next.js Image component handles lazy loading
  3. View Transitions: GPU-accelerated animations
  4. Server Components: Project data fetched on server, reducing client JS

Lessons Learned

React 19 View Transitions

  • React 19's <ViewTransition> component provides a cleaner, more declarative API compared to manual document.startViewTransition()
  • Multiple transition modes (default, enter, exit, share, update) allow fine-grained control
  • Integrates seamlessly with React's component lifecycle

Next.js 16 Routing Patterns

  • Parallel routes (@modal) and intercepting routes ((.)) work perfectly together for modal UX
  • Must provide default.tsx for parallel route slots
  • Layout must explicitly declare modal slot in props
  • Works seamlessly with i18n routing

Image Gallery Implementation

  • Native HTML <dialog> provides excellent accessibility out of the box
  • Keyboard navigation significantly improves UX
  • Body scroll lock prevents awkward scrolling behavior
  • Lightbox pattern is essential for portfolio projects

Future Enhancements

  • Add swipe gestures to close modal (mobile)
  • Implement keyboard navigation between projects in modal (←/→ to switch projects)
  • Add loading skeleton while images load
  • Consider adding video embed support in gallery
  • Add analytics tracking for modal interactions
  • Implement project comparison feature
  • Add social share buttons for individual projects

References