Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ that will suggest people matching an entered text.
- Install Prettier Extention and use this [VSCode settings](https://mate-academy.github.io/fe-program/tools/vscode/settings.json) to enable format on save.
- Implement a solution following the [React task guideline](https://github.com/mate-academy/react_task-guideline#react-tasks-guideline).
- Use the [React TypeScript cheat sheet](https://mate-academy.github.io/fe-program/js/extra/react-typescript).
- Replace `<your_account>` with your Github username in the [DEMO LINK](https://<your_account>.github.io/react_autocomplete/) and add it to the PR description.
- Replace `<your_account>` with your Github username in the [DEMO LINK](https://Banderos14.github.io/react_autocomplete/) and add it to the PR description.
- Don't remove the `data-qa` attributes. It is required for tests.

## Troubleshooting
Expand Down
109 changes: 64 additions & 45 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,73 +1,92 @@
import React from 'react';
import React, { useEffect, useMemo, useState } from 'react';
import './App.scss';
import { peopleFromServer } from './data/people';
import { Person } from './types/Person';

export const App: React.FC = () => {
const { name, born, died } = peopleFromServer[0];
const [query, setQuery] = useState('');
const [appliedQuery, setAppliedQuery] = useState('');
const [selectedPerson, setSelectedPerson] = useState<Person | null>(null);
const [isFocused, setIsFocused] = useState(false);

useEffect(() => {
const timerId = window.setTimeout(() => {
setAppliedQuery(query.trim());
}, 300);
Comment thread
Banderos14 marked this conversation as resolved.
Outdated

return () => window.clearTimeout(timerId);
}, [query]);

const visiblePeople = useMemo(() => {
if (!appliedQuery) {
return peopleFromServer;
}

return peopleFromServer.filter(person =>
person.name.toLowerCase().includes(appliedQuery.toLowerCase()),
);
}, [appliedQuery]);

const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const value = event.target.value;

setQuery(value);

if (selectedPerson && value !== selectedPerson.name) {
setSelectedPerson(null);
}
};

const handleSelect = (person: Person) => {
setSelectedPerson(person);
setQuery(person.name);
setAppliedQuery(person.name);
setIsFocused(false);
Comment thread
Banderos14 marked this conversation as resolved.
Outdated
};

return (
<div className="container">
<main className="section is-flex is-flex-direction-column">
<h1 className="title" data-cy="title">
{`${name} (${born} - ${died})`}
{selectedPerson
? `${selectedPerson.name} (${selectedPerson.born} - ${selectedPerson.died})`
: 'No selected person'}
</h1>

<div className="dropdown is-active">
<div className={`dropdown ${isFocused ? 'is-active' : ''}`}>
<div className="dropdown-trigger">
<input
type="text"
placeholder="Enter a part of the name"
className="input"
data-cy="search-input"
value={query}
onChange={handleChange}
onFocus={() => setIsFocused(true)}
/>
</div>

<div className="dropdown-menu" role="menu" data-cy="suggestions-list">
<div className="dropdown-content">
<div className="dropdown-item" data-cy="suggestion-item">
<p className="has-text-link">Pieter Haverbeke</p>
</div>

<div className="dropdown-item" data-cy="suggestion-item">
<p className="has-text-link">Pieter Bernard Haverbeke</p>
</div>

<div className="dropdown-item" data-cy="suggestion-item">
<p className="has-text-link">Pieter Antone Haverbeke</p>
</div>

<div className="dropdown-item" data-cy="suggestion-item">
<p className="has-text-danger">Elisabeth Haverbeke</p>
</div>

<div className="dropdown-item" data-cy="suggestion-item">
<p className="has-text-link">Pieter de Decker</p>
</div>

<div className="dropdown-item" data-cy="suggestion-item">
<p className="has-text-danger">Petronella de Decker</p>
</div>

<div className="dropdown-item" data-cy="suggestion-item">
<p className="has-text-danger">Elisabeth Hercke</p>
</div>
{visiblePeople.length > 0 ? (
visiblePeople.map(person => (
<div
key={person.slug}
className="dropdown-item"
data-cy="suggestion-item"
onMouseDown={() => handleSelect(person)}
>
<p className="has-text-link">{person.name}</p>
</div>
))
) : (
<div className="dropdown-item" data-cy="no-suggestions-message">
No matching suggestions
</div>
)}
</div>
</div>
</div>

<div
className="
notification
is-danger
is-light
mt-3
is-align-self-flex-start
"
role="alert"
data-cy="no-suggestions-message"
>
<p className="has-text-danger">No matching suggestions</p>
</div>
</main>
</div>
);
Expand Down
Loading