diff --git a/src/App.js b/src/App.js index f2b430fc327d647cb59324b594f526019d9e35df..3d8e552ddbfcabbcad1ed86c26a94b0d9d07b414 100644 --- a/src/App.js +++ b/src/App.js @@ -1,65 +1,59 @@ -import React from 'react'; +import React, { useState } from 'react'; import SearchPage from './SearchPage'; import Favorites from './Favorites'; import { Box, Tabs, Tab, Typography, AppBar, CssBaseline } from '@mui/material'; +const TABS = [ + { label: 'Search Music', component: SearchPage }, + { label: 'Favorites', component: Favorites }, + { label: 'More Contents', component: () => <Typography align="center" variant="h2"> Item Three</Typography> }, +]; + export default function App() { - const [currentTab, setCurrentTab] = React.useState(0); - const [searchResult, setSearchResult] = React.useState([]); - const [likes, setLikes] = React.useState({}); - const [favoriteList, setFavoriteList] = React.useState([]); + const [currentTab, setCurrentTab] = useState(0); + const [searchResult, setSearchResult] = useState([]); + const [likes, setLikes] = useState({}); + const [favoriteList, setFavoriteList] = useState([]); - const handleTabChange = (event, newValue) => { - setCurrentTab(newValue); - }; + const handleTabChange = (event, newValue) => { + setCurrentTab(newValue); + }; - const addToFavoriteList = (item) => { - setFavoriteList((prevList) => [...prevList, item]); - }; + const addToFavoriteList = (item) => { + setFavoriteList((prevList) => [...prevList, item]); + }; - const handleLikes = (id) => { - const updatedLikes = { ...likes, [id]: !likes[id] }; - setLikes(updatedLikes); - }; + const handleLikes = (id) => { + setLikes((prevLikes) => ({ ...prevLikes, [id]: !prevLikes[id] })); + }; - const removeFromFavoriteList = (id) => { - setFavoriteList((prevList) => prevList.filter((item) => item.collectionId !== id)); - }; + const removeFromFavoriteList = (id) => { + setFavoriteList((prevList) => prevList.filter((item) => item.collectionId !== id)); + }; - return ( - <React.Fragment> - <AppBar position="fixed"> - <Typography align="center" variant="h3" color="inherit">Tae Wook's Favorite Music</Typography> - </AppBar> + const TabComponent = TABS[currentTab].component; - <div style={{ height: 60, width: '100%' }}></div> - <Box sx={{ borderBottom: 1, borderColor: 'divider' }}> - <Tabs value={currentTab} onChange={handleTabChange} aria-label="basic tabs" centered> - <Tab label="Search Music" value={0} /> - <Tab label="Favorites" value={1} /> - <Tab label="More Contents" value={2} /> - </Tabs> - </Box> - {currentTab === 0 && ( - <SearchPage - list={searchResult} - onSearch={setSearchResult} - favoriteList={favoriteList} - addToFavoriteList={addToFavoriteList} - likes={likes} - handleLikes={handleLikes} - /> - )} - {currentTab === 1 && ( - <Favorites - favoriteList={favoriteList} - addToFavoriteList={addToFavoriteList} - likes={likes} - handleLikes={handleLikes} - removeFromFavoriteList={removeFromFavoriteList} - /> - )} - {currentTab === 2 && <Typography align="center" variant="h2"> Item Three</Typography>} - </React.Fragment> - ); + return ( + <React.Fragment> + <CssBaseline /> + <AppBar position="fixed"> + <Typography align="center" variant="h3" color="inherit">Tae Wook's Favorite Music</Typography> + </AppBar> + <div style={{ height: 60, width: '100%' }}></div> + <Box sx={{ borderBottom: 1, borderColor: 'divider' }}> + <Tabs value={currentTab} onChange={handleTabChange} aria-label="basic tabs" centered> + {TABS.map((tab, index) => <Tab key={index} label={tab.label} value={index} />)} + </Tabs> + </Box> + <TabComponent + list={searchResult} + onSearch={setSearchResult} + favoriteList={favoriteList} + addToFavoriteList={addToFavoriteList} + likes={likes} + handleLikes={handleLikes} + removeFromFavoriteList={removeFromFavoriteList} + /> + </React.Fragment> + ); } diff --git a/src/Favorites.js b/src/Favorites.js index 34e33b07bccc2728e8a748a5b6ebfd1a3e579b97..b7af93f3b4fef981a5d7ccf5f755965fec6ae5fc 100644 --- a/src/Favorites.js +++ b/src/Favorites.js @@ -3,46 +3,41 @@ import { Card, CardContent, CardActions, IconButton, Typography } from '@mui/mat import { Favorite, FavoriteBorder } from '@mui/icons-material'; const styles = { - content: {}, - layout: { - display: 'flex', - justifyContent: 'center' - }, - card: { - minWidth: 275, - maxWidth: 600, - marginBottom: '20pt', - marginLeft: 'auto', - marginRight: 'auto' - }, + card: { + minWidth: 275, + maxWidth: 600, + marginBottom: '20pt', + marginLeft: 'auto', + marginRight: 'auto' + }, }; export default function Favorites({ favoriteList, likes, handleLikes, removeFromFavoriteList }) { - const [favoriteLikes, setFavoriteLikes] = useState(likes); + const [favoriteLikes, setFavoriteLikes] = useState(likes); - const toggleFavorite = (id) => { - const updatedLikes = { ...favoriteLikes, [id]: !favoriteLikes[id] }; - setFavoriteLikes(updatedLikes); - handleLikes(id); -}; + const toggleFavorite = (id) => { + const updatedLikes = { ...favoriteLikes, [id]: !favoriteLikes[id] }; + setFavoriteLikes(updatedLikes); + handleLikes(id); + }; - const filteredFavoriteList = favoriteList.filter((item) => favoriteLikes[item.collectionId] === true); + const filteredFavoriteList = favoriteList.filter((item) => favoriteLikes[item.collectionId]); - return ( - <div> - {filteredFavoriteList.map((item) => ( - <Card sx={styles.card} key={item.collectionId}> - <CardContent> - <Typography variant="subtitle1">{item.artisName}</Typography> - <Typography variant="subtitle2">{item.collectionCensoredName}</Typography> - </CardContent> - <CardActions> - <IconButton onClick={() => toggleFavorite(item.collectionId)}> - {favoriteLikes[item.collectionId] ? <Favorite /> : <FavoriteBorder />} - </IconButton> - </CardActions> - </Card> - ))} - </div> - ); + return ( + <div> + {filteredFavoriteList.map((item) => ( + <Card sx={styles.card} key={item.collectionId}> + <CardContent> + <Typography variant="subtitle1">{item.artisName}</Typography> + <Typography variant="subtitle2">{item.collectionCensoredName}</Typography> + </CardContent> + <CardActions> + <IconButton onClick={() => toggleFavorite(item.collectionId)}> + {favoriteLikes[item.collectionId] ? <Favorite /> : <FavoriteBorder />} + </IconButton> + </CardActions> + </Card> + ))} + </div> + ); } diff --git a/src/MusicList.js b/src/MusicList.js index 8d40673ee75c46145084c3aebaf7fe628fe2991b..05b1c1abf853ebdee7791f55c12f8531df05fc3b 100644 --- a/src/MusicList.js +++ b/src/MusicList.js @@ -1,67 +1,61 @@ import React from 'react'; import { Card, CardContent, CardActions, IconButton, Typography } from '@mui/material'; -import { Favorite, FavoriteBorder, Preview } from '@mui/icons-material'; +import { Favorite, FavoriteBorder } from '@mui/icons-material'; import SnackMsg from './Snackbar'; const styles = { - content: {}, - layout: { - display: 'flex', - justifyContent: 'center' - }, - card: { - minWidth: 275, - maxWidth: 600, - marginBottom: '20pt', - marginLeft: 'auto', - marginRight: 'auto' - }, + card: { + minWidth: 275, + maxWidth: 600, + marginBottom: '20pt', + marginLeft: 'auto', + marginRight: 'auto' + }, }; export default function MusicList({ list, favoriteList, addToFavoriteList, likes, handleLikes }) { - let [snackState, setSnackState] = React.useState({ open: false, msg: '' }); + const [snackState, setSnackState] = React.useState({ open: false, msg: '' }); - const toggleFavorite = (id, name) => () => { - const updatedLikes = { ...likes, [id]: !likes[id] }; + const toggleFavorite = (id, name) => () => { + const updatedLikes = { ...likes, [id]: !likes[id] }; + handleLikes(id); + setSnackState({ ...snackState, open: true, msg: `${name} is clicked` }); - handleLikes(id); - setSnackState({ ...snackState, open: true, msg: `${name} is clicked` }); - - if (updatedLikes[id]) { - if (!favoriteList.find((item) => item.collectionId === id)) { - addToFavoriteList(list.find((item) => item.collectionId === id)); - } - } else { - const updatedFavoriteList = favoriteList.filter((item) => item.collectionId !== id); - addToFavoriteList(updatedFavoriteList); - } + if (updatedLikes[id]) { + if (!favoriteList.find((item) => item.collectionId === id)) { + addToFavoriteList(list.find((item) => item.collectionId === id)); + } + } else { + const updatedFavoriteList = favoriteList.filter((item) => item.collectionId !== id); + addToFavoriteList(updatedFavoriteList); + } }; const handleSnackbarClose = (event, reason) => { - if (reason === 'clickaway') { - return; - } - setSnackState({ open: false, msg: '' }); + if (reason === 'clickaway') { + return; + } + setSnackState({ open: false, msg: '' }); }; return ( - <div> - {list.map((item) => { - return ( - <Card sx={styles.card} key={item.collectionId}> - <CardContent> - <Typography variant="subtitle1">{item.artisName}</Typography> - <Typography variant="subtitle2">{item.collectionCensoredName}</Typography> - </CardContent> - <CardActions> - <IconButton onClick={toggleFavorite(item.collectionId, item.collectionName)}> - {likes[item.collectionId] === true ? <Favorite /> : <FavoriteBorder />} - <SnackMsg open={snackState.open} message={snackState.msg} onClose={handleSnackbarClose} /> - </IconButton> - </CardActions> - </Card> - ); - })} - </div> + <div> + {list.map((item) => { + return ( + <Card sx={styles.card} key={item.collectionId}> + <CardContent> + <Typography variant="subtitle1">{item.artisName}</Typography> + <Typography variant="subtitle2">{item.collectionCensoredName}</Typography> + </CardContent> + <CardActions> + <IconButton onClick={toggleFavorite(item.collectionId, item.collectionName)}> + {likes[item.collectionId] ? <Favorite /> : <FavoriteBorder />} + </IconButton> + <SnackMsg open={snackState.open} message={snackState.msg} onClose={handleSnackbarClose} /> + </CardActions> + </Card> + ); + })} + </div> ); } diff --git a/src/SearchPage.js b/src/SearchPage.js index 30a21bf81b2f231ddb982515c5c0b8a3a042ebbb..d5f466e9dd81cc6c73d909da271a5fbb42bd81c6 100644 --- a/src/SearchPage.js +++ b/src/SearchPage.js @@ -2,40 +2,49 @@ import React from 'react'; import { Button, TextField } from '@mui/material'; import MusicList from './MusicList'; -export default function SearchPage({list, onSearch, favoriteList, addToFavoriteList, likes, handleLikes}){ - const [searchWord, setSearchWord] = React.useState(''); - - const handleSearch = (event) => { - event.preventDefault(); - console.log(searchWord); +export default function SearchPage({ list, onSearch, favoriteList, addToFavoriteList, likes, handleLikes }) { + const [searchWord, setSearchWord] = React.useState(''); + + const handleSearch = (event) => { + event.preventDefault(); + fetch(`http://itunes.apple.com/search?term=${searchWord}&entity=album`) + .then((response) => response.json()) + .then((data) => { + console.log(data); + onSearch(data.results); setSearchWord(''); - fetch(`http://itunes.apple.com/search?term=${searchWord}&entity=album`) - .then(r => r.json()).then(r => { - console.log(r); - onSearch(r.results); - setSearchWord(''); - }).catch(e => console.log('error when search musician')); - } + }) + .catch((error) => console.error('Error when searching for musicians', error)); + }; - const handleSearchTextChange = (event) => { - setSearchWord(event.target.value); - } + const handleSearchTextChange = (event) => { + setSearchWord(event.target.value); + }; - return ( - <React.Fragment> - <form style={{display: 'flex', marginTop: 20, marginBottom : 15}}> - <div style={{display: 'flex', marginLeft: 'auto', marginRight: 'auto,'}}> - <TextField variant='outlined' label="Music Album Search" type='search' style={{width:450}} - onChange={handleSearchTextChange} value={searchWord}> - </TextField> - <Button variant="contained" color="primary" - type="submit" onClick={handleSearch} - style={{marginLeft: 20}}> - Search - </Button> - </div> - </form> - <MusicList list={list} favoriteList={favoriteList} addToFavoriteList={addToFavoriteList} likes={likes} handleLikes={handleLikes} ></MusicList> - </React.Fragment> - ) + return ( + <React.Fragment> + <form style={{ display: 'flex', marginTop: 20, marginBottom: 15 }}> + <div style={{ display: 'flex', marginLeft: 'auto', marginRight: 'auto' }}> + <TextField + variant='outlined' + label="Music Album Search" + type='search' + style={{ width: 450 }} + onChange={handleSearchTextChange} + value={searchWord} + /> + <Button variant="contained" color="primary" type="submit" onClick={handleSearch} style={{ marginLeft: 20 }}> + Search + </Button> + </div> + </form> + <MusicList + list={list} + favoriteList={favoriteList} + addToFavoriteList={addToFavoriteList} + likes={likes} + handleLikes={handleLikes} + /> + </React.Fragment> + ); }