mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
fix(catalog search): use query parameter so users can share searches and link to them
This commit is contained in:
@@ -1,11 +1,11 @@
|
|||||||
.button {
|
.button {
|
||||||
text-transform: capitalize;
|
text-transform: capitalize;
|
||||||
color: var(--button-desktop-text-color);
|
color: var(--button-desktop-text-color, revert);
|
||||||
text-decoration: var(--button-text-decoration);
|
text-decoration: var(--button-text-decoration, revert);
|
||||||
}
|
}
|
||||||
|
|
||||||
.button:hover {
|
.button:hover {
|
||||||
color: var(--button-desktop-text-color-hover);
|
color: var(--button-desktop-text-color-hover, revert);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -22,23 +22,23 @@
|
|||||||
margin: 0px 5px;
|
margin: 0px 5px;
|
||||||
padding: 1px;
|
padding: 1px;
|
||||||
outline: none;
|
outline: none;
|
||||||
border: 1px solid #AAA;
|
border: var(--post-form-field-input-border, revert);
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.searchContainer input:focus {
|
.searchContainer input:focus {
|
||||||
border: var(--post-form-field-input-focus-border);
|
border: var(--post-form-field-input-focus-border, revert);
|
||||||
}
|
}
|
||||||
|
|
||||||
.closeSearch {
|
.closeSearch {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border: none;
|
border: none;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
color: var(--button-desktop-text-color);
|
color: var(--button-desktop-text-color, revert);
|
||||||
}
|
}
|
||||||
|
|
||||||
.closeSearch:hover {
|
.closeSearch:hover {
|
||||||
color: var(--button-desktop-text-color-hover);
|
color: var(--button-desktop-text-color-hover, revert);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 640px) {
|
@media (max-width: 640px) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { useEffect, useState, useCallback } from 'react';
|
import { useEffect, useState, useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { useLocation, useNavigate } from 'react-router-dom';
|
||||||
import styles from './catalog-search.module.css';
|
import styles from './catalog-search.module.css';
|
||||||
import useIsMobile from '../../hooks/use-is-mobile';
|
import useIsMobile from '../../hooks/use-is-mobile';
|
||||||
import useCatalogFiltersStore from '../../stores/use-catalog-filters-store';
|
import useCatalogFiltersStore from '../../stores/use-catalog-filters-store';
|
||||||
@@ -7,21 +8,52 @@ import _ from 'lodash';
|
|||||||
|
|
||||||
const CatalogSearch = () => {
|
const CatalogSearch = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const location = useLocation();
|
||||||
|
const navigate = useNavigate();
|
||||||
const [openSearch, setOpenSearch] = useState(false);
|
const [openSearch, setOpenSearch] = useState(false);
|
||||||
const [inputValue, setInputValue] = useState('');
|
const [inputValue, setInputValue] = useState('');
|
||||||
const { setSearchFilter, clearSearchFilter } = useCatalogFiltersStore();
|
const { setSearchFilter, clearSearchFilter } = useCatalogFiltersStore();
|
||||||
|
|
||||||
// Create a debounced version of setSearchFilter
|
// Extract query parameter from URL
|
||||||
|
useEffect(() => {
|
||||||
|
const urlParams = new URLSearchParams(location.search);
|
||||||
|
const queryParam = urlParams.get('q');
|
||||||
|
if (queryParam) {
|
||||||
|
setInputValue(queryParam);
|
||||||
|
setSearchFilter(queryParam);
|
||||||
|
setOpenSearch(true);
|
||||||
|
}
|
||||||
|
}, [location.search, setSearchFilter]);
|
||||||
|
|
||||||
|
// Update URL when search changes
|
||||||
|
const updateURL = useCallback(
|
||||||
|
(searchText: string) => {
|
||||||
|
const urlParams = new URLSearchParams(location.search);
|
||||||
|
if (searchText.trim()) {
|
||||||
|
urlParams.set('q', searchText);
|
||||||
|
} else {
|
||||||
|
urlParams.delete('q');
|
||||||
|
}
|
||||||
|
const newSearch = urlParams.toString();
|
||||||
|
const newPath = location.pathname + (newSearch ? `?${newSearch}` : '');
|
||||||
|
navigate(newPath, { replace: true });
|
||||||
|
},
|
||||||
|
[location.pathname, location.search, navigate],
|
||||||
|
);
|
||||||
|
|
||||||
|
// Create a debounced version of setSearchFilter and URL update
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
const debouncedSetSearchFilter = useCallback(
|
const debouncedSetSearchFilter = useCallback(
|
||||||
_.debounce((text: string) => {
|
_.debounce((text: string) => {
|
||||||
if (text.trim()) {
|
if (text.trim()) {
|
||||||
setSearchFilter(text);
|
setSearchFilter(text);
|
||||||
|
updateURL(text);
|
||||||
} else {
|
} else {
|
||||||
clearSearchFilter();
|
clearSearchFilter();
|
||||||
|
updateURL('');
|
||||||
}
|
}
|
||||||
}, 300),
|
}, 300),
|
||||||
[setSearchFilter, clearSearchFilter],
|
[setSearchFilter, clearSearchFilter, updateURL],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleToggleSearch = useCallback(() => {
|
const handleToggleSearch = useCallback(() => {
|
||||||
@@ -30,14 +62,16 @@ const CatalogSearch = () => {
|
|||||||
if (openSearch) {
|
if (openSearch) {
|
||||||
setInputValue('');
|
setInputValue('');
|
||||||
clearSearchFilter();
|
clearSearchFilter();
|
||||||
|
updateURL('');
|
||||||
}
|
}
|
||||||
}, [openSearch, clearSearchFilter]);
|
}, [openSearch, clearSearchFilter, updateURL]);
|
||||||
|
|
||||||
const handleCloseSearch = useCallback(() => {
|
const handleCloseSearch = useCallback(() => {
|
||||||
setOpenSearch(false);
|
setOpenSearch(false);
|
||||||
setInputValue('');
|
setInputValue('');
|
||||||
clearSearchFilter();
|
clearSearchFilter();
|
||||||
}, [clearSearchFilter]);
|
updateURL('');
|
||||||
|
}, [clearSearchFilter, updateURL]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (openSearch) {
|
if (openSearch) {
|
||||||
|
|||||||
Reference in New Issue
Block a user