Skip to content
Snippets Groups Projects
Commit 11b1bb92 authored by TaeWook Kim's avatar TaeWook Kim
Browse files

1'

parent 8e881387
No related branches found
No related tags found
No related merge requests found
Pipeline #7890 passed
......@@ -6,6 +6,7 @@
"dependencies": {
"@emotion/react": "^11.9.3",
"@emotion/styled": "^11.9.3",
"@mui/icons-material": "^5.13.7",
"@mui/material": "^5.8.6"
},
"devDependencies": {
......
Source diff could not be displayed: it is too large. Options to address this: view the blob.
import React from 'react';
import { Typography, AppBar } from '@mui/material';
import MusicList from './MusicList';
import music_list from './data';
import SearchPage from './SearchPage';
import Favorites from './Favorites';
import { Box, Tabs, Tab, Typography, AppBar, CssBaseline } from '@mui/material';
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 handleTabChange = (event, newValue) => {
setCurrentTab(newValue);
};
const addToFavoriteList = (item) => {
setFavoriteList((prevList) => [...prevList, item]);
};
const handleLikes = (id) => {
const updatedLikes = { ...likes, [id]: !likes[id] };
setLikes(updatedLikes);
};
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>
<div style={{ height: 60, width: '100%' }}></div>
<MusicList list={music_list}>
</MusicList>
<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>
)
);
}
import React, { useState } from 'react';
import { Card, CardContent, CardActions, IconButton, Typography } from '@mui/material';
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'
},
};
export default function Favorites({ favoriteList, likes, handleLikes, removeFromFavoriteList }) {
const [favoriteLikes, setFavoriteLikes] = useState(likes);
const toggleFavorite = (id) => {
const updatedLikes = { ...favoriteLikes, [id]: !favoriteLikes[id] };
setFavoriteLikes(updatedLikes);
handleLikes(id);
};
const filteredFavoriteList = favoriteList.filter((item) => favoriteLikes[item.collectionId] === true);
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>
);
}
import React from 'react';
import {Card, CardContent, Typography} from '@mui/material';
import { Card, CardContent, CardActions, IconButton, Typography } from '@mui/material';
import { Favorite, FavoriteBorder, Preview } 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'
},
};
export default function MusicList({ list, favoriteList, addToFavoriteList, likes, handleLikes }) {
let [snackState, setSnackState] = React.useState({ open: false, msg: '' });
const toggleFavorite = (id, name) => () => {
const updatedLikes = { ...likes, [id]: !likes[id] };
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);
}
};
const handleSnackbarClose = (event, reason) => {
if (reason === 'clickaway') {
return;
}
setSnackState({ open: false, msg: '' });
};
export default function MusicList ({list}) {
return (
<div>
{list.result.map(item => {
{list.map((item) => {
return (
<Card>
<Card sx={styles.card} key={item.collectionId}>
<CardContent>
<Typography variant="subtitle1"> {item.artistName}</Typography>
<Typography variant="subtitle1">{item.artisName}</Typography>
<Typography variant="subtitle2">{item.collectionCensoredName}</Typography>
</CardContent>
</Card>)
<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>
);
......
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);
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'));
}
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>
)
}
import React from 'react';
import { Snackbar } from '@mui/material';
const SnackMsg = (props) => {
return (
<Snackbar
open={props.open}
anchorOrigin={{ vertical : 'bottom', horizontal : 'right'}}
autoHideDuration={3000}
onClose={props.onClose}
message={props.message}>
</Snackbar>
);
}
export default SnackMsg;
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment