# 🎯 Реализация поиска по полям - Предложения для фронтенд команды

## 📋 Обзор фичи

Реализована новая функциональность **поиска по полям** в API, которая позволяет пользователям искать ссылки по названию, саммари и URL. Поиск работает совместно с существующей фильтрацией по тегам.

## 🔧 API изменения

### Endpoint: `GET /api/links`

**Новый параметр:** `q` (query string)
- **Тип:** string
- **Обязательный:** нет
- **Описание:** Поиск по полям title, summary и url
- **Пример:** `?q=laravel`

### Полный список параметров

```yaml
GET /api/links?q=laravel&tags=технологии,программирование&status=completed&page=1&per_page=10
```

**Параметры:**
- `q` - поиск по полям (новый)
- `tags` - фильтрация по тегам (существующий)
- `status` - фильтрация по статусу (существующий)
- `type` - фильтрация по типу (существующий)
- `page` - номер страницы (существующий)
- `per_page` - элементов на странице (существующий)
- `sort_by` - поле сортировки (существующий)
- `sort_order` - порядок сортировки (существующий)

## 🔍 Логика поиска

### Как работает поиск
1. **Поиск по трем полям:** title, summary, url
2. **Case-insensitive:** поиск не чувствителен к регистру
3. **Частичное совпадение:** используется SQL LIKE с wildcards (%)
4. **Комбинирование:** поиск работает как AND с фильтрацией по тегам

### Примеры запросов
```bash
# Поиск по названию
GET /api/links?q=laravel

# Поиск + фильтрация по тегам
GET /api/links?q=tutorial&tags=программирование

# Поиск + множественная фильтрация по тегам
GET /api/links?q=framework&tags=laravel,php

# Полный пример
GET /api/links?q=video&tags=обучение&status=completed&page=1&per_page=20
```

## 📚 Документация API

**Полная документация:** [docs/openapi-spa.yaml](docs/openapi-spa.yaml)

**Схемы ответов:**
- `PaginatedLinksResponse` - список ссылок с пагинацией
- `LinkResponse` - отдельная ссылка
- `ErrorResponse` - ошибки

## 🎨 Предложения по UI/UX

### 1. Поисковая строка
```typescript
// Предлагаемая структура компонента
interface SearchBarProps {
  value: string;
  onChange: (value: string) => void;
  placeholder?: string;
  onSearch?: () => void;
}
```

**Рекомендации:**
- Разместить над списком ссылок
- Placeholder: "Поиск по названию, описанию или ссылке..."
- Debounce для оптимизации запросов (300-500ms)
- Очистка при пустом значении

### 2. Состояние URL
```typescript
// Предлагаемая структура URL
const searchParams = new URLSearchParams({
  q: searchQuery,
  tags: selectedTags.join(','),
  status: selectedStatus,
  page: currentPage.toString()
});
```

**Рекомендации:**
- Сохранять поисковый запрос в URL
- Использовать History API для навигации
- Поддержка прямых ссылок на результаты поиска
- SEO-friendly URLs

### 3. Комбинирование с фильтрами
```typescript
// Предлагаемая логика
const buildApiUrl = (params: {
  search?: string;
  tags?: string[];
  status?: string;
  page?: number;
}) => {
  const searchParams = new URLSearchParams();
  
  if (params.search) searchParams.set('q', params.search);
  if (params.tags?.length) searchParams.set('tags', params.tags.join(','));
  if (params.status) searchParams.set('status', params.status);
  if (params.page) searchParams.set('page', params.page.toString());
  
  return `/api/links?${searchParams.toString()}`;
};
```

### 4. Обработка результатов
```typescript
// Предлагаемая структура ответа
interface SearchResponse {
  data: Link[];
  meta: {
    current_page: number;
    last_page: number;
    per_page: number;
    total: number;
  };
}
```

## 🧪 Тестирование

### Тестовые данные
API полностью протестирован. Примеры тестовых запросов:

```bash
# Поиск по названию
curl "http://localhost:8000/api/links?q=laravel" \
  -H "Authorization: Bearer YOUR_TOKEN"

# Комбинированный поиск
curl "http://localhost:8000/api/links?q=tutorial&tags=программирование" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

### Ожидаемое поведение
- ✅ Поиск по title, summary, url
- ✅ Case-insensitive поиск
- ✅ Комбинирование с фильтрами
- ✅ Пагинация работает корректно
- ✅ Пустые запросы игнорируются
- ✅ Специальные символы обрабатываются

## 🚀 Рекомендации по реализации

### 1. Debouncing
```typescript
const useDebounce = (value: string, delay: number) => {
  const [debouncedValue, setDebouncedValue] = useState(value);
  
  useEffect(() => {
    const handler = setTimeout(() => {
      setDebouncedValue(value);
    }, delay);
    
    return () => clearTimeout(handler);
  }, [value, delay]);
  
  return debouncedValue;
};
```

### 2. Loading состояния
```typescript
const [isSearching, setIsSearching] = useState(false);
const [searchResults, setSearchResults] = useState<Link[]>([]);
```

### 3. Обработка ошибок
```typescript
const handleSearchError = (error: any) => {
  console.error('Search error:', error);
  // Показать уведомление пользователю
};
```

### 4. Кэширование результатов
```typescript
// Рекомендуется кэшировать результаты поиска
const searchCache = new Map<string, SearchResponse>();
```

## 📱 Адаптивность

**Рекомендации для мобильных устройств:**
- Компактная поисковая строка
- Фильтры в выпадающем меню
- Оптимизация для touch-интерфейса

## 🔗 Связанные файлы

- **API документация:** [docs/openapi-spa.yaml](docs/openapi-spa.yaml)
- **Тесты:** [tests/Feature/LinksApiTest.php](tests/Feature/LinksApiTest.php)
- **Сервис:** [app/Services/LinkFilterService.php](app/Services/LinkFilterService.php)
- **Контроллер:** [app/Http/Controllers/LinksController.php](app/Http/Controllers/LinksController.php)

## 📞 Контакты

При возникновении вопросов по API обращайтесь к бэкенд команде.

---

**Версия:** v0.0.62  
**Дата:** 2025-01-27  
**Статус:** API готов к интеграции 