Skip to content
Snippets Groups Projects
Commit c609c068 authored by Sumin Shin's avatar Sumin Shin
Browse files

complete

parent 212ff5c0
Branches
No related tags found
1 merge request!1Main
Pipeline #7938 canceled
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
"dependencies": { "dependencies": {
"@emotion/react": "^11.9.3", "@emotion/react": "^11.9.3",
"@emotion/styled": "^11.9.3", "@emotion/styled": "^11.9.3",
"@mui/icons-material": "^5.13.7",
"@mui/material": "^5.8.6" "@mui/material": "^5.8.6"
}, },
"devDependencies": { "devDependencies": {
...@@ -31,6 +32,6 @@ ...@@ -31,6 +32,6 @@
"UI", "UI",
"ReactJS" "ReactJS"
], ],
"author": "Jae Young Choi", "author": "Su Min Shin",
"license": "MIT" "license": "MIT"
} }
This diff is collapsed.
import React from 'react'; import React from 'react';
import Typography from '@mui/material/Typography'; import {Box,Tabs,Tab, Typography, AppBar, CssBaseline} from "@mui/material";
import MusicList from "./MusicList";
import Favorites from './Favorites';
import music_list from "./data";
import SnackMsg from './SnackMsg';
import SearchPage from './SearchPage';
import { SettingsCellRounded } from '@mui/icons-material';
export default function App (){ export default function App (){
return <Typography variant="h1">Hello World</Typography> const [currentTab,setCurrentTab] = React.useState(0);
const [searchResult, setSearchResult] = React.useState([]);
const [likes, setLikes] = React.useState({});
const handleTabChange = (event, newValue)=>{
setCurrentTab(newValue);
}
return (
<React.Fragment>
<AppBar position ="fixed">
<Typography align="center" variant="h3" color="inherit">Sumin's Favorite Music</Typography>
</AppBar>
<div style={{height:60, width:"100%"}}></div>
<Box sx={{borderBottom:1, borderColorl:"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}/>}
{currentTab === 1 && <Favorites list={searchResult} likes={likes} />}
{currentTab == 2 && <Typography align="center" variant='h2'>More</Typography>}
</React.Fragment>
);
} }
import React from 'react';
import { Typography } from '@mui/material';
import MusicList from './MusicList';
const Favorites = ({ list, likes }) => {
const favoriteList = list.filter(item => likes[item.collectionCensoredName]);
return (
<React.Fragment>
<Typography align="center" variant="h2">Favorites</Typography>
{favoriteList.length > 0 ? (
<MusicList list={favoriteList} />
) : (
<Typography align="center" variant="h4">No favorites yet.</Typography>
)}
</React.Fragment>
);
}
export default Favorites;
import React from "react";
import {Card, CardContent,CardActions, Typography,IconButton, Alert} from "@mui/material";
import {Favorite, FavoriteBorder} from "@mui/icons-material";
import SnackMsg from "./SnackMsg";
const styles={
content:{},
layout:{
display:"flex",
justifyContent:"center",
},
card:{
minWidth:275,
maxWidth:600,
marginBottom:"20pt",
marginLeft:"auto",
marginRight:"auto",
}
};
export default function MusicList ({list}){
const [likes,setLikes] = React.useState({});
let [snackState, setSnackState] = React.useState({open:false, msg:""});
const toggleFavorite=(id) => () => {
setLikes({...likes, [id]: !likes[id]});
setSnackState({...snackState, open :true, msg:`${id} is clicked`});
}
const handleSnackbarClose = (event, reason) => {
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.artistName}</Typography>
<Typography variant="subtitle2">{item.collectionCensoredName}</Typography>
</CardContent>
<CardActions>
<IconButton onClick={toggleFavorite(item.collectionCensoredName)}>
{(likes[item.collectionCensoredName]===true)? <Favorite />:<FavoriteBorder />}
</IconButton>
</CardActions>
</Card>)
})}
<SnackMsg open ={snackState.open} message={snackState.msg} onClose={handleSnackbarClose} />
</div>
)
}
\ No newline at end of file
import React from "react";
import {Button, TextField} from "@mui/material";
import MusicList from "./MusicList";
export default function SearchPage ({list, onSearch}) {
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="serach" 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={music_list}></MusicList> */}
<MusicList list={list}></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
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment