Files
threetwo/src/client/components/GlobalSearchBar/SearchBar.tsx
Rishi Ghan 8bebffd95e 🌊 qBittorrent Settings Scaffold (#90)
* 🌊 qBittorrent settings scaffold

* 🔧 Added scaffold for the qBittorrent connection form

* 🔧 Some refactoring

* 🔧 Cleaned up folder structure

* 🔧 Fixed broken paths

* 🔧 Cleaned up Search and Import component hierarchy

* 🔧 More path fixes

* 🔧 Tooling changes

* 📝 Qbittorrent form scaffold

* ⬆️ Bumped @dnd-kit deps

* 🧑🏼‍🔧 Fixed the hostname regex

* 🏗️ Adding fields to the settings form

* 🔧 Formatting and more layout changes

* 🔧 Added Prowlarr settings items in JSON

* 📝 Purified Card Component

* 📝 Abstracted connection form into a component

* 🏗️ Reorganized tabs

* Migrating from Redux to RTK-query

* ⬇️ Fetched qBittorrent settings

* 🏗️ Trying out react-query

* 🧩 Added react-query query to qBittorrentSettings page

* 📝 qbittorrent form RU actions first draft

* 🏗️ Added loading state check

* 🏗 Added error check state

* 🏗️ Refactored AirDCPP context using react-query

* 🏗️ Refactoring AirDCPP Settings Form with react-query

* 🔧 Removed context

* 🔧 Removing context from AirDCPP settings page

* 🔧 Fixed early init error on the store

* 🐛 Debugging AirDCPP Settings Form page

* 🧸 Zustand-ified AirDCPP Form

*  AirDCPP code cleaned up from App.tsx

*  Re-added yarn.lock
2023-11-07 11:46:08 -06:00

83 lines
2.1 KiB
TypeScript

import { debounce, isEmpty, map } from "lodash";
import React, { ReactElement, useCallback, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import Card from "../shared/Carda";
import { searchIssue } from "../../actions/fileops.actions";
import MetadataPanel from "../shared/MetadataPanel";
interface ISearchBarProps {
data: any;
}
export const SearchBar = (data: ISearchBarProps): ReactElement => {
const dispatch = useDispatch();
const searchResults = useSelector(
(state: RootState) => state.fileOps.librarySearchResultsFormatted,
);
const performSearch = useCallback(
debounce((e) => {
dispatch(
searchIssue(
{
query: {
volumeName: e.target.value,
},
},
{
pagination: {
size: 25,
from: 0,
},
type: "volumeName",
trigger: "globalSearchBar",
},
),
);
}, 500),
[data],
);
return (
<>
<div className="control has-icons-right">
<input
className="input mt-2"
placeholder="Search Library"
onChange={(e) => performSearch(e)}
/>
<span className="icon is-right mt-2">
<i className="fa-solid fa-magnifying-glass"></i>
</span>
</div>
{!isEmpty(searchResults) ? (
<div
className="columns box is-multiline"
style={{
padding: 4,
position: "absolute",
width: 360,
margin: "60px 0 0 350px",
}}
>
{map(searchResults, (result, idx) => (
<MetadataPanel
data={result}
key={idx}
imageStyle={{ maxWidth: 70 }}
titleStyle={{ fontSize: "0.8rem" }}
tagsStyle={{ fontSize: "0.7rem" }}
containerStyle={{
width: "100vw",
padding: 0,
margin: "0 0 8px 0",
}}
/>
))}
</div>
) : null}
</>
);
};