Skip to content

Commit

Permalink
Merge pull request #1009 from ita-social-projects/#1002-RedesignAdd12…
Browse files Browse the repository at this point in the history
…00ResponsiveBreakpointToSearchPage

#1002 [Redesign] Add1200 responsive breakpoint to Search Page
  • Loading branch information
Lvyshnevska authored Dec 11, 2024
2 parents c9bd83d + 60855ff commit 2945bb1
Show file tree
Hide file tree
Showing 14 changed files with 384 additions and 478 deletions.
1 change: 1 addition & 0 deletions FrontEnd/src/components/Loader/Loader.module.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.loader__container {
padding-top: 30%;
min-height: var(--min-height-block-main);
width: 100%;
}
1 change: 1 addition & 0 deletions FrontEnd/src/pages/CustomThemes/customTheme.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ const customTheme = {
},
List: {
fontFamily: 'Geologica',
emptyTextPadding: 0,
}
},
token: {
Expand Down
11 changes: 8 additions & 3 deletions FrontEnd/src/pages/ProfileList/ProfileList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import CompanyCard from '../../components/CompanyCard/CompanyCard';

export default function ProfileList({
isAuthorized,
emptyText,
current,
items,
profiles,
Expand Down Expand Up @@ -34,7 +35,7 @@ export default function ProfileList({
grid={{
justify: 'center',
align: 'stretch',
gutter: [32, 24],
gutter: [24, 24],
xs: 1,
md: 2,
xl: 3,
Expand All @@ -53,9 +54,13 @@ export default function ProfileList({
}}
dataSource={profiles}
split={false}
locale={{emptyText: 'Жодна компанія не відповідає обраному фільтру.'}}
locale={{emptyText: emptyText}}
renderItem={(item) => (
<List.Item key={item.id}>
<List.Item key={item.id}
style={{
marginBlockEnd: '0',
}}
>
<CompanyCard
isAuthorized={isAuthorized}
profile={item}
Expand Down
21 changes: 0 additions & 21 deletions FrontEnd/src/pages/ProfileList/ProfileList.module.css

This file was deleted.

2 changes: 1 addition & 1 deletion FrontEnd/src/pages/ProfileList/ProfileListPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ export default function ProfileListPage({ isAuthorized, isSaved }) {
<div className={css['company-list__content--items']}>
<ProfileList
isAuthorized={isAuthorized}
isLoading={isLoading}
emptyText={'Жодна компанія не відповідає обраному фільтру.'}
profiles={profiles}
items={fetchedProfiles?.total_items}
paginationFunc={handlePageChange}
Expand Down
6 changes: 3 additions & 3 deletions FrontEnd/src/pages/ProfileList/ProfileListPage.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
display: flex;
align-self: center;
flex-direction: column;
padding: 24px 16px 40px;
padding: 24px 27px 40px;
gap: 20px;
}

Expand Down Expand Up @@ -136,7 +136,7 @@
}

.company-list__content {
padding: 24px 32px 32px;
padding: 24px 35px 32px;
gap: 32px;
}

Expand Down Expand Up @@ -166,7 +166,7 @@
}

.company-list__content {
padding: 24px 104px 40px;
padding: 24px 107px 40px;
gap: 32px;
}

Expand Down
200 changes: 86 additions & 114 deletions FrontEnd/src/pages/SearchPage/Search.jsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,33 @@
import axios from 'axios';
import { useState, useEffect } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import SearchResults from './SearchField/SearchResults';
import link_to_left from './img/link_to_left.svg';
import link_to_right from './img/link_to_right.svg';
import styles from './search.module.scss';
import { useSearchParams } from 'react-router-dom';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import axios from 'axios';
import useSWR from 'swr';

const ITEMS_PER_PAGE = 100;
import useWindowWidth from '../../hooks/useWindowWidth';
import Loader from '../../components/Loader/Loader';
import ProfileList from '../ProfileList/ProfileList';
import styles from './Search.module.scss';

export function Search({ isAuthorized }) {
const [searchResults, setSearchResults] = useState([]);
const [searchPerformed, setSearchPerformed] = useState(false);

const location = useLocation();
const navigate = useNavigate();
const searchParams = new URLSearchParams(location.search);
const [searchParams, setSearchParams] = useSearchParams();
const searchTerm = searchParams.get('name');
const pageNumber = Number(searchParams.get('page')) || 1;
const [currentPage, setCurrentPage] = useState(pageNumber);
const [pageSize, setPageSize] = useState(16);
const servedAddress = process.env.REACT_APP_BASE_API_URL;
const searchUrl = 'search';

const fetcher = async (url) => {
const response = await axios.get(url);
setSearchResults(response.data);
};
async function fetcher(url) {
return axios.get(url)
.then(res => res.data);
}

const { data: companylist, error } = useSWR(
`${servedAddress}/api/search/?name=${searchTerm}&ordering=name`,
fetcher
const { data: companylist, isLoading } = useSWR(
`${servedAddress}/api/search/?name=${searchTerm}&ordering=name&page_size=${pageSize}&page=${currentPage}`,
fetcher,
{onSuccess: (data) => setSearchResults(data.results)}
);

const changeCompanies = (id, isSaved) => {
Expand All @@ -42,116 +40,90 @@ export function Search({ isAuthorized }) {
setSearchResults(newCompanies);
};

useEffect(() => {
if (searchTerm) {
setSearchPerformed(true);
}
}, [searchTerm, servedAddress, searchUrl, companylist]);
const windowWidth = useWindowWidth();

useEffect(() => {
setCurrentPage(pageNumber);
}, [pageNumber]);

const [currentPage, setCurrentPage] = useState(pageNumber);
const totalItems = searchResults.length;
const totalPages = Math.ceil(totalItems / ITEMS_PER_PAGE);

const startIndex = (currentPage - 1) * ITEMS_PER_PAGE;
const endIndex = startIndex + ITEMS_PER_PAGE;
const displayedResults = searchResults.slice(startIndex, endIndex);
if (windowWidth < 768) {
setPageSize(4);
} else if (windowWidth >= 768 && windowWidth < 1200) {
setPageSize(16);
} else if (windowWidth >= 1200 && windowWidth < 1512) {
setPageSize(12);
} else if (windowWidth >= 1512) {
setPageSize(16);
}
}, [windowWidth]);

const handlePageChange = (newPage) => {
setCurrentPage(newPage);
const updateQueryParams = (newPage) => {
searchParams.set('page', newPage);
navigate(`?${searchParams.toString()}`);
setSearchParams(searchParams);
};

const handlePageChange = (page) => {
setCurrentPage(page);
updateQueryParams(page);
};

useEffect(() => {
if (companylist?.total_items === 0) {
setCurrentPage(1);
searchParams.delete('page');
setSearchParams(searchParams);
} else {
const totalPages = Math.ceil(companylist?.total_items / pageSize);
if (currentPage > totalPages) {
setCurrentPage(totalPages);
updateQueryParams(totalPages);
}
}
}, [companylist?.total_items, pageSize, currentPage]);

return (
<div className={styles['main_block_outer']}>
<div className={styles['new-companies-main']}>
<div className={styles['new-companies-search_count']}>
{searchResults && (
<div className={styles['search-results']}>
<h3 className={styles['search_results_text']}>
Результати пошуку
<span className={styles['search_field_entered_value']}>
{` “${searchTerm}” `}
</span>
: {searchResults.length > 0 ? searchResults.length : 0}
</h3>
</div>
)}
</div>
{!error && searchResults.length > 0 && (
<div className={styles['search-page__outer']}>
<div
className={classNames(
styles['search-page'],
{ [styles['search-page__empty']]: companylist?.total_items === 0}
)}
>
{isLoading ?
<Loader/> : (
<>
<SearchResults
results={searchResults}
searchPerformed={searchPerformed}
displayedResults={displayedResults}
isAuthorized={isAuthorized}
changeCompanies={changeCompanies}
/>
<div className={styles['new-companies-result_pages']}>
{totalPages > 1 && (
<div className={styles['pagination']}>
{currentPage > 1 && (
<button onClick={() => handlePageChange(currentPage - 1)}>
<img src={link_to_left} alt="Link to Left" />
</button>
)}
{currentPage > 1 && (
<>
<button onClick={() => handlePageChange(1)}>1</button>
{currentPage > 2 && (
<span className={styles['ellipsis']}>...</span>
)}
</>
)}
{Array.from({ length: totalPages }, (_, i) => {
if (
i === 2 ||
i === totalPages ||
(i >= currentPage - 1 && i <= currentPage)
) {
return (
<button
key={i}
onClick={() => handlePageChange(i + 1)}
className={currentPage === i + 1 ? styles['active'] : ''}
>
{i + 1}
</button>
);
}
return null;
})}
{currentPage < totalPages - 1 && (
<>
{currentPage < totalPages - 1 && (
<span className={styles['ellipsis']}>...</span>
)}
<button onClick={() => handlePageChange(totalPages)}>
{totalPages}
</button>
</>
)}
{currentPage < totalPages && (
<button onClick={() => handlePageChange(currentPage + 1)}>
<img src={link_to_right} alt="Link to Right" />
</button>
)}
<div className={styles['search-page__results-count']}>
{searchResults && (
<div className={styles['search-results']}>
<h3 className={styles['search-results__text']}>
Результати пошуку
<span className={styles['search-field__entered-value']}>
{` “${searchTerm}” `}
</span>
: {companylist?.total_items || 0}
</h3>
</div>
)}
</div>
<div className={styles['search-list__content--items']}>
<ProfileList
isAuthorized={isAuthorized}
emptyText={' '}
profiles={searchResults}
items={companylist?.total_items}
paginationFunc={handlePageChange}
current={currentPage}
pageSize={pageSize}
changeCompanies={changeCompanies}
/>
</div>
</>
)}
</div>
{searchResults.length === 0 &&
<div className={styles['new-companies-main__error']}>
<p className={styles['search_result_error']}>
{companylist?.total_items === 0 &&
<div className={styles['search-page__error']}>
<p className={styles['search-result__error']}>
Пошук не дав результатів
</p>
</div>}
</div>
}
</div>
);
}
Expand Down
Loading

0 comments on commit 2945bb1

Please sign in to comment.