Skip to content

Commit

Permalink
💥 working search functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
mrpmohiburrahman committed Jul 9, 2024
1 parent 5fbc9d9 commit 96e2e43
Show file tree
Hide file tree
Showing 2 changed files with 164 additions and 40 deletions.
Original file line number Diff line number Diff line change
@@ -1,19 +1,77 @@
/* SearchComponent.module.css */
:root {
--bg-color: #fff;
--text-color: #333;
--border-color: #ccc;
--hover-bg-color: #f0f0f0;
--suggestion-bg-color: #fff;
--suggestion-text-color: #333;
--active-bg-color: #0070f3;
--active-text-color: #fff;
}

[data-theme='dark'] {
--bg-color: #333;
--text-color: #fff;
--border-color: #555;
--hover-bg-color: #444;
--suggestion-bg-color: #444;
--suggestion-text-color: #fff;
--active-bg-color: #1a73e8;
--active-text-color: #fff;
}

.container {
display: flex;
flex-direction: column;
align-items: center;
text-align: left;
width: 100%;
position: relative;
}

.searchInput {
width: 100%;
max-width: 800px;
padding: 1rem;
font-size: 1.5rem;
border: 1px solid #ccc;
border: 1px solid var(--border-color);
border-radius: 5px;
background-color: var(--bg-color);
color: var(--text-color);
}

.suggestionsContainer {
position: absolute;
top: 60px;
/* Adjust this value as needed */
width: 100%;
max-width: 800px;
border: 1px solid var(--border-color);
border-top: none;
background-color: var(--suggestion-bg-color);
z-index: 1000;
border-radius: 0 0 5px 5px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.suggestionItem {
padding: 1rem;
border-bottom: 1px solid var(--border-color);
cursor: pointer;
background-color: var(--suggestion-bg-color);
color: var(--suggestion-text-color);
transition: background-color 0.2s;
}

.suggestionItem:hover,
.suggestionItem.active {
background-color: var(--hover-bg-color);
}

.suggestionItem.active {
background-color: var(--active-bg-color);
color: var(--active-text-color);
}

.resultsContainer {
Expand All @@ -23,7 +81,7 @@
}

.resultItem {
border-bottom: 1px solid #ddd;
border-bottom: 1px solid var(--border-color);
padding: 1rem 0;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import React, { useState, useEffect, ChangeEvent } from 'react';
import debounce from 'lodash/debounce';
import React, { useState, useEffect, useRef, ChangeEvent, KeyboardEvent, MouseEvent } from 'react';
import combinedData from '../../../../category-selector/data/combinedFromChunks.json'; // Adjust the path to your JSON file
import categoryData from '../../../../category-selector/data/uniqueCategoryToLib.json'; // Adjust the path to your JSON file
import styles from './SearchComponent.module.css'; // Assuming styles are imported
import styles from './SearchComponent.module.css';

interface GithubData {
githubUrl: string;
Expand Down Expand Up @@ -72,62 +71,129 @@ interface GithubData {
const SearchComponent: React.FC = () => {
const [query, setQuery] = useState<string>('');
const [results, setResults] = useState<GithubData[]>([]);
const [suggestions, setSuggestions] = useState<string[]>([]);
const [showSuggestions, setShowSuggestions] = useState<boolean>(false);
const [activeSuggestionIndex, setActiveSuggestionIndex] = useState<number>(0);
const [hasSearched, setHasSearched] = useState<boolean>(false);
const inputRef = useRef<HTMLInputElement>(null);

const handleSearch = debounce((searchTerm: string) => {
if (searchTerm) {
const item = (combinedData as { [key: string]: GithubData })[searchTerm];
if (item) {
const uniqueCategory = item.uniqueCategory;
const relatedLibs = (categoryData as { [key: string]: string[] })[uniqueCategory];
if (relatedLibs) {
const fetchedResults = relatedLibs
.map(libUrl => (combinedData as { [key: string]: GithubData })[libUrl])
.filter(Boolean) as GithubData[];
setResults(fetchedResults);
} else {
setResults([]);
}
useEffect(() => {
inputRef.current?.focus();

const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === '/') {
e.preventDefault();
inputRef.current?.focus();
}
};

document.addEventListener('keydown', handleKeyDown);

return () => {
document.removeEventListener('keydown', handleKeyDown);
};
}, []);

const fetchResults = (searchTerm: string) => {
const item = (combinedData as { [key: string]: GithubData })[searchTerm];
if (item) {
const uniqueCategory = item.uniqueCategory;
const relatedLibs = (categoryData as { [key: string]: string[] })[uniqueCategory];
if (relatedLibs) {
const fetchedResults = relatedLibs
.map(libUrl => (combinedData as { [key: string]: GithubData })[libUrl])
.filter(Boolean) as GithubData[];
setResults(fetchedResults);
} else {
setResults([]);
}
} else {
setResults([]);
}
}, 300);

useEffect(() => {
handleSearch(query);
}, [query]);
setHasSearched(true);
};

const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
setQuery(e.target.value);
const value = e.target.value;
setQuery(value);
setActiveSuggestionIndex(0);

if (value) {
setShowSuggestions(true);
const filteredSuggestions = Object.keys(combinedData).filter(key =>
key.toLowerCase().includes(value.toLowerCase()),
);
setSuggestions(filteredSuggestions);
} else {
setShowSuggestions(false);
setResults([]);
setHasSearched(false);
}
};

const handleKeyDownInput = (e: KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'ArrowDown') {
setActiveSuggestionIndex(prevIndex => (prevIndex + 1) % suggestions.length);
} else if (e.key === 'ArrowUp') {
setActiveSuggestionIndex(prevIndex => (prevIndex - 1 + suggestions.length) % suggestions.length);
} else if (e.key === 'Enter') {
if (suggestions.length > 0) {
const selectedSuggestion = suggestions[activeSuggestionIndex];
setQuery(selectedSuggestion);
setShowSuggestions(false);
fetchResults(selectedSuggestion);
}
}
};

const handleSuggestionClick = (e: MouseEvent<HTMLDivElement>) => {
const selectedSuggestion = e.currentTarget.innerText;
setQuery(selectedSuggestion);
setShowSuggestions(false);
fetchResults(selectedSuggestion);
};

return (
<div className={styles.container}>
<input
ref={inputRef}
type="text"
value={query}
onChange={handleChange}
onKeyDown={handleKeyDownInput}
placeholder="Enter GitHub URL"
className={styles.searchInput}
/>
<div className={styles.resultsContainer}>
{results.length > 0 ? (
results.map(result => (
<div key={result.githubUrl} className={styles.resultItem}>
<h2>
<a href={result.github?.urls?.repo} target="_blank" rel="noopener noreferrer">
{result.github?.name}
</a>
</h2>
<p>{result.github?.description}</p>
{/* Display other relevant data from the JSON object as needed */}
{showSuggestions && suggestions.length > 0 && (
<div className={styles.suggestionsContainer}>
{suggestions.map((suggestion, index) => (
<div
key={suggestion}
className={`${styles.suggestionItem} ${index === activeSuggestionIndex ? styles.active : ''}`}
onClick={handleSuggestionClick}>
{suggestion}
</div>
))
) : (
<div className={styles.noResultsSpace}>{query && <p>No results found</p>}</div>
)}
))}
</div>
)}
<div className={styles.resultsContainer}>
{hasSearched && results.length > 0
? results.map(result => (
<div key={result.githubUrl} className={styles.resultItem}>
<h2>
<a href={result.github?.urls?.repo} target="_blank" rel="noopener noreferrer">
{result.github?.name}
</a>
</h2>
<p>{result.github?.description}</p>
{/* Display other relevant data from the JSON object as needed */}
</div>
))
: hasSearched && (
<div className={styles.noResultsSpace}>
<p>No results found</p>
</div>
)}
</div>
</div>
);
Expand Down

0 comments on commit 96e2e43

Please sign in to comment.