diff --git a/package.json b/package.json index 194ad79..027da30 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,10 @@ "react-router-dom": "^5.0.1", "react-scripts": "^5.0.0", "react-spinners": "^0.6.1", - "typescript": "^4.5.4" + "typescript": "^4.5.4", + "@algolia/autocomplete-js": "^1.17.0", + "@algolia/autocomplete-theme-classic": "^1.17.0", + "algoliasearch": "^4.24.0" }, "scripts": { "start": "react-scripts start", @@ -52,4 +55,4 @@ "enzyme": "^3.10.0", "enzyme-adapter-react-16": "^1.14.0" } -} +} \ No newline at end of file diff --git a/src/algoliaConfig.js b/src/algoliaConfig.js new file mode 100644 index 0000000..4dacca4 --- /dev/null +++ b/src/algoliaConfig.js @@ -0,0 +1,7 @@ +// Algolia configuration for Atila Scholarships +// These are placeholder values - replace with actual Algolia credentials +export const algoliaConfig = { + appId: 'YOUR_ALGOLIA_APP_ID', + apiKey: 'YOUR_ALGOLIA_SEARCH_API_KEY', + indexName: 'atila_scholarships', +}; diff --git a/src/components/ScholarshipSearch.js b/src/components/ScholarshipSearch.js new file mode 100644 index 0000000..f49de64 --- /dev/null +++ b/src/components/ScholarshipSearch.js @@ -0,0 +1,84 @@ +import React, { useEffect, useRef } from 'react'; +import { autocomplete, getAlgoliaResults } from '@algolia/autocomplete-js'; +import '@algolia/autocomplete-theme-classic/dist/theme.css'; +import { algoliaConfig } from '../algoliaConfig'; +import algoliasearch from 'algoliasearch'; + +const searchClient = algoliasearch(algoliaConfig.appId, algoliaConfig.apiKey); + +function ScholarshipSearch({ onSearch, initialValue = '' }) { + const containerRef = useRef(null); + + useEffect(() => { + if (!containerRef.current) return; + + const search = autocomplete({ + container: containerRef.current, + placeholder: 'Search scholarships...', + initialState: { query: initialValue }, + openOnFocus: true, + getSources({ query }) { + return [ + { + sourceId: 'scholarships', + getItems() { + return getAlgoliaResults({ + searchClient, + queries: [ + { + indexName: algoliaConfig.indexName, + query, + params: { + hitsPerPage: 5, + }, + }, + ], + }); + }, + getItemInputValue({ item }) { + return item.name || item.title || ''; + }, + onSelect({ item }) { + if (onSearch) { + onSearch(item.name || item.title || ''); + } + }, + templates: { + item({ item, components }) { + return ( +