Search & Filter Logic
Overview
The search and filter system is the core engine of the Explore page. It allows users to query the fundingData dataset using multiple concurrent criteria. The logic is implemented using a high-performance useMemo hook that recalculates the visible deal list whenever filter states change, ensuring a responsive UI even with large datasets.
Filter Categories
The system supports eight distinct filter dimensions. For a deal to be displayed, it must satisfy all active filter conditions.
1. Text Search
The interface provides two independent text search inputs:
- Company Search: Performs a case-insensitive partial match against the
companyfield. - Investor Search: Iterates through the
investorsarray of each deal to find matching names.
2. Categorical Filters (Multi-select)
These filters use a "match-any" logic within the category. For example, selecting "SaaS" and "Fintech" will show deals belonging to either sector.
- Sectors: Filters by industry (e.g., EdTech, E-commerce).
- Stages: Filters by funding round (e.g., Seed, Series A, Debt).
- Years: Filters based on the calendar year extracted from the deal date.
3. Location Filter (Single-select)
Filters deals based on their primary headquarters (e.g., Bengaluru, Mumbai).
4. Financial Filters
- Funding Range: A range slider that filters deals based on the amount in INR Crores.
- Undisclosed Toggle: A boolean filter to include or exclude deals where the specific funding amount was not made public.
Technical Interface
The filtering logic is driven by the state within ExplorePage. If you are extending the UI or building a custom view, the following state schema defines the filter requirements:
| State Key | Type | Description |
| :--- | :--- | :--- |
| searchQuery | string | Partial match for company names. |
| investorSearch | string | Partial match for investor names. |
| selectedSectors | string[] | Array of active sector tags. |
| selectedStages | string[] | Array of active funding stages. |
| fundingRange | [number, number] | Tuple representing [min, max] in Crores. |
| showUndisclosed | boolean | Whether to show deals where amount === 0. |
Logic Implementation Example
The filtering predicate follows this structure:
const filteredDeals = fundingData.filter((deal) => {
// Sector logic: Match if no sector is selected OR if deal sectors intersect with selection
const sectorMatch = selectedSectors.length === 0 ||
deal.sectors.some((s) => selectedSectors.includes(s));
// Search logic: Case-insensitive partial match
const companyMatch = searchQuery === "" ||
deal.company.toLowerCase().includes(searchQuery.toLowerCase());
// Range logic: Check if amount falls within the [min, max] range
const amountMatch = deal.amount >= fundingRange[0] &&
deal.amount <= fundingRange[1];
return sectorMatch && companyMatch && amountMatch; // ...and all other filters
});
Sorting Logic
Once the data is filtered, it is passed through a sort function. Users can toggle between two primary views:
- Date (Default): Most recent funding rounds appear first.
- Amount: Largest disclosed deals appear at the top of the list.
.sort((a, b) => {
if (sortBy === "date") return new Date(b.date).getTime() - new Date(a.date).getTime();
return b.amount - a.amount;
})
Internal Components
The search and filter functionality relies on several internal components:
FilterPanel: The sidebar component that manages the UI state for checkboxes and range sliders.SearchBar: A shared component used in the Header and Explore page for text-based queries.isFundingDisclosed(Utility): A helper function fromlib/utils.tsthat determines if a deal should be subject to amount-based filtering.
Usage in Components
To display the results, the filtered array is passed to the DealsList component:
<DealsList deals={filteredDeals} />
If filteredDeals is empty, the component automatically renders a "No deals found" state.