{"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","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","round","elevation","overflow","height","Image","src","fit","Heading","level","bottom","Other","handleClick","onClick","repeat","textAlign","wordBreak","Results","artists","selectedName","albums","otherArtists","slice","length","selectedAlbums","selectedImage","uniqueAlbums","Set","forEach","album","has","add","push","Grid","rows","columns","gap","areas","gridArea","responsive","min","max","wrap","map","artist","key","id","ResponsiveContext","Consumer","count","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.d9d52cb5.chunk.js","sourcesContent":["import React from 'react';\nimport { Box, Text } 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\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, Image } 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\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, Grid, ResponsiveContext, 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{selectedName}\n\t\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\tOther results\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t{otherArtists.map((artist) => (\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\t\n\t\t\t\tDiscography\n\t\t\t\n\t\t\t\n\t\t\t\t{(size) => (\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":""}