Skip to content

Commit

Permalink
feature(search): close with menu button + tabs + No result fount elem…
Browse files Browse the repository at this point in the history
…ent (#125)

* feat: add no results found components

* feat: handle close search with menu button + tabs
  • Loading branch information
amir-kedis authored Dec 13, 2024
1 parent 84eef6d commit 61e9867
Show file tree
Hide file tree
Showing 10 changed files with 173 additions and 37 deletions.
5 changes: 4 additions & 1 deletion app/src/components/side-bar/chats/SearchBar.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { getIcon } from "@data/icons";
import { setSearchTerm } from "@state/messages/global-search";
import { useDispatch } from "react-redux";
import { RootState } from "@state/store";
import { useDispatch, useSelector } from "react-redux";
import styled from "styled-components";

const StyledSearchBar = styled.div`
Expand Down Expand Up @@ -46,6 +47,7 @@ const Input = styled.input`

function SearchBar() {
const dispatch = useDispatch();
const { searchTerm } = useSelector((state: RootState) => state.globalSearch);

const onSearch = (e: React.ChangeEvent<HTMLInputElement>) => {
dispatch(setSearchTerm(e.target.value));
Expand All @@ -58,6 +60,7 @@ function SearchBar() {
placeholder="Search"
data-testid="general-search"
onChange={onSearch}
value={searchTerm}
/>
<Icon data-testid="general-serach-icon">{getIcon("Search")}</Icon>
</StyledSearchBar>
Expand Down
26 changes: 22 additions & 4 deletions app/src/components/side-bar/chats/SideBarToolsButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import { updateSideBarView } from "@state/side-bar/sideBar";
import { sideBarPages } from "@data/sideBar";
import { useMouseLeave } from "@hooks/useMouseLeave";
import { getIcon } from "@data/icons";
import { RootState } from "@state/store";
import { clearSearch } from "@state/messages/global-search";
import { useSelector } from "react-redux";

const ToolsIcon = styled.div`
> svg {
Expand Down Expand Up @@ -41,16 +44,31 @@ const StyledList = styled.ul<{ $isOpened?: boolean }>`
`;

function SettingsToolbar() {
const { searchTerm } = useSelector((state: RootState) => state.globalSearch);
const isSearching = searchTerm.length > 0;
const [isOpened, setIsOpened] = useState(false);
const dispatch = useAppDispatch();
const ref = useMouseLeave(() => setIsOpened(false), false);

const handleOpenSettings = () => {
setIsOpened((prevState) => !prevState);
};

const handleResetSearch = () => {
dispatch(clearSearch());
};

return (
<>
<ToolsIcon onClick={handleOpenSettings} data-testid="menu-items-icon">
{getIcon("Menu")}
<ToolsIcon
onClick={() =>
isSearching ? handleResetSearch() : handleOpenSettings()
}
data-testid="menu-items-icon"
>
{isSearching
? getIcon("Close", { fontSize: "large", sx: { fontSize: "2rem" } })
: getIcon("Menu")}
</ToolsIcon>
{isOpened && (
<StyledList
Expand All @@ -66,7 +84,7 @@ function SettingsToolbar() {
updateSideBarView({
redirect: sideBarPages.CONTACTS,
data: undefined,
})
}),
)
}
/>
Expand All @@ -79,7 +97,7 @@ function SettingsToolbar() {
updateSideBarView({
redirect: sideBarPages.SETTINGS,
data: undefined,
})
}),
)
}
/>
Expand Down
1 change: 1 addition & 0 deletions app/src/data/animations/not_found.json

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions app/src/features/profile-info/ProfileInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { useProfileSettings } from "@features/profile-settings/hooks/useProfileSettings";
import styled from "styled-components";
import ProfileItem from "./components/ProfileItem";
import { getIcon } from "@data/icons";

const ProfileInfoStyled = styled.div`
border-bottom: 0.625rem solid var(--color-background-secondary);
Expand Down Expand Up @@ -45,7 +44,7 @@ function ProfileInfo() {
<ProfileItem
data={profileSettings.bio}
ribbon="Bio"
icon="info"
icon="Info"
data-testid="bio-profile-item"
/>
)}
Expand Down
44 changes: 44 additions & 0 deletions app/src/features/search/components/NoResultsFound.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import Lottie from "lottie-react";
import styled from "styled-components";
import noResultsAnimation from "@data/animations/not_found.json";

const NoResultsContainer = styled.div`
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
padding-bottom: 2rem;
`;

const NoResultsIcon = styled.div`
--icon-size: 8rem;
width: var(--icon-size);
height: var(--icon-size);
`;

const NoResultsText = styled.p`
font-size: 1.5rem;
font-weight: 500;
color: var(--color-text-secondary);
`;

const NoResultsSubText = styled.p`
font-size: 1rem;
font-weight: 400;
color: var(--color-text-secondary);
`;

const NoResultsFound: React.FC = () => {
return (
<NoResultsContainer>
<NoResultsIcon>
<Lottie animationData={noResultsAnimation} />
</NoResultsIcon>
<NoResultsText>No results found</NoResultsText>
<NoResultsSubText>Try searching for something else</NoResultsSubText>
</NoResultsContainer>
);
};

export default NoResultsFound;
41 changes: 25 additions & 16 deletions app/src/features/search/components/SearchBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,10 @@ const SearchBar: React.FC<SearchBarProps> = ({ onClose }) => {
const dispatch = useDispatch();
const chatId = useParams<{ chatId: string }>().chatId;
const { searchTerm, searchResults, currentResultIndex } = useSelector(
(state: RootState) => state.search
(state: RootState) => state.search,
);
const currentChat = useSelector((state: RootState) =>
state.chats.chats.find((chat) => chat._id === chatId)
state.chats.chats.find((chat) => chat._id === chatId),
);
const messages = currentChat?.messages ?? [];

Expand All @@ -90,22 +90,31 @@ const SearchBar: React.FC<SearchBarProps> = ({ onClose }) => {
return;
}

const results = messages.reduce<{ messageId: string; highlightIndex: number }[]>((acc, message) => {
const lowerCaseTerm = term.toLowerCase();
const lowerCaseContent = message.content.toLowerCase();

if (lowerCaseContent.includes(lowerCaseTerm)) {
const matchIndices = findAllMatchIndices(message.content, term);
matchIndices.forEach((highlightIndex) => {
acc.push({
messageId: message._id,
highlightIndex,
const results = messages.reduce(
(
acc: Array<{
messageId: string;
highlightIndex: number;
}>,
message,
) => {
const lowerCaseTerm = term.toLowerCase();
const lowerCaseContent = message.content.toLowerCase();

if (lowerCaseContent.includes(lowerCaseTerm)) {
const matchIndices = findAllMatchIndices(message.content, term);
matchIndices.forEach((highlightIndex) => {
acc.push({
messageId: message._id,
highlightIndex,
});
});
});
}
}

return acc;
}, []);
return acc;
},
[],
);

dispatch(setSearchTerm(term));
dispatch(setSearchResults(results));
Expand Down
6 changes: 3 additions & 3 deletions app/src/features/search/components/TabedSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { RootState } from "@state/store";
import { motion, AnimatePresence, LayoutGroup } from "motion/react";
import { useDispatch, useSelector } from "react-redux";
import styled from "styled-components";
import { SEARCH_TABS } from "../data/tabs-components-map";
import { SEARCH_TABS_MOCK } from "../data/tabs-components-map";
import { setSelectedTab } from "@state/messages/global-search";

const TabedSearchContainer = styled(motion.div)`
Expand Down Expand Up @@ -78,7 +78,7 @@ const TabedSearch: React.FC = () => {
>
<LayoutGroup>
<TabListWrapper>
{SEARCH_TABS.map((tab) => (
{SEARCH_TABS_MOCK.map((tab) => (
<TabButton
key={tab.title}
onClick={() => dispatch(setSelectedTab(tab.title))}
Expand Down Expand Up @@ -106,7 +106,7 @@ const TabedSearch: React.FC = () => {
exit={{ opacity: 0 }}
transition={{ type: "tween", duration: 0.2 }}
>
{SEARCH_TABS.find(
{SEARCH_TABS_MOCK.find(
(tab) => tab.title === selectedTab,
)?.component()}
</TabContent>
Expand Down
34 changes: 34 additions & 0 deletions app/src/features/search/components/tabs/MessagesTab.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { RootState } from "@state/store";
import { useSelector } from "react-redux";
import MessageResult from "../result-items/MessageResult";
import NoResultsFound from "../NoResultsFound";

const MESSAGES = [
{
title: "Telware Testing",
date: new Date().toString(),
image: "https://placecats.com/200/200",
message: "Hello hi there",
},
];

const MessagesTab: React.FC = () => {
const { searchTerm } = useSelector((state: RootState) => state.globalSearch);

return (
<div style={{ height: "100%" }}>
{MESSAGES.length === 0 && <NoResultsFound />}
{MESSAGES.map((message) => (
<MessageResult
searchTerm={searchTerm}
message={message.message}
title={message.title}
date={message.date}
image={message.image}
/>
))}
</div>
);
};

export default MessagesTab;
43 changes: 33 additions & 10 deletions app/src/features/search/data/tabs-components-map.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,40 @@
import NoResultsFound from "../components/NoResultsFound";
import AudioResult from "../components/result-items/AudioResult";
import ChannelResult from "../components/result-items/ChannelResult";
import FileResult from "../components/result-items/FileResult";
import MessageResult from "../components/result-items/MessageResult";
import MessagesTab from "../components/tabs/MessagesTab";

export const SEARCH_TABS_MOCK = [
{
title: "Chats",
component: () => <MessagesTab />,
},
{
title: "Channnels",
component: () => <NoResultsFound />,
},
{
title: "Media",
component: () => <NoResultsFound />,
},
{
title: "Links",
component: () => <NoResultsFound />,
},
{
title: "Files",
component: () => <NoResultsFound />,
},
{
title: "Music",
component: () => <NoResultsFound />,
},
{
title: "Voice",
component: () => <NoResultsFound />,
},
];
export const SEARCH_TABS = [
{
title: "Chats",
Expand Down Expand Up @@ -107,16 +139,7 @@ export const SEARCH_TABS = [
},
{
title: "Files",
component: () => (
<div>
<FileResult
title="Telware Testing"
image="https://www.svgrepo.com/show/144578/pdf.svg"
size="20"
date={new Date().toString()}
/>
</div>
),
component: () => <NoResultsFound />,
},
{
title: "Music",
Expand Down
7 changes: 6 additions & 1 deletion app/src/state/messages/global-search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ const globalSearchSlice = createSlice({
name: "globalSearch",
initialState,
reducers: {
clearSearch: (state) => {
state.searchTerm = "";
state.selectedTab = "Chats";
},
setSearchTerm: (state, action: PayloadAction<string>) => {
state.searchTerm = action.payload;
},
Expand All @@ -23,5 +27,6 @@ const globalSearchSlice = createSlice({
},
});

export const { setSearchTerm, setSelectedTab } = globalSearchSlice.actions;
export const { setSearchTerm, setSelectedTab, clearSearch } =
globalSearchSlice.actions;
export default globalSearchSlice.reducer;

0 comments on commit 61e9867

Please sign in to comment.