{"version":3,"sources":["components/Header.tsx","components/Search.tsx","components/Album.tsx","components/Other.tsx","components/Results.tsx","components/App.tsx","index.tsx","assets/placeholder-music.jpg"],"names":["Header","Box","as","direction","align","justify","background","pad","left","right","vertical","style","zIndex","Text","margin","color","size","weight","Anchor","href","label","Search","inputValue","handleChange","suggestions","handleSelect","top","width","TextInput","type","name","value","onChange","e","target","onSelect","suggestion","icon","FormSearch","dropHeight","placeholder","autoFocus","aria-label","Album","image","height","repeat","Heading","level","bottom","Other","handleClick","round","onClick","textAlign","wordBreak","Results","artists","selectedName","albums","otherArtists","slice","length","selectedAlbums","selectedImage","uniqueAlbums","Set","forEach","album","has","add","push","horizontal","min","max","wrap","map","artist","key","id","QUERY_ARTISTS","gql","App","useState","setInputValue","useLazyQuery","getArtists","data","error","setArtists","setSuggestions","selected","setSelected","delayedQuery","useCallback","debounce","variables","byName","useEffect","cancel","queryArtists","updatedSuggestions","el","errorNoSearchQuery","graphQLErrors","message","Grommet","theme","updatedArtists","suggestedArtists","i","selectedArtist","splice","global","colors","brand","font","family","client","ApolloClient","uri","cache","InMemoryCache","ReactDOM","render","StrictMode","ApolloProvider","document","getElementById","module","exports"],"mappings":"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","file":"static/js/main.29d93776.chunk.js","sourcesContent":["import React from 'react';\nimport { Box, Text, Anchor } from 'grommet';\n\nexport const Header = () => {\n\treturn (\n\t\t\n\t\t\t\n\t\t\t\tSpoti Search\n\t\t\t\n\t\t\t\n\t\t\n\t);\n};\n","import React from 'react';\nimport { Box, TextInput } from 'grommet';\nimport { FormSearch } from 'grommet-icons';\n\nexport const Search = ({\n\tinputValue,\n\thandleChange,\n\tsuggestions,\n\thandleSelect,\n}: {\n\tinputValue: string;\n\thandleChange: (value: string) => void;\n\tsuggestions: string[];\n\thandleSelect: (suggestion: string) => void;\n}) => (\n\t\n\t\t\n\t\t\t handleChange(e.target.value)}\n\t\t\t\tonSelect={(target) => handleSelect(target.suggestion)}\n\t\t\t\ticon={}\n\t\t\t\tdropHeight='large'\n\t\t\t\tplaceholder='Type an artist name'\n\t\t\t\tautoFocus\n\t\t\t\taria-label='Search by artist name'\n\t\t\t/>\n\t\t\n\t\n);","import React from 'react';\nimport { Box, Heading } from 'grommet';\n\nimport placeholder from '../assets/placeholder-music.jpg';\n\nexport const Album = ({ image, name }: { image: string; name: string }) => {\n\t// Load placeholder image if none provided\n\tif (!image) {\n\t\timage = placeholder;\n\t}\n\n\treturn (\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\t{name}\n\t\t\t\n\t\t\n\t);\n};\n","import React from 'react';\nimport { Box, Text } from 'grommet';\n\nimport placeholder from '../assets/placeholder-music.jpg';\n\nexport const Other = ({\n\timage,\n\tname,\n\thandleClick,\n}: {\n\timage: string;\n\tname: string;\n\thandleClick: (name: string) => void;\n}) => {\n\t// Load placeholder image if none provided\n\tif (!image) {\n\t\timage = placeholder;\n\t}\n\n\treturn (\n\t\t handleClick(name)}\n\t\t\twidth='130px'\n\t\t>\n\t\t\t\n\t\t\t\n\t\t\t\t{name}\n\t\t\t\n\t\t\n\t);\n};\n","import React from 'react';\nimport { Box, Heading } from 'grommet';\n\nimport { Album } from './Album';\nimport { Artists, Albums } from '../interfaces';\nimport { Other } from './Other';\nimport placeholder from '../assets/placeholder-music.jpg';\n\nexport const Results = ({\n\tartists,\n\thandleClick,\n}: {\n\tartists: Artists;\n\thandleClick: (name: string) => void;\n}) => {\n\tconst { name: selectedName, image, albums } = artists[0];\n\tconst otherArtists = artists.slice(1, artists.length);\n\tlet selectedAlbums: Albums = [];\n\tlet selectedImage: string = image;\n\n\t// Load placeholder image if none provided\n\tif (!image) {\n\t\tselectedImage = placeholder;\n\t}\n\n\t// Remove duplicate albums based on `name`\n\t// Might need to refine this according to the data quality\n\tconst uniqueAlbums = new Set();\n\talbums.forEach((album) => {\n\t\tif (!uniqueAlbums.has(album.name)) {\n\t\t\tuniqueAlbums.add(album.name);\n\t\t\tselectedAlbums.push(album);\n\t\t}\n\t});\n\n\treturn (\n\t\t<>\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t{selectedName}\n\t\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\tOther results\n\t\t\t\t\t\t\n\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t{otherArtists.map((artist) => (\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\tDiscography\n\t\t\t\t\t\n\n\t\t\t\t\t\n\t\t\t\t\t\t{selectedAlbums.map((album) => (\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t))}\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\n\t);\n};\n","import React, { useState, useCallback, useEffect } from 'react';\nimport { Grommet } from 'grommet';\nimport { debounce } from 'lodash';\nimport { gql, useLazyQuery } from '@apollo/client';\n\nimport { Header } from './Header';\nimport { Search } from './Search';\nimport { Results } from './Results';\nimport { Artists, Artist } from '../interfaces';\n\nexport const QUERY_ARTISTS = gql`\n\tquery Artist($byName: String!) {\n\t\tqueryArtists(byName: $byName) {\n\t\t\tname\n\t\t\timage\n\t\t\tid\n\t\t\talbums {\n\t\t\t\tname\n\t\t\t\timage\n\t\t\t\tid\n\t\t\t}\n\t\t}\n\t}\n`;\n\nexport default function App() {\n\tconst [inputValue, setInputValue] = useState('');\n\tconst [getArtists, { data, error }] = useLazyQuery(\n\t\tQUERY_ARTISTS,\n\t);\n\tconst [artists, setArtists] = useState([]);\n\tconst [suggestions, setSuggestions] = useState([]);\n\tconst [selected, setSelected] = useState(false);\n\n\t// Debounce the database query\n\t// Based on: https://archive.is/wip/6JDqb\n\tconst handleChange = (value: string) => {\n\t\tsetInputValue(value);\n\t};\n\n\tconst updateQuery = () => {\n\t\tgetArtists({ variables: { byName: inputValue } });\n\t};\n\n\tconst delayedQuery = useCallback(debounce(updateQuery, 200), [inputValue]);\n\n\tuseEffect(() => {\n\t\tdelayedQuery();\n\t\t// Cancel previous debounce calls during useEffect cleanup.\n\t\treturn delayedQuery.cancel;\n\t}, [inputValue, delayedQuery]);\n\n\tconst handleSelect = (suggestion: string) => {\n\t\tlet updatedArtists: Artists = [];\n\n\t\tlet suggestedArtists: Artists = data.queryArtists\n\t\t\t.slice(0, 5)\n\t\t\t// Map to make a copy of the array, maybe uneeded\n\t\t\t.map((artist: Artist) => artist);\n\n\t\t// Find the selected artist and move it to index 0\n\t\tfor (let i = 0; i < suggestedArtists!.length; i++) {\n\t\t\tif (suggestedArtists![i].name === suggestion) {\n\t\t\t\tlet selectedArtist: Artists = suggestedArtists?.splice(i, 1);\n\t\t\t\tlet otherArtists: Artists = suggestedArtists;\n\t\t\t\tupdatedArtists = [...selectedArtist, ...otherArtists];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tsetArtists(updatedArtists);\n\t\tsetSelected(true);\n\t};\n\n\tconst handleClick = (name: string) => {\n\t\tlet updatedArtists: Artists = [];\n\n\t\tfor (let i = 0; i < artists.length; i++) {\n\t\t\tif (artists[i].name === name) {\n\t\t\t\tlet selectedArtist: Artists = artists.splice(i, 1);\n\t\t\t\tlet otherArtists: Artists = artists;\n\t\t\t\tupdatedArtists = [...selectedArtist, ...otherArtists];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tsetArtists(updatedArtists);\n\t};\n\n\tuseEffect(() => {\n\t\tif (data && data.queryArtists && data.queryArtists !== []) {\n\t\t\t// Limit artists to 5\n\t\t\tconst updatedArtists = data.queryArtists.slice(0, 5);\n\t\t\tconst updatedSuggestions: string[] = updatedArtists.map(\n\t\t\t\t(el: Artist) => {\n\t\t\t\t\treturn el.name;\n\t\t\t\t},\n\t\t\t);\n\t\t\tsetSuggestions(updatedSuggestions);\n\t\t}\n\t}, [data]);\n\n\t// Create flag to filter \"No search query\" errors\n\tlet errorNoSearchQuery = false;\n\tif (error && error.graphQLErrors) {\n\t\terror.graphQLErrors.forEach((error) => {\n\t\t\tif (error.message === 'Error: 400: No search query') {\n\t\t\t\terrorNoSearchQuery = true;\n\t\t\t} else {\n\t\t\t\terrorNoSearchQuery = false;\n\t\t\t}\n\t\t});\n\t}\n\n\treturn (\n\t\t\n\t\t\t
\n\t\t\t\n\t\t\t{selected && (\n\t\t\t\t\n\t\t\t)}\n\t\t\t{error && !errorNoSearchQuery && (\n\t\t\t\t
\n\t\t\t\t\t{error.graphQLErrors.map(({ message }, i) => (\n\t\t\t\t\t\t{message}\n\t\t\t\t\t))}\n\t\t\t\t
\n\t\t\t)}\n\t\t\n\t);\n}\n\nconst theme = {\n\tglobal: {\n\t\tcolors: {\n\t\t\tbrand: 'rgb(24, 177, 147)',\n\t\t},\n\t\tfont: {\n\t\t\tfamily: 'Roboto',\n\t\t\tsize: '18px',\n\t\t\theight: '20px',\n\t\t},\n\t},\n};\n","import React from 'react';\nimport ReactDOM from 'react-dom';\nimport { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client';\n\nimport App from './components/App';\n\nconst client = new ApolloClient({\n\turi: 'https://spotify-graphql-server.herokuapp.com/graphql',\n\tcache: new InMemoryCache(),\n});\n\nReactDOM.render(\n\t\n\t\t\n\t\t\t\n\t\t\n\t,\n\tdocument.getElementById('root'),\n);\n","module.exports = __webpack_public_path__ + \"static/media/placeholder-music.97fa2780.jpg\";"],"sourceRoot":""}