Add possibility to load other results on click
This commit is contained in:
parent
2b415b5189
commit
a27a6281a0
@ -27,20 +27,20 @@ export default function App() {
|
|||||||
const [inputValue, setInputValue] = useState('');
|
const [inputValue, setInputValue] = useState('');
|
||||||
const [getArtists, { data }] = useLazyQuery(QUERY_ARTISTS);
|
const [getArtists, { data }] = useLazyQuery(QUERY_ARTISTS);
|
||||||
const [artists, setArtists] = useState<Artists>([]);
|
const [artists, setArtists] = useState<Artists>([]);
|
||||||
const [suggestions, setSuggestions] = useState<string[] | undefined>();
|
const [suggestions, setSuggestions] = useState<string[]>([]);
|
||||||
const [selected, setSelected] = useState(false);
|
const [selected, setSelected] = useState(false);
|
||||||
|
|
||||||
// Debounce the database query
|
// Debounce the database query
|
||||||
// Based on: https://archive.is/wip/6JDqb
|
// Based on: https://archive.is/wip/6JDqb
|
||||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleChange = (value: string) => {
|
||||||
setInputValue(e.target.value);
|
setInputValue(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateQuery = () => {
|
const updateQuery = () => {
|
||||||
getArtists({ variables: { byName: inputValue } });
|
getArtists({ variables: { byName: inputValue } });
|
||||||
};
|
};
|
||||||
|
|
||||||
const delayedQuery = useCallback(debounce(updateQuery, 500), [inputValue]);
|
const delayedQuery = useCallback(debounce(updateQuery, 200), [inputValue]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
delayedQuery();
|
delayedQuery();
|
||||||
@ -48,18 +48,14 @@ export default function App() {
|
|||||||
return delayedQuery.cancel;
|
return delayedQuery.cancel;
|
||||||
}, [inputValue, delayedQuery]);
|
}, [inputValue, delayedQuery]);
|
||||||
|
|
||||||
const handleSelect = (suggestion: any) => {
|
const handleSelect = (suggestion: string) => {
|
||||||
const selectedName: string = suggestion.suggestion;
|
|
||||||
let updatedArtists: Artists = [];
|
let updatedArtists: Artists = [];
|
||||||
|
|
||||||
// Use map to create a copy of the array
|
let suggestedArtists: Artists = data.queryArtists.slice(0, 5);
|
||||||
let suggestedArtists: Artists = data.queryArtists
|
|
||||||
.slice(0, 5)
|
|
||||||
.map((item: Artist) => item);
|
|
||||||
|
|
||||||
// Find the selected artist and move it to index 0
|
// Find the selected artist and move it to index 0
|
||||||
for (let i = 0; i < suggestedArtists!.length; i++) {
|
for (let i = 0; i < suggestedArtists!.length; i++) {
|
||||||
if (suggestedArtists![i].name === selectedName) {
|
if (suggestedArtists![i].name === suggestion) {
|
||||||
let selectedArtist: Artists = suggestedArtists?.splice(i, 1);
|
let selectedArtist: Artists = suggestedArtists?.splice(i, 1);
|
||||||
let otherArtists: Artists = suggestedArtists;
|
let otherArtists: Artists = suggestedArtists;
|
||||||
updatedArtists = [...selectedArtist, ...otherArtists];
|
updatedArtists = [...selectedArtist, ...otherArtists];
|
||||||
@ -71,13 +67,22 @@ export default function App() {
|
|||||||
setSelected(true);
|
setSelected(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClick = () => {
|
const handleClick = (name: string) => {
|
||||||
console.log('click')
|
let updatedArtists: Artists = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < artists.length; i++) {
|
||||||
|
if (artists[i].name === name) {
|
||||||
|
let selectedArtist: Artists = artists.splice(i, 1);
|
||||||
|
let otherArtists: Artists = artists;
|
||||||
|
updatedArtists = [...selectedArtist, ...otherArtists];
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setArtists(updatedArtists);
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// TODO optimize re-rendering, probably by using onCompleted instead of this useEffect
|
|
||||||
// See https://github.com/apollographql/apollo-client/issues/5268#issuecomment-596950174
|
|
||||||
if (data && data.queryArtists !== []) {
|
if (data && data.queryArtists !== []) {
|
||||||
// Limit artists to 5
|
// Limit artists to 5
|
||||||
const updatedArtists = data.queryArtists.slice(0, 5);
|
const updatedArtists = data.queryArtists.slice(0, 5);
|
||||||
@ -101,7 +106,9 @@ export default function App() {
|
|||||||
suggestions={suggestions}
|
suggestions={suggestions}
|
||||||
handleSelect={handleSelect}
|
handleSelect={handleSelect}
|
||||||
/>
|
/>
|
||||||
{selected && <Results artists={artists} handleClick={handleClick}/>}
|
{selected && (
|
||||||
|
<Results artists={artists} handleClick={handleClick} />
|
||||||
|
)}
|
||||||
</Grommet>
|
</Grommet>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ export const Other = ({
|
|||||||
}: {
|
}: {
|
||||||
image: string;
|
image: string;
|
||||||
name: string;
|
name: string;
|
||||||
handleClick: ((...args: any[]) => any) & ((event: MouseEvent) => void);
|
handleClick: (name: string) => void;
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
@ -16,7 +16,7 @@ export const Other = ({
|
|||||||
overflow='hidden'
|
overflow='hidden'
|
||||||
align='center'
|
align='center'
|
||||||
pad='small'
|
pad='small'
|
||||||
onClick={handleClick}
|
onClick={() => handleClick(name)}
|
||||||
>
|
>
|
||||||
<Heading
|
<Heading
|
||||||
level='4'
|
level='4'
|
||||||
|
@ -10,7 +10,7 @@ export const Results = ({
|
|||||||
handleClick,
|
handleClick,
|
||||||
}: {
|
}: {
|
||||||
artists: Artists;
|
artists: Artists;
|
||||||
handleClick: ((...args: any[]) => any) & ((event: MouseEvent) => void);
|
handleClick: (name: string) => void;
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
const {
|
||||||
name: selectedName,
|
name: selectedName,
|
||||||
|
@ -9,9 +9,9 @@ export const Search = ({
|
|||||||
handleSelect,
|
handleSelect,
|
||||||
}: {
|
}: {
|
||||||
inputValue: string;
|
inputValue: string;
|
||||||
handleChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
handleChange: (value: string) => void;
|
||||||
suggestions: string[] | undefined;
|
suggestions: string[];
|
||||||
handleSelect: (x: { target: HTMLElement | null; suggestion: any }) => void;
|
handleSelect: (suggestion: string) => void;
|
||||||
}) => (
|
}) => (
|
||||||
<Box
|
<Box
|
||||||
as='section'
|
as='section'
|
||||||
@ -21,8 +21,8 @@ export const Search = ({
|
|||||||
>
|
>
|
||||||
<TextInput
|
<TextInput
|
||||||
value={inputValue}
|
value={inputValue}
|
||||||
onChange={handleChange}
|
onChange={e => handleChange(e.target.value)}
|
||||||
onSelect={handleSelect}
|
onSelect={(target) => handleSelect(target.suggestion)}
|
||||||
placeholder='Type an artist name'
|
placeholder='Type an artist name'
|
||||||
icon={<FormSearch color='plain' />}
|
icon={<FormSearch color='plain' />}
|
||||||
dropHeight='large'
|
dropHeight='large'
|
||||||
|
Loading…
Reference in New Issue
Block a user