Merge pull request #48 from SlimusMinus/fix-search_page

fixed search page
This commit is contained in:
SlimusMinus
2026-08-19 01:09:19 +03:00
committed by GitHub
5 changed files with 31 additions and 4 deletions

View File

@@ -7,6 +7,7 @@ export default function FeedContent({
error, error,
filteredAds, filteredAds,
activeNav, activeNav,
searchPrompt,
liked, liked,
likeCountAdj, likeCountAdj,
onLike, onLike,
@@ -38,6 +39,16 @@ export default function FeedContent({
); );
} }
if (searchPrompt) {
return (
<div className="f-center">
<div className="f-center-icon">🔍</div>
<div className="f-center-title">{t('feed.searchPromptTitle')}</div>
<div className="f-center-sub">{t('feed.searchPromptSub')}</div>
</div>
);
}
if (!filteredAds.length) { if (!filteredAds.length) {
const emptyMsg = activeNav === "myads" const emptyMsg = activeNav === "myads"
? { title: t('feed.emptyMyAdsTitle'), sub: t('feed.emptyMyAdsSub') } ? { title: t('feed.emptyMyAdsTitle'), sub: t('feed.emptyMyAdsSub') }

View File

@@ -8,7 +8,7 @@ const PAGE_SIZE = 20;
*/ */
export function useFeedPosts() { export function useFeedPosts() {
const [ads, setAds] = useState([]); const [ads, setAds] = useState([]);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(false);
const [error, setError] = useState(""); const [error, setError] = useState("");
const [page, setPage] = useState(0); const [page, setPage] = useState(0);
const [hasMore, setHasMore] = useState(true); const [hasMore, setHasMore] = useState(true);

View File

@@ -127,6 +127,8 @@
"emptyMyAdsSub": "Create your first one — click the button above", "emptyMyAdsSub": "Create your first one — click the button above",
"emptyAllTitle": "No ads yet", "emptyAllTitle": "No ads yet",
"emptyAllSub": "Be the first — post an ad<br />about a loss or find", "emptyAllSub": "Be the first — post an ad<br />about a loss or find",
"searchPromptTitle": "Enter search parameters",
"searchPromptSub": "Type a name or select a city to find an ad",
"createPost": "Create ad", "createPost": "Create ad",
"login": "Log in", "login": "Log in",
"searchPlaceholder": "Search by title or description...", "searchPlaceholder": "Search by title or description...",

View File

@@ -128,6 +128,8 @@
"emptyMyAdsSub": "Создайте первое — нажмите кнопку выше", "emptyMyAdsSub": "Создайте первое — нажмите кнопку выше",
"emptyAllTitle": "Объявлений пока нет", "emptyAllTitle": "Объявлений пока нет",
"emptyAllSub": "Будьте первым — разместите объявление<br />о потере или находке", "emptyAllSub": "Будьте первым — разместите объявление<br />о потере или находке",
"searchPromptTitle": "Введите параметры поиска",
"searchPromptSub": "Введите название или выберите город, чтобы найти объявление",
"createPost": "Разместить объявление", "createPost": "Разместить объявление",
"login": "Войти", "login": "Войти",
"searchPlaceholder": "Поиск по названию или описанию...", "searchPlaceholder": "Поиск по названию или описанию...",

View File

@@ -51,6 +51,8 @@ export default function MainFeed() {
const isSearchView = new URLSearchParams(location.search).get("view") === "search"; const isSearchView = new URLSearchParams(location.search).get("view") === "search";
const hasActiveFilters = searchQuery.trim().length > 0 || selectedCities.length > 0; const hasActiveFilters = searchQuery.trim().length > 0 || selectedCities.length > 0;
const hasSearchParams = searchQuery.trim().length > 0 || selectedCities.length > 0;
const searchPrompt = isSearchView && !hasSearchParams;
const feed = useFeedPosts(); const feed = useFeedPosts();
const myPosts = useMyPosts(user?.id); const myPosts = useMyPosts(user?.id);
@@ -113,15 +115,24 @@ export default function MainFeed() {
} }
}, [location.state]); // eslint-disable-line react-hooks/exhaustive-deps }, [location.state]); // eslint-disable-line react-hooks/exhaustive-deps
// Первичная загрузка ленты (дебаунс поиска), только когда нет фильтра по городам // Загрузка основной ленты (не в режиме поиска)
useEffect(() => { useEffect(() => {
if (selectedCities.length > 0) return; if (!isSearchView && selectedCities.length === 0 && !searchQuery.trim()) {
feed.loadFeed(0, "", false);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isSearchView]);
// Дебаунс поиска: только когда в search view и есть параметры
useEffect(() => {
if (!isSearchView) return;
if (!hasSearchParams) return;
const timer = setTimeout(() => { const timer = setTimeout(() => {
feed.loadFeed(0, searchQuery, false); feed.loadFeed(0, searchQuery, false);
}, 400); }, 400);
return () => clearTimeout(timer); return () => clearTimeout(timer);
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [searchQuery, selectedCities]); }, [searchQuery, selectedCities, isSearchView]);
// Когда переключаемся на «Мои объявления» — подгружаем с бэкенда // Когда переключаемся на «Мои объявления» — подгружаем с бэкенда
useEffect(() => { useEffect(() => {
@@ -239,6 +250,7 @@ export default function MainFeed() {
error={listError} error={listError}
filteredAds={filteredAds} filteredAds={filteredAds}
activeNav={activeNav} activeNav={activeNav}
searchPrompt={searchPrompt}
liked={liked} liked={liked}
likeCountAdj={likeCountAdj} likeCountAdj={likeCountAdj}
onLike={actions.toggleLike} onLike={actions.toggleLike}