Skip to content

Commit

Permalink
Add filter option to search
Browse files Browse the repository at this point in the history
  • Loading branch information
Karol-2 committed Mar 24, 2024
1 parent d21f343 commit ee6b36d
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 70 deletions.
135 changes: 135 additions & 0 deletions frontend/src/components/Search.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import { faMagnifyingGlass } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import React, { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { useUser } from "../helpers/UserProvider";
import editDistance from "../misc/editDistance";
import User from "../models/User";
import dataService from "../services/data";
import Select from "react-select";
import countriesData from "../assets/countries.json";

interface searchProps{
handler: (test: [[User, number]])=>void
}

const Search = (props: searchProps) => {
const navigate = useNavigate();
const setUsersFound = props.handler

// Logic
const [searchQuery, setSearchQuery] = useState("");
const [country, setCountry] = useState("");
const [countryList, setCountryList] = useState(countriesData);
const [error, setError] = useState("");

;
const { user, userId } = useUser();

useEffect(()=>{
const optionsWithEmpty = [{ Country: '-', Code: '-' }, ...countryList];

setCountryList(optionsWithEmpty);
},[])

const countryOptions = countryList.map((country) => ({
value: country.Country,
label: country.Country,
}));

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const handleCountryChange = (e: any) => {
const selectedCountry = e ? e.value : "";
setCountry(selectedCountry);
};

const handleSearch = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();

let url: string = `/users/search?q=${searchQuery}`;
if (country !== "" && country !== "-") {
url = url + "&country=" + country;
}

if (userId === null) navigate("/login");

if (searchQuery.trim() === "") {
return;
}
try{
setError("")
const response = await dataService.fetchData(url, "GET");

const responseWithoutCurrUser = response.users.filter(
(respArr: [User, number]) => respArr[0].id !== user!.id,
);

const usersSorted = sortUsersByDistance(
searchQuery,
responseWithoutCurrUser,
);

setUsersFound(usersSorted);
} catch{
setError("No users found")
}

};

const sortUsersByDistance = (searchTerm: string, users: [[User, number]]) => {
const userScores = users.map((respArr: [User, number]) => {
const user = respArr[0];
const score = editDistance(user.first_name + user.last_name, searchTerm);
return [user, score];
});

// eslint-disable-next-line @typescript-eslint/no-explicit-any
return userScores.sort((a: any, b: any) => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [_userA, scoreA] = a;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [_userB, scoreB] = b;

return scoreA - scoreB;
}) as [[User, number]];
};

return (
<div id="search-wrapper" className="mx-50 my-20 flex items-center flex-col">

<form
className="flex flex-col md:flex-row gap-5 max-w-3xl w-full mt-5"
onSubmit={handleSearch}
>
<div className=" w-full">
<input
type="text"
placeholder="Enter your friend's name"
className="form-input text-my-darker"
onChange={(e) => setSearchQuery(e.target.value)}
></input>
</div>

<button type="submit" className="btn bg-my-purple text-xs px-7 py-5">
<div className="flex gap-3 items-center text-cente justify-center">
<span className=" text-center">Search</span>
<FontAwesomeIcon icon={faMagnifyingGlass} />
</div>
</button>
</form>

<div className=" p-5 bg-my-orange rounded-md w-80 mt-5 self-start text-sm">
<div>Country<span className=" font-thin"> (not required)</span></div>
<Select
options={countryOptions}
onChange={handleCountryChange}
className="text-my-dark w-full text-sm "
/>
</div>
<div>{error}</div>
</div>

);
};

export default Search;
81 changes: 11 additions & 70 deletions frontend/src/pages/SearchPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@ import { useEffect, useState } from "react";
import FoundUser from "../components/FoundUser";
import { useUser } from "../helpers/UserProvider";
import User from "../models/User";
import { faMagnifyingGlass } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useNavigate } from "react-router-dom";
import editDistance from "../misc/editDistance";

import Transition from "../components/Transition";
import Paginator from "../components/Paginator";
import Search from "../components/Search";

function SearchPage() {
const navigate = useNavigate();

const [searchState, setSearchState] = useState("");
// Logic
const [usersFound, setUsersFound] = useState<[[User, number]]>();
const [usersFriends, setUsersFriends] = useState([]);

// Animation
const [showAnimation, setShowAnim] = useState(false);
const [showContent, setShowContent] = useState(false);

Expand Down Expand Up @@ -51,52 +51,20 @@ function SearchPage() {
fetchFriends();
}, [user]);

const handleSearch = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();

if (userId === null) navigate("/login");

if (searchState.trim() === "") {
return;
}

const response = await dataService.fetchData(
`/users/search?q=${searchState}`,
"GET",
);

const responseWithoutCurrUser = response.users.filter(
(respArr: [User, number]) => respArr[0].id !== user!.id,
);

const usersSorted = sortUsersByDistance(
searchState,
responseWithoutCurrUser,
);

setUsersFound(usersSorted);
};


const isFriend = (friendArr: string[], user: User): boolean => {
return friendArr.reduce((prev: boolean, curr: string) => {
return prev || curr === String(user.id);
}, false);
};

const sortUsersByDistance = (searchTerm: string, users: [[User, number]]) => {
const userScores = users.map((respArr: [User, number]) => {
const user = respArr[0];
const score = editDistance(user.first_name + user.last_name, searchTerm);
return [user, score];
});
const handler = (test: [[User, number]])=>{
setUsersFound(test)
console.log(test);

}

return userScores.sort((a: any, b: any) => {
const [_userA, scoreA] = a;
const [_userB, scoreB] = b;

return scoreA - scoreB;
}) as [[User, number]];
};

return (
<>
Expand All @@ -105,34 +73,7 @@ function SearchPage() {
{showContent ? (
<>
<section className=" min-h-screen mx-50 lg:mx-72 ">
<div className="mx-50 my-20 flex justify-center">
<form
className="flex flex-col md:flex-row gap-5 max-w-3xl w-full mt-5"
onSubmit={handleSearch}
>
<div className=" w-full">
<input
type="text"
placeholder="John Doe"
className="form-input text-my-darker"
onChange={(e) => setSearchState(e.target.value)}
></input>
<p className="text-lg">
Enter your friend's name in the field above.
</p>
</div>

<button
type="submit"
className="btn bg-my-purple text-xs px-7 py-5"
>
<div className="flex gap-3 items-center text-cente justify-center">
<span className=" text-center">Search</span>
<FontAwesomeIcon icon={faMagnifyingGlass} />
</div>
</button>
</form>
</div>
<Search handler={handler} />
{usersFound && (
<Paginator
users={usersFound.map((match: [User, number]) => match[0])}
Expand Down

0 comments on commit ee6b36d

Please sign in to comment.