"use client" // Импортируем необходимые компоненты и типы import { FC, useEffect, useState, useRef, useCallback } from 'react' import ListingCard from '../ListingCard' import { Adt } from '@prisma/client' import toast from 'react-hot-toast' interface BlockAdtsProps {} export const BlockAdts: FC = () => { // Состояния для хранения объявлений и управления их отображением const [adts, setAdts] = useState([]) // Массив объявлений const [sortBy, setSortBy] = useState('new') // Тип сортировки const [isLoading, setIsLoading] = useState(true) // Флаг загрузки const [isLoadingMore, setIsLoadingMore] = useState(false) // Флаг загрузки дополнительных объявлений const [page, setPage] = useState(1) // Текущая страница const [hasMore, setHasMore] = useState(true) // Флаг наличия дополнительных объявлений // Создаем наблюдатель для бесконечной прокрутки const observer = useRef() const lastAdtElementRef = useCallback((node: HTMLDivElement) => { if (isLoadingMore) return if (observer.current) observer.current.disconnect() observer.current = new IntersectionObserver(entries => { // Если последний элемент виден и есть еще объявления - загружаем следующую порцию if (entries[0].isIntersecting && hasMore) { loadMore() } }) if (node) observer.current.observe(node) }, [isLoadingMore, hasMore]) // Функция загрузки объявлений const loadAdts = async (pageNum: number, isLoadMore = false) => { try { // Устанавливаем соответствующий флаг загрузки if (isLoadMore) { setIsLoadingMore(true) } else { setIsLoading(true) } // Запрашиваем данные с сервера const response = await fetch(`/api/adt?page=${pageNum}&sort=${sortBy}`) const { data: newAdts, meta } = await response.json() // Обновляем список объявлений if (pageNum === 1) { setAdts(newAdts) } else { setAdts(prev => [...prev, ...newAdts]) } // Проверяем, есть ли еще объявления для загрузки setHasMore(newAdts.length > 0 && pageNum < meta.totalPages) } catch (error) { console.error('Ошибка загрузки объявлений:', error) } finally { setIsLoading(false) setIsLoadingMore(false) } } // Загружаем объявления при изменении способа сортировки useEffect(() => { loadAdts(1) }, [sortBy]) // Обработчик изменения сортировки const handleSort = (event: React.ChangeEvent) => { setSortBy(event.target.value) setAdts([]) setPage(1) setHasMore(true) } // Функция загрузки дополнительных объявлений const loadMore = () => { if (!isLoadingMore && hasMore) { const nextPage = page + 1 setPage(nextPage) loadAdts(nextPage, true) } } // Компонент-заглушка для отображения во время загрузки const SkeletonCard = () => (
) return (
{/* Заголовок и селектор сортировки */}

Listings

{/* Сетка объявлений */}
{isLoading ? ( // Отображаем заглушки во время начальной загрузки <> ) : ( // Отображаем список объявлений adts.map((adt, index) => (
)) )}
{/* Отображаем заглушки при загрузке дополнительных объявлений */} {isLoadingMore && (
)}
) }