# Frontend Components Specification

## Architecture Overview

Single Page Application built with Vue.js 3 and Inertia.js, providing a responsive image gallery interface with real-time AI processing capabilities.

## Technology Stack

- **Framework**: Vue.js 3.5.18 with Composition API
- **Routing**: Inertia.js 1.3.0 (Laravel backend integration)
- **Build Tool**: Vite 5.4.19
- **Styling**: Tailwind CSS 3.4.17
- **HTTP Client**: Axios 1.11.0
- **State Management**: Vue 3 Composition API (ref, computed, reactive)
- **Real-time**: WebSocket for ComfyUI progress, polling for other providers

## Component Hierarchy

```
App.vue (Root)
└── Home.vue (Main Gallery Page)
    ├── GalleryGrid.vue (Image Grid Display)
    ├── Navigation.vue (Pagination Controls)
    ├── ImageContextMenu.vue (Image Actions Overlay)
    │   └── StyleSelector.vue (Style Selection Interface)
    ├── StyledImageDisplay.vue (Result Preview)
    ├── LoadingSpinner.vue (Progress Indicator)
    └── PrintQuantityModal.vue (Print Options)
```

## Component Specifications

### 1. Home.vue (Main Gallery Page)

**Purpose**: Primary interface displaying user's image gallery with pagination and overlay management

**Location**: `resources/js/Pages/Home.vue`

**Props**:
```typescript
interface Props {
  galleryHeading: string      // Page title
  translations: object        // Internationalization strings
}
```

**State Management**:
```typescript
const images = ref([])                    // Gallery images array
const currentPage = ref(1)               // Current pagination page
const currentOverlayComponent = ref(null) // Active overlay ('contextMenu', 'styleSelector', etc.)
const contextMenuPosition = ref({ x: 0, y: 0 }) // Context menu coordinates
const selectedImage = ref(null)          // Currently selected image
const styledImage = ref(null)            // Newly processed styled image
const processingProgress = ref(0)        // AI processing progress (0-100)
const errorMessage = ref(null)           // Error display state
const isLoading = ref(false)             // Global loading state
const currentTheme = ref('light')        // UI theme preference
```

**Key Methods**:

#### `fetchImages()`
- **Purpose**: Retrieves and synchronizes gallery images
- **Implementation**: Axios GET to `/api/images`
- **Auto-refresh**: Polls every 5 seconds (configurable interval)
- **Error Handling**: Displays user-friendly error messages

#### `applyStyle(style, imageId)`
- **Purpose**: Initiates AI style transformation process
- **Flow**:
  1. Sends style change request to backend
  2. Receives `prompt_id` and `plugin` type
  3. Establishes appropriate progress monitoring (WebSocket vs Polling)
  4. Updates UI with real-time progress
  5. Displays result when complete

#### `showContextMenu(image, event)`
- **Purpose**: Displays context menu for selected image
- **Positioning**: Calculates optimal position based on click coordinates
- **Responsive**: Adapts to screen boundaries

**UI Structure**:
- **Header**: Title and theme toggle
- **Gallery**: Grid layout with pagination
- **Overlays**: Conditional rendering based on `currentOverlayComponent`
- **Notifications**: Error messages with auto-dismiss

**Styling**:
- **Layout**: Flexbox-based responsive design
- **Theme**: Light/dark mode support with CSS variables
- **Responsive**: Mobile-first approach with touch gestures

---

### 2. GalleryGrid.vue

**Purpose**: Displays images in responsive grid layout with interaction handling

**Props**:
```typescript
interface Props {
  images: Image[]           // Array of image objects to display
  translations: object      // UI text translations
}
```

**Events**:
```typescript
interface Events {
  imageTapped: [image: Image, event: MouseEvent]  // Image selection
}
```

**Features**:
- **Responsive Grid**: Adaptive columns based on screen size
- **Lazy Loading**: Images load as they enter viewport
- **Touch Support**: Tap gestures for mobile devices
- **Accessibility**: Proper alt text and keyboard navigation

**Image Object Structure**:
```typescript
interface Image {
  image_id: number
  path: string           // URL to image file
  name: string           // Filename
  is_temp: boolean       // Temporary styled image flag
  is_public: boolean     // Visibility status
  is_new: boolean        // Recently uploaded flag
}
```

---

### 3. ImageContextMenu.vue

**Purpose**: Contextual action menu displayed when user taps/clicks an image

**Location**: `resources/js/Components/ImageContextMenu.vue`

**Props**:
```typescript
interface Props {
  position: { x: number, y: number }  // Menu position coordinates
  image: Image                        // Selected image object
}
```

**Events**:
```typescript
interface Events {
  close: []                           // Close menu
  print: [image: Image]               // Print image
  changeStyle: []                     // Open style selector
  styleSelected: [style: Style, imageId: number]  // Style applied
}
```

**Layout Structure**:
```
┌─────────────────────────────────────────────────┐
│ [X] Close                    [Image Preview]    │
│                                                 │
│ ┌─────────────────────────────────────────────┐ │
│ │                    ▲                        │ │
│ │             Image Preview                   │ │
│ │                    ▼                        │ │
│ │              (70% width)                     │ │
│ └─────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────┐ │
│ │ [Print] [Change Style] [Close]              │ │
│ │              (30% width)                     │ │
│ └─────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘
```

**Features**:
- **Dynamic Positioning**: Calculates optimal position to stay within viewport
- **Backdrop Click**: Closes menu when clicking outside
- **Nested Components**: Embeds StyleSelector when needed
- **Responsive**: Adapts layout for different screen sizes

**Styling**:
- **Overlay**: Semi-transparent backdrop with blur effect
- **Menu**: Elevated card with shadow and rounded corners
- **Responsive**: Touch-friendly button sizes on mobile

---

### 4. StyleSelector.vue

**Purpose**: Allows users to browse and select AI styles for image transformation

**Props**:
```typescript
interface Props {
  image_id: number                    // Target image for styling
}
```

**Events**:
```typescript
interface Events {
  styleSelected: [style: Style, imageId: number]  // Style chosen
  back: []                           // Return to context menu
  close: []                          // Close selector
}
```

**State Management**:
```typescript
const styles = ref([])               // Available styles array
// Lazy loading management
const observer = ref(null)           // IntersectionObserver instance
```

**Key Methods**:

#### `fetchStyles()`
- **Purpose**: Retrieves available styles from API
- **Implementation**: Axios GET to `/api/styles`
- **Filtering**: Only enabled styles returned
- **Lazy Loading**: Sets up IntersectionObserver for preview images

#### `selectStyle(style)`
- **Purpose**: Confirms style selection and triggers processing
- **Implementation**: Emits `styleSelected` event with style and image ID

**UI Structure**:
```
┌─────────────────────────────────────────────────┐
│ [<] Back                    Available Styles    │
├─────────────────────────────────────────────────┤
│ ┌─────────────────────────────────────────────┐ │
│ │ [Preview] Style Name     [Description]      │ │
│ │ [Preview] Another Style  [Description]      │ │
│ │ [Preview] Third Style    [Description]      │ │
│ └─────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘
```

**Features**:
- **Preview Images**: Thumbnail images for each style
- **Lazy Loading**: Images load when entering viewport
- **Back Navigation**: Return to previous context menu
- **Responsive**: Scrollable list on smaller screens

**Style Object Structure**:
```typescript
interface Style {
  id: number
  title: string              // Display name
  description: string        // Human-readable description
  preview_image: string      // Thumbnail image path
  enabled: boolean           // Availability status
}
```

---

### 5. LoadingSpinner.vue

**Purpose**: Visual indicator for AI processing progress

**Props**:
```typescript
interface Props {
  progress: number           // Progress percentage (0-100)
}
```

**Features**:
- **Progress Bar**: Visual representation of completion status
- **Animated**: Smooth progress updates
- **Responsive**: Adapts to different screen sizes
- **Accessible**: Screen reader compatible

**Styling**:
- **Modern Design**: Gradient progress bar with smooth animations
- **Centered**: Overlay positioning for full-screen processes
- **Theme Aware**: Adapts to light/dark theme

---

### 6. StyledImageDisplay.vue

**Purpose**: Preview and management interface for completed AI-styled images

**Props**:
```typescript
interface Props {
  image: Image              // Styled image object
}
```

**Events**:
```typescript
interface Events {
  keep: [image: Image]      // Keep styled image permanently
  delete: [image: Image]    // Discard styled image
}
```

**Features**:
- **Full Preview**: Large display of styled result
- **Action Buttons**: Keep/Discard options
- **Responsive**: Mobile-optimized layout
- **Loading State**: Handles image loading gracefully

---

### 7. Navigation.vue

**Purpose**: Pagination controls for gallery navigation

**Props**:
```typescript
interface Props {
  currentPage: number       // Current active page
  totalPages: number        // Total available pages
}
```

**Events**:
```typescript
interface Events {
  prevPage: []             // Navigate to previous page
  nextPage: []             // Navigate to next page
}
```

**Features**:
- **Page Numbers**: Visual page indicators
- **Touch Gestures**: Swipe left/right for page navigation
- **Responsive**: Touch-friendly on mobile devices
- **Keyboard**: Arrow key navigation support

---

### 8. PrintQuantityModal.vue

**Purpose**: Print options interface for physical image printing

**Props**:
```typescript
interface Props {
  maxCopies: number         // Maximum allowed copies
}
```

**Events**:
```typescript
interface Events {
  close: []                // Close modal
  printConfirmed: [quantity: number]  // Print confirmed
}
```

**Features**:
- **Quantity Selection**: Number input for copy count
- **Validation**: Enforces maximum copy limits
- **Confirmation**: Clear confirmation before printing
- **Responsive**: Modal overlay with backdrop

## Component Interactions

### Image Selection Flow
```
User taps image → GalleryGrid emits imageTapped →
Home.vue shows contextMenu at tap position →
ImageContextMenu displays with image preview and options
```

### Style Application Flow
```
User selects "Change Style" → ImageContextMenu shows StyleSelector →
User browses and selects style → StyleSelector emits styleSelected →
Home.vue initiates AI processing with progress monitoring →
Real-time updates via WebSocket/Polling → Result displayed →
User can keep or discard styled image
```

### Progress Monitoring

#### ComfyUI (WebSocket)
```typescript
// Establish WebSocket connection
const wsUrl = `ws://${comfyUiHost}/ws`
const ws = new WebSocket(wsUrl)

// Monitor progress messages
ws.onmessage = (event) => {
  const message = JSON.parse(event.data)
  if (message.type === 'progress' && message.data.prompt_id === currentPromptId) {
    processingProgress.value = (message.data.value / message.data.max) * 100
  }
}
```

#### Other Providers (Polling)
```typescript
// Poll for completion every 2 seconds
const pollForResult = () => {
  axios.get(`/api/images/fetch-styled/${promptId}`)
    .then(response => {
      // Success - display result
      styledImage.value = response.data.styled_image
      currentOverlayComponent.value = 'styledImageDisplay'
    })
    .catch(error => {
      if (error.response?.status === 404) {
        // Still processing - continue polling
        setTimeout(pollForResult, 2000)
      } else {
        // Error - display message
        showError(error.response?.data?.error)
      }
    })
}
```

## State Management Patterns

### Overlay Management
- Single active overlay at a time
- Stack-based navigation (context menu → style selector → back)
- Proper cleanup on component unmount

### Error Handling
- Centralized error display with auto-dismiss
- User-friendly error messages
- Graceful degradation for failed operations

### Theme Management
- Persistent theme preference in localStorage
- CSS variable-based theming
- System preference detection

## Responsive Design

### Breakpoints
- **Mobile**: < 768px (single column, touch-optimized)
- **Tablet**: 768px - 1024px (2-3 columns, hybrid interaction)
- **Desktop**: > 1024px (4+ columns, mouse-optimized)

### Touch Interactions
- **Tap**: Image selection and button activation
- **Swipe**: Gallery navigation (left/right)
- **Long Press**: Context menu (mobile equivalent of right-click)
- **Pinch**: Zoom functionality (future enhancement)

## Accessibility Features

### ARIA Support
- Proper semantic HTML structure
- ARIA labels for interactive elements
- Screen reader announcements for dynamic content

### Keyboard Navigation
- Tab order for all interactive elements
- Enter/Space for button activation
- Escape key for modal dismissal
- Arrow keys for gallery navigation

### Visual Accessibility
- High contrast mode support
- Sufficient color contrast ratios
- Scalable text and UI elements
- Reduced motion preferences

## Performance Optimizations

### Image Loading
- **Lazy Loading**: IntersectionObserver for viewport detection
- **Progressive Loading**: Blur placeholder → low quality → high quality
- **Caching**: Browser cache for static assets
- **Compression**: Optimized image formats (WebP support)

### Component Optimization
- **Conditional Rendering**: Only render active overlays
- **Event Delegation**: Efficient event handling for large galleries
- **Memoization**: Computed properties for expensive operations
- **Code Splitting**: Component-based lazy loading

## Internationalization

### Translation Structure
```typescript
interface Translations {
  api: {
    dark_mode: string
    light_mode: string
    close: string
    print: string
    change_style: string
  }
}
```

### Implementation
- Laravel backend provides translations
- Vue components use translation keys
- Runtime language switching support

## Future Enhancement Opportunities

### Component Additions
- **ImageEditor.vue**: Basic image editing tools
- **BatchProcessor.vue**: Multi-image style application
- **GalleryFilters.vue**: Search and filter functionality
- **UserProfile.vue**: User settings and preferences
- **AdminDashboard.vue**: Administrative controls

### Feature Enhancements
- **Drag & Drop**: Upload images via drag-and-drop
- **Keyboard Shortcuts**: Power user productivity features
- **Offline Support**: PWA capabilities for offline viewing
- **Social Features**: Share and discover styled images
- **Advanced Progress**: Detailed processing stage information

### Technical Improvements
- **Virtual Scrolling**: Handle very large galleries efficiently
- **Service Workers**: Background processing and caching
- **WebAssembly**: Client-side image processing
- **Real-time Collaboration**: Multiple users styling same image