# Profile Widgets System Documentation

## 🎨 Modular Profile Customization

**Version**: 3.0  
**Status**: ✅ **COMPLETED**  
**Last Updated**: February 17, 2026

---

## 🎯 Overview

The Profile Widgets system transforms user profiles from static displays into dynamic, personalized spaces. Inspired by MySpace but with modern design constraints, users can add, remove, and arrange various widgets to create unique profile expressions while maintaining platform consistency.

## 🏗️ Architecture

### System Components

```
┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│   Widget Engine   │    │   Layout Manager │    │   Theme System   │
│                 │◄──►│                 │◄──►│                 │
│ • Widget Registry│    │ • Grid Layout    │    │ • Color Schemes  │
│ • Component Cache │    │ • Drag & Drop    │    │ • Font Options   │
│ • State Management│    │ • Persistence    │    │ • Style Rules    │
└─────────────────┘    └─────────────────┘    └─────────────────┘
         │                       │                       │
         ▼                       ▼                       ▼
┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│   Database        │    │   User Interface │    │   Asset Storage  │
│                 │    │                 │    │                 │
│ • Profile Layout │    │ • Widget Renderer│    │ • Widget Assets  │
│ • Widget Config  │    │ • Drag Interface │    │ • Theme Assets  │
│ • User Settings  │    │ • Preview Mode   │    │ • Custom Images │
└─────────────────┘    └─────────────────┘    └─────────────────┘
```

---

## 🎨 Widget Types

### Standard Fields (Always Present)

#### Profile Header
- **Avatar**: User profile image with upload capability
- **Display Name**: Editable display name
- **Handle**: Unique username (@handle)
- **Pronouns**: Optional pronoun field
- **Location**: Optional city-level location

### Widget Catalog

#### 📌 Pinned Posts Widget
Display up to 3 featured posts at the top of profile.

**Features:**
- Drag to reorder pinned posts
- Quick pin/unpin from post menu
- Automatic thumbnail generation
- Engagement stats display

**Configuration:**
```dart
class PinnedPostsWidgetConfig {
  final List<String> postIds;
  final bool showEngagementStats;
  final int maxPosts;
}
```

#### 🎵 Music Widget
Show currently listening or favorite music tracks.

**Features:**
- Spotify/Apple Music integration
- Manual track entry
- Album artwork display
- Play preview snippets
- Music sharing links

**Configuration:**
```dart
class MusicWidgetConfig {
  final String? currentTrack;
  final String? artist;
  final String? album;
  final String? albumArt;
  final String? spotifyUrl;
  final String? appleMusicUrl;
  final bool showCurrentlyListening;
}
```

#### 📸 Photo Grid Widget
Mini gallery of featured photos.

**Features:**
- 3-6 photo grid layout
- Tap to view full size
- Photo captions and dates
- Upload from device or library
- Photo organization

**Configuration:**
```dart
class PhotoGridWidgetConfig {
  final List<String> photoUrls;
  final int columns;
  final bool showCaptions;
  final bool showDates;
  final PhotoGridStyle style;
}
```

#### 🔗 Social Links Widget
Icon row for external social links.

**Features:**
- 20+ platform icons
- Custom link labels
- Verification badges
- Click tracking analytics
- Link preview on hover

**Configuration:**
```dart
class SocialLinksWidgetConfig {
  final List<SocialLink> links;
  final SocialLinkStyle style;
  final bool showVerificationBadges;
}

class SocialLink {
  final SocialPlatform platform;
  final String url;
  final String? customLabel;
  final bool isVerified;
}
```

#### 🏷️ Causes Widget
Tag-style badges for causes and interests.

**Features:**
- Pre-defined cause categories
- Custom cause creation
- Color-coded categories
- Click to explore similar users
- Cause-based recommendations

**Configuration:**
```dart
class CausesWidgetConfig {
  final List<CauseTag> causes;
  final bool showDescription;
  final CauseDisplayStyle style;
}

class CauseTag {
  final String name;
  final CauseCategory category;
  final String? description;
  final Color color;
}
```

#### 👥 Featured Friends Widget
Highlight 3-6 important connections.

**Features:**
- Friend selection from followers
- Mutual friends indicator
- Online status display
- Quick message action
- Relationship type labels

**Configuration:**
```dart
class FeaturedFriendsWidgetConfig {
  final List<String> friendIds;
  final int maxFriends;
  final bool showOnlineStatus;
  final bool showMutualFriends;
  final FriendDisplayStyle style;
}
```

#### 📊 Stats Widget
Display profile statistics and milestones.

**Features:**
- Post count, follower count
- Member since date
- Achievement badges
- Growth charts
- Privacy controls for sensitive stats

**Configuration:**
```dart
class StatsWidgetConfig {
  final bool showFollowerCount;
  final bool showPostCount;
  final bool showMemberSince;
  final bool showAchievements;
  final bool showGrowthChart;
  final StatPrivacyLevel privacyLevel;
}
```

#### 💭 Quote Widget
Display a favorite quote or motto.

**Features:**
- Rich text formatting
- Quote attribution
- Background styling options
- Font customization
- Share quote feature

**Configuration:**
```dart
class QuoteWidgetConfig {
  final String text;
  final String? attribution;
  final QuoteStyle style;
  final Color backgroundColor;
  final Color textColor;
  final String fontFamily;
}
```

#### 📍 Beacon Activity Widget
Show recent community contributions.

**Features:**
- Recent beacon posts
- Vouch/report statistics
- Community impact score
- Neighborhood focus
- Activity timeline

**Configuration:**
```dart
class BeaconActivityWidgetConfig {
  final int maxItems;
  final bool showVouchCount;
  final bool showReportCount;
  final bool showNeighborhood;
  final ActivityTimeframe timeframe;
}
```

#### 📝 Custom Text Widget
Markdown-rendered freeform content.

**Features:**
- Full Markdown support
- Custom styling options
- Link and media embedding
- Character limits
- Preview mode

**Configuration:**
```dart
class CustomTextWidgetConfig {
  final String markdownContent;
  final TextDisplayStyle style;
  final bool allowHtml;
  final int maxCharacters;
  final bool showWordCount;
}
```

---

## 🎨 Theming System

### Color Schemes
- **Default**: Platform blue and gray palette
- **Sunset**: Warm oranges and purples
- **Ocean**: Cool blues and teals
- **Forest**: Natural greens and browns
- **Monochrome**: Classic black and white
- **Neon**: Bright, vibrant colors

### Theme Options
```dart
class ProfileTheme {
  final String name;
  final Color primaryColor;
  final Color secondaryColor;
  final Color backgroundColor;
  final Color textColor;
  final Color accentColor;
  final String fontFamily;
  final bool darkMode;
}
```

### Customization Controls
- **Accent Color Picker**: Choose from palette or custom hex
- **Font Selection**: 5 font families with size options
- **Dark/Light Mode**: Independent of app theme
- **Banner Image**: Upload custom background
- **Widget Borders**: Show/hide widget borders
- **Shadow Effects**: Adjustable shadow intensity

---

## 📱 Implementation Details

### Frontend Components

#### Draggable Widget Grid
**File**: `sojorn_app/lib/widgets/profile/draggable_widget_grid.dart`

```dart
class DraggableWidgetGrid extends StatefulWidget {
  final List<ProfileWidget> widgets;
  final Function(List<ProfileWidget>)? onLayoutChanged;
  final bool isEditing;
  final ProfileTheme theme;
  
  @override
  _DraggableWidgetGridState createState() => _DraggableWidgetGridState();
}

class _DraggableWidgetGridState extends State<DraggableWidgetGrid> {
  late List<ProfileWidget> _widgets;
  final GlobalKey _gridKey = GlobalKey();
  
  @override
  void initState() {
    super.initState();
    _widgets = List.from(widget.widgets);
  }
  
  @override
  Widget build(BuildContext context) {
    return Container(
      key: _gridKey,
      child: ReorderableGridView.count(
        crossAxisCount: 3,
        mainAxisSpacing: 16,
        crossAxisSpacing: 16,
        onReorder: _onReorder,
        children: _widgets.map((widget) => _buildWidget(widget)).toList(),
      ),
    );
  }
  
  Widget _buildWidget(ProfileWidget widget) {
    return ReorderableWidget(
      key: ValueKey(widget.id),
      reorderable: widget.isEditing,
      child: Container(
        decoration: BoxDecoration(
          color: widget.theme.backgroundColor,
          borderRadius: BorderRadius.circular(12),
          border: widget.showBorder 
            ? Border.all(color: widget.theme.primaryColor)
            : null,
          boxShadow: widget.showShadows 
            ? [
                BoxShadow(
                  color: Colors.black.withOpacity(0.1),
                  blurRadius: 8,
                  offset: Offset(0, 4),
                ),
              ]
            : null,
        ),
        child: WidgetRenderer(
          widget: widget,
          theme: widget.theme,
          isEditing: widget.isEditing,
        ),
      ),
    );
  }
  
  void _onReorder(int oldIndex, int newIndex) {
    setState(() {
      if (newIndex > oldIndex) {
        newIndex -= 1;
      }
      final ProfileWidget widget = _widgets.removeAt(oldIndex);
      _widgets.insert(newIndex, widget);
    });
    
    widget.onLayoutChanged?.call(_widgets);
  }
}
```

#### Widget Renderer
**File**: `sojorn_app/lib/widgets/profile/widget_renderer.dart`

```dart
class WidgetRenderer extends StatelessWidget {
  final ProfileWidget widget;
  final ProfileTheme theme;
  final bool isEditing;
  
  @override
  Widget build(BuildContext context) {
    switch (widget.type) {
      case WidgetType.pinnedPosts:
        return PinnedPostsWidget(
          config: widget.config as PinnedPostsWidgetConfig,
          theme: theme,
          isEditing: isEditing,
        );
      case WidgetType.music:
        return MusicWidget(
          config: widget.config as MusicWidgetConfig,
          theme: theme,
          isEditing: isEditing,
        );
      case WidgetType.photoGrid:
        return PhotoGridWidget(
          config: widget.config as PhotoGridWidgetConfig,
          theme: theme,
          isEditing: isEditing,
        );
      // ... other widget types
      default:
        return Container(
          child: Text('Unknown widget type'),
        );
    }
  }
}
```

#### Profile Editor
**File**: `sojorn_app/lib/screens/profile/profile_editor_screen.dart`

```dart
class ProfileEditorScreen extends ConsumerStatefulWidget {
  @override
  _ProfileEditorScreenState createState() => _ProfileEditorScreenState();
}

class _ProfileEditorScreenState extends ConsumerState<ProfileEditorScreen> {
  List<ProfileWidget> _widgets = [];
  ProfileTheme _theme = ProfileTheme.default();
  bool _isEditing = false;
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Edit Profile'),
        actions: [
          IconButton(
            icon: Icon(_isEditing ? Icons.check : Icons.edit),
            onPressed: _toggleEditing,
          ),
          IconButton(
            icon: Icon(Icons.palette),
            onPressed: _showThemeSelector,
          ),
        ],
      ),
      body: Column(
        children: [
          // Profile header
          _buildProfileHeader(),
          
          // Widget grid
          Expanded(
            child: DraggableWidgetGrid(
              widgets: _widgets,
              onLayoutChanged: _onLayoutChanged,
              isEditing: _isEditing,
              theme: _theme,
            ),
          ),
          
          // Widget catalog (when editing)
          if (_isEditing) _buildWidgetCatalog(),
        ],
      ),
    );
  }
  
  Widget _buildWidgetCatalog() {
    return Container(
      height: 120,
      child: ListView(
        scrollDirection: Axis.horizontal,
        children: WidgetType.values.map((type) => 
          WidgetCatalogItem(
            type: type,
            onTap: () => _addWidget(type),
          ),
        ).toList(),
      ),
    );
  }
  
  void _addWidget(WidgetType type) {
    final newWidget = ProfileWidget.create(type, _theme);
    setState(() {
      _widgets.add(newWidget);
    });
    _saveLayout();
  }
  
  void _saveLayout() {
    final layout = ProfileLayout(
      widgets: _widgets,
      theme: _theme,
      updatedAt: DateTime.now(),
    );
    
    ref.read(profileServiceProvider).saveLayout(layout);
  }
}
```

### Backend Integration

#### Profile Layout Service
**File**: `go-backend/internal/services/profile_service.go`

```go
type ProfileService struct {
    db *pgxpool.Pool
}

type ProfileLayout struct {
    UserID    string        `json:"user_id"`
    Widgets   []ProfileWidget `json:"widgets"`
    Theme     ProfileTheme   `json:"theme"`
    UpdatedAt time.Time      `json:"updated_at"`
}

type ProfileWidget struct {
    ID     string                 `json:"id"`
    Type   string                 `json:"type"`
    Config map[string]interface{} `json:"config"`
    Order  int                    `json:"order"`
}

func (s *ProfileService) SaveLayout(ctx context.Context, userID string, layout ProfileLayout) error {
    // Serialize layout to JSON
    layoutJSON, err := json.Marshal(layout)
    if err != nil {
        return fmt.Errorf("failed to marshal layout: %w", err)
    }
    
    // Save to database
    _, err = s.db.Exec(ctx, `
        INSERT INTO profile_layouts (user_id, layout_data, updated_at)
        VALUES ($1, $2, $3)
        ON CONFLICT (user_id) 
        DO UPDATE SET 
            layout_data = $2,
            updated_at = $3
    `, userID, layoutJSON, time.Now())
    
    return err
}

func (s *ProfileService) GetLayout(ctx context.Context, userID string) (*ProfileLayout, error) {
    var layoutJSON []byte
    err := s.db.QueryRow(ctx, `
        SELECT layout_data 
        FROM profile_layouts 
        WHERE user_id = $1
    `, userID).Scan(&layoutJSON)
    
    if err != nil {
        if err == pgx.ErrNoRows {
            // Return default layout
            return s.getDefaultLayout(userID), nil
        }
        return nil, err
    }
    
    var layout ProfileLayout
    err = json.Unmarshal(layoutJSON, &layout)
    if err != nil {
        return nil, fmt.Errorf("failed to unmarshal layout: %w", err)
    }
    
    return &layout, nil
}

func (s *ProfileService) getDefaultLayout(userID string) *ProfileLayout {
    return &ProfileLayout{
        UserID: userID,
        Widgets: []ProfileWidget{
            {
                ID:   "bio",
                Type: "bio",
                Config: map[string]interface{}{
                    "show_pronouns": true,
                    "show_location": true,
                },
                Order: 0,
            },
            {
                ID:   "social_links",
                Type: "social_links",
                Config: map[string]interface{}{
                    "style": "icons",
                },
                Order: 1,
            },
            {
                ID:   "pinned_posts",
                Type: "pinned_posts",
                Config: map[string]interface{}{
                    "max_posts": 3,
                    "show_engagement": true,
                },
                Order: 2,
            },
        },
        Theme: ProfileTheme{
            Name:         "default",
            PrimaryColor: "#1976D2",
            DarkMode:     false,
        },
        UpdatedAt: time.Now(),
    }
}
```

---

## 🗂️ Data Models

### Profile Widget Model
```dart
class ProfileWidget {
  final String id;
  final WidgetType type;
  final Map<String, dynamic> config;
  final int order;
  final bool isVisible;
  final DateTime createdAt;
  final DateTime updatedAt;
  
  const ProfileWidget({
    required this.id,
    required this.type,
    required this.config,
    required this.order,
    this.isVisible = true,
    required this.createdAt,
    required this.updatedAt,
  });
  
  factory ProfileWidget.create(WidgetType type, ProfileTheme theme) {
    return ProfileWidget(
      id: const Uuid().v4(),
      type: type,
      config: _getDefaultConfig(type),
      order: 0,
      createdAt: DateTime.now(),
      updatedAt: DateTime.now(),
    );
  }
  
  static Map<String, dynamic> _getDefaultConfig(WidgetType type) {
    switch (type) {
      case WidgetType.pinnedPosts:
        return {
          'max_posts': 3,
          'show_engagement_stats': true,
          'post_ids': <String>[],
        };
      case WidgetType.music:
        return {
          'show_currently_listening': true,
          'current_track': null,
          'artist': null,
          'album': null,
        };
      case WidgetType.photoGrid:
        return {
          'columns': 3,
          'show_captions': true,
          'show_dates': false,
          'photo_urls': <String>[],
        };
      // ... other widget types
      default:
        return {};
    }
  }
}
```

### Profile Layout Model
```dart
class ProfileLayout {
  final String userId;
  final List<ProfileWidget> widgets;
  final ProfileTheme theme;
  final DateTime updatedAt;
  
  const ProfileLayout({
    required this.userId,
    required this.widgets,
    required this.theme,
    required this.updatedAt,
  });
  
  factory ProfileLayout.fromJson(Map<String, dynamic> json) {
    return ProfileLayout(
      userId: json['user_id'],
      widgets: (json['widgets'] as List)
          .map((w) => ProfileWidget.fromJson(w))
          .toList(),
      theme: ProfileTheme.fromJson(json['theme']),
      updatedAt: DateTime.parse(json['updated_at']),
    );
  }
  
  Map<String, dynamic> toJson() {
    return {
      'user_id': userId,
      'widgets': widgets.map((w) => w.toJson()).toList(),
      'theme': theme.toJson(),
      'updated_at': updatedAt.toIso8601String(),
    };
  }
}
```

---

## 🗄️ Database Schema

### Profile Layout Table
```sql
CREATE TABLE IF NOT EXISTS profile_layouts (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    layout_data JSONB NOT NULL,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW(),
    
    UNIQUE(user_id)
);

-- Index for efficient querying
CREATE INDEX idx_profile_layouts_user_id ON profile_layouts(user_id);
CREATE INDEX idx_profile_layouts_updated_at ON profile_layouts(updated_at);

-- Widget assets table
CREATE TABLE IF NOT EXISTS widget_assets (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    widget_id VARCHAR(100) NOT NULL,
    asset_type VARCHAR(50) NOT NULL, -- 'banner', 'avatar', 'custom'
    asset_url TEXT NOT NULL,
    file_name VARCHAR(255),
    file_size INTEGER,
    mime_type VARCHAR(100),
    created_at TIMESTAMP DEFAULT NOW(),
    
    INDEX idx_widget_assets_user_id ON widget_assets(user_id),
    INDEX idx_widget_assets_widget_id ON widget_assets(widget_id)
);
```

---

## 🔧 Technical Implementation

### Widget Constraints
```dart
class WidgetConstraints {
  static const double maxWidth = 400;
  static const double maxHeight = 600;
  static const double minWidth = 200;
  static const double minHeight = 150;
  
  static const Map<WidgetType, Size> defaultSizes = {
    WidgetType.pinnedPosts: Size(400, 300),
    WidgetType.music: Size(400, 200),
    WidgetType.photoGrid: Size(400, 400),
    WidgetType.socialLinks: Size(400, 100),
    WidgetType.causes: Size(400, 150),
    WidgetType.featuredFriends: Size(400, 250),
    WidgetType.stats: Size(400, 200),
    WidgetType.quote: Size(400, 150),
    WidgetType.beaconActivity: Size(400, 300),
    WidgetType.customText: Size(400, 250),
  };
  
  static Size getMaxSize(WidgetType type) {
    return defaultSizes[type] ?? Size(maxWidth, maxHeight);
  }
  
  static Size getMinSize(WidgetType type) {
    final defaultSize = defaultSizes[type] ?? Size(maxWidth, maxHeight);
    return Size(minWidth, defaultSize.height * 0.6);
  }
}
```

### Performance Optimization
```dart
class WidgetCacheManager {
  static final Map<String, Widget> _widgetCache = {};
  static const Duration _cacheTimeout = Duration(minutes: 5);
  
  static Widget? getCachedWidget(String widgetId) {
    return _widgetCache[widgetId];
  }
  
  static void cacheWidget(String widgetId, Widget widget) {
    _widgetCache[widgetId] = widget;
    
    // Auto-remove after timeout
    Timer(_cacheTimeout, () {
      _widgetCache.remove(widgetId);
    });
  }
  
  static void clearCache() {
    _widgetCache.clear();
  }
}
```

### State Management
```dart
class ProfileLayoutNotifier extends StateNotifier<ProfileLayout> {
  ProfileLayoutNotifier(this._profileService) : super(ProfileLayout.empty());
  
  final ProfileService _profileService;
  
  Future<void> loadLayout(String userId) async {
    try {
      final layout = await _profileService.getLayout(userId);
      state = layout;
    } catch (e) {
      // Handle error
      state = ProfileLayout.defaultForUser(userId);
    }
  }
  
  Future<void> saveLayout() async {
    try {
      await _profileService.saveLayout(state);
    } catch (e) {
      // Handle error
    }
  }
  
  void addWidget(WidgetType type) {
    final newWidget = ProfileWidget.create(type, state.theme);
    state = state.copyWith(
      widgets: [...state.widgets, newWidget],
      updatedAt: DateTime.now(),
    );
    saveLayout();
  }
  
  void removeWidget(String widgetId) {
    state = state.copyWith(
      widgets: state.widgets.where((w) => w.id != widgetId).toList(),
      updatedAt: DateTime.now(),
    );
    saveLayout();
  }
  
  void updateWidget(String widgetId, Map<String, dynamic> config) {
    state = state.copyWith(
      widgets: state.widgets.map((w) {
        if (w.id == widgetId) {
          return w.copyWith(
            config: config,
            updatedAt: DateTime.now(),
          );
        }
        return w;
      }).toList(),
      updatedAt: DateTime.now(),
    );
    saveLayout();
  }
  
  void reorderWidgets(int oldIndex, int newIndex) {
    final widgets = List.from(state.widgets);
    if (newIndex > oldIndex) {
      newIndex -= 1;
    }
    final widget = widgets.removeAt(oldIndex);
    widgets.insert(newIndex, widget);
    
    state = state.copyWith(
      widgets: widgets,
      updatedAt: DateTime.now(),
    );
    saveLayout();
  }
  
  void updateTheme(ProfileTheme theme) {
    state = state.copyWith(
      theme: theme,
      updatedAt: DateTime.now(),
    );
    saveLayout();
  }
}
```

---

## 📱 User Interface

### Widget Catalog
- **Visual Preview**: Thumbnail previews of each widget type
- **Drag & Drop**: Drag widgets from catalog to grid
- **Search**: Filter widget types by name or category
- **Categories**: Organized by function (social, content, media, etc.)

### Editing Interface
- **Live Preview**: See changes in real-time
- **Undo/Redo**: Revert changes if needed
- **Save Status**: Visual indication of save state
- **Help Tooltips**: Contextual help for each widget

### Theme Customization
- **Color Picker**: Visual color selection with hex input
- **Font Selector**: Preview fonts before applying
- **Banner Upload**: Drag and drop banner images
- **Reset Options**: Reset to default theme or layout

---

## 🔒 Security & Privacy

### Content Validation
- **XSS Prevention**: Sanitize all user-generated content
- **HTML Filtering**: Remove dangerous HTML tags and attributes
- **Link Validation**: Verify and sanitize external links
- **Image Upload**: Scan uploads for malicious content

### Privacy Controls
- **Widget Privacy**: Individual widget visibility settings
- **Data Minimization**: Only store necessary widget data
- **User Consent**: Clear consent for data collection
- **Access Control**: Proper authorization for profile access

### Content Moderation
- **Widget Content**: Moderate custom text and images
- **Link Safety**: Check external links for safety
- **User Reporting**: Report inappropriate profile content
- **Automated Filtering**: AI-powered content analysis

---

## 📊 Analytics & Metrics

### Widget Usage
- **Popular Widgets**: Track most used widget types
- **Customization Trends**: Analyze theme preferences
- **Engagement Metrics**: Measure widget interaction rates
- **User Behavior**: Track profile editing patterns

### Performance Metrics
- **Load Times**: Profile page load performance
- **Widget Rendering**: Individual widget render times
- **Cache Hit Rates**: Widget cache effectiveness
- **Error Rates**: Widget failure rates and types

---

## 🚀 Deployment

### Environment Configuration
```bash
# Widget system settings
PROFILE_WIDGETS_ENABLED=true
PROFILE_WIDGETS_MAX_PER_USER=10
PROFILE_WIDGETS_CACHE_TTL=300

# Asset storage
WIDGET_ASSETS_BUCKET=sojorn-widget-assets
WIDGET_ASSETS_MAX_SIZE=10485760  # 10MB

# Theme settings
PROFILE_THEMES_ENABLED=true
PROFILE_CUSTOM_THEMES=true
PROFILE_BANNER_MAX_SIZE=2097152  # 2MB
```

### Health Checks
```go
func (s *ProfileService) HealthCheck() HealthStatus {
    // Check widget cache
    if s.widgetCache == nil {
        return HealthStatus{
            Status: "degraded",
            Message: "Widget cache not available",
        }
    }
    
    // Check asset storage
    if _, err := s.assetService.HealthCheck(); err != nil {
        return HealthStatus{
            Status: "degraded",
            Message: "Asset storage not accessible",
        }
    }
    
    return HealthStatus{
        Status: "healthy",
        Message: "Profile widgets system ready",
    }
}
```

---

## 📚 Troubleshooting

### Common Issues

#### Widget Not Rendering
```dart
// Check widget configuration
if (widget.config.isEmpty) {
  return ErrorWidget(
    message: "Widget configuration is missing",
    action: "Reset to default",
  );
}

// Check theme compatibility
if (!theme.isCompatible(widget.type)) {
  return ErrorWidget(
    message: "Theme not compatible with widget",
    action: "Use default theme",
  );
}
```

#### Layout Not Saving
```dart
try {
  await profileService.saveLayout(layout);
} catch (e) {
  // Show user-friendly error
  ScaffoldMessenger.of(context).showSnackBar(
    SnackBar(content: Text('Failed to save layout: $e')),
  );
  
  // Log detailed error
  logger.error('Layout save failed', error: e);
}
```

#### Performance Issues
```dart
// Implement lazy loading for widgets
class LazyWidget extends StatelessWidget {
  final WidgetType type;
  
  @override
  Widget build(BuildContext context) {
    return FutureBuilder<Widget>(
      future: _loadWidget(type),
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          return snapshot.data!;
        }
        return CircularProgressIndicator();
      },
    );
  }
}
```

---

## 📝 Future Enhancements

### Version 3.1 (Planned)
- **Widget Templates**: Pre-designed widget combinations
- **Collaborative Profiles**: Multiple users editing same profile
- **Advanced Analytics**: Detailed widget performance metrics
- **Widget Marketplace**: Community-created widgets

### Version 4.0 (Long-term)
- **AI Widget Suggestions**: AI-powered widget recommendations
- **Interactive Widgets**: Widgets with real-time data
- **3D Widgets**: 3D visualization widgets
- **Voice Commands**: Voice-controlled profile editing

---

## 📞 Support & Documentation

### User Guides
- **Getting Started**: Quick start guide for profile customization
- **Widget Catalog**: Complete widget reference and examples
- **Theme Guide**: Theme customization and design principles
- **Troubleshooting**: Common issues and solutions

### Developer Resources
- **Widget Development**: Guide to creating custom widgets
- **API Documentation**: Complete API reference
- **Design System**: UI/UX guidelines and components
- **Code Examples**: Sample implementations and patterns

---

**🎨 The Profile Widgets system provides users with powerful yet constrained customization options, allowing for personal expression while maintaining platform consistency and performance.**
