diff --git a/client/src/components/FiltersSideMenu/filters.js b/client/src/components/FiltersSideMenu/filters.js
index 0361df0..f54d0d8 100644
--- a/client/src/components/FiltersSideMenu/filters.js
+++ b/client/src/components/FiltersSideMenu/filters.js
@@ -3,9 +3,7 @@ import PT from "prop-types";
import Button from "../Button";
import WideButton from "../wideButton";
import Collapsible from "../collapsible";
-import SearchBox from "../searchBox";
import Availability from "../availability";
-import TagList from "../tagList";
import EditFiltersPopup from "../editFiltersPopup";
import SuggestionBox from "../SuggestionBox";
import Pill from "../Pill";
@@ -20,9 +18,8 @@ import utilityStyles from "../../styles/utility.module.css";
* SearchTabFilters - component containing all the filters on the search tab page
* achievements: the values for the achievements filter options
*/
-export default function SearchTabFilters({ achievements }) {
+export default function SearchTabFilters() {
const search = useSearch();
- const [achievementsData, setAchievementsData] = useState(achievements);
/**
* Component unmount trigger
@@ -46,21 +43,6 @@ export default function SearchTabFilters({ achievements }) {
search.changePageNumber(1);
};
- useEffect(() => {
- setAchievementsData(achievements);
- }, [achievements]);
-
- const filterData = (query, initialValues, property, setState) => {
- const q = query.toLowerCase();
- if (q.length >= 3) {
- setState(
- initialValues.filter((g) => g[property].toLowerCase().includes(q))
- );
- } else if (query.length === 0) {
- setState(initialValues);
- }
- };
-
const [numberOfFiltersApplied, setNumberOfFiltersApplied] = useState();
const modal = useModal();
@@ -180,6 +162,32 @@ export default function SearchTabFilters({ achievements }) {
search["selectSkills"](skillFilters);
};
+ const addAchievementToFilter = (achievement) => {
+ const achievementFilters = JSON.parse(
+ JSON.stringify(search.selectedAchievements)
+ );
+
+ if (achievementFilters.findIndex((s) => s.id === achievement.id) !== -1) {
+ return;
+ }
+ achievementFilters.push(achievement);
+ search["selectAchievements"](achievementFilters);
+ };
+
+ const removeAchievementFromFilter = (achievement) => {
+ const achievementFilters = JSON.parse(
+ JSON.stringify(search.selectedAchievements)
+ );
+ const index = achievementFilters.findIndex((s) => s.id === achievement.id);
+
+ if (index === -1) {
+ return;
+ }
+
+ achievementFilters.splice(index, 1);
+ search["selectAchievements"](achievementFilters);
+ };
+
const addCompanyAttributeToFilter = (attrId, data) => {
const companyAttrFilters = JSON.parse(
JSON.stringify(search.selectedCompanyAttributes)
@@ -319,25 +327,26 @@ export default function SearchTabFilters({ achievements }) {
)}
{search.isFilterActive(FILTERS.ACHIEVEMENTS) && (
-
- filterData("", achievements, "name", setAchievementsData)
- }
- >
-
+
- filterData(q.trim(), achievements, "name", setAchievementsData)
- }
- />
-
+ {search.selectedAchievements.length > 0 && (
+
+ {search.selectedAchievements.map((achievement) => {
+ return (
+
removeAchievementFromFilter(achievement)}
+ />
+ );
+ })}
+
+ )}
)}
diff --git a/client/src/components/FiltersSideMenu/index.jsx b/client/src/components/FiltersSideMenu/index.jsx
index 1932495..5307e47 100644
--- a/client/src/components/FiltersSideMenu/index.jsx
+++ b/client/src/components/FiltersSideMenu/index.jsx
@@ -1,5 +1,4 @@
import React from "react";
-import PT from "prop-types";
import style from "./style.module.scss";
import SearchTabFilters from "./filters";
@@ -7,11 +6,7 @@ import SearchTabFilters from "./filters";
export default function FiltersSideMenu({ achievements }) {
return (
-
+
);
}
-
-FiltersSideMenu.propTypes = {
- achievements: PT.array.isRequired,
-};
diff --git a/client/src/components/SuggestionBox/index.jsx b/client/src/components/SuggestionBox/index.jsx
index 1f12746..b1a79d3 100644
--- a/client/src/components/SuggestionBox/index.jsx
+++ b/client/src/components/SuggestionBox/index.jsx
@@ -5,6 +5,7 @@ import api from "../../services/api";
import style from "./style.module.scss";
import _ from "lodash";
import { useSearch, FILTERS } from "../../lib/search";
+import { getAchievements } from "../../lib/achievements";
const NO_RESULTS_FOUND = "no results found";
const DELAY_SEARCH = 300;
@@ -66,6 +67,22 @@ const getSkillsSuggestions = async (apiClient, inputValue) => {
return data.skills;
};
+/**
+ * Returns the suggestions for achievements
+ * @param {Object} apiClient The api client to make the query
+ * @param {String} inputValue The search query
+ */
+const getAchievementSuggestions = async (apiClient, inputValue) => {
+ let term = inputValue.trim();
+ if (term.length < 1) {
+ return [];
+ }
+
+ term = encodeURIComponent(term);
+ const suggestions = await getAchievements(apiClient, term);
+ return suggestions;
+};
+
/**
* Returns the suggestions for company attributes
* @param {Object} apiClient The api client to make the query
@@ -112,6 +129,11 @@ export default function SuggestionBox({
if (purpose === "skills") {
let data = await getSkillsSuggestions(apiClient, value);
+ if (data.length < 1) data = [{ name: NO_RESULTS_FOUND }];
+ setSuggestions(data);
+ } else if (purpose === "achievements") {
+ let data = await getAchievementSuggestions(apiClient, value);
+
if (data.length < 1) data = [{ name: NO_RESULTS_FOUND }];
setSuggestions(data);
} else {
@@ -137,6 +159,8 @@ export default function SuggestionBox({
if (suggestion.name !== NO_RESULTS_FOUND) onSelect(suggestion);
} else if (purpose === "locations") {
if (suggestion.name !== NO_RESULTS_FOUND) onSelect(suggestion);
+ } else if (purpose === "achievements") {
+ if (suggestion.name !== NO_RESULTS_FOUND) onSelect(suggestion);
} else {
if (suggestion.name !== NO_RESULTS_FOUND)
onSelect(companyAttrId, suggestion);
diff --git a/client/src/lib/achievements.js b/client/src/lib/achievements.js
new file mode 100644
index 0000000..5c3b0ca
--- /dev/null
+++ b/client/src/lib/achievements.js
@@ -0,0 +1,26 @@
+import config from "../config";
+import * as OrgService from "../services/user-org";
+
+/**
+ * Returns achivement suggestions based on query
+ * @param {Object} apiClient The api client (you can get this from src/services/api and then call api() to get the apiClient)
+ * @param {String} query query to search for
+ */
+export async function getAchievements(apiClient, query) {
+ let response;
+ const organizationId = OrgService.getSingleOrg();
+ let url = `${config.API_URL}/search/userAchievements?organizationId=${organizationId}&keyword=${query}`;
+
+ try {
+ response = await apiClient.get(url);
+ } catch (error) {
+ console.log(error);
+ return [];
+ }
+
+ if (!response.data || response.data.length < 1) {
+ return [];
+ }
+
+ return response.data;
+}
diff --git a/client/src/pages/Search/Global.jsx b/client/src/pages/Search/Global.jsx
index 899eac6..e7b154c 100644
--- a/client/src/pages/Search/Global.jsx
+++ b/client/src/pages/Search/Global.jsx
@@ -14,7 +14,6 @@ import { useSearch, FILTERS } from "../../lib/search";
import { makeColorIterator, avatarColors } from "../../lib/colors";
import config from "../../config";
import api from "../../services/api";
-import staticData from "../../services/static-data";
import style from "./style.module.scss";
import _ from "lodash";
@@ -50,7 +49,6 @@ export default function SearchGlobal({ keyword }) {
const apiClient = api();
const searchContext = useSearch();
const [isSearching, setIsSearching] = React.useState(false);
- const [achievements, setAchievements] = React.useState([]);
const [users, setUsers] = React.useState([]);
const [page, setPage] = React.useState(1);
const [totalResults, setTotalResults] = React.useState(0);
@@ -75,26 +73,6 @@ export default function SearchGlobal({ keyword }) {
};
});
- // Static data only
- React.useEffect(() => {
- if (isLoading || !isAuthenticated) {
- return;
- }
-
- let isSubscribed = true;
-
- (async () => {
- const achievements = await staticData.getAchievements();
-
- if (isSubscribed) {
- setAchievements(achievements);
- }
- })();
-
- return () => (isSubscribed = false);
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [isLoading, isAuthenticated]);
-
// Non-static data and Non-user related data
React.useEffect(() => {
if (isLoading || !isAuthenticated) {
@@ -165,7 +143,9 @@ export default function SearchGlobal({ keyword }) {
searchContext.filters[FILTERS.ACHIEVEMENTS].active &&
searchContext.selectedAchievements.length > 0
) {
- criteria.achievements = searchContext.selectedAchievements;
+ criteria.achievements = searchContext.selectedAchievements.map(
+ (a) => a.name
+ );
}
if (searchContext.filters[FILTERS.AVAILABILITY].active) {
if (
@@ -312,7 +292,7 @@ export default function SearchGlobal({ keyword }) {
return (
<>
-
+
{!isSearching && users.length > 0 && (
diff --git a/client/src/services/static-data.js b/client/src/services/static-data.js
deleted file mode 100644
index 68273c1..0000000
--- a/client/src/services/static-data.js
+++ /dev/null
@@ -1,13 +0,0 @@
-async function getAchievements() {
- const mockAchievementsTags = [
- { name: "Informatika" },
- { name: "Upwork" },
- { name: "TopCoder" },
- ];
-
- return mockAchievementsTags;
-}
-
-export default {
- getAchievements,
-};