Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Search UI updates #2325

Merged
merged 1 commit into from
Feb 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/components/Navbar/SearchDrawer/Footer/Footer.module.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
@use "src/styles/breakpoints";

.container {
padding-block-end: var(--spacing-mega);
@include breakpoints.tablet {
padding-block-end: var(--spacing-mega);
}
padding-block-end: calc(4 * var(--spacing-mega));
}

.betaContainer {
Expand Down
4 changes: 4 additions & 0 deletions src/components/Navbar/SearchDrawer/Header/Header.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,7 @@
max-height: var(--spacing-mega);
margin-inline: calc(0.5 * var(--spacing-xxsmall));
}

.form {
display: contents;
}
12 changes: 9 additions & 3 deletions src/components/Navbar/SearchDrawer/Header/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { RefObject } from 'react';

import classNames from 'classnames';
import { useRouter } from 'next/router';
import useTranslation from 'next-translate/useTranslation';

import DrawerSearchIcon from '../Buttons/DrawerSearchIcon';
Expand All @@ -10,6 +11,7 @@ import styles from './Header.module.scss';
import TarteelVoiceSearchTrigger from '@/components/TarteelVoiceSearch/Trigger';
import Separator from '@/dls/Separator/Separator';
import { logButtonClick } from '@/utils/eventLogger';
import { getSearchQueryNavigationUrl } from '@/utils/navigation';

interface Props {
isVoiceFlowStarted: boolean;
Expand All @@ -29,10 +31,14 @@ const Header: React.FC<Props> = ({
searchQuery,
}) => {
const { t } = useTranslation('common');
const router = useRouter();

const onKeyboardReturnPressed = (e) => {
const onSubmit = (e: React.FormEvent) => {
e.preventDefault();
inputRef.current.blur();
inputRef.current?.blur();
if (searchQuery) {
router.push(getSearchQueryNavigationUrl(searchQuery));
}
};

return (
Expand All @@ -47,7 +53,7 @@ const Header: React.FC<Props> = ({
<>
<DrawerSearchIcon />
<div className={classNames(styles.searchInputContainer)}>
<form onSubmit={onKeyboardReturnPressed}>
<form onSubmit={onSubmit} className={styles.from}>
<input
className={styles.searchInput}
type="search"
Expand Down
1 change: 0 additions & 1 deletion src/components/Navbar/SearchDrawer/SearchDrawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ const SearchDrawer: React.FC = () => {
<VoiceSearchBodyContainer />
) : (
<SearchBodyContainer
onSearchResultClicked={() => searchInputRef?.current?.blur()}
onSearchKeywordClicked={onSearchKeywordClicked}
searchQuery={searchQuery}
searchResult={searchResult}
Expand Down
19 changes: 1 addition & 18 deletions src/components/Search/CommandBar/CommandsList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,12 @@ import CommandControl from './CommandControl';
import styles from './CommandList.module.scss';
import CommandPrefix from './CommandPrefix';

import SearchResultsHeader from '@/components/Search/SearchResults/SearchResultsHeader';
import useScroll, { SMOOTH_SCROLL_TO_CENTER } from '@/hooks/useScrollToElement';
import {
addRecentNavigation,
removeRecentNavigation,
setIsExpanded,
} from '@/redux/slices/CommandBar/state';
import SearchQuerySource from '@/types/SearchQuerySource';
import { logButtonClick } from '@/utils/eventLogger';
import { getSearchQueryNavigationUrl, resolveUrlBySearchNavigationType } from '@/utils/navigation';
import { getResultType } from '@/utils/search';
Expand Down Expand Up @@ -136,15 +134,6 @@ const CommandsList: React.FC<Props> = ({
dispatch({ type: removeRecentNavigation.type, payload: navigationItemKey });
};

const onSearchResultsHeaderClicked = () => {
navigateToLink({
name: searchQuery,
resultType: SearchNavigationType.SEARCH_PAGE,
key: searchQuery,
group: RESULTS_GROUP,
});
};

if (numberOfCommands === 0) {
return <p className={styles.noResult}>{t('command-bar.no-nav-results')}</p>;
}
Expand All @@ -159,13 +148,7 @@ const CommandsList: React.FC<Props> = ({
{Object.keys(groups).map((commandGroup) => {
return (
<div key={commandGroup}>
{commandGroup === RESULTS_GROUP ? (
<SearchResultsHeader
searchQuery={searchQuery}
source={SearchQuerySource.CommandBar}
onSearchResultClicked={onSearchResultsHeaderClicked}
/>
) : (
{commandGroup !== RESULTS_GROUP && (
<div className={styles.groupHeader} id={commandGroup}>
{commandGroup}
</div>
Expand Down
3 changes: 0 additions & 3 deletions src/components/Search/SearchBodyContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ interface Props {
hasError: boolean;
searchResult: SearchResponse;
onSearchKeywordClicked: (keyword: string) => void;
onSearchResultClicked?: () => void;
currentPage?: number;
pageSize?: number;
onPageChange?: (page: number) => void;
Expand All @@ -32,7 +31,6 @@ const SearchBodyContainer: React.FC<Props> = ({
hasError,
searchResult,
onSearchKeywordClicked,
onSearchResultClicked,
currentPage,
pageSize,
onPageChange,
Expand Down Expand Up @@ -70,7 +68,6 @@ const SearchBodyContainer: React.FC<Props> = ({
/>
) : (
<SearchResults
onSearchResultClicked={onSearchResultClicked}
searchResult={searchResult}
searchQuery={searchQuery}
source={source}
Expand Down
4 changes: 4 additions & 0 deletions src/components/Search/SearchInput/SearchInput.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@
justify-content: center;
}

.form {
display: contents;
}

.input {
border: none !important;
width: 100%;
Expand Down
60 changes: 36 additions & 24 deletions src/components/Search/SearchInput/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useCallback, useEffect, useRef, useState } from 'react';

import classNames from 'classnames';
import { useRouter } from 'next/router';
import { useHotkeys } from 'react-hotkeys-hook';
import { shallowEqual, useDispatch, useSelector } from 'react-redux';

Expand All @@ -20,6 +21,7 @@ import {
stopCommandBarVoiceFlow,
} from '@/redux/slices/voiceSearch';
import { logButtonClick } from '@/utils/eventLogger';
import { getSearchQueryNavigationUrl } from '@/utils/navigation';
import { isMobile } from '@/utils/responsive';

type Props = {
Expand All @@ -35,6 +37,7 @@ const SearchInput: React.FC<Props> = ({
shouldExpandOnClick = false,
shouldOpenDrawerOnMobile = false,
}) => {
const router = useRouter();
const isVoiceSearchFlowStarted = useSelector(selectIsCommandBarVoiceFlowStarted, shallowEqual);
const [searchQuery, setSearchQuery] = useState<string>(initialSearchQuery || '');
const isExpanded = useSelector(selectIsExpanded);
Expand Down Expand Up @@ -93,36 +96,45 @@ const SearchInput: React.FC<Props> = ({
}
};

const onSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (searchQuery) {
router.push(getSearchQueryNavigationUrl(searchQuery));
}
};

return (
<div
ref={containerRef}
className={classNames(styles.headerOuterContainer, { [styles.expanded]: isExpanded })}
>
<div className={styles.inputContainer}>
<Input
onClick={onInputClick}
id="searchQuery"
disabled={isVoiceSearchFlowStarted}
onChange={onSearchQueryChange}
value={searchQuery}
placeholder={placeholder}
onClearClicked={onClearClicked}
clearable
prefix={<SearchIcon />}
prefixSuffixContainerClassName={styles.prefixSuffixContainer}
containerClassName={styles.input}
htmlType="search"
enterKeyHint="search"
suffix={
<>
<KeyboardInput meta keyboardKey="K" />
<TarteelVoiceSearchTrigger isCommandBar onClick={onTarteelTriggerClicked} />
</>
}
shouldUseDefaultStyles={false}
fixedWidth={false}
size={InputSize.Large}
/>
<form onSubmit={onSubmit} className={styles.form}>
<Input
onClick={onInputClick}
id="searchQuery"
disabled={isVoiceSearchFlowStarted}
onChange={onSearchQueryChange}
value={searchQuery}
placeholder={placeholder}
onClearClicked={onClearClicked}
clearable
prefix={<SearchIcon />}
prefixSuffixContainerClassName={styles.prefixSuffixContainer}
containerClassName={styles.input}
htmlType="search"
enterKeyHint="search"
suffix={
<>
<KeyboardInput meta keyboardKey="K" />
<TarteelVoiceSearchTrigger isCommandBar onClick={onTarteelTriggerClicked} />
</>
}
shouldUseDefaultStyles={false}
fixedWidth={false}
size={InputSize.Large}
/>
</form>
</div>
{isExpanded && (
<div className={styles.dropdownContainer}>
Expand Down
31 changes: 13 additions & 18 deletions src/components/Search/SearchResults/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import React from 'react';
import useTranslation from 'next-translate/useTranslation';

import SearchResultItem from './SearchResultItem';
import SearchResultsHeader from './SearchResultsHeader';

import Pagination from '@/dls/Pagination/Pagination';
import useScrollToTop from '@/hooks/useScrollToTop';
import SearchQuerySource from '@/types/SearchQuerySource';
import { toLocalizedNumber } from '@/utils/locale';
import { SearchResponse } from 'types/ApiResponses';
Expand All @@ -16,7 +16,6 @@ interface Props {
currentPage?: number;
pageSize?: number;
onPageChange?: (page: number) => void;
onSearchResultClicked?: () => void;
source: SearchQuerySource;
}

Expand All @@ -27,28 +26,24 @@ const SearchResults: React.FC<Props> = ({
currentPage,
onPageChange,
pageSize,
onSearchResultClicked,
}) => {
const results = searchResult.result.navigation.concat(searchResult.result.verses);
const isSearchDrawer = source === SearchQuerySource.SearchDrawer;
const { t, lang } = useTranslation('common');
const scrollToTop = useScrollToTop();

const handlePageChange = (page: number) => {
scrollToTop();
onPageChange?.(page);
};

return (
<div>
{isSearchDrawer ? (
<SearchResultsHeader
searchQuery={searchQuery}
onSearchResultClicked={onSearchResultClicked}
source={source}
/>
) : (
{!isSearchDrawer && searchQuery && (
<>
{searchQuery && (
<>
{t('search-results', {
count: toLocalizedNumber(searchResult.pagination.totalRecords, lang),
})}
</>
)}
{t('search-results', {
count: toLocalizedNumber(searchResult.pagination.totalRecords, lang),
})}
</>
)}
<>
Expand All @@ -65,7 +60,7 @@ const SearchResults: React.FC<Props> = ({
<Pagination
currentPage={currentPage}
totalCount={searchResult.pagination.totalRecords}
onPageChange={onPageChange}
onPageChange={handlePageChange}
pageSize={pageSize}
/>
)}
Expand Down
2 changes: 1 addition & 1 deletion src/utils/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ export const resolveUrlBySearchNavigationType = (
* @returns {string}
*/
export const getSearchQueryNavigationUrl = (query?: string): string =>
`/search${query ? `?${QueryParam.QUERY}=${query}` : ''}`;
`/search${query ? `?${QueryParam.QUERY}=${encodeURIComponent(query)}` : ''}`;

/**
* Get the href link to the info page of a Surah.
Expand Down