# Blog Match Link Fix - October 2025

## Problem
React Error #310 (Maximum update depth exceeded) - infinite render loop caused by backend returning `map[string]interface{}` instead of Article structs. Each map created new object references, triggering infinite re-renders in React useEffect hooks.

## Root Cause
Previous attempt to add match link data to article JSON responses used helper functions that returned maps instead of structs. This broke React's referential equality checks.

## Solution

### 1. Added MatchLink Field to Article Model
**File**: `internal/models/models.go`

```go
type Article struct {
    // ... existing fields ...
    
    // Match link (loaded separately, not stored in this table)
    MatchLink *ArticleMatchLink `gorm:"-" json:"match_link,omitempty"`
}
```

The `gorm:"-"` tag prevents GORM from treating it as a database column, and `omitempty` keeps it out of JSON if nil.

### 2. Updated Backend Controllers
**File**: `internal/controllers/base_controller.go`

#### GetArticle (single article by ID)
- Loads match link after fetching article
- Sets `art.MatchLink` if found

#### GetArticles (paginated list)
- Batch loads all match links for returned articles in single query
- Maps match links to articles by ID for O(1) lookup
- Efficient: one extra query regardless of result set size

#### GetArticleBySlug (single article by slug)
- Same as GetArticle - loads match link if exists

### 3. Simplified Frontend
**File**: `frontend/src/pages/admin/ArticlesAdminPage.tsx`

- **Removed**: Redundant useEffect that fetched match link separately
- **Kept**: openEdit() function that extracts match_link from article data
- **Result**: Fewer API calls, no infinite loops

## Benefits

1. **No Infinite Loops**: Article structs maintain referential equality
2. **Complete Data**: Article JSON now includes both competition AND match data
3. **Better Performance**: Batch loading for lists (N+1 → 2 queries)
4. **Backward Compatible**: Match link is optional (`omitempty`)
5. **Cleaner Code**: No complex map transformations

## Album Link Reuse

The album link reuse feature was **already implemented** (lines 400-415 in ArticlesAdminPage.tsx). When photos are selected in the Obsah tab, both the album link AND photos are automatically populated in the Media tab.

**Enhancement made**: Improved UI feedback with green background and clear status messages when album is loaded.

## Article JSON Structure

Articles now include:

```json
{
  "id": 123,
  "title": "Match Report",
  "category_name": "A třída",
  "gallery_album_url": "https://eu.zonerama.com/...",
  "youtube_video_id": "abc123",
  "match_link": {
    "external_match_id": "match-abc-123",
    "title": "Home Team vs Away Team"
  }
}
```

## Testing

Test that:
1. ✅ No React infinite loop errors
2. ✅ Match link appears in article JSON responses
3. ✅ Match link displays correctly in admin UI
4. ✅ Album link persists between Obsah and Media tabs
5. ✅ All article endpoints work (GetArticle, GetArticles, GetArticleBySlug)

## Files Modified

- `internal/models/models.go` - Added MatchLink field
- `internal/controllers/base_controller.go` - Load match links in 3 endpoints
- `frontend/src/pages/admin/ArticlesAdminPage.tsx` - Removed redundant fetch, improved UI
