Skip to content

Find Contracts Filters

FindContracts Component Documentation

Overview

The FindContracts component in the Rifbid application allows users to search for contracts using various filters. It supports both simple and semantic searches, allows filtering by date, industry, and country, and can recommend contracts based on the user’s profile.

Key Features

  1. Filter Contracts: Users can filter contracts by start date, end date, industry, and country.
  2. Search Functionality: Supports both simple keyword searches and semantic searches for finding contracts with similar meanings.
  3. Recommendations: Can recommend contracts based on the user’s profile.
  4. Save Filters in URL: Keeps the state of filters in the URL for easy sharing and persistence.
  5. Fetch User Profile: Loads and uses the supplier’s profile information from Firestore.
  6. Tooltips: Provides additional information to the user with tooltips.

Dependencies

  • React: For building the component.
  • Firebase: For authentication and Firestore database interactions.
  • Next.js: For routing and handling URL parameters.
  • Custom UI Components: Various UI components for filters, switches, search bars, and contract items.

State Management

The component uses React’s useState and useEffect hooks for managing state and side effects.

const [startDate, setStartDate] = useState("");
const [endDate, setEndDate] = useState("");
const [industry, setIndustry] = useState<string>("");
const [country, setCountry] = useState<string>("");
const [recommendedContracts, setRecommendedContracts] = useState(false);
const [simpleSearch, setSimpleSearch] = useState<string>("");
const [semanticSearch, setSemanticSearch] = useState<string>("");
const [isSemanticSearch, setIsSemanticSearch] = useState(false);
const [pageNumber, setPageNumber] = useState(1);
const [supplierProfile, setSupplierProfile] = useState<
SupplierUserProfile | undefined
>();
const [isLoading, setIsLoading] = useState(false);
const [token, setToken] = useState<string | undefined>("");
const [showTooltip, setShowTooltip] = useState(false);

Fetching and Updating Filters

Initialize Filters from URL

useEffect(() => {
setCountry(searchParams.get("country") || "");
setIndustry(searchParams.get("industry") || "");
setStartDate(searchParams.get("startDate") || "");
setEndDate(searchParams.get("endDate") || "");
setSimpleSearch(searchParams.get("simpleSearch") || "");
setSemanticSearch(searchParams.get("semanticSearch") || "");
setIsSemanticSearch(searchParams.get("isSemanticSearch") === "true");
setRecommendedContracts(searchParams.get("isRecommendedContract") === "true");
setPageNumber(parseInt(searchParams.get("pageNumber") || "1"));
}, []);

Update Filters in URL

const updateFiltersInUrl = useCallback(() => {
const queryParams = new URLSearchParams();
if (startDate) queryParams.set("startDate", startDate);
if (endDate) queryParams.set("endDate", endDate);
if (industry) queryParams.set("industry", industry);
if (country) queryParams.set("country", country);
if (simpleSearch) queryParams.set("simpleSearch", simpleSearch);
if (semanticSearch) queryParams.set("semanticSearch", semanticSearch);
if (isSemanticSearch)
queryParams.set("isSemanticSearch", isSemanticSearch.toString());
if (recommendedContracts)
queryParams.set("isRecommendedContract", recommendedContracts.toString());
if (pageNumber > 1) queryParams.set("pageNumber", pageNumber.toString());
router.push(`/find-contracts?${queryParams.toString()}`);
}, [
startDate,
endDate,
industry,
country,
simpleSearch,
semanticSearch,
isSemanticSearch,
recommendedContracts,
pageNumber,
]);
useEffect(() => {
updateFiltersInUrl();
}, [updateFiltersInUrl]);

Fetching User Profile

Fetches and sets the supplier’s profile information from Firestore.

useEffect(() => {
setIsLoading(true);
async function getUserProfile() {
const docRef = doc(db, "supplierprofileinformation", user?.uid);
const docSnap = await getDoc(docRef);
if (docSnap.exists()) {
const supplierProfile = docSnap.data();
setSupplierProfile(supplierProfile);
setIsLoading(false);
} else {
console.log("No such document!");
return null;
}
}
const getIdToken = async () => {
const token = await user?.getIdToken(true);
setToken(token);
};
getUserProfile();
getIdToken();
}, []);

Component Structure

Renders the search bar, filters, and contract items based on the current state.

return (
<>
{isLoading ? (
<h1>Loading...</h1>
) : (
<div className="grid grid-cols-1 gap-4 md:grid-cols-3">
<div className="relative flex items-center space-x-4 ps-5">
<h1 className="text-xl font-bold">Semantic Search</h1>
<CiCircleInfo
size={20}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
/>
{showTooltip && (
<div className={styles.tooltip}>
Click this button to toggle to semantic search. Instead of looking
for an exact match, we will return contracts similar in meaning to
what you searched. Users on the free plan are allowed 5 searches
per month.
</div>
)}
<Switch onClick={toggleSemanticSearch} checked={isSemanticSearch} />
</div>
{isSemanticSearch ? (
<SupplierSemanticSearchBar setSemanticSearch={handleSemanticSearch} />
) : (
<SupplierSearchBar
setSimpleSearch={handleSimpleSearch}
simpleSearch={simpleSearch}
/>
)}
<SupplierSearchFilters
handleStartDateChange={handleStartDateChange}
handleEndDateChange={handleEndDateChange}
setIndustry={handleIndustry}
setCountry={handleLocation}
toggleRecommendedContracts={toggleRecommendedContracts}
isRecommendedContract={recommendedContracts}
selectedCountry={country}
selectedIndustry={industry}
selectedStartDate={startDate}
selectedEndDate={endDate}
/>
<ContractItem
startDate={startDate}
endDate={endDate}
industry={industry}
country={country}
simpleSearch={simpleSearch}
semanticSearch={semanticSearch}
isSemanticSearch={isSemanticSearch}
isRecommendedContract={recommendedContracts}
recommendation={recommendationString}
pageNumber={pageNumber}
setPageNumber={setPageNumber}
token={token}
queryUrlString={queryUrlString}
userId={user?.uid}
/>
</div>
)}
<NetPromoterScore />
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 md:gap-6 xl:grid-cols-4 2xl:gap-7.5"></div>
</>
);

Conclusion

This documentation provides an overview of the FindContracts component, its key features, state management, and critical functions. For further details, refer to the component’s source code in the project directory.