Ctrl K
ComunidadGuías…

docs/plans/2026-03-16-ui-redesign-full.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# PicImpact Full UI Redesign — Implementation Plan

> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.

**Goal:** Redesign PicImpact's entire UI inspired by Afilmory — immersive masonry gallery, fullscreen photo viewer with inspector panel, split-screen auth, and streamlined admin.

**Architecture:** 4 independent phases. Each phase is a PR-ready deliverable. Phases modify different page areas with minimal overlap.

**Tech Stack:** Next.js 16, React 19, Tailwind CSS v4, motion/react, Radix UI, shadcn/ui, Zustand, SWR

**Reference:** https://github.com/Afilmory/afilmory

---

## Phase 1: Gallery Redesign (Highest Visual Impact)

### Task 1.1: Replace Dock Menu with Fixed Top Navigation Bar

**Files:**
- Delete: `components/layout/dock-menu.tsx` (replace entirely)
- Create: `components/layout/top-nav.tsx`
- Modify: `app/(default)/layout.tsx`
- Modify: `components/ui/origin/dock.tsx` (may keep for admin or remove)

**What to build:**

A fixed top navigation bar with blur background:

```tsx
<header className="fixed top-0 inset-x-0 z-50">
  {/* Blur backdrop */}
  <div className="absolute inset-0 bg-background/80 backdrop-blur-xl" />
  <nav className="relative flex h-12 items-center justify-between px-4">
    {/* Left: Site name */}
    <Link href="/" className="font-display text-lg font-semibold">
      {config.title || 'PicImpact'}
    </Link>

    {/* Center: Album tabs (horizontal scroll on mobile) */}
    <div className="flex items-center gap-1 overflow-x-auto scrollbar-hide">
      {albums.map(album => (
        <Link
          key={album.id}
          href={`/${album.album_value}`}
          className={cn(
            'rounded-full px-3 py-1 text-sm transition-colors',
            isActive ? 'bg-primary text-primary-foreground' : 'text-muted-foreground hover:text-foreground'
          )}
        >
          {album.name}
        </Link>
      ))}
    </div>

    {/* Right: Theme toggle + Map link + Admin link */}
    <div className="flex items-center gap-2">
      <ThemeToggle />
      <Link href="/map">Map</Link>
    </div>
  </nav>
</header>
```

Update `app/(default)/layout.tsx` to use `<TopNav>` instead of `<DockMenu>`, add `pt-12` to content area.

---

### Task 1.2: Redesign Default Gallery — Immersive Masonry

**Files:**
- Rewrite: `components/layout/theme/default/default-gallery.tsx`
- Rewrite: `components/album/blur-image.tsx`
- Create: `components/gallery/masonry-photo-item.tsx`
- Modify: `style/globals.css` (add hover overlay utilities)

**What to build:**

**MasonryPhotoItem** — the core gallery item:

```tsx
<div
  className="group relative cursor-pointer overflow-hidden"
  style={{ width, height: width / aspectRatio }}
  onClick={() => router.push(`/preview/${photo.id}`)}
>
  {/* Thumbhash placeholder */}
  {photo.blurhash && <BlurHashPlaceholder hash={photo.blurhash} className="absolute inset-0" />}

  {/* Image with hover zoom */}
  <Image
    src={photo.preview_url || photo.url}
    alt={photo.title || ''}
    fill
    className="object-cover transition-transform duration-500 group-hover:scale-105"
    loading="lazy"
  />

  {/* Hover overlay — bottom gradient + info */}
  <div className="pointer-events-none absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent opacity-0 transition-opacity duration-300 group-hover:opacity-100" />

  <div className="absolute inset-x-0 bottom-0 p-3 text-white">
    {/* Title */}
    <h3 className="truncate text-sm font-medium opacity-0 transition-opacity duration-300 group-hover:opacity-100">
      {photo.title}
    </h3>

    {/* EXIF grid — 2x2 frosted badges */}
    {photo.exif && (
      <div className="mt-2 grid grid-cols-2 gap-1.5 text-xs opacity-0 transition-opacity duration-300 group-hover:opacity-100">
        {photo.exif.f_number && (
          <div className="flex items-center gap-1 rounded-md bg-white/15 px-2 py-1 backdrop-blur-md">
            <ApertureIcon className="h-3 w-3 text-white/70" />
            <span className="text-white/90">ƒ/{photo.exif.f_number}</span>
          </div>
        )}
        {/* Same pattern for shutter_speed, focal_length_35mm, iso_speed_rating */}
      </div>
    )}
  </div>

  {/* Live Photo badge */}
  {photo.type === 2 && (
    <div className="absolute top-2 left-2 flex items-center gap-1 rounded-full bg-black/50 px-2 py-1 text-xs text-white backdrop-blur-sm">
      <LivePhotoIcon className="h-3.5 w-3.5" />
      <span>Live</span>
    </div>
  )}
</div>
```

**Default Gallery** — CSS columns-based masonry:

```tsx
<div className="columns-2 gap-1 sm:columns-3 lg:columns-4 xl:columns-5 px-1 sm:px-2 pt-14">
  {photos.map(photo => (
    <div key={photo.id} className="mb-1 break-inside-avoid">
      <MasonryPhotoItem photo={photo} />
    </div>
  ))}
</div>
```

Using CSS `columns` for true masonry layout — simpler than JS-based masonry and natively supported.

---

### Task 1.3: Update Simple Gallery for Immersive Style

**Files:**
- Rewrite: `components/layout/theme/simple/simple-gallery.tsx`
- Rewrite: `components/gallery/simple/gallery-image.tsx`

Simple gallery becomes a single-column editorial layout:
- Full-width images with generous vertical spacing
- Title + EXIF below each image (not hover)
- No cards, no shadows — images float directly

---

### Task 1.4: Update Tag Gallery Page

**Files:**
- Modify: `app/(default)/tag/[...tag]/page.tsx`

Use the same masonry layout and `MasonryPhotoItem` component. Add a tag header pill showing the active filter.

---

## Phase 2: Fullscreen Photo Viewer

### Task 2.1: Build Fullscreen Viewer Shell

**Files:**
- Rewrite: `app/@modal/(...)preview/[id]/modal.tsx`
- Rewrite: `app/@modal/(...)preview/[id]/page.tsx`
- Create: `components/viewer/photo-viewer.tsx`
- Create: `components/viewer/photo-viewer-controls.tsx`

**What to build:**

Fullscreen viewer with dark backdrop, centered image, navigation:

```tsx
<div className="fixed inset-0 z-[100] bg-background/95 flex">
  {/* Main image area */}
  <div className="flex-1 flex items-center justify-center relative">
    {/* Close button — top left */}
    <Button variant="ghost" className="absolute top-4 left-4 z-10" onClick={onClose}>
      <X />
    </Button>

    {/* Previous / Next arrows */}
    <Button className="absolute left-4 top-1/2 -translate-y-1/2" onClick={goPrev}>
      <ChevronLeft />
    </Button>
    <Button className="absolute right-4 top-1/2 -translate-y-1/2" onClick={goNext}>
      <ChevronRight />
    </Button>

    {/* Image */}
    <motion.div key={photo.id} initial={{ opacity: 0 }} animate={{ opacity: 1 }}>
      <Image src={photo.url} ... />
    </motion.div>
  </div>

  {/* Inspector panel — desktop only */}
  <InspectorPanel photo={photo} className="hidden lg:block w-80 border-l" />
</div>
```

Keyboard: `←` `→` navigate, `Escape` close, `i` toggle inspector.

---

### Task 2.2: Build Inspector Panel

**Files:**
- Create: `components/viewer/inspector-panel.tsx`
- Refactor from: `components/album/preview-image.tsx` and `preview-image-exif.tsx`

Right-side panel (320px) containing:
- Photo title (font-display, text-xl)
- Camera + lens badge
- 2x2 EXIF grid (frosted glass cards matching hover overlay style)
- Date & location
- Collapsible histogram / tone analysis
- Download original link
- Tags

Mobile: Same content in a bottom Drawer (using Vaul or existing Drawer component).

---

### Task 2.3: Integrate WebGL Viewer

**Files:**
- Modify: `components/viewer/photo-viewer.tsx`
- Keep: `components/album/progressive-image.tsx` (WebGL logic)

Integrate existing WebGL viewer into the new fullscreen shell. Double-click or pinch to zoom.

---

### Task 2.4: Left/Right Navigation with Transition

**Files:**
- Modify: `components/viewer/photo-viewer.tsx`
- Create: `hooks/use-photo-navigation.ts`

Hook that manages:
- Current photo index in album
- Keyboard arrow navigation
- Touch swipe detection
- Preload adjacent images
- `AnimatePresence` with `translateX` + opacity transition

---

## Phase 3: Login/Signup Redesign

### Task 3.1: Split-Screen Login Page

**Files:**
- Rewrite: `app/login/page.tsx`
- Rewrite: `components/login/user-from.tsx`

**Desktop layout:**
```tsx
<div className="flex h-screen">
  {/* Left: Featured photo */}
  <div className="hidden lg:block lg:w-1/2 relative">
    <Image src={randomPhoto} fill className="object-cover" />
    <div className="absolute inset-0 bg-gradient-to-r from-transparent to-background/30" />
  </div>

  {/* Right: Login form */}
  <div className="flex flex-1 items-center justify-center px-8">
    <div className="w-full max-w-sm space-y-8">
      <h1 className="font-display text-3xl">{siteName}</h1>
      {/* form fields — no Card wrapper */}
      <Input placeholder="Email" className="h-12" />
      <Input type="password" placeholder="Password" className="h-12" />
      <Button className="w-full h-12">Sign in</Button>
      {/* Passkey / 2FA options */}
    </div>
  </div>
</div>
```

**Mobile:** Background image (darkened) + overlaid form.

---

### Task 3.2: Split-Screen Signup Page

**Files:**
- Rewrite: `app/sign-up/page.tsx`
- Rewrite: `components/sign-up/sign-up-from.tsx`

Same split-screen pattern as login.

---

## Phase 4: Admin Dashboard Redesign

### Task 4.1: Streamline Admin Layout

**Files:**
- Modify: `app/admin/layout.tsx`
- Modify: `components/layout/admin/app-sidebar.tsx`

Collapse sidebar to icon-only (48px) by default, expand on hover/click. Content area gets more room.

---

### Task 4.2: Redesign Dashboard Page

**Files:**
- Rewrite: `app/admin/page.tsx`

Key metrics row (3 cards: photos / albums / storage) + recent uploads grid (masonry thumbnails).

---

### Task 4.3: Image Management — Grid/List Toggle

**Files:**
- Rewrite: `components/admin/list/list-image.tsx`
- Modify: `components/admin/list/image-view.tsx`
- Modify: `components/admin/list/image-edit-sheet.tsx`

Add view toggle (grid | list). Grid = dense thumbnails with checkbox overlay. List = table rows with inline expand-to-edit.

---

### Task 4.4: Upload Page Enhancement

**Files:**
- Modify: `app/admin/upload/page.tsx` (or relevant upload page)
- Modify: `components/admin/upload/simple-file-upload.tsx`
- Modify: `components/admin/upload/livephoto-file-upload.tsx`

Larger drag zone, inline progress bars, preview thumbnails during upload.

---

## Execution Order

| Phase | Tasks | Impact | Est. Files |
|-------|-------|--------|------------|
| 1. Gallery | 4 tasks | Highest — what users see first | ~10 files |
| 2. Viewer | 4 tasks | High — core photo experience | ~8 files |
| 3. Auth | 2 tasks | Medium — first-time impression | ~4 files |
| 4. Admin | 4 tasks | Lower — admin only | ~10 files |

Start with Phase 1 for maximum visual impact.