SearchPageLayout.tsx 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import React, { FC } from 'react';
  2. import { useTranslation } from 'react-i18next';
  3. type SearchResultMeta = {
  4. took?: number,
  5. total?: number,
  6. results?: number
  7. }
  8. type Props = {
  9. SearchControl: React.FunctionComponent,
  10. SearchResultList: React.FunctionComponent,
  11. SearchResultContent: React.FunctionComponent,
  12. searchResultMeta: SearchResultMeta,
  13. searchingKeyword: string,
  14. pagingLimit: number,
  15. activePage: number,
  16. onPagingLimitChanged: (limit: number) => void
  17. }
  18. const SearchPageLayout: FC<Props> = (props: Props) => {
  19. const { t } = useTranslation('');
  20. const {
  21. SearchResultList, SearchControl, SearchResultContent, searchResultMeta, searchingKeyword, pagingLimit, activePage,
  22. } = props;
  23. const renderShowingPageCountInfo = () => {
  24. if (searchResultMeta.total == null || searchResultMeta.total === 0) return;
  25. const leftNum = pagingLimit * (activePage - 1) + 1;
  26. const rightNum = (leftNum - 1) + (searchResultMeta.results || 0);
  27. return <span className="ml-3">{`${leftNum}-${rightNum}`} / {searchResultMeta.total || 0}</span>;
  28. };
  29. return (
  30. <div className="content-main">
  31. <div className="search-result d-flex" id="search-result">
  32. <div className="mw-0 flex-grow-1 flex-basis-0 border boder-gray search-result-list" id="search-result-list">
  33. <SearchControl></SearchControl>
  34. <div className="search-result-list-scroll">
  35. <div className="d-flex align-items-center justify-content-between my-3 ml-4">
  36. <div className="search-result-meta text-nowrap">
  37. <span className="font-weight-light">{t('search_result.result_meta')} </span>
  38. <span className="h5">{`"${searchingKeyword}"`}</span>
  39. {/* Todo: replace "1-10" to the appropriate value */}
  40. {renderShowingPageCountInfo()}
  41. </div>
  42. <div className="input-group search-result-select-group ml-4 d-lg-flex d-none">
  43. <div className="input-group-prepend">
  44. <label className="input-group-text text-muted" htmlFor="inputGroupSelect01">{t('search_result.number_of_list_to_display')}</label>
  45. </div>
  46. <select
  47. defaultValue={props.pagingLimit}
  48. className="custom-select"
  49. id="inputGroupSelect01"
  50. onChange={(e) => { props.onPagingLimitChanged(Number(e.target.value)) }}
  51. >
  52. {[20, 50, 100, 200].map((limit) => {
  53. return <option key={limit} value={limit}>{limit}{t('search_result.page_number_unit')}</option>;
  54. })}
  55. </select>
  56. </div>
  57. </div>
  58. <div className="page-list px-md-4">
  59. <SearchResultList></SearchResultList>
  60. </div>
  61. </div>
  62. </div>
  63. <div className="mw-0 flex-grow-1 flex-basis-0 d-none d-lg-block search-result-content">
  64. <SearchResultContent></SearchResultContent>
  65. </div>
  66. </div>
  67. </div>
  68. );
  69. };
  70. export default SearchPageLayout;