Files
ai-stylegallery/prp/frontend-components.md
2025-11-11 21:23:00 +01:00

16 KiB

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

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

Location: resources/js/Pages/Home.vue

Props:

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

State Management:

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:

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

Events:

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:

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:

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

Events:

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:

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

Events:

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

State Management:

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:

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:

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:

interface Props {
  image: Image              // Styled image object
}

Events:

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:

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

Events:

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:

interface Props {
  maxCopies: number         // Maximum allowed copies
}

Events:

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)

// 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)

// 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

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